@everfur/cli 0.2.0 → 0.4.1
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 +122 -47
- package/dist/{chunk-S6UN7D2O.js → chunk-2MTX6YWO.js} +74 -30
- package/dist/{chunk-TBFOL2D3.js → chunk-A2QEBO5U.js} +1 -1
- package/dist/{chunk-CEWWBPPT.js → chunk-EBVP6FAD.js} +5638 -990
- package/dist/{chunk-WCH6AI6K.js → chunk-QCXZJW5C.js} +663 -227
- package/dist/{chunk-VHZWTB6J.js → chunk-YRGSY4R2.js} +81 -14
- package/dist/everfur-mcp-hosted.js +4 -4
- package/dist/everfur-mcp-http.js +3 -3
- package/dist/everfur-mcp.js +2 -2
- package/dist/everfur.js +2 -2
- package/dist/index.d.ts +420 -113
- package/dist/index.js +2 -2
- package/package.json +4 -3
- package/schema/error-explanation.v1.schema.json +26 -4
- package/schema/plan.v1.schema.json +49 -4
- package/schema/verification.v1.schema.json +5 -4
- package/dist/everfur-mcp-container.d.ts +0 -2
- package/dist/everfur-mcp-container.js +0 -60
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { VERIFY_IDENTITY_MODES, SURFACES, ENVIRONMENTS, BASE_URL_ENV_VAR, MIN_TIMEOUT_MS, MAX_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, ALL_CAPABILITIES, expandCapabilities, errorOutcome, describeFailure, failureDetails, countsAsNotOn, diagnoseVerdict, isJsonObject, succeed, CAPABILITY_QUESTION, CAPABILITIES_TREE, WEB_EMBEDDING_QUESTION, PLATFORM_TREE, loadDecisionSpace, fetchContract, contractUnavailableOutcome, loadDecisionSpaceFromContract, parseEnvironment, detectProject, planIntegration, fail, ExitCode, DOCS_KEY, resolveContractPath, validateContractFile, buildSupportBundle, renderSupportBundle, chooseWidgetAuth, DIAGNOSTICS_PATH, diagnoseFailure, parseDiagnostics, buildDiagnosisDocument, PARTNER_KEY, SESSION_TOKEN, resolveCredential, ADMIN_TOKEN, withPrefix, parseOrigin, parseLoaderUrl, parseSurfaces, parseIdentityMode, runVerification, PARTNER_SECRET_KEY, resolveOffline,
|
|
2
|
+
import { VERIFY_IDENTITY_MODES, SURFACES, ENVIRONMENTS, BASE_URL_ENV_VAR, MIN_TIMEOUT_MS, MAX_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, ALL_CAPABILITIES, expandCapabilities, errorOutcome, describeFailure, failureDetails, countsAsNotOn, diagnoseVerdict, isJsonObject, succeed, CAPABILITY_QUESTION, CAPABILITIES_TREE, WEB_EMBEDDING_QUESTION, PLATFORM_TREE, loadDecisionSpace, fetchContract, contractUnavailableOutcome, loadDecisionSpaceFromContract, parseEnvironment, checkTenantMode, detectProject, planIntegration, fail, ExitCode, DOCS_KEY, resolveContractPath, validateContractFile, buildSupportBundle, renderSupportBundle, chooseWidgetAuth, DIAGNOSTICS_PATH, diagnoseFailure, parseDiagnostics, buildDiagnosisDocument, PARTNER_KEY, SESSION_TOKEN, resolveCredential, ADMIN_TOKEN, withPrefix, parseOrigin, parseLoaderUrl, parseSurfaces, parseIdentityMode, runVerification, PARTNER_SECRET_KEY, resolveOffline, resolveWithoutRegistry, knownCodes, loadErrorRegistryFromContract, loadErrorRegistry, resolveAfterRegistryMiss, registryAlsoIn, buildExplanationDocument, renderExplanation, alsoInLines, resolveEndpoint, isCorrelatableRequestId, EMPTY_REGISTRY, createApiClient, offlineDocument, renderOffline, IDENTITY_QUESTION, IDENTITY_TREE, BACKEND_LANGUAGE_QUESTION, SESSION_MINT_TREE, CREDENTIAL_SPECS } from './chunk-EBVP6FAD.js';
|
|
3
3
|
import { isAbsolute, resolve } from 'path';
|
|
4
4
|
|
|
5
5
|
// src/cli/format.ts
|
|
@@ -186,6 +186,9 @@ function renderRefusal(document) {
|
|
|
186
186
|
lines.push(` ${fact.fact}`);
|
|
187
187
|
lines.push(` why: ${fact.reason}`);
|
|
188
188
|
lines.push(` supply: ${fact.supplyWith}`);
|
|
189
|
+
if (fact.requiredWhen !== void 0) {
|
|
190
|
+
lines.push(` only when: ${fact.requiredWhen.fact} is ${fact.requiredWhen.oneOf.join(" or ")}; answer it with that fact`);
|
|
191
|
+
}
|
|
189
192
|
}
|
|
190
193
|
lines.push("");
|
|
191
194
|
lines.push(...renderDetected(document));
|
|
@@ -523,6 +526,14 @@ var CONTRACT_FLAG = Object.freeze({
|
|
|
523
526
|
summary: "Path to a contract-public projection, used to explain any error code returned.",
|
|
524
527
|
placeholder: "file"
|
|
525
528
|
});
|
|
529
|
+
var PLAN_CONTRACT_FLAG = Object.freeze({
|
|
530
|
+
...CONTRACT_FLAG,
|
|
531
|
+
summary: "Path to a contract-public projection to plan from (its decision trees), read instead of the contract fetched with EVERFUR_DOCS_KEY."
|
|
532
|
+
});
|
|
533
|
+
var EXPLAIN_CONTRACT_FLAG = Object.freeze({
|
|
534
|
+
...CONTRACT_FLAG,
|
|
535
|
+
summary: "Path to a contract-public projection whose error registry answers the code, read instead of the contract fetched with EVERFUR_DOCS_KEY."
|
|
536
|
+
});
|
|
526
537
|
var CONTRACT_ENV_VAR = "EVERFUR_CONTRACT_PUBLIC";
|
|
527
538
|
var DEFAULT_CONTRACT_PATHS = Object.freeze([
|
|
528
539
|
"contract-public/contract-public.json",
|
|
@@ -613,6 +624,7 @@ var POLL_DELAY_MS = 500;
|
|
|
613
624
|
var MAX_ATTEMPTS = 20;
|
|
614
625
|
var VERIFICATION_SCHEMA_VERSION = 1;
|
|
615
626
|
var VERIFICATION_DOCUMENT_KIND = "everfur.verification";
|
|
627
|
+
var WEB_EMBEDDINGS = Object.freeze(["in-page", "frame"]);
|
|
616
628
|
var FLAGS = Object.freeze([
|
|
617
629
|
BASE_URL_FLAG,
|
|
618
630
|
{
|
|
@@ -630,9 +642,16 @@ var FLAGS = Object.freeze([
|
|
|
630
642
|
{
|
|
631
643
|
name: "origin",
|
|
632
644
|
kind: "string",
|
|
633
|
-
summary: "For a web
|
|
645
|
+
summary: "For a framed web page (the loader and an iframe): the page origin (https://shop.example.com) the frame renders on. Adds the CORS preflight, embed fence, CORS exposure, session policy and loader checks. An in-page integration needs no --origin.",
|
|
634
646
|
placeholder: "origin"
|
|
635
647
|
},
|
|
648
|
+
{
|
|
649
|
+
// The same flag name `plan` takes for the same fact (the argv parser knows it as a value flag).
|
|
650
|
+
name: "embedding",
|
|
651
|
+
kind: "string",
|
|
652
|
+
summary: `With --origin: how the page embeds the surface, ${WEB_EMBEDDINGS.join(" or ")}. frame (the default without --project-root) runs every check; in-page (the SDK's React components in the page) reports the embed fence and the loader N/A, since only the frame uses them. Read from --project-root when not given.`,
|
|
653
|
+
placeholder: "mode"
|
|
654
|
+
},
|
|
636
655
|
{
|
|
637
656
|
name: "loader-url",
|
|
638
657
|
kind: "string",
|
|
@@ -665,10 +684,12 @@ var FLAGS = Object.freeze([
|
|
|
665
684
|
function buildVerificationDocument(verification, baseUrl, cliVersion) {
|
|
666
685
|
const counts = { passed: 0, failed: 0, skipped: 0 };
|
|
667
686
|
let gated = 0;
|
|
687
|
+
let notApplicable = 0;
|
|
668
688
|
for (const entry of verification.steps) {
|
|
669
689
|
if (entry.result === "PASS") counts.passed += 1;
|
|
670
690
|
else if (entry.result === "FAIL") counts.failed += 1;
|
|
671
691
|
else if (entry.result === "GATED") gated += 1;
|
|
692
|
+
else if (entry.result === "N/A") notApplicable += 1;
|
|
672
693
|
else counts.skipped += 1;
|
|
673
694
|
}
|
|
674
695
|
return {
|
|
@@ -677,8 +698,9 @@ function buildVerificationDocument(verification, baseUrl, cliVersion) {
|
|
|
677
698
|
generatedBy: { name: "@everfur/cli", version: cliVersion },
|
|
678
699
|
status: verification.status,
|
|
679
700
|
baseUrl,
|
|
680
|
-
// `gated` appears only when a step was GATED, so a document from a run
|
|
681
|
-
|
|
701
|
+
// `gated` appears only when a step was GATED, and `notApplicable` only when one was N/A, so a document from a run
|
|
702
|
+
// with neither is unchanged.
|
|
703
|
+
summary: { ...counts, ...gated === 0 ? {} : { gated }, ...notApplicable === 0 ? {} : { notApplicable } },
|
|
682
704
|
steps: verification.steps.map((entry) => ({
|
|
683
705
|
id: entry.id,
|
|
684
706
|
title: entry.title,
|
|
@@ -709,6 +731,8 @@ function renderVerification(verification, baseUrl) {
|
|
|
709
731
|
lines.push("Nothing failed, but a step was skipped, so the wire was not fully exercised.");
|
|
710
732
|
} else if (verification.steps.some((entry) => entry.result === "GATED")) {
|
|
711
733
|
lines.push("Nothing failed. A GATED step is a surface Everfur has not switched on for this tenant, not a fault in the integration.");
|
|
734
|
+
} else if (verification.steps.some((entry) => entry.result === "N/A")) {
|
|
735
|
+
lines.push("Nothing failed. An N/A step is a check that does not apply to this integration, and it was not run.");
|
|
712
736
|
} else {
|
|
713
737
|
lines.push(
|
|
714
738
|
verification.steps.some((entry) => entry.id === "anonymous-identity") ? "Every step passed. The anonymous identity, the verdict read, and the verdict itself are all healthy." : "Every step passed. The session mint, the verdict read, and the verdict itself are all healthy."
|
|
@@ -716,6 +740,12 @@ function renderVerification(verification, baseUrl) {
|
|
|
716
740
|
}
|
|
717
741
|
return lines.join("\n");
|
|
718
742
|
}
|
|
743
|
+
function parseEmbedding2(raw) {
|
|
744
|
+
if (raw === null) return { value: null, errors: [] };
|
|
745
|
+
const value = raw.trim();
|
|
746
|
+
const known2 = WEB_EMBEDDINGS.find((embedding) => embedding === value);
|
|
747
|
+
return known2 === void 0 ? { value: null, errors: [`--embedding must be ${WEB_EMBEDDINGS.join(" or ")}, not "${raw}"`] } : { value: known2, errors: [] };
|
|
748
|
+
}
|
|
719
749
|
function parseAttempts(raw) {
|
|
720
750
|
if (raw === null) return { value: DEFAULT_ATTEMPTS, errors: [] };
|
|
721
751
|
const parsed = Number(raw.trim());
|
|
@@ -730,7 +760,7 @@ function parseAttempts(raw) {
|
|
|
730
760
|
var verifyCommand = {
|
|
731
761
|
path: ["verify"],
|
|
732
762
|
summary: "Exercise the wire: mint a session, read the verdict, assert it is not empty.",
|
|
733
|
-
usage: "verify [--base-url <url>] [--user-ref <ref>] [--attempts <n>] [--identity <mode>] [--origin <origin>] [--loader-url <url>] [--surfaces <list>] [--project-root <path>] [--json]",
|
|
763
|
+
usage: "verify [--base-url <url>] [--user-ref <ref>] [--attempts <n>] [--identity <mode>] [--origin <origin>] [--embedding <mode>] [--loader-url <url>] [--surfaces <list>] [--project-root <path>] [--json]",
|
|
734
764
|
flags: FLAGS,
|
|
735
765
|
/**
|
|
736
766
|
* Exactly what `mintSession` resolves: the session token first, else the key pair it mints with locally. Without
|
|
@@ -741,6 +771,7 @@ var verifyCommand = {
|
|
|
741
771
|
const attempts = parseAttempts(flags.string("attempts"));
|
|
742
772
|
const originFlag = flags.string("origin");
|
|
743
773
|
const origin = originFlag === null ? { origin: null, error: null } : parseOrigin(originFlag);
|
|
774
|
+
const embedding = parseEmbedding2(flags.string("embedding"));
|
|
744
775
|
const loaderFlag = flags.string("loader-url");
|
|
745
776
|
const loader = loaderFlag === null ? { url: null, error: null } : parseLoaderUrl(loaderFlag);
|
|
746
777
|
const surfaces = parseSurfaces(flags.string("surfaces"));
|
|
@@ -751,6 +782,7 @@ var verifyCommand = {
|
|
|
751
782
|
const flagErrors = [
|
|
752
783
|
...attempts.errors,
|
|
753
784
|
...origin.error === null ? [] : [origin.error],
|
|
785
|
+
...embedding.errors,
|
|
754
786
|
...loader.error === null ? [] : [loader.error],
|
|
755
787
|
...surfaces.errors,
|
|
756
788
|
...identityMode.errors,
|
|
@@ -771,6 +803,7 @@ var verifyCommand = {
|
|
|
771
803
|
attempts: attempts.value,
|
|
772
804
|
pollDelayMs: POLL_DELAY_MS,
|
|
773
805
|
origin: origin.origin,
|
|
806
|
+
embedding: embedding.value,
|
|
774
807
|
loaderUrl: loader.url,
|
|
775
808
|
transport: context.transport,
|
|
776
809
|
surfaces: surfaces.value ?? [],
|
|
@@ -826,7 +859,7 @@ var FLAGS2 = Object.freeze([
|
|
|
826
859
|
summary: `The Everfur deployment the generated configuration targets: ${ENVIRONMENTS.join(", ")}. Required for a plan that writes configuration; never assumed.`,
|
|
827
860
|
placeholder: "name"
|
|
828
861
|
},
|
|
829
|
-
|
|
862
|
+
PLAN_CONTRACT_FLAG
|
|
830
863
|
]);
|
|
831
864
|
function asJsonObject(document) {
|
|
832
865
|
return JSON.parse(JSON.stringify(document));
|
|
@@ -912,8 +945,10 @@ var planCommand = {
|
|
|
912
945
|
...environment.errors
|
|
913
946
|
]);
|
|
914
947
|
}
|
|
948
|
+
const mode = await checkTenantMode({ env: context.env, environment: environment.value, transport: context.transport, clock: context.clock });
|
|
949
|
+
if (mode.kind === "mismatch") return errorOutcome("usage_error", mode.message, mode.details);
|
|
915
950
|
const detection = detectProject(context.fs, root);
|
|
916
|
-
const
|
|
951
|
+
const planned = planIntegration({
|
|
917
952
|
detection,
|
|
918
953
|
capabilities: supplied.capabilities,
|
|
919
954
|
allCapabilities: supplied.allCapabilities,
|
|
@@ -924,6 +959,7 @@ var planCommand = {
|
|
|
924
959
|
space,
|
|
925
960
|
cliVersion: context.version
|
|
926
961
|
});
|
|
962
|
+
const document = mode.kind === "not_checked" && planned.status === "ready" ? Object.freeze({ ...planned, warnings: Object.freeze([...planned.warnings, mode.warning]) }) : planned;
|
|
927
963
|
const json = asJsonObject(document);
|
|
928
964
|
const text = renderPlan(document);
|
|
929
965
|
if (document.status === "underspecified") return fail(ExitCode.UNDERSPECIFIED, json, text);
|
|
@@ -1115,7 +1151,7 @@ var diagnoseCommand = {
|
|
|
1115
1151
|
};
|
|
1116
1152
|
|
|
1117
1153
|
// src/commands/explain-error/index.ts
|
|
1118
|
-
var FLAGS5 = Object.freeze([
|
|
1154
|
+
var FLAGS5 = Object.freeze([EXPLAIN_CONTRACT_FLAG]);
|
|
1119
1155
|
var POSITIONALS = Object.freeze([
|
|
1120
1156
|
{
|
|
1121
1157
|
name: "code",
|
|
@@ -1136,7 +1172,7 @@ var explainErrorCommand = {
|
|
|
1136
1172
|
return errorOutcome("usage_error", "no error code was given", ["usage: everfur explain-error <code>"]);
|
|
1137
1173
|
}
|
|
1138
1174
|
const offline = resolveOffline(code);
|
|
1139
|
-
if (offline?.kind === "sdk_member") return offlineOutcome(offline, context.version);
|
|
1175
|
+
if (offline?.kind === "sdk_member") return offlineOutcome(offline, context.version, "no_registry");
|
|
1140
1176
|
const contractFlag = flags.string("contract");
|
|
1141
1177
|
const contractPath = findContractPath(context, contractFlag);
|
|
1142
1178
|
let load;
|
|
@@ -1148,10 +1184,13 @@ var explainErrorCommand = {
|
|
|
1148
1184
|
...context.contractCache === void 0 ? {} : { cache: context.contractCache }
|
|
1149
1185
|
});
|
|
1150
1186
|
if (fetched.kind === "unavailable") {
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
return
|
|
1154
|
-
...suggestions.length > 0 ? [`did you mean: ${suggestions.join(", ")}`, "codes are case sensitive; a client branches on the literal"] : [`no
|
|
1187
|
+
const resolved = resolveWithoutRegistry(code);
|
|
1188
|
+
if (resolved.kind !== "unknown") return offlineOutcome(resolved, context.version, "no_registry");
|
|
1189
|
+
return errorOutcome("unknown_error_code", `"${code}" is not a code this CLI knows`, [
|
|
1190
|
+
...resolved.suggestions.length > 0 ? [`did you mean: ${resolved.suggestions.join(", ")}`, "codes are case sensitive; a client branches on the literal"] : [`no similar code exists in the ${knownCodes(null).length} codes this CLI carries`],
|
|
1191
|
+
"searched: the SDK taxonomy, the SDK contract table, the MCP tools' codes, the diagnostics reason codes, this CLI's error codes and the SDK's sub-enums",
|
|
1192
|
+
`the live error registry was not read (${fetched.message}); it can list a code these tables predate:`,
|
|
1193
|
+
...fetched.details.filter((detail) => detail.startsWith("export "))
|
|
1155
1194
|
]);
|
|
1156
1195
|
}
|
|
1157
1196
|
load = loadErrorRegistryFromContract(fetched.contract);
|
|
@@ -1168,11 +1207,11 @@ var explainErrorCommand = {
|
|
|
1168
1207
|
const entry = load.registry.lookup(code);
|
|
1169
1208
|
if (entry === null) {
|
|
1170
1209
|
const fallback = resolveAfterRegistryMiss(code, load.registry);
|
|
1171
|
-
if (fallback.kind !== "unknown") return offlineOutcome(fallback, context.version);
|
|
1210
|
+
if (fallback.kind !== "unknown") return offlineOutcome(fallback, context.version, "registry_miss");
|
|
1172
1211
|
return errorOutcome("unknown_error_code", `"${code}" is not in the error registry`, [
|
|
1173
1212
|
...fallback.suggestions.length > 0 ? [`did you mean: ${fallback.suggestions.join(", ")}`, "codes are case sensitive; a client branches on the literal"] : ["no similar code exists in the registry"],
|
|
1174
1213
|
`the registry loaded from ${load.path} lists ${load.registry.codes.length} codes`,
|
|
1175
|
-
`
|
|
1214
|
+
`no other table this CLI carries knows it either: the SDK taxonomy, the SDK contract table, the MCP tools' codes, the diagnostics reason codes, this CLI's error codes and the SDK's sub-enums (${knownCodes(load.registry).length} codes searched in all)`
|
|
1176
1215
|
]);
|
|
1177
1216
|
}
|
|
1178
1217
|
const input = {
|
|
@@ -1181,11 +1220,13 @@ var explainErrorCommand = {
|
|
|
1181
1220
|
digest: load.digest,
|
|
1182
1221
|
cliVersion: context.version
|
|
1183
1222
|
};
|
|
1184
|
-
|
|
1223
|
+
const document = { ...buildExplanationDocument(input), ...registryAlsoIn(code) };
|
|
1224
|
+
return succeed(document, [renderExplanation(input), ...alsoInLines(document)].join("\n"));
|
|
1185
1225
|
}
|
|
1186
1226
|
};
|
|
1187
|
-
function offlineOutcome(resolution, cliVersion) {
|
|
1188
|
-
|
|
1227
|
+
function offlineOutcome(resolution, cliVersion, context) {
|
|
1228
|
+
const document = offlineDocument(resolution, cliVersion, context);
|
|
1229
|
+
return succeed(document, renderOffline(resolution, document, context));
|
|
1189
1230
|
}
|
|
1190
1231
|
function contractOutcome2(outcome) {
|
|
1191
1232
|
switch (outcome.kind) {
|
|
@@ -1233,7 +1274,11 @@ var FLAGS6 = Object.freeze([
|
|
|
1233
1274
|
]);
|
|
1234
1275
|
var sandboxCreateCommand = {
|
|
1235
1276
|
path: ["sandbox", "create"],
|
|
1236
|
-
|
|
1277
|
+
/**
|
|
1278
|
+
* What the command does TODAY (ROADMAP.md), not the designed claim flow: the live route returns the secret inline and
|
|
1279
|
+
* no claim URL, so the key is revoked unread and the command exits 8 (SECRET_UNCLAIMABLE).
|
|
1280
|
+
*/
|
|
1281
|
+
summary: "Everfur-internal. Mints a partner secret key and, because no claim flow exists to hand it over safely, revokes it again and exits 8. Never prints the secret.",
|
|
1237
1282
|
usage: "sandbox create --client <client-id> [--label <text>] [--base-url <url>] [--json]",
|
|
1238
1283
|
flags: FLAGS6,
|
|
1239
1284
|
/** The one credential this command resolves. It never reads a partner key of either kind. */
|
|
@@ -1357,20 +1402,14 @@ function parseArgv(argv) {
|
|
|
1357
1402
|
const path = [];
|
|
1358
1403
|
const flags = /* @__PURE__ */ new Map();
|
|
1359
1404
|
const errors = [];
|
|
1360
|
-
let sawFlag = false;
|
|
1361
1405
|
for (let index = 0; index < argv.length; index += 1) {
|
|
1362
1406
|
const token = argv[index];
|
|
1363
1407
|
if (token === void 0) continue;
|
|
1364
1408
|
if (token === "--") break;
|
|
1365
1409
|
if (!isFlagToken(token)) {
|
|
1366
|
-
|
|
1367
|
-
errors.push(`unexpected argument "${token}" after flags began`);
|
|
1368
|
-
} else {
|
|
1369
|
-
path.push(token);
|
|
1370
|
-
}
|
|
1410
|
+
path.push(token);
|
|
1371
1411
|
continue;
|
|
1372
1412
|
}
|
|
1373
|
-
sawFlag = true;
|
|
1374
1413
|
const equalsAt = token.indexOf("=");
|
|
1375
1414
|
const rawName = equalsAt === -1 ? token : token.slice(0, equalsAt);
|
|
1376
1415
|
const inlineValue = equalsAt === -1 ? null : token.slice(equalsAt + 1);
|
|
@@ -1477,7 +1516,7 @@ function renderRootHelp(commands, version) {
|
|
|
1477
1516
|
lines.push("", "Global flags");
|
|
1478
1517
|
for (const spec of GLOBAL_FLAGS) lines.push(renderFlag(spec));
|
|
1479
1518
|
lines.push(" --version".padEnd(FLAG_COLUMN) + "Print the CLI version.");
|
|
1480
|
-
lines.push(...environmentBlock(CREDENTIAL_SPECS));
|
|
1519
|
+
lines.push(...environmentBlock(CREDENTIAL_SPECS, "all"));
|
|
1481
1520
|
lines.push(
|
|
1482
1521
|
"",
|
|
1483
1522
|
"Not in this release",
|
|
@@ -1486,9 +1525,10 @@ function renderRootHelp(commands, version) {
|
|
|
1486
1525
|
);
|
|
1487
1526
|
return lines.join("\n");
|
|
1488
1527
|
}
|
|
1489
|
-
function environmentBlock(specs) {
|
|
1528
|
+
function environmentBlock(specs, baseUrlFlag) {
|
|
1490
1529
|
const lines = ["", "Environment"];
|
|
1491
|
-
|
|
1530
|
+
const override = baseUrlFlag === "all" ? " Overridden by --base-url on the commands that take it." : baseUrlFlag ? " Overridden by --base-url." : "";
|
|
1531
|
+
lines.push(` ${BASE_URL_ENV_VAR}`.padEnd(FLAG_COLUMN) + `API base URL.${override}`);
|
|
1492
1532
|
for (const spec of specs) {
|
|
1493
1533
|
lines.push(` ${spec.envVar}`.padEnd(FLAG_COLUMN) + spec.summary);
|
|
1494
1534
|
}
|
|
@@ -1521,7 +1561,9 @@ function renderCommandHelp(command) {
|
|
|
1521
1561
|
lines.push("", "Global flags");
|
|
1522
1562
|
for (const spec of GLOBAL_FLAGS) lines.push(renderFlag(spec));
|
|
1523
1563
|
const credentials = command.credentials ?? [];
|
|
1524
|
-
if (credentials.length > 0)
|
|
1564
|
+
if (credentials.length > 0) {
|
|
1565
|
+
lines.push(...environmentBlock(credentials, command.flags.some((spec) => spec.name === "base-url")));
|
|
1566
|
+
}
|
|
1525
1567
|
return lines.join("\n");
|
|
1526
1568
|
}
|
|
1527
1569
|
|
|
@@ -1561,8 +1603,10 @@ async function runCli(options) {
|
|
|
1561
1603
|
const specs = match.command.positionals ?? [];
|
|
1562
1604
|
if (positionals.length > specs.length) {
|
|
1563
1605
|
const surplus = positionals[specs.length] ?? "";
|
|
1606
|
+
const flagErrors = bindFlags(match.command.flags, parsed);
|
|
1564
1607
|
return formatOutcome(
|
|
1565
1608
|
errorOutcome("usage_error", `unexpected argument "${surplus}" after "${commandName(match.command)}"`, [
|
|
1609
|
+
...flagErrors.ok ? [] : flagErrors.errors,
|
|
1566
1610
|
`usage: everfur ${match.command.usage}`
|
|
1567
1611
|
]),
|
|
1568
1612
|
format
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { buildServer } from './chunk-
|
|
2
|
+
import { buildServer } from './chunk-QCXZJW5C.js';
|
|
3
3
|
import { createServer } from 'http';
|
|
4
4
|
import { timingSafeEqual } from 'crypto';
|
|
5
5
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|