@thinkingai/ae-cli 6.0.54 → 6.0.56
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.
- package/README.md +24 -3
- package/README.zh.md +24 -3
- package/dist/{auth-MBWRZTB6.js → auth-U7MNUUEF.js} +37 -13
- package/dist/{automation-NWWVLWG2.js → automation-K32V2NKP.js} +94 -38
- package/dist/{capability-7SSN6PNZ.js → capability-VV7RHB3B.js} +8 -7
- package/dist/{chunk-CT7QDJS6.js → chunk-2IYIYSUO.js} +2 -2
- package/dist/{chunk-PLE722AJ.js → chunk-2UWS5CUP.js} +62 -35
- package/dist/{chunk-ZIQWCZTS.js → chunk-3TQA5RXE.js} +3 -3
- package/dist/{chunk-KFNMQTZI.js → chunk-ELCR235M.js} +26 -19
- package/dist/{chunk-FMNNGNYO.js → chunk-F6NIPIT5.js} +7 -6
- package/dist/{chunk-D6ACFILC.js → chunk-GI5BMEZO.js} +1 -1
- package/dist/chunk-JJJIP2XQ.js +105 -0
- package/dist/{chunk-5XJYLEVC.js → chunk-KHS64JZQ.js} +4 -4
- package/dist/{chunk-UQ77JXYH.js → chunk-LMCYSVVA.js} +12 -13
- package/dist/{chunk-EOYSKMXN.js → chunk-MXV3PYC3.js} +14 -6
- package/dist/{chunk-7QXISROD.js → chunk-P6VFCH3P.js} +4 -2
- package/dist/{chunk-GIK6EDUG.js → chunk-P7KL7IOH.js} +41 -13
- package/dist/{chunk-AP7YP2NX.js → chunk-QSAR3GHY.js} +2 -2
- package/dist/{chunk-S6M42KND.js → chunk-T44M3PLZ.js} +1 -1
- package/dist/{chunk-HVHR4SCP.js → chunk-UUD5RB36.js} +3 -3
- package/dist/{chunk-HBLK3ZHW.js → chunk-W2PTY5NN.js} +3 -3
- package/dist/chunk-X7DRLE62.js +233 -0
- package/dist/{chunk-WNGFSIOB.js → chunk-ZW4VMY5H.js} +103 -6
- package/dist/{community-report-client-PEERQCX2.js → community-report-client-S2K3A3Q6.js} +1 -1
- package/dist/{config-FF6YVJKI.js → config-ASSAAIOI.js} +10 -9
- package/dist/{context-YAE3QXP3.js → context-6RWLVOM5.js} +4 -4
- package/dist/{data-integration-HESZET7E.js → data-integration-EXSUPUDZ.js} +6 -6
- package/dist/evaluation-5YT4QLCL.js +3714 -0
- package/dist/index.js +93 -49
- package/dist/{local-data-upload-client-TWMHFLUA.js → local-data-upload-client-7HCPGIS3.js} +1 -1
- package/dist/{memory-62BJOULV.js → memory-VCYLVPMI.js} +6 -6
- package/dist/{metadata-7CUMWIB4.js → metadata-TIWIOFTU.js} +8 -8
- package/dist/{model-SBV2JFJI.js → model-DPJHSD73.js} +4 -4
- package/dist/{personal-semantic-preference-6SRCYPGE.js → personal-semantic-preference-SBKU2LOK.js} +6 -6
- package/dist/{project-semantic-YYEM4OSU.js → project-semantic-SKNWLH3I.js} +6 -6
- package/dist/{sync-SU33KYX7.js → sync-7PP6KQ75.js} +7 -7
- package/dist/{te-agent-F5QBZSQA.js → te-agent-L2BYNPHM.js} +753 -94
- package/dist/{te-analysis-U4I2W2WC.js → te-analysis-RJB6VJC4.js} +411 -79
- package/dist/{te-community-PFLDLPP4.js → te-community-QN3WMPNT.js} +6 -4
- package/dist/{te-dataops-FOQSRIAZ.js → te-dataops-UKD2XN3E.js} +8 -6
- package/dist/{te-engage-ZX76CNAB.js → te-engage-KPTN4N2U.js} +6 -6
- package/dist/{te-kb-MHDOST62.js → te-kb-SFZI3W5T.js} +7 -7
- package/dist/{te-system-J2FQF5ER.js → te-system-IE7NCKC3.js} +10 -9
- package/dist/{te-team-5UOZPTU3.js → te-team-4KHCFM2I.js} +63 -41
- package/dist/{things-VPPXXLHB.js → things-7JJUVAWL.js} +7 -7
- package/dist/{update-EEUTEI6R.js → update-AX66IFMJ.js} +4 -4
- package/dist/{workspace-O3EEIYQM.js → workspace-Q5NMEKEN.js} +6 -6
- package/package.json +11 -7
- package/skills/ae-agent/SKILL.md +22 -3
- package/skills/ae-agent/references/command_index.md +8 -0
- package/skills/ae-agent/references/resource-package.md +53 -0
- package/skills/ae-analysis/SKILL.md +12 -3
- package/skills/ae-analysis/references/adhoc_export.md +1 -1
- package/skills/ae-analysis/references/agent_review_preflight.md +4 -0
- package/skills/ae-analysis/references/agent_review_submit_to_page.md +4 -0
- package/skills/ae-analysis/references/ai_models/event.md +58 -2
- package/skills/ae-analysis/references/ai_models/rank_list.md +1 -0
- package/skills/ae-analysis/references/ai_models/retention.md +2 -0
- package/skills/ae-analysis/references/ai_models/revenue.md +2 -0
- package/skills/ae-analysis/references/analysis_data_export.md +11 -1
- package/skills/ae-analysis/references/asset_batch_info_export.md +2 -2
- package/skills/ae-analysis/references/asset_batch_sql_export.md +2 -2
- package/skills/ae-analysis/references/asset_export.md +1 -1
- package/skills/ae-analysis/references/bi_panel_page_data_export.md +1 -1
- package/skills/ae-analysis/references/check_export.md +1 -1
- package/skills/ae-analysis/references/command_index.md +34 -25
- package/skills/ae-analysis/references/dashboard_report_data_export.md +2 -0
- package/skills/ae-analysis/references/dashboard_report_get.md +6 -2
- package/skills/ae-analysis/references/dashboard_report_update.md +24 -5
- package/skills/ae-analysis/references/feedback_submit.md +1 -1
- package/skills/ae-analysis/references/governance_recommendation_export.md +10 -2
- package/skills/ae-analysis/references/live_data_export.md +1 -1
- package/skills/ae-analysis/references/metric_create.md +29 -0
- package/skills/ae-analysis/references/metric_get.md +2 -0
- package/skills/ae-analysis/references/metric_update.md +2 -0
- package/skills/ae-analysis/references/operation_record_export.md +1 -1
- package/skills/ae-analysis/references/plan_change_log_export.md +1 -1
- package/skills/ae-analysis/references/plan_export.md +1 -1
- package/skills/ae-analysis/references/project_info_get.md +4 -0
- package/skills/ae-analysis/references/project_member_group_add_members.md +35 -0
- package/skills/ae-analysis/references/project_member_group_create.md +25 -0
- package/skills/ae-analysis/references/project_member_group_delete.md +34 -0
- package/skills/ae-analysis/references/project_member_group_list.md +29 -0
- package/skills/ae-analysis/references/project_member_group_members.md +28 -0
- package/skills/ae-analysis/references/project_member_group_remove_members.md +35 -0
- package/skills/ae-analysis/references/project_member_group_rename.md +26 -0
- package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +6 -1
- package/skills/ae-analysis/references/report_data_export.md +1 -1
- package/skills/ae-analysis/references/scenario_append.md +25 -0
- package/skills/ae-analysis/references/scenario_collect.md +35 -0
- package/skills/ae-analysis/references/scenario_evaluation.md +30 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +73 -4
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-schema.md +5 -1
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/execution-contract.mjs +173 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +109 -64
- package/skills/ae-automation/SKILL.md +2 -2
- package/skills/ae-automation/references/cli.md +18 -1
- package/skills/ae-capability/SKILL.md +7 -3
- package/skills/ae-evaluation/SKILL.md +83 -0
- package/skills/ae-evaluation/references/access-and-members.md +55 -0
- package/skills/ae-evaluation/references/connections.md +78 -0
- package/skills/ae-evaluation/references/datasets.md +57 -0
- package/skills/ae-evaluation/references/evaluators.md +81 -0
- package/skills/ae-evaluation/references/files.md +33 -0
- package/skills/ae-evaluation/references/integrations.md +39 -0
- package/skills/ae-evaluation/references/runs.md +160 -0
- package/skills/ae-evaluation/references/schedules.md +31 -0
- package/skills/ae-metadata/SKILL.md +2 -1
- package/skills/ae-metadata/references/metadata_data_table_download.md +7 -1
- package/skills/ae-metadata/references/metadata_data_table_get.md +2 -0
- package/skills/ae-team/SKILL.md +2 -2
- package/skills/ae-team/references/run-start.md +1 -0
- package/skills/ae-team/references/run-watch.md +7 -5
- package/skills/ae-things/SKILL.md +53 -51
- package/skills/ae-things/references/cli.md +56 -54
- package/skills/ae-things-progress/SKILL.md +20 -20
- package/skills/ae-things-review/SKILL.md +19 -19
- package/dist/chunk-4655PUNX.js +0 -43
|
@@ -3,14 +3,17 @@ import {
|
|
|
3
3
|
getActiveHost,
|
|
4
4
|
getConfigDir,
|
|
5
5
|
getFallbackCliToken,
|
|
6
|
-
|
|
6
|
+
readSandboxCliTokenEntry,
|
|
7
7
|
safeJsonParse,
|
|
8
8
|
safeReadJsonFile
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LMCYSVVA.js";
|
|
10
10
|
import {
|
|
11
11
|
PermissionError,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
externalCliTokenRequestOptions,
|
|
13
|
+
logger,
|
|
14
|
+
normalizeUrl,
|
|
15
|
+
readExternalCliToken
|
|
16
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
14
17
|
|
|
15
18
|
// src/core/secure-store.ts
|
|
16
19
|
import crypto from "crypto";
|
|
@@ -696,7 +699,8 @@ async function validateCliTokenOnServer(hostUrl, cliToken) {
|
|
|
696
699
|
try {
|
|
697
700
|
resp = await fetch(url, {
|
|
698
701
|
method: "GET",
|
|
699
|
-
headers: { Accept: "application/json", "cli-token": cliToken }
|
|
702
|
+
headers: { Accept: "application/json", "cli-token": cliToken },
|
|
703
|
+
...externalCliTokenRequestOptions(url)
|
|
700
704
|
});
|
|
701
705
|
} catch (error) {
|
|
702
706
|
throw new CliTokenValidationUnavailableError(`Unable to validate CLI token for ${hostUrl}: ${error.message}`);
|
|
@@ -734,10 +738,14 @@ async function validateCliTokenOnServer(hostUrl, cliToken) {
|
|
|
734
738
|
...cliTokenExpiresAt ? { cliTokenExpiresAt } : {}
|
|
735
739
|
};
|
|
736
740
|
}
|
|
737
|
-
async function renewCliTokenOnServer(hostUrl, cliToken) {
|
|
741
|
+
async function renewCliTokenOnServer(hostUrl, cliToken, external = false) {
|
|
738
742
|
const url = new URL(`${hostUrl.replace(/\/+$/, "")}${CLI_TOKEN_RENEW_PATH}`);
|
|
739
|
-
url.searchParams.set("cli-token", cliToken);
|
|
740
|
-
const resp = await fetch(url.toString(), {
|
|
743
|
+
if (!external) url.searchParams.set("cli-token", cliToken);
|
|
744
|
+
const resp = await fetch(url.toString(), {
|
|
745
|
+
method: "GET",
|
|
746
|
+
headers: { Accept: "application/json", ...external ? { "cli-token": cliToken } : {} },
|
|
747
|
+
...externalCliTokenRequestOptions(url.toString())
|
|
748
|
+
});
|
|
741
749
|
const text = await resp.text();
|
|
742
750
|
let data;
|
|
743
751
|
try {
|
|
@@ -750,10 +758,10 @@ async function renewCliTokenOnServer(hostUrl, cliToken) {
|
|
|
750
758
|
throw new Error(`CLI token renew error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
|
|
751
759
|
}
|
|
752
760
|
}
|
|
753
|
-
async function maybeRenewCliTokenDaily(hostUrl, cliToken) {
|
|
761
|
+
async function maybeRenewCliTokenDaily(hostUrl, cliToken, external = false) {
|
|
754
762
|
const key = renewKey(hostUrl, cliToken);
|
|
755
763
|
const today = localRenewDate();
|
|
756
|
-
if (renewedLocalDate.get(key) === today || persistedRenewDate(hostUrl, cliToken) === today) {
|
|
764
|
+
if (renewedLocalDate.get(key) === today || !external && persistedRenewDate(hostUrl, cliToken) === today) {
|
|
757
765
|
renewedLocalDate.set(key, today);
|
|
758
766
|
return;
|
|
759
767
|
}
|
|
@@ -761,11 +769,12 @@ async function maybeRenewCliTokenDaily(hostUrl, cliToken) {
|
|
|
761
769
|
if (existing) return existing;
|
|
762
770
|
const attempt = (async () => {
|
|
763
771
|
try {
|
|
764
|
-
await renewCliTokenOnServer(hostUrl, cliToken);
|
|
765
|
-
|
|
772
|
+
await renewCliTokenOnServer(hostUrl, cliToken, external);
|
|
773
|
+
if (external) renewedLocalDate.set(key, today);
|
|
774
|
+
else markRenewSucceeded(hostUrl, cliToken, today);
|
|
766
775
|
logger.info(`cli-token: renewed for ${normalizeUrl(hostUrl)} (local day ${today})`);
|
|
767
776
|
} catch (error) {
|
|
768
|
-
logger.warn(`cli-token: renew failed for ${normalizeUrl(hostUrl)}: ${error?.message || error}; business call proceeds`);
|
|
777
|
+
logger.warn(`cli-token: renew failed for ${normalizeUrl(hostUrl)}${external ? "" : `: ${error?.message || error}`}; business call proceeds`);
|
|
769
778
|
} finally {
|
|
770
779
|
renewInFlight.delete(key);
|
|
771
780
|
}
|
|
@@ -774,6 +783,9 @@ async function maybeRenewCliTokenDaily(hostUrl, cliToken) {
|
|
|
774
783
|
await attempt;
|
|
775
784
|
}
|
|
776
785
|
function peekCliToken(hostOverride) {
|
|
786
|
+
const external = readExternalCliToken(hostOverride);
|
|
787
|
+
if (external) return external.token;
|
|
788
|
+
if (process.env.TE_AGENT_CLI_CONFIG_DIR !== void 0) return sessionCliToken(hostOverride);
|
|
777
789
|
const hostUrl = hostOverride || getActiveHost();
|
|
778
790
|
if (!hostUrl) return void 0;
|
|
779
791
|
const normalizedHost = normalizeUrl(hostUrl);
|
|
@@ -791,6 +803,16 @@ function peekCliToken(hostOverride) {
|
|
|
791
803
|
return cliTokenCache.get(normalizedHost) || getFallbackCliToken(normalizedHost) || void 0;
|
|
792
804
|
}
|
|
793
805
|
async function getCliToken(hostOverride) {
|
|
806
|
+
const external = readExternalCliToken(hostOverride);
|
|
807
|
+
if (external) {
|
|
808
|
+
await maybeRenewCliTokenDaily(external.url, external.token, true);
|
|
809
|
+
return external.token;
|
|
810
|
+
}
|
|
811
|
+
if (process.env.TE_AGENT_CLI_CONFIG_DIR !== void 0) {
|
|
812
|
+
const token2 = sessionCliToken(hostOverride);
|
|
813
|
+
if (!token2) throw new SecureStoreAuthError("Current session CLI credential is unavailable or does not match the requested host.");
|
|
814
|
+
return token2;
|
|
815
|
+
}
|
|
794
816
|
const resolvedHost = hostOverride || getActiveHost();
|
|
795
817
|
if (!resolvedHost) throw new SecureStoreAuthError("No AE host configured. Run: ae-cli auth login --host <url>");
|
|
796
818
|
const hostUrl = normalizeUrl(resolvedHost);
|
|
@@ -803,6 +825,12 @@ async function getCliToken(hostOverride) {
|
|
|
803
825
|
await maybeRenewCliTokenDaily(hostUrl, token);
|
|
804
826
|
return token;
|
|
805
827
|
}
|
|
828
|
+
function sessionCliToken(hostOverride) {
|
|
829
|
+
const entry = readSandboxCliTokenEntry();
|
|
830
|
+
if (!entry?.token.startsWith("cli_")) return void 0;
|
|
831
|
+
if (hostOverride && normalizeUrl(entry.url) !== normalizeUrl(hostOverride)) return void 0;
|
|
832
|
+
return entry.token;
|
|
833
|
+
}
|
|
806
834
|
async function mintCliToken(hostUrl, accessToken) {
|
|
807
835
|
logger.info(`Generating CLI token for ${hostUrl}`);
|
|
808
836
|
const cliToken = await generateCliToken(hostUrl, accessToken);
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
require_node,
|
|
6
6
|
require_process_nextick_args,
|
|
7
7
|
require_util
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-T44M3PLZ.js";
|
|
9
9
|
import {
|
|
10
10
|
__commonJS,
|
|
11
11
|
__esm,
|
|
12
12
|
__export,
|
|
13
13
|
__require,
|
|
14
14
|
__toCommonJS
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
16
16
|
|
|
17
17
|
// node_modules/readdir-glob/node_modules/minimatch/lib/path.js
|
|
18
18
|
var require_path = __commonJS({
|
|
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from 'node:module'; const require =
|
|
|
2
2
|
import {
|
|
3
3
|
__commonJS,
|
|
4
4
|
__require
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
6
6
|
|
|
7
7
|
// node_modules/process-nextick-args/index.js
|
|
8
8
|
var require_process_nextick_args = __commonJS({
|
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
postAgentApi,
|
|
10
10
|
putAgentApi,
|
|
11
11
|
uploadAgentApi
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JJJIP2XQ.js";
|
|
13
13
|
import {
|
|
14
14
|
TeAgentApiError,
|
|
15
15
|
createTeAgentApiError
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2UWS5CUP.js";
|
|
17
17
|
import {
|
|
18
18
|
CliValidationError,
|
|
19
19
|
isApiErrorType
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
21
21
|
|
|
22
22
|
// src/commands/workspace/client.ts
|
|
23
23
|
var DEFAULT_TE_CLAUDE_BASE_PATH = "/agent";
|
|
@@ -6,15 +6,15 @@ import {
|
|
|
6
6
|
CapabilityGatewayError,
|
|
7
7
|
fetchCapabilityGateway,
|
|
8
8
|
requestCapabilityGateway
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MXV3PYC3.js";
|
|
10
10
|
import {
|
|
11
11
|
readOutputMetadata,
|
|
12
12
|
unwrapOutputData,
|
|
13
13
|
withOutputMetadata
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-ELCR235M.js";
|
|
15
15
|
import {
|
|
16
16
|
PermissionError
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
18
18
|
|
|
19
19
|
// src/core/analysis-async-artifact.ts
|
|
20
20
|
import { randomBytes } from "crypto";
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
CliValidationError,
|
|
4
|
+
logger
|
|
5
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
6
|
+
|
|
7
|
+
// src/core/eval-endpoint.ts
|
|
8
|
+
function resolveEvaluationHost(host) {
|
|
9
|
+
let endpoint;
|
|
10
|
+
try {
|
|
11
|
+
endpoint = new URL(host);
|
|
12
|
+
if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash || /[?#\s]/.test(host)) throw new Error();
|
|
13
|
+
} catch {
|
|
14
|
+
throw new CliValidationError("Evaluation AE Host must be an absolute HTTP(S) URL without credentials, query, or fragment.", {
|
|
15
|
+
code: "EVAL_ENDPOINT_INVALID"
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const hostname = endpoint.hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.$/, "");
|
|
19
|
+
const mappedIpv4 = /^::ffff:([0-9a-f]+):[0-9a-f]+$/.exec(hostname);
|
|
20
|
+
if (hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "::1" || hostname === "::" || hostname === "0.0.0.0" || hostname.startsWith("127.") || mappedIpv4 && parseInt(mappedIpv4[1], 16) >> 8 === 127 || hostname === "::ffff:0:0") {
|
|
21
|
+
throw new CliValidationError("Loopback evaluation endpoints are unsupported.", {
|
|
22
|
+
code: "EVAL_ENDPOINT_LOOPBACK_UNSUPPORTED",
|
|
23
|
+
hint: "Select an online AE Host with --host."
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (endpoint.protocol !== "http:" && endpoint.protocol !== "https:") {
|
|
27
|
+
throw new CliValidationError("Evaluation AE Host must use HTTP or HTTPS.", {
|
|
28
|
+
code: "EVAL_ENDPOINT_INVALID"
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return endpoint.toString().replace(/\/+$/, "").replace(/\/agent$/, "");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/core/eval-client.ts
|
|
35
|
+
import { open, unlink } from "fs/promises";
|
|
36
|
+
import { resolve } from "path";
|
|
37
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
38
|
+
var EvalApiError = class extends Error {
|
|
39
|
+
code;
|
|
40
|
+
httpStatus;
|
|
41
|
+
hint;
|
|
42
|
+
details;
|
|
43
|
+
constructor(message, options) {
|
|
44
|
+
const redact = evaluationErrorRedactor([
|
|
45
|
+
...options.sensitiveValues ?? [],
|
|
46
|
+
process.env.AE_EVAL_ACCESS_TOKEN ?? ""
|
|
47
|
+
]);
|
|
48
|
+
super(redact(message));
|
|
49
|
+
this.name = "EvalApiError";
|
|
50
|
+
this.code = options.code;
|
|
51
|
+
this.httpStatus = options.httpStatus;
|
|
52
|
+
this.hint = options.hint === void 0 ? void 0 : redact(options.hint);
|
|
53
|
+
this.details = options.details === void 0 ? void 0 : redact(options.details);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
function evaluationErrorRedactor(secrets) {
|
|
57
|
+
const forms = [...new Set(secrets.filter(Boolean).flatMap((secret) => [
|
|
58
|
+
secret,
|
|
59
|
+
JSON.stringify(secret).slice(1, -1),
|
|
60
|
+
encodeURIComponent(secret)
|
|
61
|
+
]))].sort((a, b) => b.length - a.length);
|
|
62
|
+
const redact = (value) => {
|
|
63
|
+
if (typeof value === "string") {
|
|
64
|
+
for (const secret of forms) value = value.split(secret).join("[REDACTED]");
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(value)) return value.map(redact);
|
|
68
|
+
if (value && typeof value === "object") {
|
|
69
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [redact(key), redact(item)]));
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
};
|
|
73
|
+
return redact;
|
|
74
|
+
}
|
|
75
|
+
async function evalRequest(options) {
|
|
76
|
+
const url = buildEvalUrl(options.baseUrl, options.path, options.params);
|
|
77
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
78
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
81
|
+
const headers = {
|
|
82
|
+
...options.headers,
|
|
83
|
+
Accept: options.responseType === "bytes" ? "application/octet-stream, application/json" : "application/json"
|
|
84
|
+
};
|
|
85
|
+
const isMultipart = options.body instanceof FormData;
|
|
86
|
+
if (options.body !== void 0 && !isMultipart) {
|
|
87
|
+
headers["Content-Type"] = "application/json";
|
|
88
|
+
}
|
|
89
|
+
if (options.idempotencyKey) {
|
|
90
|
+
headers["Idempotency-Key"] = options.idempotencyKey;
|
|
91
|
+
}
|
|
92
|
+
let response;
|
|
93
|
+
let responseText = "";
|
|
94
|
+
let bytes;
|
|
95
|
+
try {
|
|
96
|
+
response = await fetchImpl(url, {
|
|
97
|
+
method: options.method,
|
|
98
|
+
headers,
|
|
99
|
+
body: options.body === void 0 ? void 0 : options.body instanceof FormData ? options.body : JSON.stringify(options.body),
|
|
100
|
+
redirect: "error",
|
|
101
|
+
signal: controller.signal
|
|
102
|
+
});
|
|
103
|
+
if (response.ok && options.responseType === "bytes") {
|
|
104
|
+
bytes = new Uint8Array(await response.arrayBuffer());
|
|
105
|
+
} else {
|
|
106
|
+
responseText = await response.text();
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
const timedOut = controller.signal.aborted || error instanceof Error && error.name === "AbortError";
|
|
110
|
+
logEvalRequest(options.method, url, response?.status ?? "unavailable");
|
|
111
|
+
if (timedOut) {
|
|
112
|
+
throw new EvalApiError(`Evaluation API request timed out after ${timeoutMs} ms.`, {
|
|
113
|
+
code: "EVAL_API_TIMEOUT",
|
|
114
|
+
httpStatus: 0,
|
|
115
|
+
hint: "Verify the evaluation platform is reachable at the configured endpoint."
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
throw new EvalApiError("Evaluation API request failed before a response was received.", {
|
|
119
|
+
code: "EVAL_API_NETWORK_ERROR",
|
|
120
|
+
httpStatus: 0,
|
|
121
|
+
hint: "Verify the --endpoint URL and network path."
|
|
122
|
+
});
|
|
123
|
+
} finally {
|
|
124
|
+
clearTimeout(timeout);
|
|
125
|
+
}
|
|
126
|
+
logEvalRequest(options.method, url, response.status);
|
|
127
|
+
if (bytes !== void 0) return bytes;
|
|
128
|
+
const responseBody = parseEvalResponseBody(responseText, response.status);
|
|
129
|
+
if (!response.ok) {
|
|
130
|
+
const sensitiveValues = Object.values(options.headers).flatMap((value) => [value, value.replace(/^Bearer\s+/i, "")]);
|
|
131
|
+
if (isRecord(options.body)) {
|
|
132
|
+
for (const key of ["secret", "data_token", "report_source"]) {
|
|
133
|
+
if (typeof options.body[key] === "string") sensitiveValues.push(options.body[key]);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
throw evalErrorFromBody(responseBody, response.status, sensitiveValues);
|
|
137
|
+
}
|
|
138
|
+
return responseBody;
|
|
139
|
+
}
|
|
140
|
+
async function evalDownloadFile(options, outputPath) {
|
|
141
|
+
const path = resolve(outputPath);
|
|
142
|
+
let file;
|
|
143
|
+
try {
|
|
144
|
+
file = await open(path, "wx", 384);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
if (error.code === "EEXIST") {
|
|
147
|
+
throw new CliValidationError("Output file already exists; choose a new --output path.", {
|
|
148
|
+
code: "EVAL_OUTPUT_EXISTS"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
let completed = false;
|
|
154
|
+
try {
|
|
155
|
+
const bytes = await evalRequest({ ...options, responseType: "bytes" });
|
|
156
|
+
await file.writeFile(bytes);
|
|
157
|
+
completed = true;
|
|
158
|
+
return { path, byte_size: bytes.byteLength };
|
|
159
|
+
} finally {
|
|
160
|
+
await file.close();
|
|
161
|
+
if (!completed) await unlink(path);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function buildEvalUrl(baseUrl, path, params) {
|
|
165
|
+
const base = resolveEvaluationHost(baseUrl);
|
|
166
|
+
const url = new URL(`${base}${path}`);
|
|
167
|
+
if (params) {
|
|
168
|
+
for (const [key, value] of Object.entries(params)) {
|
|
169
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
170
|
+
url.searchParams.set(key, String(value));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return url.toString();
|
|
174
|
+
}
|
|
175
|
+
function parseEvalResponseBody(text, httpStatus) {
|
|
176
|
+
if (!text.trim()) {
|
|
177
|
+
if (httpStatus === 204) return void 0;
|
|
178
|
+
throw new EvalApiError("Evaluation API returned an empty response body.", {
|
|
179
|
+
code: "EVAL_API_INVALID_RESPONSE",
|
|
180
|
+
httpStatus
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
return JSON.parse(text);
|
|
185
|
+
} catch {
|
|
186
|
+
throw new EvalApiError("Evaluation API returned a non-JSON response body.", {
|
|
187
|
+
code: "EVAL_API_INVALID_RESPONSE",
|
|
188
|
+
httpStatus
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function evalErrorFromBody(body, httpStatus, sensitiveValues) {
|
|
193
|
+
const error = body?.error;
|
|
194
|
+
if (isRecord(error) && typeof error.message === "string" && error.message.trim()) {
|
|
195
|
+
return new EvalApiError(error.message.trim(), {
|
|
196
|
+
code: typeof error.code === "string" && /^[A-Z][A-Z0-9_]{0,127}$/.test(error.code) ? error.code : `EVAL_API_HTTP_${httpStatus}`,
|
|
197
|
+
httpStatus,
|
|
198
|
+
hint: typeof error.details === "string" ? error.details : void 0,
|
|
199
|
+
details: isRecord(error.details) ? error.details : void 0,
|
|
200
|
+
sensitiveValues
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return new EvalApiError(`Evaluation API returned HTTP ${httpStatus}.`, {
|
|
204
|
+
code: `EVAL_API_HTTP_${httpStatus}`,
|
|
205
|
+
httpStatus,
|
|
206
|
+
hint: httpStatus >= 500 ? "The server response was suppressed. Check the evaluation platform logs; the CLI did not retry." : void 0
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function isRecord(value) {
|
|
210
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
211
|
+
}
|
|
212
|
+
function logEvalRequest(method, url, status) {
|
|
213
|
+
logger.info(`EVAL ${method} ${redactEvalLogUrl(url)} status=${status}`);
|
|
214
|
+
}
|
|
215
|
+
function redactEvalLogUrl(url) {
|
|
216
|
+
try {
|
|
217
|
+
const parsed = new URL(url);
|
|
218
|
+
parsed.username = "";
|
|
219
|
+
parsed.password = "";
|
|
220
|
+
parsed.search = "";
|
|
221
|
+
parsed.hash = "";
|
|
222
|
+
return parsed.toString();
|
|
223
|
+
} catch {
|
|
224
|
+
return "[invalid evaluation URL]";
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export {
|
|
229
|
+
resolveEvaluationHost,
|
|
230
|
+
EvalApiError,
|
|
231
|
+
evalRequest,
|
|
232
|
+
evalDownloadFile
|
|
233
|
+
};
|
|
@@ -48,8 +48,97 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
48
48
|
));
|
|
49
49
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
50
50
|
|
|
51
|
-
// src/core/
|
|
51
|
+
// src/core/url-utils.ts
|
|
52
|
+
function normalizeUrl(url) {
|
|
53
|
+
if (!url) return url;
|
|
54
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
55
|
+
url = `https://${url}`;
|
|
56
|
+
}
|
|
57
|
+
return url.replace(/\/$/, "");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/core/external-cli-token.ts
|
|
52
61
|
import fs from "fs";
|
|
62
|
+
var ExternalCliTokenError = class extends Error {
|
|
63
|
+
constructor(message, code = "EXTERNAL_CLI_TOKEN_INVALID") {
|
|
64
|
+
super(message);
|
|
65
|
+
this.code = code;
|
|
66
|
+
this.name = "ExternalCliTokenError";
|
|
67
|
+
}
|
|
68
|
+
code;
|
|
69
|
+
hint = "Set AE_CLI_TOKEN with AE_CLI_TOKEN_HOST, or use a JSON CLI token file containing url and token. Remove external token settings to use stored accounts.";
|
|
70
|
+
};
|
|
71
|
+
var explicitTokenFile;
|
|
72
|
+
var diagnosticSecrets = /* @__PURE__ */ new Set();
|
|
73
|
+
function setExternalCliTokenFile(file) {
|
|
74
|
+
explicitTokenFile = file;
|
|
75
|
+
}
|
|
76
|
+
function normalizedHost(value) {
|
|
77
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
78
|
+
throw new ExternalCliTokenError("The external CLI token requires a host URL.");
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const url = new URL(value);
|
|
82
|
+
if (!["http:", "https:"].includes(url.protocol) || !url.hostname || url.username || url.password || url.search || url.hash || /\s/.test(value)) throw new Error();
|
|
83
|
+
return normalizeUrl(url.toString());
|
|
84
|
+
} catch {
|
|
85
|
+
throw new ExternalCliTokenError("The external CLI token host must be an HTTP(S) URL without credentials, query, or fragment.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function credential(url, value, source) {
|
|
89
|
+
if (typeof value !== "string" || !/^cli_[!-~]+$/.test(value.trim())) {
|
|
90
|
+
throw new ExternalCliTokenError("The external CLI token must be a non-empty ASCII cli_ token without whitespace.");
|
|
91
|
+
}
|
|
92
|
+
return { url: normalizedHost(url), token: value.trim(), source };
|
|
93
|
+
}
|
|
94
|
+
function readExternalCliToken(hostOverride) {
|
|
95
|
+
let entry;
|
|
96
|
+
const file = explicitTokenFile ?? (process.env.AE_CLI_TOKEN === void 0 ? process.env.AE_CLI_TOKEN_FILE : void 0);
|
|
97
|
+
if (file !== void 0) {
|
|
98
|
+
if (!file.trim()) throw new ExternalCliTokenError("The external CLI token file path is empty.");
|
|
99
|
+
let data;
|
|
100
|
+
try {
|
|
101
|
+
const stat = fs.statSync(file);
|
|
102
|
+
if (!stat.isFile() || stat.size > 64 * 1024) throw new Error();
|
|
103
|
+
data = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
104
|
+
} catch {
|
|
105
|
+
throw new ExternalCliTokenError("The external CLI token file must be a readable JSON file no larger than 64 KiB.");
|
|
106
|
+
}
|
|
107
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
108
|
+
throw new ExternalCliTokenError("The external CLI token file must contain an object with url and token.");
|
|
109
|
+
}
|
|
110
|
+
entry = credential(data.url, data.token ?? data["cli-token"], "file-cli-token");
|
|
111
|
+
} else if (process.env.AE_CLI_TOKEN !== void 0) {
|
|
112
|
+
entry = credential(process.env.AE_CLI_TOKEN_HOST, process.env.AE_CLI_TOKEN, "environment-cli-token");
|
|
113
|
+
} else if (process.env.AE_CLI_TOKEN_HOST !== void 0) {
|
|
114
|
+
throw new ExternalCliTokenError("AE_CLI_TOKEN_HOST requires AE_CLI_TOKEN.");
|
|
115
|
+
}
|
|
116
|
+
if (entry && hostOverride && normalizedHost(hostOverride) !== entry.url) {
|
|
117
|
+
throw new ExternalCliTokenError("The selected host does not match the external CLI token host.");
|
|
118
|
+
}
|
|
119
|
+
if (entry) diagnosticSecrets.add(entry.token);
|
|
120
|
+
return entry;
|
|
121
|
+
}
|
|
122
|
+
function externalCliTokenRequestOptions(destination) {
|
|
123
|
+
const external = readExternalCliToken();
|
|
124
|
+
if (!external) return {};
|
|
125
|
+
if (new URL(destination).origin !== new URL(external.url).origin) {
|
|
126
|
+
throw new ExternalCliTokenError("The request destination does not match the external CLI token host.");
|
|
127
|
+
}
|
|
128
|
+
return { redirect: "error" };
|
|
129
|
+
}
|
|
130
|
+
function redactExternalCliToken(value) {
|
|
131
|
+
try {
|
|
132
|
+
readExternalCliToken();
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
const forms = [...diagnosticSecrets].flatMap((token) => [token, JSON.stringify(token).slice(1, -1), encodeURIComponent(token)]);
|
|
136
|
+
for (const form of [...new Set(forms)].sort((a, b) => b.length - a.length)) value = value.split(form).join("[REDACTED]");
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/core/logger.ts
|
|
141
|
+
import fs2 from "fs";
|
|
53
142
|
import path from "path";
|
|
54
143
|
var LOG_DIR = path.join(process.env.HOME || "", ".ae-cli", "log");
|
|
55
144
|
var Logger = class {
|
|
@@ -68,8 +157,8 @@ var Logger = class {
|
|
|
68
157
|
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").split(".")[0];
|
|
69
158
|
}
|
|
70
159
|
ensureDir() {
|
|
71
|
-
if (!
|
|
72
|
-
|
|
160
|
+
if (!fs2.existsSync(this.logDir)) {
|
|
161
|
+
fs2.mkdirSync(this.logDir, { recursive: true });
|
|
73
162
|
}
|
|
74
163
|
}
|
|
75
164
|
filePath(level) {
|
|
@@ -84,10 +173,10 @@ var Logger = class {
|
|
|
84
173
|
*/
|
|
85
174
|
write(level, message) {
|
|
86
175
|
const ts = this.timestamp();
|
|
87
|
-
const line = `[${ts}] ${message}
|
|
176
|
+
const line = `[${ts}] ${redactExternalCliToken(message)}
|
|
88
177
|
`;
|
|
89
178
|
try {
|
|
90
|
-
|
|
179
|
+
fs2.appendFileSync(this.filePath(level), line);
|
|
91
180
|
} catch {
|
|
92
181
|
}
|
|
93
182
|
}
|
|
@@ -133,16 +222,18 @@ var logger = new Logger();
|
|
|
133
222
|
|
|
134
223
|
// src/core/errors.ts
|
|
135
224
|
var PermissionError = class extends Error {
|
|
136
|
-
constructor(message, code, hint, details) {
|
|
225
|
+
constructor(message, code, hint, details, meta) {
|
|
137
226
|
super(message);
|
|
138
227
|
this.code = code;
|
|
139
228
|
this.hint = hint;
|
|
140
229
|
this.details = details;
|
|
230
|
+
this.meta = meta;
|
|
141
231
|
this.name = "PermissionError";
|
|
142
232
|
}
|
|
143
233
|
code;
|
|
144
234
|
hint;
|
|
145
235
|
details;
|
|
236
|
+
meta;
|
|
146
237
|
};
|
|
147
238
|
function isApiErrorType(value) {
|
|
148
239
|
return value === "auth" || value === "permission" || value === "validation" || value === "not_found" || value === "api";
|
|
@@ -219,6 +310,12 @@ export {
|
|
|
219
310
|
__export,
|
|
220
311
|
__toESM,
|
|
221
312
|
__toCommonJS,
|
|
313
|
+
normalizeUrl,
|
|
314
|
+
ExternalCliTokenError,
|
|
315
|
+
setExternalCliTokenFile,
|
|
316
|
+
readExternalCliToken,
|
|
317
|
+
externalCliTokenRequestOptions,
|
|
318
|
+
redactExternalCliToken,
|
|
222
319
|
logger,
|
|
223
320
|
PermissionError,
|
|
224
321
|
isApiErrorType,
|
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
AE_TRIAL_URL,
|
|
4
|
-
missingAeHostHint
|
|
5
|
-
} from "./chunk-6ZIQV5GW.js";
|
|
6
2
|
import {
|
|
7
3
|
MultiselectCancelled,
|
|
8
4
|
promptSingleSelect
|
|
9
5
|
} from "./chunk-7K24F7T2.js";
|
|
6
|
+
import {
|
|
7
|
+
AE_TRIAL_URL,
|
|
8
|
+
missingAeHostHint
|
|
9
|
+
} from "./chunk-6ZIQV5GW.js";
|
|
10
10
|
import {
|
|
11
11
|
fetchCliConfig,
|
|
12
12
|
printError,
|
|
13
13
|
printOutput,
|
|
14
14
|
resolveKbAutoDiscoveryFeature
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ELCR235M.js";
|
|
16
16
|
import {
|
|
17
17
|
peekCliToken
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-P7KL7IOH.js";
|
|
19
19
|
import {
|
|
20
20
|
addHost,
|
|
21
21
|
getActiveHost,
|
|
22
22
|
listHosts,
|
|
23
23
|
loadConfig,
|
|
24
|
-
normalizeUrl,
|
|
25
24
|
removeHost,
|
|
26
25
|
resolveHostSelector,
|
|
27
26
|
setActiveHost,
|
|
28
27
|
updateHostLabel
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import
|
|
28
|
+
} from "./chunk-LMCYSVVA.js";
|
|
29
|
+
import {
|
|
30
|
+
normalizeUrl
|
|
31
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
31
32
|
|
|
32
33
|
// src/commands/config.ts
|
|
33
34
|
import * as readline2 from "readline";
|
|
@@ -2,15 +2,15 @@ import { createRequire as __createRequire } from 'node:module'; const require =
|
|
|
2
2
|
import {
|
|
3
3
|
TeAgentApiError,
|
|
4
4
|
getFromMainApp
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2UWS5CUP.js";
|
|
6
6
|
import "./chunk-Y74WTIKJ.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-P7KL7IOH.js";
|
|
8
8
|
import {
|
|
9
9
|
safeJsonParse
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LMCYSVVA.js";
|
|
11
11
|
import {
|
|
12
12
|
CliValidationError
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
14
14
|
|
|
15
15
|
// src/core/current-page-context-client.ts
|
|
16
16
|
async function readCurrentPageContext(path) {
|
|
@@ -8,20 +8,20 @@ import {
|
|
|
8
8
|
utils,
|
|
9
9
|
validateAndFix,
|
|
10
10
|
validateDraft
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-KHS64JZQ.js";
|
|
12
|
+
import "./chunk-2IYIYSUO.js";
|
|
13
13
|
import {
|
|
14
14
|
require_archiver
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-QSAR3GHY.js";
|
|
16
|
+
import "./chunk-T44M3PLZ.js";
|
|
17
17
|
import {
|
|
18
18
|
getConfigDir
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-LMCYSVVA.js";
|
|
20
20
|
import {
|
|
21
21
|
CliValidationError,
|
|
22
22
|
LocalDataUploadError,
|
|
23
23
|
__toESM
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-ZW4VMY5H.js";
|
|
25
25
|
|
|
26
26
|
// src/commands/data-integration/inspect.ts
|
|
27
27
|
import { basename as basename3 } from "path";
|