@cmmd-center/forge 0.10.8 → 0.10.9
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 +375 -322
- package/dist/bin.mjs +375 -322
- package/dist/client/assets/{DiffPanel-BmZCQ7ie.js → DiffPanel-xCfkBV0D.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-EQgKCWRo.js → DiffPanel.logic-BfOamVHM.js} +2 -2
- package/dist/client/assets/DiffPanelShell-B6MeDvYA.js +2531 -0
- package/dist/client/assets/{DiffWorkerPoolProvider-CU7zWBfP.js → DiffWorkerPoolProvider-C-r-Zusj.js} +9 -9
- package/dist/client/assets/{PullRequestCodePanel-FhNDL-Wv.js → PullRequestCodePanel-BSLzdOzf.js} +3 -3
- package/dist/client/assets/{Virtualizer-BLq-Dt-i.js → Virtualizer-4ILVlhCf.js} +2 -2
- package/dist/client/assets/{index-D22UpSjv.css → index-CUmbThfW.css} +1 -1
- package/dist/client/assets/{index-BYEPqKu0.js → index-CjhPsbaL.js} +58 -58
- package/dist/client/index.html +13 -6
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/DiffPanelShell-CpaWJE6J.js +0 -2531
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.10.
|
|
16547
|
+
const FORGE_RELEASE_VERSION = "0.10.6";
|
|
16548
16548
|
//#endregion
|
|
16549
16549
|
//#region ../../packages/shared/src/hostProcess.ts
|
|
16550
16550
|
/**
|
|
@@ -65379,7 +65379,7 @@ function normalizeNumberish(value) {
|
|
|
65379
65379
|
}
|
|
65380
65380
|
//#endregion
|
|
65381
65381
|
//#region package.json
|
|
65382
|
-
var version$1 = "0.10.
|
|
65382
|
+
var version$1 = "0.10.9";
|
|
65383
65383
|
//#endregion
|
|
65384
65384
|
//#region src/sentry.ts
|
|
65385
65385
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -93464,6 +93464,31 @@ function lifecycleIntentCommandId(runtimeId, threadId, requestedAt) {
|
|
|
93464
93464
|
return CommandId.make("lifecycle-intent:" + stableReplicaDigest(runtimeId, threadId, requestedAt));
|
|
93465
93465
|
}
|
|
93466
93466
|
//#endregion
|
|
93467
|
+
//#region src/runtimeReplication/replicaHydrationProjects.ts
|
|
93468
|
+
function activePathMatchedProjects(projects, index, summary) {
|
|
93469
|
+
return projects.filter((project) => project.deletedAt === null && (project.id === summary.projectId || index.runtime.workspaceRoot !== null && project.workspaceRoot === index.runtime.workspaceRoot));
|
|
93470
|
+
}
|
|
93471
|
+
const resolveRepositoryMatchedProjects = require_Schema$1.fn("resolveRepositoryMatchedProjects")(function* (projects, replicaRepositoryFullName, dependencies) {
|
|
93472
|
+
if (replicaRepositoryFullName === null) return [];
|
|
93473
|
+
return yield* require_Schema$1.filter(projects.filter((project) => project.deletedAt === null), (project) => dependencies.resolveProjectRepositoryFullName(project.workspaceRoot).pipe(require_Schema$1.map((repositoryFullName) => repositoryFullName?.toLowerCase() === replicaRepositoryFullName)), { concurrency: 1 });
|
|
93474
|
+
});
|
|
93475
|
+
const resolveLocalReplicaProjects = require_Schema$1.fn("resolveLocalReplicaProjects")(function* (projects, index, summary, dependencies) {
|
|
93476
|
+
const pathMatches = activePathMatchedProjects(projects, index, summary);
|
|
93477
|
+
if (pathMatches.length > 0) return {
|
|
93478
|
+
projects: pathMatches,
|
|
93479
|
+
repositoryRemapped: false
|
|
93480
|
+
};
|
|
93481
|
+
return {
|
|
93482
|
+
projects: yield* resolveRepositoryMatchedProjects(projects, index.runtime.githubRepoFullName?.toLowerCase() ?? null, dependencies),
|
|
93483
|
+
repositoryRemapped: true
|
|
93484
|
+
};
|
|
93485
|
+
});
|
|
93486
|
+
function replicaWorkspaceMatchesLocalProject(input) {
|
|
93487
|
+
if (input.detail.runtime.workspaceRoot === input.localProject.workspaceRoot) return true;
|
|
93488
|
+
const localRepository = input.localProjectRepositoryFullName?.toLowerCase() ?? null;
|
|
93489
|
+
return localRepository !== null && input.detail.runtime.githubRepoFullName?.toLowerCase() === localRepository && input.detail.project.githubRepoFullName?.toLowerCase() === localRepository;
|
|
93490
|
+
}
|
|
93491
|
+
//#endregion
|
|
93467
93492
|
//#region src/runtimeReplication/protocol.ts
|
|
93468
93493
|
const EMPTY_RUNTIME_THREAD_HEAD_HASH = "sha256:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU";
|
|
93469
93494
|
const REPLICA_MESSAGE_ID_PREFIX = "replica-source-v1:";
|
|
@@ -93658,25 +93683,6 @@ function replicaSummaryMatchesDetail(summary, detail) {
|
|
|
93658
93683
|
[summary.lastActivityAt, detail.thread.lastActivityAt]
|
|
93659
93684
|
].every(([summaryValue, detailValue]) => summaryValue === detailValue);
|
|
93660
93685
|
}
|
|
93661
|
-
function replicaSummaryPayload(summary) {
|
|
93662
|
-
return {
|
|
93663
|
-
conversationId: summary.conversationId,
|
|
93664
|
-
project: {
|
|
93665
|
-
projectId: summary.projectId,
|
|
93666
|
-
title: summary.projectTitle,
|
|
93667
|
-
githubRepoFullName: summary.projectGithubRepoFullName,
|
|
93668
|
-
branch: summary.projectBranch
|
|
93669
|
-
},
|
|
93670
|
-
thread: {
|
|
93671
|
-
threadId: summary.threadId,
|
|
93672
|
-
title: summary.title,
|
|
93673
|
-
status: summary.status,
|
|
93674
|
-
model: summary.model,
|
|
93675
|
-
branch: summary.branch,
|
|
93676
|
-
lastActivityAt: summary.lastActivityAt
|
|
93677
|
-
}
|
|
93678
|
-
};
|
|
93679
|
-
}
|
|
93680
93686
|
function hasValidReplicaGeneration(runtimeId, threadId, generationId, threadStatus, sourceEvents) {
|
|
93681
93687
|
const streamKey = "thread:" + threadId;
|
|
93682
93688
|
const base = runtimeThreadGenerationId(runtimeId, streamKey);
|
|
@@ -93817,30 +93823,11 @@ function threadDates(events, fallback) {
|
|
|
93817
93823
|
updatedAt: events.at(-1).occurredAt
|
|
93818
93824
|
};
|
|
93819
93825
|
}
|
|
93820
|
-
function replicaWorkspaceMatchesLocalProject(input) {
|
|
93821
|
-
if (input.detail.runtime.workspaceRoot === input.localProject.workspaceRoot) return true;
|
|
93822
|
-
const localRepository = input.localProjectRepositoryFullName?.toLowerCase() ?? null;
|
|
93823
|
-
return localRepository !== null && input.detail.runtime.githubRepoFullName?.toLowerCase() === localRepository && input.detail.project.githubRepoFullName?.toLowerCase() === localRepository;
|
|
93824
|
-
}
|
|
93825
93826
|
function replicaToOrchestrationThread(input) {
|
|
93826
|
-
const
|
|
93827
|
-
data: {
|
|
93828
|
-
runtime: input.indexRuntimePayload,
|
|
93829
|
-
reachability: "unknown",
|
|
93830
|
-
threads: [input.summaryPayload],
|
|
93831
|
-
nextCursor: null
|
|
93832
|
-
},
|
|
93833
|
-
meta: {
|
|
93834
|
-
domain: "runtimeThreadIndex",
|
|
93835
|
-
version: "1.0",
|
|
93836
|
-
timestamp: input.hydratedAt
|
|
93837
|
-
}
|
|
93838
|
-
});
|
|
93827
|
+
const { indexRuntime, summary } = input;
|
|
93839
93828
|
const detail = decodeReplicaThreadDetail(input.replicaPayload);
|
|
93840
|
-
if (index === null) return null;
|
|
93841
|
-
const summary = index.threads[0];
|
|
93842
93829
|
const sourceEvents = detail?.events.map(replicaSourceEvent) ?? [];
|
|
93843
|
-
if (detail === null ||
|
|
93830
|
+
if (detail === null || indexRuntime.id !== input.expectedRuntimeId || detail.runtime.id !== input.expectedRuntimeId || !replicaRuntimeMatches(indexRuntime, detail.runtime) || !replicaSummaryMatchesDetail(summary, detail) || input.localProject.deletedAt !== null || input.localProject.defaultModelSelection === null || detail.runtime.workspaceRoot === null || !replicaWorkspaceMatchesLocalProject({
|
|
93844
93831
|
detail,
|
|
93845
93832
|
localProject: input.localProject,
|
|
93846
93833
|
localProjectRepositoryFullName: input.localProjectRepositoryFullName
|
|
@@ -93895,24 +93882,6 @@ function replicaHydrationFailure(detail, cause) {
|
|
|
93895
93882
|
//#endregion
|
|
93896
93883
|
//#region src/runtimeReplication/replicaHydration.ts
|
|
93897
93884
|
const REPLICA_INDEX_PAGE_SIZE$1 = 100;
|
|
93898
|
-
function activePathMatchedProjects(state, index, summary) {
|
|
93899
|
-
return state.initialModel.projects.filter((project) => project.deletedAt === null && (project.id === summary.projectId || index.runtime.workspaceRoot !== null && project.workspaceRoot === index.runtime.workspaceRoot));
|
|
93900
|
-
}
|
|
93901
|
-
const resolveRepositoryMatchedProjects = require_Schema$1.fn("resolveRepositoryMatchedProjects")(function* (state, replicaRepositoryFullName, dependencies) {
|
|
93902
|
-
if (replicaRepositoryFullName === null) return [];
|
|
93903
|
-
return yield* require_Schema$1.filter(state.initialModel.projects.filter((project) => project.deletedAt === null), (project) => dependencies.resolveProjectRepositoryFullName(project.workspaceRoot).pipe(require_Schema$1.map((repositoryFullName) => repositoryFullName?.toLowerCase() === replicaRepositoryFullName)), { concurrency: 1 });
|
|
93904
|
-
});
|
|
93905
|
-
const resolveLocalReplicaProjects = require_Schema$1.fn("resolveLocalReplicaProjects")(function* (state, index, summary, dependencies) {
|
|
93906
|
-
const pathMatches = activePathMatchedProjects(state, index, summary);
|
|
93907
|
-
if (pathMatches.length > 0) return {
|
|
93908
|
-
projects: pathMatches,
|
|
93909
|
-
repositoryRemapped: false
|
|
93910
|
-
};
|
|
93911
|
-
return {
|
|
93912
|
-
projects: yield* resolveRepositoryMatchedProjects(state, index.runtime.githubRepoFullName?.toLowerCase() ?? null, dependencies),
|
|
93913
|
-
repositoryRemapped: true
|
|
93914
|
-
};
|
|
93915
|
-
});
|
|
93916
93885
|
const readValidatedIndex = require_Schema$1.fn("readValidatedReplicaIndex")(function* (expectedRuntimeId, cursor, dependencies) {
|
|
93917
93886
|
const rawIndex = yield* dependencies.readIndex({
|
|
93918
93887
|
limit: REPLICA_INDEX_PAGE_SIZE$1,
|
|
@@ -93938,7 +93907,7 @@ const prepareReplicaSummary = require_Schema$1.fn("prepareReplicaSummary")(funct
|
|
|
93938
93907
|
state.skippedQuarantined += 1;
|
|
93939
93908
|
return;
|
|
93940
93909
|
}
|
|
93941
|
-
const localResolution = yield* resolveLocalReplicaProjects(state, index, summary, dependencies);
|
|
93910
|
+
const localResolution = yield* resolveLocalReplicaProjects(state.initialModel.projects, index, summary, dependencies);
|
|
93942
93911
|
const localProjects = localResolution.projects;
|
|
93943
93912
|
if (localProjects.length !== 1) return yield* replicaHydrationFailure("replica project '" + summary.projectId + "' does not resolve to one active workspace");
|
|
93944
93913
|
const detail = yield* dependencies.readThread({ threadId: summary.threadId });
|
|
@@ -93949,8 +93918,8 @@ const prepareReplicaSummary = require_Schema$1.fn("prepareReplicaSummary")(funct
|
|
|
93949
93918
|
localProject: localProjects[0],
|
|
93950
93919
|
localProjectRepositoryFullName: localResolution.repositoryRemapped ? index.runtime.githubRepoFullName : null,
|
|
93951
93920
|
replicaPayload: detail,
|
|
93952
|
-
|
|
93953
|
-
|
|
93921
|
+
indexRuntime: index.runtime,
|
|
93922
|
+
summary
|
|
93954
93923
|
});
|
|
93955
93924
|
if (candidate === null) return yield* replicaHydrationFailure("thread '" + summary.threadId + "' failed identity or generation checks");
|
|
93956
93925
|
state.prepared.push({
|
|
@@ -99829,6 +99798,316 @@ function claudeWriteToken(env = process.env) {
|
|
|
99829
99798
|
return accessor.read(env);
|
|
99830
99799
|
}
|
|
99831
99800
|
//#endregion
|
|
99801
|
+
//#region src/egress/providerDeliveryReceipt.ts
|
|
99802
|
+
const PROVIDER_ACCOUNT_IDENTITY$2 = /^pai_v1_[A-Za-z0-9_-]{43}$/;
|
|
99803
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
99804
|
+
const RFC3339$1 = /^(\d{4})-(\d{2})-(\d{2})T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
|
99805
|
+
const RECEIPT_KEYS = new Set([
|
|
99806
|
+
"receiptId",
|
|
99807
|
+
"runtimeId",
|
|
99808
|
+
"machineId",
|
|
99809
|
+
"credentialEpoch",
|
|
99810
|
+
"identity",
|
|
99811
|
+
"issuedAt",
|
|
99812
|
+
"expiresAt"
|
|
99813
|
+
]);
|
|
99814
|
+
const BINDING_KEYS = new Set([
|
|
99815
|
+
"runtimeId",
|
|
99816
|
+
"machineId",
|
|
99817
|
+
"credentialEpoch",
|
|
99818
|
+
"identity"
|
|
99819
|
+
]);
|
|
99820
|
+
const CODEX_IDENTITY_KEYS = new Set([
|
|
99821
|
+
"kind",
|
|
99822
|
+
"provider",
|
|
99823
|
+
"providerAccountIdentity"
|
|
99824
|
+
]);
|
|
99825
|
+
const CLAUDE_IDENTITY_KEYS = new Set([
|
|
99826
|
+
"kind",
|
|
99827
|
+
"provider",
|
|
99828
|
+
"credentialGenerationId"
|
|
99829
|
+
]);
|
|
99830
|
+
function isRecord$13(value) {
|
|
99831
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
99832
|
+
}
|
|
99833
|
+
function isStrictRfc3339DateTime(value) {
|
|
99834
|
+
if (typeof value !== "string") return false;
|
|
99835
|
+
const match = RFC3339$1.exec(value);
|
|
99836
|
+
if (!match || !Number.isFinite(Date.parse(value))) return false;
|
|
99837
|
+
const year = Number(match[1]);
|
|
99838
|
+
const month = Number(match[2]);
|
|
99839
|
+
const day = Number(match[3]);
|
|
99840
|
+
return month >= 1 && month <= 12 && day >= 1 && day <= daysInMonth$1(year, month);
|
|
99841
|
+
}
|
|
99842
|
+
function daysInMonth$1(year, month) {
|
|
99843
|
+
if (month === 2) return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0 ? 29 : 28;
|
|
99844
|
+
return [
|
|
99845
|
+
4,
|
|
99846
|
+
6,
|
|
99847
|
+
9,
|
|
99848
|
+
11
|
|
99849
|
+
].includes(month) ? 30 : 31;
|
|
99850
|
+
}
|
|
99851
|
+
function hasExactKeys$2(value, keys) {
|
|
99852
|
+
return Object.keys(value).every((key) => keys.has(key)) && Object.keys(value).length === keys.size;
|
|
99853
|
+
}
|
|
99854
|
+
function parseDeliveryIdentity(value, provider) {
|
|
99855
|
+
if (!isRecord$13(value)) return null;
|
|
99856
|
+
if (provider === "openai") return parseCodexDeliveryIdentity(value);
|
|
99857
|
+
if (provider === "anthropic") return parseClaudeDeliveryIdentity(value);
|
|
99858
|
+
return null;
|
|
99859
|
+
}
|
|
99860
|
+
function parseCodexDeliveryIdentity(value) {
|
|
99861
|
+
if (!hasExactKeys$2(value, CODEX_IDENTITY_KEYS) || value.kind !== "provider_account" || value.provider !== "codex" || typeof value.providerAccountIdentity !== "string" || !PROVIDER_ACCOUNT_IDENTITY$2.test(value.providerAccountIdentity)) return null;
|
|
99862
|
+
return {
|
|
99863
|
+
kind: "provider_account",
|
|
99864
|
+
provider: "codex",
|
|
99865
|
+
providerAccountIdentity: value.providerAccountIdentity
|
|
99866
|
+
};
|
|
99867
|
+
}
|
|
99868
|
+
function parseClaudeDeliveryIdentity(value) {
|
|
99869
|
+
if (!hasExactKeys$2(value, CLAUDE_IDENTITY_KEYS) || value.kind !== "credential_generation" || value.provider !== "claude" || typeof value.credentialGenerationId !== "string" || !UUID.test(value.credentialGenerationId)) return null;
|
|
99870
|
+
return {
|
|
99871
|
+
kind: "credential_generation",
|
|
99872
|
+
provider: "claude",
|
|
99873
|
+
credentialGenerationId: value.credentialGenerationId
|
|
99874
|
+
};
|
|
99875
|
+
}
|
|
99876
|
+
function parseProviderRuntimeDeliveryReceipt(value, expected) {
|
|
99877
|
+
if (!isRecord$13(value) || !hasExactKeys$2(value, RECEIPT_KEYS)) return null;
|
|
99878
|
+
const identity = parseDeliveryIdentity(value.identity, expected.provider);
|
|
99879
|
+
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;
|
|
99880
|
+
return {
|
|
99881
|
+
receiptId: value.receiptId,
|
|
99882
|
+
runtimeId: expected.runtimeId,
|
|
99883
|
+
machineId: expected.machineId,
|
|
99884
|
+
credentialEpoch: expected.credentialEpoch,
|
|
99885
|
+
identity,
|
|
99886
|
+
issuedAt: value.issuedAt,
|
|
99887
|
+
expiresAt: value.expiresAt
|
|
99888
|
+
};
|
|
99889
|
+
}
|
|
99890
|
+
function providerDeliveryBindingFromReceipt(receipt) {
|
|
99891
|
+
return {
|
|
99892
|
+
runtimeId: receipt.runtimeId,
|
|
99893
|
+
machineId: receipt.machineId,
|
|
99894
|
+
credentialEpoch: receipt.credentialEpoch,
|
|
99895
|
+
identity: receipt.identity
|
|
99896
|
+
};
|
|
99897
|
+
}
|
|
99898
|
+
function readProviderDeliveryBinding(value) {
|
|
99899
|
+
if (!isRecord$13(value) || !hasExactKeys$2(value, BINDING_KEYS)) return null;
|
|
99900
|
+
const identityProvider = isRecord$13(value.identity) ? value.identity.provider : void 0;
|
|
99901
|
+
const tokenProvider = identityProvider === "codex" ? "openai" : identityProvider === "claude" ? "anthropic" : null;
|
|
99902
|
+
if (!tokenProvider) return null;
|
|
99903
|
+
const identity = parseDeliveryIdentity(value.identity, tokenProvider);
|
|
99904
|
+
if (!identity || typeof value.runtimeId !== "string" || value.runtimeId.length === 0 || typeof value.machineId !== "string" || value.machineId.length === 0 || !Number.isInteger(value.credentialEpoch) || value.credentialEpoch < 0) return null;
|
|
99905
|
+
return {
|
|
99906
|
+
runtimeId: value.runtimeId,
|
|
99907
|
+
machineId: value.machineId,
|
|
99908
|
+
credentialEpoch: value.credentialEpoch,
|
|
99909
|
+
identity
|
|
99910
|
+
};
|
|
99911
|
+
}
|
|
99912
|
+
function providerDeliveryBindingsEqual(left, right) {
|
|
99913
|
+
if (left.runtimeId !== right.runtimeId || left.machineId !== right.machineId || left.credentialEpoch !== right.credentialEpoch || left.identity.kind !== right.identity.kind || left.identity.provider !== right.identity.provider) return false;
|
|
99914
|
+
if (left.identity.kind === "provider_account" && right.identity.kind === "provider_account") return left.identity.providerAccountIdentity === right.identity.providerAccountIdentity;
|
|
99915
|
+
return left.identity.kind === "credential_generation" && right.identity.kind === "credential_generation" && left.identity.credentialGenerationId === right.identity.credentialGenerationId;
|
|
99916
|
+
}
|
|
99917
|
+
//#endregion
|
|
99918
|
+
//#region src/provider/claudeReadinessReason.ts
|
|
99919
|
+
/**
|
|
99920
|
+
* The reason literals Forge has copy for, confirmed against CMMD-36441's
|
|
99921
|
+
* readiness service. If the route renames one, the rename lands here as a
|
|
99922
|
+
* fall-through to the generic sentence, never as a wrong sentence.
|
|
99923
|
+
*
|
|
99924
|
+
* Reading the reason is what makes `stale` legible. CMMD-36441 answers
|
|
99925
|
+
* `credential_reconnect_required` on a `stale` answer that still reports
|
|
99926
|
+
* `connected: true`, and the older `credential_generation_not_applied` on a
|
|
99927
|
+
* `stale` answer that simply has not landed yet. Those want opposite
|
|
99928
|
+
* sentences, and both used to get "Reconnect Claude in Settings" because the
|
|
99929
|
+
* guard read only the delivery status.
|
|
99930
|
+
*/
|
|
99931
|
+
const CODE_BY_UPSTREAM_REASON$1 = {
|
|
99932
|
+
credential_expired_refreshing: "CREDENTIAL_EXPIRED_REFRESHING",
|
|
99933
|
+
credential_reconnect_required: "CREDENTIAL_RECONNECT_REQUIRED",
|
|
99934
|
+
credential_not_connected: "CREDENTIAL_RECONNECT_REQUIRED",
|
|
99935
|
+
credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED",
|
|
99936
|
+
runtime_unavailable: "RUNTIME_UNAVAILABLE"
|
|
99937
|
+
};
|
|
99938
|
+
const CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY = "The delivered Claude credential is unavailable or unusable in this runtime.";
|
|
99939
|
+
/**
|
|
99940
|
+
* An ISO 8601 instant, with or without fractional seconds, UTC or offset.
|
|
99941
|
+
* Anchored to nothing on purpose: CMMD wraps the time in a sentence, and the
|
|
99942
|
+
* time is the only part of that sentence Forge repeats.
|
|
99943
|
+
*/
|
|
99944
|
+
const ISO_INSTANT_PATTERN = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})/;
|
|
99945
|
+
function claudeReadinessReasonCode(reason) {
|
|
99946
|
+
if (typeof reason !== "string" || !Object.hasOwn(CODE_BY_UPSTREAM_REASON$1, reason)) return null;
|
|
99947
|
+
return CODE_BY_UPSTREAM_REASON$1[reason] ?? null;
|
|
99948
|
+
}
|
|
99949
|
+
function expiredAtFromReadinessMessage(message) {
|
|
99950
|
+
if (typeof message !== "string") return null;
|
|
99951
|
+
return ISO_INSTANT_PATTERN.exec(message)?.[0] ?? null;
|
|
99952
|
+
}
|
|
99953
|
+
function claudeCredentialExpiredTurnCopy(expiredAt) {
|
|
99954
|
+
return `The delivered Claude credential expired at ${expiredAt}. CMMD is delivering a refreshed one, so retry this turn in a moment.`;
|
|
99955
|
+
}
|
|
99956
|
+
function claudeCredentialExpiredCardCopy(expiredAt) {
|
|
99957
|
+
return `The delivered Claude credential expired at ${expiredAt}. CMMD is delivering a refreshed one to this runtime.`;
|
|
99958
|
+
}
|
|
99959
|
+
/**
|
|
99960
|
+
* The last allowlisted readiness reason this process saw.
|
|
99961
|
+
*
|
|
99962
|
+
* A server process serves exactly one runtime, so one slot is the whole store.
|
|
99963
|
+
* It holds a reason code and a timestamp, never credential bytes. The provider
|
|
99964
|
+
* catalog reads a local credential file and cannot tell an expired snapshot
|
|
99965
|
+
* from a blank one, so without this the card can only offer the generic
|
|
99966
|
+
* sentence while the guard already knows better.
|
|
99967
|
+
*/
|
|
99968
|
+
let latestVerdict = null;
|
|
99969
|
+
/**
|
|
99970
|
+
* Remember, or clear, what the readiness answer said.
|
|
99971
|
+
*
|
|
99972
|
+
* An answer carrying no allowlisted reason clears the slot, which is what makes
|
|
99973
|
+
* the card go back to the generic sentence the moment CMMD applies a
|
|
99974
|
+
* credential: an applied answer carries no reason.
|
|
99975
|
+
*/
|
|
99976
|
+
function recordClaudeReadinessVerdict(readiness) {
|
|
99977
|
+
const code = claudeReadinessReasonCode(readiness.reason);
|
|
99978
|
+
latestVerdict = code === null ? null : {
|
|
99979
|
+
code,
|
|
99980
|
+
expiredAt: expiredAtFromReadinessMessage(readiness.lastErrorMessage)
|
|
99981
|
+
};
|
|
99982
|
+
}
|
|
99983
|
+
/**
|
|
99984
|
+
* What the provider status card says about a delivered credential it cannot
|
|
99985
|
+
* use. Names the expiry only when a readiness answer supplied the time; a
|
|
99986
|
+
* guessed time would be worse than the generic sentence.
|
|
99987
|
+
*/
|
|
99988
|
+
function claudeNativeCredentialUnusableMessage() {
|
|
99989
|
+
const verdict = latestVerdict;
|
|
99990
|
+
if (verdict?.code === "CREDENTIAL_EXPIRED_REFRESHING" && verdict.expiredAt !== null) return claudeCredentialExpiredCardCopy(verdict.expiredAt);
|
|
99991
|
+
return CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY;
|
|
99992
|
+
}
|
|
99993
|
+
//#endregion
|
|
99994
|
+
//#region src/provider/providerReadiness.ts
|
|
99995
|
+
const GENERATION_HASH_PATTERN$1 = /^[a-f0-9]{64}$/;
|
|
99996
|
+
const STILL_APPLYING_STATUSES = new Set([
|
|
99997
|
+
"pending",
|
|
99998
|
+
"claimed",
|
|
99999
|
+
"activating"
|
|
100000
|
+
]);
|
|
100001
|
+
const OAUTH_SECRET_FIELDS = ["accessToken", "refreshToken"];
|
|
100002
|
+
var ProviderReadinessFetchError = class extends Error {
|
|
100003
|
+
constructor(failure) {
|
|
100004
|
+
super(failure);
|
|
100005
|
+
this.failure = failure;
|
|
100006
|
+
this.name = "ProviderReadinessFetchError";
|
|
100007
|
+
}
|
|
100008
|
+
};
|
|
100009
|
+
async function queryProviderReadiness(input) {
|
|
100010
|
+
if (input.sprite !== null && input.environmentId !== input.sprite.environmentId) return {
|
|
100011
|
+
kind: "query_failed",
|
|
100012
|
+
failure: "wrong_environment"
|
|
100013
|
+
};
|
|
100014
|
+
if (input.provider !== "claudeAgent" || input.sprite === null) return {
|
|
100015
|
+
kind: "ready",
|
|
100016
|
+
binding: null
|
|
100017
|
+
};
|
|
100018
|
+
const sprite = input.sprite;
|
|
100019
|
+
if (!GENERATION_HASH_PATTERN$1.test(sprite.localGenerationHash)) return {
|
|
100020
|
+
kind: "not_ready",
|
|
100021
|
+
reason: "generation_mismatch"
|
|
100022
|
+
};
|
|
100023
|
+
let snapshot;
|
|
100024
|
+
try {
|
|
100025
|
+
snapshot = await input.claude.fetch(sprite.runtimeId);
|
|
100026
|
+
} catch (cause) {
|
|
100027
|
+
if (cause instanceof ProviderReadinessFetchError) return {
|
|
100028
|
+
kind: "query_failed",
|
|
100029
|
+
failure: cause.failure
|
|
100030
|
+
};
|
|
100031
|
+
return {
|
|
100032
|
+
kind: "query_failed",
|
|
100033
|
+
failure: "cmmd_unavailable"
|
|
100034
|
+
};
|
|
100035
|
+
}
|
|
100036
|
+
return classifyClaudeSnapshot(snapshot, sprite);
|
|
100037
|
+
}
|
|
100038
|
+
function isAppliedClaudeSnapshot(snapshot) {
|
|
100039
|
+
return snapshot.connected === true && snapshot.deliveryStatus === "applied" && snapshot.nativeExecutable === true && typeof snapshot.generationId === "string" && snapshot.generationId.trim().length > 0;
|
|
100040
|
+
}
|
|
100041
|
+
function classifyUnappliedClaudeSnapshot(snapshot) {
|
|
100042
|
+
const code = claudeReadinessReasonCode(snapshot.reason);
|
|
100043
|
+
if (code === "RUNTIME_UNAVAILABLE") return {
|
|
100044
|
+
kind: "not_ready",
|
|
100045
|
+
reason: "environment_unavailable"
|
|
100046
|
+
};
|
|
100047
|
+
if (code === "CREDENTIAL_EXPIRED_REFRESHING" || code === "CREDENTIAL_GENERATION_NOT_APPLIED") return {
|
|
100048
|
+
kind: "not_ready",
|
|
100049
|
+
reason: "still_applying"
|
|
100050
|
+
};
|
|
100051
|
+
if (code === "CREDENTIAL_RECONNECT_REQUIRED") return {
|
|
100052
|
+
kind: "not_ready",
|
|
100053
|
+
reason: "credential_unusable"
|
|
100054
|
+
};
|
|
100055
|
+
if (STILL_APPLYING_STATUSES.has(snapshot.deliveryStatus)) return {
|
|
100056
|
+
kind: "not_ready",
|
|
100057
|
+
reason: "still_applying"
|
|
100058
|
+
};
|
|
100059
|
+
if (snapshot.deliveryStatus === "failed") return {
|
|
100060
|
+
kind: "not_ready",
|
|
100061
|
+
reason: "apply_failed"
|
|
100062
|
+
};
|
|
100063
|
+
return {
|
|
100064
|
+
kind: "not_ready",
|
|
100065
|
+
reason: "credential_unusable"
|
|
100066
|
+
};
|
|
100067
|
+
}
|
|
100068
|
+
function classifyClaudeSnapshot(snapshot, sprite) {
|
|
100069
|
+
if (!isAppliedClaudeSnapshot(snapshot)) return classifyUnappliedClaudeSnapshot(snapshot);
|
|
100070
|
+
const generationId = snapshot.generationId.trim();
|
|
100071
|
+
if ((0, node_crypto.createHash)("sha256").update(generationId).digest("hex") !== sprite.localGenerationHash) return {
|
|
100072
|
+
kind: "not_ready",
|
|
100073
|
+
reason: "generation_mismatch"
|
|
100074
|
+
};
|
|
100075
|
+
const deliveryReceipt = parseProviderRuntimeDeliveryReceipt(snapshot.deliveryReceipt, {
|
|
100076
|
+
provider: "anthropic",
|
|
100077
|
+
runtimeId: sprite.runtimeId,
|
|
100078
|
+
machineId: sprite.machineId,
|
|
100079
|
+
credentialEpoch: sprite.credentialEpoch,
|
|
100080
|
+
expiresAt: snapshot.deliveryReceipt?.expiresAt ?? null
|
|
100081
|
+
});
|
|
100082
|
+
if (deliveryReceipt?.identity.kind !== "credential_generation" || deliveryReceipt.identity.credentialGenerationId !== generationId) return {
|
|
100083
|
+
kind: "not_ready",
|
|
100084
|
+
reason: "sprite_identity_drift"
|
|
100085
|
+
};
|
|
100086
|
+
return {
|
|
100087
|
+
kind: "ready",
|
|
100088
|
+
binding: providerDeliveryBindingFromReceipt(deliveryReceipt)
|
|
100089
|
+
};
|
|
100090
|
+
}
|
|
100091
|
+
/**
|
|
100092
|
+
* A Claude.ai subscription blob is usable when claudeAiOauth holds at least one
|
|
100093
|
+
* non-empty secret. Metadata without tokens is how production showed Connected
|
|
100094
|
+
* (max) for three days while every turn failed to refresh.
|
|
100095
|
+
*/
|
|
100096
|
+
function hasUsableClaudeCredentialBlob(credentialJson) {
|
|
100097
|
+
try {
|
|
100098
|
+
const parsed = JSON.parse(credentialJson);
|
|
100099
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return false;
|
|
100100
|
+
const oauth = parsed.claudeAiOauth;
|
|
100101
|
+
if (typeof oauth !== "object" || oauth === null || Array.isArray(oauth)) return false;
|
|
100102
|
+
return OAUTH_SECRET_FIELDS.some((field) => {
|
|
100103
|
+
const value = oauth[field];
|
|
100104
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
100105
|
+
});
|
|
100106
|
+
} catch {
|
|
100107
|
+
return false;
|
|
100108
|
+
}
|
|
100109
|
+
}
|
|
100110
|
+
//#endregion
|
|
99832
100111
|
//#region src/providerAuth/ClaudeDeviceAuth.ts
|
|
99833
100112
|
const AUTHORIZE_URL_PATTERN = /https:\/\/[^\s]*\/oauth\/authorize\?[^\s]+/u;
|
|
99834
100113
|
const ANSI_ESCAPE_PATTERN$1 = new RegExp(String.raw`\x1B\[[0-?]*[ -/]*[@-~]`, "gu");
|
|
@@ -100110,21 +100389,7 @@ function resolveLocalClaudeCredentialPath(homePath) {
|
|
|
100110
100389
|
* an API-key config. Claude Code stores the subscription OAuth under a
|
|
100111
100390
|
* `claudeAiOauth` object; require that marker. Mirrors CMMD's
|
|
100112
100391
|
* validateClaudeCredentialJson.
|
|
100113
|
-
|
|
100114
|
-
function isClaudeSubscriptionCredential(credentialJson) {
|
|
100115
|
-
try {
|
|
100116
|
-
const parsed = JSON.parse(credentialJson);
|
|
100117
|
-
if (typeof parsed !== "object" || parsed === null) return false;
|
|
100118
|
-
const oauth = parsed.claudeAiOauth;
|
|
100119
|
-
if (typeof oauth !== "object" || oauth === null) return false;
|
|
100120
|
-
return hasUsableOauthSecrets(oauth);
|
|
100121
|
-
} catch {
|
|
100122
|
-
return false;
|
|
100123
|
-
}
|
|
100124
|
-
}
|
|
100125
|
-
/** Either of these alone is enough to authenticate. */
|
|
100126
|
-
const OAUTH_SECRET_FIELDS = ["accessToken", "refreshToken"];
|
|
100127
|
-
/**
|
|
100392
|
+
*
|
|
100128
100393
|
* Require AT LEAST ONE usable token before uploading anything.
|
|
100129
100394
|
*
|
|
100130
100395
|
* This gate used to end at "claudeAiOauth is an object", and in production that
|
|
@@ -100151,11 +100416,8 @@ const OAUTH_SECRET_FIELDS = ["accessToken", "refreshToken"];
|
|
|
100151
100416
|
* schema Anthropic might ship, and fields they add, rename or drop around these
|
|
100152
100417
|
* two keep flowing through untouched.
|
|
100153
100418
|
*/
|
|
100154
|
-
function
|
|
100155
|
-
return
|
|
100156
|
-
const value = oauth[field];
|
|
100157
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
100158
|
-
});
|
|
100419
|
+
function isClaudeSubscriptionCredential(credentialJson) {
|
|
100420
|
+
return hasUsableClaudeCredentialBlob(credentialJson);
|
|
100159
100421
|
}
|
|
100160
100422
|
const EMAIL_FIELD_NAMES = new Set([
|
|
100161
100423
|
"email",
|
|
@@ -146720,12 +146982,12 @@ function decodeProviderKind(providerName, operation) {
|
|
|
146720
146982
|
detail: `Unknown persisted provider '${providerName}'.`
|
|
146721
146983
|
}));
|
|
146722
146984
|
}
|
|
146723
|
-
function isRecord$
|
|
146985
|
+
function isRecord$12(value) {
|
|
146724
146986
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
146725
146987
|
}
|
|
146726
146988
|
function mergeRuntimePayload(existing, next) {
|
|
146727
146989
|
if (next === void 0) return existing ?? null;
|
|
146728
|
-
if (isRecord$
|
|
146990
|
+
if (isRecord$12(existing) && isRecord$12(next)) return {
|
|
146729
146991
|
...existing,
|
|
146730
146992
|
...next
|
|
146731
146993
|
};
|
|
@@ -148319,123 +148581,6 @@ function buildCodexCredentialModelScope(input) {
|
|
|
148319
148581
|
return providerEgressModelScope(input.selectedModel, catalog);
|
|
148320
148582
|
}
|
|
148321
148583
|
//#endregion
|
|
148322
|
-
//#region src/egress/providerDeliveryReceipt.ts
|
|
148323
|
-
const PROVIDER_ACCOUNT_IDENTITY$2 = /^pai_v1_[A-Za-z0-9_-]{43}$/;
|
|
148324
|
-
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
148325
|
-
const RFC3339$1 = /^(\d{4})-(\d{2})-(\d{2})T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
|
148326
|
-
const RECEIPT_KEYS = new Set([
|
|
148327
|
-
"receiptId",
|
|
148328
|
-
"runtimeId",
|
|
148329
|
-
"machineId",
|
|
148330
|
-
"credentialEpoch",
|
|
148331
|
-
"identity",
|
|
148332
|
-
"issuedAt",
|
|
148333
|
-
"expiresAt"
|
|
148334
|
-
]);
|
|
148335
|
-
const BINDING_KEYS = new Set([
|
|
148336
|
-
"runtimeId",
|
|
148337
|
-
"machineId",
|
|
148338
|
-
"credentialEpoch",
|
|
148339
|
-
"identity"
|
|
148340
|
-
]);
|
|
148341
|
-
const CODEX_IDENTITY_KEYS = new Set([
|
|
148342
|
-
"kind",
|
|
148343
|
-
"provider",
|
|
148344
|
-
"providerAccountIdentity"
|
|
148345
|
-
]);
|
|
148346
|
-
const CLAUDE_IDENTITY_KEYS = new Set([
|
|
148347
|
-
"kind",
|
|
148348
|
-
"provider",
|
|
148349
|
-
"credentialGenerationId"
|
|
148350
|
-
]);
|
|
148351
|
-
function isRecord$12(value) {
|
|
148352
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
148353
|
-
}
|
|
148354
|
-
function isStrictRfc3339DateTime(value) {
|
|
148355
|
-
if (typeof value !== "string") return false;
|
|
148356
|
-
const match = RFC3339$1.exec(value);
|
|
148357
|
-
if (!match || !Number.isFinite(Date.parse(value))) return false;
|
|
148358
|
-
const year = Number(match[1]);
|
|
148359
|
-
const month = Number(match[2]);
|
|
148360
|
-
const day = Number(match[3]);
|
|
148361
|
-
return month >= 1 && month <= 12 && day >= 1 && day <= daysInMonth$1(year, month);
|
|
148362
|
-
}
|
|
148363
|
-
function daysInMonth$1(year, month) {
|
|
148364
|
-
if (month === 2) return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0 ? 29 : 28;
|
|
148365
|
-
return [
|
|
148366
|
-
4,
|
|
148367
|
-
6,
|
|
148368
|
-
9,
|
|
148369
|
-
11
|
|
148370
|
-
].includes(month) ? 30 : 31;
|
|
148371
|
-
}
|
|
148372
|
-
function hasExactKeys$2(value, keys) {
|
|
148373
|
-
return Object.keys(value).every((key) => keys.has(key)) && Object.keys(value).length === keys.size;
|
|
148374
|
-
}
|
|
148375
|
-
function parseDeliveryIdentity(value, provider) {
|
|
148376
|
-
if (!isRecord$12(value)) return null;
|
|
148377
|
-
if (provider === "openai") return parseCodexDeliveryIdentity(value);
|
|
148378
|
-
if (provider === "anthropic") return parseClaudeDeliveryIdentity(value);
|
|
148379
|
-
return null;
|
|
148380
|
-
}
|
|
148381
|
-
function parseCodexDeliveryIdentity(value) {
|
|
148382
|
-
if (!hasExactKeys$2(value, CODEX_IDENTITY_KEYS) || value.kind !== "provider_account" || value.provider !== "codex" || typeof value.providerAccountIdentity !== "string" || !PROVIDER_ACCOUNT_IDENTITY$2.test(value.providerAccountIdentity)) return null;
|
|
148383
|
-
return {
|
|
148384
|
-
kind: "provider_account",
|
|
148385
|
-
provider: "codex",
|
|
148386
|
-
providerAccountIdentity: value.providerAccountIdentity
|
|
148387
|
-
};
|
|
148388
|
-
}
|
|
148389
|
-
function parseClaudeDeliveryIdentity(value) {
|
|
148390
|
-
if (!hasExactKeys$2(value, CLAUDE_IDENTITY_KEYS) || value.kind !== "credential_generation" || value.provider !== "claude" || typeof value.credentialGenerationId !== "string" || !UUID.test(value.credentialGenerationId)) return null;
|
|
148391
|
-
return {
|
|
148392
|
-
kind: "credential_generation",
|
|
148393
|
-
provider: "claude",
|
|
148394
|
-
credentialGenerationId: value.credentialGenerationId
|
|
148395
|
-
};
|
|
148396
|
-
}
|
|
148397
|
-
function parseProviderRuntimeDeliveryReceipt(value, expected) {
|
|
148398
|
-
if (!isRecord$12(value) || !hasExactKeys$2(value, RECEIPT_KEYS)) return null;
|
|
148399
|
-
const identity = parseDeliveryIdentity(value.identity, expected.provider);
|
|
148400
|
-
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;
|
|
148401
|
-
return {
|
|
148402
|
-
receiptId: value.receiptId,
|
|
148403
|
-
runtimeId: expected.runtimeId,
|
|
148404
|
-
machineId: expected.machineId,
|
|
148405
|
-
credentialEpoch: expected.credentialEpoch,
|
|
148406
|
-
identity,
|
|
148407
|
-
issuedAt: value.issuedAt,
|
|
148408
|
-
expiresAt: value.expiresAt
|
|
148409
|
-
};
|
|
148410
|
-
}
|
|
148411
|
-
function providerDeliveryBindingFromReceipt(receipt) {
|
|
148412
|
-
return {
|
|
148413
|
-
runtimeId: receipt.runtimeId,
|
|
148414
|
-
machineId: receipt.machineId,
|
|
148415
|
-
credentialEpoch: receipt.credentialEpoch,
|
|
148416
|
-
identity: receipt.identity
|
|
148417
|
-
};
|
|
148418
|
-
}
|
|
148419
|
-
function readProviderDeliveryBinding(value) {
|
|
148420
|
-
if (!isRecord$12(value) || !hasExactKeys$2(value, BINDING_KEYS)) return null;
|
|
148421
|
-
const identityProvider = isRecord$12(value.identity) ? value.identity.provider : void 0;
|
|
148422
|
-
const tokenProvider = identityProvider === "codex" ? "openai" : identityProvider === "claude" ? "anthropic" : null;
|
|
148423
|
-
if (!tokenProvider) return null;
|
|
148424
|
-
const identity = parseDeliveryIdentity(value.identity, tokenProvider);
|
|
148425
|
-
if (!identity || typeof value.runtimeId !== "string" || value.runtimeId.length === 0 || typeof value.machineId !== "string" || value.machineId.length === 0 || !Number.isInteger(value.credentialEpoch) || value.credentialEpoch < 0) return null;
|
|
148426
|
-
return {
|
|
148427
|
-
runtimeId: value.runtimeId,
|
|
148428
|
-
machineId: value.machineId,
|
|
148429
|
-
credentialEpoch: value.credentialEpoch,
|
|
148430
|
-
identity
|
|
148431
|
-
};
|
|
148432
|
-
}
|
|
148433
|
-
function providerDeliveryBindingsEqual(left, right) {
|
|
148434
|
-
if (left.runtimeId !== right.runtimeId || left.machineId !== right.machineId || left.credentialEpoch !== right.credentialEpoch || left.identity.kind !== right.identity.kind || left.identity.provider !== right.identity.provider) return false;
|
|
148435
|
-
if (left.identity.kind === "provider_account" && right.identity.kind === "provider_account") return left.identity.providerAccountIdentity === right.identity.providerAccountIdentity;
|
|
148436
|
-
return left.identity.kind === "credential_generation" && right.identity.kind === "credential_generation" && left.identity.credentialGenerationId === right.identity.credentialGenerationId;
|
|
148437
|
-
}
|
|
148438
|
-
//#endregion
|
|
148439
148584
|
//#region src/egress/providerEgressToken.ts
|
|
148440
148585
|
var ProviderEgressTokenError = class extends require_Schema$1.TaggedError("ProviderEgressTokenError") {};
|
|
148441
148586
|
const PROVIDER_EGRESS_TOKEN_TIMEOUT_MS = 1e4;
|
|
@@ -208783,82 +208928,6 @@ const makeProviderAuthProvenance = (input) => {
|
|
|
208783
208928
|
};
|
|
208784
208929
|
};
|
|
208785
208930
|
//#endregion
|
|
208786
|
-
//#region src/provider/claudeReadinessReason.ts
|
|
208787
|
-
/**
|
|
208788
|
-
* The reason literals Forge has copy for, confirmed against CMMD-36441's
|
|
208789
|
-
* readiness service. If the route renames one, the rename lands here as a
|
|
208790
|
-
* fall-through to the generic sentence, never as a wrong sentence.
|
|
208791
|
-
*
|
|
208792
|
-
* Reading the reason is what makes `stale` legible. CMMD-36441 answers
|
|
208793
|
-
* `credential_reconnect_required` on a `stale` answer that still reports
|
|
208794
|
-
* `connected: true`, and the older `credential_generation_not_applied` on a
|
|
208795
|
-
* `stale` answer that simply has not landed yet. Those want opposite
|
|
208796
|
-
* sentences, and both used to get "Reconnect Claude in Settings" because the
|
|
208797
|
-
* guard read only the delivery status.
|
|
208798
|
-
*/
|
|
208799
|
-
const CODE_BY_UPSTREAM_REASON$1 = {
|
|
208800
|
-
credential_expired_refreshing: "CREDENTIAL_EXPIRED_REFRESHING",
|
|
208801
|
-
credential_reconnect_required: "CREDENTIAL_RECONNECT_REQUIRED",
|
|
208802
|
-
credential_not_connected: "CREDENTIAL_RECONNECT_REQUIRED",
|
|
208803
|
-
credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED",
|
|
208804
|
-
runtime_unavailable: "RUNTIME_UNAVAILABLE"
|
|
208805
|
-
};
|
|
208806
|
-
const CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY = "The delivered Claude credential is unavailable or unusable in this runtime.";
|
|
208807
|
-
/**
|
|
208808
|
-
* An ISO 8601 instant, with or without fractional seconds, UTC or offset.
|
|
208809
|
-
* Anchored to nothing on purpose: CMMD wraps the time in a sentence, and the
|
|
208810
|
-
* time is the only part of that sentence Forge repeats.
|
|
208811
|
-
*/
|
|
208812
|
-
const ISO_INSTANT_PATTERN = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})/;
|
|
208813
|
-
function claudeReadinessReasonCode(reason) {
|
|
208814
|
-
if (typeof reason !== "string" || !Object.hasOwn(CODE_BY_UPSTREAM_REASON$1, reason)) return null;
|
|
208815
|
-
return CODE_BY_UPSTREAM_REASON$1[reason] ?? null;
|
|
208816
|
-
}
|
|
208817
|
-
function expiredAtFromReadinessMessage(message) {
|
|
208818
|
-
if (typeof message !== "string") return null;
|
|
208819
|
-
return ISO_INSTANT_PATTERN.exec(message)?.[0] ?? null;
|
|
208820
|
-
}
|
|
208821
|
-
function claudeCredentialExpiredTurnCopy(expiredAt) {
|
|
208822
|
-
return `The delivered Claude credential expired at ${expiredAt}. CMMD is delivering a refreshed one, so retry this turn in a moment.`;
|
|
208823
|
-
}
|
|
208824
|
-
function claudeCredentialExpiredCardCopy(expiredAt) {
|
|
208825
|
-
return `The delivered Claude credential expired at ${expiredAt}. CMMD is delivering a refreshed one to this runtime.`;
|
|
208826
|
-
}
|
|
208827
|
-
/**
|
|
208828
|
-
* The last allowlisted readiness reason this process saw.
|
|
208829
|
-
*
|
|
208830
|
-
* A server process serves exactly one runtime, so one slot is the whole store.
|
|
208831
|
-
* It holds a reason code and a timestamp, never credential bytes. The provider
|
|
208832
|
-
* catalog reads a local credential file and cannot tell an expired snapshot
|
|
208833
|
-
* from a blank one, so without this the card can only offer the generic
|
|
208834
|
-
* sentence while the guard already knows better.
|
|
208835
|
-
*/
|
|
208836
|
-
let latestVerdict = null;
|
|
208837
|
-
/**
|
|
208838
|
-
* Remember, or clear, what the readiness answer said.
|
|
208839
|
-
*
|
|
208840
|
-
* An answer carrying no allowlisted reason clears the slot, which is what makes
|
|
208841
|
-
* the card go back to the generic sentence the moment CMMD applies a
|
|
208842
|
-
* credential: an applied answer carries no reason.
|
|
208843
|
-
*/
|
|
208844
|
-
function recordClaudeReadinessVerdict(readiness) {
|
|
208845
|
-
const code = claudeReadinessReasonCode(readiness.reason);
|
|
208846
|
-
latestVerdict = code === null ? null : {
|
|
208847
|
-
code,
|
|
208848
|
-
expiredAt: expiredAtFromReadinessMessage(readiness.lastErrorMessage)
|
|
208849
|
-
};
|
|
208850
|
-
}
|
|
208851
|
-
/**
|
|
208852
|
-
* What the provider status card says about a delivered credential it cannot
|
|
208853
|
-
* use. Names the expiry only when a readiness answer supplied the time; a
|
|
208854
|
-
* guessed time would be worse than the generic sentence.
|
|
208855
|
-
*/
|
|
208856
|
-
function claudeNativeCredentialUnusableMessage() {
|
|
208857
|
-
const verdict = latestVerdict;
|
|
208858
|
-
if (verdict?.code === "CREDENTIAL_EXPIRED_REFRESHING" && verdict.expiredAt !== null) return claudeCredentialExpiredCardCopy(verdict.expiredAt);
|
|
208859
|
-
return CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY;
|
|
208860
|
-
}
|
|
208861
|
-
//#endregion
|
|
208862
208931
|
//#region src/provider/personalClaudeInVm.ts
|
|
208863
208932
|
/**
|
|
208864
208933
|
* CMMD writes this marker when it activates a personal Claude subscription
|
|
@@ -208926,18 +208995,6 @@ function supportsFable51ClaudeCli(version) {
|
|
|
208926
208995
|
function modelsForClaudeCliVersion(models, version) {
|
|
208927
208996
|
return supportsFable51ClaudeCli(version) ? models : models.filter((model) => model.slug !== "claude-fable-5-1");
|
|
208928
208997
|
}
|
|
208929
|
-
function hasUsableNativeClaudeCredential(value) {
|
|
208930
|
-
try {
|
|
208931
|
-
const parsed = JSON.parse(value);
|
|
208932
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return false;
|
|
208933
|
-
const oauth = parsed.claudeAiOauth;
|
|
208934
|
-
if (typeof oauth !== "object" || oauth === null || Array.isArray(oauth)) return false;
|
|
208935
|
-
const record = oauth;
|
|
208936
|
-
return [record.accessToken, record.refreshToken].some((token) => typeof token === "string" && token.trim().length > 0);
|
|
208937
|
-
} catch {
|
|
208938
|
-
return false;
|
|
208939
|
-
}
|
|
208940
|
-
}
|
|
208941
208998
|
function getClaudeModelCapabilities(model) {
|
|
208942
208999
|
return getProviderModelCapabilities(PROVIDER$12, model) ?? DEFAULT_CLAUDE_MODEL_CAPABILITIES;
|
|
208943
209000
|
}
|
|
@@ -209390,7 +209447,7 @@ function claudeVersionProbeTimeoutProvider(input) {
|
|
|
209390
209447
|
const nativeClaudeProviderStatus = require_Schema$1.fn("nativeClaudeProviderStatus")(function* (input) {
|
|
209391
209448
|
const nativeConfigPath = input.configPath ?? (0, node_path.join)((0, node_os.homedir)(), ".claude");
|
|
209392
209449
|
const nativeCredential = yield* require_Schema$1.tryPromise(() => (0, node_fs_promises.readFile)((0, node_path.join)(nativeConfigPath, ".credentials.json"), "utf8")).pipe(require_Schema$1.option);
|
|
209393
|
-
const usable = require_Schema$1.isSome(nativeCredential) ?
|
|
209450
|
+
const usable = require_Schema$1.isSome(nativeCredential) ? hasUsableClaudeCredentialBlob(nativeCredential.value) : false;
|
|
209394
209451
|
return buildServerProvider({
|
|
209395
209452
|
provider: PROVIDER$12,
|
|
209396
209453
|
enabled: input.enabled,
|
|
@@ -227578,44 +227635,40 @@ function readinessFailureIssue(readiness) {
|
|
|
227578
227635
|
if (readiness.connected === false || readiness.deliveryStatus === "stale" || readiness.deliveryStatus === "not_connected") return CLAUDE_READINESS_COPY.invalid;
|
|
227579
227636
|
return CLAUDE_READINESS_COPY.unavailable;
|
|
227580
227637
|
}
|
|
227581
|
-
function generationHash(generationId) {
|
|
227582
|
-
return (0, node_crypto.createHash)("sha256").update(generationId).digest("hex");
|
|
227583
|
-
}
|
|
227584
227638
|
async function assertNativeClaudeRuntimeReady(input) {
|
|
227585
227639
|
if (!GENERATION_HASH_PATTERN.test(input.localGenerationHash)) throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
227640
|
+
const environmentId = EnvironmentId.make(`cmmd-runtime:${input.runtimeId}`);
|
|
227641
|
+
const sprite = {
|
|
227642
|
+
environmentId,
|
|
227643
|
+
runtimeId: input.runtimeId,
|
|
227644
|
+
machineId: input.machineId,
|
|
227645
|
+
credentialEpoch: input.credentialEpoch,
|
|
227646
|
+
localGenerationHash: input.localGenerationHash
|
|
227647
|
+
};
|
|
227586
227648
|
return await withReadinessRetry(async () => {
|
|
227587
227649
|
const readiness = decodeClaudeRuntimeReadiness(await input.fetchReadiness(input.runtimeId));
|
|
227588
227650
|
recordClaudeReadinessVerdict(readiness);
|
|
227589
|
-
return
|
|
227590
|
-
|
|
227591
|
-
|
|
227592
|
-
|
|
227593
|
-
|
|
227594
|
-
|
|
227595
|
-
const deliveryReceipt = parseProviderRuntimeDeliveryReceipt(readiness.deliveryReceipt, {
|
|
227596
|
-
provider: "anthropic",
|
|
227597
|
-
runtimeId: authority.runtimeId,
|
|
227598
|
-
machineId: authority.machineId,
|
|
227599
|
-
credentialEpoch: authority.credentialEpoch,
|
|
227600
|
-
expiresAt: readiness.deliveryReceipt?.expiresAt ?? null
|
|
227651
|
+
return bindingFromProviderReadiness(await queryProviderReadiness({
|
|
227652
|
+
environmentId,
|
|
227653
|
+
provider: "claudeAgent",
|
|
227654
|
+
sprite,
|
|
227655
|
+
claude: { fetch: async () => readiness }
|
|
227656
|
+
}), readiness);
|
|
227601
227657
|
});
|
|
227602
|
-
if (!isMatchingClaudeReceipt(deliveryReceipt, generationId)) throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
227603
|
-
return providerDeliveryBindingFromReceipt(deliveryReceipt);
|
|
227604
227658
|
}
|
|
227605
|
-
function
|
|
227606
|
-
if (
|
|
227607
|
-
|
|
227608
|
-
|
|
227609
|
-
"pending",
|
|
227610
|
-
"claimed",
|
|
227611
|
-
"activating"
|
|
227612
|
-
].includes(readiness.deliveryStatus));
|
|
227613
|
-
throw new ClaudeRuntimeReadinessError(readinessFailureIssue(readiness), retryable, refreshing ? "credentialRefresh" : "default");
|
|
227659
|
+
function bindingFromProviderReadiness(result, snapshot) {
|
|
227660
|
+
if (result.kind === "ready") {
|
|
227661
|
+
if (result.binding === null) throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
227662
|
+
return result.binding;
|
|
227614
227663
|
}
|
|
227615
|
-
|
|
227616
|
-
|
|
227617
|
-
|
|
227618
|
-
|
|
227664
|
+
if (result.kind === "query_failed") throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
227665
|
+
const refreshing = isCredentialRefreshInFlight(snapshot);
|
|
227666
|
+
const retryable = !isRuntimeUnavailable(snapshot) && (refreshing || [
|
|
227667
|
+
"pending",
|
|
227668
|
+
"claimed",
|
|
227669
|
+
"activating"
|
|
227670
|
+
].includes(snapshot.deliveryStatus));
|
|
227671
|
+
throw new ClaudeRuntimeReadinessError(result.reason === "generation_mismatch" ? CLAUDE_READINESS_COPY.generationMismatch : result.reason === "sprite_identity_drift" ? CLAUDE_READINESS_COPY.unavailable : readinessFailureIssue(snapshot), retryable, refreshing ? "credentialRefresh" : "default");
|
|
227619
227672
|
}
|
|
227620
227673
|
function readinessData(value) {
|
|
227621
227674
|
if (typeof value !== "object" || value === null || !("data" in value)) throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
@@ -292036,7 +292089,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
292036
292089
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
292037
292090
|
*/
|
|
292038
292091
|
function readBakedBuildCommit() {
|
|
292039
|
-
return "
|
|
292092
|
+
return "e94d1f3729cdbbc5b3f87cc2368279c7ef20aec8";
|
|
292040
292093
|
}
|
|
292041
292094
|
async function resolveServerBuildCommit(input) {
|
|
292042
292095
|
if (isFullCommitSha(input.baked)) return input.baked;
|