@thinkingai/ae-cli 6.0.28 → 6.0.30

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 (103) hide show
  1. package/dist/capability-KVA55RMK.js +227 -0
  2. package/dist/capability-LKHLZQPD.js +227 -0
  3. package/dist/chunk-CWZUGF2J.js +26 -0
  4. package/dist/{chunk-YNQFYBDB.js → chunk-OJR23CIK.js} +12 -0
  5. package/dist/chunk-OO6XR6LK.js +26 -0
  6. package/dist/{chunk-C4DH76LX.js → chunk-P2JRP6HJ.js} +4 -21
  7. package/dist/{chunk-LG5YT7P7.js → chunk-S5XN6KEX.js} +4 -21
  8. package/dist/{chunk-BXMXMUD7.js → chunk-THBBNYXI.js} +12 -0
  9. package/dist/index.js +22 -11
  10. package/dist/{metadata-IPSPQBX3.js → metadata-6CCFV4K5.js} +11 -8
  11. package/dist/{metadata-N5REJ7R7.js → metadata-PDOIWH5O.js} +11 -8
  12. package/dist/{te-agent-QLIVKRUN.js → te-agent-FAIBM3SA.js} +5 -5
  13. package/dist/{te-analysis-5WZKVFHI.js → te-analysis-DDXGM7WM.js} +173 -260
  14. package/dist/{te-analysis-KAEZXLNS.js → te-analysis-HCDNYI7E.js} +173 -260
  15. package/dist/{te-audience-XMRMVD2V.js → te-audience-ECFS4GF4.js} +11 -10
  16. package/dist/{te-audience-PVMKQAFH.js → te-audience-WO377T2J.js} +11 -10
  17. package/dist/{te-engage-AGREUOW7.js → te-engage-545HJL6J.js} +4 -4
  18. package/dist/{te-engage-MIIUKY6M.js → te-engage-M7JQSJDP.js} +4 -4
  19. package/dist/{te-kb-KQJ53M3A.js → te-kb-NT33UHAE.js} +1 -1
  20. package/dist/{te-meta-QLANJ4B4.js → te-meta-FADFLTDM.js} +3 -3
  21. package/dist/{te-meta-TOA6FWDE.js → te-meta-PKT27OTN.js} +3 -3
  22. package/dist/{te-team-TQGMNHQQ.js → te-team-RG75PR5D.js} +1 -1
  23. package/package.json +2 -1
  24. package/skills/ae-agent/SKILL.md +4 -3
  25. package/skills/ae-analysis/SKILL.md +35 -16
  26. package/skills/ae-analysis/references/analysis_gateway_assets.md +42 -9
  27. package/skills/ae-analysis/references/asset_abnormal_get.md +3 -3
  28. package/skills/ae-analysis/references/asset_abnormal_list.md +3 -3
  29. package/skills/ae-analysis/references/asset_authentication_list.md +3 -3
  30. package/skills/ae-analysis/references/asset_authentication_update.md +3 -3
  31. package/skills/ae-analysis/references/asset_recent_list.md +3 -3
  32. package/skills/ae-analysis/references/asset_search.md +3 -3
  33. package/skills/ae-analysis/references/build_event_analysis_qp.md +1 -1
  34. package/skills/ae-analysis/references/build_funnel_analysis_qp.md +1 -1
  35. package/skills/ae-analysis/references/build_prop_analysis_qp.md +1 -1
  36. package/skills/ae-analysis/references/build_retention_analysis_qp.md +1 -1
  37. package/skills/ae-analysis/references/cancel_query.md +1 -1
  38. package/skills/ae-analysis/references/datatable_columns_get.md +3 -3
  39. package/skills/ae-analysis/references/datatable_influence_list.md +3 -3
  40. package/skills/ae-analysis/references/datatable_version_get.md +3 -3
  41. package/skills/ae-analysis/references/datatable_version_list.md +3 -3
  42. package/skills/ae-analysis/references/drilldown_user_events.md +4 -4
  43. package/skills/ae-analysis/references/event_changelog_list.md +3 -3
  44. package/skills/ae-analysis/references/event_create.md +3 -3
  45. package/skills/ae-analysis/references/event_delete.md +3 -3
  46. package/skills/ae-analysis/references/event_get.md +3 -3
  47. package/skills/ae-analysis/references/event_hide_update.md +3 -3
  48. package/skills/ae-analysis/references/event_influence_list.md +3 -3
  49. package/skills/ae-analysis/references/event_list.md +3 -3
  50. package/skills/ae-analysis/references/event_relation_update.md +3 -3
  51. package/skills/ae-analysis/references/event_update.md +3 -3
  52. package/skills/ae-analysis/references/exchange_config_update.md +3 -3
  53. package/skills/ae-analysis/references/exchange_rate_refresh.md +3 -3
  54. package/skills/ae-analysis/references/exchange_rule_list.md +3 -3
  55. package/skills/ae-analysis/references/exchange_rule_update.md +3 -3
  56. package/skills/ae-analysis/references/exchange_rule_validate.md +3 -3
  57. package/skills/ae-analysis/references/folder_create.md +18 -6
  58. package/skills/ae-analysis/references/folder_delete.md +21 -6
  59. package/skills/ae-analysis/references/folder_share.md +16 -6
  60. package/skills/ae-analysis/references/get_analysis_query_schema.md +17 -18
  61. package/skills/ae-analysis/references/get_report_definition.md +1 -1
  62. package/skills/ae-analysis/references/list_events.md +1 -1
  63. package/skills/ae-analysis/references/list_metrics.md +1 -1
  64. package/skills/ae-analysis/references/list_properties.md +1 -1
  65. package/skills/ae-analysis/references/metric_create.md +3 -3
  66. package/skills/ae-analysis/references/metric_delete.md +3 -3
  67. package/skills/ae-analysis/references/metric_get.md +3 -3
  68. package/skills/ae-analysis/references/metric_list.md +3 -3
  69. package/skills/ae-analysis/references/metric_update.md +3 -3
  70. package/skills/ae-analysis/references/project_space_create.md +19 -5
  71. package/skills/ae-analysis/references/project_space_delete.md +23 -6
  72. package/skills/ae-analysis/references/project_space_share.md +16 -6
  73. package/skills/ae-analysis/references/property_changelog_list.md +3 -3
  74. package/skills/ae-analysis/references/property_create.md +3 -3
  75. package/skills/ae-analysis/references/property_delete.md +3 -3
  76. package/skills/ae-analysis/references/property_get.md +3 -3
  77. package/skills/ae-analysis/references/property_hide_update.md +3 -3
  78. package/skills/ae-analysis/references/property_influence_list.md +3 -3
  79. package/skills/ae-analysis/references/property_list.md +3 -3
  80. package/skills/ae-analysis/references/property_related_events.md +3 -3
  81. package/skills/ae-analysis/references/property_relation_update.md +3 -3
  82. package/skills/ae-analysis/references/property_update.md +3 -3
  83. package/skills/ae-analysis/references/query_adhoc.md +34 -21
  84. package/skills/ae-analysis/references/super_metadata_export.md +4 -4
  85. package/skills/ae-analysis/references/super_metadata_import.md +3 -3
  86. package/skills/ae-analysis/references/update_report.md +3 -3
  87. package/skills/ae-analysis/references/virtual_event_create.md +3 -3
  88. package/skills/ae-analysis/references/virtual_event_delete.md +3 -3
  89. package/skills/ae-analysis/references/virtual_event_get.md +3 -3
  90. package/skills/ae-analysis/references/virtual_property_create.md +3 -3
  91. package/skills/ae-analysis/references/virtual_property_sql_rule_delete.md +3 -3
  92. package/skills/ae-analysis/references/virtual_property_sql_rule_update.md +3 -3
  93. package/skills/ae-capability/SKILL.md +103 -0
  94. package/skills/ae-community/SKILL.md +1 -1
  95. package/skills/ae-data-integration-helper/SKILL.md +1 -1
  96. package/skills/ae-dataops/references/dataops-integration.md +3 -3
  97. package/skills/ae-engage/SKILL.md +5 -5
  98. package/skills/ae-generate-tracking-code/SKILL.md +1 -1
  99. package/skills/ae-generate-tracking-plan/SKILL.md +1 -1
  100. package/skills/ae-metadata/references/metadata_data_table_sql_write.md +60 -8
  101. package/skills/ae-team/SKILL.md +1 -1
  102. package/skills/ae-analysis/references/folder_members.md +0 -15
  103. package/skills/ae-analysis/references/project_space_members.md +0 -15
