@cmmd-center/forge 0.13.0 → 0.13.2
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/bin.cjs +409 -134
- package/dist/bin.mjs +433 -158
- package/dist/client/assets/{CanvasPanel-BUdwnabz.js → CanvasPanel-BrVen-8G.js} +2 -2
- package/dist/client/assets/{CompositeItem-BxaZQRyb.js → CompositeItem-BNZfMUvm.js} +2 -2
- package/dist/client/assets/{DiffPanel-BOLibNHF.js → DiffPanel-Bh9UFe_U.js} +2 -2
- package/dist/client/assets/{DiffPanel.logic-BrRjlJeM.js → DiffPanel.logic-A3r3u_Vr.js} +2 -2
- package/dist/client/assets/{DiffPanelShell-CgycIPfE.js → DiffPanelShell-B30xoHOs.js} +3 -3
- package/dist/client/assets/{DiffWorkerPoolProvider-jWJpEXVo.js → DiffWorkerPoolProvider-CYkhfTpq.js} +2 -2
- package/dist/client/assets/{PullRequestCodePanel-BW7XdaG8.js → PullRequestCodePanel-T32DALQE.js} +2 -2
- package/dist/client/assets/{Virtualizer-qjNwH1hl.js → Virtualizer-DbDh3RHG.js} +2 -2
- package/dist/client/assets/{canvasStateStore-DDwjZ3AG.js → canvasStateStore-DN5mPB5B.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-CPfIOB5Y.js → cmmdAuthRedirect-sqR8W6vY.js} +2 -2
- package/dist/client/assets/{index-9clxg-cN.js → index-FpNJGy15.js} +59 -59
- package/dist/client/assets/{src-dZ5rHSKC.js → src-CFqnisEM.js} +2 -2
- package/dist/client/assets/{toggle-Bn-2EZmB.js → toggle-CLUqZXdO.js} +2 -2
- package/dist/client/assets/{useTriggerFocusGuards-DRINKzwL.js → useTriggerFocusGuards-CaUimC-O.js} +2 -2
- package/dist/client/index.html +10 -10
- package/dist/forge-build.json +1 -1
- package/dist/{open-D8mGyWmt.mjs → open-FIgTDosf.mjs} +3 -3
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -16544,7 +16544,7 @@ function makeNetServiceShape(createServer = node_net.createServer) {
|
|
|
16544
16544
|
}
|
|
16545
16545
|
//#endregion
|
|
16546
16546
|
//#region ../../packages/shared/src/releaseInfo.generated.ts
|
|
16547
|
-
const FORGE_RELEASE_VERSION = "0.13.
|
|
16547
|
+
const FORGE_RELEASE_VERSION = "0.13.2";
|
|
16548
16548
|
//#endregion
|
|
16549
16549
|
//#region ../../packages/shared/src/hostProcess.ts
|
|
16550
16550
|
/**
|
|
@@ -22647,6 +22647,27 @@ const ProviderUnavailableDetail = require_Schema$1.Literals([
|
|
|
22647
22647
|
"delivery-pending",
|
|
22648
22648
|
"reconnect-required"
|
|
22649
22649
|
]);
|
|
22650
|
+
/**
|
|
22651
|
+
* Whether the provider CLI honours the credential-directory variable, as this
|
|
22652
|
+
* Environment's probe found. `inconclusive` is a probe that ran and could not
|
|
22653
|
+
* tell. It is not `unsupported`, and it is never reported as `supported`. The
|
|
22654
|
+
* members are CMMD's `forgeRuntimeInventoryCredentialDirectoryAnswers`.
|
|
22655
|
+
*/
|
|
22656
|
+
const ProviderCredentialDirectoryAnswer = require_Schema$1.Literals([
|
|
22657
|
+
"supported",
|
|
22658
|
+
"unsupported",
|
|
22659
|
+
"inconclusive"
|
|
22660
|
+
]);
|
|
22661
|
+
/**
|
|
22662
|
+
* Which Credential Store the provider CLI uses on this Environment: its file,
|
|
22663
|
+
* the operating system's store, or `unknown` when it cannot be read the way
|
|
22664
|
+
* the CLI reads it. The members are CMMD's `forgeRuntimeInventoryCredentialStores`.
|
|
22665
|
+
*/
|
|
22666
|
+
const ProviderCredentialStore = require_Schema$1.Literals([
|
|
22667
|
+
"file",
|
|
22668
|
+
"os",
|
|
22669
|
+
"unknown"
|
|
22670
|
+
]);
|
|
22650
22671
|
const ServerProviderModel = require_Schema$1.Struct({
|
|
22651
22672
|
slug: TrimmedNonEmptyString,
|
|
22652
22673
|
name: TrimmedNonEmptyString,
|
|
@@ -22683,6 +22704,8 @@ const ServerProvider = require_Schema$1.Struct({
|
|
|
22683
22704
|
availability: require_Schema$1.optional(ProviderAvailability),
|
|
22684
22705
|
unavailableReason: require_Schema$1.optional(ProviderUnavailableReason),
|
|
22685
22706
|
unavailableDetail: require_Schema$1.optional(ProviderUnavailableDetail),
|
|
22707
|
+
credentialDirectory: require_Schema$1.optional(ProviderCredentialDirectoryAnswer),
|
|
22708
|
+
credentialStore: require_Schema$1.optional(ProviderCredentialStore),
|
|
22686
22709
|
slashCommands: require_Schema$1.ArraySchema(ServerProviderSlashCommand).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed([]))),
|
|
22687
22710
|
skills: require_Schema$1.ArraySchema(ServerProviderSkill).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed([])))
|
|
22688
22711
|
});
|
|
@@ -26721,12 +26744,12 @@ function encodeCmmdRuntimeThreadWorkspaceMetadata(workspace) {
|
|
|
26721
26744
|
}
|
|
26722
26745
|
//#endregion
|
|
26723
26746
|
//#region ../../packages/contracts/src/cmmdRuntimeToolActivity.ts
|
|
26724
|
-
function isRecord$
|
|
26747
|
+
function isRecord$23(value) {
|
|
26725
26748
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26726
26749
|
}
|
|
26727
26750
|
function encodeCmmdRuntimeToolActivityPayload(kind, payload) {
|
|
26728
26751
|
return {
|
|
26729
|
-
...isRecord$
|
|
26752
|
+
...isRecord$23(payload) ? payload : { sourcePayload: payload },
|
|
26730
26753
|
forgeToolActivity: {
|
|
26731
26754
|
schemaVersion: 1,
|
|
26732
26755
|
source: "native",
|
|
@@ -30726,13 +30749,13 @@ async function completePendingDesktopRelayIdentityRotation(input) {
|
|
|
30726
30749
|
}
|
|
30727
30750
|
//#endregion
|
|
30728
30751
|
//#region ../../packages/relay-host/src/internal/desktopRelayJws.ts
|
|
30729
|
-
function isRecord$
|
|
30752
|
+
function isRecord$22(value) {
|
|
30730
30753
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30731
30754
|
}
|
|
30732
30755
|
function decodeBase64UrlJson$1(value) {
|
|
30733
30756
|
try {
|
|
30734
30757
|
const decoded = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
30735
|
-
return isRecord$
|
|
30758
|
+
return isRecord$22(decoded) ? decoded : null;
|
|
30736
30759
|
} catch {
|
|
30737
30760
|
return null;
|
|
30738
30761
|
}
|
|
@@ -30886,11 +30909,11 @@ var DesktopRelayControlPlaneError = class extends Error {
|
|
|
30886
30909
|
this.name = "DesktopRelayControlPlaneError";
|
|
30887
30910
|
}
|
|
30888
30911
|
};
|
|
30889
|
-
function isRecord$
|
|
30912
|
+
function isRecord$21(value) {
|
|
30890
30913
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30891
30914
|
}
|
|
30892
30915
|
function parseErrorPayload(value) {
|
|
30893
|
-
return isRecord$
|
|
30916
|
+
return isRecord$21(value) ? value : {};
|
|
30894
30917
|
}
|
|
30895
30918
|
function messageFromErrorPayload(payload, fallback) {
|
|
30896
30919
|
return typeof payload.error === "string" && payload.error.trim().length > 0 ? payload.error.trim() : fallback;
|
|
@@ -30988,7 +31011,7 @@ async function postControlPlane(input) {
|
|
|
30988
31011
|
const errorPayload = parseErrorPayload(payload);
|
|
30989
31012
|
throw new DesktopRelayControlPlaneError(typeof errorPayload.code === "string" && errorPayload.code.trim().length > 0 ? errorPayload.code.trim() : `CMMD_HTTP_${response.status}`, messageFromErrorPayload(errorPayload, `CMMD relay request failed (${response.status}).`), response.status === 408 || response.status === 429 || response.status >= 500);
|
|
30990
31013
|
}
|
|
30991
|
-
if (!isRecord$
|
|
31014
|
+
if (!isRecord$21(payload) || !("data" in payload)) throw new DesktopRelayControlPlaneError("CONTROL_PLANE_INVALID_RESPONSE", "CMMD returned an invalid Forge relay response.", false);
|
|
30992
31015
|
return payload.data;
|
|
30993
31016
|
}
|
|
30994
31017
|
function resolveRegisteredDevice(input) {
|
|
@@ -65841,7 +65864,7 @@ function normalizeNumberish(value) {
|
|
|
65841
65864
|
}
|
|
65842
65865
|
//#endregion
|
|
65843
65866
|
//#region package.json
|
|
65844
|
-
var version$1 = "0.13.
|
|
65867
|
+
var version$1 = "0.13.2";
|
|
65845
65868
|
//#endregion
|
|
65846
65869
|
//#region src/sentry.ts
|
|
65847
65870
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -71405,12 +71428,12 @@ function resolveDesktopRelayControlPlaneTarget(path, configuredRuntimeId) {
|
|
|
71405
71428
|
code: "RELAY_OPERATION_DENIED"
|
|
71406
71429
|
};
|
|
71407
71430
|
}
|
|
71408
|
-
function isRecord$
|
|
71431
|
+
function isRecord$20(value) {
|
|
71409
71432
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
71410
71433
|
}
|
|
71411
71434
|
function relayControlPlaneBodyMatchesRuntime(path, body, configuredRuntimeId) {
|
|
71412
71435
|
if (path !== "/api/forge/context/devices/register") return true;
|
|
71413
|
-
if (!isRecord$
|
|
71436
|
+
if (!isRecord$20(body) || !isRecord$20(body.runtime)) return false;
|
|
71414
71437
|
return body.runtime.runtimeId === configuredRuntimeId;
|
|
71415
71438
|
}
|
|
71416
71439
|
/** Matches the client id `connect login` used, so CMMD accepts the refresh. */
|
|
@@ -71425,7 +71448,7 @@ function forbiddenResponse() {
|
|
|
71425
71448
|
return errorResponse(403, "RELAY_BRIDGE_FORBIDDEN", "Desktop relay bridge access denied.");
|
|
71426
71449
|
}
|
|
71427
71450
|
function relayProxyErrorResponse(error) {
|
|
71428
|
-
if (error instanceof CmmdProxyRequestError && isRecord$
|
|
71451
|
+
if (error instanceof CmmdProxyRequestError && isRecord$20(error.body)) {
|
|
71429
71452
|
const code = typeof error.body.code === "string" ? error.body.code : error.code;
|
|
71430
71453
|
const message = typeof error.body.error === "string" ? error.body.error : error.detail;
|
|
71431
71454
|
return errorResponse(error.status >= 500 ? 502 : error.status, code, message ?? "CMMD relay coordination failed.");
|
|
@@ -93801,7 +93824,7 @@ const REPLICA_THREAD_STATUSES = [
|
|
|
93801
93824
|
];
|
|
93802
93825
|
//#endregion
|
|
93803
93826
|
//#region src/runtimeReplication/replicaDecodeModel.ts
|
|
93804
|
-
function isRecord$
|
|
93827
|
+
function isRecord$19(value) {
|
|
93805
93828
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
93806
93829
|
}
|
|
93807
93830
|
function isNonBlankString(value) {
|
|
@@ -93821,7 +93844,7 @@ function nullableInteger(value) {
|
|
|
93821
93844
|
return value === null || typeof value === "number" && Number.isSafeInteger(value);
|
|
93822
93845
|
}
|
|
93823
93846
|
function unwrapEnvelope(payload, expectedDomain) {
|
|
93824
|
-
if (!isRecord$
|
|
93847
|
+
if (!isRecord$19(payload) || !isRecord$19(payload.meta) || !isRecord$19(payload.data)) return null;
|
|
93825
93848
|
const { domain, timestamp, version } = payload.meta;
|
|
93826
93849
|
if (!isNonBlankString(domain) || expectedDomain !== void 0 && domain !== expectedDomain || version !== "1.0" || !isIsoDateTime(timestamp)) return null;
|
|
93827
93850
|
return payload.data;
|
|
@@ -93834,12 +93857,12 @@ function hasValidRuntimeIdentity(value) {
|
|
|
93834
93857
|
].includes(String(value.runtimeKind)) && typeof value.displayName === "string" && typeof value.status === "string";
|
|
93835
93858
|
}
|
|
93836
93859
|
function decodeRuntime$1(value) {
|
|
93837
|
-
if (!isRecord$
|
|
93838
|
-
if (!nullableString(value.endpointUrl) || value.endpointUrl !== null && !URL.canParse(value.endpointUrl) || !nullableInteger(value.deviceId) || !nullableString(value.workspaceRoot) || !nullableString(value.githubRepoFullName) || !(value.lastSeenAt === null || isIsoDateTime(value.lastSeenAt)) || !(value.metadata === null || isRecord$
|
|
93860
|
+
if (!isRecord$19(value) || !hasValidRuntimeIdentity(value)) return null;
|
|
93861
|
+
if (!nullableString(value.endpointUrl) || value.endpointUrl !== null && !URL.canParse(value.endpointUrl) || !nullableInteger(value.deviceId) || !nullableString(value.workspaceRoot) || !nullableString(value.githubRepoFullName) || !(value.lastSeenAt === null || isIsoDateTime(value.lastSeenAt)) || !(value.metadata === null || isRecord$19(value.metadata))) return null;
|
|
93839
93862
|
return value;
|
|
93840
93863
|
}
|
|
93841
93864
|
function decodeProject(value) {
|
|
93842
|
-
if (!isRecord$
|
|
93865
|
+
if (!isRecord$19(value) || !isNonBlankString(value.projectId) || typeof value.title !== "string" || !nullableString(value.githubRepoFullName) || !nullableString(value.branch)) return null;
|
|
93843
93866
|
return {
|
|
93844
93867
|
projectId: value.projectId,
|
|
93845
93868
|
title: value.title,
|
|
@@ -93848,11 +93871,11 @@ function decodeProject(value) {
|
|
|
93848
93871
|
};
|
|
93849
93872
|
}
|
|
93850
93873
|
function decodeThread$1(value) {
|
|
93851
|
-
if (!isRecord$
|
|
93874
|
+
if (!isRecord$19(value) || !isNonBlankString(value.threadId) || typeof value.title !== "string" || !isReplicaThreadStatus(value.status) || !nullableString(value.model) || !nullableString(value.branch) || !(value.lastActivityAt === null || isIsoDateTime(value.lastActivityAt))) return null;
|
|
93852
93875
|
return value;
|
|
93853
93876
|
}
|
|
93854
93877
|
function decodeSummary(value) {
|
|
93855
|
-
if (!isRecord$
|
|
93878
|
+
if (!isRecord$19(value) || !nullableString(value.conversationId)) return null;
|
|
93856
93879
|
const project = decodeProject(value.project);
|
|
93857
93880
|
const thread = decodeThread$1(value.thread);
|
|
93858
93881
|
return project === null || thread === null ? null : {
|
|
@@ -93963,7 +93986,7 @@ function isNonNegativeInt(value) {
|
|
|
93963
93986
|
/** `usage` is null for an Unreported turn, otherwise exactly the five buckets. */
|
|
93964
93987
|
function isValidTurnUsageTokens(value) {
|
|
93965
93988
|
if (value === null) return true;
|
|
93966
|
-
if (!isRecord$
|
|
93989
|
+
if (!isRecord$19(value)) return false;
|
|
93967
93990
|
return turnUsageTokenKeys.every((key) => isNonNegativeInt(value[key])) && Object.keys(value).every((key) => turnUsageTokenKeys.includes(key));
|
|
93968
93991
|
}
|
|
93969
93992
|
/** The row itself: no text, no status, and the turn it belongs to. */
|
|
@@ -93972,7 +93995,7 @@ function hasValidTurnUsageEnvelope(value) {
|
|
|
93972
93995
|
}
|
|
93973
93996
|
/** What the row records: who ran it, what it spent, and what it says of itself. */
|
|
93974
93997
|
function hasValidTurnUsageRecord(payload) {
|
|
93975
|
-
return isRecord$
|
|
93998
|
+
return isRecord$19(payload) && isNonBlankString(payload.provider) && isNonBlankString(payload.model) && "usage" in payload && isValidTurnUsageTokens(payload.usage) && hasValidTurnUsageAttribution(payload);
|
|
93976
93999
|
}
|
|
93977
94000
|
/** A turn_usage row: no text, no status, and its record in `payload`. */
|
|
93978
94001
|
function hasValidTurnUsagePayload(value) {
|
|
@@ -94009,7 +94032,7 @@ function hasValidEventPayload(value) {
|
|
|
94009
94032
|
return isNonBlankString(value.text) && value.status === null;
|
|
94010
94033
|
}
|
|
94011
94034
|
function decodeEvent$1(value) {
|
|
94012
|
-
if (!isRecord$
|
|
94035
|
+
if (!isRecord$19(value) || !hasValidEventFields(value) || !hasValidEventPayload(value)) return null;
|
|
94013
94036
|
return value;
|
|
94014
94037
|
}
|
|
94015
94038
|
function decodeEvents(data) {
|
|
@@ -94030,11 +94053,11 @@ function decodeReplicaThreadDetail(payload) {
|
|
|
94030
94053
|
const thread = decodeThread$1(data.thread);
|
|
94031
94054
|
const reachability = decodeReachability(data.reachability);
|
|
94032
94055
|
const events = decodeEvents(data);
|
|
94033
|
-
if (runtime === null || project === null || thread === null || reachability === null || events === null || !isRecord$
|
|
94056
|
+
if (runtime === null || project === null || thread === null || reachability === null || events === null || !isRecord$19(data.execution) || typeof data.execution.available !== "boolean" || ![
|
|
94034
94057
|
null,
|
|
94035
94058
|
"runtime_offline",
|
|
94036
94059
|
"runtime_unavailable"
|
|
94037
|
-
].includes(data.execution.reason) || (data.execution.available ? data.execution.reason !== null : data.execution.reason === null) || !isRecord$
|
|
94060
|
+
].includes(data.execution.reason) || (data.execution.available ? data.execution.reason !== null : data.execution.reason === null) || !isRecord$19(data.replication) || data.replication.protocolVersion !== 2 || !isNonBlankString(data.replication.generationId) || !Number.isSafeInteger(data.replication.acknowledgedSequence) || Number(data.replication.acknowledgedSequence) < 0 || !isNonBlankString(data.replication.headHash)) return null;
|
|
94038
94061
|
return {
|
|
94039
94062
|
conversationId: data.conversationId,
|
|
94040
94063
|
runtime,
|
|
@@ -94955,7 +94978,7 @@ function resolveRuntimeReplicationRuntimeId(config) {
|
|
|
94955
94978
|
}
|
|
94956
94979
|
//#endregion
|
|
94957
94980
|
//#region src/usage/providerTokenBuckets.ts
|
|
94958
|
-
function isRecord$
|
|
94981
|
+
function isRecord$18(value) {
|
|
94959
94982
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
94960
94983
|
}
|
|
94961
94984
|
function count(record, ...keys) {
|
|
@@ -94976,7 +94999,7 @@ function reportedOrNull(tokens) {
|
|
|
94976
94999
|
* the app server sends camelCase.
|
|
94977
95000
|
*/
|
|
94978
95001
|
function codexTokenBuckets(value) {
|
|
94979
|
-
if (!isRecord$
|
|
95002
|
+
if (!isRecord$18(value)) return null;
|
|
94980
95003
|
const inputTokens = count(value, "input_tokens", "inputTokens");
|
|
94981
95004
|
const cachedInputTokens = count(value, "cached_input_tokens", "cachedInputTokens");
|
|
94982
95005
|
const cacheCreationTokens = count(value, "cache_write_input_tokens", "cacheWriteInputTokens");
|
|
@@ -94995,7 +95018,7 @@ function codexTokenBuckets(value) {
|
|
|
94995
95018
|
* tokens into output and does not break them out, so reasoning stays zero.
|
|
94996
95019
|
*/
|
|
94997
95020
|
function claudeTokenBuckets(value) {
|
|
94998
|
-
if (!isRecord$
|
|
95021
|
+
if (!isRecord$18(value)) return null;
|
|
94999
95022
|
return reportedOrNull({
|
|
95000
95023
|
uncachedInputTokens: count(value, "input_tokens", "inputTokens"),
|
|
95001
95024
|
cachedInputTokens: count(value, "cache_read_input_tokens", "cacheReadInputTokens"),
|
|
@@ -95889,6 +95912,20 @@ function publishedAvailability(provider) {
|
|
|
95889
95912
|
...detail === void 0 ? {} : { unavailableDetail: detail }
|
|
95890
95913
|
};
|
|
95891
95914
|
}
|
|
95915
|
+
/**
|
|
95916
|
+
* What the Claude CLI said about its credentials, beside the version it said
|
|
95917
|
+
* it for. CMMD keeps each Claude version's answers, so these go on the Claude
|
|
95918
|
+
* entry only. Each is copied only when the snapshot has an answer: absent means
|
|
95919
|
+
* the runtime has not answered yet, and inventing a value would hide that.
|
|
95920
|
+
*/
|
|
95921
|
+
function claudeCredentialAnswersToPublish(provider) {
|
|
95922
|
+
if (provider.provider !== "claudeAgent") return {};
|
|
95923
|
+
const { credentialDirectory, credentialStore } = provider;
|
|
95924
|
+
return {
|
|
95925
|
+
...credentialDirectory === void 0 ? {} : { credentialDirectory },
|
|
95926
|
+
...credentialStore === void 0 ? {} : { credentialStore }
|
|
95927
|
+
};
|
|
95928
|
+
}
|
|
95892
95929
|
function serializeProvider(provider) {
|
|
95893
95930
|
const models = [];
|
|
95894
95931
|
for (const model of provider.models) {
|
|
@@ -95901,7 +95938,8 @@ function serializeProvider(provider) {
|
|
|
95901
95938
|
models,
|
|
95902
95939
|
...publishedAvailability(provider),
|
|
95903
95940
|
version: cappedText(provider.version, VERSION_MAX_LENGTH),
|
|
95904
|
-
binaryPath: cappedText(provider.auth.provenance?.binaryPath, BINARY_PATH_MAX_LENGTH)
|
|
95941
|
+
binaryPath: cappedText(provider.auth.provenance?.binaryPath, BINARY_PATH_MAX_LENGTH),
|
|
95942
|
+
...claudeCredentialAnswersToPublish(provider)
|
|
95905
95943
|
};
|
|
95906
95944
|
}
|
|
95907
95945
|
function serializeProviderCatalog(providers) {
|
|
@@ -95922,7 +95960,7 @@ const replicaTurnStatuses = new Set([
|
|
|
95922
95960
|
"cancelled",
|
|
95923
95961
|
"interrupted"
|
|
95924
95962
|
]);
|
|
95925
|
-
function isRecord$
|
|
95963
|
+
function isRecord$17(value) {
|
|
95926
95964
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
95927
95965
|
}
|
|
95928
95966
|
function replicaSourceSequence(value) {
|
|
@@ -95935,7 +95973,7 @@ function replicaSourceTurn(sourceTurnId) {
|
|
|
95935
95973
|
return typeof sourceTurnId === "string" && sourceTurnId.length > 0 ? { turnId: sourceTurnId } : {};
|
|
95936
95974
|
}
|
|
95937
95975
|
function replicaActivitySource(activity) {
|
|
95938
|
-
if (!activity.kind.startsWith("replica.") || !isRecord$
|
|
95976
|
+
if (!activity.kind.startsWith("replica.") || !isRecord$17(activity.payload)) return null;
|
|
95939
95977
|
const sourceSequence = replicaSourceSequence(activity.sequence);
|
|
95940
95978
|
const eventId = replicaSourceEventId(activity.payload.sourceEventId);
|
|
95941
95979
|
if (sourceSequence === null || eventId === null) return null;
|
|
@@ -95948,7 +95986,7 @@ function replicaActivitySource(activity) {
|
|
|
95948
95986
|
}
|
|
95949
95987
|
function replicaSummaryEvent(activity, source) {
|
|
95950
95988
|
if (activity.kind !== "replica.activity_summary" && activity.kind !== "replica.error_summary") return null;
|
|
95951
|
-
const sourceText = isRecord$
|
|
95989
|
+
const sourceText = isRecord$17(activity.payload) ? activity.payload.text : null;
|
|
95952
95990
|
return {
|
|
95953
95991
|
sourceSequence: source.sourceSequence,
|
|
95954
95992
|
event: {
|
|
@@ -95961,7 +95999,7 @@ function replicaSummaryEvent(activity, source) {
|
|
|
95961
95999
|
};
|
|
95962
96000
|
}
|
|
95963
96001
|
function replicaTurnEvent(activity, source) {
|
|
95964
|
-
const status = isRecord$
|
|
96002
|
+
const status = isRecord$17(activity.payload) ? activity.payload.status : null;
|
|
95965
96003
|
if (activity.kind !== "replica.turn_status" || !replicaTurnStatuses.has(status)) return null;
|
|
95966
96004
|
return {
|
|
95967
96005
|
sourceSequence: source.sourceSequence,
|
|
@@ -95975,7 +96013,7 @@ function replicaTurnEvent(activity, source) {
|
|
|
95975
96013
|
};
|
|
95976
96014
|
}
|
|
95977
96015
|
function replicaToolCallEvent(activity, source) {
|
|
95978
|
-
if (activity.kind !== "replica.tool_call" || !isRecord$
|
|
96016
|
+
if (activity.kind !== "replica.tool_call" || !isRecord$17(activity.payload)) return null;
|
|
95979
96017
|
const sourceText = activity.payload.text;
|
|
95980
96018
|
const status = activity.payload.status;
|
|
95981
96019
|
if (typeof sourceText !== "string" || typeof status !== "string") return null;
|
|
@@ -95993,9 +96031,9 @@ function replicaToolCallEvent(activity, source) {
|
|
|
95993
96031
|
};
|
|
95994
96032
|
}
|
|
95995
96033
|
function replicaTurnUsageEvent(activity, source) {
|
|
95996
|
-
if (activity.kind !== "replica.turn_usage" || !isRecord$
|
|
96034
|
+
if (activity.kind !== "replica.turn_usage" || !isRecord$17(activity.payload)) return null;
|
|
95997
96035
|
const usage = activity.payload.payload;
|
|
95998
|
-
if (!("turnId" in source.turn) || !isRecord$
|
|
96036
|
+
if (!("turnId" in source.turn) || !isRecord$17(usage)) return null;
|
|
95999
96037
|
const provider = usage.provider;
|
|
96000
96038
|
const model = usage.model;
|
|
96001
96039
|
if (typeof provider !== "string" || typeof model !== "string" || !("usage" in usage)) return null;
|
|
@@ -96808,9 +96846,9 @@ function isUsageSessionLookupRuntimeNotFound(error) {
|
|
|
96808
96846
|
async function isRuntimeNotFoundResponse(response) {
|
|
96809
96847
|
if (response.status !== 404) return false;
|
|
96810
96848
|
const body = await response.json().catch(() => null);
|
|
96811
|
-
return isRecord$
|
|
96849
|
+
return isRecord$16(body) && body["code"] === "RUNTIME_NOT_FOUND";
|
|
96812
96850
|
}
|
|
96813
|
-
function isRecord$
|
|
96851
|
+
function isRecord$16(value) {
|
|
96814
96852
|
return typeof value === "object" && value !== null;
|
|
96815
96853
|
}
|
|
96816
96854
|
/**
|
|
@@ -96822,11 +96860,11 @@ function isRecord$15(value) {
|
|
|
96822
96860
|
* no count on the page saying so.
|
|
96823
96861
|
*/
|
|
96824
96862
|
function decodeHeldSessions(body) {
|
|
96825
|
-
const held = isRecord$
|
|
96863
|
+
const held = isRecord$16(body) && isRecord$16(body["data"]) ? body["data"]["held"] : void 0;
|
|
96826
96864
|
if (!Array.isArray(held)) throw new Error("The usage session lookup returned an invalid body.");
|
|
96827
96865
|
return held.map((row) => {
|
|
96828
|
-
const providerSessionId = isRecord$
|
|
96829
|
-
const runtimeId = isRecord$
|
|
96866
|
+
const providerSessionId = isRecord$16(row) ? row["providerSessionId"] : void 0;
|
|
96867
|
+
const runtimeId = isRecord$16(row) ? row["runtimeId"] : void 0;
|
|
96830
96868
|
if (typeof providerSessionId !== "string" || typeof runtimeId !== "string") throw new Error("The usage session lookup returned an invalid held row.");
|
|
96831
96869
|
return {
|
|
96832
96870
|
providerSessionId,
|
|
@@ -99622,7 +99660,7 @@ function emptyConfig(source, path) {
|
|
|
99622
99660
|
issues: []
|
|
99623
99661
|
};
|
|
99624
99662
|
}
|
|
99625
|
-
function isRecord$
|
|
99663
|
+
function isRecord$15(value) {
|
|
99626
99664
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
99627
99665
|
}
|
|
99628
99666
|
function stringArray(value) {
|
|
@@ -99650,7 +99688,7 @@ function terminalsFromValue(value) {
|
|
|
99650
99688
|
name: `Terminal ${index + 1}`,
|
|
99651
99689
|
command: terminal.trim()
|
|
99652
99690
|
}];
|
|
99653
|
-
if (!isRecord$
|
|
99691
|
+
if (!isRecord$15(terminal)) return [];
|
|
99654
99692
|
const command = typeof terminal.command === "string" ? terminal.command.trim() : "";
|
|
99655
99693
|
if (!command) return [];
|
|
99656
99694
|
return [{
|
|
@@ -99689,7 +99727,7 @@ function readConfigFile(source, path) {
|
|
|
99689
99727
|
}]
|
|
99690
99728
|
};
|
|
99691
99729
|
}
|
|
99692
|
-
if (!isRecord$
|
|
99730
|
+
if (!isRecord$15(parsed)) return {
|
|
99693
99731
|
...emptyConfig(source, path),
|
|
99694
99732
|
issues: [{
|
|
99695
99733
|
severity: "blocked",
|
|
@@ -100832,7 +100870,7 @@ const CLAUDE_IDENTITY_KEYS = new Set([
|
|
|
100832
100870
|
"credentialGenerationId"
|
|
100833
100871
|
]);
|
|
100834
100872
|
const CLAUDE_IDENTITY_OPTIONAL_KEYS = new Set(["providerAccountIdentity"]);
|
|
100835
|
-
function isRecord$
|
|
100873
|
+
function isRecord$14(value) {
|
|
100836
100874
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
100837
100875
|
}
|
|
100838
100876
|
function isStrictRfc3339DateTime(value) {
|
|
@@ -100861,7 +100899,7 @@ function hasAllowedKeys(value, required, optional) {
|
|
|
100861
100899
|
return keys.every((key) => required.has(key) || optional.has(key)) && [...required].every((key) => keys.includes(key));
|
|
100862
100900
|
}
|
|
100863
100901
|
function parseDeliveryIdentity(value, provider) {
|
|
100864
|
-
if (!isRecord$
|
|
100902
|
+
if (!isRecord$14(value)) return null;
|
|
100865
100903
|
if (provider === "openai") return parseCodexDeliveryIdentity(value);
|
|
100866
100904
|
if (provider === "anthropic") return parseClaudeDeliveryIdentity(value);
|
|
100867
100905
|
return null;
|
|
@@ -100896,7 +100934,7 @@ function parseClaudeDeliveryIdentity(value) {
|
|
|
100896
100934
|
};
|
|
100897
100935
|
}
|
|
100898
100936
|
function parseProviderRuntimeDeliveryReceipt(value, expected) {
|
|
100899
|
-
if (!isRecord$
|
|
100937
|
+
if (!isRecord$14(value) || !hasExactKeys$2(value, RECEIPT_KEYS)) return null;
|
|
100900
100938
|
const identity = parseDeliveryIdentity(value.identity, expected.provider);
|
|
100901
100939
|
if (!identity || typeof value.receiptId !== "string" || value.receiptId.length === 0 || value.receiptId.length > 256 || value.runtimeId !== expected.runtimeId || value.machineId !== expected.machineId || value.credentialEpoch !== expected.credentialEpoch || !Number.isInteger(value.credentialEpoch) || value.credentialEpoch < 0 || !isStrictRfc3339DateTime(value.issuedAt) || value.expiresAt !== expected.expiresAt || value.expiresAt !== null && !isStrictRfc3339DateTime(value.expiresAt)) return null;
|
|
100902
100940
|
return {
|
|
@@ -100918,8 +100956,8 @@ function providerDeliveryBindingFromReceipt(receipt) {
|
|
|
100918
100956
|
};
|
|
100919
100957
|
}
|
|
100920
100958
|
function readProviderDeliveryBinding(value) {
|
|
100921
|
-
if (!isRecord$
|
|
100922
|
-
const identityProvider = isRecord$
|
|
100959
|
+
if (!isRecord$14(value) || !hasExactKeys$2(value, BINDING_KEYS)) return null;
|
|
100960
|
+
const identityProvider = isRecord$14(value.identity) ? value.identity.provider : void 0;
|
|
100923
100961
|
const tokenProvider = identityProvider === "codex" ? "openai" : identityProvider === "claude" ? "anthropic" : null;
|
|
100924
100962
|
if (!tokenProvider) return null;
|
|
100925
100963
|
const identity = parseDeliveryIdentity(value.identity, tokenProvider);
|
|
@@ -148203,12 +148241,12 @@ function decodeProviderKind(providerName, operation) {
|
|
|
148203
148241
|
detail: `Unknown persisted provider '${providerName}'.`
|
|
148204
148242
|
}));
|
|
148205
148243
|
}
|
|
148206
|
-
function isRecord$
|
|
148244
|
+
function isRecord$13(value) {
|
|
148207
148245
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
148208
148246
|
}
|
|
148209
148247
|
function mergeRuntimePayload(existing, next) {
|
|
148210
148248
|
if (next === void 0) return existing ?? null;
|
|
148211
|
-
if (isRecord$
|
|
148249
|
+
if (isRecord$13(existing) && isRecord$13(next)) return {
|
|
148212
148250
|
...existing,
|
|
148213
148251
|
...next
|
|
148214
148252
|
};
|
|
@@ -150180,7 +150218,7 @@ const PAGINATION_KEYS = new Set([
|
|
|
150180
150218
|
"total",
|
|
150181
150219
|
"hasMore"
|
|
150182
150220
|
]);
|
|
150183
|
-
function isRecord$
|
|
150221
|
+
function isRecord$12(value) {
|
|
150184
150222
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
150185
150223
|
}
|
|
150186
150224
|
function hasOnlyKeys(value, allowed) {
|
|
@@ -150193,17 +150231,17 @@ function isRfc3339(value) {
|
|
|
150193
150231
|
return typeof value === "string" && RFC3339.test(value) && Number.isFinite(Date.parse(value));
|
|
150194
150232
|
}
|
|
150195
150233
|
function isEnvelopeMeta(value) {
|
|
150196
|
-
if (!isRecord$
|
|
150234
|
+
if (!isRecord$12(value) || !hasExactKeys$1(value, META_KEYS)) return false;
|
|
150197
150235
|
return typeof value.domain === "string" && value.domain.length > 0 && isRfc3339(value.timestamp) && typeof value.version === "string" && value.version.length > 0;
|
|
150198
150236
|
}
|
|
150199
150237
|
function isPagination(value) {
|
|
150200
|
-
if (!isRecord$
|
|
150238
|
+
if (!isRecord$12(value) || !hasExactKeys$1(value, PAGINATION_KEYS)) return false;
|
|
150201
150239
|
return Number.isInteger(value.page) && value.page >= 0 && Number.isInteger(value.limit) && value.limit >= 0 && Number.isInteger(value.total) && value.total >= 0 && typeof value.hasMore === "boolean";
|
|
150202
150240
|
}
|
|
150203
150241
|
function readLocalProviderAccountId(authJson) {
|
|
150204
150242
|
try {
|
|
150205
150243
|
const value = JSON.parse(authJson);
|
|
150206
|
-
if (!isRecord$
|
|
150244
|
+
if (!isRecord$12(value) || value.auth_mode !== "chatgpt" || !isRecord$12(value.tokens)) return null;
|
|
150207
150245
|
const providerAccountId = value.tokens.account_id;
|
|
150208
150246
|
if (typeof providerAccountId !== "string") return null;
|
|
150209
150247
|
const normalized = providerAccountId.trim();
|
|
@@ -150216,13 +150254,13 @@ function resolveLocalAuthJsonPath(homePath) {
|
|
|
150216
150254
|
return (0, node_path.join)(homePath?.trim() || process.env.CODEX_HOME?.trim() || (0, node_path.join)((0, node_os.homedir)(), ".codex"), "auth.json");
|
|
150217
150255
|
}
|
|
150218
150256
|
function parseCodexAccountIdentityEnvelope(value) {
|
|
150219
|
-
if (!isRecord$
|
|
150257
|
+
if (!isRecord$12(value) || !hasOnlyKeys(value, ENVELOPE_KEYS)) return null;
|
|
150220
150258
|
if (!("data" in value) || !("meta" in value) || !isEnvelopeMeta(value.meta)) return null;
|
|
150221
150259
|
if (value.pagination !== void 0 && !isPagination(value.pagination)) return null;
|
|
150222
150260
|
return readCodexAccountIdentity(value.data);
|
|
150223
150261
|
}
|
|
150224
150262
|
function readCodexAccountIdentity(value) {
|
|
150225
|
-
if (!isRecord$
|
|
150263
|
+
if (!isRecord$12(value) || !hasExactKeys$1(value, IDENTITY_KEYS)) return null;
|
|
150226
150264
|
if (value.kind !== "provider_account" || value.provider !== "codex" || typeof value.providerAccountIdentity !== "string" || !PROVIDER_ACCOUNT_IDENTITY$1.test(value.providerAccountIdentity)) return null;
|
|
150227
150265
|
return {
|
|
150228
150266
|
kind: "provider_account",
|
|
@@ -211407,10 +211445,16 @@ function claudeSubscriptionChildEnv(processEnv, credentialDirectory) {
|
|
|
211407
211445
|
* environment with `claudeSubscriptionChildEnv`, the same builder as the turn's
|
|
211408
211446
|
* personal-subscription branch.
|
|
211409
211447
|
*
|
|
211410
|
-
* `claude auth status`
|
|
211411
|
-
*
|
|
211448
|
+
* `claude auth status` sends no prompt and leaves `.credentials.json`
|
|
211449
|
+
* byte-identical, so probing spends no subscription usage. For Team and
|
|
211450
|
+
* Enterprise accounts the CLI's `auth` preAction schedules a remote-settings
|
|
211451
|
+
* fetch it never awaits, and the command exits before that fetch runs (see the
|
|
211452
|
+
* 2026-09-10 amendment to `docs/adr/cmmd-is-the-only-claude-credential-renewer.md`).
|
|
211412
211453
|
* It prints JSON on stdout and exits 1 when logged out, so the exit code is not
|
|
211413
211454
|
* a failure signal and the `loggedIn` field is what gets read.
|
|
211455
|
+
*
|
|
211456
|
+
* Each answer a probe reaches is also kept in `claudeCredentialDirectoryAnswers`
|
|
211457
|
+
* so the provider check can publish it without probing.
|
|
211414
211458
|
*/
|
|
211415
211459
|
const execFileAsync$3 = (0, node_util.promisify)(node_child_process.execFile);
|
|
211416
211460
|
const AUTH_STATUS_ARGS = ["auth", "status"];
|
|
@@ -211427,8 +211471,7 @@ const PROBE_DIRECTORY_PREFIX = "forge-claude-capability-";
|
|
|
211427
211471
|
const VERSION_PATTERN = /\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?/;
|
|
211428
211472
|
function makeClaudeCredentialDirectoryProbe(deps) {
|
|
211429
211473
|
const answers = /* @__PURE__ */ new Map();
|
|
211430
|
-
const
|
|
211431
|
-
const version = await readVersionSafely(deps);
|
|
211474
|
+
const answerFor = (version) => {
|
|
211432
211475
|
if (version === null) return runProbe(deps);
|
|
211433
211476
|
const cached = answers.get(version);
|
|
211434
211477
|
if (cached) return cached;
|
|
@@ -211439,10 +211482,47 @@ function makeClaudeCredentialDirectoryProbe(deps) {
|
|
|
211439
211482
|
};
|
|
211440
211483
|
pending.then((result) => {
|
|
211441
211484
|
if (result === "inconclusive") forget();
|
|
211442
|
-
|
|
211485
|
+
deps.onAnswer?.(version, result);
|
|
211486
|
+
}, () => {
|
|
211487
|
+
forget();
|
|
211488
|
+
deps.onAnswer?.(version, "inconclusive");
|
|
211489
|
+
});
|
|
211443
211490
|
return pending;
|
|
211444
211491
|
};
|
|
211445
|
-
return { support:
|
|
211492
|
+
return { support: inconclusiveOnFailure(async () => answerFor(await readVersionSafely(deps))) };
|
|
211493
|
+
}
|
|
211494
|
+
/**
|
|
211495
|
+
* The one place a probe failure is handled. A missing binary, a timeout or a
|
|
211496
|
+
* directory that cannot be made all mean the probe could not tell.
|
|
211497
|
+
*/
|
|
211498
|
+
function inconclusiveOnFailure(run) {
|
|
211499
|
+
return require_Schema$1.tryPromise(run).pipe(require_Schema$1.orElseSucceed(() => "inconclusive"));
|
|
211500
|
+
}
|
|
211501
|
+
const keyOf = (binaryPath, version) => JSON.stringify([binaryPath, version]);
|
|
211502
|
+
function makeClaudeCredentialDirectoryAnswers() {
|
|
211503
|
+
const answers = /* @__PURE__ */ new Map();
|
|
211504
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
211505
|
+
return {
|
|
211506
|
+
record: (binaryPath, version, answer) => {
|
|
211507
|
+
const key = keyOf(binaryPath, version);
|
|
211508
|
+
if (answers.get(key) === answer) return;
|
|
211509
|
+
answers.set(key, answer);
|
|
211510
|
+
for (const listener of listeners) listener();
|
|
211511
|
+
},
|
|
211512
|
+
answerFor: (binaryPath, version) => answers.get(keyOf(binaryPath, version)),
|
|
211513
|
+
subscribe: (listener) => {
|
|
211514
|
+
listeners.add(listener);
|
|
211515
|
+
return () => {
|
|
211516
|
+
listeners.delete(listener);
|
|
211517
|
+
};
|
|
211518
|
+
}
|
|
211519
|
+
};
|
|
211520
|
+
}
|
|
211521
|
+
/** Every answer a turn-time probe in this process has reached. */
|
|
211522
|
+
const claudeCredentialDirectoryAnswers = makeClaudeCredentialDirectoryAnswers();
|
|
211523
|
+
/** The version in `claude --version` output, the key a probe answer is kept under. */
|
|
211524
|
+
function claudeVersionFromOutput(stdout) {
|
|
211525
|
+
return VERSION_PATTERN.exec(stdout)?.[0] ?? null;
|
|
211446
211526
|
}
|
|
211447
211527
|
/**
|
|
211448
211528
|
* One probe per binary path for the life of the process. A conclusive answer is
|
|
@@ -211467,7 +211547,12 @@ function claudeCredentialDirectoryProbeFor(binaryPath) {
|
|
|
211467
211547
|
if (!binaryPath) return INCONCLUSIVE_PROBE;
|
|
211468
211548
|
const existing = probesByBinaryPath.get(binaryPath);
|
|
211469
211549
|
if (existing) return existing;
|
|
211470
|
-
const probe = makeClaudeCredentialDirectoryProbe(
|
|
211550
|
+
const probe = makeClaudeCredentialDirectoryProbe({
|
|
211551
|
+
...claudeCredentialDirectoryProbeDeps(binaryPath),
|
|
211552
|
+
onAnswer: (version, answer) => {
|
|
211553
|
+
claudeCredentialDirectoryAnswers.record(binaryPath, version, answer);
|
|
211554
|
+
}
|
|
211555
|
+
});
|
|
211471
211556
|
probesByBinaryPath.set(binaryPath, probe);
|
|
211472
211557
|
return probe;
|
|
211473
211558
|
}
|
|
@@ -211478,7 +211563,7 @@ function claudeCredentialDirectoryProbeDeps(binaryPath, options = {}) {
|
|
|
211478
211563
|
runAuthStatus: ({ credentialDirectory }) => run(AUTH_STATUS_ARGS, credentialDirectory),
|
|
211479
211564
|
readBinaryVersion: async () => {
|
|
211480
211565
|
const { stdout } = await run(VERSION_ARGS, null);
|
|
211481
|
-
return
|
|
211566
|
+
return claudeVersionFromOutput(stdout);
|
|
211482
211567
|
},
|
|
211483
211568
|
makeProbeDirectory: () => (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), PROBE_DIRECTORY_PREFIX)),
|
|
211484
211569
|
removeProbeDirectory: (directory) => (0, node_fs_promises.rm)(directory, {
|
|
@@ -211647,6 +211732,171 @@ const makeProviderAuthProvenance = (input) => {
|
|
|
211647
211732
|
};
|
|
211648
211733
|
};
|
|
211649
211734
|
//#endregion
|
|
211735
|
+
//#region src/provider/claudeCredentialStore.ts
|
|
211736
|
+
/**
|
|
211737
|
+
* Which Credential Store the Claude CLI uses on this machine, read the way the
|
|
211738
|
+
* CLI reads it.
|
|
211739
|
+
*
|
|
211740
|
+
* The CLI has two stores, `.credentials.json` in the credential directory and
|
|
211741
|
+
* the operating system's own, and no platform check picks between them. It
|
|
211742
|
+
* takes the OS store when `CLAUDE_CODE_FORCE_WINDOWS_CREDMAN` is `1`, and
|
|
211743
|
+
* otherwise when the remote flag it caches in its config file,
|
|
211744
|
+
* `cachedGrowthBookFeatures.tengu_windows_credman`, is `true`. That file is a
|
|
211745
|
+
* legacy `.config.json` in the config directory when one exists, and
|
|
211746
|
+
* `.claude.json` otherwise. Read from Claude Code 2.1.265 in #3086.
|
|
211747
|
+
*
|
|
211748
|
+
* The CLI takes the file when it cannot find, read or parse the config, and so
|
|
211749
|
+
* does this. A config that parses to JSON `null` reads `file` as well: the CLI
|
|
211750
|
+
* reads a property off the parsed value, which throws on `null`, and it falls
|
|
211751
|
+
* back to the file store on that throw. Any other config that parses but
|
|
211752
|
+
* carries no boolean flag also means the file to the CLI, but it is the shape a
|
|
211753
|
+
* moved key leaves, so this reads `unknown` rather than guess.
|
|
211754
|
+
*
|
|
211755
|
+
* Linux with no session bus has no secret service, so the OS store fails its
|
|
211756
|
+
* own check and the CLI falls back to the file whatever the flag says. Every
|
|
211757
|
+
* Sprite is that case, and it reads `file` without opening the config. Linux
|
|
211758
|
+
* with a session bus is `unknown` when the OS store is selected, because only
|
|
211759
|
+
* the secret service knows whether it would answer.
|
|
211760
|
+
* See `docs/adr/delivery-clears-the-os-credential-store-first.md`.
|
|
211761
|
+
*
|
|
211762
|
+
* Two things in 2.1.265 this does not follow. The CLI puts its OAuth name
|
|
211763
|
+
* suffix, `F$()` in that bundle, into the config name. The suffix is empty in a
|
|
211764
|
+
* production build and `-custom-oauth` with `CLAUDE_CODE_CUSTOM_OAUTH_URL` set,
|
|
211765
|
+
* so the config is then `.claude-custom-oauth.json` instead of `.claude.json`.
|
|
211766
|
+
* And `primeWindowsCredManBackendEnabled` can set the choice before the file is
|
|
211767
|
+
* read, but only with a v5 storage backend, and `tryCreateV5Backend` returns
|
|
211768
|
+
* nothing in that build, so it never does.
|
|
211769
|
+
*/
|
|
211770
|
+
const CLAUDE_FORCE_OS_CREDENTIAL_STORE_ENV = "CLAUDE_CODE_FORCE_WINDOWS_CREDMAN";
|
|
211771
|
+
const CACHED_FEATURES_KEY = "cachedGrowthBookFeatures";
|
|
211772
|
+
const OS_STORE_FLAG_KEY = "tengu_windows_credman";
|
|
211773
|
+
function readClaudeCredentialStore(input) {
|
|
211774
|
+
if (input.platform === "linux" && !hasSessionBus(input)) return "file";
|
|
211775
|
+
const selectsOsStore = cliSelectsOsStore(input);
|
|
211776
|
+
if (selectsOsStore === null) return "unknown";
|
|
211777
|
+
if (!selectsOsStore) return "file";
|
|
211778
|
+
return input.platform === "darwin" || input.platform === "win32" ? "os" : "unknown";
|
|
211779
|
+
}
|
|
211780
|
+
/** The same read against this machine's home directory and disk. */
|
|
211781
|
+
const readClaudeCredentialStoreFromDisk = (context) => {
|
|
211782
|
+
let homeDirectory;
|
|
211783
|
+
try {
|
|
211784
|
+
homeDirectory = (0, node_os.homedir)();
|
|
211785
|
+
} catch {
|
|
211786
|
+
homeDirectory = null;
|
|
211787
|
+
}
|
|
211788
|
+
return readClaudeCredentialStore({
|
|
211789
|
+
...context,
|
|
211790
|
+
homeDirectory: homeDirectory ?? "",
|
|
211791
|
+
fileExists: homeDirectory === null ? () => false : node_fs.existsSync,
|
|
211792
|
+
readFile: (path) => {
|
|
211793
|
+
if (homeDirectory === null) throw new Error("no home directory");
|
|
211794
|
+
return (0, node_fs.readFileSync)(path, "utf8");
|
|
211795
|
+
}
|
|
211796
|
+
});
|
|
211797
|
+
};
|
|
211798
|
+
/** True, false, or null when a parsed config does not say. */
|
|
211799
|
+
function cliSelectsOsStore(input) {
|
|
211800
|
+
if (input.env[CLAUDE_FORCE_OS_CREDENTIAL_STORE_ENV] === "1") return true;
|
|
211801
|
+
const config = readConfig(input);
|
|
211802
|
+
if (config === null) return false;
|
|
211803
|
+
const features = isRecord$11(config.parsed) ? config.parsed[CACHED_FEATURES_KEY] : void 0;
|
|
211804
|
+
const flag = isRecord$11(features) ? features[OS_STORE_FLAG_KEY] : void 0;
|
|
211805
|
+
return typeof flag === "boolean" ? flag : null;
|
|
211806
|
+
}
|
|
211807
|
+
/**
|
|
211808
|
+
* The parsed config, or null wherever the CLI's own read throws and it falls
|
|
211809
|
+
* back to the file store: a file that is missing, unreadable or not JSON, and a
|
|
211810
|
+
* config that parses to JSON `null`, because the CLI reads a property off it.
|
|
211811
|
+
*/
|
|
211812
|
+
function readConfig(input) {
|
|
211813
|
+
try {
|
|
211814
|
+
const parsed = JSON.parse(input.readFile(cachedFlagFile(input)));
|
|
211815
|
+
return parsed === null ? null : { parsed };
|
|
211816
|
+
} catch {
|
|
211817
|
+
return null;
|
|
211818
|
+
}
|
|
211819
|
+
}
|
|
211820
|
+
function cachedFlagFile(input) {
|
|
211821
|
+
const configured = input.configDirectory?.trim();
|
|
211822
|
+
const legacy = (0, node_path.join)(configured || (0, node_path.join)(input.homeDirectory, ".claude"), ".config.json");
|
|
211823
|
+
if (input.fileExists(legacy)) return legacy;
|
|
211824
|
+
return (0, node_path.join)(configured || input.homeDirectory, ".claude.json");
|
|
211825
|
+
}
|
|
211826
|
+
/** libsecret reaches the secret service over the session bus, so no bus means no OS store. */
|
|
211827
|
+
function hasSessionBus(input) {
|
|
211828
|
+
if (input.env.DBUS_SESSION_BUS_ADDRESS?.trim()) return true;
|
|
211829
|
+
const runtimeDirectory = input.env.XDG_RUNTIME_DIR?.trim();
|
|
211830
|
+
return runtimeDirectory ? input.fileExists((0, node_path.join)(runtimeDirectory, "bus")) : false;
|
|
211831
|
+
}
|
|
211832
|
+
function isRecord$11(value) {
|
|
211833
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
211834
|
+
}
|
|
211835
|
+
//#endregion
|
|
211836
|
+
//#region src/provider/claudeCredentialAnswers.ts
|
|
211837
|
+
/**
|
|
211838
|
+
* The live resolver. The credential-directory answer is whatever the turn-time
|
|
211839
|
+
* probe last reached for this binary path and version, so the published answer
|
|
211840
|
+
* and the one that gated a turn are the same. Until a turn has probed, or with
|
|
211841
|
+
* no version to look it up by, the field stays absent.
|
|
211842
|
+
*/
|
|
211843
|
+
function makeClaudeCredentialAnswersResolver(options) {
|
|
211844
|
+
const readCredentialStore = options.readCredentialStore ?? readClaudeCredentialStoreFromDisk;
|
|
211845
|
+
return (input) => require_Schema$1.gen(function* () {
|
|
211846
|
+
const platform = yield* HostProcessPlatform;
|
|
211847
|
+
const credentialStore = yield* require_Schema$1.sync(() => readCredentialStore({
|
|
211848
|
+
env: options.env ?? process.env,
|
|
211849
|
+
platform,
|
|
211850
|
+
configDirectory: input.configDirectory
|
|
211851
|
+
}));
|
|
211852
|
+
const credentialDirectory = input.version === null ? void 0 : options.credentialDirectoryAnswers.answerFor(input.binaryPath, input.version);
|
|
211853
|
+
return credentialDirectory === void 0 ? { credentialStore } : {
|
|
211854
|
+
credentialStore,
|
|
211855
|
+
credentialDirectory
|
|
211856
|
+
};
|
|
211857
|
+
});
|
|
211858
|
+
}
|
|
211859
|
+
//#endregion
|
|
211860
|
+
//#region src/runtimeDrain/supervisedRepeat.ts
|
|
211861
|
+
/**
|
|
211862
|
+
* Runs `work` on a fixed schedule, forever, and RESTARTS the schedule itself
|
|
211863
|
+
* if it ever dies for any reason other than this scope closing.
|
|
211864
|
+
*
|
|
211865
|
+
* `Effect.repeat(work, Schedule.spaced(interval)).pipe(Effect.forkScoped)`
|
|
211866
|
+
* alone has no restart path. `work` catching its own errors only protects
|
|
211867
|
+
* the TICK: an interrupt that lands while `Effect.repeat` is asleep between
|
|
211868
|
+
* ticks — which, at any non-trivial interval, is nearly this loop's entire
|
|
211869
|
+
* life — happens outside anything `work` wraps, and kills that one fiber
|
|
211870
|
+
* outright with nothing logged, because nothing was running to log from.
|
|
211871
|
+
* The process this runs in can otherwise be perfectly healthy while the
|
|
211872
|
+
* schedule is silently, permanently dead.
|
|
211873
|
+
*
|
|
211874
|
+
* This runs the schedule on its own child fiber, raced against an explicit
|
|
211875
|
+
* shutdown signal fired by a finalizer registered in this scope. Only that
|
|
211876
|
+
* signal stops the loop for good; any other death of the schedule fiber —
|
|
211877
|
+
* whatever causes it, defect or interrupt — logs and restarts it. `work`
|
|
211878
|
+
* itself must still handle its own EXPECTED failures (this only supervises
|
|
211879
|
+
* the schedule, and treats every death of it as unexpected).
|
|
211880
|
+
*/
|
|
211881
|
+
function runSupervisedRepeat(input) {
|
|
211882
|
+
return require_Schema$1.gen(function* () {
|
|
211883
|
+
const shutdownSignal = yield* require_Schema$1.make$4();
|
|
211884
|
+
yield* require_Schema$1.addFinalizer(() => require_Schema$1.succeed$2(shutdownSignal, void 0));
|
|
211885
|
+
let firstAttempt = true;
|
|
211886
|
+
while (true) {
|
|
211887
|
+
if (!firstAttempt) yield* require_Schema$1.sleep(input.interval);
|
|
211888
|
+
firstAttempt = false;
|
|
211889
|
+
const scheduleFiber = yield* require_Schema$1.forkChild(require_Schema$1.repeat(input.work, require_Schema$1.spaced(input.interval)));
|
|
211890
|
+
const outcome = yield* require_Schema$1.race(require_Path.await_(scheduleFiber), require_Schema$1._await(shutdownSignal).pipe(require_Schema$1.as("shutdown")));
|
|
211891
|
+
if (outcome === "shutdown") {
|
|
211892
|
+
yield* require_Path.interrupt(scheduleFiber);
|
|
211893
|
+
return;
|
|
211894
|
+
}
|
|
211895
|
+
yield* require_Schema$1.logError(`${input.label} died unexpectedly — restarting`, { cause: require_Schema$1.isFailure(outcome) ? require_Schema$1.pretty(outcome.cause) : "unknown exit" });
|
|
211896
|
+
}
|
|
211897
|
+
});
|
|
211898
|
+
}
|
|
211899
|
+
//#endregion
|
|
211650
211900
|
//#region src/provider/Layers/ClaudeProvider.ts
|
|
211651
211901
|
function endpointProfileDisplayNames(settings) {
|
|
211652
211902
|
return Object.fromEntries(settings.endpointProfiles.filter((p) => p.displayName).map((p) => [p.slug, p.displayName]));
|
|
@@ -212148,7 +212398,21 @@ const nativeClaudeProviderStatus = require_Schema$1.fn("nativeClaudeProviderStat
|
|
|
212148
212398
|
}
|
|
212149
212399
|
});
|
|
212150
212400
|
});
|
|
212151
|
-
|
|
212401
|
+
/**
|
|
212402
|
+
* Adds what the CLI said about its credentials. Every check where
|
|
212403
|
+
* `claude --version` ran and exited 0 reaches here, including one whose
|
|
212404
|
+
* version did not parse; that one has no key to look a probe answer up by, so
|
|
212405
|
+
* only the store is added.
|
|
212406
|
+
*/
|
|
212407
|
+
function withClaudeCredentialAnswers(provider, resolve, input) {
|
|
212408
|
+
if (!resolve) return require_Schema$1.succeed(provider);
|
|
212409
|
+
return resolve(input).pipe(require_Schema$1.map((answers) => ({
|
|
212410
|
+
...provider,
|
|
212411
|
+
...answers
|
|
212412
|
+
})));
|
|
212413
|
+
}
|
|
212414
|
+
const checkClaudeProviderStatus = require_Schema$1.fn("checkClaudeProviderStatus")(function* (resolvers = {}) {
|
|
212415
|
+
const { resolveSubscriptionType, resolveSlashCommands, resolveModels, resolveCredentialAnswers } = resolvers;
|
|
212152
212416
|
const config = require_Schema$1.getOrElse(yield* require_Schema$1.serviceOption(ServerConfig), () => ({
|
|
212153
212417
|
...DEFAULT_PROVIDER_AUTH_CONFIG,
|
|
212154
212418
|
forgeClaudeConfigPath: void 0
|
|
@@ -212220,19 +212484,24 @@ const checkClaudeProviderStatus = require_Schema$1.fn("checkClaudeProviderStatus
|
|
|
212220
212484
|
});
|
|
212221
212485
|
}
|
|
212222
212486
|
const executableFallbackModels = modelsForClaudeCliVersion(fallbackModels, parsedVersion);
|
|
212223
|
-
|
|
212487
|
+
const credentialAnswersInput = {
|
|
212488
|
+
binaryPath: claudeSettings.binaryPath,
|
|
212489
|
+
version: claudeVersionFromOutput(version.stdout),
|
|
212490
|
+
configDirectory: effectiveConfigPath
|
|
212491
|
+
};
|
|
212492
|
+
if (personalClaudeInVmEnabled()) return yield* withClaudeCredentialAnswers(yield* nativeClaudeProviderStatus({
|
|
212224
212493
|
enabled: claudeSettings.enabled,
|
|
212225
212494
|
checkedAt,
|
|
212226
212495
|
version: parsedVersion,
|
|
212227
212496
|
configPath: effectiveConfigPath,
|
|
212228
212497
|
models: executableFallbackModels,
|
|
212229
212498
|
provenance
|
|
212230
|
-
});
|
|
212499
|
+
}), resolveCredentialAnswers, credentialAnswersInput);
|
|
212231
212500
|
const capabilitiesProbeInput = claudeCapabilitiesProbeInput(claudeSettings.binaryPath, effectiveConfigPath);
|
|
212232
212501
|
const discovery = yield* resolveClaudeDiscovery(capabilitiesProbeInput, resolveSlashCommands, resolveModels);
|
|
212233
212502
|
const models = modelsForClaudeCliVersion(providerModelsFromSettings(resolveClaudeProviderModels(discovery.models), PROVIDER$12, claudeSettings.customModels, DEFAULT_CLAUDE_MODEL_CAPABILITIES, endpointProfileDisplayNames(claudeSettings)), parsedVersion);
|
|
212234
212503
|
const authProbe = yield* runClaudeCommand(["auth", "status"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$3), require_Schema$1.result);
|
|
212235
|
-
return buildClaudeProviderFromAuthProbe({
|
|
212504
|
+
return yield* withClaudeCredentialAnswers(buildClaudeProviderFromAuthProbe({
|
|
212236
212505
|
authProbe,
|
|
212237
212506
|
authMetadata: yield* resolveClaudeAuthMetadata(authProbe, capabilitiesProbeInput, resolveSubscriptionType),
|
|
212238
212507
|
checkedAt,
|
|
@@ -212241,7 +212510,7 @@ const checkClaudeProviderStatus = require_Schema$1.fn("checkClaudeProviderStatus
|
|
|
212241
212510
|
slashCommands: discovery.slashCommands,
|
|
212242
212511
|
parsedVersion,
|
|
212243
212512
|
provenance
|
|
212244
|
-
});
|
|
212513
|
+
}), resolveCredentialAnswers, credentialAnswersInput);
|
|
212245
212514
|
});
|
|
212246
212515
|
const makePendingClaudeProvider = (claudeSettings) => {
|
|
212247
212516
|
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -212273,30 +212542,76 @@ const makePendingClaudeProvider = (claudeSettings) => {
|
|
|
212273
212542
|
}
|
|
212274
212543
|
});
|
|
212275
212544
|
};
|
|
212276
|
-
|
|
212277
|
-
|
|
212278
|
-
|
|
212279
|
-
|
|
212280
|
-
|
|
212281
|
-
|
|
212282
|
-
|
|
212283
|
-
|
|
212284
|
-
|
|
212285
|
-
|
|
212286
|
-
|
|
212287
|
-
|
|
212288
|
-
|
|
212289
|
-
|
|
212290
|
-
|
|
212291
|
-
|
|
212292
|
-
|
|
212293
|
-
|
|
212294
|
-
|
|
212295
|
-
|
|
212296
|
-
|
|
212297
|
-
|
|
212298
|
-
});
|
|
212299
|
-
}));
|
|
212545
|
+
/**
|
|
212546
|
+
* A refresh can wait behind a check that already holds the provider's refresh
|
|
212547
|
+
* permit before running its own, so it gets two check budgets.
|
|
212548
|
+
*/
|
|
212549
|
+
const CREDENTIAL_ANSWER_REFRESH_TIMEOUT_MS = 2 * (CLAUDE_VERSION_PROBE_TIMEOUT_MS + CAPABILITIES_PROBE_TIMEOUT_MS$1 + DEFAULT_TIMEOUT_MS$3);
|
|
212550
|
+
/** The gap after each answer refresh, and the pause before a restart. */
|
|
212551
|
+
const CREDENTIAL_ANSWER_REFRESH_SPACING = require_Schema$1.seconds(1);
|
|
212552
|
+
/**
|
|
212553
|
+
* Reruns the check when a probe reaches a new or changed answer, so the
|
|
212554
|
+
* inventory carries it without waiting for the next scheduled check. Answers
|
|
212555
|
+
* that arrive during a refresh collapse into one more refresh.
|
|
212556
|
+
*
|
|
212557
|
+
* A refresh that fails, dies or outlives its timeout is logged, and the loop
|
|
212558
|
+
* goes back to waiting for the next answer. The timeout interrupts the check,
|
|
212559
|
+
* which hands back the refresh permit. `runSupervisedRepeat` restarts the loop
|
|
212560
|
+
* after any interrupt that does not come from the scope closing; closing the
|
|
212561
|
+
* scope stops it and drops the subscription.
|
|
212562
|
+
*/
|
|
212563
|
+
const refreshOnNewCredentialDirectoryAnswer = require_Schema$1.fn("refreshOnNewCredentialDirectoryAnswer")(function* (credentialDirectoryAnswers, refresh) {
|
|
212564
|
+
const changed = yield* require_Path.sliding(1);
|
|
212565
|
+
yield* require_Schema$1.acquireRelease(require_Schema$1.sync(() => credentialDirectoryAnswers.subscribe(() => {
|
|
212566
|
+
require_Path.offerUnsafe(changed, void 0);
|
|
212567
|
+
})), (unsubscribe) => require_Schema$1.sync(unsubscribe));
|
|
212568
|
+
const refreshOnce = refresh.pipe(require_Schema$1.timeout(CREDENTIAL_ANSWER_REFRESH_TIMEOUT_MS), require_Schema$1.asVoid, require_Schema$1.catchCause((cause) => require_Schema$1.hasInterruptsOnly(cause) ? require_Schema$1.interrupt : require_Schema$1.logWarning("Claude refresh for a new credential-directory answer failed", { cause: require_Schema$1.pretty(cause) })));
|
|
212569
|
+
yield* require_Schema$1.forkScoped(runSupervisedRepeat({
|
|
212570
|
+
label: "Claude credential-directory answer refresh",
|
|
212571
|
+
work: require_Path.take(changed).pipe(require_Schema$1.andThen(refreshOnce)),
|
|
212572
|
+
interval: CREDENTIAL_ANSWER_REFRESH_SPACING
|
|
212573
|
+
}));
|
|
212574
|
+
});
|
|
212575
|
+
/** The Claude provider. Tests hand in their own answers and store read. */
|
|
212576
|
+
function makeClaudeProviderLive(options = {}) {
|
|
212577
|
+
const credentialDirectoryAnswers = options.credentialDirectoryAnswers ?? claudeCredentialDirectoryAnswers;
|
|
212578
|
+
const resolveCredentialAnswers = makeClaudeCredentialAnswersResolver({
|
|
212579
|
+
...options,
|
|
212580
|
+
credentialDirectoryAnswers
|
|
212581
|
+
});
|
|
212582
|
+
return require_Schema$1.effect(ClaudeProvider, require_Schema$1.gen(function* () {
|
|
212583
|
+
const serverSettings = yield* ServerSettingsService;
|
|
212584
|
+
const spawner = yield* require_NodeTerminal.ChildProcessSpawner;
|
|
212585
|
+
const subscriptionProbeCache = yield* require_Cache.make({
|
|
212586
|
+
capacity: 4,
|
|
212587
|
+
timeToLive: require_Schema$1.minutes(5),
|
|
212588
|
+
lookup: (key) => {
|
|
212589
|
+
const [binaryPath, configPath] = JSON.parse(key);
|
|
212590
|
+
return probeClaudeCapabilities({
|
|
212591
|
+
binaryPath,
|
|
212592
|
+
...configPath ? { configPath } : {}
|
|
212593
|
+
});
|
|
212594
|
+
}
|
|
212595
|
+
});
|
|
212596
|
+
const getDiscovery = (input) => require_Cache.get(subscriptionProbeCache, JSON.stringify([input.binaryPath, input.configPath]));
|
|
212597
|
+
const checkProvider = checkClaudeProviderStatus({
|
|
212598
|
+
resolveSubscriptionType: (input) => getDiscovery(input).pipe(require_Schema$1.map((probe) => probe?.subscriptionType)),
|
|
212599
|
+
resolveSlashCommands: (input) => getDiscovery(input).pipe(require_Schema$1.map((probe) => probe?.slashCommands)),
|
|
212600
|
+
resolveModels: (input) => getDiscovery(input).pipe(require_Schema$1.map((probe) => probe?.models)),
|
|
212601
|
+
resolveCredentialAnswers
|
|
212602
|
+
}).pipe(require_Schema$1.provideService(ServerSettingsService, serverSettings), require_Schema$1.provideService(require_NodeTerminal.ChildProcessSpawner, spawner));
|
|
212603
|
+
const provider = yield* makeManagedServerProvider({
|
|
212604
|
+
getSettings: serverSettings.getSettings.pipe(require_Schema$1.map((settings) => settings.providers.claudeAgent), require_Schema$1.orDie),
|
|
212605
|
+
streamSettings: serverSettings.streamChanges.pipe(require_Path.map((settings) => settings.providers.claudeAgent)),
|
|
212606
|
+
haveSettingsChanged: (previous, next) => !require_Schema$1.equals(previous, next),
|
|
212607
|
+
initialSnapshot: makePendingClaudeProvider,
|
|
212608
|
+
checkProvider
|
|
212609
|
+
});
|
|
212610
|
+
yield* refreshOnNewCredentialDirectoryAnswer(credentialDirectoryAnswers, provider.refresh);
|
|
212611
|
+
return provider;
|
|
212612
|
+
}));
|
|
212613
|
+
}
|
|
212614
|
+
const ClaudeProviderLive = makeClaudeProviderLive();
|
|
212300
212615
|
//#endregion
|
|
212301
212616
|
//#region src/provider/Services/ClaudeAdapter.ts
|
|
212302
212617
|
/**
|
|
@@ -287537,46 +287852,6 @@ const makeRuntimeDrainState = require_Schema$1.gen(function* () {
|
|
|
287537
287852
|
var RuntimeDrainState = class extends require_Schema$1.Service()("forge/runtimeDrain/RuntimeDrainState") {};
|
|
287538
287853
|
const RuntimeDrainStateLive = require_Schema$1.effect(RuntimeDrainState, makeRuntimeDrainState);
|
|
287539
287854
|
//#endregion
|
|
287540
|
-
//#region src/runtimeDrain/supervisedRepeat.ts
|
|
287541
|
-
/**
|
|
287542
|
-
* Runs `work` on a fixed schedule, forever, and RESTARTS the schedule itself
|
|
287543
|
-
* if it ever dies for any reason other than this scope closing.
|
|
287544
|
-
*
|
|
287545
|
-
* `Effect.repeat(work, Schedule.spaced(interval)).pipe(Effect.forkScoped)`
|
|
287546
|
-
* alone has no restart path. `work` catching its own errors only protects
|
|
287547
|
-
* the TICK: an interrupt that lands while `Effect.repeat` is asleep between
|
|
287548
|
-
* ticks — which, at any non-trivial interval, is nearly this loop's entire
|
|
287549
|
-
* life — happens outside anything `work` wraps, and kills that one fiber
|
|
287550
|
-
* outright with nothing logged, because nothing was running to log from.
|
|
287551
|
-
* The process this runs in can otherwise be perfectly healthy while the
|
|
287552
|
-
* schedule is silently, permanently dead.
|
|
287553
|
-
*
|
|
287554
|
-
* This runs the schedule on its own child fiber, raced against an explicit
|
|
287555
|
-
* shutdown signal fired by a finalizer registered in this scope. Only that
|
|
287556
|
-
* signal stops the loop for good; any other death of the schedule fiber —
|
|
287557
|
-
* whatever causes it, defect or interrupt — logs and restarts it. `work`
|
|
287558
|
-
* itself must still handle its own EXPECTED failures (this only supervises
|
|
287559
|
-
* the schedule, and treats every death of it as unexpected).
|
|
287560
|
-
*/
|
|
287561
|
-
function runSupervisedRepeat(input) {
|
|
287562
|
-
return require_Schema$1.gen(function* () {
|
|
287563
|
-
const shutdownSignal = yield* require_Schema$1.make$4();
|
|
287564
|
-
yield* require_Schema$1.addFinalizer(() => require_Schema$1.succeed$2(shutdownSignal, void 0));
|
|
287565
|
-
let firstAttempt = true;
|
|
287566
|
-
while (true) {
|
|
287567
|
-
if (!firstAttempt) yield* require_Schema$1.sleep(input.interval);
|
|
287568
|
-
firstAttempt = false;
|
|
287569
|
-
const scheduleFiber = yield* require_Schema$1.forkChild(require_Schema$1.repeat(input.work, require_Schema$1.spaced(input.interval)));
|
|
287570
|
-
const outcome = yield* require_Schema$1.race(require_Path.await_(scheduleFiber), require_Schema$1._await(shutdownSignal).pipe(require_Schema$1.as("shutdown")));
|
|
287571
|
-
if (outcome === "shutdown") {
|
|
287572
|
-
yield* require_Path.interrupt(scheduleFiber);
|
|
287573
|
-
return;
|
|
287574
|
-
}
|
|
287575
|
-
yield* require_Schema$1.logError(`${input.label} died unexpectedly — restarting`, { cause: require_Schema$1.isFailure(outcome) ? require_Schema$1.pretty(outcome.cause) : "unknown exit" });
|
|
287576
|
-
}
|
|
287577
|
-
});
|
|
287578
|
-
}
|
|
287579
|
-
//#endregion
|
|
287580
287855
|
//#region src/runtimeDrain/RuntimeDrainReporter.ts
|
|
287581
287856
|
const HEARTBEAT_INTERVAL = require_Schema$1.seconds(30);
|
|
287582
287857
|
const HEARTBEAT_TICK_TIMEOUT = require_Schema$1.seconds(60);
|
|
@@ -294999,7 +295274,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
294999
295274
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
295000
295275
|
*/
|
|
295001
295276
|
function readBakedBuildCommit() {
|
|
295002
|
-
return "
|
|
295277
|
+
return "69affcc8397652715f8bd06fe2f226f4b607e1db";
|
|
295003
295278
|
}
|
|
295004
295279
|
async function resolveServerBuildCommit(input) {
|
|
295005
295280
|
if (isFullCommitSha(input.baked)) return input.baked;
|