@capxul/mcp 4.20.0-beta.2 → 4.20.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.mjs +692 -21
- package/package.json +3 -3
package/dist/main.mjs
CHANGED
|
@@ -8,8 +8,8 @@ import { createHash } from "node:crypto";
|
|
|
8
8
|
import { createServer } from "node:http";
|
|
9
9
|
import { localhostHostValidation, localhostOriginValidation, toNodeHandler } from "@modelcontextprotocol/node";
|
|
10
10
|
import { z } from "zod";
|
|
11
|
-
import { Cause, Clock, Context, Data, Deferred, Duration, Effect, Exit, Fiber, FiberSet, Layer, Logger, Option, Queue, Ref, Result, Schedule, Schema, SchemaGetter, SchemaIssue, SchemaParser, Scope, Stream, Tracer } from "effect";
|
|
12
|
-
import { FetchHttpClient, Headers, HttpBody, HttpClient, HttpClientResponse, HttpTraceContext } from "effect/unstable/http";
|
|
11
|
+
import { Cause, Clock, Context, Data, Deferred, Duration, Effect, Exit, Fiber, FiberSet, Layer, Logger, Metric, Option, Queue, Ref, References, Result, Schedule, Schema, SchemaGetter, SchemaIssue, SchemaParser, Scope, Stream, Tracer } from "effect";
|
|
12
|
+
import { FetchHttpClient, Headers, HttpBody, HttpClient, HttpClientError, HttpClientResponse, HttpTraceContext } from "effect/unstable/http";
|
|
13
13
|
import { OtlpExporter, OtlpLogger, OtlpMetrics, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
|
|
14
14
|
import { resolve } from "path";
|
|
15
15
|
import util from "util";
|
|
@@ -99,7 +99,12 @@ const CREDENTIAL_FIELDS = /* @__PURE__ */ new Set([
|
|
|
99
99
|
"authcode",
|
|
100
100
|
"authorizationcode",
|
|
101
101
|
"oauthcode",
|
|
102
|
-
"codeverifier"
|
|
102
|
+
"codeverifier",
|
|
103
|
+
"devicecode",
|
|
104
|
+
"usercode",
|
|
105
|
+
"continuitytoken",
|
|
106
|
+
"refreshattemptid",
|
|
107
|
+
"revocationtoken"
|
|
103
108
|
]);
|
|
104
109
|
/** Match credential fields by meaning, without hiding token addresses or replay IDs. */
|
|
105
110
|
function isCredentialField(name, context) {
|
|
@@ -858,6 +863,8 @@ const COUNTRY_CODE_RE = /^[A-Z]{2}$/;
|
|
|
858
863
|
const ACCOUNT_ID_RE = /^account_[0-9A-Za-z]+$/;
|
|
859
864
|
const PARTY_ID_RE$1 = /^party_[0-9A-Za-z]+$/;
|
|
860
865
|
const APP_ID_RE = /^app_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
|
|
866
|
+
const CLIENT_REQUEST_ID_RE = /^creq_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
|
|
867
|
+
const CLIENT_GRANT_ID_RE = /^cgrant_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
|
|
861
868
|
const TX_HASH_RE = /^0x[0-9a-f]{64}$/i;
|
|
862
869
|
const WEI_RE = /^[0-9]+$/;
|
|
863
870
|
Math.floor(Number.MAX_SAFE_INTEGER / 1e3);
|
|
@@ -8180,6 +8187,92 @@ const ContactActionProps = {
|
|
|
8180
8187
|
party_id: OptionalString,
|
|
8181
8188
|
reason_code: OptionalReasonCode
|
|
8182
8189
|
};
|
|
8190
|
+
/** One completed online CLI diagnostic. No command input or provider text. */
|
|
8191
|
+
const CLI_COMMAND_NAMES = [
|
|
8192
|
+
"capxul",
|
|
8193
|
+
"doctor",
|
|
8194
|
+
"telemetry",
|
|
8195
|
+
"telemetry.status",
|
|
8196
|
+
"telemetry.enable",
|
|
8197
|
+
"telemetry.disable",
|
|
8198
|
+
"unknown"
|
|
8199
|
+
];
|
|
8200
|
+
const CLI_CAPABILITIES = [
|
|
8201
|
+
"cli",
|
|
8202
|
+
"diagnostics",
|
|
8203
|
+
"collection"
|
|
8204
|
+
];
|
|
8205
|
+
const CLI_INVOCATION_KINDS = [
|
|
8206
|
+
"command",
|
|
8207
|
+
"help",
|
|
8208
|
+
"version",
|
|
8209
|
+
"completion",
|
|
8210
|
+
"parse_refusal",
|
|
8211
|
+
"collection_control"
|
|
8212
|
+
];
|
|
8213
|
+
const CliRelease = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/u));
|
|
8214
|
+
const CliInvocationProps = {
|
|
8215
|
+
...TelemetryEnvelopeProps,
|
|
8216
|
+
schema_version: Schema.Literal(1),
|
|
8217
|
+
command: Schema.Literals(CLI_COMMAND_NAMES),
|
|
8218
|
+
capability: Schema.Literals(CLI_CAPABILITIES),
|
|
8219
|
+
invocation_kind: Schema.Literals(CLI_INVOCATION_KINDS),
|
|
8220
|
+
invocation_id: Schema.String.check(Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u)),
|
|
8221
|
+
cli_identity_kind: Schema.optional(Schema.Literal("anonymous")),
|
|
8222
|
+
anonymous_id: Schema.optional(Schema.String.check(Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u))),
|
|
8223
|
+
occurred_at: Schema.Number,
|
|
8224
|
+
cli_version: CliRelease,
|
|
8225
|
+
sdk_version: CliRelease,
|
|
8226
|
+
release: CliRelease,
|
|
8227
|
+
platform: Schema.Literals([
|
|
8228
|
+
"darwin",
|
|
8229
|
+
"linux",
|
|
8230
|
+
"unknown"
|
|
8231
|
+
]),
|
|
8232
|
+
architecture: Schema.Literals([
|
|
8233
|
+
"arm64",
|
|
8234
|
+
"x64",
|
|
8235
|
+
"unknown"
|
|
8236
|
+
]),
|
|
8237
|
+
ci: Schema.Boolean,
|
|
8238
|
+
tty: Schema.Boolean,
|
|
8239
|
+
output_mode: Schema.Literals(["human", "json"])
|
|
8240
|
+
};
|
|
8241
|
+
Schema.Struct({
|
|
8242
|
+
name: Schema.Literal("cli_first_used"),
|
|
8243
|
+
props: Schema.Struct(CliInvocationProps)
|
|
8244
|
+
});
|
|
8245
|
+
Schema.Struct({
|
|
8246
|
+
name: Schema.Literal("cli_command_started"),
|
|
8247
|
+
props: Schema.Struct({
|
|
8248
|
+
...CliInvocationProps,
|
|
8249
|
+
invocation_kind: Schema.Literals([
|
|
8250
|
+
"command",
|
|
8251
|
+
"help",
|
|
8252
|
+
"version"
|
|
8253
|
+
])
|
|
8254
|
+
})
|
|
8255
|
+
});
|
|
8256
|
+
Schema.Struct({
|
|
8257
|
+
name: Schema.Literal("cli_command_completed"),
|
|
8258
|
+
props: Schema.Struct({
|
|
8259
|
+
...CliInvocationProps,
|
|
8260
|
+
outcome: Schema.Literals([
|
|
8261
|
+
"succeeded",
|
|
8262
|
+
"refused",
|
|
8263
|
+
"failed",
|
|
8264
|
+
"cancelled"
|
|
8265
|
+
]),
|
|
8266
|
+
duration_ms: Schema.Number,
|
|
8267
|
+
error_code: Schema.optional(Schema.Literals([
|
|
8268
|
+
...CAPXUL_ERROR_CODES,
|
|
8269
|
+
"CLI_USAGE",
|
|
8270
|
+
"CLI_CONFIG",
|
|
8271
|
+
"CLI_STORAGE",
|
|
8272
|
+
"CLI_DEFECT"
|
|
8273
|
+
]))
|
|
8274
|
+
})
|
|
8275
|
+
});
|
|
8183
8276
|
Schema.Struct({
|
|
8184
8277
|
name: Schema.Literal("cli_diagnostic_completed"),
|
|
8185
8278
|
props: Schema.Struct({
|
|
@@ -9045,6 +9138,30 @@ const PAYMENT_DOCUMENT_KINDS = [
|
|
|
9045
9138
|
"receipt",
|
|
9046
9139
|
"withdrawal"
|
|
9047
9140
|
];
|
|
9141
|
+
/** Native browser projection, distinct from the issuer's persisted request state. */
|
|
9142
|
+
const CLIENT_AUTHORIZATION_PHASE = {
|
|
9143
|
+
OTP_REQUIRED: "otp_required",
|
|
9144
|
+
REVIEW: "review",
|
|
9145
|
+
PROCESSING: "processing",
|
|
9146
|
+
CONNECTED: "connected",
|
|
9147
|
+
REFUSED: "refused"
|
|
9148
|
+
};
|
|
9149
|
+
CLIENT_AUTHORIZATION_PHASE.OTP_REQUIRED, CLIENT_AUTHORIZATION_PHASE.REVIEW, CLIENT_AUTHORIZATION_PHASE.PROCESSING, CLIENT_AUTHORIZATION_PHASE.CONNECTED, CLIENT_AUTHORIZATION_PHASE.REFUSED;
|
|
9150
|
+
/** Closed native refusals; existing Capxul error codes retain their own meaning. */
|
|
9151
|
+
const CLIENT_AUTHORIZATION_REFUSALS = [
|
|
9152
|
+
"signup_required",
|
|
9153
|
+
"setup_required",
|
|
9154
|
+
"already_signed_up",
|
|
9155
|
+
"identity_mismatch",
|
|
9156
|
+
"invalid_request",
|
|
9157
|
+
"request_expired",
|
|
9158
|
+
"request_denied",
|
|
9159
|
+
"cancelled",
|
|
9160
|
+
"grant_revoked",
|
|
9161
|
+
"grant_expired",
|
|
9162
|
+
"refresh_reused",
|
|
9163
|
+
"revoke_unconfirmed"
|
|
9164
|
+
];
|
|
9048
9165
|
//#endregion
|
|
9049
9166
|
//#region ../../packages/wire/src/financial-ops.ts
|
|
9050
9167
|
const MINOR_UNIT_STRING_RE = /^[0-9]+$/;
|
|
@@ -10746,6 +10863,251 @@ function isSafeField(field, value) {
|
|
|
10746
10863
|
return value.length > 0 && value.length <= rule.maxLength && value === value.trim() && !value.includes("://") && !containsSensitiveMaterial(value) && rule.pattern.test(value);
|
|
10747
10864
|
}
|
|
10748
10865
|
//#endregion
|
|
10866
|
+
//#region ../../packages/wire/src/client-authorization.ts
|
|
10867
|
+
const NATIVE_CLIENT_ID = "capxul-cli";
|
|
10868
|
+
const NATIVE_CLIENT_SCOPE = "account:read";
|
|
10869
|
+
const NATIVE_CLIENT_LIMITS = {
|
|
10870
|
+
accessMs: 36e5,
|
|
10871
|
+
renewalMs: 2592e6,
|
|
10872
|
+
absoluteMs: 7776e6,
|
|
10873
|
+
requestMs: 6e5,
|
|
10874
|
+
pollSeconds: 5,
|
|
10875
|
+
imageBytes: 5242880
|
|
10876
|
+
};
|
|
10877
|
+
const strict = { parseOptions: { onExcessProperty: "error" } };
|
|
10878
|
+
const text$2 = (max) => Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(max));
|
|
10879
|
+
const nonNegativeInt = Schema.Number.check(Schema.makeFilter((n) => Number.isSafeInteger(n) && n >= 0));
|
|
10880
|
+
const normalize = (f) => Schema.String.pipe(Schema.decodeTo(Schema.String, {
|
|
10881
|
+
decode: SchemaGetter.transform(f),
|
|
10882
|
+
encode: SchemaGetter.transform((s) => s)
|
|
10883
|
+
}));
|
|
10884
|
+
const ClientRequestIdSchema = Schema.String.pipe(Schema.refine((s) => CLIENT_REQUEST_ID_RE.test(s)));
|
|
10885
|
+
const ClientGrantIdSchema = Schema.String.pipe(Schema.refine((s) => CLIENT_GRANT_ID_RE.test(s)));
|
|
10886
|
+
const authUserId = Schema.String.pipe(Schema.refine((s) => s.length > 0));
|
|
10887
|
+
const keyId = Schema.String.pipe(Schema.refine((s) => s.length > 0));
|
|
10888
|
+
const email$1 = normalize((s) => s.toLowerCase()).pipe(Schema.refine((s) => EMAIL_RE$1.test(s))).check(Schema.isMaxLength(254));
|
|
10889
|
+
const handle$1 = Schema.String.pipe(Schema.refine((s) => HANDLE_RE$1.test(s)));
|
|
10890
|
+
const country = normalize((s) => s.toUpperCase()).pipe(Schema.refine((s) => COUNTRY_CODE_RE.test(s)));
|
|
10891
|
+
const credential = Schema.RedactedFromValue(Schema.String.check(Schema.isMinLength(32), Schema.isMaxLength(8192), Schema.isPattern(/^[A-Za-z0-9._~-]+$/u)), { label: "native authorization credential" });
|
|
10892
|
+
const otp = Schema.RedactedFromValue(Schema.String.check(Schema.isPattern(/^[0-9]{6}$/u)), { label: "OTP" });
|
|
10893
|
+
const scopes = Schema.Tuple([Schema.Literal(NATIVE_CLIENT_SCOPE)]);
|
|
10894
|
+
/** Exact HTTPS origin, no credentials/path/query and no retired cloud deployment. */
|
|
10895
|
+
const NativeHttpsOriginSchema = Schema.String.check(Schema.makeFilter((value) => {
|
|
10896
|
+
try {
|
|
10897
|
+
const url = new URL(value);
|
|
10898
|
+
const host = url.hostname.toLowerCase().replace(/\.$/u, "");
|
|
10899
|
+
return url.protocol === "https:" && value === url.origin && !url.username && !url.password && !url.search && !url.hash && host !== "convex.cloud" && !host.endsWith(".convex.cloud") && host !== "convex.site" && !host.endsWith(".convex.site");
|
|
10900
|
+
} catch {
|
|
10901
|
+
return false;
|
|
10902
|
+
}
|
|
10903
|
+
}, { message: "must be a canonical credential-free HTTPS origin outside retired Convex cloud hosts" }));
|
|
10904
|
+
const NativeClientConfigurationSchema = Schema.Struct({
|
|
10905
|
+
clientId: Schema.Literal(NATIVE_CLIENT_ID),
|
|
10906
|
+
applicationId: AppIdSchema,
|
|
10907
|
+
keyId,
|
|
10908
|
+
environment: Schema.Literals([
|
|
10909
|
+
"development",
|
|
10910
|
+
"staging",
|
|
10911
|
+
"production"
|
|
10912
|
+
]),
|
|
10913
|
+
keyEnvironment: Schema.Literals(["test", "live"]),
|
|
10914
|
+
issuer: NativeHttpsOriginSchema,
|
|
10915
|
+
verificationOrigin: NativeHttpsOriginSchema
|
|
10916
|
+
}).annotate(strict).check(Schema.makeFilter((c) => c.keyEnvironment === (c.environment === "production" ? "live" : "test"), { message: "key environment must match the configured deployment" })).annotate(strict);
|
|
10917
|
+
const NativeSignupProfileSchema = Schema.Struct({
|
|
10918
|
+
displayName: normalize((s) => s.trim()).check(Schema.isMinLength(1), Schema.isMaxLength(200)),
|
|
10919
|
+
country,
|
|
10920
|
+
handle: handle$1,
|
|
10921
|
+
payoutAddresses: Schema.optional(Schema.Array(Schema.Struct({
|
|
10922
|
+
chain: Schema.Literals([
|
|
10923
|
+
"evm",
|
|
10924
|
+
"solana",
|
|
10925
|
+
"starknet"
|
|
10926
|
+
]),
|
|
10927
|
+
address: text$2(256)
|
|
10928
|
+
}).annotate(strict)).check(Schema.isMaxLength(10))),
|
|
10929
|
+
image: Schema.optional(Schema.Struct({
|
|
10930
|
+
mediaType: Schema.Literals([
|
|
10931
|
+
"image/jpeg",
|
|
10932
|
+
"image/png",
|
|
10933
|
+
"image/webp"
|
|
10934
|
+
]),
|
|
10935
|
+
byteLength: Schema.Number.check(Schema.isInt(), Schema.isBetween({
|
|
10936
|
+
minimum: 1,
|
|
10937
|
+
maximum: NATIVE_CLIENT_LIMITS.imageBytes
|
|
10938
|
+
})),
|
|
10939
|
+
sha256: Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/u))
|
|
10940
|
+
}).annotate(strict))
|
|
10941
|
+
}).annotate(strict);
|
|
10942
|
+
const ClientAuthorizationIntentSchema = Schema.Union([Schema.Struct({ mode: Schema.Literal("login") }).annotate(strict), Schema.Struct({
|
|
10943
|
+
mode: Schema.Literal("signup"),
|
|
10944
|
+
profile: NativeSignupProfileSchema
|
|
10945
|
+
}).annotate(strict)]).annotate(strict);
|
|
10946
|
+
Schema.Struct({
|
|
10947
|
+
clientId: Schema.Literal(NATIVE_CLIENT_ID),
|
|
10948
|
+
email: email$1,
|
|
10949
|
+
intent: ClientAuthorizationIntentSchema,
|
|
10950
|
+
waitMs: Schema.Number.check(Schema.isInt(), Schema.isBetween({
|
|
10951
|
+
minimum: 1,
|
|
10952
|
+
maximum: NATIVE_CLIENT_LIMITS.requestMs
|
|
10953
|
+
})),
|
|
10954
|
+
continuityToken: Schema.optional(credential)
|
|
10955
|
+
}).annotate(strict);
|
|
10956
|
+
const request = {
|
|
10957
|
+
requestId: ClientRequestIdSchema,
|
|
10958
|
+
revision: nonNegativeInt,
|
|
10959
|
+
expiresAt: EpochMsSchema
|
|
10960
|
+
};
|
|
10961
|
+
const principal = {
|
|
10962
|
+
authUserId,
|
|
10963
|
+
email: email$1
|
|
10964
|
+
};
|
|
10965
|
+
const profileSummary = {
|
|
10966
|
+
displayName: text$2(200),
|
|
10967
|
+
handle: handle$1,
|
|
10968
|
+
country
|
|
10969
|
+
};
|
|
10970
|
+
Schema.Union([
|
|
10971
|
+
Schema.Struct({
|
|
10972
|
+
...request,
|
|
10973
|
+
phase: Schema.Literal(CLIENT_AUTHORIZATION_PHASE.OTP_REQUIRED),
|
|
10974
|
+
email: email$1,
|
|
10975
|
+
resendAt: EpochMsSchema
|
|
10976
|
+
}).annotate(strict),
|
|
10977
|
+
Schema.Struct({
|
|
10978
|
+
...request,
|
|
10979
|
+
phase: Schema.Literal(CLIENT_AUTHORIZATION_PHASE.REVIEW),
|
|
10980
|
+
...principal,
|
|
10981
|
+
clientLabel: Schema.Literal("Capxul CLI"),
|
|
10982
|
+
scopes,
|
|
10983
|
+
intent: ClientAuthorizationIntentSchema,
|
|
10984
|
+
setupState: Schema.Literals([
|
|
10985
|
+
"not_required",
|
|
10986
|
+
"new",
|
|
10987
|
+
"resumable"
|
|
10988
|
+
])
|
|
10989
|
+
}).annotate(strict).check(Schema.makeFilter((v) => v.intent.mode === "login" === (v.setupState === "not_required"), { message: "login review cannot permit account setup" })),
|
|
10990
|
+
Schema.Struct({
|
|
10991
|
+
...request,
|
|
10992
|
+
phase: Schema.Literal(CLIENT_AUTHORIZATION_PHASE.PROCESSING),
|
|
10993
|
+
...principal,
|
|
10994
|
+
purpose: Schema.Literals(["login", "signup"]),
|
|
10995
|
+
step: Schema.Literals([
|
|
10996
|
+
"profile",
|
|
10997
|
+
"wallet",
|
|
10998
|
+
"account",
|
|
10999
|
+
"delivery"
|
|
11000
|
+
])
|
|
11001
|
+
}).annotate(strict).check(Schema.makeFilter((v) => v.purpose === "signup" || v.step === "delivery", { message: "login may wait for delivery but cannot enter signup processing" })),
|
|
11002
|
+
Schema.Struct({
|
|
11003
|
+
...request,
|
|
11004
|
+
phase: Schema.Literal(CLIENT_AUTHORIZATION_PHASE.CONNECTED),
|
|
11005
|
+
...principal,
|
|
11006
|
+
...profileSummary,
|
|
11007
|
+
accountId: AccountIdSchema,
|
|
11008
|
+
grantId: ClientGrantIdSchema
|
|
11009
|
+
}).annotate(strict),
|
|
11010
|
+
Schema.Struct({
|
|
11011
|
+
...request,
|
|
11012
|
+
phase: Schema.Literal(CLIENT_AUTHORIZATION_PHASE.REFUSED),
|
|
11013
|
+
reason: Schema.Literals(CLIENT_AUTHORIZATION_REFUSALS),
|
|
11014
|
+
code: Schema.Literals(CAPXUL_ERROR_CODES),
|
|
11015
|
+
field: Schema.optional(Schema.Literals([
|
|
11016
|
+
"email",
|
|
11017
|
+
"displayName",
|
|
11018
|
+
"country",
|
|
11019
|
+
"handle",
|
|
11020
|
+
"image",
|
|
11021
|
+
"payoutAddresses"
|
|
11022
|
+
])),
|
|
11023
|
+
retryable: Schema.Boolean
|
|
11024
|
+
}).annotate(strict)
|
|
11025
|
+
]).annotate(strict);
|
|
11026
|
+
Schema.Struct({
|
|
11027
|
+
requestId: ClientRequestIdSchema,
|
|
11028
|
+
revision: nonNegativeInt
|
|
11029
|
+
}).annotate(strict);
|
|
11030
|
+
Schema.Struct({
|
|
11031
|
+
requestId: ClientRequestIdSchema,
|
|
11032
|
+
code: otp
|
|
11033
|
+
}).annotate(strict);
|
|
11034
|
+
Schema.Struct({
|
|
11035
|
+
client_id: Schema.Literal(NATIVE_CLIENT_ID),
|
|
11036
|
+
grant_type: Schema.Literal("refresh_token"),
|
|
11037
|
+
refresh_token: credential,
|
|
11038
|
+
refreshAttemptId: Schema.RedactedFromValue(Schema.String.check(Schema.isPattern(/^[A-Za-z0-9_-]{32,128}$/u)), { label: "refresh attempt" })
|
|
11039
|
+
}).annotate(strict);
|
|
11040
|
+
Schema.Struct({
|
|
11041
|
+
client_id: Schema.Literal(NATIVE_CLIENT_ID),
|
|
11042
|
+
applicationId: AppIdSchema,
|
|
11043
|
+
resource: text$2(2048),
|
|
11044
|
+
token_type: Schema.Literal("Bearer"),
|
|
11045
|
+
access_token: credential,
|
|
11046
|
+
refresh_token: credential,
|
|
11047
|
+
scope: Schema.Literal(NATIVE_CLIENT_SCOPE),
|
|
11048
|
+
expires_in: Schema.Number.check(Schema.isInt(), Schema.isBetween({
|
|
11049
|
+
minimum: 1,
|
|
11050
|
+
maximum: NATIVE_CLIENT_LIMITS.accessMs / 1e3
|
|
11051
|
+
})),
|
|
11052
|
+
grantId: ClientGrantIdSchema,
|
|
11053
|
+
...principal,
|
|
11054
|
+
accountId: AccountIdSchema,
|
|
11055
|
+
issuedAt: EpochMsSchema,
|
|
11056
|
+
grantCreatedAt: EpochMsSchema,
|
|
11057
|
+
accessExpiresAt: EpochMsSchema,
|
|
11058
|
+
renewalExpiresAt: EpochMsSchema,
|
|
11059
|
+
absoluteExpiresAt: EpochMsSchema,
|
|
11060
|
+
revision: nonNegativeInt
|
|
11061
|
+
}).annotate(strict).check(Schema.makeFilter((t) => t.grantCreatedAt <= t.issuedAt && t.absoluteExpiresAt - t.grantCreatedAt === NATIVE_CLIENT_LIMITS.absoluteMs && t.renewalExpiresAt <= Math.min(t.issuedAt + NATIVE_CLIENT_LIMITS.renewalMs, t.absoluteExpiresAt) && t.accessExpiresAt <= Math.min(t.issuedAt + NATIVE_CLIENT_LIMITS.accessMs, t.renewalExpiresAt) && t.expires_in === Math.floor((t.accessExpiresAt - t.issuedAt) / 1e3), { message: "native credentials must obey the approved access, renewal and absolute deadlines" })).annotate(strict);
|
|
11062
|
+
/** One endpoint mapping; consumers cannot substitute callback or resource URLs. */
|
|
11063
|
+
function nativeClientEndpoints(config) {
|
|
11064
|
+
const resource = `${config.issuer}/api/auth/native`;
|
|
11065
|
+
return {
|
|
11066
|
+
resource,
|
|
11067
|
+
device_authorization_endpoint: `${resource}/device/code`,
|
|
11068
|
+
token_endpoint: `${resource}/token`,
|
|
11069
|
+
revocation_endpoint: `${resource}/revoke`,
|
|
11070
|
+
session_endpoint: `${resource}/session`,
|
|
11071
|
+
verification_uri: `${config.verificationOrigin}/connect`
|
|
11072
|
+
};
|
|
11073
|
+
}
|
|
11074
|
+
Schema.Struct({
|
|
11075
|
+
protocol: Schema.Literal("capxul.client-authorization"),
|
|
11076
|
+
version: Schema.Literal(1),
|
|
11077
|
+
configuration: NativeClientConfigurationSchema,
|
|
11078
|
+
scopes_supported: scopes,
|
|
11079
|
+
grant_types_supported: Schema.Tuple([Schema.Literal("urn:ietf:params:oauth:grant-type:device_code"), Schema.Literal("refresh_token")]),
|
|
11080
|
+
resource: text$2(2048),
|
|
11081
|
+
device_authorization_endpoint: text$2(2048),
|
|
11082
|
+
token_endpoint: text$2(2048),
|
|
11083
|
+
revocation_endpoint: text$2(2048),
|
|
11084
|
+
session_endpoint: text$2(2048),
|
|
11085
|
+
verification_uri: text$2(2048)
|
|
11086
|
+
}).annotate(strict).check(Schema.makeFilter((m) => {
|
|
11087
|
+
const expected = nativeClientEndpoints(m.configuration);
|
|
11088
|
+
return m.resource === expected.resource && m.device_authorization_endpoint === expected.device_authorization_endpoint && m.token_endpoint === expected.token_endpoint && m.revocation_endpoint === expected.revocation_endpoint && m.session_endpoint === expected.session_endpoint && m.verification_uri === expected.verification_uri;
|
|
11089
|
+
}, { message: "native endpoints must match their configured issuer and verification origin" })).annotate(strict);
|
|
11090
|
+
Schema.Struct({
|
|
11091
|
+
client_id: Schema.Literal(NATIVE_CLIENT_ID),
|
|
11092
|
+
grant_type: Schema.Literal("urn:ietf:params:oauth:grant-type:device_code"),
|
|
11093
|
+
device_code: credential
|
|
11094
|
+
}).annotate(strict);
|
|
11095
|
+
Schema.Struct({
|
|
11096
|
+
requestId: ClientRequestIdSchema,
|
|
11097
|
+
device_code: credential,
|
|
11098
|
+
user_code: Schema.RedactedFromValue(Schema.String.check(Schema.isPattern(/^[A-Z0-9]{4}-[A-Z0-9]{4}$/u)), { label: "device user code" }),
|
|
11099
|
+
continuityToken: credential,
|
|
11100
|
+
verification_uri: text$2(2048),
|
|
11101
|
+
expires_in: Schema.Number.check(Schema.isInt(), Schema.isBetween({
|
|
11102
|
+
minimum: 1,
|
|
11103
|
+
maximum: NATIVE_CLIENT_LIMITS.requestMs / 1e3
|
|
11104
|
+
})),
|
|
11105
|
+
interval: Schema.Number.check(Schema.isInt(), Schema.isBetween({
|
|
11106
|
+
minimum: NATIVE_CLIENT_LIMITS.pollSeconds,
|
|
11107
|
+
maximum: NATIVE_CLIENT_LIMITS.requestMs / 1e3
|
|
11108
|
+
}))
|
|
11109
|
+
}).annotate(strict);
|
|
11110
|
+
//#endregion
|
|
10749
11111
|
//#region ../../packages/sdk/src/internal/invocation-observation.ts
|
|
10750
11112
|
const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
|
|
10751
11113
|
const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
|
|
@@ -13182,7 +13544,7 @@ function subscribeActivity(deps, actor, controls, onChange) {
|
|
|
13182
13544
|
}
|
|
13183
13545
|
//#endregion
|
|
13184
13546
|
//#region ../../packages/sdk/package.json
|
|
13185
|
-
var version$1 = "4.20.0-beta.
|
|
13547
|
+
var version$1 = "4.20.0-beta.3";
|
|
13186
13548
|
//#endregion
|
|
13187
13549
|
//#region ../../packages/sdk/src/telemetry/exception-projection.ts
|
|
13188
13550
|
/** Fixed fallback for failures that have no safe message. */
|
|
@@ -15258,6 +15620,277 @@ async function recoverRawDigestSigner(input) {
|
|
|
15258
15620
|
}
|
|
15259
15621
|
}
|
|
15260
15622
|
//#endregion
|
|
15623
|
+
//#region ../../packages/observability/src/engineering-delivery.ts
|
|
15624
|
+
/** Fixed admission limits for one CLI invocation and its SDK client. */
|
|
15625
|
+
const CLI_ENGINEERING_LIMITS = Object.freeze({
|
|
15626
|
+
records: 80,
|
|
15627
|
+
ordinaryRecords: 64,
|
|
15628
|
+
recordBytes: 16384,
|
|
15629
|
+
requests: 5,
|
|
15630
|
+
ordinaryRequests: 2,
|
|
15631
|
+
requestBytes: 1572864,
|
|
15632
|
+
metricSeries: 16,
|
|
15633
|
+
requestTimeoutMs: 1e3
|
|
15634
|
+
});
|
|
15635
|
+
const text$1 = (value) => typeof value === "string" ? value.slice(0, 128) : "capxul.engineering";
|
|
15636
|
+
const attributes = (input, limit = 32) => {
|
|
15637
|
+
const out = {};
|
|
15638
|
+
let count = 0;
|
|
15639
|
+
let bytes = 0;
|
|
15640
|
+
try {
|
|
15641
|
+
for (const key in input) {
|
|
15642
|
+
if (count++ >= limit) break;
|
|
15643
|
+
if (key.length > 64) continue;
|
|
15644
|
+
const value = Object.getOwnPropertyDescriptor(input, key)?.value;
|
|
15645
|
+
const scalar = typeof value === "string" ? value.slice(0, 128) : typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
15646
|
+
if (scalar === void 0) continue;
|
|
15647
|
+
bytes += new TextEncoder().encode(JSON.stringify([key, scalar])).length;
|
|
15648
|
+
if (bytes > (limit >= 24 ? 2e3 : 300)) break;
|
|
15649
|
+
out[key] = scalar;
|
|
15650
|
+
}
|
|
15651
|
+
} catch {}
|
|
15652
|
+
return out;
|
|
15653
|
+
};
|
|
15654
|
+
const terminalName = (name) => name === "cli.command.completed" || CLI_COMMAND_NAMES.some((command) => name === `cli.command.${command}`);
|
|
15655
|
+
/** Native exporters retain their serialization and scheduling; this owns admission only. */
|
|
15656
|
+
function cliEngineeringDelivery(budget, ownsMetrics) {
|
|
15657
|
+
const closed = Deferred.makeUnsafe();
|
|
15658
|
+
let isClosed = false;
|
|
15659
|
+
let metricsRunning = false;
|
|
15660
|
+
const logs = [];
|
|
15661
|
+
const spans = /* @__PURE__ */ new Map();
|
|
15662
|
+
const terminalBodies = /* @__PURE__ */ new WeakSet();
|
|
15663
|
+
const bodyLeases = /* @__PURE__ */ new WeakMap();
|
|
15664
|
+
const pendingBodies = /* @__PURE__ */ new Set();
|
|
15665
|
+
const holdBody = (body, releases) => {
|
|
15666
|
+
if (releases.length === 0) return;
|
|
15667
|
+
const lease = {
|
|
15668
|
+
started: false,
|
|
15669
|
+
release: () => {
|
|
15670
|
+
if (!pendingBodies.delete(lease)) return;
|
|
15671
|
+
bodyLeases.delete(body);
|
|
15672
|
+
for (const release of releases) release();
|
|
15673
|
+
}
|
|
15674
|
+
};
|
|
15675
|
+
bodyLeases.set(body, lease);
|
|
15676
|
+
pendingBodies.add(lease);
|
|
15677
|
+
};
|
|
15678
|
+
const discardBody = (body) => bodyLeases.get(body)?.release();
|
|
15679
|
+
const drainLogs = () => {
|
|
15680
|
+
for (const release of logs.splice(0)) release();
|
|
15681
|
+
};
|
|
15682
|
+
const close = () => {
|
|
15683
|
+
isClosed = true;
|
|
15684
|
+
Deferred.doneUnsafe(closed, Effect.void);
|
|
15685
|
+
for (const lease of pendingBodies) if (!lease.started) lease.release();
|
|
15686
|
+
drainLogs();
|
|
15687
|
+
for (const release of spans.values()) release();
|
|
15688
|
+
spans.clear();
|
|
15689
|
+
if (ownsMetrics) budget.metricRegistry.clear();
|
|
15690
|
+
};
|
|
15691
|
+
return {
|
|
15692
|
+
close,
|
|
15693
|
+
discardBody,
|
|
15694
|
+
metrics(run) {
|
|
15695
|
+
return Effect.suspend(() => {
|
|
15696
|
+
if (isClosed || metricsRunning) return Effect.void;
|
|
15697
|
+
metricsRunning = true;
|
|
15698
|
+
return run.pipe(Effect.ensuring(Effect.sync(() => {
|
|
15699
|
+
metricsRunning = false;
|
|
15700
|
+
})));
|
|
15701
|
+
});
|
|
15702
|
+
},
|
|
15703
|
+
logger(delegate) {
|
|
15704
|
+
return Logger.make((options) => {
|
|
15705
|
+
if (isClosed) return;
|
|
15706
|
+
let release;
|
|
15707
|
+
try {
|
|
15708
|
+
const message = text$1(Array.isArray(options.message) ? Object.getOwnPropertyDescriptor(options.message, "0")?.value : options.message);
|
|
15709
|
+
release = budget.admitRecord(terminalName(message));
|
|
15710
|
+
if (release === void 0) return;
|
|
15711
|
+
const context = Context.add(options.fiber.context, References.CurrentLogAnnotations, attributes(options.fiber.getRef(References.CurrentLogAnnotations)));
|
|
15712
|
+
const fiber = Object.create(options.fiber);
|
|
15713
|
+
Object.defineProperty(fiber, "getRef", { value: (ref) => Context.get(context, ref) });
|
|
15714
|
+
logs.push(release);
|
|
15715
|
+
delegate.log({
|
|
15716
|
+
...options,
|
|
15717
|
+
message,
|
|
15718
|
+
cause: Cause.empty,
|
|
15719
|
+
fiber
|
|
15720
|
+
});
|
|
15721
|
+
} catch {
|
|
15722
|
+
if (release !== void 0) {
|
|
15723
|
+
const index = logs.indexOf(release);
|
|
15724
|
+
if (index !== -1) logs.splice(index, 1);
|
|
15725
|
+
release();
|
|
15726
|
+
}
|
|
15727
|
+
budget.drop();
|
|
15728
|
+
}
|
|
15729
|
+
});
|
|
15730
|
+
},
|
|
15731
|
+
tracer(delegate) {
|
|
15732
|
+
return Tracer.make({
|
|
15733
|
+
span(options) {
|
|
15734
|
+
const name = text$1(options.name);
|
|
15735
|
+
const release = isClosed ? void 0 : budget.admitRecord(terminalName(name));
|
|
15736
|
+
const spanOptions = {
|
|
15737
|
+
...options,
|
|
15738
|
+
name,
|
|
15739
|
+
annotations: Context.empty(),
|
|
15740
|
+
links: []
|
|
15741
|
+
};
|
|
15742
|
+
const span = release === void 0 ? new Tracer.NativeSpan({
|
|
15743
|
+
...spanOptions,
|
|
15744
|
+
sampled: false
|
|
15745
|
+
}) : delegate.span(spanOptions);
|
|
15746
|
+
if (release !== void 0) spans.set(span.spanId, release);
|
|
15747
|
+
const wrapped = Object.create(span);
|
|
15748
|
+
let fields = 0, events = 0, links = 0, attributeBytes = 0;
|
|
15749
|
+
let ended = false;
|
|
15750
|
+
Object.defineProperties(wrapped, {
|
|
15751
|
+
attribute: { value: (key, value) => {
|
|
15752
|
+
if (fields >= 32 && !span.attributes.has(key)) {
|
|
15753
|
+
budget.drop();
|
|
15754
|
+
return;
|
|
15755
|
+
}
|
|
15756
|
+
const safe = attributes({ [key]: value }, 1);
|
|
15757
|
+
if (!Object.hasOwn(safe, key)) return;
|
|
15758
|
+
const previous = span.attributes.has(key) ? new TextEncoder().encode(JSON.stringify([key, span.attributes.get(key)])).length : 0;
|
|
15759
|
+
const next = new TextEncoder().encode(JSON.stringify([key, safe[key]])).length;
|
|
15760
|
+
if (attributeBytes - previous + next > 2e3) {
|
|
15761
|
+
budget.drop();
|
|
15762
|
+
return;
|
|
15763
|
+
}
|
|
15764
|
+
attributeBytes += next - previous;
|
|
15765
|
+
if (!span.attributes.has(key)) fields += 1;
|
|
15766
|
+
span.attribute(key, safe[key]);
|
|
15767
|
+
} },
|
|
15768
|
+
event: { value: (eventName, time, attrs) => {
|
|
15769
|
+
if (events++ >= 2) {
|
|
15770
|
+
budget.drop();
|
|
15771
|
+
return;
|
|
15772
|
+
}
|
|
15773
|
+
span.event(text$1(eventName), time, attributes(attrs ?? {}, 4));
|
|
15774
|
+
} },
|
|
15775
|
+
addLinks: { value: (items) => {
|
|
15776
|
+
for (const item of items.slice(0, Math.max(0, 2 - links))) {
|
|
15777
|
+
if (!/^[a-f0-9]{32}$/u.test(item.span.traceId) || !/^[a-f0-9]{16}$/u.test(item.span.spanId)) {
|
|
15778
|
+
budget.drop();
|
|
15779
|
+
continue;
|
|
15780
|
+
}
|
|
15781
|
+
span.addLinks([{
|
|
15782
|
+
span: Tracer.externalSpan({
|
|
15783
|
+
traceId: item.span.traceId,
|
|
15784
|
+
spanId: item.span.spanId,
|
|
15785
|
+
sampled: item.span.sampled
|
|
15786
|
+
}),
|
|
15787
|
+
attributes: attributes(item.attributes, 4)
|
|
15788
|
+
}]);
|
|
15789
|
+
links += 1;
|
|
15790
|
+
}
|
|
15791
|
+
} },
|
|
15792
|
+
end: { value: (time, exit) => {
|
|
15793
|
+
if (ended) return;
|
|
15794
|
+
ended = true;
|
|
15795
|
+
span.end(time, Exit.isFailure(exit) ? Exit.fail("CLI operation failed") : Exit.void);
|
|
15796
|
+
} }
|
|
15797
|
+
});
|
|
15798
|
+
wrapped.addLinks(options.links ?? []);
|
|
15799
|
+
return wrapped;
|
|
15800
|
+
},
|
|
15801
|
+
...delegate.context === void 0 ? {} : { context: delegate.context.bind(delegate) }
|
|
15802
|
+
});
|
|
15803
|
+
},
|
|
15804
|
+
serialization(delegate) {
|
|
15805
|
+
return {
|
|
15806
|
+
logs(data) {
|
|
15807
|
+
const releases = logs.splice(0);
|
|
15808
|
+
try {
|
|
15809
|
+
const body = delegate.logs(data);
|
|
15810
|
+
if (data.resourceLogs.some((r) => r.scopeLogs.some((s) => s.logRecords?.some((l) => l.body?.stringValue === "cli.command.completed")))) terminalBodies.add(body);
|
|
15811
|
+
holdBody(body, releases);
|
|
15812
|
+
return body;
|
|
15813
|
+
} catch (error) {
|
|
15814
|
+
for (const release of releases) release();
|
|
15815
|
+
throw error;
|
|
15816
|
+
}
|
|
15817
|
+
},
|
|
15818
|
+
traces(data) {
|
|
15819
|
+
const releases = [];
|
|
15820
|
+
for (const resource of data.resourceSpans) for (const scope of resource.scopeSpans) for (const span of scope.spans) {
|
|
15821
|
+
const release = spans.get(span.spanId);
|
|
15822
|
+
if (release !== void 0) releases.push(release);
|
|
15823
|
+
spans.delete(span.spanId);
|
|
15824
|
+
}
|
|
15825
|
+
try {
|
|
15826
|
+
const body = delegate.traces(data);
|
|
15827
|
+
if (data.resourceSpans.some((r) => r.scopeSpans.some((s) => s.spans.some((span) => terminalName(span.name))))) terminalBodies.add(body);
|
|
15828
|
+
holdBody(body, releases);
|
|
15829
|
+
return body;
|
|
15830
|
+
} catch (error) {
|
|
15831
|
+
for (const release of releases) release();
|
|
15832
|
+
throw error;
|
|
15833
|
+
}
|
|
15834
|
+
},
|
|
15835
|
+
metrics(data) {
|
|
15836
|
+
const body = delegate.metrics(data);
|
|
15837
|
+
terminalBodies.add(body);
|
|
15838
|
+
return body;
|
|
15839
|
+
}
|
|
15840
|
+
};
|
|
15841
|
+
},
|
|
15842
|
+
transport(client, enabled = () => true) {
|
|
15843
|
+
const retrying = HttpClient.transform(client, (response, request) => Effect.suspend(() => {
|
|
15844
|
+
if (enabled()) return response;
|
|
15845
|
+
budget.drop();
|
|
15846
|
+
return Effect.succeed(HttpClientResponse.fromWeb(request, new Response(null)));
|
|
15847
|
+
})).pipe(HttpClient.transformResponse((response) => Effect.tap(response, (result) => {
|
|
15848
|
+
let received = 0;
|
|
15849
|
+
return Stream.runForEach(result.stream, (chunk) => Effect.sync(() => {
|
|
15850
|
+
received += chunk.byteLength;
|
|
15851
|
+
if (received > 65536) throw new Error("Engineering response limit exceeded");
|
|
15852
|
+
})).pipe(Effect.catchTag("HttpClientError", (error) => error.reason._tag === "EmptyBodyError" ? Effect.void : Effect.fail(error)));
|
|
15853
|
+
}))).pipe(HttpClient.filterStatusOk, HttpClient.retryTransient({
|
|
15854
|
+
times: 1,
|
|
15855
|
+
schedule: Schedule.spaced("100 millis").pipe(Schedule.addDelay(({ input }) => Effect.map(Clock.currentTimeMillis, (now) => {
|
|
15856
|
+
if (!HttpClientError.isHttpClientError(input) || input.reason._tag !== "StatusCodeError" || input.reason.response.status !== 429) return Duration.zero;
|
|
15857
|
+
const header = input.reason.response.headers["retry-after"];
|
|
15858
|
+
const numeric = Number(header);
|
|
15859
|
+
const delay = header === void 0 ? 2e3 : Number.isFinite(numeric) ? numeric * 1e3 : Date.parse(header) - now;
|
|
15860
|
+
return Duration.millis(Number.isFinite(delay) ? Math.min(2e3, Math.max(0, delay)) : 2e3);
|
|
15861
|
+
})))
|
|
15862
|
+
}));
|
|
15863
|
+
return HttpClient.transform(retrying, (response, request) => Effect.suspend(() => {
|
|
15864
|
+
if (isClosed) {
|
|
15865
|
+
discardBody(request.body);
|
|
15866
|
+
return Effect.succeed(HttpClientResponse.fromWeb(request, new Response(null)));
|
|
15867
|
+
}
|
|
15868
|
+
const droppedResponse = () => HttpClientResponse.fromWeb(request, new Response(null, { status: 200 }));
|
|
15869
|
+
if (request.body._tag === "Empty") {
|
|
15870
|
+
discardBody(request.body);
|
|
15871
|
+
return Effect.succeed(droppedResponse());
|
|
15872
|
+
}
|
|
15873
|
+
const bytes = request.body.contentLength;
|
|
15874
|
+
const release = budget.admitRequest(bytes ?? Number.POSITIVE_INFINITY, terminalBodies.has(request.body));
|
|
15875
|
+
if (release === void 0) {
|
|
15876
|
+
discardBody(request.body);
|
|
15877
|
+
return Effect.succeed(droppedResponse());
|
|
15878
|
+
}
|
|
15879
|
+
const lease = bodyLeases.get(request.body);
|
|
15880
|
+
if (lease !== void 0) lease.started = true;
|
|
15881
|
+
return response.pipe(Effect.asVoid, Effect.timeoutOption(CLI_ENGINEERING_LIMITS.requestTimeoutMs), Effect.raceFirst(Deferred.await(closed).pipe(Effect.andThen(Effect.interrupt))), Effect.tap((result) => Effect.sync(() => {
|
|
15882
|
+
if (Option.isNone(result)) budget.drop();
|
|
15883
|
+
})), Effect.catchCause(() => Effect.sync(() => {
|
|
15884
|
+
budget.drop();
|
|
15885
|
+
})), Effect.as(droppedResponse()), Effect.ensuring(Effect.sync(() => {
|
|
15886
|
+
release();
|
|
15887
|
+
discardBody(request.body);
|
|
15888
|
+
})));
|
|
15889
|
+
}));
|
|
15890
|
+
}
|
|
15891
|
+
};
|
|
15892
|
+
}
|
|
15893
|
+
//#endregion
|
|
15261
15894
|
//#region ../../packages/observability/src/engineering.ts
|
|
15262
15895
|
const ENGINEERING_CAPXUL_ENVS = [
|
|
15263
15896
|
"development",
|
|
@@ -15432,10 +16065,13 @@ const MINIMAL_NUMBERS = /* @__PURE__ */ new Set([
|
|
|
15432
16065
|
const MINIMAL_CORRELATIONS = /* @__PURE__ */ new Set([
|
|
15433
16066
|
"correlation_id",
|
|
15434
16067
|
"journey_id",
|
|
15435
|
-
"invocation_id"
|
|
16068
|
+
"invocation_id",
|
|
16069
|
+
"posthogDistinctId"
|
|
15436
16070
|
]);
|
|
15437
16071
|
const MINIMAL_METRIC_LABELS = /* @__PURE__ */ new Set([
|
|
15438
16072
|
"command",
|
|
16073
|
+
"capability",
|
|
16074
|
+
"invocation_kind",
|
|
15439
16075
|
"outcome",
|
|
15440
16076
|
"capxul_env",
|
|
15441
16077
|
"unit"
|
|
@@ -15443,7 +16079,7 @@ const MINIMAL_METRIC_LABELS = /* @__PURE__ */ new Set([
|
|
|
15443
16079
|
const MINIMAL_METRIC_NAMES = /* @__PURE__ */ new Set(["capxul.cli.command.count", "capxul.cli.command.duration"]);
|
|
15444
16080
|
const traceId = (value) => typeof value === "string" && /^(?!0+$)[0-9a-f]{32}$/u.test(value);
|
|
15445
16081
|
const spanId = (value) => typeof value === "string" && /^(?!0+$)[0-9a-f]{16}$/u.test(value);
|
|
15446
|
-
const minimalName = (value) => typeof value === "string" && (MINIMAL_LOG_NAMES.has(value) || isCapxulOperation(value)) ? value : "capxul.engineering";
|
|
16082
|
+
const minimalName = (value) => typeof value === "string" && (MINIMAL_LOG_NAMES.has(value) || isCapxulOperation(value) || CLI_COMMAND_NAMES.some((command) => value === `cli.command.${command}`)) ? value : "capxul.engineering";
|
|
15447
16083
|
const MINIMAL_ENUM_VALUES = /* @__PURE__ */ new Map([
|
|
15448
16084
|
["outcome", [
|
|
15449
16085
|
"succeeded",
|
|
@@ -15456,7 +16092,10 @@ const MINIMAL_ENUM_VALUES = /* @__PURE__ */ new Map([
|
|
|
15456
16092
|
["failure_mode", FAILURE_MODES$1],
|
|
15457
16093
|
["capxul_env", ENGINEERING_CAPXUL_ENVS],
|
|
15458
16094
|
["producer", ["browser", "server"]],
|
|
15459
|
-
["command",
|
|
16095
|
+
["command", CLI_COMMAND_NAMES],
|
|
16096
|
+
["capability", CLI_CAPABILITIES],
|
|
16097
|
+
["invocation_kind", CLI_INVOCATION_KINDS],
|
|
16098
|
+
["cli_identity_kind", ["anonymous"]],
|
|
15460
16099
|
["output_mode", ["human", "json"]],
|
|
15461
16100
|
["unit", [
|
|
15462
16101
|
"1",
|
|
@@ -15673,10 +16312,12 @@ function minimalSerialization(config) {
|
|
|
15673
16312
|
};
|
|
15674
16313
|
}
|
|
15675
16314
|
Effect.flatMap(OtlpExporter.Flusher, (flusher) => flusher.flush);
|
|
16315
|
+
var EngineeringLog = class extends Context.Service()("capxul/EngineeringLog") {};
|
|
15676
16316
|
/** Shared browser/server OTLP layer. OtlpLogger merges with incumbent loggers once. */
|
|
15677
16317
|
const makeEngineeringTelemetryLayer = (config) => {
|
|
15678
16318
|
const validated = validateEngineeringTelemetryConfig(config);
|
|
15679
16319
|
return Layer.suspend(() => {
|
|
16320
|
+
const bounded = validated.deliveryBudget === void 0 ? void 0 : cliEngineeringDelivery(validated.deliveryBudget, validated.serviceName === "capxul-cli");
|
|
15680
16321
|
const endpoints = postHogOtlpEndpoints(validated.host);
|
|
15681
16322
|
let disabled = false;
|
|
15682
16323
|
const enabled = () => {
|
|
@@ -15690,7 +16331,12 @@ const makeEngineeringTelemetryLayer = (config) => {
|
|
|
15690
16331
|
};
|
|
15691
16332
|
const delivery = {
|
|
15692
16333
|
...validated.shutdownTimeout === void 0 ? {} : { shutdownTimeout: validated.shutdownTimeout },
|
|
15693
|
-
...validated.exportInterval === void 0 ? {} : { exportInterval: validated.exportInterval }
|
|
16334
|
+
...validated.exportInterval === void 0 ? {} : { exportInterval: validated.exportInterval },
|
|
16335
|
+
...bounded === void 0 ? {} : {
|
|
16336
|
+
maxBatchSize: Number.MAX_SAFE_INTEGER,
|
|
16337
|
+
exportInterval: 1e3,
|
|
16338
|
+
shutdownTimeout: validated.serviceName === "capxul-cli" ? 0 : 500
|
|
16339
|
+
}
|
|
15694
16340
|
};
|
|
15695
16341
|
const resource = {
|
|
15696
16342
|
serviceName: validated.serviceName ?? "capxul-sdk",
|
|
@@ -15706,22 +16352,38 @@ const makeEngineeringTelemetryLayer = (config) => {
|
|
|
15706
16352
|
headers: validated.headers,
|
|
15707
16353
|
resource,
|
|
15708
16354
|
...delivery
|
|
15709
|
-
}).pipe(Effect.map((tracer) => makeLeakSafeEngineeringTracer(tracer, enabled)))).pipe(Layer.provideMerge(OtlpExporter.layerFlusher));
|
|
15710
|
-
const
|
|
16355
|
+
}).pipe(Effect.map((tracer) => makeLeakSafeEngineeringTracer(bounded?.tracer(tracer) ?? tracer, enabled)))).pipe(Layer.provideMerge(OtlpExporter.layerFlusher));
|
|
16356
|
+
const ownedLogging = Layer.effect(EngineeringLog, OtlpLogger.make({
|
|
15711
16357
|
url: endpoints.logs,
|
|
15712
16358
|
headers: validated.headers,
|
|
15713
16359
|
resource,
|
|
15714
|
-
...delivery
|
|
15715
|
-
|
|
15716
|
-
|
|
15717
|
-
|
|
15718
|
-
|
|
16360
|
+
...delivery,
|
|
16361
|
+
...bounded === void 0 ? {} : { excludeLogSpans: true }
|
|
16362
|
+
}).pipe(Effect.map((nativeLogger) => {
|
|
16363
|
+
const logger = bounded?.logger(nativeLogger) ?? nativeLogger;
|
|
16364
|
+
return Logger.make((options) => {
|
|
16365
|
+
if (enabled()) logger.log(options);
|
|
16366
|
+
});
|
|
16367
|
+
}))).pipe(Layer.provideMerge(OtlpExporter.layerFlusher));
|
|
16368
|
+
const logging = Logger.layer([EngineeringLog], { mergeWithExisting: true }).pipe(Layer.provideMerge(ownedLogging));
|
|
16369
|
+
const metricConfig = {
|
|
15719
16370
|
url: endpoints.metrics,
|
|
15720
16371
|
headers: validated.headers,
|
|
15721
16372
|
resource,
|
|
15722
16373
|
temporality: "delta",
|
|
15723
16374
|
...delivery
|
|
15724
|
-
}
|
|
16375
|
+
};
|
|
16376
|
+
const metrics = bounded === void 0 ? OtlpMetrics.layer(metricConfig) : validated.serviceName !== "capxul-cli" ? Layer.empty : Layer.effectDiscard(Effect.gen(function* () {
|
|
16377
|
+
const flusher = yield* OtlpExporter.Flusher;
|
|
16378
|
+
yield* OtlpMetrics.make({
|
|
16379
|
+
...metricConfig,
|
|
16380
|
+
exportInterval: Number.POSITIVE_INFINITY,
|
|
16381
|
+
shutdownTimeout: 0
|
|
16382
|
+
}).pipe(Effect.provideService(OtlpExporter.Flusher, {
|
|
16383
|
+
...flusher,
|
|
16384
|
+
register: (run) => flusher.register(bounded.metrics(run))
|
|
16385
|
+
}));
|
|
16386
|
+
})).pipe(Layer.provideMerge(OtlpExporter.layerFlusher));
|
|
15725
16387
|
const headerPolicy = Layer.merge(Layer.succeed(HttpClient.TracerHeaderFilter, traceHeaderFilter), Layer.succeed(Headers.CurrentRedactedNames, [credentialHeaderPattern]));
|
|
15726
16388
|
const browserLifecycle = Layer.effectDiscard(Effect.gen(function* () {
|
|
15727
16389
|
if (validated.producer !== "browser" || !hasBrowserDocument()) return;
|
|
@@ -15744,17 +16406,25 @@ const makeEngineeringTelemetryLayer = (config) => {
|
|
|
15744
16406
|
}));
|
|
15745
16407
|
}));
|
|
15746
16408
|
const transport = Layer.effect(HttpClient.HttpClient, Effect.map(HttpClient.HttpClient, (client) => {
|
|
15747
|
-
const
|
|
15748
|
-
|
|
16409
|
+
const originalTransport = validated.producer === "browser" && hasBrowserDocument() ? browserExportClient(client) : client;
|
|
16410
|
+
const selectedTransport = bounded?.transport(originalTransport, enabled) ?? originalTransport;
|
|
16411
|
+
return HttpClient.transform(selectedTransport, (response, request) => Effect.suspend(() => {
|
|
16412
|
+
if (enabled() && request.body._tag !== "Empty") return response;
|
|
16413
|
+
bounded?.discardBody(request.body);
|
|
16414
|
+
return Effect.succeed(HttpClientResponse.fromWeb(request, new Response(null, { status: 200 })));
|
|
16415
|
+
}));
|
|
15749
16416
|
})).pipe(Layer.provide(FetchHttpClient.layer));
|
|
15750
16417
|
const serialization = Layer.effect(OtlpSerialization.OtlpSerialization, Effect.map(OtlpSerialization.OtlpSerialization, (json) => {
|
|
15751
16418
|
const projected = minimalSerialization(validated);
|
|
15752
|
-
|
|
16419
|
+
const selected = validated.privacy === "minimal" ? projected : {
|
|
15753
16420
|
...json,
|
|
15754
16421
|
metrics: projected.metrics
|
|
15755
16422
|
};
|
|
16423
|
+
return bounded?.serialization(selected) ?? selected;
|
|
15756
16424
|
})).pipe(Layer.provide(OtlpSerialization.layerJson));
|
|
15757
|
-
|
|
16425
|
+
const combined = browserLifecycle.pipe(Layer.provideMerge(Layer.mergeAll(tracing, logging, metrics, headerPolicy)), Layer.provide(serialization), Layer.provide(transport));
|
|
16426
|
+
const scoped = bounded === void 0 ? combined : combined.pipe(Layer.provideMerge(Layer.effectDiscard(Effect.addFinalizer(() => Effect.sync(bounded.close)))));
|
|
16427
|
+
return validated.deliveryBudget === void 0 ? scoped : scoped.pipe(Layer.provideMerge(Layer.succeed(Metric.MetricRegistry, validated.serviceName === "capxul-cli" ? validated.deliveryBudget.metricRegistry : validated.deliveryBudget.emptyMetricRegistry())));
|
|
15758
16428
|
});
|
|
15759
16429
|
};
|
|
15760
16430
|
//#endregion
|
|
@@ -47994,6 +48664,7 @@ function snapshotHostObservability(observability) {
|
|
|
47994
48664
|
function hostEngineeringPolicy(observability) {
|
|
47995
48665
|
const policy = observability?.[HOST_ENGINEERING_POLICY];
|
|
47996
48666
|
return {
|
|
48667
|
+
...policy?.engineeringDeliveryBudget === void 0 ? {} : { deliveryBudget: policy.engineeringDeliveryBudget },
|
|
47997
48668
|
...policy?.engineeringEnabled === void 0 ? {} : { enabled: policy.engineeringEnabled },
|
|
47998
48669
|
...policy?.engineeringPrivacy === void 0 ? {} : { privacy: policy.engineeringPrivacy }
|
|
47999
48670
|
};
|
|
@@ -49877,7 +50548,7 @@ function stdioIdentity(env = process.env, options = {}) {
|
|
|
49877
50548
|
}
|
|
49878
50549
|
//#endregion
|
|
49879
50550
|
//#region package.json
|
|
49880
|
-
var version = "4.20.0-beta.
|
|
50551
|
+
var version = "4.20.0-beta.3";
|
|
49881
50552
|
//#endregion
|
|
49882
50553
|
//#region src/deps.ts
|
|
49883
50554
|
const NO_IDENTITY = async () => void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capxul/mcp",
|
|
3
|
-
"version": "4.20.0-beta.
|
|
3
|
+
"version": "4.20.0-beta.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Capxul MCP server for auth, Account readiness, identity, Organizations, relationships, requests, destinations, and testnet funding over Streamable HTTP.",
|
|
6
6
|
"keywords": [
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
|
|
52
52
|
"vite-plus": "0.3.0",
|
|
53
53
|
"@capxul/config": "0.3.0",
|
|
54
|
-
"@capxul/
|
|
55
|
-
"@capxul/
|
|
54
|
+
"@capxul/typescript-config": "0.0.0",
|
|
55
|
+
"@capxul/sdk": "4.20.0-beta.3"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"dev": "vp exec tsx src/main.ts serve",
|