@aexhq/cli 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +165 -5
- package/dist/cli.mjs.sha256 +1 -1
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -126,6 +126,34 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
126
126
|
runtimeEvidence: {
|
|
127
127
|
managed: COMMON_EVIDENCE
|
|
128
128
|
}
|
|
129
|
+
},
|
|
130
|
+
// Doubao (ByteDance) via the official Ark API — international BytePlus gateway.
|
|
131
|
+
// Wired + parser/routing-verified but not yet proven against a live BytePlus
|
|
132
|
+
// account, so `live-unverified`. Promote to `supported` (and swap COMMON_EVIDENCE
|
|
133
|
+
// for a DOUBAO_MANAGED_EVIDENCE pointer to live-sdk-doubao.test.ts) once the
|
|
134
|
+
// live run passes.
|
|
135
|
+
doubao: {
|
|
136
|
+
displayName: "Doubao",
|
|
137
|
+
status: "live-unverified",
|
|
138
|
+
docsAnchor: "doubao",
|
|
139
|
+
docs: COMMON_DOCS,
|
|
140
|
+
evidence: COMMON_EVIDENCE,
|
|
141
|
+
runtimeEvidence: {
|
|
142
|
+
managed: COMMON_EVIDENCE
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
// Doubao (ByteDance) via the official Ark API — China Volcengine gateway.
|
|
146
|
+
// Same wiring as `doubao`; additionally gated on CF Worker egress reaching the
|
|
147
|
+
// Beijing host (see apps/egress-probe). `live-unverified` until proven live.
|
|
148
|
+
"doubao-cn": {
|
|
149
|
+
displayName: "Doubao (China)",
|
|
150
|
+
status: "live-unverified",
|
|
151
|
+
docsAnchor: "doubao-cn",
|
|
152
|
+
docs: COMMON_DOCS,
|
|
153
|
+
evidence: COMMON_EVIDENCE,
|
|
154
|
+
runtimeEvidence: {
|
|
155
|
+
managed: COMMON_EVIDENCE
|
|
156
|
+
}
|
|
129
157
|
}
|
|
130
158
|
};
|
|
131
159
|
|
|
@@ -144,7 +172,21 @@ var MODEL_PROVIDER_IDS = {
|
|
|
144
172
|
"gemini-2.0-flash": { gemini: "gemini-2.0-flash", openrouter: "google/gemini-2.0-flash-001" },
|
|
145
173
|
"gemini-2.5-flash": { gemini: "gemini-2.5-flash" },
|
|
146
174
|
"mistral-large-latest": { mistral: "mistral-large-latest" },
|
|
147
|
-
"mistral-small-latest": { mistral: "mistral-small-latest" }
|
|
175
|
+
"mistral-small-latest": { mistral: "mistral-small-latest" },
|
|
176
|
+
// Doubao (ByteDance) via the official Ark API. Served by both the
|
|
177
|
+
// international BytePlus ModelArk gateway (`doubao`, the default) and the
|
|
178
|
+
// China Volcengine Ark gateway (`doubao-cn`). Ark accepts the API-format
|
|
179
|
+
// model NAME directly in the chat-completions `model` field (no `ep-…`
|
|
180
|
+
// inference-endpoint id). The native strings are the same Ark catalog ids on
|
|
181
|
+
// both gateways; BytePlus per-account availability is confirmed at live-verify
|
|
182
|
+
// (both providers ship `live-unverified` until then — provider-support.ts).
|
|
183
|
+
// pro — Doubao Seed 1.8 (flagship, 256K context).
|
|
184
|
+
// flash — Doubao Seed 1.6 Flash (fast/cheap, 256K context).
|
|
185
|
+
"doubao-seed-pro": { doubao: "doubao-seed-1-8-251228", "doubao-cn": "doubao-seed-1-8-251228" },
|
|
186
|
+
"doubao-seed-flash": {
|
|
187
|
+
doubao: "doubao-seed-1-6-flash-250828",
|
|
188
|
+
"doubao-cn": "doubao-seed-1-6-flash-250828"
|
|
189
|
+
}
|
|
148
190
|
};
|
|
149
191
|
var RUN_MODELS = Object.keys(MODEL_PROVIDER_IDS);
|
|
150
192
|
var PROVIDERS_BY_MODEL = (() => {
|
|
@@ -743,7 +785,9 @@ var RUN_PROVIDERS = [
|
|
|
743
785
|
"openai",
|
|
744
786
|
"gemini",
|
|
745
787
|
"mistral",
|
|
746
|
-
"openrouter"
|
|
788
|
+
"openrouter",
|
|
789
|
+
"doubao",
|
|
790
|
+
"doubao-cn"
|
|
747
791
|
];
|
|
748
792
|
var DEFAULT_RUN_PROVIDER = "anthropic";
|
|
749
793
|
var RUNTIME_KINDS = ["managed"];
|
|
@@ -794,7 +838,7 @@ function visitCustodyValue(input, path, findings) {
|
|
|
794
838
|
}
|
|
795
839
|
function scanStringValue(value, path, findings) {
|
|
796
840
|
for (const pattern of forbiddenStringPatterns) {
|
|
797
|
-
if (pattern
|
|
841
|
+
if (matchesForbiddenPattern(pattern, value)) {
|
|
798
842
|
findings.push(Object.freeze({
|
|
799
843
|
path,
|
|
800
844
|
reason: pattern.reason,
|
|
@@ -803,11 +847,32 @@ function scanStringValue(value, path, findings) {
|
|
|
803
847
|
}
|
|
804
848
|
}
|
|
805
849
|
}
|
|
850
|
+
function matchesForbiddenPattern(pattern, value) {
|
|
851
|
+
if (!pattern.accept) {
|
|
852
|
+
return pattern.regex.test(value);
|
|
853
|
+
}
|
|
854
|
+
const scan = pattern.regex.global ? pattern.regex : new RegExp(pattern.regex.source, `${pattern.regex.flags}g`);
|
|
855
|
+
scan.lastIndex = 0;
|
|
856
|
+
let match;
|
|
857
|
+
while ((match = scan.exec(value)) !== null) {
|
|
858
|
+
if (pattern.accept(match[0])) {
|
|
859
|
+
return true;
|
|
860
|
+
}
|
|
861
|
+
if (match.index === scan.lastIndex) {
|
|
862
|
+
scan.lastIndex++;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
806
867
|
var forbiddenStringPatterns = Object.freeze([
|
|
807
868
|
{ reason: "bearer_token", regex: /\bBearer\s+[A-Za-z0-9._~+/=-]{8,}/i },
|
|
808
869
|
{
|
|
809
870
|
reason: "provider_key",
|
|
810
|
-
|
|
871
|
+
// Prefixed provider keys (`sk-…`, Slack `xox*-…`, Google `AIza…`). The bare
|
|
872
|
+
// `sk-` body is intentionally generic so an unrecognised vendor's `sk-` key
|
|
873
|
+
// (e.g. DeepSeek `sk-<hex>`, OpenRouter `sk-or-…`) is still caught by shape,
|
|
874
|
+
// not left to the narrowed entropy catch-all below.
|
|
875
|
+
regex: /\b(?:sk-[A-Za-z0-9_-]{16,}|xox[baprs]-[A-Za-z0-9-]{8,}|AIza[A-Za-z0-9_-]{8,})/i
|
|
811
876
|
},
|
|
812
877
|
{ reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
|
|
813
878
|
{ reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
|
|
@@ -816,8 +881,59 @@ var forbiddenStringPatterns = Object.freeze([
|
|
|
816
881
|
reason: "private_resource_handle",
|
|
817
882
|
regex: /\b(?:machine|session|agent|file|skill|env|resource|handle|token_hash|bearer_hash)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i
|
|
818
883
|
},
|
|
819
|
-
{
|
|
884
|
+
{
|
|
885
|
+
reason: "high_entropy_token",
|
|
886
|
+
// Catch-all for an unrecognised opaque secret blob. The candidate run
|
|
887
|
+
// EXCLUDES `_` (so `SCREAMING_SNAKE` env names and `slug_with_words` URL
|
|
888
|
+
// segments split instead of fusing into a phantom 40-char run — the live
|
|
889
|
+
// false positive was `ted_season_2_peacock_official_discussion_thread` in
|
|
890
|
+
// web-search result text and a fetched URL), and the `accept` predicate
|
|
891
|
+
// vetoes content-addressed hashes (md5/sha1/sha256 digests — the platform's
|
|
892
|
+
// OWN asset filenames) and low-entropy / single-class runs so only genuine
|
|
893
|
+
// opaque secrets remain. Slash-bearing secrets (signed URLs, connection
|
|
894
|
+
// strings, `Bearer …`) are covered by the named patterns above.
|
|
895
|
+
regex: /\b[A-Za-z0-9-]{40,}\b/,
|
|
896
|
+
accept: isHighEntropySecretRun
|
|
897
|
+
}
|
|
820
898
|
]);
|
|
899
|
+
var CONTENT_HASH_RUN = /^(?:[0-9a-f]{32}|[0-9a-f]{40}|[0-9a-f]{64})$/i;
|
|
900
|
+
function isHighEntropySecretRun(run) {
|
|
901
|
+
if (CONTENT_HASH_RUN.test(run)) {
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
if (!/[A-Za-z]/.test(run) || !/\d/.test(run)) {
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
if (highEntropyCharClassCount(run) < 2) {
|
|
908
|
+
return false;
|
|
909
|
+
}
|
|
910
|
+
return highEntropyShannonBits(run) >= 3;
|
|
911
|
+
}
|
|
912
|
+
function highEntropyCharClassCount(value) {
|
|
913
|
+
let count = 0;
|
|
914
|
+
if (/[a-z]/.test(value))
|
|
915
|
+
count++;
|
|
916
|
+
if (/[A-Z]/.test(value))
|
|
917
|
+
count++;
|
|
918
|
+
if (/[0-9]/.test(value))
|
|
919
|
+
count++;
|
|
920
|
+
return count;
|
|
921
|
+
}
|
|
922
|
+
function highEntropyShannonBits(value) {
|
|
923
|
+
if (value.length === 0) {
|
|
924
|
+
return 0;
|
|
925
|
+
}
|
|
926
|
+
const counts = /* @__PURE__ */ new Map();
|
|
927
|
+
for (const char of value) {
|
|
928
|
+
counts.set(char, (counts.get(char) ?? 0) + 1);
|
|
929
|
+
}
|
|
930
|
+
let bits = 0;
|
|
931
|
+
for (const count of counts.values()) {
|
|
932
|
+
const p = count / value.length;
|
|
933
|
+
bits -= p * Math.log2(p);
|
|
934
|
+
}
|
|
935
|
+
return bits;
|
|
936
|
+
}
|
|
821
937
|
function isForbiddenCustodyFieldName(key) {
|
|
822
938
|
return /^(apiKey|secretValue|bearerHash|signedUrl|objectStoreKey|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
|
|
823
939
|
}
|
|
@@ -1246,11 +1362,13 @@ __export(operations_exports, {
|
|
|
1246
1362
|
createAgentsMd: () => createAgentsMd,
|
|
1247
1363
|
createFile: () => createFile,
|
|
1248
1364
|
createOutputLink: () => createOutputLink,
|
|
1365
|
+
createSecret: () => createSecret,
|
|
1249
1366
|
createSkillBundle: () => createSkillBundle,
|
|
1250
1367
|
createSkillBundleDirect: () => createSkillBundleDirect,
|
|
1251
1368
|
deleteAgentsMd: () => deleteAgentsMd,
|
|
1252
1369
|
deleteFile: () => deleteFile,
|
|
1253
1370
|
deleteRun: () => deleteRun,
|
|
1371
|
+
deleteSecret: () => deleteSecret,
|
|
1254
1372
|
deleteSkill: () => deleteSkill,
|
|
1255
1373
|
deleteWorkspaceAsset: () => deleteWorkspaceAsset,
|
|
1256
1374
|
download: () => download,
|
|
@@ -1265,13 +1383,17 @@ __export(operations_exports, {
|
|
|
1265
1383
|
getFile: () => getFile,
|
|
1266
1384
|
getRun: () => getRun,
|
|
1267
1385
|
getRunUnit: () => getRunUnit,
|
|
1386
|
+
getSecret: () => getSecret,
|
|
1268
1387
|
getSkill: () => getSkill,
|
|
1269
1388
|
listAgentsMd: () => listAgentsMd,
|
|
1270
1389
|
listFiles: () => listFiles,
|
|
1271
1390
|
listOutputs: () => listOutputs,
|
|
1272
1391
|
listRunEvents: () => listRunEvents,
|
|
1392
|
+
listSecrets: () => listSecrets,
|
|
1273
1393
|
listSkills: () => listSkills,
|
|
1274
1394
|
resolveOutputFileSelector: () => resolveOutputFileSelector,
|
|
1395
|
+
revealSecret: () => revealSecret,
|
|
1396
|
+
rotateSecret: () => rotateSecret,
|
|
1275
1397
|
submitRun: () => submitRun,
|
|
1276
1398
|
submitRunMultipart: () => submitRunMultipart,
|
|
1277
1399
|
uploadWorkspaceAsset: () => uploadWorkspaceAsset,
|
|
@@ -2380,6 +2502,44 @@ function unwrapFile(result) {
|
|
|
2380
2502
|
}
|
|
2381
2503
|
return result;
|
|
2382
2504
|
}
|
|
2505
|
+
async function createSecret(http, args) {
|
|
2506
|
+
const result = await http.request("/api/secrets", {
|
|
2507
|
+
method: "POST",
|
|
2508
|
+
body: JSON.stringify({ name: args.name, value: args.value })
|
|
2509
|
+
});
|
|
2510
|
+
return unwrapSecret(result);
|
|
2511
|
+
}
|
|
2512
|
+
async function listSecrets(http) {
|
|
2513
|
+
const result = await http.request("/api/secrets");
|
|
2514
|
+
if (Array.isArray(result)) {
|
|
2515
|
+
return result;
|
|
2516
|
+
}
|
|
2517
|
+
return result.secrets;
|
|
2518
|
+
}
|
|
2519
|
+
async function getSecret(http, name) {
|
|
2520
|
+
const result = await http.request(`/api/secrets/${encodeURIComponent(name)}`);
|
|
2521
|
+
return unwrapSecret(result);
|
|
2522
|
+
}
|
|
2523
|
+
async function revealSecret(http, name) {
|
|
2524
|
+
return http.request(`/api/secrets/${encodeURIComponent(name)}/reveal`, {
|
|
2525
|
+
method: "POST"
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2528
|
+
async function rotateSecret(http, args) {
|
|
2529
|
+
const result = await http.request(`/api/secrets/${encodeURIComponent(args.name)}/rotate`, { method: "POST", body: JSON.stringify({ value: args.value }) });
|
|
2530
|
+
return unwrapSecret(result);
|
|
2531
|
+
}
|
|
2532
|
+
async function deleteSecret(http, name) {
|
|
2533
|
+
await http.request(`/api/secrets/${encodeURIComponent(name)}`, {
|
|
2534
|
+
method: "DELETE"
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
function unwrapSecret(result) {
|
|
2538
|
+
if (result && typeof result === "object" && "secret" in result) {
|
|
2539
|
+
return result.secret;
|
|
2540
|
+
}
|
|
2541
|
+
return result;
|
|
2542
|
+
}
|
|
2383
2543
|
function unwrapSkill(result) {
|
|
2384
2544
|
if (result && typeof result === "object" && "skill" in result) {
|
|
2385
2545
|
return result.skill;
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d05e5e074b577553d20fa3680f834b7941fe0cb7692c0a743975fcf36c4ec9b5 cli.mjs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/aexhq/aex.git"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"fflate": "^0.8.2",
|
|
30
|
-
"@aexhq/contracts": "0.
|
|
30
|
+
"@aexhq/contracts": "0.21.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"esbuild": "^0.28.0"
|