@limecloud/cli 0.0.0-stage → 0.6.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/LICENSE +201 -0
- package/README.md +292 -2
- package/bin/limecloud-cli.mjs +5 -0
- package/dist/identity.json +1453 -0
- package/dist/locales.json +17 -0
- package/dist/management.json +24928 -0
- package/package.json +36 -4
- package/src/cli.mjs +366 -0
- package/src/commands.mjs +70 -0
- package/src/contract.mjs +68 -0
- package/src/i18n.mjs +68 -0
- package/src/input.mjs +92 -0
- package/src/install.mjs +91 -0
- package/src/locales/en.json +153 -0
- package/src/locales/zh-CN.json +153 -0
- package/src/management.mjs +161 -0
- package/src/output.mjs +61 -0
- package/src/protocol.mjs +148 -0
- package/src/resources.mjs +11 -0
- package/src/storage.mjs +96 -0
package/src/input.mjs
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { message } from "./i18n.mjs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { requestSchema } from "./contract.mjs";
|
|
4
|
+
import { CLIError } from "./protocol.mjs";
|
|
5
|
+
|
|
6
|
+
const sensitive = new Set(["access_token", "refresh_token", "id_token", "device_code", "client_secret", "code", "code_verifier", "token"]);
|
|
7
|
+
const fail = (message) => { throw new CLIError("invalid_arguments", message); };
|
|
8
|
+
|
|
9
|
+
export async function readSource(path, limit = 1_048_576) {
|
|
10
|
+
if (path !== 0) {
|
|
11
|
+
const bytes = await readFile(path);
|
|
12
|
+
if (bytes.length > limit) fail(message("arguments.inputTooLarge"));
|
|
13
|
+
return bytes;
|
|
14
|
+
}
|
|
15
|
+
const chunks = [];
|
|
16
|
+
let size = 0;
|
|
17
|
+
for await (const chunk of process.stdin) {
|
|
18
|
+
const bytes = Buffer.from(chunk); size += bytes.length;
|
|
19
|
+
if (size > limit) fail(message("arguments.inputTooLarge"));
|
|
20
|
+
chunks.push(bytes);
|
|
21
|
+
}
|
|
22
|
+
return Buffer.concat(chunks);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function jsonInput(input, readInput = async (path) => (await readSource(path)).toString("utf8")) {
|
|
26
|
+
const indirect = input === "-" || input.startsWith("@");
|
|
27
|
+
const source = indirect ? await readInput(input === "-" ? 0 : input.slice(1)) : input;
|
|
28
|
+
if (Buffer.byteLength(source) > 1_048_576) fail(message("arguments.jsonTooLarge"));
|
|
29
|
+
let value;
|
|
30
|
+
try { value = JSON.parse(source); } catch { fail(message("arguments.invalidJSON")); }
|
|
31
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) fail(message("arguments.objectRequired"));
|
|
32
|
+
return { value, indirect };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function parametersFor(parsed, env, method, readInput) {
|
|
36
|
+
const form = new URLSearchParams();
|
|
37
|
+
function append(name, value, privateInput) {
|
|
38
|
+
if (!/^[a-z][a-z0-9_]*$/.test(name)) fail(message("arguments.invalidParameterName"));
|
|
39
|
+
if (["access_token", "client_secret", "id_token"].includes(name)) fail(message("arguments.authEnvironmentRequired"));
|
|
40
|
+
if (!privateInput && sensitive.has(name)) fail(`Use --param-env or --data @file for the sensitive field ${name}`);
|
|
41
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
42
|
+
if (!["string", "number", "boolean"].includes(typeof item)) fail(message("arguments.scalarRequired", { name }));
|
|
43
|
+
form.append(name, String(item));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const flag of ["params", "data"]) {
|
|
47
|
+
const input = parsed.get(flag);
|
|
48
|
+
if (input === undefined) continue;
|
|
49
|
+
if (flag === "data" && method === "GET") fail(message("arguments.getDataUnsupported"));
|
|
50
|
+
const { value, indirect } = await jsonInput(input, readInput);
|
|
51
|
+
if (flag === "params" && method !== "GET" && Object.keys(value).length) fail(message("arguments.oauthQueryUnsupported"));
|
|
52
|
+
for (const [name, item] of Object.entries(value)) append(name, item, indirect);
|
|
53
|
+
}
|
|
54
|
+
for (const flag of ["param", "param-env"]) for (const value of parsed.flags.get(flag) ?? []) {
|
|
55
|
+
const equal = value.indexOf("=");
|
|
56
|
+
if (equal < 1) fail(message("arguments.nameValueRequired", { flag }));
|
|
57
|
+
const name = value.slice(0, equal), input = value.slice(equal + 1);
|
|
58
|
+
if (flag === "param-env") {
|
|
59
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(input) || !env[input]) fail(message("arguments.environmentValueRequired", { name }));
|
|
60
|
+
append(name, env[input], true);
|
|
61
|
+
} else append(name, input, false);
|
|
62
|
+
}
|
|
63
|
+
return form;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function validateParameters(contract, operation, form, basic, dryRun = false) {
|
|
67
|
+
const schema = requestSchema(contract, operation, form);
|
|
68
|
+
const properties = schema?.properties ?? Object.fromEntries((operation.parameters ?? []).map((p) => [p.name, p.schema]));
|
|
69
|
+
const required = schema?.required ?? (operation.parameters ?? []).filter((p) => p.required).map((p) => p.name);
|
|
70
|
+
for (const name of form.keys()) {
|
|
71
|
+
const property = properties[name];
|
|
72
|
+
if (!property) fail(message("arguments.unknownProtocolParameter", { name, command: operation.command ?? operation.operationId }));
|
|
73
|
+
const values = form.getAll(name);
|
|
74
|
+
if (values.length > 1 && property.type !== "array") fail(message("arguments.singleParameter", { name }));
|
|
75
|
+
for (const value of values) {
|
|
76
|
+
if (property.const !== undefined && value !== property.const || property.enum && !property.enum.includes(value) ||
|
|
77
|
+
property.minLength !== undefined && value.length < property.minLength ||
|
|
78
|
+
property.maxLength !== undefined && value.length > property.maxLength) fail(message("arguments.invalidParameterValue", { name }));
|
|
79
|
+
}
|
|
80
|
+
if (operation.method === "GET" && sensitive.has(name)) fail(message("arguments.credentialsInURL"));
|
|
81
|
+
}
|
|
82
|
+
for (const name of required) if (!form.get(name)) fail(message("arguments.requiredParameter", { name }));
|
|
83
|
+
if (!dryRun && !basic && ["/oauth/token", "/oauth/device/authorization", "/oauth/revoke"].includes(operation.path) && !form.get("client_id")) {
|
|
84
|
+
fail(message("arguments.clientIDRequired"));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function scopeList(value) {
|
|
89
|
+
const scopes = value.trim().split(/[\s,]+/).filter(Boolean);
|
|
90
|
+
if (!scopes.length || scopes.some((scope) => !/^[A-Za-z0-9_:.\/-]{1,100}$/.test(scope)) || new Set(scopes).size !== scopes.length) fail(message("arguments.uniqueScopesRequired"));
|
|
91
|
+
return scopes;
|
|
92
|
+
}
|
package/src/install.mjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { access, readFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { createInterface } from "node:readline/promises";
|
|
6
|
+
import { CLIError } from "./protocol.mjs";
|
|
7
|
+
import { message, translate } from "./i18n.mjs";
|
|
8
|
+
import { validateSettings } from "./storage.mjs";
|
|
9
|
+
|
|
10
|
+
export function installationPlan(version, prefix, env = process.env) {
|
|
11
|
+
const destination = prefix ?? env.LIMECLOUD_INSTALL_PREFIX ?? join(homedir(), ".local");
|
|
12
|
+
if (typeof destination !== "string" || !destination.trim() || destination.length > 2048 || /[\x00-\x1f\x7f]/.test(destination)) {
|
|
13
|
+
throw new CLIError("invalid_arguments", message("install.invalidPrefix"));
|
|
14
|
+
}
|
|
15
|
+
const absolute = resolve(destination);
|
|
16
|
+
const bin = process.platform === "win32" ? absolute : join(absolute, "bin");
|
|
17
|
+
return { package: "@limecloud/cli", version, prefix: absolute, bin_directory: bin,
|
|
18
|
+
executable: join(bin, process.platform === "win32" ? "limecloud-cli.cmd" : "limecloud-cli"),
|
|
19
|
+
command: ["npm", "install", "--global", "--prefix", absolute, "--no-audit", "--no-fund", `@limecloud/cli@${version}`] };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 参数通过 argv 传递,不经 shell;npm 输出走 stderr,保持 stdout 的结构化合同。
|
|
23
|
+
export async function installRuntime(plan, { env = process.env, io = process, signal } = {}) {
|
|
24
|
+
const npmScript = env.npm_execpath;
|
|
25
|
+
const fromNpm = typeof npmScript === "string" && /(?:^|[\\/])npm-cli\.js$/.test(npmScript);
|
|
26
|
+
if (process.platform === "win32" && !fromNpm) throw new CLIError("installation_failed", message("install.npmRequired"));
|
|
27
|
+
const command = fromNpm ? process.execPath : "npm";
|
|
28
|
+
const args = [...(fromNpm ? [npmScript] : []), ...plan.command.slice(1)];
|
|
29
|
+
await new Promise((done, reject) => {
|
|
30
|
+
const child = spawn(command, args, { env, signal, shell: false, stdio: ["ignore", "pipe", "pipe"] });
|
|
31
|
+
child.stdout.on("data", value => io.stderr.write(value));
|
|
32
|
+
child.stderr.on("data", value => io.stderr.write(value));
|
|
33
|
+
child.once("error", () => reject(new CLIError("installation_failed", message("install.failed", { prefix: plan.prefix }))));
|
|
34
|
+
child.once("exit", status => status === 0 ? done() : reject(new CLIError("installation_failed", message("install.failed", { prefix: plan.prefix }))));
|
|
35
|
+
});
|
|
36
|
+
try {
|
|
37
|
+
const moduleRoot = process.platform === "win32" ? join(plan.prefix, "node_modules") : join(plan.prefix, "lib", "node_modules");
|
|
38
|
+
const installed = JSON.parse(await readFile(join(moduleRoot, "@limecloud", "cli", "package.json"), "utf8"));
|
|
39
|
+
await access(plan.executable);
|
|
40
|
+
if (installed.name !== plan.package || installed.version !== plan.version) throw new Error("Unexpected installed package");
|
|
41
|
+
} catch { throw new CLIError("installation_failed", message("install.verificationFailed")); }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function withSetupPrompt({ io = process, prompt, signal, interactive = true }, action) {
|
|
45
|
+
if (prompt) return action(prompt);
|
|
46
|
+
if (!interactive || !io.stdin?.isTTY) return action(undefined);
|
|
47
|
+
const terminal = createInterface({ input: io.stdin, output: io.stderr });
|
|
48
|
+
try {
|
|
49
|
+
return await action(async (key, value = "") => {
|
|
50
|
+
const answer = await terminal.question(translate(key, { value }), signal ? { signal } : {});
|
|
51
|
+
return answer.trim() || value;
|
|
52
|
+
});
|
|
53
|
+
} finally { terminal.close(); }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function initialSettings(parsed, env, old, ask) {
|
|
57
|
+
const settings = { issuer: parsed.get("issuer") ?? env.LIMECLOUD_ISSUER ?? old.issuer ?? "https://auth.limeai.run",
|
|
58
|
+
api_origin: parsed.get("api-origin") ?? env.LIMECLOUD_API_ORIGIN ?? old.api_origin,
|
|
59
|
+
client_id: parsed.get("client-id") ?? env.LIMECLOUD_CLIENT_ID ?? old.client_id,
|
|
60
|
+
scope: parsed.get("scope") ?? old.scope ?? "openid profile email offline_access" };
|
|
61
|
+
if (ask) {
|
|
62
|
+
if (!parsed.get("issuer") && !env.LIMECLOUD_ISSUER) settings.issuer = await ask("install.promptIssuer", settings.issuer);
|
|
63
|
+
if (!parsed.get("api-origin") && !env.LIMECLOUD_API_ORIGIN) settings.api_origin = await ask("install.promptAPIOrigin", settings.api_origin ?? "");
|
|
64
|
+
if (!parsed.get("client-id") && !env.LIMECLOUD_CLIENT_ID) settings.client_id = await ask("install.promptClientID", settings.client_id ?? "");
|
|
65
|
+
}
|
|
66
|
+
return validateSettings(Object.fromEntries(Object.entries(settings).filter(([, value]) => value !== undefined && value !== "")));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function discoverCLISettings(settings, request) {
|
|
70
|
+
const response = await request({ issuer: settings.issuer, path: "/runtime/v1/cli" });
|
|
71
|
+
const metadata = response?.data;
|
|
72
|
+
if (!metadata || typeof metadata !== "object" || metadata.issuer !== settings.issuer ||
|
|
73
|
+
typeof metadata.client_id !== "string" || !metadata.client_id || typeof metadata.api_origin !== "string" ||
|
|
74
|
+
metadata.scope !== "openid profile email offline_access") {
|
|
75
|
+
throw new CLIError("invalid_response", message("install.invalidMetadata"));
|
|
76
|
+
}
|
|
77
|
+
const defaults = validateSettings({ issuer: metadata.issuer, api_origin: metadata.api_origin, client_id: metadata.client_id, scope: metadata.scope });
|
|
78
|
+
return { ...defaults, ...settings, client_id: settings.client_id ?? defaults.client_id, api_origin: settings.api_origin ?? defaults.api_origin };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function configureInitialSettings(settingsStore, parsed, env, ask, allowIncomplete = false, defaults = {}) {
|
|
82
|
+
return settingsStore.withLock(async () => {
|
|
83
|
+
const settings = await initialSettings(parsed, env, { ...defaults, ...await settingsStore.read() }, ask);
|
|
84
|
+
if (!settings.client_id) {
|
|
85
|
+
if (allowIncomplete) return null;
|
|
86
|
+
throw new CLIError("invalid_arguments", message("arguments.publicClientRequired"));
|
|
87
|
+
}
|
|
88
|
+
await settingsStore.write(settings);
|
|
89
|
+
return settings;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
{
|
|
2
|
+
"arguments.docsUsage": "Use docs [article-slug]",
|
|
3
|
+
"arguments.publicClientRequired": "Provide the already registered public client with --client-id",
|
|
4
|
+
"arguments.configUsage": "Use config init, config show or config set <issuer|api_origin|client_id|scope> <value>",
|
|
5
|
+
"arguments.tooMany": "Too many arguments; use --help",
|
|
6
|
+
"arguments.operationRequired": "Choose a public operationId from api list",
|
|
7
|
+
"arguments.basicCredentialsRequired": "This request requires LIMECLOUD_CLIENT_ID and LIMECLOUD_CLIENT_SECRET",
|
|
8
|
+
"arguments.unknownCommand": "Unknown command or public method; use --help or schema identity",
|
|
9
|
+
"arguments.scopeCheckUsage": "Use auth check --scope SCOPES",
|
|
10
|
+
"arguments.publicClientOnly": "Auth commands require a public client; unset LIMECLOUD_CLIENT_SECRET",
|
|
11
|
+
"arguments.externalTokenActive": "Unset LIMECLOUD_ACCESS_TOKEN before managing saved credentials; revoke environment tokens explicitly with api",
|
|
12
|
+
"arguments.deviceModeConflict": "--no-wait and --resume cannot be combined",
|
|
13
|
+
"arguments.resumeContextImmutable": "A resumed authorization keeps its original scope and installation context",
|
|
14
|
+
"arguments.installationContextPair": "--installation-id and --space-id must be supplied together",
|
|
15
|
+
"arguments.resumeIdentityMismatch": "Resume issuer and client ID must match the saved device authorization",
|
|
16
|
+
"arguments.resumeOriginMismatch": "Resume API origin must match the original device authorization",
|
|
17
|
+
"arguments.registeredClientRequired": "Provide a registered public client with --client-id or config init",
|
|
18
|
+
"arguments.openidRequired": "Device sign-in requires the openid scope",
|
|
19
|
+
"arguments.inputTooLarge": "Input exceeds its byte limit",
|
|
20
|
+
"arguments.jsonTooLarge": "JSON input exceeds 1 MiB",
|
|
21
|
+
"arguments.invalidJSON": "Invalid JSON input",
|
|
22
|
+
"arguments.objectRequired": "JSON input must be an object",
|
|
23
|
+
"arguments.invalidParameterName": "Invalid parameter name",
|
|
24
|
+
"arguments.authEnvironmentRequired": "Use credential environment variables for authentication",
|
|
25
|
+
"arguments.getDataUnsupported": "GET accepts --params, not --data",
|
|
26
|
+
"arguments.oauthQueryUnsupported": "OAuth POST fields belong in --data, not query --params",
|
|
27
|
+
"arguments.credentialsInURL": "Credential parameters cannot be sent in URLs",
|
|
28
|
+
"arguments.clientIDRequired": "Set --client-id or LIMECLOUD_CLIENT_ID for this public-client request",
|
|
29
|
+
"arguments.uniqueScopesRequired": "Provide a non-empty list of unique scopes",
|
|
30
|
+
"arguments.invalidFormat": "--format must be json, ndjson, table or csv",
|
|
31
|
+
"arguments.formatConflict": "--json conflicts with --format",
|
|
32
|
+
"arguments.invalidFields": "--fields must be comma-separated field paths",
|
|
33
|
+
"arguments.privateJSONRequired": "Sensitive JSON fields require --data @file, stdin, or --param-env",
|
|
34
|
+
"arguments.numericRequired": "Expected a numeric parameter",
|
|
35
|
+
"arguments.booleanRequired": "Expected true or false",
|
|
36
|
+
"arguments.structuredJSONRequired": "Structured typed fields require a JSON value",
|
|
37
|
+
"arguments.fileUnsupported": "This public method does not accept --file",
|
|
38
|
+
"arguments.binaryBodyConflict": "Use --file alone for a binary request body",
|
|
39
|
+
"arguments.invalidPNG": "Choose a cropped 256 by 256 PNG no larger than 320 KiB",
|
|
40
|
+
"arguments.dataUnsupported": "This public method does not accept --data",
|
|
41
|
+
"arguments.privateFieldRequired": "Sensitive fields require --param-env or private JSON input",
|
|
42
|
+
"arguments.headerUndeclared": "Only contract-declared HTTP headers can be set",
|
|
43
|
+
"arguments.unsafeHeader": "Unsafe or reserved request header",
|
|
44
|
+
"arguments.fileRequired": "This public method requires --file PNG_PATH (or --file - for stdin)",
|
|
45
|
+
"arguments.dataRequired": "This public method requires --data JSON",
|
|
46
|
+
"arguments.configKeys": "Supported config keys: issuer, api_origin, client_id, scope",
|
|
47
|
+
"arguments.invalidClientID": "client_id must be a registered public client ID",
|
|
48
|
+
"arguments.invalidScope": "scope must be a space-separated string",
|
|
49
|
+
"arguments.grantTypeRequired": "Choose a supported grant_type; use schema identity.token.exchange",
|
|
50
|
+
"contract.commandMappingRequired": "Every public CLI operation needs an explicit service.resource.method mapping",
|
|
51
|
+
"contract.versionMismatch": "Public API contract versions must match",
|
|
52
|
+
"contract.securityCollision": "Public API security scheme collision",
|
|
53
|
+
"contract.unexpectedPath": "Management contract contains an unexpected public path",
|
|
54
|
+
"contract.duplicatePath": "Duplicate public API path",
|
|
55
|
+
"contract.duplicateOperation": "Duplicate public operationId",
|
|
56
|
+
"contract.referenceUnsupported": "Unsupported public schema reference",
|
|
57
|
+
"contract.referenceUnknown": "Unknown public schema reference",
|
|
58
|
+
"auth.loginRequired": "Run auth login or set LIMECLOUD_ACCESS_TOKEN",
|
|
59
|
+
"auth.tokenExpired": "Run auth refresh or start auth login again",
|
|
60
|
+
"auth.apiOriginRequired": "Set --api-origin, LIMECLOUD_API_ORIGIN or config api_origin before calling a business API",
|
|
61
|
+
"auth.apiBindingChanged": "API origin changed or was not bound to this login; run auth login with the intended --api-origin",
|
|
62
|
+
"auth.externalScopesUnknown": "Environment-token scopes are unknown; use a saved login or verify remotely in your application",
|
|
63
|
+
"auth.discoveryInvalid": "Discovery did not return this issuer and its supported scopes",
|
|
64
|
+
"auth.pendingMissing": "No pending device authorization; start auth login --no-wait",
|
|
65
|
+
"auth.pendingCodeInvalid": "Invalid pending user code",
|
|
66
|
+
"auth.refreshUncertain": "A previous refresh has an unknown result; start auth login again",
|
|
67
|
+
"auth.refreshMissing": "No refresh token is saved; start auth login again",
|
|
68
|
+
"auth.refreshBindingChanged": "API origin changed; refreshing cannot bind an existing grant to another API. Start auth login again",
|
|
69
|
+
"storage.unsafeFile": "Local configuration must be a regular file owned by this user with mode 0600",
|
|
70
|
+
"storage.unreadable": "Unable to read private local configuration; check the file or select another path",
|
|
71
|
+
"storage.busy": "Another command holds this configuration lock; finish it before retrying",
|
|
72
|
+
"storage.invalidCredentials": "Invalid saved credentials; use a separate LIMECLOUD_CONFIG and sign in again",
|
|
73
|
+
"protocol.invalidIssuer": "Issuer must be an absolute HTTPS origin",
|
|
74
|
+
"protocol.insecureIssuer": "Issuer must be an HTTPS origin; HTTP is allowed only on loopback",
|
|
75
|
+
"protocol.invalidVerificationURI": "Invalid device verification URI",
|
|
76
|
+
"protocol.verificationIssuerMismatch": "Device verification URI does not match this issuer",
|
|
77
|
+
"protocol.invalidEndpoint": "Endpoint must be a contract path on this issuer",
|
|
78
|
+
"protocol.basicClientRequired": "Set LIMECLOUD_CLIENT_ID with LIMECLOUD_CLIENT_SECRET",
|
|
79
|
+
"protocol.requestUncertain": "Request failed or timed out; a token exchange may have completed. Do not replay an uncertain token exchange",
|
|
80
|
+
"protocol.redirectRefused": "Endpoint returned a redirect; no follow-up request was sent",
|
|
81
|
+
"protocol.nonJSONResponse": "Endpoint returned a non-JSON response",
|
|
82
|
+
"protocol.invalidTokenResponse": "Invalid OAuth token response; start a new login",
|
|
83
|
+
"protocol.invalidDeviceResponse": "Invalid device authorization response",
|
|
84
|
+
"protocol.deviceExchangeUncertain": "The previous device token exchange has an unknown result; start a new auth login",
|
|
85
|
+
"protocol.invalidPendingDevice": "Invalid pending device authorization",
|
|
86
|
+
"protocol.deviceExpired": "Device authorization expired; start auth login again",
|
|
87
|
+
"arguments.unknownOption": "Unknown option --{{name}}",
|
|
88
|
+
"arguments.booleanOptionValue": "--{{name}} does not take a value",
|
|
89
|
+
"arguments.optionValueRequired": "--{{name}} needs a value",
|
|
90
|
+
"arguments.duplicateOption": "Duplicate option --{{name}}",
|
|
91
|
+
"arguments.optionUnsupported": "Option --{{name}} is not supported by this command",
|
|
92
|
+
"arguments.noPositionals": "Use {{command}} without positional arguments",
|
|
93
|
+
"auth.requiredScopes": "This method requires explicit login scopes: {{scopes}}",
|
|
94
|
+
"auth.missingScopes": "Missing locally granted scopes: {{scopes}}",
|
|
95
|
+
"arguments.sensitiveField": "Use --param-env or --data @file for the sensitive field {{name}}",
|
|
96
|
+
"arguments.scalarRequired": "Parameter {{name}} must be a scalar or array of scalars",
|
|
97
|
+
"arguments.nameValueRequired": "--{{flag}} requires name=value",
|
|
98
|
+
"arguments.environmentValueRequired": "--param-env {{name}} requires a populated environment variable",
|
|
99
|
+
"arguments.unknownProtocolParameter": "Unknown parameter {{name}}; use schema {{command}}",
|
|
100
|
+
"arguments.singleParameter": "Parameter {{name}} must occur once",
|
|
101
|
+
"arguments.invalidParameterValue": "Invalid value for {{name}}",
|
|
102
|
+
"arguments.requiredParameter": "Required parameter: {{name}}",
|
|
103
|
+
"arguments.schemaMismatch": "{{label}} does not match its public schema",
|
|
104
|
+
"arguments.unsupportedValue": "{{label}} has an unsupported value",
|
|
105
|
+
"arguments.wrongType": "{{label}} has the wrong type",
|
|
106
|
+
"arguments.invalidString": "{{label}} has an invalid string value",
|
|
107
|
+
"arguments.outsideRange": "{{label}} is outside the allowed range",
|
|
108
|
+
"arguments.invalidItemCount": "{{label}} has an invalid number of items",
|
|
109
|
+
"arguments.requiredField": "{{label}}.{{name}} is required",
|
|
110
|
+
"arguments.undeclaredField": "{{label}}.{{name}} is not a declared field",
|
|
111
|
+
"arguments.unknownParameter": "Unknown parameter {{name}}",
|
|
112
|
+
"arguments.unknownRequestParameter": "Unknown path/query/header parameter {{name}}",
|
|
113
|
+
"arguments.pathConflict": "Path parameter {{name}} conflicts with the raw HTTP path",
|
|
114
|
+
"arguments.requiredRequestParameter": "Required {{location}} parameter: {{name}}",
|
|
115
|
+
"arguments.invalidPathParameter": "Invalid path parameter {{name}}",
|
|
116
|
+
"arguments.requiredPathParameter": "Required path parameter: {{name}}",
|
|
117
|
+
"arguments.unknownSchema": "Unknown schema path: {{target}}; start with schema",
|
|
118
|
+
"protocol.apiFailed": "API request failed: {{code}} (HTTP {{status}})",
|
|
119
|
+
"help.overview": "limecloud-cli — Lime Cloud CLI (@limecloud/cli)\n\nUsage:\n limecloud-cli <command> [resource] [method] [flags]\n limecloud-cli identity +login | +whoami\n limecloud-cli identity token exchange --data <json>\n limecloud-cli api <METHOD> <contract-path> [--params <json>] [--data <json>]\n limecloud-cli schema [service.resource.method | service resource method]\n\nIdentity:\n identity Public OAuth / OpenID Connect operations and +shortcuts\n\nCLI management:\n install Install this CLI and guide first-time setup\n config init | show | set: local public-client configuration\n auth login | status | whoami | refresh | logout | scopes | check\n whoami Show the local effective identity and token state\n doctor Check local configuration and contract (--offline; no network)\n docs Print a documentation URL\n\nAPI tools:\n api Call a contract HTTP path; list/schema/call also accept operationId\n schema Inspect public methods, parameters, responses and authentication\n\n",
|
|
120
|
+
"help.apiFlags": "API flags:\n --params JSON Query JSON; supports @file or - for stdin\n --data JSON OAuth form or API JSON body; supports @file or - for stdin\n --dry-run Print a redacted request without executing or changing state\n --format FORMAT json (default), ndjson, table or csv\n --fields PATHS Comma-separated data field paths\n --json Shorthand for --format json\n --param name=value Repeat a non-sensitive protocol parameter\n --param-env name=ENV Read a sensitive protocol parameter from an environment variable\n --header name=value Set a contract-declared HTTP header\n --file PATH Binary body for image/png methods; - reads stdin\n --show-secrets Explicitly include API response credentials in stdout\n\n",
|
|
121
|
+
"help.connectionFlags": "Connection flags:\n --issuer ORIGIN Auth origin (HTTPS; HTTP only on loopback)\n --api-origin ORIGIN Explicit business API origin, bound to the saved login\n --client-id ID Already registered sign-in client ID\n --auth-client-id ID Override the OAuth client context for a business API call\n\n --locale TAG Output language (also LIMECLOUD_LOCALE, LC_ALL, LC_MESSAGES, LANG)\n\nRun limecloud-cli <command> --help or schema identity before calling a method.\n",
|
|
122
|
+
"help.auth": "Usage: auth <login|status|whoami|refresh|logout|scopes|check> [flags]\n\nlogin --client-id ID [--scope \"openid profile\"] [--installation-id ID --space-id ID]\n --no-wait: return a verification URL and save private pending state\n --resume: complete the saved authorization without exposing its device code\nstatus: local state; whoami: remote UserInfo; refresh: rotate stored credentials\nlogout [--local-only]: revoke, then forget; --local-only forgets without revocation\nscopes: read supported OIDC scopes and report locally granted scopes\ncheck --scope SCOPES: check unexpired local granted scopes (no network)\n\nAuth commands use an already registered public client. --dry-run previews login, refresh, logout or scopes without execution.\n",
|
|
123
|
+
"help.config": "Usage:\n config init\n config init --issuer ORIGIN --client-id ID [--api-origin ORIGIN] [--scope SCOPES]\n config show\n config set <issuer|api_origin|client_id|scope> <value>\n\nConfiguration stores public client settings only. Business API origin must be explicit; changing it requires a new login binding.\n",
|
|
124
|
+
"help.schema": "Usage: schema [identity | identity.resource | identity.resource.method | identity resource method]\nReturns public inputSchema, outputSchema and _meta derived from the OpenAPI contract. Risk: read.\n",
|
|
125
|
+
"help.identityShortcuts": "Identity shortcuts:\n identity +login [--scope SCOPES] [--no-wait | --resume]\n identity +whoami\n\n",
|
|
126
|
+
"help.typedMethods": "Typed API commands:\n{{methods}}\n\nUse schema {{service}}.<resource>.<method> for parameters. --dry-run executes nothing.\n",
|
|
127
|
+
"help.services": "Available services: {{services}}\n",
|
|
128
|
+
"help.api": "Usage: api GET <path> --params JSON\n api POST <path> --data JSON\n api list [query] [--locale TAG]\n api schema <operationId>\n api call <operationId> [flags]\n\nOnly exact public contract paths are callable. Arbitrary URLs and management BFF paths are rejected.\n",
|
|
129
|
+
"errors.cancelled": "Command cancelled",
|
|
130
|
+
"errors.failed": "Command failed; check local configuration and retry",
|
|
131
|
+
"arguments.unsupportedLocale": "Unsupported --locale; choose one of: {{locales}}",
|
|
132
|
+
"auth.deviceNotice": "Open {{uri}}\nConfirm code: {{code}}\n",
|
|
133
|
+
"columns.command": "command",
|
|
134
|
+
"columns.operationId": "operationId",
|
|
135
|
+
"columns.method": "method",
|
|
136
|
+
"columns.path": "path",
|
|
137
|
+
"columns.summary": "summary",
|
|
138
|
+
"columns.description": "description",
|
|
139
|
+
"columns.value": "value",
|
|
140
|
+
"help.install": "Usage:\n npx @limecloud/cli@latest install [--prefix DIRECTORY]\n limecloud-cli install --client-id ID --issuer ORIGIN --api-origin ORIGIN [--skip-login]\n limecloud-cli install --dry-run [--no-config]\n\nInstalls this package version to ~/.local by default, then guides public-client configuration and optional device authorization. Missing Client ID defaults come from the issuer public /runtime/v1/cli metadata. --prefix or LIMECLOUD_INSTALL_PREFIX changes the destination. Non-interactive runs leave missing configuration pending. --login explicitly starts device authorization without waiting; --no-config skips setup. Shell profiles and Agent skills are not modified.\n",
|
|
141
|
+
"install.invalidPrefix": "Provide a valid installation directory with --prefix",
|
|
142
|
+
"install.invalidMetadata": "The public CLI setup metadata does not match this identity service or the supported setup contract",
|
|
143
|
+
"install.discoveryUnavailable": "Public CLI setup metadata is unavailable. Run limecloud-cli config init and use the public CLI Client ID provided by your deployment administrator.",
|
|
144
|
+
"install.npmRequired": "Run installation through npx so the npm JavaScript entry point is available on Windows",
|
|
145
|
+
"install.failed": "CLI installation failed; check npm access and permissions for {{prefix}}, then retry install",
|
|
146
|
+
"install.verificationFailed": "npm finished, but the installed CLI version or executable could not be verified",
|
|
147
|
+
"install.usage": "Use install [--prefix DIRECTORY] [--client-id ID] [--skip-login | --login]; --login cannot be combined with --no-config",
|
|
148
|
+
"install.promptIssuer": "Identity service origin [{{value}}]: ",
|
|
149
|
+
"install.promptAPIOrigin": "Business API origin (leave empty for identity-only use) [{{value}}]: ",
|
|
150
|
+
"install.promptClientID": "Already registered public CLI Client ID [{{value}}]: ",
|
|
151
|
+
"install.promptLogin": "Start device authorization now? You must confirm it in your browser (y/N) [{{value}}]: ",
|
|
152
|
+
"install.pathHint": "Add {{directory}} to PATH to run limecloud-cli from any terminal."
|
|
153
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
{
|
|
2
|
+
"arguments.docsUsage": "使用 docs [article-slug]",
|
|
3
|
+
"arguments.publicClientRequired": "通过 --client-id 指定已登记的公共客户端",
|
|
4
|
+
"arguments.configUsage": "使用 config init、config show 或 config set <issuer|api_origin|client_id|scope> <value>",
|
|
5
|
+
"arguments.tooMany": "参数过多;请使用 --help",
|
|
6
|
+
"arguments.operationRequired": "从 api list 选择公开的 operationId",
|
|
7
|
+
"arguments.basicCredentialsRequired": "此请求需要 LIMECLOUD_CLIENT_ID 和 LIMECLOUD_CLIENT_SECRET",
|
|
8
|
+
"arguments.unknownCommand": "未知命令或公开方法;请使用 --help 或 schema identity",
|
|
9
|
+
"arguments.scopeCheckUsage": "使用 auth check --scope SCOPES",
|
|
10
|
+
"arguments.publicClientOnly": "Auth 命令需要公共客户端;请取消设置 LIMECLOUD_CLIENT_SECRET",
|
|
11
|
+
"arguments.externalTokenActive": "管理已保存凭据前请取消设置 LIMECLOUD_ACCESS_TOKEN;环境令牌需通过 api 显式撤销",
|
|
12
|
+
"arguments.deviceModeConflict": "--no-wait 与 --resume 不能同时使用",
|
|
13
|
+
"arguments.resumeContextImmutable": "恢复授权时须保留原始 Scope 与安装上下文",
|
|
14
|
+
"arguments.installationContextPair": "--installation-id 与 --space-id 必须一起提供",
|
|
15
|
+
"arguments.resumeIdentityMismatch": "恢复时的 Issuer 与客户端 ID 必须匹配已保存的设备授权",
|
|
16
|
+
"arguments.resumeOriginMismatch": "恢复时的 API Origin 必须匹配原始设备授权",
|
|
17
|
+
"arguments.registeredClientRequired": "通过 --client-id 或 config init 指定已登记的公共客户端",
|
|
18
|
+
"arguments.openidRequired": "设备登录需要 openid Scope",
|
|
19
|
+
"arguments.inputTooLarge": "输入超过允许的字节数",
|
|
20
|
+
"arguments.jsonTooLarge": "JSON 输入超过 1 MiB",
|
|
21
|
+
"arguments.invalidJSON": "JSON 输入无效",
|
|
22
|
+
"arguments.objectRequired": "JSON 输入必须为对象",
|
|
23
|
+
"arguments.invalidParameterName": "参数名无效",
|
|
24
|
+
"arguments.authEnvironmentRequired": "请使用凭据环境变量进行身份验证",
|
|
25
|
+
"arguments.getDataUnsupported": "GET 请求请使用 --params,不能使用 --data",
|
|
26
|
+
"arguments.oauthQueryUnsupported": "OAuth POST 字段应放在 --data 中,不能放在查询 --params 中",
|
|
27
|
+
"arguments.credentialsInURL": "凭据参数不能通过 URL 发送",
|
|
28
|
+
"arguments.clientIDRequired": "为此公共客户端请求设置 --client-id 或 LIMECLOUD_CLIENT_ID",
|
|
29
|
+
"arguments.uniqueScopesRequired": "请提供非空且不重复的 Scope 列表",
|
|
30
|
+
"arguments.invalidFormat": "--format 必须为 json、ndjson、table 或 csv",
|
|
31
|
+
"arguments.formatConflict": "--json 与 --format 冲突",
|
|
32
|
+
"arguments.invalidFields": "--fields 必须为逗号分隔的字段路径",
|
|
33
|
+
"arguments.privateJSONRequired": "敏感 JSON 字段需使用 --data @file、标准输入或 --param-env",
|
|
34
|
+
"arguments.numericRequired": "参数必须为数值",
|
|
35
|
+
"arguments.booleanRequired": "参数必须为 true 或 false",
|
|
36
|
+
"arguments.structuredJSONRequired": "结构化字段必须提供 JSON 值",
|
|
37
|
+
"arguments.fileUnsupported": "此公开方法不支持 --file",
|
|
38
|
+
"arguments.binaryBodyConflict": "二进制请求体仅使用 --file",
|
|
39
|
+
"arguments.invalidPNG": "请选择不超过 320 KiB 的 256 × 256 PNG 图片",
|
|
40
|
+
"arguments.dataUnsupported": "此公开方法不支持 --data",
|
|
41
|
+
"arguments.privateFieldRequired": "敏感字段需使用 --param-env 或私有 JSON 输入",
|
|
42
|
+
"arguments.headerUndeclared": "只能设置公开合同声明的 HTTP 请求头",
|
|
43
|
+
"arguments.unsafeHeader": "请求头不安全或被保留",
|
|
44
|
+
"arguments.fileRequired": "此公开方法需要 --file PNG_PATH,或使用 --file - 从标准输入读取",
|
|
45
|
+
"arguments.dataRequired": "此公开方法需要 --data JSON",
|
|
46
|
+
"arguments.configKeys": "支持的配置键为 issuer、api_origin、client_id、scope",
|
|
47
|
+
"arguments.invalidClientID": "client_id 必须为已登记的公共客户端 ID",
|
|
48
|
+
"arguments.invalidScope": "scope 必须为空格分隔的字符串",
|
|
49
|
+
"arguments.grantTypeRequired": "请选择支持的 grant_type;使用 schema identity.token.exchange 查看",
|
|
50
|
+
"contract.commandMappingRequired": "每个公开 CLI 操作都需要显式的 service.resource.method 映射",
|
|
51
|
+
"contract.versionMismatch": "公开 API 合同版本必须一致",
|
|
52
|
+
"contract.securityCollision": "公开 API 安全方案发生冲突",
|
|
53
|
+
"contract.unexpectedPath": "管理合同包含非预期的公开路径",
|
|
54
|
+
"contract.duplicatePath": "公开 API 路径重复",
|
|
55
|
+
"contract.duplicateOperation": "公开 operationId 重复",
|
|
56
|
+
"contract.referenceUnsupported": "不支持此公开 Schema 引用",
|
|
57
|
+
"contract.referenceUnknown": "未知的公开 Schema 引用",
|
|
58
|
+
"auth.loginRequired": "请运行 auth login 或设置 LIMECLOUD_ACCESS_TOKEN",
|
|
59
|
+
"auth.tokenExpired": "请运行 auth refresh 或重新运行 auth login",
|
|
60
|
+
"auth.apiOriginRequired": "调用业务 API 前,请设置 --api-origin、LIMECLOUD_API_ORIGIN 或配置 api_origin",
|
|
61
|
+
"auth.apiBindingChanged": "API Origin 已改变或未绑定此登录;请指定目标 --api-origin 运行 auth login",
|
|
62
|
+
"auth.externalScopesUnknown": "无法确定环境令牌的 Scope;请使用已保存登录,或由应用远程验证",
|
|
63
|
+
"auth.discoveryInvalid": "发现文档未返回当前 Issuer 及其支持的 Scope",
|
|
64
|
+
"auth.pendingMissing": "没有待完成的设备授权;请运行 auth login --no-wait",
|
|
65
|
+
"auth.pendingCodeInvalid": "待完成授权的用户码无效",
|
|
66
|
+
"auth.refreshUncertain": "上一次刷新结果未知;请重新运行 auth login",
|
|
67
|
+
"auth.refreshMissing": "未保存刷新令牌;请重新运行 auth login",
|
|
68
|
+
"auth.refreshBindingChanged": "API Origin 已改变;刷新不能将已有授权绑定到另一个 API,请重新运行 auth login",
|
|
69
|
+
"storage.unsafeFile": "本地配置须为当前用户所有、权限为 0600 的普通文件",
|
|
70
|
+
"storage.unreadable": "无法读取私有本地配置;请检查文件或选择其他路径",
|
|
71
|
+
"storage.busy": "其他命令持有此配置锁;请等待其完成后重试",
|
|
72
|
+
"storage.invalidCredentials": "已保存凭据无效;请使用独立 LIMECLOUD_CONFIG 并重新登录",
|
|
73
|
+
"protocol.invalidIssuer": "Issuer 必须为绝对 HTTPS 来源",
|
|
74
|
+
"protocol.insecureIssuer": "Issuer 必须为 HTTPS 来源;HTTP 仅允许回环地址",
|
|
75
|
+
"protocol.invalidVerificationURI": "设备验证 URI 无效",
|
|
76
|
+
"protocol.verificationIssuerMismatch": "设备验证 URI 与当前 Issuer 不匹配",
|
|
77
|
+
"protocol.invalidEndpoint": "端点必须为当前 Issuer 上公开合同声明的路径",
|
|
78
|
+
"protocol.basicClientRequired": "设置 LIMECLOUD_CLIENT_SECRET 时也须设置 LIMECLOUD_CLIENT_ID",
|
|
79
|
+
"protocol.requestUncertain": "请求失败或超时,令牌兑换可能已完成;请勿重放结果未知的令牌兑换",
|
|
80
|
+
"protocol.redirectRefused": "端点返回重定向,未发送后续请求",
|
|
81
|
+
"protocol.nonJSONResponse": "端点返回了非 JSON 响应",
|
|
82
|
+
"protocol.invalidTokenResponse": "OAuth 令牌响应无效;请重新登录",
|
|
83
|
+
"protocol.invalidDeviceResponse": "设备授权响应无效",
|
|
84
|
+
"protocol.deviceExchangeUncertain": "上一次设备令牌兑换结果未知;请重新运行 auth login",
|
|
85
|
+
"protocol.invalidPendingDevice": "待完成的设备授权无效",
|
|
86
|
+
"protocol.deviceExpired": "设备授权已到期;请重新运行 auth login",
|
|
87
|
+
"arguments.unknownOption": "未知选项 --{{name}}",
|
|
88
|
+
"arguments.booleanOptionValue": "--{{name}} 不接受值",
|
|
89
|
+
"arguments.optionValueRequired": "--{{name}} 需要一个值",
|
|
90
|
+
"arguments.duplicateOption": "选项 --{{name}} 重复",
|
|
91
|
+
"arguments.optionUnsupported": "此命令不支持 --{{name}} 选项",
|
|
92
|
+
"arguments.noPositionals": "使用 {{command}} 时不要提供位置参数",
|
|
93
|
+
"auth.requiredScopes": "此方法需要显式登录 Scope:{{scopes}}",
|
|
94
|
+
"auth.missingScopes": "缺少本地已授予的 Scope:{{scopes}}",
|
|
95
|
+
"arguments.sensitiveField": "敏感字段 {{name}} 请使用 --param-env 或 --data @file",
|
|
96
|
+
"arguments.scalarRequired": "参数 {{name}} 必须为标量或标量数组",
|
|
97
|
+
"arguments.nameValueRequired": "--{{flag}} 需要 name=value",
|
|
98
|
+
"arguments.environmentValueRequired": "--param-env {{name}} 需要非空环境变量",
|
|
99
|
+
"arguments.unknownProtocolParameter": "未知参数 {{name}};请使用 schema {{command}}",
|
|
100
|
+
"arguments.singleParameter": "参数 {{name}} 只能出现一次",
|
|
101
|
+
"arguments.invalidParameterValue": "参数 {{name}} 的值无效",
|
|
102
|
+
"arguments.requiredParameter": "缺少必填参数:{{name}}",
|
|
103
|
+
"arguments.schemaMismatch": "{{label}} 与公开 Schema 不匹配",
|
|
104
|
+
"arguments.unsupportedValue": "{{label}} 的值不受支持",
|
|
105
|
+
"arguments.wrongType": "{{label}} 的类型错误",
|
|
106
|
+
"arguments.invalidString": "{{label}} 的字符串值无效",
|
|
107
|
+
"arguments.outsideRange": "{{label}} 超出允许范围",
|
|
108
|
+
"arguments.invalidItemCount": "{{label}} 的项目数量无效",
|
|
109
|
+
"arguments.requiredField": "{{label}}.{{name}} 为必填字段",
|
|
110
|
+
"arguments.undeclaredField": "{{label}}.{{name}} 不是已声明字段",
|
|
111
|
+
"arguments.unknownParameter": "未知参数 {{name}}",
|
|
112
|
+
"arguments.unknownRequestParameter": "未知的路径、查询或请求头参数 {{name}}",
|
|
113
|
+
"arguments.pathConflict": "路径参数 {{name}} 与原始 HTTP 路径冲突",
|
|
114
|
+
"arguments.requiredRequestParameter": "缺少必填 {{location}} 参数:{{name}}",
|
|
115
|
+
"arguments.invalidPathParameter": "路径参数 {{name}} 无效",
|
|
116
|
+
"arguments.requiredPathParameter": "缺少必填路径参数:{{name}}",
|
|
117
|
+
"arguments.unknownSchema": "未知 Schema 路径:{{target}};请从 schema 开始",
|
|
118
|
+
"protocol.apiFailed": "API 请求失败:{{code}}(HTTP {{status}})",
|
|
119
|
+
"help.overview": "limecloud-cli — Lime Cloud CLI (@limecloud/cli)\n\n用法:\n limecloud-cli <command> [resource] [method] [flags]\n limecloud-cli identity +login | +whoami\n limecloud-cli identity token exchange --data <json>\n limecloud-cli api <METHOD> <contract-path> [--params <json>] [--data <json>]\n limecloud-cli schema [service.resource.method | service resource method]\n\n身份协议:\n identity 公开 OAuth / OpenID Connect 操作与 +快捷命令\n\nCLI 管理:\n install 安装 CLI 并引导首次配置\n config init | show | set:本地公共客户端配置\n auth login | status | whoami | refresh | logout | scopes | check\n whoami 查看本地有效身份与令牌状态\n doctor 检查本地配置与合同(--offline;不访问网络)\n docs 输出文档链接\n\nAPI 工具:\n api 调用合同中的 HTTP 路径;list/schema/call 也支持 operationId\n schema 查看公开方法、参数、响应与身份验证\n\n",
|
|
120
|
+
"help.apiFlags": "API 选项:\n --params JSON 查询 JSON;支持 @file 或 - 从标准输入读取\n --data JSON OAuth 表单或 API JSON 请求体;支持 @file 或 -\n --dry-run 输出脱敏请求,不执行请求或改变状态\n --format FORMAT json(默认)、ndjson、table 或 csv\n --fields PATHS 逗号分隔的数据字段路径\n --json --format json 的简写\n --param name=value 重复提供非敏感协议参数\n --param-env name=ENV 从环境变量读取敏感协议参数\n --header name=value 设置合同声明的 HTTP 请求头\n --file PATH image/png 方法的二进制请求体;- 从标准输入读取\n --show-secrets 显式在标准输出中包含 API 响应凭据\n\n",
|
|
121
|
+
"help.connectionFlags": "连接选项:\n --issuer ORIGIN Auth 来源(HTTPS;HTTP 仅允许回环地址)\n --api-origin ORIGIN 显式指定业务 API 来源,并绑定保存的登录\n --client-id ID 已登记的登录客户端 ID\n --auth-client-id ID 覆盖业务 API 调用的 OAuth 客户端上下文\n --locale TAG 输出语言(也支持 LIMECLOUD_LOCALE、LC_ALL、LC_MESSAGES、LANG)\n\n调用方法前,请运行 limecloud-cli <command> --help 或 schema identity。\n",
|
|
122
|
+
"help.auth": "用法:auth <login|status|whoami|refresh|logout|scopes|check> [flags]\n\nlogin --client-id ID [--scope \"openid profile\"] [--installation-id ID --space-id ID]\n --no-wait:返回验证链接并保存私有待完成授权状态\n --resume:完成已保存授权,不暴露设备码\nstatus:本地状态;whoami:远程 UserInfo;refresh:轮换保存的凭据\nlogout [--local-only]:先撤销再清除;--local-only 仅清除本地凭据\nscopes:读取支持的 OIDC Scope 并显示本地已授予 Scope\ncheck --scope SCOPES:检查未到期的本地已授予 Scope(不访问网络)\n\nAuth 命令使用已登记的公共客户端。--dry-run 可预览 login、refresh、logout 或 scopes,不执行操作。\n",
|
|
123
|
+
"help.config": "用法:\n config init\n config init --issuer ORIGIN --client-id ID [--api-origin ORIGIN] [--scope SCOPES]\n config show\n config set <issuer|api_origin|client_id|scope> <value>\n\n配置仅保存公共客户端设置。业务 API 来源必须显式指定;改变来源后需重新登录绑定。\n",
|
|
124
|
+
"help.schema": "用法:schema [identity | identity.resource | identity.resource.method | identity resource method]\n返回从 OpenAPI 合同生成的公开 inputSchema、outputSchema 与 _meta。风险:读取。\n",
|
|
125
|
+
"help.identityShortcuts": "身份快捷命令:\n identity +login [--scope SCOPES] [--no-wait | --resume]\n identity +whoami\n\n",
|
|
126
|
+
"help.typedMethods": "类型化 API 命令:\n{{methods}}\n\n使用 schema {{service}}.<resource>.<method> 查看参数。--dry-run 不执行操作。\n",
|
|
127
|
+
"help.services": "可用服务:{{services}}\n",
|
|
128
|
+
"help.api": "用法:api GET <path> --params JSON\n api POST <path> --data JSON\n api list [query] [--locale TAG]\n api schema <operationId>\n api call <operationId> [flags]\n\n仅支持公开合同中的精确路径。任意 URL 与管理 BFF 路径均被拒绝。\n",
|
|
129
|
+
"errors.cancelled": "命令已取消",
|
|
130
|
+
"errors.failed": "命令执行失败;请检查本地配置后重试",
|
|
131
|
+
"arguments.unsupportedLocale": "不支持此 --locale;请选择:{{locales}}",
|
|
132
|
+
"auth.deviceNotice": "打开 {{uri}}\n确认用户码:{{code}}\n",
|
|
133
|
+
"columns.command": "命令",
|
|
134
|
+
"columns.operationId": "操作标识",
|
|
135
|
+
"columns.method": "HTTP 方法",
|
|
136
|
+
"columns.path": "路径",
|
|
137
|
+
"columns.summary": "摘要",
|
|
138
|
+
"columns.description": "说明",
|
|
139
|
+
"columns.value": "值",
|
|
140
|
+
"help.install": "用法:\n npx @limecloud/cli@latest install [--prefix DIRECTORY]\n limecloud-cli install --client-id ID --issuer ORIGIN --api-origin ORIGIN [--skip-login]\n limecloud-cli install --dry-run [--no-config]\n\n默认将本次包版本安装到 ~/.local,然后引导配置公共客户端及可选的设备授权。缺少 Client ID 时从身份服务的公开 /runtime/v1/cli 元数据获取默认配置。使用 --prefix 或 LIMECLOUD_INSTALL_PREFIX 指定目录。非交互运行时,缺少的配置保持待完成。--login 显式发起设备授权后立即返回;--no-config 跳过配置。不修改 shell 配置或 Agent Skills。\n",
|
|
141
|
+
"install.invalidPrefix": "请使用 --prefix 提供有效的安装目录",
|
|
142
|
+
"install.invalidMetadata": "公共 CLI 配置元数据与当前身份服务或支持的配置合同不匹配",
|
|
143
|
+
"install.discoveryUnavailable": "暂时无法获取公共 CLI 配置元数据。请运行 limecloud-cli config init,并使用部署管理员提供的公共 CLI Client ID。",
|
|
144
|
+
"install.npmRequired": "在 Windows 上请通过 npx 安装,以使用 npm 的 JavaScript 入口",
|
|
145
|
+
"install.failed": "CLI 安装失败;请检查 npm 访问与 {{prefix}} 的权限后重新执行 install",
|
|
146
|
+
"install.verificationFailed": "npm 已结束,但无法核验已安装的 CLI 版本或可执行文件",
|
|
147
|
+
"install.usage": "请使用 install [--prefix DIRECTORY] [--client-id ID] [--skip-login | --login];--login 不能与 --no-config 同时使用",
|
|
148
|
+
"install.promptIssuer": "身份服务来源 [{{value}}]:",
|
|
149
|
+
"install.promptAPIOrigin": "业务 API 来源(仅使用身份协议可留空)[{{value}}]:",
|
|
150
|
+
"install.promptClientID": "已登记的公共 CLI Client ID [{{value}}]:",
|
|
151
|
+
"install.promptLogin": "现在发起设备授权吗?你仍需在浏览器中确认(y/N)[{{value}}]:",
|
|
152
|
+
"install.pathHint": "请将 {{directory}} 加入 PATH,以便在任意终端运行 limecloud-cli。"
|
|
153
|
+
}
|