@@ -0,0 +1,227 @@
1
+ import {
2
+ normalizeRiskLevel,
3
+ requiresConfirmation
4
+ } from "./chunk-OO6XR6LK.js";
5
+ import {
6
+ printError,
7
+ printOutput
8
+ } from "./chunk-ZAOL36CG.js";
9
+ import {
10
+ findGatewayDomain
11
+ } from "./chunk-CWZUGF2J.js";
12
+ import {
13
+ CapabilityGatewayError,
14
+ dryRunCapability,
15
+ executeCapability,
16
+ inspectCapability,
17
+ listCapabilities
18
+ } from "./chunk-OJR23CIK.js";
19
+ import {
20
+ PermissionError
21
+ } from "./chunk-NOO24N7W.js";
22
+ import "./chunk-2NDGFQHW.js";
23
+ import {
24
+ SecureStoreAuthError,
25
+ resolveHost
26
+ } from "./chunk-AJTH7LT3.js";
27
+ import {
28
+ safeJsonParse
29
+ } from "./chunk-YCLVYFK7.js";
30
+
31
+ // src/commands/capability/index.ts
32
+ import * as readline from "readline";
33
+
34
+ // src/commands/capability/helpers.ts
35
+ import { readFileSync } from "fs";
36
+ var CapabilityCommandValidationError = class extends Error {
37
+ constructor(message, hint) {
38
+ super(message);
39
+ this.hint = hint;
40
+ this.name = "CapabilityCommandValidationError";
41
+ }
42
+ hint;
43
+ };
44
+ function capabilityNamespace(capabilityId) {
45
+ return capabilityId.split(".")[0] ?? "";
46
+ }
47
+ function resolveCapabilityGatewayDomain(capabilityId, domainOverride) {
48
+ const cliDomain = domainOverride?.trim() || capabilityNamespace(capabilityId);
49
+ if (!cliDomain) {
50
+ throw new CapabilityCommandValidationError(
51
+ "Cannot determine the capability domain.",
52
+ "Pass --domain <domain>."
53
+ );
54
+ }
55
+ return findGatewayDomain(cliDomain) ?? cliDomain;
56
+ }
57
+ function normalizeCapabilityList(value) {
58
+ if (!Array.isArray(value)) {
59
+ throw new Error("Capability gateway returned an invalid catalog: expected an array.");
60
+ }
61
+ return value.filter((item) => {
62
+ return item !== null && typeof item === "object" && typeof item.id === "string";
63
+ });
64
+ }
65
+ function filterCapabilities(capabilities, domain, query) {
66
+ const prefix = `${domain.toLowerCase()}.`;
67
+ const terms = query?.trim().toLowerCase().split(/\s+/).filter(Boolean) ?? [];
68
+ return capabilities.filter((capability) => {
69
+ if (!capability.id.toLowerCase().startsWith(prefix)) {
70
+ return false;
71
+ }
72
+ if (terms.length === 0) {
73
+ return true;
74
+ }
75
+ const searchable = `${capability.id} ${capability.description ?? ""}`.toLowerCase();
76
+ return terms.every((term) => searchable.includes(term));
77
+ });
78
+ }
79
+ function parseCapabilityInput(raw) {
80
+ if (!raw) {
81
+ return {};
82
+ }
83
+ const trimmed = raw.trim();
84
+ let parsed;
85
+ try {
86
+ if (trimmed === "-") {
87
+ parsed = safeJsonParse(readFileSync(0, "utf8"));
88
+ } else if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
89
+ parsed = safeJsonParse(trimmed);
90
+ } else {
91
+ const path = trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
92
+ parsed = safeJsonParse(readFileSync(path, "utf8"));
93
+ }
94
+ } catch (error) {
95
+ const message = error instanceof Error ? error.message : String(error);
96
+ throw new CapabilityCommandValidationError(
97
+ `Invalid capability input: ${message}`,
98
+ "Pass an inline JSON object, a JSON file path, @<path>, or - for stdin."
99
+ );
100
+ }
101
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
102
+ throw new CapabilityCommandValidationError(
103
+ "Capability input must be a JSON object.",
104
+ `Example: --input '{"project_id":1}'`
105
+ );
106
+ }
107
+ return parsed;
108
+ }
109
+
110
+ // src/commands/capability/index.ts
111
+ function registerCapability(program) {
112
+ const capability = program.command("capability").description("Discover and invoke capability gateway operations").action(() => {
113
+ printError("validation", "Missing subcommand.", "Run: ae-cli capability --help");
114
+ process.exitCode = 1;
115
+ });
116
+ capability.command("list").description("List capability summaries in a domain").requiredOption("--domain <domain>", "Capability namespace, such as analysis or metadata").action(async (opts) => {
117
+ await executeAndPrint(program, async (host) => {
118
+ const gatewayDomain = findGatewayDomain(opts.domain) ?? opts.domain;
119
+ const catalog = normalizeCapabilityList(await listCapabilities(host, gatewayDomain));
120
+ const capabilities = filterCapabilities(catalog, opts.domain);
121
+ return { domain: opts.domain, count: capabilities.length, capabilities };
122
+ });
123
+ }).addHelpText("after", "\nExample:\n ae-cli capability list --domain analysis");
124
+ capability.command("search").description("Search capability IDs and descriptions in a domain").argument("<query>", "Case-insensitive search terms").requiredOption("--domain <domain>", "Capability namespace, such as analysis or metadata").action(async (query, opts) => {
125
+ await executeAndPrint(program, async (host) => {
126
+ const gatewayDomain = findGatewayDomain(opts.domain) ?? opts.domain;
127
+ const catalog = normalizeCapabilityList(await listCapabilities(host, gatewayDomain));
128
+ const capabilities = filterCapabilities(catalog, opts.domain, query);
129
+ return { domain: opts.domain, query, count: capabilities.length, capabilities };
130
+ });
131
+ }).addHelpText("after", '\nExample:\n ae-cli capability search "dashboard list" --domain analysis');
132
+ capability.command("inspect").description("Inspect one capability schema, risk, auth, and output metadata").argument("<capability-id>", "Capability ID, such as analysis.report.list").option("--domain <domain>", "Override the capability namespace used for gateway routing").action(async (capabilityId, opts) => {
133
+ await executeAndPrint(program, async (host) => {
134
+ const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
135
+ return inspectCapability(host, gatewayDomain, capabilityId);
136
+ });
137
+ }).addHelpText("after", "\nExample:\n ae-cli capability inspect analysis.dashboard.list");
138
+ capability.command("dry-run").description("Validate and preview one capability invocation without executing it").argument("<capability-id>", "Capability ID, such as analysis.query.export").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--input <json-or-path>", "Input JSON object, file path, @<path>, or - for stdin").action(async (capabilityId, opts) => {
139
+ await executeAndPrint(program, async (host) => {
140
+ const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
141
+ return dryRunCapability(host, gatewayDomain, capabilityId, parseCapabilityInput(opts.input));
142
+ });
143
+ }).addHelpText(
144
+ "after",
145
+ `
146
+ Examples:
147
+ ae-cli capability dry-run analysis.dashboard.list --input '{"project_id":1}'
148
+ ae-cli capability dry-run analysis.dashboard.list --input input.json`
149
+ );
150
+ capability.command("run").description("Execute one capability by ID").argument("<capability-id>", "Capability ID, such as analysis.report.list").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--input <json-or-path>", "Input JSON object, file path, @<path>, or - for stdin").action(async (capabilityId, opts) => {
151
+ await executeAndPrint(program, async (host, globalOpts) => {
152
+ const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
153
+ const input = parseCapabilityInput(opts.input);
154
+ if (globalOpts.dryRun) {
155
+ return dryRunCapability(host, gatewayDomain, capabilityId, input);
156
+ }
157
+ if (!globalOpts.yes) {
158
+ const metadata = await inspectCapability(host, gatewayDomain, capabilityId);
159
+ const risk = normalizeRiskLevel(typeof metadata?.risk === "string" ? metadata.risk : void 0);
160
+ if (requiresConfirmation(risk)) {
161
+ const confirmed = await confirm(`This capability is marked ${risk} (${capabilityId}). Continue?`);
162
+ if (!confirmed) {
163
+ process.stderr.write("Aborted.\n");
164
+ return void 0;
165
+ }
166
+ }
167
+ }
168
+ return executeCapability(host, gatewayDomain, capabilityId, input);
169
+ });
170
+ }).addHelpText(
171
+ "after",
172
+ `
173
+ Examples:
174
+ ae-cli capability run analysis.dashboard.list --input '{"project_id":1}'
175
+ ae-cli capability run analysis.dashboard.list --input input.json --yes`
176
+ );
177
+ }
178
+ async function executeAndPrint(program, action) {
179
+ const globalOpts = program.opts();
180
+ const host = resolveHost(globalOpts.host);
181
+ if (!host) {
182
+ printError("config", "No AE host configured.", "Run: ae-cli config set-host <url>");
183
+ process.exitCode = 1;
184
+ return;
185
+ }
186
+ try {
187
+ const result = await action(host, globalOpts);
188
+ if (result !== void 0) {
189
+ printOutput(result, globalOpts.format ?? "json", globalOpts.jq);
190
+ }
191
+ } catch (error) {
192
+ printCapabilityError(error);
193
+ process.exitCode = 1;
194
+ }
195
+ }
196
+ function printCapabilityError(error) {
197
+ if (error instanceof CapabilityCommandValidationError) {
198
+ printError("validation", error.message, error.hint);
199
+ return;
200
+ }
201
+ if (error instanceof SecureStoreAuthError) {
202
+ printError("auth", error.message, "Run: ae-cli auth login");
203
+ return;
204
+ }
205
+ if (error instanceof PermissionError) {
206
+ printError("permission", error.message);
207
+ return;
208
+ }
209
+ if (error instanceof CapabilityGatewayError) {
210
+ printError("api", error.message, error.hint, error.code);
211
+ return;
212
+ }
213
+ const message = error instanceof Error ? error.message : String(error);
214
+ printError("api", message);
215
+ }
216
+ async function confirm(message) {
217
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
218
+ return new Promise((resolve) => {
219
+ rl.question(`${message} [y/N] `, (answer) => {
220
+ rl.close();
221
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
222
+ });
223
+ });
224
+ }
225
+ export {
226
+ registerCapability
227
+ };
@@ -0,0 +1,227 @@
1
+ import {
2
+ normalizeRiskLevel,
3
+ requiresConfirmation
4
+ } from "./chunk-OO6XR6LK.js";
5
+ import {
6
+ printError,
7
+ printOutput
8
+ } from "./chunk-ZAOL36CG.js";
9
+ import {
10
+ findGatewayDomain
11
+ } from "./chunk-CWZUGF2J.js";
12
+ import {
13
+ CapabilityGatewayError,
14
+ dryRunCapability,
15
+ executeCapability,
16
+ inspectCapability,
17
+ listCapabilities
18
+ } from "./chunk-THBBNYXI.js";
19
+ import {
20
+ PermissionError
21
+ } from "./chunk-NOO24N7W.js";
22
+ import "./chunk-2NDGFQHW.js";
23
+ import {
24
+ SecureStoreAuthError,
25
+ resolveHost
26
+ } from "./chunk-AJTH7LT3.js";
27
+ import {
28
+ safeJsonParse
29
+ } from "./chunk-YCLVYFK7.js";
30
+
31
+ // src/commands/capability/index.ts
32
+ import * as readline from "readline";
33
+
34
+ // src/commands/capability/helpers.ts
35
+ import { readFileSync } from "fs";
36
+ var CapabilityCommandValidationError = class extends Error {
37
+ constructor(message, hint) {
38
+ super(message);
39
+ this.hint = hint;
40
+ this.name = "CapabilityCommandValidationError";
41
+ }
42
+ hint;
43
+ };
44
+ function capabilityNamespace(capabilityId) {
45
+ return capabilityId.split(".")[0] ?? "";
46
+ }
47
+ function resolveCapabilityGatewayDomain(capabilityId, domainOverride) {
48
+ const cliDomain = domainOverride?.trim() || capabilityNamespace(capabilityId);
49
+ if (!cliDomain) {
50
+ throw new CapabilityCommandValidationError(
51
+ "Cannot determine the capability domain.",
52
+ "Pass --domain <domain>."
53
+ );
54
+ }
55
+ return findGatewayDomain(cliDomain) ?? cliDomain;
56
+ }
57
+ function normalizeCapabilityList(value) {
58
+ if (!Array.isArray(value)) {
59
+ throw new Error("Capability gateway returned an invalid catalog: expected an array.");
60
+ }
61
+ return value.filter((item) => {
62
+ return item !== null && typeof item === "object" && typeof item.id === "string";
63
+ });
64
+ }
65
+ function filterCapabilities(capabilities, domain, query) {
66
+ const prefix = `${domain.toLowerCase()}.`;
67
+ const terms = query?.trim().toLowerCase().split(/\s+/).filter(Boolean) ?? [];
68
+ return capabilities.filter((capability) => {
69
+ if (!capability.id.toLowerCase().startsWith(prefix)) {
70
+ return false;
71
+ }
72
+ if (terms.length === 0) {
73
+ return true;
74
+ }
75
+ const searchable = `${capability.id} ${capability.description ?? ""}`.toLowerCase();
76
+ return terms.every((term) => searchable.includes(term));
77
+ });
78
+ }
79
+ function parseCapabilityInput(raw) {
80
+ if (!raw) {
81
+ return {};
82
+ }
83
+ const trimmed = raw.trim();
84
+ let parsed;
85
+ try {
86
+ if (trimmed === "-") {
87
+ parsed = safeJsonParse(readFileSync(0, "utf8"));
88
+ } else if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
89
+ parsed = safeJsonParse(trimmed);
90
+ } else {
91
+ const path = trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
92
+ parsed = safeJsonParse(readFileSync(path, "utf8"));
93
+ }
94
+ } catch (error) {
95
+ const message = error instanceof Error ? error.message : String(error);
96
+ throw new CapabilityCommandValidationError(
97
+ `Invalid capability input: ${message}`,
98
+ "Pass an inline JSON object, a JSON file path, @<path>, or - for stdin."
99
+ );
100
+ }
101
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
102
+ throw new CapabilityCommandValidationError(
103
+ "Capability input must be a JSON object.",
104
+ `Example: --input '{"project_id":1}'`
105
+ );
106
+ }
107
+ return parsed;
108
+ }
109
+
110
+ // src/commands/capability/index.ts
111
+ function registerCapability(program) {
112
+ const capability = program.command("capability").description("Discover and invoke capability gateway operations").action(() => {
113
+ printError("validation", "Missing subcommand.", "Run: ae-cli capability --help");
114
+ process.exitCode = 1;
115
+ });
116
+ capability.command("list").description("List capability summaries in a domain").requiredOption("--domain <domain>", "Capability namespace, such as analysis or metadata").action(async (opts) => {
117
+ await executeAndPrint(program, async (host) => {
118
+ const gatewayDomain = findGatewayDomain(opts.domain) ?? opts.domain;
119
+ const catalog = normalizeCapabilityList(await listCapabilities(host, gatewayDomain));
120
+ const capabilities = filterCapabilities(catalog, opts.domain);
121
+ return { domain: opts.domain, count: capabilities.length, capabilities };
122
+ });
123
+ }).addHelpText("after", "\nExample:\n ae-cli capability list --domain analysis");
124
+ capability.command("search").description("Search capability IDs and descriptions in a domain").argument("<query>", "Case-insensitive search terms").requiredOption("--domain <domain>", "Capability namespace, such as analysis or metadata").action(async (query, opts) => {
125
+ await executeAndPrint(program, async (host) => {
126
+ const gatewayDomain = findGatewayDomain(opts.domain) ?? opts.domain;
127
+ const catalog = normalizeCapabilityList(await listCapabilities(host, gatewayDomain));
128
+ const capabilities = filterCapabilities(catalog, opts.domain, query);
129
+ return { domain: opts.domain, query, count: capabilities.length, capabilities };
130
+ });
131
+ }).addHelpText("after", '\nExample:\n ae-cli capability search "dashboard list" --domain analysis');
132
+ capability.command("inspect").description("Inspect one capability schema, risk, auth, and output metadata").argument("<capability-id>", "Capability ID, such as analysis.report.list").option("--domain <domain>", "Override the capability namespace used for gateway routing").action(async (capabilityId, opts) => {
133
+ await executeAndPrint(program, async (host) => {
134
+ const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
135
+ return inspectCapability(host, gatewayDomain, capabilityId);
136
+ });
137
+ }).addHelpText("after", "\nExample:\n ae-cli capability inspect analysis.dashboard.list");
138
+ capability.command("dry-run").description("Validate and preview one capability invocation without executing it").argument("<capability-id>", "Capability ID, such as analysis.query.export").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--input <json-or-path>", "Input JSON object, file path, @<path>, or - for stdin").action(async (capabilityId, opts) => {
139
+ await executeAndPrint(program, async (host) => {
140
+ const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
141
+ return dryRunCapability(host, gatewayDomain, capabilityId, parseCapabilityInput(opts.input));
142
+ });
143
+ }).addHelpText(
144
+ "after",
145
+ `
146
+ Examples:
147
+ ae-cli capability dry-run analysis.dashboard.list --input '{"project_id":1}'
148
+ ae-cli capability dry-run analysis.dashboard.list --input input.json`
149
+ );
150
+ capability.command("run").description("Execute one capability by ID").argument("<capability-id>", "Capability ID, such as analysis.report.list").option("--domain <domain>", "Override the capability namespace used for gateway routing").option("--input <json-or-path>", "Input JSON object, file path, @<path>, or - for stdin").action(async (capabilityId, opts) => {
151
+ await executeAndPrint(program, async (host, globalOpts) => {
152
+ const gatewayDomain = resolveCapabilityGatewayDomain(capabilityId, opts.domain);
153
+ const input = parseCapabilityInput(opts.input);
154
+ if (globalOpts.dryRun) {
155
+ return dryRunCapability(host, gatewayDomain, capabilityId, input);
156
+ }
157
+ if (!globalOpts.yes) {
158
+ const metadata = await inspectCapability(host, gatewayDomain, capabilityId);
159
+ const risk = normalizeRiskLevel(typeof metadata?.risk === "string" ? metadata.risk : void 0);
160
+ if (requiresConfirmation(risk)) {
161
+ const confirmed = await confirm(`This capability is marked ${risk} (${capabilityId}). Continue?`);
162
+ if (!confirmed) {
163
+ process.stderr.write("Aborted.\n");
164
+ return void 0;
165
+ }
166
+ }
167
+ }
168
+ return executeCapability(host, gatewayDomain, capabilityId, input);
169
+ });
170
+ }).addHelpText(
171
+ "after",
172
+ `
173
+ Examples:
174
+ ae-cli capability run analysis.dashboard.list --input '{"project_id":1}'
175
+ ae-cli capability run analysis.dashboard.list --input input.json --yes`
176
+ );
177
+ }
178
+ async function executeAndPrint(program, action) {
179
+ const globalOpts = program.opts();
180
+ const host = resolveHost(globalOpts.host);
181
+ if (!host) {
182
+ printError("config", "No AE host configured.", "Run: ae-cli config set-host <url>");
183
+ process.exitCode = 1;
184
+ return;
185
+ }
186
+ try {
187
+ const result = await action(host, globalOpts);
188
+ if (result !== void 0) {
189
+ printOutput(result, globalOpts.format ?? "json", globalOpts.jq);
190
+ }
191
+ } catch (error) {
192
+ printCapabilityError(error);
193
+ process.exitCode = 1;
194
+ }
195
+ }
196
+ function printCapabilityError(error) {
197
+ if (error instanceof CapabilityCommandValidationError) {
198
+ printError("validation", error.message, error.hint);
199
+ return;
200
+ }
201
+ if (error instanceof SecureStoreAuthError) {
202
+ printError("auth", error.message, "Run: ae-cli auth login");
203
+ return;
204
+ }
205
+ if (error instanceof PermissionError) {
206
+ printError("permission", error.message);
207
+ return;
208
+ }
209
+ if (error instanceof CapabilityGatewayError) {
210
+ printError("api", error.message, error.hint, error.code);
211
+ return;
212
+ }
213
+ const message = error instanceof Error ? error.message : String(error);
214
+ printError("api", message);
215
+ }
216
+ async function confirm(message) {
217
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
218
+ return new Promise((resolve) => {
219
+ rl.question(`${message} [y/N] `, (answer) => {
220
+ rl.close();
221
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
222
+ });
223
+ });
224
+ }
225
+ export {
226
+ registerCapability
227
+ };
@@ -0,0 +1,26 @@
1
+ // src/core/capability-routing.ts
2
+ var cliServiceRoutes = /* @__PURE__ */ new Map();
3
+ function registerCapabilityGatewayRoute(cliService, route) {
4
+ cliServiceRoutes.set(cliService, route);
5
+ }
6
+ function findGatewayDomain(cliService) {
7
+ return cliServiceRoutes.get(cliService)?.gatewayDomain;
8
+ }
9
+ function resolveGatewayDomain(cliService, override) {
10
+ if (override !== void 0) {
11
+ return override;
12
+ }
13
+ const route = cliServiceRoutes.get(cliService);
14
+ if (!route) {
15
+ throw new Error(
16
+ `Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
17
+ );
18
+ }
19
+ return route.gatewayDomain;
20
+ }
21
+
22
+ export {
23
+ registerCapabilityGatewayRoute,
24
+ findGatewayDomain,
25
+ resolveGatewayDomain
26
+ };
@@ -159,9 +159,18 @@ async function callGateway(host, domain, pathAfterV1, method, body) {
159
159
  }
160
160
  return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
161
161
  }
162
+ async function listCapabilities(host, domain) {
163
+ return callGateway(host, domain, "capabilities", "GET");
164
+ }
165
+ async function inspectCapability(host, domain, capabilityId) {
166
+ return callGateway(host, domain, `capabilities/${capabilityId}`, "GET");
167
+ }
162
168
  async function executeCapability(host, domain, capabilityId, input = {}) {
163
169
  return callGateway(host, domain, `capabilities/${capabilityId}/execute`, "POST", { input });
164
170
  }
171
+ async function dryRunCapability(host, domain, capabilityId, input = {}) {
172
+ return callGateway(host, domain, `capabilities/${capabilityId}/dry-run`, "POST", { input });
173
+ }
165
174
  async function uploadInputFile(host, domain, projectId, purpose, filePath) {
166
175
  const fileBytes = await readFile(filePath);
167
176
  return uploadInputFileBytes(host, domain, projectId, purpose, fileBytes, basename(filePath));
@@ -243,7 +252,10 @@ async function callCapabilityApi(host, domain, action, method = "POST", params =
243
252
  export {
244
253
  CapabilityGatewayError,
245
254
  buildCapabilityGatewayUrl,
255
+ listCapabilities,
256
+ inspectCapability,
246
257
  executeCapability,
258
+ dryRunCapability,
247
259
  uploadInputFile,
248
260
  uploadInputFileBytes,
249
261
  downloadCapabilityArtifact,
@@ -0,0 +1,26 @@
1
+ // src/core/capability-risk.ts
2
+ var HIGH_RISK_LEVELS = /* @__PURE__ */ new Set(["high-risk-write"]);
3
+ function normalizeRiskLevel(risk) {
4
+ switch (risk) {
5
+ case "read":
6
+ return "read";
7
+ case "high-risk-write":
8
+ return "high-risk-write";
9
+ case "delete":
10
+ return "high-risk-write";
11
+ case "create":
12
+ case "update":
13
+ case "write":
14
+ return "write";
15
+ default:
16
+ return "write";
17
+ }
18
+ }
19
+ function requiresConfirmation(risk) {
20
+ return HIGH_RISK_LEVELS.has(normalizeRiskLevel(risk));
21
+ }
22
+
23
+ export {
24
+ normalizeRiskLevel,
25
+ requiresConfirmation
26
+ };
@@ -1,25 +1,10 @@
1
+ import {
2
+ resolveGatewayDomain
3
+ } from "./chunk-CWZUGF2J.js";
1
4
  import {
2
5
  buildCapabilityGatewayUrl,
3
6
  executeCapability
4
- } from "./chunk-BXMXMUD7.js";
5
-
6
- // src/core/capability-routing.ts
7
- var cliServiceRoutes = /* @__PURE__ */ new Map();
8
- function registerCapabilityGatewayRoute(cliService, route) {
9
- cliServiceRoutes.set(cliService, route);
10
- }
11
- function resolveGatewayDomain(cliService, override) {
12
- if (override !== void 0) {
13
- return override;
14
- }
15
- const route = cliServiceRoutes.get(cliService);
16
- if (!route) {
17
- throw new Error(
18
- `Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
19
- );
20
- }
21
- return route.gatewayDomain;
22
- }
7
+ } from "./chunk-THBBNYXI.js";
23
8
 
