@odla-ai/cli 0.25.18 → 0.25.20
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 +16 -8
- package/dist/bin.cjs +428 -405
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-B6DISJPC.js → chunk-ONETPJFW.js} +305 -282
- package/dist/chunk-ONETPJFW.js.map +1 -0
- package/dist/index.cjs +428 -405
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-B6DISJPC.js.map +0 -1
|
@@ -861,6 +861,7 @@ function isRecord3(value) {
|
|
|
861
861
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
862
862
|
import { dirname as dirname3, isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
|
|
863
863
|
import { pathToFileURL } from "url";
|
|
864
|
+
import { appServiceDefinition, appServiceIds } from "@odla-ai/apps";
|
|
864
865
|
|
|
865
866
|
// src/integration-validation.ts
|
|
866
867
|
function validateIntegrations(cfg, path, defaultServices) {
|
|
@@ -948,6 +949,7 @@ async function loadProjectConfig(configPath = "odla.config.mjs") {
|
|
|
948
949
|
const dbEndpoint = trimSlash(process.env.ODLA_DB_ENDPOINT || raw.dbEndpoint || platformUrl);
|
|
949
950
|
const envs = unique2(raw.envs?.length ? raw.envs : DEFAULT_ENVS);
|
|
950
951
|
const services = unique2(raw.services?.length ? raw.services : DEFAULT_SERVICES);
|
|
952
|
+
validateServices(services, resolved);
|
|
951
953
|
validateCalendarConfig(raw, envs, services, resolved);
|
|
952
954
|
const local = {
|
|
953
955
|
tokenFile: resolve2(rootDir, raw.local?.tokenFile ?? ".odla/dev-token.json"),
|
|
@@ -1103,7 +1105,19 @@ function validateCalendarConfig(cfg, envs, services, path) {
|
|
|
1103
1105
|
}
|
|
1104
1106
|
}
|
|
1105
1107
|
}
|
|
1106
|
-
|
|
1108
|
+
}
|
|
1109
|
+
function validateServices(services, path) {
|
|
1110
|
+
for (const service of services) {
|
|
1111
|
+
const definition = appServiceDefinition(service);
|
|
1112
|
+
if (!definition) {
|
|
1113
|
+
throw new Error(`${path}: unknown service "${service}" (known: ${appServiceIds().join(", ")})`);
|
|
1114
|
+
}
|
|
1115
|
+
for (const dependency of definition.requires) {
|
|
1116
|
+
if (!services.includes(dependency)) {
|
|
1117
|
+
throw new Error(`${path}: ${service} service requires the ${dependency} service`);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1107
1121
|
}
|
|
1108
1122
|
function assertOnly(value, allowed, label) {
|
|
1109
1123
|
const extra = Object.keys(value).find((key) => !allowed.includes(key));
|
|
@@ -2070,6 +2084,7 @@ async function doctor(options) {
|
|
|
2070
2084
|
// src/init.ts
|
|
2071
2085
|
import { existsSync as existsSync6, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
2072
2086
|
import { dirname as dirname4, resolve as resolve4 } from "path";
|
|
2087
|
+
import { appServiceDefinition as appServiceDefinition2, appServiceIds as appServiceIds2 } from "@odla-ai/apps";
|
|
2073
2088
|
function initProject(options) {
|
|
2074
2089
|
const out = options.stdout ?? console;
|
|
2075
2090
|
const rootDir = resolve4(options.rootDir ?? process.cwd());
|
|
@@ -2082,7 +2097,13 @@ function initProject(options) {
|
|
|
2082
2097
|
}
|
|
2083
2098
|
const envs = options.envs?.length ? options.envs : ["dev"];
|
|
2084
2099
|
const services = options.services?.length ? options.services : ["db", "ai"];
|
|
2085
|
-
|
|
2100
|
+
for (const service of services) {
|
|
2101
|
+
const definition = appServiceDefinition2(service);
|
|
2102
|
+
if (!definition) throw new Error(`--services contains unknown service "${service}" (known: ${appServiceIds2().join(", ")})`);
|
|
2103
|
+
for (const dependency of definition.requires) {
|
|
2104
|
+
if (!services.includes(dependency)) throw new Error(`--services ${service} requires ${dependency}`);
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2086
2107
|
const aiProvider = options.aiProvider ?? "anthropic";
|
|
2087
2108
|
mkdirSync2(dirname4(configPath), { recursive: true });
|
|
2088
2109
|
mkdirSync2(resolve4(rootDir, "src/odla"), { recursive: true });
|
|
@@ -6033,15 +6054,16 @@ Usage:
|
|
|
6033
6054
|
odla-ai runbook rm <slug> [--app <id>]
|
|
6034
6055
|
odla-ai capabilities [--json]
|
|
6035
6056
|
odla-ai code connect [--env dev|prod] [--email <odla-account>] [--engine auto|container|podman|docker] [--slots <1-64>] [--once]
|
|
6036
|
-
odla-ai admin ai show [--platform https://odla.ai] [--email <odla-account>] [--json]
|
|
6037
|
-
odla-ai admin ai models [--provider <id>] [--json]
|
|
6038
|
-
odla-ai admin ai set <purpose> [--provider <id>] [--model <id>] [--enabled|--no-enabled]
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
odla-ai admin ai
|
|
6043
|
-
odla-ai admin ai
|
|
6044
|
-
odla-ai admin ai
|
|
6057
|
+
odla-ai admin ai show [--context <name>] [--platform https://odla.ai] [--email <odla-account>] [--json]
|
|
6058
|
+
odla-ai admin ai models [--context <name>] [--provider <id>] [--json]
|
|
6059
|
+
odla-ai admin ai set <purpose> [--context <name>] [--provider <id>] [--model <id>] [--enabled|--no-enabled]
|
|
6060
|
+
[--max-input-bytes <n>] [--max-output-tokens <n>] [--max-calls-per-run <n>] [--json]
|
|
6061
|
+
odla-ai admin ai set security [--context <name>] --discovery-provider <id> --discovery-model <id>
|
|
6062
|
+
--validation-provider <id> --validation-model <id> [--enabled|--no-enabled] [--json]
|
|
6063
|
+
odla-ai admin ai credentials [--context <name>] [--json]
|
|
6064
|
+
odla-ai admin ai credential set <provider> [--context <name>] (--from-env <NAME>|--stdin)
|
|
6065
|
+
odla-ai admin ai usage [--context <name>] [--app-id <id>] [--env <env>] [--run-id <id>] [--limit <1-500>] [--json]
|
|
6066
|
+
odla-ai admin ai audit [--context <name>] [--limit <1-200>] [--json]
|
|
6045
6067
|
odla-ai security github connect [--repo owner/name] [--env dev] [--email <odla-account>] [--no-open]
|
|
6046
6068
|
odla-ai security github disconnect --source <id> [--env dev] [--yes]
|
|
6047
6069
|
odla-ai security plan [--env dev] [--json]
|
|
@@ -6430,7 +6452,7 @@ function record4(value) {
|
|
|
6430
6452
|
}
|
|
6431
6453
|
|
|
6432
6454
|
// src/provision.ts
|
|
6433
|
-
import { createAppsClient, tenantIdFor as tenantIdFor4 } from "@odla-ai/apps";
|
|
6455
|
+
import { createAppsClient, orderAppServices, tenantIdFor as tenantIdFor4 } from "@odla-ai/apps";
|
|
6434
6456
|
import { putSecret as putSecret2 } from "@odla-ai/ai";
|
|
6435
6457
|
import process8 from "process";
|
|
6436
6458
|
|
|
@@ -6584,11 +6606,6 @@ async function safeText4(res) {
|
|
|
6584
6606
|
// src/provision-helpers.ts
|
|
6585
6607
|
import { DEFAULT_SECRET_NAMES } from "@odla-ai/ai";
|
|
6586
6608
|
import { tenantIdFor as tenantIdFor3 } from "@odla-ai/apps";
|
|
6587
|
-
function serviceRank(service) {
|
|
6588
|
-
if (service === "db") return 0;
|
|
6589
|
-
if (service === "calendar") return 2;
|
|
6590
|
-
return 1;
|
|
6591
|
-
}
|
|
6592
6609
|
function defaultSecretName(provider) {
|
|
6593
6610
|
const names = DEFAULT_SECRET_NAMES;
|
|
6594
6611
|
return names[provider] ?? `${provider}_api_key`;
|
|
@@ -6714,7 +6731,7 @@ async function provision(options) {
|
|
|
6714
6731
|
for (const env of cfg.envs) {
|
|
6715
6732
|
await assertTenantAdminAccess(doFetch, cfg, env, token);
|
|
6716
6733
|
}
|
|
6717
|
-
const serviceOrder =
|
|
6734
|
+
const serviceOrder = orderAppServices(cfg.services);
|
|
6718
6735
|
for (const env of cfg.envs) {
|
|
6719
6736
|
for (const service of serviceOrder) {
|
|
6720
6737
|
if (service === "ai") {
|
|
@@ -7328,8 +7345,250 @@ function addOption(options, name, value) {
|
|
|
7328
7345
|
else options[name] = [String(current), String(value)];
|
|
7329
7346
|
}
|
|
7330
7347
|
|
|
7348
|
+
// src/operator-context.ts
|
|
7349
|
+
import { existsSync as existsSync10 } from "fs";
|
|
7350
|
+
import { join as join10, resolve as resolve11 } from "path";
|
|
7351
|
+
import process10 from "process";
|
|
7352
|
+
|
|
7353
|
+
// src/operator-profiles.ts
|
|
7354
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
|
|
7355
|
+
import { homedir as homedir2 } from "os";
|
|
7356
|
+
import { dirname as dirname7, join as join9, resolve as resolve10 } from "path";
|
|
7357
|
+
import process9 from "process";
|
|
7358
|
+
function operatorProfileFile() {
|
|
7359
|
+
return resolve10(
|
|
7360
|
+
clean(process9.env.ODLA_CONTEXT_FILE) ?? join9(homedir2(), ".odla", "contexts.json")
|
|
7361
|
+
);
|
|
7362
|
+
}
|
|
7363
|
+
function resolveOperatorProfile(parsed) {
|
|
7364
|
+
const fromFlag = clean(stringOpt(parsed.options.context));
|
|
7365
|
+
const fromEnvironment = clean(process9.env.ODLA_CONTEXT);
|
|
7366
|
+
const name = fromFlag ?? fromEnvironment ?? null;
|
|
7367
|
+
const file = operatorProfileFile();
|
|
7368
|
+
if (!name) {
|
|
7369
|
+
return { name: null, source: "unresolved", file, value: null };
|
|
7370
|
+
}
|
|
7371
|
+
assertOperatorName(name, "context");
|
|
7372
|
+
const profiles = readOperatorProfiles(file);
|
|
7373
|
+
const value = Object.hasOwn(profiles, name) ? profiles[name] : void 0;
|
|
7374
|
+
if (!value) {
|
|
7375
|
+
throw new Error(
|
|
7376
|
+
`operator context "${name}" not found in ${file}; run "odla-ai context list" or save it first`
|
|
7377
|
+
);
|
|
7378
|
+
}
|
|
7379
|
+
return {
|
|
7380
|
+
name,
|
|
7381
|
+
source: fromFlag ? "flag" : "environment",
|
|
7382
|
+
file,
|
|
7383
|
+
value
|
|
7384
|
+
};
|
|
7385
|
+
}
|
|
7386
|
+
function listOperatorProfiles(file = operatorProfileFile()) {
|
|
7387
|
+
return Object.entries(readOperatorProfiles(file)).sort(([a], [b]) => a.localeCompare(b)).map(([name, profile]) => ({ name, ...profile }));
|
|
7388
|
+
}
|
|
7389
|
+
function saveOperatorProfile(name, profile, file = operatorProfileFile()) {
|
|
7390
|
+
assertOperatorName(name, "context");
|
|
7391
|
+
const normalized = validateProfile(profile, `operator context "${name}"`);
|
|
7392
|
+
const profiles = readOperatorProfiles(file);
|
|
7393
|
+
profiles[name] = normalized;
|
|
7394
|
+
writePrivateJson(file, { schemaVersion: 1, profiles });
|
|
7395
|
+
}
|
|
7396
|
+
function removeOperatorProfile(name, file = operatorProfileFile()) {
|
|
7397
|
+
assertOperatorName(name, "context");
|
|
7398
|
+
const profiles = readOperatorProfiles(file);
|
|
7399
|
+
if (!Object.hasOwn(profiles, name)) return false;
|
|
7400
|
+
delete profiles[name];
|
|
7401
|
+
writePrivateJson(file, { schemaVersion: 1, profiles });
|
|
7402
|
+
return true;
|
|
7403
|
+
}
|
|
7404
|
+
function operatorCredentialFiles(selection) {
|
|
7405
|
+
const base = selection.name ? join9(dirname7(selection.file), "profiles", selection.name) : join9(homedir2(), ".odla");
|
|
7406
|
+
return {
|
|
7407
|
+
developer: join9(base, "dev-token.json"),
|
|
7408
|
+
scoped: join9(base, "admin-token.local.json")
|
|
7409
|
+
};
|
|
7410
|
+
}
|
|
7411
|
+
function assertOperatorName(value, label) {
|
|
7412
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(value)) {
|
|
7413
|
+
throw new Error(
|
|
7414
|
+
`${label} must contain lowercase letters, numbers, and hyphens`
|
|
7415
|
+
);
|
|
7416
|
+
}
|
|
7417
|
+
}
|
|
7418
|
+
function readOperatorProfiles(file) {
|
|
7419
|
+
if (!existsSync9(file)) return emptyProfiles();
|
|
7420
|
+
let raw;
|
|
7421
|
+
try {
|
|
7422
|
+
raw = JSON.parse(readFileSync7(file, "utf8"));
|
|
7423
|
+
} catch {
|
|
7424
|
+
throw new Error(`operator context file ${file} is not valid JSON`);
|
|
7425
|
+
}
|
|
7426
|
+
if (!raw || typeof raw !== "object" || raw.schemaVersion !== 1 || !raw.profiles || typeof raw.profiles !== "object" || Array.isArray(raw.profiles)) {
|
|
7427
|
+
throw new Error(`operator context file ${file} has an invalid shape`);
|
|
7428
|
+
}
|
|
7429
|
+
const unknown = Object.keys(raw).filter(
|
|
7430
|
+
(key) => !["schemaVersion", "profiles"].includes(key)
|
|
7431
|
+
);
|
|
7432
|
+
if (unknown.length > 0) {
|
|
7433
|
+
throw new Error(
|
|
7434
|
+
`operator context file ${file} contains unsupported field(s): ${unknown.sort().join(", ")}`
|
|
7435
|
+
);
|
|
7436
|
+
}
|
|
7437
|
+
const profiles = emptyProfiles();
|
|
7438
|
+
for (const [name, value] of Object.entries(
|
|
7439
|
+
raw.profiles
|
|
7440
|
+
)) {
|
|
7441
|
+
assertOperatorName(name, "context");
|
|
7442
|
+
profiles[name] = validateProfile(value, `operator context "${name}"`);
|
|
7443
|
+
}
|
|
7444
|
+
return profiles;
|
|
7445
|
+
}
|
|
7446
|
+
function emptyProfiles() {
|
|
7447
|
+
return /* @__PURE__ */ Object.create(null);
|
|
7448
|
+
}
|
|
7449
|
+
function validateProfile(value, label) {
|
|
7450
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7451
|
+
throw new Error(`${label} has an invalid shape`);
|
|
7452
|
+
}
|
|
7453
|
+
const unknown = Object.keys(value).filter(
|
|
7454
|
+
(key) => !["platform", "app", "environment"].includes(key)
|
|
7455
|
+
);
|
|
7456
|
+
if (unknown.length > 0) {
|
|
7457
|
+
throw new Error(
|
|
7458
|
+
`${label} contains unsupported field(s): ${unknown.sort().join(", ")}; contexts store scope metadata only, never credentials`
|
|
7459
|
+
);
|
|
7460
|
+
}
|
|
7461
|
+
const candidate = value;
|
|
7462
|
+
if (typeof candidate.platform !== "string") {
|
|
7463
|
+
throw new Error(`${label} needs an absolute platform URL`);
|
|
7464
|
+
}
|
|
7465
|
+
const platform = platformAudience(candidate.platform);
|
|
7466
|
+
const app = clean(candidate.app);
|
|
7467
|
+
const environment2 = clean(candidate.environment);
|
|
7468
|
+
if (app) assertOperatorName(app, "app");
|
|
7469
|
+
if (environment2) assertOperatorName(environment2, "environment");
|
|
7470
|
+
return {
|
|
7471
|
+
platform,
|
|
7472
|
+
...app ? { app } : {},
|
|
7473
|
+
...environment2 ? { environment: environment2 } : {}
|
|
7474
|
+
};
|
|
7475
|
+
}
|
|
7476
|
+
function clean(value) {
|
|
7477
|
+
const normalized = value?.trim();
|
|
7478
|
+
return normalized || void 0;
|
|
7479
|
+
}
|
|
7480
|
+
|
|
7481
|
+
// src/operator-context.ts
|
|
7482
|
+
var DEFAULT_PLATFORM2 = "https://odla.ai";
|
|
7483
|
+
async function resolveOperatorContext(parsed, options = {}) {
|
|
7484
|
+
const profile = resolveOperatorProfile(parsed);
|
|
7485
|
+
const configArgument = stringOpt(parsed.options.config) ?? "odla.config.mjs";
|
|
7486
|
+
const configPath = resolve11(configArgument);
|
|
7487
|
+
const explicitConfig = parsed.options.config !== void 0;
|
|
7488
|
+
const hasConfig = existsSync10(configPath);
|
|
7489
|
+
if (!hasConfig && (!options.allowMissingConfig || explicitConfig)) {
|
|
7490
|
+
await loadProjectConfig(configArgument);
|
|
7491
|
+
}
|
|
7492
|
+
const loaded = hasConfig ? await loadProjectConfig(configArgument) : void 0;
|
|
7493
|
+
const platformFlag = clean2(stringOpt(parsed.options.platform));
|
|
7494
|
+
const platformEnvironment = clean2(process10.env.ODLA_PLATFORM_URL);
|
|
7495
|
+
const platformValue = platformAudience(
|
|
7496
|
+
platformFlag ?? platformEnvironment ?? profile.value?.platform ?? loaded?.platformUrl ?? DEFAULT_PLATFORM2
|
|
7497
|
+
);
|
|
7498
|
+
const platformSource = platformFlag ? "flag" : platformEnvironment ? "environment" : profile.value ? "profile" : loaded ? "config" : "default";
|
|
7499
|
+
const appFlag = clean2(stringOpt(parsed.options.app));
|
|
7500
|
+
const appEnvironment = clean2(process10.env.ODLA_APP_ID);
|
|
7501
|
+
const appValue = appFlag ?? appEnvironment ?? profile.value?.app ?? loaded?.app.id ?? null;
|
|
7502
|
+
const appSource = appFlag ? "flag" : appEnvironment ? "environment" : profile.value?.app ? "profile" : loaded ? "config" : "unresolved";
|
|
7503
|
+
if (appValue) assertOperatorName(appValue, "app");
|
|
7504
|
+
if (options.requireApp && !appValue) {
|
|
7505
|
+
throw new Error(
|
|
7506
|
+
"app context is unresolved; pass --app <id>, set ODLA_APP_ID, select --context <name>, or run inside a project with odla.config.mjs"
|
|
7507
|
+
);
|
|
7508
|
+
}
|
|
7509
|
+
const envFlag = clean2(stringOpt(parsed.options.env));
|
|
7510
|
+
const envEnvironment = clean2(process10.env.ODLA_ENV);
|
|
7511
|
+
const environmentValue = envFlag ?? envEnvironment ?? profile.value?.environment ?? options.defaultEnvironment ?? null;
|
|
7512
|
+
const environmentSource = envFlag ? "flag" : envEnvironment ? "environment" : profile.value?.environment ? "profile" : options.defaultEnvironment ? "default" : "unresolved";
|
|
7513
|
+
if (environmentValue) {
|
|
7514
|
+
assertOperatorName(environmentValue, "environment");
|
|
7515
|
+
}
|
|
7516
|
+
const rootDir = loaded?.rootDir ?? process10.cwd();
|
|
7517
|
+
const profileCredentials = operatorCredentialFiles(profile);
|
|
7518
|
+
const tokenFile = clean2(process10.env.ODLA_DEV_TOKEN_FILE) ? resolve11(process10.env.ODLA_DEV_TOKEN_FILE) : profile.name ? profileCredentials.developer : loaded?.local.tokenFile ?? profileCredentials.developer;
|
|
7519
|
+
const scopedTokenFile = clean2(process10.env.ODLA_ADMIN_TOKEN_FILE) ? resolve11(process10.env.ODLA_ADMIN_TOKEN_FILE) : profile.name ? profileCredentials.scoped : loaded ? join10(loaded.rootDir, ".odla", "admin-token.local.json") : profileCredentials.scoped;
|
|
7520
|
+
const cfg = loaded ? {
|
|
7521
|
+
...loaded,
|
|
7522
|
+
platformUrl: platformValue,
|
|
7523
|
+
app: appValue ? {
|
|
7524
|
+
id: appValue,
|
|
7525
|
+
name: appValue === loaded.app.id ? loaded.app.name : appValue
|
|
7526
|
+
} : loaded.app,
|
|
7527
|
+
local: { ...loaded.local, tokenFile }
|
|
7528
|
+
} : {
|
|
7529
|
+
configPath,
|
|
7530
|
+
rootDir,
|
|
7531
|
+
platformUrl: platformValue,
|
|
7532
|
+
dbEndpoint: platformValue,
|
|
7533
|
+
app: {
|
|
7534
|
+
id: appValue ?? "operator",
|
|
7535
|
+
name: appValue ?? "Operator"
|
|
7536
|
+
},
|
|
7537
|
+
envs: environmentValue ? [environmentValue] : [],
|
|
7538
|
+
services: [],
|
|
7539
|
+
local: {
|
|
7540
|
+
tokenFile,
|
|
7541
|
+
credentialsFile: join10(rootDir, ".odla", "credentials.local.json"),
|
|
7542
|
+
devVarsFile: join10(rootDir, ".dev.vars"),
|
|
7543
|
+
gitignore: true
|
|
7544
|
+
}
|
|
7545
|
+
};
|
|
7546
|
+
return {
|
|
7547
|
+
cfg,
|
|
7548
|
+
profile: {
|
|
7549
|
+
name: profile.name,
|
|
7550
|
+
source: profile.source,
|
|
7551
|
+
file: profile.file
|
|
7552
|
+
},
|
|
7553
|
+
config: {
|
|
7554
|
+
path: configPath,
|
|
7555
|
+
status: loaded ? "loaded" : "absent",
|
|
7556
|
+
explicit: explicitConfig
|
|
7557
|
+
},
|
|
7558
|
+
platform: { value: platformValue, source: platformSource },
|
|
7559
|
+
app: { value: appValue, source: appSource },
|
|
7560
|
+
environment: {
|
|
7561
|
+
value: environmentValue,
|
|
7562
|
+
source: environmentSource
|
|
7563
|
+
},
|
|
7564
|
+
credentials: {
|
|
7565
|
+
developerTokenFile: tokenFile,
|
|
7566
|
+
scopedTokenFile
|
|
7567
|
+
}
|
|
7568
|
+
};
|
|
7569
|
+
}
|
|
7570
|
+
function clean2(value) {
|
|
7571
|
+
const normalized = value?.trim();
|
|
7572
|
+
return normalized || void 0;
|
|
7573
|
+
}
|
|
7574
|
+
|
|
7331
7575
|
// src/admin-command.ts
|
|
7332
|
-
|
|
7576
|
+
var CONTEXT_OPTIONS = ["platform", "config", "context", "token", "open", "email"];
|
|
7577
|
+
var JSON_OPTIONS = [...CONTEXT_OPTIONS, "json"];
|
|
7578
|
+
var SET_OPTIONS = [
|
|
7579
|
+
...JSON_OPTIONS,
|
|
7580
|
+
"provider",
|
|
7581
|
+
"model",
|
|
7582
|
+
"enabled",
|
|
7583
|
+
"max-input-bytes",
|
|
7584
|
+
"max-output-tokens",
|
|
7585
|
+
"max-calls-per-run",
|
|
7586
|
+
"discovery-provider",
|
|
7587
|
+
"discovery-model",
|
|
7588
|
+
"validation-provider",
|
|
7589
|
+
"validation-model"
|
|
7590
|
+
];
|
|
7591
|
+
async function adminCommand(parsed, deps = {}) {
|
|
7333
7592
|
const area = parsed.positionals[1];
|
|
7334
7593
|
const action = parsed.positionals[2];
|
|
7335
7594
|
const credentialSet = action === "credential" && parsed.positionals[3] === "set";
|
|
@@ -7340,28 +7599,9 @@ async function adminCommand(parsed) {
|
|
|
7340
7599
|
if (area !== "ai" || action !== "show" && action !== "set" && !credentialSet && !credentials && !models && !usage && !audit) {
|
|
7341
7600
|
throw new Error('unknown admin command. Try "odla-ai admin ai show".');
|
|
7342
7601
|
}
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
"open",
|
|
7347
|
-
"email",
|
|
7348
|
-
"provider",
|
|
7349
|
-
"model",
|
|
7350
|
-
"enabled",
|
|
7351
|
-
"max-input-bytes",
|
|
7352
|
-
"max-output-tokens",
|
|
7353
|
-
"max-calls-per-run",
|
|
7354
|
-
"from-env",
|
|
7355
|
-
"stdin",
|
|
7356
|
-
"discovery-provider",
|
|
7357
|
-
"discovery-model",
|
|
7358
|
-
"validation-provider",
|
|
7359
|
-
"validation-model",
|
|
7360
|
-
"app-id",
|
|
7361
|
-
"env",
|
|
7362
|
-
"run-id",
|
|
7363
|
-
"limit"
|
|
7364
|
-
], credentialSet ? 5 : action === "set" ? 4 : 3);
|
|
7602
|
+
const allowed = credentialSet ? [...CONTEXT_OPTIONS, "from-env", "stdin"] : action === "set" ? SET_OPTIONS : models ? [...JSON_OPTIONS, "provider"] : usage ? [...JSON_OPTIONS, "app-id", "env", "run-id", "limit"] : audit ? [...JSON_OPTIONS, "limit"] : JSON_OPTIONS;
|
|
7603
|
+
assertArgs(parsed, allowed, credentialSet ? 5 : action === "set" ? 4 : 3);
|
|
7604
|
+
const context = await resolveOperatorContext(parsed, { allowMissingConfig: true });
|
|
7365
7605
|
await adminAi({
|
|
7366
7606
|
action: credentialSet ? "credential-set" : credentials ? "credentials" : models ? "models" : usage ? "usage" : audit ? "audit" : action,
|
|
7367
7607
|
purpose: action === "set" ? parsed.positionals[3] : void 0,
|
|
@@ -7371,13 +7611,16 @@ async function adminCommand(parsed) {
|
|
|
7371
7611
|
maxInputBytes: numberOpt(parsed.options["max-input-bytes"], "--max-input-bytes"),
|
|
7372
7612
|
maxOutputTokens: numberOpt(parsed.options["max-output-tokens"], "--max-output-tokens"),
|
|
7373
7613
|
maxCallsPerRun: numberOpt(parsed.options["max-calls-per-run"], "--max-calls-per-run"),
|
|
7374
|
-
platform:
|
|
7614
|
+
platform: context.platform.value,
|
|
7615
|
+
token: stringOpt(parsed.options.token),
|
|
7616
|
+
tokenFile: context.credentials.scopedTokenFile,
|
|
7375
7617
|
email: stringOpt(parsed.options.email),
|
|
7376
7618
|
json: parsed.options.json === true,
|
|
7377
7619
|
open: parsed.options.open === false ? false : parsed.options.open === true ? true : void 0,
|
|
7378
7620
|
credentialProvider: credentialSet ? parsed.positionals[4] : void 0,
|
|
7379
7621
|
fromEnv: stringOpt(parsed.options["from-env"]),
|
|
7380
7622
|
stdin: parsed.options.stdin === true,
|
|
7623
|
+
readStdin: deps.readStdin,
|
|
7381
7624
|
discoveryProvider: stringOpt(parsed.options["discovery-provider"]),
|
|
7382
7625
|
discoveryModel: stringOpt(parsed.options["discovery-model"]),
|
|
7383
7626
|
validationProvider: stringOpt(parsed.options["validation-provider"]),
|
|
@@ -7385,7 +7628,10 @@ async function adminCommand(parsed) {
|
|
|
7385
7628
|
appId: stringOpt(parsed.options["app-id"]),
|
|
7386
7629
|
env: stringOpt(parsed.options.env),
|
|
7387
7630
|
runId: stringOpt(parsed.options["run-id"]),
|
|
7388
|
-
limit: numberOpt(parsed.options.limit, "--limit")
|
|
7631
|
+
limit: numberOpt(parsed.options.limit, "--limit"),
|
|
7632
|
+
fetch: deps.fetch,
|
|
7633
|
+
stdout: deps.stdout,
|
|
7634
|
+
openApprovalUrl: deps.openUrl
|
|
7389
7635
|
});
|
|
7390
7636
|
}
|
|
7391
7637
|
|
|
@@ -7537,7 +7783,7 @@ async function appExport(options) {
|
|
|
7537
7783
|
}
|
|
7538
7784
|
|
|
7539
7785
|
// src/app-import.ts
|
|
7540
|
-
import { readFileSync as
|
|
7786
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
7541
7787
|
import {
|
|
7542
7788
|
buildImportOps,
|
|
7543
7789
|
importMutationId,
|
|
@@ -7561,7 +7807,7 @@ async function appImport(options) {
|
|
|
7561
7807
|
const say = options.json ? (line) => out.error(line) : (line) => out.log(line);
|
|
7562
7808
|
const doFetch = options.fetch ?? fetch;
|
|
7563
7809
|
const { tenant } = resolveTenant(cfg, options.env);
|
|
7564
|
-
const text = options.file === "-" ? (options.readStdin ?? (() =>
|
|
7810
|
+
const text = options.file === "-" ? (options.readStdin ?? (() => readFileSync8(0, "utf8")))() : readFileSync8(options.file, "utf8");
|
|
7565
7811
|
const { format, sources } = parseImport(text, options.ns);
|
|
7566
7812
|
if (format === "namespace-map" && options.ns) {
|
|
7567
7813
|
throw new Error("--ns cannot be combined with a {namespace: rows} file \u2014 the file already names each namespace");
|
|
@@ -8024,13 +8270,16 @@ function harnessOption(value, flag) {
|
|
|
8024
8270
|
|
|
8025
8271
|
// src/cli-project.ts
|
|
8026
8272
|
var SKILL_OPTS = ["dir", "global", "force", "agent", "harness"];
|
|
8027
|
-
function install(parsed, positionals) {
|
|
8273
|
+
function install(parsed, positionals, deps) {
|
|
8028
8274
|
assertArgs(parsed, SKILL_OPTS, positionals);
|
|
8029
8275
|
installSkill({
|
|
8030
8276
|
dir: stringOpt(parsed.options.dir),
|
|
8031
8277
|
global: parsed.options.global === true,
|
|
8032
8278
|
harnesses: harnessList(parsed),
|
|
8033
|
-
force: parsed.options.force === true
|
|
8279
|
+
force: parsed.options.force === true,
|
|
8280
|
+
homeDir: deps.homeDir,
|
|
8281
|
+
codexHomeDir: deps.codexHomeDir,
|
|
8282
|
+
stdout: deps.stdout
|
|
8034
8283
|
});
|
|
8035
8284
|
}
|
|
8036
8285
|
async function secretsCommand(parsed, deps) {
|
|
@@ -8046,6 +8295,7 @@ async function secretsCommand(parsed, deps) {
|
|
|
8046
8295
|
token: stringOpt(parsed.options.token),
|
|
8047
8296
|
email: stringOpt(parsed.options.email),
|
|
8048
8297
|
yes: parsed.options.yes === true,
|
|
8298
|
+
readStdin: deps.readStdin,
|
|
8049
8299
|
fetch: deps.fetch,
|
|
8050
8300
|
stdout: deps.stdout
|
|
8051
8301
|
};
|
|
@@ -8104,8 +8354,8 @@ async function projectCommand(command, parsed, deps) {
|
|
|
8104
8354
|
return true;
|
|
8105
8355
|
}
|
|
8106
8356
|
if (command === "setup") {
|
|
8107
|
-
install(parsed, 1);
|
|
8108
|
-
console.log(
|
|
8357
|
+
install(parsed, 1, deps);
|
|
8358
|
+
(deps.stdout ?? console).log(
|
|
8109
8359
|
"\nOffline runbooks installed. Open this repo in your coding agent and ask it to set up odla.\nIts native adapter finds the local `odla` skill, chooses build or migration, and drives the CLI."
|
|
8110
8360
|
);
|
|
8111
8361
|
return true;
|
|
@@ -8113,7 +8363,7 @@ async function projectCommand(command, parsed, deps) {
|
|
|
8113
8363
|
if (command === "skill") {
|
|
8114
8364
|
const sub = parsed.positionals[1];
|
|
8115
8365
|
if (sub !== "install") throw new Error(`unknown skill subcommand "${sub ?? ""}". Try "odla-ai skill install".`);
|
|
8116
|
-
install(parsed, 2);
|
|
8366
|
+
install(parsed, 2, deps);
|
|
8117
8367
|
return true;
|
|
8118
8368
|
}
|
|
8119
8369
|
if (command === "secrets") {
|
|
@@ -8166,246 +8416,19 @@ async function codeCommand(parsed, dependencies) {
|
|
|
8166
8416
|
}
|
|
8167
8417
|
|
|
8168
8418
|
// src/operator-credentials.ts
|
|
8169
|
-
import
|
|
8419
|
+
import process11 from "process";
|
|
8170
8420
|
function developerTokenStatus(context, parsed, now = Date.now()) {
|
|
8171
8421
|
const cached = readJsonFile(context.cfg.local.tokenFile);
|
|
8172
8422
|
const cacheStatus = !cached?.token ? "missing" : cached.platform !== context.platform.value ? "other-platform" : (cached.expiresAt ?? 0) <= now + 6e4 ? "expired" : "valid";
|
|
8173
|
-
const source =
|
|
8423
|
+
const source = clean3(
|
|
8174
8424
|
stringOpt(parsed.options.token)
|
|
8175
|
-
) ? "flag" :
|
|
8425
|
+
) ? "flag" : clean3(process11.env.ODLA_DEV_TOKEN) ? "environment" : cacheStatus === "valid" ? "cache" : "missing";
|
|
8176
8426
|
return {
|
|
8177
8427
|
source,
|
|
8178
8428
|
cacheFile: context.cfg.local.tokenFile,
|
|
8179
8429
|
cacheStatus
|
|
8180
8430
|
};
|
|
8181
8431
|
}
|
|
8182
|
-
function clean(value) {
|
|
8183
|
-
const normalized = value?.trim();
|
|
8184
|
-
return normalized || void 0;
|
|
8185
|
-
}
|
|
8186
|
-
|
|
8187
|
-
// src/operator-context.ts
|
|
8188
|
-
import { existsSync as existsSync10 } from "fs";
|
|
8189
|
-
import { join as join10, resolve as resolve11 } from "path";
|
|
8190
|
-
import process11 from "process";
|
|
8191
|
-
|
|
8192
|
-
// src/operator-profiles.ts
|
|
8193
|
-
import { existsSync as existsSync9, readFileSync as readFileSync8 } from "fs";
|
|
8194
|
-
import { homedir as homedir2 } from "os";
|
|
8195
|
-
import { dirname as dirname7, join as join9, resolve as resolve10 } from "path";
|
|
8196
|
-
import process10 from "process";
|
|
8197
|
-
function operatorProfileFile() {
|
|
8198
|
-
return resolve10(
|
|
8199
|
-
clean2(process10.env.ODLA_CONTEXT_FILE) ?? join9(homedir2(), ".odla", "contexts.json")
|
|
8200
|
-
);
|
|
8201
|
-
}
|
|
8202
|
-
function resolveOperatorProfile(parsed) {
|
|
8203
|
-
const fromFlag = clean2(stringOpt(parsed.options.context));
|
|
8204
|
-
const fromEnvironment = clean2(process10.env.ODLA_CONTEXT);
|
|
8205
|
-
const name = fromFlag ?? fromEnvironment ?? null;
|
|
8206
|
-
const file = operatorProfileFile();
|
|
8207
|
-
if (!name) {
|
|
8208
|
-
return { name: null, source: "unresolved", file, value: null };
|
|
8209
|
-
}
|
|
8210
|
-
assertOperatorName(name, "context");
|
|
8211
|
-
const profiles = readOperatorProfiles(file);
|
|
8212
|
-
const value = Object.hasOwn(profiles, name) ? profiles[name] : void 0;
|
|
8213
|
-
if (!value) {
|
|
8214
|
-
throw new Error(
|
|
8215
|
-
`operator context "${name}" not found in ${file}; run "odla-ai context list" or save it first`
|
|
8216
|
-
);
|
|
8217
|
-
}
|
|
8218
|
-
return {
|
|
8219
|
-
name,
|
|
8220
|
-
source: fromFlag ? "flag" : "environment",
|
|
8221
|
-
file,
|
|
8222
|
-
value
|
|
8223
|
-
};
|
|
8224
|
-
}
|
|
8225
|
-
function listOperatorProfiles(file = operatorProfileFile()) {
|
|
8226
|
-
return Object.entries(readOperatorProfiles(file)).sort(([a], [b]) => a.localeCompare(b)).map(([name, profile]) => ({ name, ...profile }));
|
|
8227
|
-
}
|
|
8228
|
-
function saveOperatorProfile(name, profile, file = operatorProfileFile()) {
|
|
8229
|
-
assertOperatorName(name, "context");
|
|
8230
|
-
const normalized = validateProfile(profile, `operator context "${name}"`);
|
|
8231
|
-
const profiles = readOperatorProfiles(file);
|
|
8232
|
-
profiles[name] = normalized;
|
|
8233
|
-
writePrivateJson(file, { schemaVersion: 1, profiles });
|
|
8234
|
-
}
|
|
8235
|
-
function removeOperatorProfile(name, file = operatorProfileFile()) {
|
|
8236
|
-
assertOperatorName(name, "context");
|
|
8237
|
-
const profiles = readOperatorProfiles(file);
|
|
8238
|
-
if (!Object.hasOwn(profiles, name)) return false;
|
|
8239
|
-
delete profiles[name];
|
|
8240
|
-
writePrivateJson(file, { schemaVersion: 1, profiles });
|
|
8241
|
-
return true;
|
|
8242
|
-
}
|
|
8243
|
-
function operatorCredentialFiles(selection) {
|
|
8244
|
-
const base = selection.name ? join9(dirname7(selection.file), "profiles", selection.name) : join9(homedir2(), ".odla");
|
|
8245
|
-
return {
|
|
8246
|
-
developer: join9(base, "dev-token.json"),
|
|
8247
|
-
scoped: join9(base, "admin-token.local.json")
|
|
8248
|
-
};
|
|
8249
|
-
}
|
|
8250
|
-
function assertOperatorName(value, label) {
|
|
8251
|
-
if (!/^[a-z0-9][a-z0-9-]*$/.test(value)) {
|
|
8252
|
-
throw new Error(
|
|
8253
|
-
`${label} must contain lowercase letters, numbers, and hyphens`
|
|
8254
|
-
);
|
|
8255
|
-
}
|
|
8256
|
-
}
|
|
8257
|
-
function readOperatorProfiles(file) {
|
|
8258
|
-
if (!existsSync9(file)) return emptyProfiles();
|
|
8259
|
-
let raw;
|
|
8260
|
-
try {
|
|
8261
|
-
raw = JSON.parse(readFileSync8(file, "utf8"));
|
|
8262
|
-
} catch {
|
|
8263
|
-
throw new Error(`operator context file ${file} is not valid JSON`);
|
|
8264
|
-
}
|
|
8265
|
-
if (!raw || typeof raw !== "object" || raw.schemaVersion !== 1 || !raw.profiles || typeof raw.profiles !== "object" || Array.isArray(raw.profiles)) {
|
|
8266
|
-
throw new Error(`operator context file ${file} has an invalid shape`);
|
|
8267
|
-
}
|
|
8268
|
-
const unknown = Object.keys(raw).filter(
|
|
8269
|
-
(key) => !["schemaVersion", "profiles"].includes(key)
|
|
8270
|
-
);
|
|
8271
|
-
if (unknown.length > 0) {
|
|
8272
|
-
throw new Error(
|
|
8273
|
-
`operator context file ${file} contains unsupported field(s): ${unknown.sort().join(", ")}`
|
|
8274
|
-
);
|
|
8275
|
-
}
|
|
8276
|
-
const profiles = emptyProfiles();
|
|
8277
|
-
for (const [name, value] of Object.entries(
|
|
8278
|
-
raw.profiles
|
|
8279
|
-
)) {
|
|
8280
|
-
assertOperatorName(name, "context");
|
|
8281
|
-
profiles[name] = validateProfile(value, `operator context "${name}"`);
|
|
8282
|
-
}
|
|
8283
|
-
return profiles;
|
|
8284
|
-
}
|
|
8285
|
-
function emptyProfiles() {
|
|
8286
|
-
return /* @__PURE__ */ Object.create(null);
|
|
8287
|
-
}
|
|
8288
|
-
function validateProfile(value, label) {
|
|
8289
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
8290
|
-
throw new Error(`${label} has an invalid shape`);
|
|
8291
|
-
}
|
|
8292
|
-
const unknown = Object.keys(value).filter(
|
|
8293
|
-
(key) => !["platform", "app", "environment"].includes(key)
|
|
8294
|
-
);
|
|
8295
|
-
if (unknown.length > 0) {
|
|
8296
|
-
throw new Error(
|
|
8297
|
-
`${label} contains unsupported field(s): ${unknown.sort().join(", ")}; contexts store scope metadata only, never credentials`
|
|
8298
|
-
);
|
|
8299
|
-
}
|
|
8300
|
-
const candidate = value;
|
|
8301
|
-
if (typeof candidate.platform !== "string") {
|
|
8302
|
-
throw new Error(`${label} needs an absolute platform URL`);
|
|
8303
|
-
}
|
|
8304
|
-
const platform = platformAudience(candidate.platform);
|
|
8305
|
-
const app = clean2(candidate.app);
|
|
8306
|
-
const environment2 = clean2(candidate.environment);
|
|
8307
|
-
if (app) assertOperatorName(app, "app");
|
|
8308
|
-
if (environment2) assertOperatorName(environment2, "environment");
|
|
8309
|
-
return {
|
|
8310
|
-
platform,
|
|
8311
|
-
...app ? { app } : {},
|
|
8312
|
-
...environment2 ? { environment: environment2 } : {}
|
|
8313
|
-
};
|
|
8314
|
-
}
|
|
8315
|
-
function clean2(value) {
|
|
8316
|
-
const normalized = value?.trim();
|
|
8317
|
-
return normalized || void 0;
|
|
8318
|
-
}
|
|
8319
|
-
|
|
8320
|
-
// src/operator-context.ts
|
|
8321
|
-
var DEFAULT_PLATFORM2 = "https://odla.ai";
|
|
8322
|
-
async function resolveOperatorContext(parsed, options = {}) {
|
|
8323
|
-
const profile = resolveOperatorProfile(parsed);
|
|
8324
|
-
const configArgument = stringOpt(parsed.options.config) ?? "odla.config.mjs";
|
|
8325
|
-
const configPath = resolve11(configArgument);
|
|
8326
|
-
const explicitConfig = parsed.options.config !== void 0;
|
|
8327
|
-
const hasConfig = existsSync10(configPath);
|
|
8328
|
-
if (!hasConfig && (!options.allowMissingConfig || explicitConfig)) {
|
|
8329
|
-
await loadProjectConfig(configArgument);
|
|
8330
|
-
}
|
|
8331
|
-
const loaded = hasConfig ? await loadProjectConfig(configArgument) : void 0;
|
|
8332
|
-
const platformFlag = clean3(stringOpt(parsed.options.platform));
|
|
8333
|
-
const platformEnvironment = clean3(process11.env.ODLA_PLATFORM_URL);
|
|
8334
|
-
const platformValue = platformAudience(
|
|
8335
|
-
platformFlag ?? platformEnvironment ?? profile.value?.platform ?? loaded?.platformUrl ?? DEFAULT_PLATFORM2
|
|
8336
|
-
);
|
|
8337
|
-
const platformSource = platformFlag ? "flag" : platformEnvironment ? "environment" : profile.value ? "profile" : loaded ? "config" : "default";
|
|
8338
|
-
const appFlag = clean3(stringOpt(parsed.options.app));
|
|
8339
|
-
const appEnvironment = clean3(process11.env.ODLA_APP_ID);
|
|
8340
|
-
const appValue = appFlag ?? appEnvironment ?? profile.value?.app ?? loaded?.app.id ?? null;
|
|
8341
|
-
const appSource = appFlag ? "flag" : appEnvironment ? "environment" : profile.value?.app ? "profile" : loaded ? "config" : "unresolved";
|
|
8342
|
-
if (appValue) assertOperatorName(appValue, "app");
|
|
8343
|
-
if (options.requireApp && !appValue) {
|
|
8344
|
-
throw new Error(
|
|
8345
|
-
"app context is unresolved; pass --app <id>, set ODLA_APP_ID, select --context <name>, or run inside a project with odla.config.mjs"
|
|
8346
|
-
);
|
|
8347
|
-
}
|
|
8348
|
-
const envFlag = clean3(stringOpt(parsed.options.env));
|
|
8349
|
-
const envEnvironment = clean3(process11.env.ODLA_ENV);
|
|
8350
|
-
const environmentValue = envFlag ?? envEnvironment ?? profile.value?.environment ?? options.defaultEnvironment ?? null;
|
|
8351
|
-
const environmentSource = envFlag ? "flag" : envEnvironment ? "environment" : profile.value?.environment ? "profile" : options.defaultEnvironment ? "default" : "unresolved";
|
|
8352
|
-
if (environmentValue) {
|
|
8353
|
-
assertOperatorName(environmentValue, "environment");
|
|
8354
|
-
}
|
|
8355
|
-
const rootDir = loaded?.rootDir ?? process11.cwd();
|
|
8356
|
-
const profileCredentials = operatorCredentialFiles(profile);
|
|
8357
|
-
const tokenFile = clean3(process11.env.ODLA_DEV_TOKEN_FILE) ? resolve11(process11.env.ODLA_DEV_TOKEN_FILE) : profile.name ? profileCredentials.developer : loaded?.local.tokenFile ?? profileCredentials.developer;
|
|
8358
|
-
const scopedTokenFile = clean3(process11.env.ODLA_ADMIN_TOKEN_FILE) ? resolve11(process11.env.ODLA_ADMIN_TOKEN_FILE) : profile.name ? profileCredentials.scoped : loaded ? join10(loaded.rootDir, ".odla", "admin-token.local.json") : profileCredentials.scoped;
|
|
8359
|
-
const cfg = loaded ? {
|
|
8360
|
-
...loaded,
|
|
8361
|
-
platformUrl: platformValue,
|
|
8362
|
-
app: appValue ? {
|
|
8363
|
-
id: appValue,
|
|
8364
|
-
name: appValue === loaded.app.id ? loaded.app.name : appValue
|
|
8365
|
-
} : loaded.app,
|
|
8366
|
-
local: { ...loaded.local, tokenFile }
|
|
8367
|
-
} : {
|
|
8368
|
-
configPath,
|
|
8369
|
-
rootDir,
|
|
8370
|
-
platformUrl: platformValue,
|
|
8371
|
-
dbEndpoint: platformValue,
|
|
8372
|
-
app: {
|
|
8373
|
-
id: appValue ?? "operator",
|
|
8374
|
-
name: appValue ?? "Operator"
|
|
8375
|
-
},
|
|
8376
|
-
envs: environmentValue ? [environmentValue] : [],
|
|
8377
|
-
services: [],
|
|
8378
|
-
local: {
|
|
8379
|
-
tokenFile,
|
|
8380
|
-
credentialsFile: join10(rootDir, ".odla", "credentials.local.json"),
|
|
8381
|
-
devVarsFile: join10(rootDir, ".dev.vars"),
|
|
8382
|
-
gitignore: true
|
|
8383
|
-
}
|
|
8384
|
-
};
|
|
8385
|
-
return {
|
|
8386
|
-
cfg,
|
|
8387
|
-
profile: {
|
|
8388
|
-
name: profile.name,
|
|
8389
|
-
source: profile.source,
|
|
8390
|
-
file: profile.file
|
|
8391
|
-
},
|
|
8392
|
-
config: {
|
|
8393
|
-
path: configPath,
|
|
8394
|
-
status: loaded ? "loaded" : "absent",
|
|
8395
|
-
explicit: explicitConfig
|
|
8396
|
-
},
|
|
8397
|
-
platform: { value: platformValue, source: platformSource },
|
|
8398
|
-
app: { value: appValue, source: appSource },
|
|
8399
|
-
environment: {
|
|
8400
|
-
value: environmentValue,
|
|
8401
|
-
source: environmentSource
|
|
8402
|
-
},
|
|
8403
|
-
credentials: {
|
|
8404
|
-
developerTokenFile: tokenFile,
|
|
8405
|
-
scopedTokenFile
|
|
8406
|
-
}
|
|
8407
|
-
};
|
|
8408
|
-
}
|
|
8409
8432
|
function clean3(value) {
|
|
8410
8433
|
const normalized = value?.trim();
|
|
8411
8434
|
return normalized || void 0;
|
|
@@ -11205,7 +11228,7 @@ async function runCli(argv = process.argv.slice(2), dependencies = {}) {
|
|
|
11205
11228
|
return;
|
|
11206
11229
|
}
|
|
11207
11230
|
if (command === "admin") {
|
|
11208
|
-
await adminCommand(parsed);
|
|
11231
|
+
await adminCommand(parsed, runtime);
|
|
11209
11232
|
return;
|
|
11210
11233
|
}
|
|
11211
11234
|
if (command === "agent") {
|
|
@@ -11351,4 +11374,4 @@ export {
|
|
|
11351
11374
|
exitCodeFor,
|
|
11352
11375
|
runCli
|
|
11353
11376
|
};
|
|
11354
|
-
//# sourceMappingURL=chunk-
|
|
11377
|
+
//# sourceMappingURL=chunk-ONETPJFW.js.map
|