@anythingai/cli 0.1.2 → 0.1.4
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/CHANGELOG.md +29 -0
- package/dist/js/bin.mjs +242 -109
- package/package.json +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@anythingai/cli` are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Breaking:** `--env` now accepts only lowercase values (`development`,
|
|
13
|
+
`preview`, `production`). The uppercase forms (`DEVELOPMENT`, `PREVIEW`,
|
|
14
|
+
`PRODUCTION`) that 0.0.x silently accepted no longer validate — pass the
|
|
15
|
+
lowercase form instead.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- `--json` failures now write the error envelope to stdout (was stderr), so
|
|
20
|
+
`anything … --json | jq` receives the payload on failure as well as success.
|
|
21
|
+
- Strict-mode (argument-validation) error envelopes no longer leak positional
|
|
22
|
+
values into `command`; the field is now the canonical command path (e.g.
|
|
23
|
+
`orgs get`, `members invite`), keeping IDs and emails out of the envelope.
|
|
24
|
+
- Silenced the yargs `"version" is a reserved word` warning emitted by
|
|
25
|
+
`anything update` / `anything update --check`.
|
|
26
|
+
- `domains add` now rejects RFC 2606 reserved TLDs (`.invalid`, `.example`,
|
|
27
|
+
`.test`, `.localhost`) before the network round-trip.
|
|
28
|
+
- Deployment-failure `buildLogs` are now emitted as an array of lines
|
|
29
|
+
(`string[]`) in the JSON envelope instead of one newline-joined string.
|
package/dist/js/bin.mjs
CHANGED
|
@@ -3069,7 +3069,7 @@ function errorCodeFromHttpStatus(status) {
|
|
|
3069
3069
|
|
|
3070
3070
|
//#endregion
|
|
3071
3071
|
//#region package.json
|
|
3072
|
-
var version = "0.1.
|
|
3072
|
+
var version = "0.1.4";
|
|
3073
3073
|
|
|
3074
3074
|
//#endregion
|
|
3075
3075
|
//#region generated/core/bodySerializer.gen.ts
|
|
@@ -4576,13 +4576,19 @@ var AnythingApiClient = class {
|
|
|
4576
4576
|
}));
|
|
4577
4577
|
}
|
|
4578
4578
|
async listProjectFiles({ projectGroupId }) {
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4579
|
+
const fetchOnce = async () => {
|
|
4580
|
+
return this.toResult(await getV0ApiProjectsByProjectGroupIdFiles({
|
|
4581
|
+
client: this.client,
|
|
4582
|
+
path: { projectGroupId }
|
|
4583
|
+
})).andThen((data) => "files" in data ? ok({ files: data.files ?? [] }) : err({
|
|
4584
|
+
message: "Unexpected API response format",
|
|
4585
|
+
status: 200
|
|
4586
|
+
}));
|
|
4587
|
+
};
|
|
4588
|
+
const first = await fetchOnce();
|
|
4589
|
+
if (first.isErr() || first.value.files.length > 0) return first;
|
|
4590
|
+
await new Promise((resolve) => setTimeout(resolve, 750));
|
|
4591
|
+
return fetchOnce();
|
|
4586
4592
|
}
|
|
4587
4593
|
async getProjectFile({ projectGroupId, path }) {
|
|
4588
4594
|
return this.toResult(await getV0ApiProjectsByProjectGroupIdFiles({
|
|
@@ -4852,6 +4858,11 @@ var AnythingApiClient = class {
|
|
|
4852
4858
|
function printJson(data) {
|
|
4853
4859
|
console.log(JSON.stringify(data, null, 2));
|
|
4854
4860
|
}
|
|
4861
|
+
function buildLogsToLines(buildLogs) {
|
|
4862
|
+
const lines = buildLogs.split("\n");
|
|
4863
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
4864
|
+
return lines;
|
|
4865
|
+
}
|
|
4855
4866
|
function printSuccess(message) {
|
|
4856
4867
|
console.log(styleText("green", message));
|
|
4857
4868
|
}
|
|
@@ -4900,15 +4911,58 @@ function extractErrorCode(details) {
|
|
|
4900
4911
|
const parsed = DetailsWithCodeSchema.safeParse(details);
|
|
4901
4912
|
return parsed.success ? parsed.data.code : null;
|
|
4902
4913
|
}
|
|
4914
|
+
function resolveErrorCode({ error, exitCode, codeOverride }) {
|
|
4915
|
+
const status = "status" in error ? error.status ?? null : null;
|
|
4916
|
+
const details = "details" in error ? error.details : void 0;
|
|
4917
|
+
return codeOverride ?? extractErrorCode(details) ?? (status === null && exitCode !== void 0 ? errorCodeFromExitCode(exitCode) : errorCodeFromHttpStatus(status));
|
|
4918
|
+
}
|
|
4919
|
+
function outputStreamError({ argv, command, error, hint, exitCode, buildLogs, code: codeOverride }) {
|
|
4920
|
+
const status = "status" in error ? error.status ?? null : null;
|
|
4921
|
+
process.exitCode = exitCode ?? exitCodeFromHttpStatus(status);
|
|
4922
|
+
if (!argv.json && !argv.quiet) {
|
|
4923
|
+
outputError({
|
|
4924
|
+
argv,
|
|
4925
|
+
command,
|
|
4926
|
+
error,
|
|
4927
|
+
hint,
|
|
4928
|
+
exitCode,
|
|
4929
|
+
buildLogs,
|
|
4930
|
+
code: codeOverride
|
|
4931
|
+
});
|
|
4932
|
+
return;
|
|
4933
|
+
}
|
|
4934
|
+
const code = resolveErrorCode({
|
|
4935
|
+
error,
|
|
4936
|
+
exitCode,
|
|
4937
|
+
codeOverride
|
|
4938
|
+
});
|
|
4939
|
+
const retryAfter = "retryAfter" in error && typeof error.retryAfter === "number" ? error.retryAfter : null;
|
|
4940
|
+
const resolvedHint = hint ?? ("hint" in error && typeof error.hint === "string" ? error.hint : void 0);
|
|
4941
|
+
printNdjson({
|
|
4942
|
+
type: "result",
|
|
4943
|
+
ok: false,
|
|
4944
|
+
error: {
|
|
4945
|
+
code,
|
|
4946
|
+
message: error.message,
|
|
4947
|
+
...resolvedHint ? { hint: resolvedHint } : {},
|
|
4948
|
+
...retryAfter !== null ? { retry_after_seconds: retryAfter } : {},
|
|
4949
|
+
...buildLogs ? { buildLogs: buildLogsToLines(buildLogs) } : {}
|
|
4950
|
+
}
|
|
4951
|
+
});
|
|
4952
|
+
}
|
|
4903
4953
|
function outputError({ argv, command, error, hint, exitCode, buildLogs, code: codeOverride }) {
|
|
4904
4954
|
const status = "status" in error ? error.status ?? null : null;
|
|
4905
4955
|
const details = "details" in error ? error.details : void 0;
|
|
4906
4956
|
const retryAfter = "retryAfter" in error && typeof error.retryAfter === "number" ? error.retryAfter : null;
|
|
4907
4957
|
const resolvedHint = hint ?? ("hint" in error && typeof error.hint === "string" ? error.hint : void 0);
|
|
4908
4958
|
process.exitCode = exitCode ?? exitCodeFromHttpStatus(status);
|
|
4909
|
-
const code =
|
|
4959
|
+
const code = resolveErrorCode({
|
|
4960
|
+
error,
|
|
4961
|
+
exitCode,
|
|
4962
|
+
codeOverride
|
|
4963
|
+
});
|
|
4910
4964
|
if (argv.json || argv.quiet) {
|
|
4911
|
-
console.
|
|
4965
|
+
console.log(JSON.stringify({
|
|
4912
4966
|
ok: false,
|
|
4913
4967
|
command,
|
|
4914
4968
|
error: {
|
|
@@ -4916,7 +4970,7 @@ function outputError({ argv, command, error, hint, exitCode, buildLogs, code: co
|
|
|
4916
4970
|
message: error.message,
|
|
4917
4971
|
...resolvedHint ? { hint: resolvedHint } : {},
|
|
4918
4972
|
...retryAfter !== null ? { retry_after_seconds: retryAfter } : {},
|
|
4919
|
-
...buildLogs ? { buildLogs } : {}
|
|
4973
|
+
...buildLogs ? { buildLogs: buildLogsToLines(buildLogs) } : {}
|
|
4920
4974
|
}
|
|
4921
4975
|
}, null, 2));
|
|
4922
4976
|
return;
|
|
@@ -5373,7 +5427,7 @@ async function selectAndSetOrg({ config, json, nonInteractive }) {
|
|
|
5373
5427
|
return choice;
|
|
5374
5428
|
}
|
|
5375
5429
|
}
|
|
5376
|
-
const recommended = orgs.find((org) =>
|
|
5430
|
+
const recommended = orgs.find((org) => org.creditsBalance > 0) ?? orgs[0];
|
|
5377
5431
|
if (!recommended) return null;
|
|
5378
5432
|
if (!json) {
|
|
5379
5433
|
console.log();
|
|
@@ -6645,11 +6699,19 @@ function toPublicDomain(domain) {
|
|
|
6645
6699
|
//#region src/commands/domain-add.ts
|
|
6646
6700
|
const COMMAND$19 = "domains add";
|
|
6647
6701
|
const HOSTNAME_PATTERN = /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
|
|
6702
|
+
const RESERVED_TLDS = new Set([
|
|
6703
|
+
"invalid",
|
|
6704
|
+
"example",
|
|
6705
|
+
"test",
|
|
6706
|
+
"localhost"
|
|
6707
|
+
]);
|
|
6648
6708
|
function domainValidationError(domain) {
|
|
6649
6709
|
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(domain)) return `Enter a bare hostname without a scheme (got "${domain}"). Example: app.example.com`;
|
|
6650
6710
|
if (domain.includes("/") || /\s/.test(domain)) return `Invalid domain "${domain}". Enter a bare hostname like app.example.com`;
|
|
6651
6711
|
if (!domain.includes(".")) return `Invalid domain "${domain}". A domain must include a dot, e.g. app.example.com`;
|
|
6652
6712
|
if (!HOSTNAME_PATTERN.test(domain)) return `Invalid domain "${domain}". Enter a valid hostname like app.example.com`;
|
|
6713
|
+
const tld = domain.split(".").pop()?.toLowerCase() ?? "";
|
|
6714
|
+
if (RESERVED_TLDS.has(tld)) return `Invalid domain "${domain}". ".${tld}" is a reserved TLD that cannot be used for a real domain. Use a registered domain like app.example.com`;
|
|
6653
6715
|
return null;
|
|
6654
6716
|
}
|
|
6655
6717
|
const domainAddCommand = {
|
|
@@ -8490,7 +8552,7 @@ const llmContextCommand = {
|
|
|
8490
8552
|
id: org.id,
|
|
8491
8553
|
name: org.name,
|
|
8492
8554
|
plan: org.plan,
|
|
8493
|
-
hasCredits:
|
|
8555
|
+
hasCredits: org.creditsBalance > 0
|
|
8494
8556
|
}))
|
|
8495
8557
|
};
|
|
8496
8558
|
} catch {}
|
|
@@ -8912,18 +8974,6 @@ const membersCommand = {
|
|
|
8912
8974
|
handler: () => {}
|
|
8913
8975
|
};
|
|
8914
8976
|
|
|
8915
|
-
//#endregion
|
|
8916
|
-
//#region src/format-credits.ts
|
|
8917
|
-
const HUMAN_READABLE_FACTOR = 10000000n;
|
|
8918
|
-
const formatter = Intl.NumberFormat("en", {
|
|
8919
|
-
notation: "compact",
|
|
8920
|
-
maximumSignificantDigits: 3
|
|
8921
|
-
});
|
|
8922
|
-
const humanizeCredits = (credits) => {
|
|
8923
|
-
const normalized = BigInt(credits) * 100n / HUMAN_READABLE_FACTOR;
|
|
8924
|
-
return formatter.format(Math.ceil(Number(normalized) / 100));
|
|
8925
|
-
};
|
|
8926
|
-
|
|
8927
8977
|
//#endregion
|
|
8928
8978
|
//#region src/commands/org-members.ts
|
|
8929
8979
|
const orgMembersCommand = {
|
|
@@ -9048,9 +9098,6 @@ async function loadOrganizations(argv, command) {
|
|
|
9048
9098
|
}
|
|
9049
9099
|
return result.value.organizations;
|
|
9050
9100
|
}
|
|
9051
|
-
function formatCredits$1(creditBalance) {
|
|
9052
|
-
return `${humanizeCredits(creditBalance)} credits`;
|
|
9053
|
-
}
|
|
9054
9101
|
const getCommand = {
|
|
9055
9102
|
command: "get <organizationId>",
|
|
9056
9103
|
describe: "Inspect a single organization",
|
|
@@ -9086,7 +9133,7 @@ const getCommand = {
|
|
|
9086
9133
|
printLabel("ID", organization.id);
|
|
9087
9134
|
printLabel("Plan", organization.planDisplayName);
|
|
9088
9135
|
printLabel("Paid", organization.isPaid ? "yes" : "no");
|
|
9089
|
-
printLabel("Credits",
|
|
9136
|
+
printLabel("Credits", `${organization.creditsBalance} credits`);
|
|
9090
9137
|
printLabel("Plan Code", organization.plan);
|
|
9091
9138
|
}
|
|
9092
9139
|
};
|
|
@@ -9590,13 +9637,25 @@ const createCommand = {
|
|
|
9590
9637
|
const DEPLOY_POLL_INTERVAL_MS = 3e3;
|
|
9591
9638
|
const DEPLOY_POLL_TIMEOUT_MS = 6e5;
|
|
9592
9639
|
const DEPLOY_JITTER_MS = 500;
|
|
9640
|
+
const MAX_CONSECUTIVE_POLL_ERRORS = 5;
|
|
9593
9641
|
const TERMINAL_STATUSES = new Set(["SUCCESS", "FAILED"]);
|
|
9594
9642
|
async function waitForDeployment({ client, deploymentId, emit }) {
|
|
9595
9643
|
const deadline = Date.now() + DEPLOY_POLL_TIMEOUT_MS;
|
|
9596
9644
|
let lastStatus = null;
|
|
9645
|
+
let consecutiveErrors = 0;
|
|
9597
9646
|
while (Date.now() < deadline) {
|
|
9598
9647
|
const result = await client.getDeployment({ deploymentId });
|
|
9599
|
-
if (result.isErr())
|
|
9648
|
+
if (result.isErr()) {
|
|
9649
|
+
consecutiveErrors += 1;
|
|
9650
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_POLL_ERRORS) return ok({
|
|
9651
|
+
outcome: "unconfirmed",
|
|
9652
|
+
deploymentId,
|
|
9653
|
+
reason: `Could not confirm deployment status after ${consecutiveErrors} consecutive polling errors (last: ${result.error.message}).`
|
|
9654
|
+
});
|
|
9655
|
+
await setTimeout$1(DEPLOY_POLL_INTERVAL_MS + Math.random() * DEPLOY_JITTER_MS);
|
|
9656
|
+
continue;
|
|
9657
|
+
}
|
|
9658
|
+
consecutiveErrors = 0;
|
|
9600
9659
|
const { deployment } = result.value;
|
|
9601
9660
|
if (deployment.status !== lastStatus) {
|
|
9602
9661
|
lastStatus = deployment.status;
|
|
@@ -9623,10 +9682,12 @@ async function waitForDeployment({ client, deploymentId, emit }) {
|
|
|
9623
9682
|
* error info if the deployment did not succeed, or null if it succeeded.
|
|
9624
9683
|
*/
|
|
9625
9684
|
function getDeploymentError({ result, statusCommand }) {
|
|
9626
|
-
if (result.outcome === "timeout") return {
|
|
9627
|
-
message:
|
|
9685
|
+
if (result.outcome === "timeout" || result.outcome === "unconfirmed") return {
|
|
9686
|
+
message: `${result.outcome === "timeout" ? "Deployment did not reach a terminal status before the wait timed out" : result.reason} The deploy may still be in progress. Resume with: ${statusCommand}`,
|
|
9628
9687
|
exitCode: 6,
|
|
9629
|
-
buildLogs: null
|
|
9688
|
+
buildLogs: null,
|
|
9689
|
+
deploymentId: result.deploymentId,
|
|
9690
|
+
hint: `Resume with: ${statusCommand}`
|
|
9630
9691
|
};
|
|
9631
9692
|
if (result.deployment.status === "FAILED") {
|
|
9632
9693
|
const reason = result.deployment.failureReason ?? null;
|
|
@@ -9634,7 +9695,9 @@ function getDeploymentError({ result, statusCommand }) {
|
|
|
9634
9695
|
return {
|
|
9635
9696
|
message: reason ?? (logs ? "Deployment failed. See build logs for details." : "Deployment failed (no logs available)."),
|
|
9636
9697
|
exitCode: 1,
|
|
9637
|
-
buildLogs: logs
|
|
9698
|
+
buildLogs: logs,
|
|
9699
|
+
deploymentId: result.deployment.id,
|
|
9700
|
+
hint: null
|
|
9638
9701
|
};
|
|
9639
9702
|
}
|
|
9640
9703
|
return null;
|
|
@@ -9845,11 +9908,12 @@ const publishCommand = {
|
|
|
9845
9908
|
argv,
|
|
9846
9909
|
command: COMMAND$15,
|
|
9847
9910
|
error: {
|
|
9848
|
-
message: deployError.message,
|
|
9911
|
+
message: deployError.deploymentId ? `${deployError.message} (deploymentId: ${deployError.deploymentId})` : deployError.message,
|
|
9849
9912
|
status: null
|
|
9850
9913
|
},
|
|
9851
9914
|
exitCode: deployError.exitCode,
|
|
9852
|
-
buildLogs: deployError.buildLogs ?? void 0
|
|
9915
|
+
buildLogs: deployError.buildLogs ?? void 0,
|
|
9916
|
+
hint: deployError.hint ?? void 0
|
|
9853
9917
|
});
|
|
9854
9918
|
return;
|
|
9855
9919
|
}
|
|
@@ -9980,20 +10044,24 @@ const list$1 = {
|
|
|
9980
10044
|
});
|
|
9981
10045
|
return;
|
|
9982
10046
|
}
|
|
10047
|
+
const files = result.value.files;
|
|
9983
10048
|
if (argv.json && outputSuccess({
|
|
9984
10049
|
argv,
|
|
9985
10050
|
command,
|
|
9986
|
-
data:
|
|
10051
|
+
data: {
|
|
10052
|
+
files,
|
|
10053
|
+
count: files.length
|
|
10054
|
+
}
|
|
9987
10055
|
})) return;
|
|
9988
10056
|
if (argv.quiet) {
|
|
9989
|
-
for (const file of
|
|
10057
|
+
for (const file of files) console.log(file.path);
|
|
9990
10058
|
return;
|
|
9991
10059
|
}
|
|
9992
|
-
if (
|
|
10060
|
+
if (files.length === 0) {
|
|
9993
10061
|
console.log("No files found.");
|
|
9994
10062
|
return;
|
|
9995
10063
|
}
|
|
9996
|
-
for (const file of
|
|
10064
|
+
for (const file of files) console.log(file.path);
|
|
9997
10065
|
}
|
|
9998
10066
|
};
|
|
9999
10067
|
const get$1 = {
|
|
@@ -10945,7 +11013,11 @@ const secretEnvironmentChoices = [
|
|
|
10945
11013
|
"preview",
|
|
10946
11014
|
"production"
|
|
10947
11015
|
];
|
|
10948
|
-
const
|
|
11016
|
+
const ALL_SECRET_ENVIRONMENTS = [
|
|
11017
|
+
"DEVELOPMENT",
|
|
11018
|
+
"PREVIEW",
|
|
11019
|
+
"PRODUCTION"
|
|
11020
|
+
];
|
|
10949
11021
|
const add = {
|
|
10950
11022
|
command: "add <projectId>",
|
|
10951
11023
|
describe: "Add a secret to an app",
|
|
@@ -10964,7 +11036,7 @@ const add = {
|
|
|
10964
11036
|
type: "string",
|
|
10965
11037
|
coerce: (value) => value.toLowerCase(),
|
|
10966
11038
|
choices: secretEnvironmentChoices,
|
|
10967
|
-
describe: "Target environment
|
|
11039
|
+
describe: "Target a single environment. Omit to add the secret to all environments (development, preview, production) so it reaches the published app."
|
|
10968
11040
|
}).option("force", {
|
|
10969
11041
|
type: "boolean",
|
|
10970
11042
|
default: false,
|
|
@@ -10972,16 +11044,17 @@ const add = {
|
|
|
10972
11044
|
}).example("anything projects secrets add <id> --name KEY --value \"secret\"", "Add a secret from an inline value").example("cat secret.txt | anything projects secrets add <id> --name KEY", "Read a secret value from stdin"),
|
|
10973
11045
|
handler: async (argv) => {
|
|
10974
11046
|
const command = "projects secrets add";
|
|
11047
|
+
const targetEnvironments = argv.env ? [argv.env.toUpperCase()] : [...ALL_SECRET_ENVIRONMENTS];
|
|
10975
11048
|
if (argv["dry-run"]) {
|
|
10976
11049
|
outputDryRun({
|
|
10977
11050
|
argv,
|
|
10978
11051
|
command,
|
|
10979
|
-
plannedActions:
|
|
11052
|
+
plannedActions: targetEnvironments.map((environment) => ({
|
|
10980
11053
|
action: "add_secret",
|
|
10981
11054
|
projectGroupId: argv.projectId,
|
|
10982
11055
|
name: argv.name,
|
|
10983
|
-
|
|
10984
|
-
}
|
|
11056
|
+
environment
|
|
11057
|
+
}))
|
|
10985
11058
|
});
|
|
10986
11059
|
return;
|
|
10987
11060
|
}
|
|
@@ -11019,16 +11092,16 @@ const add = {
|
|
|
11019
11092
|
return;
|
|
11020
11093
|
}
|
|
11021
11094
|
const client = new AnythingApiClient(config.value);
|
|
11022
|
-
const targetEnvironment = argv.env ? argv.env.toUpperCase() : DEFAULT_SECRET_ENVIRONMENT;
|
|
11023
11095
|
if (!argv.force) {
|
|
11024
11096
|
const existing = await client.listSecrets({ projectGroupId: argv.projectId });
|
|
11025
11097
|
if (existing.isOk()) {
|
|
11026
|
-
|
|
11098
|
+
const collisions = targetEnvironments.filter((environment) => existing.value.secrets.some((secret) => secret.displayName === argv.name && secret.environment === environment));
|
|
11099
|
+
if (collisions.length > 0) {
|
|
11027
11100
|
outputError({
|
|
11028
11101
|
argv,
|
|
11029
11102
|
command,
|
|
11030
11103
|
error: {
|
|
11031
|
-
message: `A secret named "${argv.name}" already exists in ${
|
|
11104
|
+
message: `A secret named "${argv.name}" already exists in ${collisions.join(", ")}.`,
|
|
11032
11105
|
status: 409
|
|
11033
11106
|
},
|
|
11034
11107
|
hint: "Remove the existing secret first, or pass --force to create a suffixed sibling."
|
|
@@ -11037,31 +11110,41 @@ const add = {
|
|
|
11037
11110
|
}
|
|
11038
11111
|
}
|
|
11039
11112
|
}
|
|
11040
|
-
const
|
|
11041
|
-
|
|
11042
|
-
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11113
|
+
const added = [];
|
|
11114
|
+
for (const environment of targetEnvironments) {
|
|
11115
|
+
const result = await client.addSecret({
|
|
11116
|
+
projectGroupId: argv.projectId,
|
|
11117
|
+
displayName: argv.name,
|
|
11118
|
+
value: valueResult.value,
|
|
11119
|
+
environment
|
|
11120
|
+
});
|
|
11121
|
+
if (result.isErr()) {
|
|
11122
|
+
outputError({
|
|
11123
|
+
argv,
|
|
11124
|
+
command,
|
|
11125
|
+
error: result.error
|
|
11126
|
+
});
|
|
11127
|
+
return;
|
|
11128
|
+
}
|
|
11129
|
+
added.push({
|
|
11130
|
+
id: result.value.secret.id,
|
|
11131
|
+
envKey: result.value.secret.envKey,
|
|
11132
|
+
environment: result.value.secret.environment
|
|
11051
11133
|
});
|
|
11052
|
-
return;
|
|
11053
11134
|
}
|
|
11135
|
+
const environments = added.map((s) => s.environment);
|
|
11054
11136
|
if (outputSuccess({
|
|
11055
11137
|
argv,
|
|
11056
11138
|
command,
|
|
11057
|
-
data:
|
|
11058
|
-
|
|
11139
|
+
data: {
|
|
11140
|
+
secrets: added,
|
|
11141
|
+
environments
|
|
11142
|
+
},
|
|
11143
|
+
primaryId: added[0]?.id
|
|
11059
11144
|
})) return;
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
printLabel(
|
|
11063
|
-
printLabel("Env Key", s.envKey);
|
|
11064
|
-
printLabel("Environment", s.environment);
|
|
11145
|
+
printSuccess(`Secret added to ${environments.join(", ")}.`);
|
|
11146
|
+
printLabel("Env Key", added[0]?.envKey ?? argv.name);
|
|
11147
|
+
for (const s of added) printLabel(`ID (${s.environment})`, s.id);
|
|
11065
11148
|
}
|
|
11066
11149
|
};
|
|
11067
11150
|
const remove = {
|
|
@@ -11948,7 +12031,7 @@ const shipCommand = {
|
|
|
11948
12031
|
apiUrl: argv.apiUrl
|
|
11949
12032
|
});
|
|
11950
12033
|
if (config.isErr()) {
|
|
11951
|
-
|
|
12034
|
+
outputStreamError({
|
|
11952
12035
|
argv,
|
|
11953
12036
|
command: COMMAND$4,
|
|
11954
12037
|
error: {
|
|
@@ -11970,7 +12053,7 @@ const shipCommand = {
|
|
|
11970
12053
|
nonInteractive: isNonInteractive(argv)
|
|
11971
12054
|
});
|
|
11972
12055
|
if (!orgResult.ok) {
|
|
11973
|
-
|
|
12056
|
+
outputStreamError({
|
|
11974
12057
|
argv,
|
|
11975
12058
|
command: COMMAND$4,
|
|
11976
12059
|
error: {
|
|
@@ -11993,7 +12076,7 @@ const shipCommand = {
|
|
|
11993
12076
|
name: argv.name ?? null
|
|
11994
12077
|
});
|
|
11995
12078
|
if (createResult.isErr()) {
|
|
11996
|
-
|
|
12079
|
+
outputStreamError({
|
|
11997
12080
|
argv,
|
|
11998
12081
|
command: COMMAND$4,
|
|
11999
12082
|
error: createResult.error
|
|
@@ -12021,7 +12104,7 @@ const shipCommand = {
|
|
|
12021
12104
|
createNewThread: false
|
|
12022
12105
|
});
|
|
12023
12106
|
if (genResult.isErr()) {
|
|
12024
|
-
|
|
12107
|
+
outputStreamError({
|
|
12025
12108
|
argv,
|
|
12026
12109
|
command: COMMAND$4,
|
|
12027
12110
|
error: genResult.error
|
|
@@ -12085,7 +12168,7 @@ const shipCommand = {
|
|
|
12085
12168
|
slug: argv.slug ?? null
|
|
12086
12169
|
});
|
|
12087
12170
|
if (publishResult.isErr()) {
|
|
12088
|
-
|
|
12171
|
+
outputStreamError({
|
|
12089
12172
|
argv,
|
|
12090
12173
|
command: COMMAND$4,
|
|
12091
12174
|
error: publishResult.error
|
|
@@ -12100,7 +12183,7 @@ const shipCommand = {
|
|
|
12100
12183
|
emit
|
|
12101
12184
|
});
|
|
12102
12185
|
if (deployResult.isErr()) {
|
|
12103
|
-
|
|
12186
|
+
outputStreamError({
|
|
12104
12187
|
argv,
|
|
12105
12188
|
command: COMMAND$4,
|
|
12106
12189
|
error: deployResult.error
|
|
@@ -12112,15 +12195,16 @@ const shipCommand = {
|
|
|
12112
12195
|
statusCommand: `anything projects publish status ${projectGroupId} ${deploymentId}`
|
|
12113
12196
|
});
|
|
12114
12197
|
if (deployError) {
|
|
12115
|
-
|
|
12198
|
+
outputStreamError({
|
|
12116
12199
|
argv,
|
|
12117
12200
|
command: COMMAND$4,
|
|
12118
12201
|
error: {
|
|
12119
|
-
message: deployError.message,
|
|
12202
|
+
message: deployError.deploymentId ? `${deployError.message} (deploymentId: ${deployError.deploymentId})` : deployError.message,
|
|
12120
12203
|
status: null
|
|
12121
12204
|
},
|
|
12122
12205
|
exitCode: deployError.exitCode,
|
|
12123
|
-
buildLogs: deployError.buildLogs ?? void 0
|
|
12206
|
+
buildLogs: deployError.buildLogs ?? void 0,
|
|
12207
|
+
hint: deployError.hint ?? void 0
|
|
12124
12208
|
});
|
|
12125
12209
|
return;
|
|
12126
12210
|
}
|
|
@@ -12418,8 +12502,9 @@ const switchCommand = {
|
|
|
12418
12502
|
const PACKAGE_NAME = "@anythingai/cli";
|
|
12419
12503
|
const REGISTRY_BASE_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;
|
|
12420
12504
|
const REGISTRY_URL = `${REGISTRY_BASE_URL}/latest`;
|
|
12421
|
-
const
|
|
12422
|
-
const
|
|
12505
|
+
const INTERNAL_UPDATE_CHECK_ARG = "__update-check";
|
|
12506
|
+
const CHECK_INTERVAL_MS = 10800 * 1e3;
|
|
12507
|
+
const REFRESH_FETCH_TIMEOUT_MS = 1e4;
|
|
12423
12508
|
const latestManifestSchema = z.object({ version: z.string() });
|
|
12424
12509
|
function isNewerVersion(candidate, current) {
|
|
12425
12510
|
const core = (v) => (v.split("-")[0] ?? "").split(".").map((part) => Number.parseInt(part, 10));
|
|
@@ -12467,30 +12552,62 @@ function printUpdateNotice({ current, latest }) {
|
|
|
12467
12552
|
""
|
|
12468
12553
|
].join("\n"));
|
|
12469
12554
|
}
|
|
12470
|
-
|
|
12555
|
+
function spawnBackgroundRefresh() {
|
|
12556
|
+
const entry = process.argv[1];
|
|
12557
|
+
if (!entry) return;
|
|
12558
|
+
try {
|
|
12559
|
+
spawn(process.execPath, [entry, INTERNAL_UPDATE_CHECK_ARG], {
|
|
12560
|
+
detached: true,
|
|
12561
|
+
stdio: "ignore",
|
|
12562
|
+
windowsHide: true,
|
|
12563
|
+
env: backgroundRefreshEnv()
|
|
12564
|
+
}).unref();
|
|
12565
|
+
} catch {}
|
|
12566
|
+
}
|
|
12567
|
+
function backgroundRefreshEnv() {
|
|
12568
|
+
const allowed = [
|
|
12569
|
+
"PATH",
|
|
12570
|
+
"HOME",
|
|
12571
|
+
"XDG_CONFIG_HOME",
|
|
12572
|
+
"APPDATA",
|
|
12573
|
+
"LOCALAPPDATA",
|
|
12574
|
+
"SystemRoot"
|
|
12575
|
+
];
|
|
12576
|
+
const env = {};
|
|
12577
|
+
for (const key of allowed) {
|
|
12578
|
+
const value = process.env[key];
|
|
12579
|
+
if (value !== void 0) env[key] = value;
|
|
12580
|
+
}
|
|
12581
|
+
return env;
|
|
12582
|
+
}
|
|
12583
|
+
async function refreshUpdateCheckCache(now) {
|
|
12584
|
+
recordUpdateCheck({
|
|
12585
|
+
checkedAt: now,
|
|
12586
|
+
latestVersion: await fetchLatestVersion({ timeoutMs: REFRESH_FETCH_TIMEOUT_MS })
|
|
12587
|
+
});
|
|
12588
|
+
}
|
|
12589
|
+
function notifyIfUpdateAvailable(now) {
|
|
12471
12590
|
const state = getUpdateCheckState();
|
|
12472
|
-
|
|
12473
|
-
if (
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
|
|
12480
|
-
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
current: CLI_VERSION,
|
|
12485
|
-
latest
|
|
12591
|
+
const latest = state.latestKnownVersion;
|
|
12592
|
+
if (latest && isNewerVersion(latest, CLI_VERSION) && state.notifiedVersion !== latest) {
|
|
12593
|
+
printUpdateNotice({
|
|
12594
|
+
current: CLI_VERSION,
|
|
12595
|
+
latest
|
|
12596
|
+
});
|
|
12597
|
+
recordUpdateNotified(latest);
|
|
12598
|
+
}
|
|
12599
|
+
if (!(state.checkedAt === null || now - state.checkedAt >= CHECK_INTERVAL_MS)) return;
|
|
12600
|
+
recordUpdateCheck({
|
|
12601
|
+
checkedAt: now,
|
|
12602
|
+
latestVersion: null
|
|
12486
12603
|
});
|
|
12487
|
-
|
|
12604
|
+
spawnBackgroundRefresh();
|
|
12488
12605
|
}
|
|
12489
|
-
|
|
12606
|
+
function maybeNotifyUpdate(argv, now) {
|
|
12490
12607
|
if (argv.json || argv.quiet) return;
|
|
12491
12608
|
if (isNonInteractive(argv)) return;
|
|
12492
12609
|
if (!process.stderr.isTTY) return;
|
|
12493
|
-
|
|
12610
|
+
notifyIfUpdateAvailable(now);
|
|
12494
12611
|
}
|
|
12495
12612
|
|
|
12496
12613
|
//#endregion
|
|
@@ -12580,7 +12697,7 @@ function runInstall({ command, args, capture }) {
|
|
|
12580
12697
|
const updateCommand = {
|
|
12581
12698
|
command: "update [version]",
|
|
12582
12699
|
describe: "Update the CLI to the latest (or a specific) published version",
|
|
12583
|
-
builder: (yargs) => yargs.positional("version", {
|
|
12700
|
+
builder: (yargs) => yargs.version(false).positional("version", {
|
|
12584
12701
|
type: "string",
|
|
12585
12702
|
describe: "A specific published version to install (defaults to the latest)"
|
|
12586
12703
|
}).option("check", {
|
|
@@ -12753,9 +12870,6 @@ const updateCommand = {
|
|
|
12753
12870
|
|
|
12754
12871
|
//#endregion
|
|
12755
12872
|
//#region src/commands/user.ts
|
|
12756
|
-
function formatCredits(creditBalance) {
|
|
12757
|
-
return `${humanizeCredits(creditBalance)} credits`;
|
|
12758
|
-
}
|
|
12759
12873
|
const COMMAND = "user";
|
|
12760
12874
|
const userCommand = {
|
|
12761
12875
|
command: "user",
|
|
@@ -12794,14 +12908,14 @@ const userCommand = {
|
|
|
12794
12908
|
}
|
|
12795
12909
|
const activeOrgId = getStoredOrgId();
|
|
12796
12910
|
const defaultOrganization = result.value.organizations[0] ?? null;
|
|
12797
|
-
const organizationWithCredits = result.value.organizations.find((org) =>
|
|
12798
|
-
const recommendedOrganization = defaultOrganization !== null &&
|
|
12911
|
+
const organizationWithCredits = result.value.organizations.find((org) => org.creditsBalance > 0) ?? null;
|
|
12912
|
+
const recommendedOrganization = defaultOrganization !== null && defaultOrganization.creditsBalance > 0 ? defaultOrganization : organizationWithCredits;
|
|
12799
12913
|
const credentialSource = env.ANYTHING_API_KEY ? "env" : configExists() ? "config" : "unknown";
|
|
12800
12914
|
const checks = {
|
|
12801
12915
|
hasOrganizations: result.value.organizations.length > 0,
|
|
12802
12916
|
hasPaidOrganization: result.value.organizations.some((org) => org.isPaid),
|
|
12803
12917
|
hasCredits: organizationWithCredits !== null,
|
|
12804
|
-
defaultOrganizationHasCredits: defaultOrganization !== null ?
|
|
12918
|
+
defaultOrganizationHasCredits: defaultOrganization !== null ? defaultOrganization.creditsBalance > 0 : null
|
|
12805
12919
|
};
|
|
12806
12920
|
const activeOrg = activeOrgId ? result.value.organizations.find((o) => o.id === activeOrgId) ?? null : null;
|
|
12807
12921
|
if (argv.quiet && !argv.json) {
|
|
@@ -12870,7 +12984,7 @@ const userCommand = {
|
|
|
12870
12984
|
org.id === activeOrgId ? "*" : "",
|
|
12871
12985
|
org.name,
|
|
12872
12986
|
org.planDisplayName,
|
|
12873
|
-
|
|
12987
|
+
`${org.creditsBalance} credits`,
|
|
12874
12988
|
org.id
|
|
12875
12989
|
])
|
|
12876
12990
|
});
|
|
@@ -12882,7 +12996,7 @@ const userCommand = {
|
|
|
12882
12996
|
if (!activeOrgId && recommendedOrganization !== null) {
|
|
12883
12997
|
console.log();
|
|
12884
12998
|
console.log(`No active organization set. Run \`anything orgs set ${recommendedOrganization.id}\` to set one.`);
|
|
12885
|
-
} else if (activeOrg !== null &&
|
|
12999
|
+
} else if (activeOrg !== null && activeOrg.creditsBalance === 0 && recommendedOrganization !== null && recommendedOrganization.id !== activeOrg.id) {
|
|
12886
13000
|
console.log();
|
|
12887
13001
|
console.log(`Active organization has no credits. Run \`anything orgs set ${recommendedOrganization.id}\` to switch.`);
|
|
12888
13002
|
}
|
|
@@ -13036,6 +13150,16 @@ const watchCommand = {
|
|
|
13036
13150
|
|
|
13037
13151
|
//#endregion
|
|
13038
13152
|
//#region src/cli.ts
|
|
13153
|
+
const REGISTERED_COMMAND_PATHS = (() => {
|
|
13154
|
+
const paths = /* @__PURE__ */ new Set();
|
|
13155
|
+
for (const { name } of commandTree) {
|
|
13156
|
+
const words = name.split(" ");
|
|
13157
|
+
for (let i = 1; i <= words.length; i++) paths.add(words.slice(0, i).join(" "));
|
|
13158
|
+
}
|
|
13159
|
+
paths.add("dev");
|
|
13160
|
+
paths.add("update");
|
|
13161
|
+
return paths;
|
|
13162
|
+
})();
|
|
13039
13163
|
var HandledCliError = class extends Error {};
|
|
13040
13164
|
function commandPathFromArgv(argv) {
|
|
13041
13165
|
const words = [];
|
|
@@ -13043,7 +13167,15 @@ function commandPathFromArgv(argv) {
|
|
|
13043
13167
|
if (token.startsWith("-")) break;
|
|
13044
13168
|
words.push(token);
|
|
13045
13169
|
}
|
|
13046
|
-
|
|
13170
|
+
const [firstWord] = words;
|
|
13171
|
+
if (firstWord === void 0) return null;
|
|
13172
|
+
let matched = "";
|
|
13173
|
+
for (let i = 0; i < words.length; i++) {
|
|
13174
|
+
const candidate = words.slice(0, i + 1).join(" ");
|
|
13175
|
+
if (!REGISTERED_COMMAND_PATHS.has(candidate)) break;
|
|
13176
|
+
matched = candidate;
|
|
13177
|
+
}
|
|
13178
|
+
return matched === "" ? firstWord : matched;
|
|
13047
13179
|
}
|
|
13048
13180
|
function createCli(argv) {
|
|
13049
13181
|
const cli = yargs(argv).scriptName("anything").usage("$0 <command> [options]").example("anything auth login", "Log in via browser").example("anything ship --prompt \"Build a todo app\"", "Create + publish in one shot").example("anything domains list org_123", "List domains for one organization").example("anything orgs", "List your organizations").example("anything orgs get <org-id>", "Inspect one organization").example("anything orgs set <org-id>", "Set the active organization").example("anything orgs members <org-id>", "Inspect collaborators and pending invites").example("anything projects create --prompt todo-app", "Create a new app").example("anything projects generate <project-id> --prompt add-auth", "Iterate on an existing app").example("anything projects publish <project-id> --slug my-app", "Publish an app").example("anything projects get <project-id> --json", "Inspect an app in JSON").example("anything projects rename <project-id> --name \"My App\"", "Rename a project").example("anything databases list --org <org-id>", "List databases for an organization").example("anything deployments list <project-id>", "List deployments for a project").example("anything members invite user@example.com --org org_123", "Invite a member").example("anything update", "Update the CLI to the latest version").example("anything status", "Show current context").example("anything switch", "Interactive org/project picker").example("anything introspect", "Output command tree as JSON").option("json", {
|
|
@@ -13075,9 +13207,9 @@ function createCli(argv) {
|
|
|
13075
13207
|
type: "string",
|
|
13076
13208
|
description: "Override the API base URL",
|
|
13077
13209
|
global: true
|
|
13078
|
-
}).middleware(
|
|
13210
|
+
}).middleware((args) => {
|
|
13079
13211
|
setDevFlagOverride(args.dev === true);
|
|
13080
|
-
|
|
13212
|
+
maybeNotifyUpdate({
|
|
13081
13213
|
json: args.json === true,
|
|
13082
13214
|
quiet: args.quiet === true,
|
|
13083
13215
|
"non-interactive": args["non-interactive"] === true,
|
|
@@ -13112,7 +13244,8 @@ function createCli(argv) {
|
|
|
13112
13244
|
function isHandled(err) {
|
|
13113
13245
|
return err instanceof HandledCliError;
|
|
13114
13246
|
}
|
|
13115
|
-
|
|
13247
|
+
if (process.argv[2] === INTERNAL_UPDATE_CHECK_ARG) refreshUpdateCheckCache(Date.now()).catch(() => {}).finally(() => process.exit(0));
|
|
13248
|
+
else try {
|
|
13116
13249
|
const result = createCli(hideBin(process.argv)).parse();
|
|
13117
13250
|
if (result instanceof Promise) result.catch((err) => {
|
|
13118
13251
|
if (isHandled(err)) return;
|