24
9
  // src/core/capability-command.ts
25
10
  function createCapabilityCommand(config) {
@@ -53,7 +38,5 @@ function createCapabilityCommand(config) {
53
38
  }
54
39
 
55
40
  export {
56
- registerCapabilityGatewayRoute,
57
- resolveGatewayDomain,
58
41
  createCapabilityCommand
59
42
  };
@@ -1,25 +1,10 @@
1
+ import {
2
+ resolveGatewayDomain
3
+ } from "./chunk-CWZUGF2J.js";
1
4
  import {
2
5
  buildCapabilityGatewayUrl,
3
6
  executeCapability
4
- } from "./chunk-YNQFYBDB.js";
5
-
6
- // src/core/capability-routing.ts
7
- var cliServiceRoutes = /* @__PURE__ */ new Map();
8
- function registerCapabilityGatewayRoute(cliService, route) {
9
- cliServiceRoutes.set(cliService, route);
10
- }
11
- function resolveGatewayDomain(cliService, override) {
12
- if (override !== void 0) {
13
- return override;
14
- }
15
- const route = cliServiceRoutes.get(cliService);
16
- if (!route) {
17
- throw new Error(
18
- `Capability gateway route not registered for CLI service '${cliService}'. Call registerCapabilityGatewayRoute() in commands/${cliService}/index.ts.`
19
- );
20
- }
21
- return route.gatewayDomain;
22
- }
7
+ } from "./chunk-OJR23CIK.js";
23
8
 
