@cmmd-center/forge 0.12.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +546 -192
- package/dist/bin.mjs +543 -191
- package/dist/client/assets/{CanvasPanel-CL4T3ptl.js → CanvasPanel-BrVen-8G.js} +2 -2
- package/dist/client/assets/{CompositeItem-NATmsDHX.js → CompositeItem-BNZfMUvm.js} +2 -2
- package/dist/client/assets/{DiffPanel-29UmSyE3.js → DiffPanel-tnITsSoL.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-D5Bn5tgT.js → DiffPanel.logic-Ce-amvoZ.js} +2 -2
- package/dist/client/assets/DiffPanelShell-C14W3dyR.js +2531 -0
- package/dist/client/assets/{DiffWorkerPoolProvider-BMZL3CsO.js → DiffWorkerPoolProvider-BmseZYiJ.js} +8 -8
- package/dist/client/assets/PullRequestCodePanel-A_x1n0YN.js +5 -0
- package/dist/client/assets/{Virtualizer-uq0d5TwY.js → Virtualizer-CU3LnU6A.js} +2 -2
- package/dist/client/assets/{canvasStateStore-DtidOKbV.js → canvasStateStore-DN5mPB5B.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-CzACd5XJ.js → cmmdAuthRedirect-sqR8W6vY.js} +2 -2
- package/dist/client/assets/index-DUeDfPMN.js +151 -0
- package/dist/client/assets/index-Dk7T0zVg.css +1 -0
- package/dist/client/assets/src-CFqnisEM.js +3 -0
- package/dist/client/assets/{toggle-pwklbW9N.js → toggle-CLUqZXdO.js} +2 -2
- package/dist/client/assets/{useTriggerFocusGuards-CPLQ8_CW.js → useTriggerFocusGuards-CaUimC-O.js} +2 -2
- package/dist/client/index.html +11 -11
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/DiffPanelShell-ClKPX_Pu.js +0 -2531
- package/dist/client/assets/PullRequestCodePanel-Cp75delh.js +0 -5
- package/dist/client/assets/index-BMcOaHS_.css +0 -1
- package/dist/client/assets/index-BOI5P7rG.js +0 -151
- package/dist/client/assets/src-BlFkWEsP.js +0 -3
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.
|
|
16547
|
+
const FORGE_RELEASE_VERSION = "0.13.1";
|
|
16548
16548
|
//#endregion
|
|
16549
16549
|
//#region ../../packages/shared/src/hostProcess.ts
|
|
16550
16550
|
/**
|
|
@@ -18654,6 +18654,43 @@ const TerminalError = require_Schema$1.Union([
|
|
|
18654
18654
|
TerminalSignalError
|
|
18655
18655
|
]);
|
|
18656
18656
|
//#endregion
|
|
18657
|
+
//#region ../../packages/contracts/src/projectScriptCommands.ts
|
|
18658
|
+
const ProjectScriptIcon = require_Schema$1.Literals([
|
|
18659
|
+
"play",
|
|
18660
|
+
"test",
|
|
18661
|
+
"lint",
|
|
18662
|
+
"configure",
|
|
18663
|
+
"build",
|
|
18664
|
+
"debug"
|
|
18665
|
+
]);
|
|
18666
|
+
const ProjectScript = require_Schema$1.Struct({
|
|
18667
|
+
id: TrimmedNonEmptyString,
|
|
18668
|
+
name: TrimmedNonEmptyString,
|
|
18669
|
+
command: TrimmedNonEmptyString,
|
|
18670
|
+
icon: ProjectScriptIcon,
|
|
18671
|
+
runOnWorktreeCreate: require_Schema$1.Boolean
|
|
18672
|
+
});
|
|
18673
|
+
const ProjectScriptUpdateCommand = require_Schema$1.Struct({
|
|
18674
|
+
type: require_Schema$1.Literal("project.script.update"),
|
|
18675
|
+
commandId: CommandId,
|
|
18676
|
+
projectId: ProjectId,
|
|
18677
|
+
mutation: require_Schema$1.Union([
|
|
18678
|
+
require_Schema$1.Struct({
|
|
18679
|
+
kind: require_Schema$1.Literal("add"),
|
|
18680
|
+
script: ProjectScript
|
|
18681
|
+
}),
|
|
18682
|
+
require_Schema$1.Struct({
|
|
18683
|
+
kind: require_Schema$1.Literal("update"),
|
|
18684
|
+
script: ProjectScript,
|
|
18685
|
+
expected: ProjectScript
|
|
18686
|
+
}),
|
|
18687
|
+
require_Schema$1.Struct({
|
|
18688
|
+
kind: require_Schema$1.Literal("remove"),
|
|
18689
|
+
expected: ProjectScript
|
|
18690
|
+
})
|
|
18691
|
+
])
|
|
18692
|
+
});
|
|
18693
|
+
//#endregion
|
|
18657
18694
|
//#region ../../packages/contracts/src/model.ts
|
|
18658
18695
|
const CODEX_REASONING_EFFORT_OPTIONS = [
|
|
18659
18696
|
"ultra",
|
|
@@ -19313,21 +19350,6 @@ const UploadChatImageAttachment = require_Schema$1.Struct({
|
|
|
19313
19350
|
});
|
|
19314
19351
|
const ChatAttachment = require_Schema$1.Union([ChatImageAttachment]);
|
|
19315
19352
|
const UploadChatAttachment = require_Schema$1.Union([UploadChatImageAttachment]);
|
|
19316
|
-
const ProjectScriptIcon = require_Schema$1.Literals([
|
|
19317
|
-
"play",
|
|
19318
|
-
"test",
|
|
19319
|
-
"lint",
|
|
19320
|
-
"configure",
|
|
19321
|
-
"build",
|
|
19322
|
-
"debug"
|
|
19323
|
-
]);
|
|
19324
|
-
const ProjectScript = require_Schema$1.Struct({
|
|
19325
|
-
id: TrimmedNonEmptyString,
|
|
19326
|
-
name: TrimmedNonEmptyString,
|
|
19327
|
-
command: TrimmedNonEmptyString,
|
|
19328
|
-
icon: ProjectScriptIcon,
|
|
19329
|
-
runOnWorktreeCreate: require_Schema$1.Boolean
|
|
19330
|
-
});
|
|
19331
19353
|
/**
|
|
19332
19354
|
* Availability of the project's `workspaceRoot` on the server's filesystem.
|
|
19333
19355
|
*
|
|
@@ -19958,6 +19980,7 @@ const ThreadSessionStopCommand = require_Schema$1.Struct({
|
|
|
19958
19980
|
const DispatchableClientOrchestrationCommand = require_Schema$1.Union([
|
|
19959
19981
|
ProjectCreateCommand,
|
|
19960
19982
|
ProjectMetaUpdateCommand,
|
|
19983
|
+
ProjectScriptUpdateCommand,
|
|
19961
19984
|
ProjectDeleteCommand,
|
|
19962
19985
|
ThreadCreateCommand,
|
|
19963
19986
|
ThreadDeleteCommand,
|
|
@@ -19979,6 +20002,7 @@ const DispatchableClientOrchestrationCommand = require_Schema$1.Union([
|
|
|
19979
20002
|
const ClientOrchestrationCommand = require_Schema$1.Union([
|
|
19980
20003
|
ProjectCreateCommand,
|
|
19981
20004
|
ProjectMetaUpdateCommand,
|
|
20005
|
+
ProjectScriptUpdateCommand,
|
|
19982
20006
|
ProjectDeleteCommand,
|
|
19983
20007
|
ThreadCreateCommand,
|
|
19984
20008
|
ThreadDeleteCommand,
|
|
@@ -22623,6 +22647,27 @@ const ProviderUnavailableDetail = require_Schema$1.Literals([
|
|
|
22623
22647
|
"delivery-pending",
|
|
22624
22648
|
"reconnect-required"
|
|
22625
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
|
+
]);
|
|
22626
22671
|
const ServerProviderModel = require_Schema$1.Struct({
|
|
22627
22672
|
slug: TrimmedNonEmptyString,
|
|
22628
22673
|
name: TrimmedNonEmptyString,
|
|
@@ -22659,6 +22704,8 @@ const ServerProvider = require_Schema$1.Struct({
|
|
|
22659
22704
|
availability: require_Schema$1.optional(ProviderAvailability),
|
|
22660
22705
|
unavailableReason: require_Schema$1.optional(ProviderUnavailableReason),
|
|
22661
22706
|
unavailableDetail: require_Schema$1.optional(ProviderUnavailableDetail),
|
|
22707
|
+
credentialDirectory: require_Schema$1.optional(ProviderCredentialDirectoryAnswer),
|
|
22708
|
+
credentialStore: require_Schema$1.optional(ProviderCredentialStore),
|
|
22662
22709
|
slashCommands: require_Schema$1.ArraySchema(ServerProviderSlashCommand).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed([]))),
|
|
22663
22710
|
skills: require_Schema$1.ArraySchema(ServerProviderSkill).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed([])))
|
|
22664
22711
|
});
|
|
@@ -26697,12 +26744,12 @@ function encodeCmmdRuntimeThreadWorkspaceMetadata(workspace) {
|
|
|
26697
26744
|
}
|
|
26698
26745
|
//#endregion
|
|
26699
26746
|
//#region ../../packages/contracts/src/cmmdRuntimeToolActivity.ts
|
|
26700
|
-
function isRecord$
|
|
26747
|
+
function isRecord$23(value) {
|
|
26701
26748
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
26702
26749
|
}
|
|
26703
26750
|
function encodeCmmdRuntimeToolActivityPayload(kind, payload) {
|
|
26704
26751
|
return {
|
|
26705
|
-
...isRecord$
|
|
26752
|
+
...isRecord$23(payload) ? payload : { sourcePayload: payload },
|
|
26706
26753
|
forgeToolActivity: {
|
|
26707
26754
|
schemaVersion: 1,
|
|
26708
26755
|
source: "native",
|
|
@@ -30702,13 +30749,13 @@ async function completePendingDesktopRelayIdentityRotation(input) {
|
|
|
30702
30749
|
}
|
|
30703
30750
|
//#endregion
|
|
30704
30751
|
//#region ../../packages/relay-host/src/internal/desktopRelayJws.ts
|
|
30705
|
-
function isRecord$
|
|
30752
|
+
function isRecord$22(value) {
|
|
30706
30753
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30707
30754
|
}
|
|
30708
30755
|
function decodeBase64UrlJson$1(value) {
|
|
30709
30756
|
try {
|
|
30710
30757
|
const decoded = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
30711
|
-
return isRecord$
|
|
30758
|
+
return isRecord$22(decoded) ? decoded : null;
|
|
30712
30759
|
} catch {
|
|
30713
30760
|
return null;
|
|
30714
30761
|
}
|
|
@@ -30862,11 +30909,11 @@ var DesktopRelayControlPlaneError = class extends Error {
|
|
|
30862
30909
|
this.name = "DesktopRelayControlPlaneError";
|
|
30863
30910
|
}
|
|
30864
30911
|
};
|
|
30865
|
-
function isRecord$
|
|
30912
|
+
function isRecord$21(value) {
|
|
30866
30913
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30867
30914
|
}
|
|
30868
30915
|
function parseErrorPayload(value) {
|
|
30869
|
-
return isRecord$
|
|
30916
|
+
return isRecord$21(value) ? value : {};
|
|
30870
30917
|
}
|
|
30871
30918
|
function messageFromErrorPayload(payload, fallback) {
|
|
30872
30919
|
return typeof payload.error === "string" && payload.error.trim().length > 0 ? payload.error.trim() : fallback;
|
|
@@ -30964,7 +31011,7 @@ async function postControlPlane(input) {
|
|
|
30964
31011
|
const errorPayload = parseErrorPayload(payload);
|
|
30965
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);
|
|
30966
31013
|
}
|
|
30967
|
-
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);
|
|
30968
31015
|
return payload.data;
|
|
30969
31016
|
}
|
|
30970
31017
|
function resolveRegisteredDevice(input) {
|
|
@@ -31834,6 +31881,10 @@ const relayCommandPolicyByType = {
|
|
|
31834
31881
|
requiredScope: "project.write",
|
|
31835
31882
|
deliveryClass: "idempotent-command"
|
|
31836
31883
|
},
|
|
31884
|
+
"project.script.update": {
|
|
31885
|
+
requiredScope: "project.write",
|
|
31886
|
+
deliveryClass: "idempotent-command"
|
|
31887
|
+
},
|
|
31837
31888
|
"project.delete": {
|
|
31838
31889
|
requiredScope: "project.write",
|
|
31839
31890
|
deliveryClass: "idempotent-command"
|
|
@@ -65813,7 +65864,7 @@ function normalizeNumberish(value) {
|
|
|
65813
65864
|
}
|
|
65814
65865
|
//#endregion
|
|
65815
65866
|
//#region package.json
|
|
65816
|
-
var version$1 = "0.
|
|
65867
|
+
var version$1 = "0.13.1";
|
|
65817
65868
|
//#endregion
|
|
65818
65869
|
//#region src/sentry.ts
|
|
65819
65870
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -71377,12 +71428,12 @@ function resolveDesktopRelayControlPlaneTarget(path, configuredRuntimeId) {
|
|
|
71377
71428
|
code: "RELAY_OPERATION_DENIED"
|
|
71378
71429
|
};
|
|
71379
71430
|
}
|
|
71380
|
-
function isRecord$
|
|
71431
|
+
function isRecord$20(value) {
|
|
71381
71432
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
71382
71433
|
}
|
|
71383
71434
|
function relayControlPlaneBodyMatchesRuntime(path, body, configuredRuntimeId) {
|
|
71384
71435
|
if (path !== "/api/forge/context/devices/register") return true;
|
|
71385
|
-
if (!isRecord$
|
|
71436
|
+
if (!isRecord$20(body) || !isRecord$20(body.runtime)) return false;
|
|
71386
71437
|
return body.runtime.runtimeId === configuredRuntimeId;
|
|
71387
71438
|
}
|
|
71388
71439
|
/** Matches the client id `connect login` used, so CMMD accepts the refresh. */
|
|
@@ -71397,7 +71448,7 @@ function forbiddenResponse() {
|
|
|
71397
71448
|
return errorResponse(403, "RELAY_BRIDGE_FORBIDDEN", "Desktop relay bridge access denied.");
|
|
71398
71449
|
}
|
|
71399
71450
|
function relayProxyErrorResponse(error) {
|
|
71400
|
-
if (error instanceof CmmdProxyRequestError && isRecord$
|
|
71451
|
+
if (error instanceof CmmdProxyRequestError && isRecord$20(error.body)) {
|
|
71401
71452
|
const code = typeof error.body.code === "string" ? error.body.code : error.code;
|
|
71402
71453
|
const message = typeof error.body.error === "string" ? error.body.error : error.detail;
|
|
71403
71454
|
return errorResponse(error.status >= 500 ? 502 : error.status, code, message ?? "CMMD relay coordination failed.");
|
|
@@ -93773,7 +93824,7 @@ const REPLICA_THREAD_STATUSES = [
|
|
|
93773
93824
|
];
|
|
93774
93825
|
//#endregion
|
|
93775
93826
|
//#region src/runtimeReplication/replicaDecodeModel.ts
|
|
93776
|
-
function isRecord$
|
|
93827
|
+
function isRecord$19(value) {
|
|
93777
93828
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
93778
93829
|
}
|
|
93779
93830
|
function isNonBlankString(value) {
|
|
@@ -93793,7 +93844,7 @@ function nullableInteger(value) {
|
|
|
93793
93844
|
return value === null || typeof value === "number" && Number.isSafeInteger(value);
|
|
93794
93845
|
}
|
|
93795
93846
|
function unwrapEnvelope(payload, expectedDomain) {
|
|
93796
|
-
if (!isRecord$
|
|
93847
|
+
if (!isRecord$19(payload) || !isRecord$19(payload.meta) || !isRecord$19(payload.data)) return null;
|
|
93797
93848
|
const { domain, timestamp, version } = payload.meta;
|
|
93798
93849
|
if (!isNonBlankString(domain) || expectedDomain !== void 0 && domain !== expectedDomain || version !== "1.0" || !isIsoDateTime(timestamp)) return null;
|
|
93799
93850
|
return payload.data;
|
|
@@ -93806,12 +93857,12 @@ function hasValidRuntimeIdentity(value) {
|
|
|
93806
93857
|
].includes(String(value.runtimeKind)) && typeof value.displayName === "string" && typeof value.status === "string";
|
|
93807
93858
|
}
|
|
93808
93859
|
function decodeRuntime$1(value) {
|
|
93809
|
-
if (!isRecord$
|
|
93810
|
-
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;
|
|
93811
93862
|
return value;
|
|
93812
93863
|
}
|
|
93813
93864
|
function decodeProject(value) {
|
|
93814
|
-
if (!isRecord$
|
|
93865
|
+
if (!isRecord$19(value) || !isNonBlankString(value.projectId) || typeof value.title !== "string" || !nullableString(value.githubRepoFullName) || !nullableString(value.branch)) return null;
|
|
93815
93866
|
return {
|
|
93816
93867
|
projectId: value.projectId,
|
|
93817
93868
|
title: value.title,
|
|
@@ -93820,11 +93871,11 @@ function decodeProject(value) {
|
|
|
93820
93871
|
};
|
|
93821
93872
|
}
|
|
93822
93873
|
function decodeThread$1(value) {
|
|
93823
|
-
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;
|
|
93824
93875
|
return value;
|
|
93825
93876
|
}
|
|
93826
93877
|
function decodeSummary(value) {
|
|
93827
|
-
if (!isRecord$
|
|
93878
|
+
if (!isRecord$19(value) || !nullableString(value.conversationId)) return null;
|
|
93828
93879
|
const project = decodeProject(value.project);
|
|
93829
93880
|
const thread = decodeThread$1(value.thread);
|
|
93830
93881
|
return project === null || thread === null ? null : {
|
|
@@ -93935,7 +93986,7 @@ function isNonNegativeInt(value) {
|
|
|
93935
93986
|
/** `usage` is null for an Unreported turn, otherwise exactly the five buckets. */
|
|
93936
93987
|
function isValidTurnUsageTokens(value) {
|
|
93937
93988
|
if (value === null) return true;
|
|
93938
|
-
if (!isRecord$
|
|
93989
|
+
if (!isRecord$19(value)) return false;
|
|
93939
93990
|
return turnUsageTokenKeys.every((key) => isNonNegativeInt(value[key])) && Object.keys(value).every((key) => turnUsageTokenKeys.includes(key));
|
|
93940
93991
|
}
|
|
93941
93992
|
/** The row itself: no text, no status, and the turn it belongs to. */
|
|
@@ -93944,7 +93995,7 @@ function hasValidTurnUsageEnvelope(value) {
|
|
|
93944
93995
|
}
|
|
93945
93996
|
/** What the row records: who ran it, what it spent, and what it says of itself. */
|
|
93946
93997
|
function hasValidTurnUsageRecord(payload) {
|
|
93947
|
-
return isRecord$
|
|
93998
|
+
return isRecord$19(payload) && isNonBlankString(payload.provider) && isNonBlankString(payload.model) && "usage" in payload && isValidTurnUsageTokens(payload.usage) && hasValidTurnUsageAttribution(payload);
|
|
93948
93999
|
}
|
|
93949
94000
|
/** A turn_usage row: no text, no status, and its record in `payload`. */
|
|
93950
94001
|
function hasValidTurnUsagePayload(value) {
|
|
@@ -93981,7 +94032,7 @@ function hasValidEventPayload(value) {
|
|
|
93981
94032
|
return isNonBlankString(value.text) && value.status === null;
|
|
93982
94033
|
}
|
|
93983
94034
|
function decodeEvent$1(value) {
|
|
93984
|
-
if (!isRecord$
|
|
94035
|
+
if (!isRecord$19(value) || !hasValidEventFields(value) || !hasValidEventPayload(value)) return null;
|
|
93985
94036
|
return value;
|
|
93986
94037
|
}
|
|
93987
94038
|
function decodeEvents(data) {
|
|
@@ -94002,11 +94053,11 @@ function decodeReplicaThreadDetail(payload) {
|
|
|
94002
94053
|
const thread = decodeThread$1(data.thread);
|
|
94003
94054
|
const reachability = decodeReachability(data.reachability);
|
|
94004
94055
|
const events = decodeEvents(data);
|
|
94005
|
-
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" || ![
|
|
94006
94057
|
null,
|
|
94007
94058
|
"runtime_offline",
|
|
94008
94059
|
"runtime_unavailable"
|
|
94009
|
-
].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;
|
|
94010
94061
|
return {
|
|
94011
94062
|
conversationId: data.conversationId,
|
|
94012
94063
|
runtime,
|
|
@@ -94927,7 +94978,7 @@ function resolveRuntimeReplicationRuntimeId(config) {
|
|
|
94927
94978
|
}
|
|
94928
94979
|
//#endregion
|
|
94929
94980
|
//#region src/usage/providerTokenBuckets.ts
|
|
94930
|
-
function isRecord$
|
|
94981
|
+
function isRecord$18(value) {
|
|
94931
94982
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
94932
94983
|
}
|
|
94933
94984
|
function count(record, ...keys) {
|
|
@@ -94948,7 +94999,7 @@ function reportedOrNull(tokens) {
|
|
|
94948
94999
|
* the app server sends camelCase.
|
|
94949
95000
|
*/
|
|
94950
95001
|
function codexTokenBuckets(value) {
|
|
94951
|
-
if (!isRecord$
|
|
95002
|
+
if (!isRecord$18(value)) return null;
|
|
94952
95003
|
const inputTokens = count(value, "input_tokens", "inputTokens");
|
|
94953
95004
|
const cachedInputTokens = count(value, "cached_input_tokens", "cachedInputTokens");
|
|
94954
95005
|
const cacheCreationTokens = count(value, "cache_write_input_tokens", "cacheWriteInputTokens");
|
|
@@ -94967,7 +95018,7 @@ function codexTokenBuckets(value) {
|
|
|
94967
95018
|
* tokens into output and does not break them out, so reasoning stays zero.
|
|
94968
95019
|
*/
|
|
94969
95020
|
function claudeTokenBuckets(value) {
|
|
94970
|
-
if (!isRecord$
|
|
95021
|
+
if (!isRecord$18(value)) return null;
|
|
94971
95022
|
return reportedOrNull({
|
|
94972
95023
|
uncachedInputTokens: count(value, "input_tokens", "inputTokens"),
|
|
94973
95024
|
cachedInputTokens: count(value, "cache_read_input_tokens", "cacheReadInputTokens"),
|
|
@@ -95861,6 +95912,20 @@ function publishedAvailability(provider) {
|
|
|
95861
95912
|
...detail === void 0 ? {} : { unavailableDetail: detail }
|
|
95862
95913
|
};
|
|
95863
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
|
+
}
|
|
95864
95929
|
function serializeProvider(provider) {
|
|
95865
95930
|
const models = [];
|
|
95866
95931
|
for (const model of provider.models) {
|
|
@@ -95873,7 +95938,8 @@ function serializeProvider(provider) {
|
|
|
95873
95938
|
models,
|
|
95874
95939
|
...publishedAvailability(provider),
|
|
95875
95940
|
version: cappedText(provider.version, VERSION_MAX_LENGTH),
|
|
95876
|
-
binaryPath: cappedText(provider.auth.provenance?.binaryPath, BINARY_PATH_MAX_LENGTH)
|
|
95941
|
+
binaryPath: cappedText(provider.auth.provenance?.binaryPath, BINARY_PATH_MAX_LENGTH),
|
|
95942
|
+
...claudeCredentialAnswersToPublish(provider)
|
|
95877
95943
|
};
|
|
95878
95944
|
}
|
|
95879
95945
|
function serializeProviderCatalog(providers) {
|
|
@@ -95894,7 +95960,7 @@ const replicaTurnStatuses = new Set([
|
|
|
95894
95960
|
"cancelled",
|
|
95895
95961
|
"interrupted"
|
|
95896
95962
|
]);
|
|
95897
|
-
function isRecord$
|
|
95963
|
+
function isRecord$17(value) {
|
|
95898
95964
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
95899
95965
|
}
|
|
95900
95966
|
function replicaSourceSequence(value) {
|
|
@@ -95907,7 +95973,7 @@ function replicaSourceTurn(sourceTurnId) {
|
|
|
95907
95973
|
return typeof sourceTurnId === "string" && sourceTurnId.length > 0 ? { turnId: sourceTurnId } : {};
|
|
95908
95974
|
}
|
|
95909
95975
|
function replicaActivitySource(activity) {
|
|
95910
|
-
if (!activity.kind.startsWith("replica.") || !isRecord$
|
|
95976
|
+
if (!activity.kind.startsWith("replica.") || !isRecord$17(activity.payload)) return null;
|
|
95911
95977
|
const sourceSequence = replicaSourceSequence(activity.sequence);
|
|
95912
95978
|
const eventId = replicaSourceEventId(activity.payload.sourceEventId);
|
|
95913
95979
|
if (sourceSequence === null || eventId === null) return null;
|
|
@@ -95920,7 +95986,7 @@ function replicaActivitySource(activity) {
|
|
|
95920
95986
|
}
|
|
95921
95987
|
function replicaSummaryEvent(activity, source) {
|
|
95922
95988
|
if (activity.kind !== "replica.activity_summary" && activity.kind !== "replica.error_summary") return null;
|
|
95923
|
-
const sourceText = isRecord$
|
|
95989
|
+
const sourceText = isRecord$17(activity.payload) ? activity.payload.text : null;
|
|
95924
95990
|
return {
|
|
95925
95991
|
sourceSequence: source.sourceSequence,
|
|
95926
95992
|
event: {
|
|
@@ -95933,7 +95999,7 @@ function replicaSummaryEvent(activity, source) {
|
|
|
95933
95999
|
};
|
|
95934
96000
|
}
|
|
95935
96001
|
function replicaTurnEvent(activity, source) {
|
|
95936
|
-
const status = isRecord$
|
|
96002
|
+
const status = isRecord$17(activity.payload) ? activity.payload.status : null;
|
|
95937
96003
|
if (activity.kind !== "replica.turn_status" || !replicaTurnStatuses.has(status)) return null;
|
|
95938
96004
|
return {
|
|
95939
96005
|
sourceSequence: source.sourceSequence,
|
|
@@ -95947,7 +96013,7 @@ function replicaTurnEvent(activity, source) {
|
|
|
95947
96013
|
};
|
|
95948
96014
|
}
|
|
95949
96015
|
function replicaToolCallEvent(activity, source) {
|
|
95950
|
-
if (activity.kind !== "replica.tool_call" || !isRecord$
|
|
96016
|
+
if (activity.kind !== "replica.tool_call" || !isRecord$17(activity.payload)) return null;
|
|
95951
96017
|
const sourceText = activity.payload.text;
|
|
95952
96018
|
const status = activity.payload.status;
|
|
95953
96019
|
if (typeof sourceText !== "string" || typeof status !== "string") return null;
|
|
@@ -95965,9 +96031,9 @@ function replicaToolCallEvent(activity, source) {
|
|
|
95965
96031
|
};
|
|
95966
96032
|
}
|
|
95967
96033
|
function replicaTurnUsageEvent(activity, source) {
|
|
95968
|
-
if (activity.kind !== "replica.turn_usage" || !isRecord$
|
|
96034
|
+
if (activity.kind !== "replica.turn_usage" || !isRecord$17(activity.payload)) return null;
|
|
95969
96035
|
const usage = activity.payload.payload;
|
|
95970
|
-
if (!("turnId" in source.turn) || !isRecord$
|
|
96036
|
+
if (!("turnId" in source.turn) || !isRecord$17(usage)) return null;
|
|
95971
96037
|
const provider = usage.provider;
|
|
95972
96038
|
const model = usage.model;
|
|
95973
96039
|
if (typeof provider !== "string" || typeof model !== "string" || !("usage" in usage)) return null;
|
|
@@ -96019,6 +96085,10 @@ function threadStatus(thread) {
|
|
|
96019
96085
|
if (thread.latestTurn) return "running";
|
|
96020
96086
|
return "active";
|
|
96021
96087
|
}
|
|
96088
|
+
function threadProviderAccountId(thread) {
|
|
96089
|
+
const selection = thread.modelSelection;
|
|
96090
|
+
return selection && "providerAccountId" in selection ? selection.providerAccountId ?? null : null;
|
|
96091
|
+
}
|
|
96022
96092
|
function serializeRuntimeInventory(snapshot, providerInventory) {
|
|
96023
96093
|
const activeProjects = snapshot.projects.filter((project) => project.availability !== "missing");
|
|
96024
96094
|
const projectIds = new Set(activeProjects.map((project) => project.id));
|
|
@@ -96049,6 +96119,7 @@ function serializeRuntimeInventory(snapshot, providerInventory) {
|
|
|
96049
96119
|
status: threadStatus(thread),
|
|
96050
96120
|
model: thread.modelSelection?.model ?? null,
|
|
96051
96121
|
provider: thread.modelSelection?.provider ?? null,
|
|
96122
|
+
providerAccountId: threadProviderAccountId(thread),
|
|
96052
96123
|
branch: thread.branch,
|
|
96053
96124
|
lastActivityAt: thread.latestUserMessageAt ?? thread.updatedAt,
|
|
96054
96125
|
kind: thread.kind,
|
|
@@ -96775,9 +96846,9 @@ function isUsageSessionLookupRuntimeNotFound(error) {
|
|
|
96775
96846
|
async function isRuntimeNotFoundResponse(response) {
|
|
96776
96847
|
if (response.status !== 404) return false;
|
|
96777
96848
|
const body = await response.json().catch(() => null);
|
|
96778
|
-
return isRecord$
|
|
96849
|
+
return isRecord$16(body) && body["code"] === "RUNTIME_NOT_FOUND";
|
|
96779
96850
|
}
|
|
96780
|
-
function isRecord$
|
|
96851
|
+
function isRecord$16(value) {
|
|
96781
96852
|
return typeof value === "object" && value !== null;
|
|
96782
96853
|
}
|
|
96783
96854
|
/**
|
|
@@ -96789,11 +96860,11 @@ function isRecord$15(value) {
|
|
|
96789
96860
|
* no count on the page saying so.
|
|
96790
96861
|
*/
|
|
96791
96862
|
function decodeHeldSessions(body) {
|
|
96792
|
-
const held = isRecord$
|
|
96863
|
+
const held = isRecord$16(body) && isRecord$16(body["data"]) ? body["data"]["held"] : void 0;
|
|
96793
96864
|
if (!Array.isArray(held)) throw new Error("The usage session lookup returned an invalid body.");
|
|
96794
96865
|
return held.map((row) => {
|
|
96795
|
-
const providerSessionId = isRecord$
|
|
96796
|
-
const runtimeId = isRecord$
|
|
96866
|
+
const providerSessionId = isRecord$16(row) ? row["providerSessionId"] : void 0;
|
|
96867
|
+
const runtimeId = isRecord$16(row) ? row["runtimeId"] : void 0;
|
|
96797
96868
|
if (typeof providerSessionId !== "string" || typeof runtimeId !== "string") throw new Error("The usage session lookup returned an invalid held row.");
|
|
96798
96869
|
return {
|
|
96799
96870
|
providerSessionId,
|
|
@@ -99286,7 +99357,7 @@ var BrowserManager = class extends require_Schema$1.Service()("forge/browser/Ser
|
|
|
99286
99357
|
const DEFAULT_PORT_MIN = 5200;
|
|
99287
99358
|
const DEFAULT_PORT_MAX = 5999;
|
|
99288
99359
|
var ThreadDevRuntime = class extends require_Schema$1.Service()("forge/threadDevRuntime/ThreadDevRuntime") {};
|
|
99289
|
-
function nowIso$
|
|
99360
|
+
function nowIso$5() {
|
|
99290
99361
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
99291
99362
|
}
|
|
99292
99363
|
function previewUrlForPort(port) {
|
|
@@ -99313,7 +99384,7 @@ const ThreadDevRuntimeLive = require_Schema$1.effect(ThreadDevRuntime, require_S
|
|
|
99313
99384
|
allocatedPort: port,
|
|
99314
99385
|
status: "allocated",
|
|
99315
99386
|
previewUrl: previewUrlForPort(port),
|
|
99316
|
-
updatedAt: nowIso$
|
|
99387
|
+
updatedAt: nowIso$5()
|
|
99317
99388
|
};
|
|
99318
99389
|
yield* require_HttpServer.update(byThreadId, (current) => {
|
|
99319
99390
|
const next = new Map(current);
|
|
@@ -99335,7 +99406,7 @@ const ThreadDevRuntimeLive = require_Schema$1.effect(ThreadDevRuntime, require_S
|
|
|
99335
99406
|
next.set(input.threadId, {
|
|
99336
99407
|
...existing,
|
|
99337
99408
|
status: "released",
|
|
99338
|
-
updatedAt: nowIso$
|
|
99409
|
+
updatedAt: nowIso$5()
|
|
99339
99410
|
});
|
|
99340
99411
|
return next;
|
|
99341
99412
|
});
|
|
@@ -99361,7 +99432,7 @@ const ThreadDevRuntimeLive = require_Schema$1.effect(ThreadDevRuntime, require_S
|
|
|
99361
99432
|
...patch.terminalId !== void 0 ? { terminalId: patch.terminalId } : {},
|
|
99362
99433
|
...patch.previewUrl !== void 0 ? { previewUrl: patch.previewUrl } : {},
|
|
99363
99434
|
...patch.tunnelId !== void 0 ? { tunnelId: patch.tunnelId } : {},
|
|
99364
|
-
updatedAt: nowIso$
|
|
99435
|
+
updatedAt: nowIso$5()
|
|
99365
99436
|
};
|
|
99366
99437
|
yield* require_HttpServer.update(byThreadId, (current) => {
|
|
99367
99438
|
const next = new Map(current);
|
|
@@ -99589,7 +99660,7 @@ function emptyConfig(source, path) {
|
|
|
99589
99660
|
issues: []
|
|
99590
99661
|
};
|
|
99591
99662
|
}
|
|
99592
|
-
function isRecord$
|
|
99663
|
+
function isRecord$15(value) {
|
|
99593
99664
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
99594
99665
|
}
|
|
99595
99666
|
function stringArray(value) {
|
|
@@ -99617,7 +99688,7 @@ function terminalsFromValue(value) {
|
|
|
99617
99688
|
name: `Terminal ${index + 1}`,
|
|
99618
99689
|
command: terminal.trim()
|
|
99619
99690
|
}];
|
|
99620
|
-
if (!isRecord$
|
|
99691
|
+
if (!isRecord$15(terminal)) return [];
|
|
99621
99692
|
const command = typeof terminal.command === "string" ? terminal.command.trim() : "";
|
|
99622
99693
|
if (!command) return [];
|
|
99623
99694
|
return [{
|
|
@@ -99656,7 +99727,7 @@ function readConfigFile(source, path) {
|
|
|
99656
99727
|
}]
|
|
99657
99728
|
};
|
|
99658
99729
|
}
|
|
99659
|
-
if (!isRecord$
|
|
99730
|
+
if (!isRecord$15(parsed)) return {
|
|
99660
99731
|
...emptyConfig(source, path),
|
|
99661
99732
|
issues: [{
|
|
99662
99733
|
severity: "blocked",
|
|
@@ -100799,7 +100870,7 @@ const CLAUDE_IDENTITY_KEYS = new Set([
|
|
|
100799
100870
|
"credentialGenerationId"
|
|
100800
100871
|
]);
|
|
100801
100872
|
const CLAUDE_IDENTITY_OPTIONAL_KEYS = new Set(["providerAccountIdentity"]);
|
|
100802
|
-
function isRecord$
|
|
100873
|
+
function isRecord$14(value) {
|
|
100803
100874
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
100804
100875
|
}
|
|
100805
100876
|
function isStrictRfc3339DateTime(value) {
|
|
@@ -100828,7 +100899,7 @@ function hasAllowedKeys(value, required, optional) {
|
|
|
100828
100899
|
return keys.every((key) => required.has(key) || optional.has(key)) && [...required].every((key) => keys.includes(key));
|
|
100829
100900
|
}
|
|
100830
100901
|
function parseDeliveryIdentity(value, provider) {
|
|
100831
|
-
if (!isRecord$
|
|
100902
|
+
if (!isRecord$14(value)) return null;
|
|
100832
100903
|
if (provider === "openai") return parseCodexDeliveryIdentity(value);
|
|
100833
100904
|
if (provider === "anthropic") return parseClaudeDeliveryIdentity(value);
|
|
100834
100905
|
return null;
|
|
@@ -100863,7 +100934,7 @@ function parseClaudeDeliveryIdentity(value) {
|
|
|
100863
100934
|
};
|
|
100864
100935
|
}
|
|
100865
100936
|
function parseProviderRuntimeDeliveryReceipt(value, expected) {
|
|
100866
|
-
if (!isRecord$
|
|
100937
|
+
if (!isRecord$14(value) || !hasExactKeys$2(value, RECEIPT_KEYS)) return null;
|
|
100867
100938
|
const identity = parseDeliveryIdentity(value.identity, expected.provider);
|
|
100868
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;
|
|
100869
100940
|
return {
|
|
@@ -100885,8 +100956,8 @@ function providerDeliveryBindingFromReceipt(receipt) {
|
|
|
100885
100956
|
};
|
|
100886
100957
|
}
|
|
100887
100958
|
function readProviderDeliveryBinding(value) {
|
|
100888
|
-
if (!isRecord$
|
|
100889
|
-
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;
|
|
100890
100961
|
const tokenProvider = identityProvider === "codex" ? "openai" : identityProvider === "claude" ? "anthropic" : null;
|
|
100891
100962
|
if (!tokenProvider) return null;
|
|
100892
100963
|
const identity = parseDeliveryIdentity(value.identity, tokenProvider);
|
|
@@ -148170,12 +148241,12 @@ function decodeProviderKind(providerName, operation) {
|
|
|
148170
148241
|
detail: `Unknown persisted provider '${providerName}'.`
|
|
148171
148242
|
}));
|
|
148172
148243
|
}
|
|
148173
|
-
function isRecord$
|
|
148244
|
+
function isRecord$13(value) {
|
|
148174
148245
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
148175
148246
|
}
|
|
148176
148247
|
function mergeRuntimePayload(existing, next) {
|
|
148177
148248
|
if (next === void 0) return existing ?? null;
|
|
148178
|
-
if (isRecord$
|
|
148249
|
+
if (isRecord$13(existing) && isRecord$13(next)) return {
|
|
148179
148250
|
...existing,
|
|
148180
148251
|
...next
|
|
148181
148252
|
};
|
|
@@ -150147,7 +150218,7 @@ const PAGINATION_KEYS = new Set([
|
|
|
150147
150218
|
"total",
|
|
150148
150219
|
"hasMore"
|
|
150149
150220
|
]);
|
|
150150
|
-
function isRecord$
|
|
150221
|
+
function isRecord$12(value) {
|
|
150151
150222
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
150152
150223
|
}
|
|
150153
150224
|
function hasOnlyKeys(value, allowed) {
|
|
@@ -150160,17 +150231,17 @@ function isRfc3339(value) {
|
|
|
150160
150231
|
return typeof value === "string" && RFC3339.test(value) && Number.isFinite(Date.parse(value));
|
|
150161
150232
|
}
|
|
150162
150233
|
function isEnvelopeMeta(value) {
|
|
150163
|
-
if (!isRecord$
|
|
150234
|
+
if (!isRecord$12(value) || !hasExactKeys$1(value, META_KEYS)) return false;
|
|
150164
150235
|
return typeof value.domain === "string" && value.domain.length > 0 && isRfc3339(value.timestamp) && typeof value.version === "string" && value.version.length > 0;
|
|
150165
150236
|
}
|
|
150166
150237
|
function isPagination(value) {
|
|
150167
|
-
if (!isRecord$
|
|
150238
|
+
if (!isRecord$12(value) || !hasExactKeys$1(value, PAGINATION_KEYS)) return false;
|
|
150168
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";
|
|
150169
150240
|
}
|
|
150170
150241
|
function readLocalProviderAccountId(authJson) {
|
|
150171
150242
|
try {
|
|
150172
150243
|
const value = JSON.parse(authJson);
|
|
150173
|
-
if (!isRecord$
|
|
150244
|
+
if (!isRecord$12(value) || value.auth_mode !== "chatgpt" || !isRecord$12(value.tokens)) return null;
|
|
150174
150245
|
const providerAccountId = value.tokens.account_id;
|
|
150175
150246
|
if (typeof providerAccountId !== "string") return null;
|
|
150176
150247
|
const normalized = providerAccountId.trim();
|
|
@@ -150183,13 +150254,13 @@ function resolveLocalAuthJsonPath(homePath) {
|
|
|
150183
150254
|
return (0, node_path.join)(homePath?.trim() || process.env.CODEX_HOME?.trim() || (0, node_path.join)((0, node_os.homedir)(), ".codex"), "auth.json");
|
|
150184
150255
|
}
|
|
150185
150256
|
function parseCodexAccountIdentityEnvelope(value) {
|
|
150186
|
-
if (!isRecord$
|
|
150257
|
+
if (!isRecord$12(value) || !hasOnlyKeys(value, ENVELOPE_KEYS)) return null;
|
|
150187
150258
|
if (!("data" in value) || !("meta" in value) || !isEnvelopeMeta(value.meta)) return null;
|
|
150188
150259
|
if (value.pagination !== void 0 && !isPagination(value.pagination)) return null;
|
|
150189
150260
|
return readCodexAccountIdentity(value.data);
|
|
150190
150261
|
}
|
|
150191
150262
|
function readCodexAccountIdentity(value) {
|
|
150192
|
-
if (!isRecord$
|
|
150263
|
+
if (!isRecord$12(value) || !hasExactKeys$1(value, IDENTITY_KEYS)) return null;
|
|
150193
150264
|
if (value.kind !== "provider_account" || value.provider !== "codex" || typeof value.providerAccountIdentity !== "string" || !PROVIDER_ACCOUNT_IDENTITY$1.test(value.providerAccountIdentity)) return null;
|
|
150194
150265
|
return {
|
|
150195
150266
|
kind: "provider_account",
|
|
@@ -210973,6 +211044,11 @@ const PUBLIC_PROVIDER_LEAK_PATTERNS = [
|
|
|
210973
211044
|
/https?:\/\/[^\s'"<>)]*(?:apex|deepseek|moonshot|kimi)[^\s'"<>)]*/i
|
|
210974
211045
|
];
|
|
210975
211046
|
const DEFAULT_PUBLIC_PROVIDER_ERROR = "CMMD is temporarily unavailable. Check the workspace AI connection and retry.";
|
|
211047
|
+
function isProviderRateOrQuotaError(message) {
|
|
211048
|
+
if (!message) return false;
|
|
211049
|
+
const normalized = message.toLowerCase();
|
|
211050
|
+
return /\b(rate[\s-]?limit|too\s+many\s+requests|usage[ _-]limit|usage_limit_reached|quota|insufficient_quota)\b/.test(normalized) || /\b429\b/.test(normalized);
|
|
211051
|
+
}
|
|
210976
211052
|
/**
|
|
210977
211053
|
* Infer a SAFE, clearer failure category from a (possibly leaky) provider error.
|
|
210978
211054
|
*
|
|
@@ -210988,7 +211064,7 @@ function categorizePublicProviderError(message) {
|
|
|
210988
211064
|
if (/\bforge_runtime_stopped\b/.test(m) || /\bthis turn was interrupted because the environment was stopped\b/.test(m)) return "This turn was interrupted because the environment was stopped. Start the environment and retry.";
|
|
210989
211065
|
if (/\bforge_provider_model_not_allowed\b/.test(m) || /\bnot\s+scoped\s+to\s+the\s+requested\s+model\b/.test(m)) return "The workspace AI credential does not cover the model this turn asked for. Retry, or pick that model for the thread.";
|
|
210990
211066
|
if (/\bmodel\b[\s\S]*\b(not\s+(found|available|supported)|does\s+not\s+exist|unsupported|invalid|unknown)\b/.test(m) || /\b(unsupported|unknown|invalid)\b[\s\S]*\bmodel\b/.test(m) || /\b(model_not_found|invalid_model|model_not_supported)\b/.test(m)) return "The selected model isn't available right now. Pick a different model and retry.";
|
|
210991
|
-
if (
|
|
211067
|
+
if (isProviderRateOrQuotaError(m)) return "The AI service is rate-limited or out of quota. Wait a moment and retry.";
|
|
210992
211068
|
if (/\b(unauthorized|forbidden|authentication\s+(failed|error|required)|invalid\s+api\s+key|expired\s+(token|credential))\b/.test(m) || /\b40[13]\b/.test(m)) return "Workspace AI authentication failed. Reconnect the workspace and retry.";
|
|
210993
211069
|
if (/\b(timed?\s*out|timeout|overloaded|service\s+unavailable)\b/.test(m) || /\b50[234]\b/.test(m)) return "The AI service is temporarily overloaded. Retry in a moment.";
|
|
210994
211070
|
return null;
|
|
@@ -211369,10 +211445,16 @@ function claudeSubscriptionChildEnv(processEnv, credentialDirectory) {
|
|
|
211369
211445
|
* environment with `claudeSubscriptionChildEnv`, the same builder as the turn's
|
|
211370
211446
|
* personal-subscription branch.
|
|
211371
211447
|
*
|
|
211372
|
-
* `claude auth status`
|
|
211373
|
-
*
|
|
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`).
|
|
211374
211453
|
* It prints JSON on stdout and exits 1 when logged out, so the exit code is not
|
|
211375
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.
|
|
211376
211458
|
*/
|
|
211377
211459
|
const execFileAsync$3 = (0, node_util.promisify)(node_child_process.execFile);
|
|
211378
211460
|
const AUTH_STATUS_ARGS = ["auth", "status"];
|
|
@@ -211389,8 +211471,7 @@ const PROBE_DIRECTORY_PREFIX = "forge-claude-capability-";
|
|
|
211389
211471
|
const VERSION_PATTERN = /\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?/;
|
|
211390
211472
|
function makeClaudeCredentialDirectoryProbe(deps) {
|
|
211391
211473
|
const answers = /* @__PURE__ */ new Map();
|
|
211392
|
-
const
|
|
211393
|
-
const version = await readVersionSafely(deps);
|
|
211474
|
+
const answerFor = (version) => {
|
|
211394
211475
|
if (version === null) return runProbe(deps);
|
|
211395
211476
|
const cached = answers.get(version);
|
|
211396
211477
|
if (cached) return cached;
|
|
@@ -211401,10 +211482,47 @@ function makeClaudeCredentialDirectoryProbe(deps) {
|
|
|
211401
211482
|
};
|
|
211402
211483
|
pending.then((result) => {
|
|
211403
211484
|
if (result === "inconclusive") forget();
|
|
211404
|
-
|
|
211485
|
+
deps.onAnswer?.(version, result);
|
|
211486
|
+
}, () => {
|
|
211487
|
+
forget();
|
|
211488
|
+
deps.onAnswer?.(version, "inconclusive");
|
|
211489
|
+
});
|
|
211405
211490
|
return pending;
|
|
211406
211491
|
};
|
|
211407
|
-
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;
|
|
211408
211526
|
}
|
|
211409
211527
|
/**
|
|
211410
211528
|
* One probe per binary path for the life of the process. A conclusive answer is
|
|
@@ -211429,7 +211547,12 @@ function claudeCredentialDirectoryProbeFor(binaryPath) {
|
|
|
211429
211547
|
if (!binaryPath) return INCONCLUSIVE_PROBE;
|
|
211430
211548
|
const existing = probesByBinaryPath.get(binaryPath);
|
|
211431
211549
|
if (existing) return existing;
|
|
211432
|
-
const probe = makeClaudeCredentialDirectoryProbe(
|
|
211550
|
+
const probe = makeClaudeCredentialDirectoryProbe({
|
|
211551
|
+
...claudeCredentialDirectoryProbeDeps(binaryPath),
|
|
211552
|
+
onAnswer: (version, answer) => {
|
|
211553
|
+
claudeCredentialDirectoryAnswers.record(binaryPath, version, answer);
|
|
211554
|
+
}
|
|
211555
|
+
});
|
|
211433
211556
|
probesByBinaryPath.set(binaryPath, probe);
|
|
211434
211557
|
return probe;
|
|
211435
211558
|
}
|
|
@@ -211440,7 +211563,7 @@ function claudeCredentialDirectoryProbeDeps(binaryPath, options = {}) {
|
|
|
211440
211563
|
runAuthStatus: ({ credentialDirectory }) => run(AUTH_STATUS_ARGS, credentialDirectory),
|
|
211441
211564
|
readBinaryVersion: async () => {
|
|
211442
211565
|
const { stdout } = await run(VERSION_ARGS, null);
|
|
211443
|
-
return
|
|
211566
|
+
return claudeVersionFromOutput(stdout);
|
|
211444
211567
|
},
|
|
211445
211568
|
makeProbeDirectory: () => (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), PROBE_DIRECTORY_PREFIX)),
|
|
211446
211569
|
removeProbeDirectory: (directory) => (0, node_fs_promises.rm)(directory, {
|
|
@@ -211609,6 +211732,171 @@ const makeProviderAuthProvenance = (input) => {
|
|
|
211609
211732
|
};
|
|
211610
211733
|
};
|
|
211611
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
|
|
211612
211900
|
//#region src/provider/Layers/ClaudeProvider.ts
|
|
211613
211901
|
function endpointProfileDisplayNames(settings) {
|
|
211614
211902
|
return Object.fromEntries(settings.endpointProfiles.filter((p) => p.displayName).map((p) => [p.slug, p.displayName]));
|
|
@@ -212110,7 +212398,21 @@ const nativeClaudeProviderStatus = require_Schema$1.fn("nativeClaudeProviderStat
|
|
|
212110
212398
|
}
|
|
212111
212399
|
});
|
|
212112
212400
|
});
|
|
212113
|
-
|
|
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;
|
|
212114
212416
|
const config = require_Schema$1.getOrElse(yield* require_Schema$1.serviceOption(ServerConfig), () => ({
|
|
212115
212417
|
...DEFAULT_PROVIDER_AUTH_CONFIG,
|
|
212116
212418
|
forgeClaudeConfigPath: void 0
|
|
@@ -212182,19 +212484,24 @@ const checkClaudeProviderStatus = require_Schema$1.fn("checkClaudeProviderStatus
|
|
|
212182
212484
|
});
|
|
212183
212485
|
}
|
|
212184
212486
|
const executableFallbackModels = modelsForClaudeCliVersion(fallbackModels, parsedVersion);
|
|
212185
|
-
|
|
212487
|
+
const credentialAnswersInput = {
|
|
212488
|
+
binaryPath: claudeSettings.binaryPath,
|
|
212489
|
+
version: claudeVersionFromOutput(version.stdout),
|
|
212490
|
+
configDirectory: effectiveConfigPath
|
|
212491
|
+
};
|
|
212492
|
+
if (personalClaudeInVmEnabled()) return yield* withClaudeCredentialAnswers(yield* nativeClaudeProviderStatus({
|
|
212186
212493
|
enabled: claudeSettings.enabled,
|
|
212187
212494
|
checkedAt,
|
|
212188
212495
|
version: parsedVersion,
|
|
212189
212496
|
configPath: effectiveConfigPath,
|
|
212190
212497
|
models: executableFallbackModels,
|
|
212191
212498
|
provenance
|
|
212192
|
-
});
|
|
212499
|
+
}), resolveCredentialAnswers, credentialAnswersInput);
|
|
212193
212500
|
const capabilitiesProbeInput = claudeCapabilitiesProbeInput(claudeSettings.binaryPath, effectiveConfigPath);
|
|
212194
212501
|
const discovery = yield* resolveClaudeDiscovery(capabilitiesProbeInput, resolveSlashCommands, resolveModels);
|
|
212195
212502
|
const models = modelsForClaudeCliVersion(providerModelsFromSettings(resolveClaudeProviderModels(discovery.models), PROVIDER$12, claudeSettings.customModels, DEFAULT_CLAUDE_MODEL_CAPABILITIES, endpointProfileDisplayNames(claudeSettings)), parsedVersion);
|
|
212196
212503
|
const authProbe = yield* runClaudeCommand(["auth", "status"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$3), require_Schema$1.result);
|
|
212197
|
-
return buildClaudeProviderFromAuthProbe({
|
|
212504
|
+
return yield* withClaudeCredentialAnswers(buildClaudeProviderFromAuthProbe({
|
|
212198
212505
|
authProbe,
|
|
212199
212506
|
authMetadata: yield* resolveClaudeAuthMetadata(authProbe, capabilitiesProbeInput, resolveSubscriptionType),
|
|
212200
212507
|
checkedAt,
|
|
@@ -212203,7 +212510,7 @@ const checkClaudeProviderStatus = require_Schema$1.fn("checkClaudeProviderStatus
|
|
|
212203
212510
|
slashCommands: discovery.slashCommands,
|
|
212204
212511
|
parsedVersion,
|
|
212205
212512
|
provenance
|
|
212206
|
-
});
|
|
212513
|
+
}), resolveCredentialAnswers, credentialAnswersInput);
|
|
212207
212514
|
});
|
|
212208
212515
|
const makePendingClaudeProvider = (claudeSettings) => {
|
|
212209
212516
|
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -212235,30 +212542,76 @@ const makePendingClaudeProvider = (claudeSettings) => {
|
|
|
212235
212542
|
}
|
|
212236
212543
|
});
|
|
212237
212544
|
};
|
|
212238
|
-
|
|
212239
|
-
|
|
212240
|
-
|
|
212241
|
-
|
|
212242
|
-
|
|
212243
|
-
|
|
212244
|
-
|
|
212245
|
-
|
|
212246
|
-
|
|
212247
|
-
|
|
212248
|
-
|
|
212249
|
-
|
|
212250
|
-
|
|
212251
|
-
|
|
212252
|
-
|
|
212253
|
-
|
|
212254
|
-
|
|
212255
|
-
|
|
212256
|
-
|
|
212257
|
-
|
|
212258
|
-
|
|
212259
|
-
|
|
212260
|
-
});
|
|
212261
|
-
}));
|
|
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();
|
|
212262
212615
|
//#endregion
|
|
212263
212616
|
//#region src/provider/Services/ClaudeAdapter.ts
|
|
212264
212617
|
/**
|
|
@@ -228638,7 +228991,7 @@ const OpenCodeRuntimeLive = require_Schema$1.effect(OpenCodeRuntime, makeOpenCod
|
|
|
228638
228991
|
//#endregion
|
|
228639
228992
|
//#region src/provider/Layers/OpenCodeAdapter.ts
|
|
228640
228993
|
const PROVIDER$5 = "opencode";
|
|
228641
|
-
const nowIso$
|
|
228994
|
+
const nowIso$4 = require_Schema$1.map(require_Schema$1.now, require_Schema$1.formatIso);
|
|
228642
228995
|
/**
|
|
228643
228996
|
* Map a tagged OpenCodeRuntimeError produced by {@link runOpenCodeSdk} into
|
|
228644
228997
|
* the adapter-boundary `ProviderAdapterRequestError`. SDK-method-level call
|
|
@@ -228665,7 +229018,7 @@ const toProcessError = (threadId, cause) => new ProviderAdapterProcessError({
|
|
|
228665
229018
|
});
|
|
228666
229019
|
const buildEventBase = (input) => require_Schema$1.gen(function* () {
|
|
228667
229020
|
const uuid = yield* nextUUIDv4;
|
|
228668
|
-
const createdAt = input.createdAt ?? (yield* nowIso$
|
|
229021
|
+
const createdAt = input.createdAt ?? (yield* nowIso$4);
|
|
228669
229022
|
return {
|
|
228670
229023
|
eventId: EventId.make(uuid),
|
|
228671
229024
|
provider: PROVIDER$5,
|
|
@@ -228824,7 +229177,7 @@ function sessionErrorMessage(error) {
|
|
|
228824
229177
|
}
|
|
228825
229178
|
function updateProviderSession(context, patch, options) {
|
|
228826
229179
|
return require_Schema$1.gen(function* () {
|
|
228827
|
-
const updatedAt = yield* nowIso$
|
|
229180
|
+
const updatedAt = yield* nowIso$4;
|
|
228828
229181
|
const nextSession = {
|
|
228829
229182
|
...context.session,
|
|
228830
229183
|
...patch,
|
|
@@ -228946,7 +229299,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
228946
229299
|
if (("properties" in event ? event.properties.sessionID : void 0) !== context.openCodeSessionId) return;
|
|
228947
229300
|
const turnId = context.activeTurnId;
|
|
228948
229301
|
yield* writeNativeEventBestEffort(context.session.threadId, {
|
|
228949
|
-
observedAt: yield* nowIso$
|
|
229302
|
+
observedAt: yield* nowIso$4,
|
|
228950
229303
|
event: {
|
|
228951
229304
|
provider: PROVIDER$5,
|
|
228952
229305
|
threadId: context.session.threadId,
|
|
@@ -229262,7 +229615,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
|
|
|
229262
229615
|
yield* require_Schema$1.close(started.sessionScope, require_Schema$1.void_$1).pipe(require_Schema$1.ignore);
|
|
229263
229616
|
return raceWinner.session;
|
|
229264
229617
|
}
|
|
229265
|
-
const createdAt = yield* nowIso$
|
|
229618
|
+
const createdAt = yield* nowIso$4;
|
|
229266
229619
|
const session = {
|
|
229267
229620
|
provider: PROVIDER$5,
|
|
229268
229621
|
status: "ready",
|
|
@@ -236061,7 +236414,7 @@ function filterEvents(events, options) {
|
|
|
236061
236414
|
});
|
|
236062
236415
|
return options.limit === void 0 ? filtered : filtered.slice(-options.limit);
|
|
236063
236416
|
}
|
|
236064
|
-
function nowIso$
|
|
236417
|
+
function nowIso$3() {
|
|
236065
236418
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
236066
236419
|
}
|
|
236067
236420
|
//#endregion
|
|
@@ -236076,7 +236429,7 @@ var BrowserActionEventRecorder = class {
|
|
|
236076
236429
|
type: "browser.action",
|
|
236077
236430
|
action,
|
|
236078
236431
|
...this.sessionFields(),
|
|
236079
|
-
timestamp: nowIso$
|
|
236432
|
+
timestamp: nowIso$3()
|
|
236080
236433
|
});
|
|
236081
236434
|
}
|
|
236082
236435
|
async result(action) {
|
|
@@ -236085,7 +236438,7 @@ var BrowserActionEventRecorder = class {
|
|
|
236085
236438
|
action,
|
|
236086
236439
|
ok: true,
|
|
236087
236440
|
...this.sessionFields(),
|
|
236088
|
-
timestamp: nowIso$
|
|
236441
|
+
timestamp: nowIso$3()
|
|
236089
236442
|
});
|
|
236090
236443
|
}
|
|
236091
236444
|
async error(action, error) {
|
|
@@ -236094,7 +236447,7 @@ var BrowserActionEventRecorder = class {
|
|
|
236094
236447
|
action,
|
|
236095
236448
|
error: error instanceof Error ? error.message : String(error),
|
|
236096
236449
|
...this.sessionFields(),
|
|
236097
|
-
timestamp: nowIso$
|
|
236450
|
+
timestamp: nowIso$3()
|
|
236098
236451
|
});
|
|
236099
236452
|
}
|
|
236100
236453
|
sessionFields() {
|
|
@@ -236615,7 +236968,7 @@ var AgentBrowser = class {
|
|
|
236615
236968
|
await this.options.events?.record({
|
|
236616
236969
|
type: "browser.safety.confirmation.requested",
|
|
236617
236970
|
...request,
|
|
236618
|
-
createdAt: nowIso$
|
|
236971
|
+
createdAt: nowIso$3()
|
|
236619
236972
|
});
|
|
236620
236973
|
const result = await this.resolveConfirmation(request);
|
|
236621
236974
|
const approved = typeof result === "boolean" ? result : result.approved;
|
|
@@ -236623,7 +236976,7 @@ var AgentBrowser = class {
|
|
|
236623
236976
|
type: "browser.safety.confirmation.resolved",
|
|
236624
236977
|
approved,
|
|
236625
236978
|
requestId: request.requestId,
|
|
236626
|
-
resolvedAt: nowIso$
|
|
236979
|
+
resolvedAt: nowIso$3(),
|
|
236627
236980
|
...this.events.sessionFields()
|
|
236628
236981
|
});
|
|
236629
236982
|
if (!approved) throw new BrowserSafetyError(decision.reason ?? "Browser action was not confirmed.", action, {
|
|
@@ -281978,7 +282331,7 @@ const DEFAULT_AGENT_BROWSER_BRIDGE_CLOSE_TIMEOUT_MS = 3e4;
|
|
|
281978
282331
|
const DEFAULT_AGENT_BROWSER_PLAYWRIGHT_BACKEND_CLOSE_TIMEOUT_MS = 1e4;
|
|
281979
282332
|
const REMOTE_WEBRTC_UNAVAILABLE_DETAIL = "Remote WebRTC browser display is not available: the current Agent Browser runtime exposes tab control but does not provide a media transport.";
|
|
281980
282333
|
const REMOTE_WEBRTC_RELAY_REQUIRED_DETAIL = "Remote WebRTC browser display requires a TURN relay in cloud mode. Configure FORGE_BROWSER_WEBRTC_ICE_SERVERS with authenticated turn: or turns: URLs.";
|
|
281981
|
-
function nowIso$
|
|
282334
|
+
function nowIso$2() {
|
|
281982
282335
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
281983
282336
|
}
|
|
281984
282337
|
function positiveTimeoutMs(value) {
|
|
@@ -282078,12 +282431,12 @@ function snapshotAfterTimedOutControl(snapshot, command) {
|
|
|
282078
282431
|
case "setViewport": return {
|
|
282079
282432
|
...snapshot,
|
|
282080
282433
|
viewport: command.viewport,
|
|
282081
|
-
updatedAt: nowIso$
|
|
282434
|
+
updatedAt: nowIso$2()
|
|
282082
282435
|
};
|
|
282083
282436
|
case "resetViewport": return {
|
|
282084
282437
|
...snapshot,
|
|
282085
282438
|
viewport: DEFAULT_AGENT_BROWSER_VIEWPORT,
|
|
282086
|
-
updatedAt: nowIso$
|
|
282439
|
+
updatedAt: nowIso$2()
|
|
282087
282440
|
};
|
|
282088
282441
|
default: return snapshot;
|
|
282089
282442
|
}
|
|
@@ -282529,7 +282882,7 @@ function toStreamEvent(input) {
|
|
|
282529
282882
|
userId: BrowserUserId.make(input.userId),
|
|
282530
282883
|
agentId: input.agentId,
|
|
282531
282884
|
...input.controlState ? { sessionEpoch: input.controlState.sessionEpoch } : {},
|
|
282532
|
-
createdAt: nowIso$
|
|
282885
|
+
createdAt: nowIso$2()
|
|
282533
282886
|
};
|
|
282534
282887
|
switch (input.event.type) {
|
|
282535
282888
|
case "session.started": return {
|
|
@@ -282830,7 +283183,7 @@ function createAgentBrowserHostBridgeManager(bridge, options) {
|
|
|
282830
283183
|
environmentId: event.input.environmentId ?? DEFAULT_BROWSER_ENVIRONMENT_ID,
|
|
282831
283184
|
userId: event.input.userId ?? "local-user",
|
|
282832
283185
|
agentId: null,
|
|
282833
|
-
createdAt: nowIso$
|
|
283186
|
+
createdAt: nowIso$2(),
|
|
282834
283187
|
type: "display.iceCandidate",
|
|
282835
283188
|
payload: {
|
|
282836
283189
|
sessionId: event.input.sessionId,
|
|
@@ -287499,46 +287852,6 @@ const makeRuntimeDrainState = require_Schema$1.gen(function* () {
|
|
|
287499
287852
|
var RuntimeDrainState = class extends require_Schema$1.Service()("forge/runtimeDrain/RuntimeDrainState") {};
|
|
287500
287853
|
const RuntimeDrainStateLive = require_Schema$1.effect(RuntimeDrainState, makeRuntimeDrainState);
|
|
287501
287854
|
//#endregion
|
|
287502
|
-
//#region src/runtimeDrain/supervisedRepeat.ts
|
|
287503
|
-
/**
|
|
287504
|
-
* Runs `work` on a fixed schedule, forever, and RESTARTS the schedule itself
|
|
287505
|
-
* if it ever dies for any reason other than this scope closing.
|
|
287506
|
-
*
|
|
287507
|
-
* `Effect.repeat(work, Schedule.spaced(interval)).pipe(Effect.forkScoped)`
|
|
287508
|
-
* alone has no restart path. `work` catching its own errors only protects
|
|
287509
|
-
* the TICK: an interrupt that lands while `Effect.repeat` is asleep between
|
|
287510
|
-
* ticks — which, at any non-trivial interval, is nearly this loop's entire
|
|
287511
|
-
* life — happens outside anything `work` wraps, and kills that one fiber
|
|
287512
|
-
* outright with nothing logged, because nothing was running to log from.
|
|
287513
|
-
* The process this runs in can otherwise be perfectly healthy while the
|
|
287514
|
-
* schedule is silently, permanently dead.
|
|
287515
|
-
*
|
|
287516
|
-
* This runs the schedule on its own child fiber, raced against an explicit
|
|
287517
|
-
* shutdown signal fired by a finalizer registered in this scope. Only that
|
|
287518
|
-
* signal stops the loop for good; any other death of the schedule fiber —
|
|
287519
|
-
* whatever causes it, defect or interrupt — logs and restarts it. `work`
|
|
287520
|
-
* itself must still handle its own EXPECTED failures (this only supervises
|
|
287521
|
-
* the schedule, and treats every death of it as unexpected).
|
|
287522
|
-
*/
|
|
287523
|
-
function runSupervisedRepeat(input) {
|
|
287524
|
-
return require_Schema$1.gen(function* () {
|
|
287525
|
-
const shutdownSignal = yield* require_Schema$1.make$4();
|
|
287526
|
-
yield* require_Schema$1.addFinalizer(() => require_Schema$1.succeed$2(shutdownSignal, void 0));
|
|
287527
|
-
let firstAttempt = true;
|
|
287528
|
-
while (true) {
|
|
287529
|
-
if (!firstAttempt) yield* require_Schema$1.sleep(input.interval);
|
|
287530
|
-
firstAttempt = false;
|
|
287531
|
-
const scheduleFiber = yield* require_Schema$1.forkChild(require_Schema$1.repeat(input.work, require_Schema$1.spaced(input.interval)));
|
|
287532
|
-
const outcome = yield* require_Schema$1.race(require_Path.await_(scheduleFiber), require_Schema$1._await(shutdownSignal).pipe(require_Schema$1.as("shutdown")));
|
|
287533
|
-
if (outcome === "shutdown") {
|
|
287534
|
-
yield* require_Path.interrupt(scheduleFiber);
|
|
287535
|
-
return;
|
|
287536
|
-
}
|
|
287537
|
-
yield* require_Schema$1.logError(`${input.label} died unexpectedly — restarting`, { cause: require_Schema$1.isFailure(outcome) ? require_Schema$1.pretty(outcome.cause) : "unknown exit" });
|
|
287538
|
-
}
|
|
287539
|
-
});
|
|
287540
|
-
}
|
|
287541
|
-
//#endregion
|
|
287542
287855
|
//#region src/runtimeDrain/RuntimeDrainReporter.ts
|
|
287543
287856
|
const HEARTBEAT_INTERVAL = require_Schema$1.seconds(30);
|
|
287544
287857
|
const HEARTBEAT_TICK_TIMEOUT = require_Schema$1.seconds(60);
|
|
@@ -294961,7 +295274,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
294961
295274
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
294962
295275
|
*/
|
|
294963
295276
|
function readBakedBuildCommit() {
|
|
294964
|
-
return "
|
|
295277
|
+
return "9243995fc67ca68aa610fabccbf48bba35a5ffd1";
|
|
294965
295278
|
}
|
|
294966
295279
|
async function resolveServerBuildCommit(input) {
|
|
294967
295280
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -298042,6 +298355,52 @@ function toProjectorDecodeError(eventType) {
|
|
|
298042
298355
|
});
|
|
298043
298356
|
}
|
|
298044
298357
|
//#endregion
|
|
298358
|
+
//#region src/orchestration/deciderEventBase.ts
|
|
298359
|
+
const nowIso$1 = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
298360
|
+
const defaultMetadata = {
|
|
298361
|
+
eventId: crypto.randomUUID(),
|
|
298362
|
+
aggregateKind: "thread",
|
|
298363
|
+
aggregateId: "",
|
|
298364
|
+
occurredAt: nowIso$1(),
|
|
298365
|
+
commandId: null,
|
|
298366
|
+
causationEventId: null,
|
|
298367
|
+
correlationId: null,
|
|
298368
|
+
metadata: {}
|
|
298369
|
+
};
|
|
298370
|
+
function withEventBase(input) {
|
|
298371
|
+
return {
|
|
298372
|
+
...defaultMetadata,
|
|
298373
|
+
eventId: crypto.randomUUID(),
|
|
298374
|
+
aggregateKind: input.aggregateKind,
|
|
298375
|
+
aggregateId: input.aggregateId,
|
|
298376
|
+
occurredAt: input.occurredAt,
|
|
298377
|
+
commandId: input.commandId,
|
|
298378
|
+
correlationId: input.commandId,
|
|
298379
|
+
metadata: input.metadata ?? {}
|
|
298380
|
+
};
|
|
298381
|
+
}
|
|
298382
|
+
//#endregion
|
|
298383
|
+
//#region src/orchestration/projectScriptMutation.ts
|
|
298384
|
+
function unchanged(a, b) {
|
|
298385
|
+
return a !== void 0 && a.id === b.id && a.name === b.name && a.command === b.command && a.icon === b.icon && a.runOnWorktreeCreate === b.runOnWorktreeCreate;
|
|
298386
|
+
}
|
|
298387
|
+
const applyProjectScriptMutation = require_Schema$1.fn("applyProjectScriptMutation")(function* (scripts, command) {
|
|
298388
|
+
const mutation = command.mutation;
|
|
298389
|
+
const id = mutation.kind === "add" ? mutation.script.id : mutation.expected.id;
|
|
298390
|
+
const existing = scripts.find((script) => script.id === id);
|
|
298391
|
+
if (mutation.kind === "add" ? existing !== void 0 : !unchanged(existing, mutation.expected)) return yield* new OrchestrationCommandInvariantError({
|
|
298392
|
+
commandType: command.type,
|
|
298393
|
+
detail: "This action changed in another window. Reopen it and try again."
|
|
298394
|
+
});
|
|
298395
|
+
if (mutation.kind === "add") return [...scripts, mutation.script];
|
|
298396
|
+
if (mutation.kind === "remove") return scripts.filter((script) => script.id !== id);
|
|
298397
|
+
if (mutation.script.id !== id) return yield* new OrchestrationCommandInvariantError({
|
|
298398
|
+
commandType: command.type,
|
|
298399
|
+
detail: "An action's ID cannot change during an update."
|
|
298400
|
+
});
|
|
298401
|
+
return scripts.map((script) => script.id === id ? mutation.script : script);
|
|
298402
|
+
});
|
|
298403
|
+
//#endregion
|
|
298045
298404
|
//#region src/orchestration/turnAccountSelection.ts
|
|
298046
298405
|
/** A per-turn account choice remains local to the thread and cannot change its provider. */
|
|
298047
298406
|
function turnAccountSelection(current, requested) {
|
|
@@ -298098,28 +298457,6 @@ function requireThreadAbsent(input) {
|
|
|
298098
298457
|
//#endregion
|
|
298099
298458
|
//#region src/orchestration/decider.ts
|
|
298100
298459
|
const nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
298101
|
-
const defaultMetadata = {
|
|
298102
|
-
eventId: crypto.randomUUID(),
|
|
298103
|
-
aggregateKind: "thread",
|
|
298104
|
-
aggregateId: "",
|
|
298105
|
-
occurredAt: nowIso(),
|
|
298106
|
-
commandId: null,
|
|
298107
|
-
causationEventId: null,
|
|
298108
|
-
correlationId: null,
|
|
298109
|
-
metadata: {}
|
|
298110
|
-
};
|
|
298111
|
-
function withEventBase(input) {
|
|
298112
|
-
return {
|
|
298113
|
-
...defaultMetadata,
|
|
298114
|
-
eventId: crypto.randomUUID(),
|
|
298115
|
-
aggregateKind: input.aggregateKind,
|
|
298116
|
-
aggregateId: input.aggregateId,
|
|
298117
|
-
occurredAt: input.occurredAt,
|
|
298118
|
-
commandId: input.commandId,
|
|
298119
|
-
correlationId: input.commandId,
|
|
298120
|
-
metadata: input.metadata ?? {}
|
|
298121
|
-
};
|
|
298122
|
-
}
|
|
298123
298460
|
function requireOrdinaryMessageId(commandType, messageId) {
|
|
298124
298461
|
return isReservedReplicaSourceMessageId(messageId) ? require_Schema$1.fail(new OrchestrationCommandInvariantError({
|
|
298125
298462
|
commandType,
|
|
@@ -298172,6 +298509,22 @@ const decideOrchestrationCommand = require_Schema$1.fn("decideOrchestrationComma
|
|
|
298172
298509
|
updatedAt: command.createdAt
|
|
298173
298510
|
}
|
|
298174
298511
|
};
|
|
298512
|
+
case "project.script.update": {
|
|
298513
|
+
const scripts = yield* applyProjectScriptMutation((yield* requireProject({
|
|
298514
|
+
readModel,
|
|
298515
|
+
command,
|
|
298516
|
+
projectId: command.projectId
|
|
298517
|
+
})).scripts, command);
|
|
298518
|
+
return yield* decideOrchestrationCommand({
|
|
298519
|
+
readModel,
|
|
298520
|
+
command: {
|
|
298521
|
+
type: "project.meta.update",
|
|
298522
|
+
commandId: command.commandId,
|
|
298523
|
+
projectId: command.projectId,
|
|
298524
|
+
scripts
|
|
298525
|
+
}
|
|
298526
|
+
});
|
|
298527
|
+
}
|
|
298175
298528
|
case "project.meta.update": {
|
|
298176
298529
|
yield* requireProject({
|
|
298177
298530
|
readModel,
|
|
@@ -299458,6 +299811,7 @@ function commandToAggregateRef(command) {
|
|
|
299458
299811
|
switch (command.type) {
|
|
299459
299812
|
case "project.create":
|
|
299460
299813
|
case "project.meta.update":
|
|
299814
|
+
case "project.script.update":
|
|
299461
299815
|
case "project.delete": return {
|
|
299462
299816
|
aggregateKind: "project",
|
|
299463
299817
|
aggregateId: command.projectId
|