@cmmd-center/forge 0.10.7 → 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 +395 -324
- package/dist/bin.mjs +395 -324
- package/dist/client/assets/{DiffPanel-BqOO3dsl.js → DiffPanel-xCfkBV0D.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-Bzm8oiCr.js → DiffPanel.logic-BfOamVHM.js} +2 -2
- package/dist/client/assets/DiffPanelShell-B6MeDvYA.js +2531 -0
- package/dist/client/assets/{DiffWorkerPoolProvider-BsMgSHbg.js → DiffWorkerPoolProvider-C-r-Zusj.js} +9 -9
- package/dist/client/assets/{PullRequestCodePanel-DNrNrubs.js → PullRequestCodePanel-BSLzdOzf.js} +3 -3
- package/dist/client/assets/{Virtualizer-RRV_x18w.js → Virtualizer-4ILVlhCf.js} +2 -2
- package/dist/client/assets/{index-D22UpSjv.css → index-CUmbThfW.css} +1 -1
- package/dist/client/assets/index-CjhPsbaL.js +151 -0
- package/dist/client/index.html +13 -6
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/DiffPanelShell-DVVw1mR3.js +0 -2531
- package/dist/client/assets/index-DCVtRkq1.js +0 -151
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;
|
|
@@ -207361,6 +207506,7 @@ function toCanonicalItemType(raw) {
|
|
|
207361
207506
|
if (type.includes("computer")) return "mcp_tool_call";
|
|
207362
207507
|
if (type.includes("mcp")) return "mcp_tool_call";
|
|
207363
207508
|
if (type.includes("dynamic tool")) return "dynamic_tool_call";
|
|
207509
|
+
if (type.includes("sub agent")) return "collab_agent_tool_call";
|
|
207364
207510
|
if (type.includes("collab")) return "collab_agent_tool_call";
|
|
207365
207511
|
if (type.includes("web search")) return "web_search";
|
|
207366
207512
|
if (type.includes("image")) return "image_view";
|
|
@@ -207425,6 +207571,21 @@ function itemDetail(item, payload) {
|
|
|
207425
207571
|
return trimmed;
|
|
207426
207572
|
}
|
|
207427
207573
|
}
|
|
207574
|
+
const SUB_AGENT_ACTIVITY_TITLE = "Subagent";
|
|
207575
|
+
/**
|
|
207576
|
+
* The text a subagent spawn shows in the timeline.
|
|
207577
|
+
*
|
|
207578
|
+
* A `SubAgentActivity` item carries only the agent path, the child thread id,
|
|
207579
|
+
* and whether the spawn started or completed. `itemDetail` reads none of those
|
|
207580
|
+
* fields, and both the started and the completed item arrive as `item/completed`,
|
|
207581
|
+
* so the lifecycle status cannot tell them apart either. Without this the row
|
|
207582
|
+
* renders as a bare title with no text under it. The app-server wire is
|
|
207583
|
+
* camelCase and the rollout file is snake_case, so read both.
|
|
207584
|
+
*/
|
|
207585
|
+
function subAgentActivityDetail(item) {
|
|
207586
|
+
const parts = [asString$2(item.agentPath)?.trim() || asString$2(item.agent_path)?.trim(), asString$2(item.kind)?.trim()].filter((part) => part !== void 0 && part.length > 0);
|
|
207587
|
+
return parts.length > 0 ? parts.join(" ") : void 0;
|
|
207588
|
+
}
|
|
207428
207589
|
function toRequestTypeFromMethod(method) {
|
|
207429
207590
|
switch (method) {
|
|
207430
207591
|
case "item/commandExecution/requestApproval": return "command_execution_approval";
|
|
@@ -207596,7 +207757,9 @@ function mapItemLifecycle(event, canonicalThreadId, lifecycle) {
|
|
|
207596
207757
|
if ((itemType === "mcp_tool_call" || itemType === "dynamic_tool_call") && (isBrowserToolName(source.name) || isBrowserToolName(source.toolName) || isBrowserToolName(source.method) || isBrowserToolName(payload?.toolName) || isBrowserToolName(payload?.method))) itemType = "browser_automation";
|
|
207597
207758
|
if ((itemType === "unknown" || itemType === "mcp_tool_call" || itemType === "dynamic_tool_call") && (isComputerToolName(source.name) || isComputerToolName(source.toolName) || isComputerToolName(source.method) || isComputerToolName(payload?.toolName) || isComputerToolName(payload?.method))) itemType = "mcp_tool_call";
|
|
207598
207759
|
if (itemType === "unknown" && lifecycle !== "item.updated") return;
|
|
207599
|
-
const
|
|
207760
|
+
const subAgentDetail = normalizeItemType(source.type).includes("sub agent") ? subAgentActivityDetail(source) : void 0;
|
|
207761
|
+
const detail = subAgentDetail ?? itemDetail(source, payload ?? {});
|
|
207762
|
+
const title = subAgentDetail ? SUB_AGENT_ACTIVITY_TITLE : itemTitle(itemType);
|
|
207600
207763
|
const status = lifecycle === "item.started" ? "inProgress" : lifecycle === "item.completed" ? "completed" : void 0;
|
|
207601
207764
|
return {
|
|
207602
207765
|
...runtimeEventBase(event, canonicalThreadId),
|
|
@@ -207604,7 +207767,7 @@ function mapItemLifecycle(event, canonicalThreadId, lifecycle) {
|
|
|
207604
207767
|
payload: {
|
|
207605
207768
|
itemType,
|
|
207606
207769
|
...status ? { status } : {},
|
|
207607
|
-
...
|
|
207770
|
+
...title ? { title } : {},
|
|
207608
207771
|
...detail ? { detail } : {},
|
|
207609
207772
|
...event.payload !== void 0 ? { data: event.payload } : {}
|
|
207610
207773
|
}
|
|
@@ -208765,82 +208928,6 @@ const makeProviderAuthProvenance = (input) => {
|
|
|
208765
208928
|
};
|
|
208766
208929
|
};
|
|
208767
208930
|
//#endregion
|
|
208768
|
-
//#region src/provider/claudeReadinessReason.ts
|
|
208769
|
-
/**
|
|
208770
|
-
* The reason literals Forge has copy for, confirmed against CMMD-36441's
|
|
208771
|
-
* readiness service. If the route renames one, the rename lands here as a
|
|
208772
|
-
* fall-through to the generic sentence, never as a wrong sentence.
|
|
208773
|
-
*
|
|
208774
|
-
* Reading the reason is what makes `stale` legible. CMMD-36441 answers
|
|
208775
|
-
* `credential_reconnect_required` on a `stale` answer that still reports
|
|
208776
|
-
* `connected: true`, and the older `credential_generation_not_applied` on a
|
|
208777
|
-
* `stale` answer that simply has not landed yet. Those want opposite
|
|
208778
|
-
* sentences, and both used to get "Reconnect Claude in Settings" because the
|
|
208779
|
-
* guard read only the delivery status.
|
|
208780
|
-
*/
|
|
208781
|
-
const CODE_BY_UPSTREAM_REASON$1 = {
|
|
208782
|
-
credential_expired_refreshing: "CREDENTIAL_EXPIRED_REFRESHING",
|
|
208783
|
-
credential_reconnect_required: "CREDENTIAL_RECONNECT_REQUIRED",
|
|
208784
|
-
credential_not_connected: "CREDENTIAL_RECONNECT_REQUIRED",
|
|
208785
|
-
credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED",
|
|
208786
|
-
runtime_unavailable: "RUNTIME_UNAVAILABLE"
|
|
208787
|
-
};
|
|
208788
|
-
const CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY = "The delivered Claude credential is unavailable or unusable in this runtime.";
|
|
208789
|
-
/**
|
|
208790
|
-
* An ISO 8601 instant, with or without fractional seconds, UTC or offset.
|
|
208791
|
-
* Anchored to nothing on purpose: CMMD wraps the time in a sentence, and the
|
|
208792
|
-
* time is the only part of that sentence Forge repeats.
|
|
208793
|
-
*/
|
|
208794
|
-
const ISO_INSTANT_PATTERN = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})/;
|
|
208795
|
-
function claudeReadinessReasonCode(reason) {
|
|
208796
|
-
if (typeof reason !== "string" || !Object.hasOwn(CODE_BY_UPSTREAM_REASON$1, reason)) return null;
|
|
208797
|
-
return CODE_BY_UPSTREAM_REASON$1[reason] ?? null;
|
|
208798
|
-
}
|
|
208799
|
-
function expiredAtFromReadinessMessage(message) {
|
|
208800
|
-
if (typeof message !== "string") return null;
|
|
208801
|
-
return ISO_INSTANT_PATTERN.exec(message)?.[0] ?? null;
|
|
208802
|
-
}
|
|
208803
|
-
function claudeCredentialExpiredTurnCopy(expiredAt) {
|
|
208804
|
-
return `The delivered Claude credential expired at ${expiredAt}. CMMD is delivering a refreshed one, so retry this turn in a moment.`;
|
|
208805
|
-
}
|
|
208806
|
-
function claudeCredentialExpiredCardCopy(expiredAt) {
|
|
208807
|
-
return `The delivered Claude credential expired at ${expiredAt}. CMMD is delivering a refreshed one to this runtime.`;
|
|
208808
|
-
}
|
|
208809
|
-
/**
|
|
208810
|
-
* The last allowlisted readiness reason this process saw.
|
|
208811
|
-
*
|
|
208812
|
-
* A server process serves exactly one runtime, so one slot is the whole store.
|
|
208813
|
-
* It holds a reason code and a timestamp, never credential bytes. The provider
|
|
208814
|
-
* catalog reads a local credential file and cannot tell an expired snapshot
|
|
208815
|
-
* from a blank one, so without this the card can only offer the generic
|
|
208816
|
-
* sentence while the guard already knows better.
|
|
208817
|
-
*/
|
|
208818
|
-
let latestVerdict = null;
|
|
208819
|
-
/**
|
|
208820
|
-
* Remember, or clear, what the readiness answer said.
|
|
208821
|
-
*
|
|
208822
|
-
* An answer carrying no allowlisted reason clears the slot, which is what makes
|
|
208823
|
-
* the card go back to the generic sentence the moment CMMD applies a
|
|
208824
|
-
* credential: an applied answer carries no reason.
|
|
208825
|
-
*/
|
|
208826
|
-
function recordClaudeReadinessVerdict(readiness) {
|
|
208827
|
-
const code = claudeReadinessReasonCode(readiness.reason);
|
|
208828
|
-
latestVerdict = code === null ? null : {
|
|
208829
|
-
code,
|
|
208830
|
-
expiredAt: expiredAtFromReadinessMessage(readiness.lastErrorMessage)
|
|
208831
|
-
};
|
|
208832
|
-
}
|
|
208833
|
-
/**
|
|
208834
|
-
* What the provider status card says about a delivered credential it cannot
|
|
208835
|
-
* use. Names the expiry only when a readiness answer supplied the time; a
|
|
208836
|
-
* guessed time would be worse than the generic sentence.
|
|
208837
|
-
*/
|
|
208838
|
-
function claudeNativeCredentialUnusableMessage() {
|
|
208839
|
-
const verdict = latestVerdict;
|
|
208840
|
-
if (verdict?.code === "CREDENTIAL_EXPIRED_REFRESHING" && verdict.expiredAt !== null) return claudeCredentialExpiredCardCopy(verdict.expiredAt);
|
|
208841
|
-
return CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY;
|
|
208842
|
-
}
|
|
208843
|
-
//#endregion
|
|
208844
208931
|
//#region src/provider/personalClaudeInVm.ts
|
|
208845
208932
|
/**
|
|
208846
208933
|
* CMMD writes this marker when it activates a personal Claude subscription
|
|
@@ -208908,18 +208995,6 @@ function supportsFable51ClaudeCli(version) {
|
|
|
208908
208995
|
function modelsForClaudeCliVersion(models, version) {
|
|
208909
208996
|
return supportsFable51ClaudeCli(version) ? models : models.filter((model) => model.slug !== "claude-fable-5-1");
|
|
208910
208997
|
}
|
|
208911
|
-
function hasUsableNativeClaudeCredential(value) {
|
|
208912
|
-
try {
|
|
208913
|
-
const parsed = JSON.parse(value);
|
|
208914
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return false;
|
|
208915
|
-
const oauth = parsed.claudeAiOauth;
|
|
208916
|
-
if (typeof oauth !== "object" || oauth === null || Array.isArray(oauth)) return false;
|
|
208917
|
-
const record = oauth;
|
|
208918
|
-
return [record.accessToken, record.refreshToken].some((token) => typeof token === "string" && token.trim().length > 0);
|
|
208919
|
-
} catch {
|
|
208920
|
-
return false;
|
|
208921
|
-
}
|
|
208922
|
-
}
|
|
208923
208998
|
function getClaudeModelCapabilities(model) {
|
|
208924
208999
|
return getProviderModelCapabilities(PROVIDER$12, model) ?? DEFAULT_CLAUDE_MODEL_CAPABILITIES;
|
|
208925
209000
|
}
|
|
@@ -209372,7 +209447,7 @@ function claudeVersionProbeTimeoutProvider(input) {
|
|
|
209372
209447
|
const nativeClaudeProviderStatus = require_Schema$1.fn("nativeClaudeProviderStatus")(function* (input) {
|
|
209373
209448
|
const nativeConfigPath = input.configPath ?? (0, node_path.join)((0, node_os.homedir)(), ".claude");
|
|
209374
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);
|
|
209375
|
-
const usable = require_Schema$1.isSome(nativeCredential) ?
|
|
209450
|
+
const usable = require_Schema$1.isSome(nativeCredential) ? hasUsableClaudeCredentialBlob(nativeCredential.value) : false;
|
|
209376
209451
|
return buildServerProvider({
|
|
209377
209452
|
provider: PROVIDER$12,
|
|
209378
209453
|
enabled: input.enabled,
|
|
@@ -227560,44 +227635,40 @@ function readinessFailureIssue(readiness) {
|
|
|
227560
227635
|
if (readiness.connected === false || readiness.deliveryStatus === "stale" || readiness.deliveryStatus === "not_connected") return CLAUDE_READINESS_COPY.invalid;
|
|
227561
227636
|
return CLAUDE_READINESS_COPY.unavailable;
|
|
227562
227637
|
}
|
|
227563
|
-
function generationHash(generationId) {
|
|
227564
|
-
return (0, node_crypto.createHash)("sha256").update(generationId).digest("hex");
|
|
227565
|
-
}
|
|
227566
227638
|
async function assertNativeClaudeRuntimeReady(input) {
|
|
227567
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
|
+
};
|
|
227568
227648
|
return await withReadinessRetry(async () => {
|
|
227569
227649
|
const readiness = decodeClaudeRuntimeReadiness(await input.fetchReadiness(input.runtimeId));
|
|
227570
227650
|
recordClaudeReadinessVerdict(readiness);
|
|
227571
|
-
return
|
|
227572
|
-
|
|
227573
|
-
|
|
227574
|
-
|
|
227575
|
-
|
|
227576
|
-
|
|
227577
|
-
const deliveryReceipt = parseProviderRuntimeDeliveryReceipt(readiness.deliveryReceipt, {
|
|
227578
|
-
provider: "anthropic",
|
|
227579
|
-
runtimeId: authority.runtimeId,
|
|
227580
|
-
machineId: authority.machineId,
|
|
227581
|
-
credentialEpoch: authority.credentialEpoch,
|
|
227582
|
-
expiresAt: readiness.deliveryReceipt?.expiresAt ?? null
|
|
227651
|
+
return bindingFromProviderReadiness(await queryProviderReadiness({
|
|
227652
|
+
environmentId,
|
|
227653
|
+
provider: "claudeAgent",
|
|
227654
|
+
sprite,
|
|
227655
|
+
claude: { fetch: async () => readiness }
|
|
227656
|
+
}), readiness);
|
|
227583
227657
|
});
|
|
227584
|
-
if (!isMatchingClaudeReceipt(deliveryReceipt, generationId)) throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
227585
|
-
return providerDeliveryBindingFromReceipt(deliveryReceipt);
|
|
227586
227658
|
}
|
|
227587
|
-
function
|
|
227588
|
-
if (
|
|
227589
|
-
|
|
227590
|
-
|
|
227591
|
-
"pending",
|
|
227592
|
-
"claimed",
|
|
227593
|
-
"activating"
|
|
227594
|
-
].includes(readiness.deliveryStatus));
|
|
227595
|
-
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;
|
|
227596
227663
|
}
|
|
227597
|
-
|
|
227598
|
-
|
|
227599
|
-
|
|
227600
|
-
|
|
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");
|
|
227601
227672
|
}
|
|
227602
227673
|
function readinessData(value) {
|
|
227603
227674
|
if (typeof value !== "object" || value === null || !("data" in value)) throw new ClaudeRuntimeReadinessError(CLAUDE_READINESS_COPY.unavailable);
|
|
@@ -292018,7 +292089,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
292018
292089
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
292019
292090
|
*/
|
|
292020
292091
|
function readBakedBuildCommit() {
|
|
292021
|
-
return "
|
|
292092
|
+
return "e94d1f3729cdbbc5b3f87cc2368279c7ef20aec8";
|
|
292022
292093
|
}
|
|
292023
292094
|
async function resolveServerBuildCommit(input) {
|
|
292024
292095
|
if (isFullCommitSha(input.baked)) return input.baked;
|