24
9
  // src/core/capability-command.ts
25
10
  function createCapabilityCommand(config) {
@@ -53,7 +38,5 @@ function createCapabilityCommand(config) {
53
38
  }
54
39
 
55
40
  export {
56
- registerCapabilityGatewayRoute,
57
- resolveGatewayDomain,
58
41
  createCapabilityCommand
59
42
  };
@@ -162,9 +162,18 @@ async function callGateway(host, domain, pathAfterV1, method, body) {
162
162
  }
163
163
  return unwrapCapabilityEnvelope(parseCapabilityResponse(await resp.text()));
164
164
  }
165
+ async function listCapabilities(host, domain) {
166
+ return callGateway(host, domain, "capabilities", "GET");
167
+ }
168
+ async function inspectCapability(host, domain, capabilityId) {
169
+ return callGateway(host, domain, `capabilities/${capabilityId}`, "GET");
170
+ }
165
171
  async function executeCapability(host, domain, capabilityId, input = {}) {
166
172
  return callGateway(host, domain, `capabilities/${capabilityId}/execute`, "POST", { input });
167
173
  }
174
+ async function dryRunCapability(host, domain, capabilityId, input = {}) {
175
+ return callGateway(host, domain, `capabilities/${capabilityId}/dry-run`, "POST", { input });
176
+ }
168
177
  async function uploadInputFile(host, domain, projectId, purpose, filePath) {
169
178
  const fileBytes = await readFile(filePath);
170
179
  return uploadInputFileBytes(host, domain, projectId, purpose, fileBytes, basename(filePath));
@@ -246,7 +255,10 @@ async function callCapabilityApi(host, domain, action, method = "POST", params =
246
255
  export {
247
256
  CapabilityGatewayError,
248
257
  buildCapabilityGatewayUrl,
258
+ listCapabilities,
259
+ inspectCapability,
249
260
  executeCapability,
261
+ dryRunCapability,
250
262
  uploadInputFile,
251
263
  uploadInputFileBytes,
252
264
  downloadCapabilityArtifact,