@cmmd-center/forge 0.13.8 → 0.13.10
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 +330 -50
- package/dist/bin.mjs +330 -50
- package/dist/client/assets/{DiffPanel-CBfeDIH3.js → DiffPanel-aGVgMMDS.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-CZdlskWf.js → DiffPanel.logic-CAL295cZ.js} +2 -2
- package/dist/client/assets/{DiffPanelShell-BnSbIo9A.js → DiffPanelShell-BLRSawDM.js} +114 -114
- package/dist/client/assets/{DiffWorkerPoolProvider-DC4SN57K.js → DiffWorkerPoolProvider-tqcKyIAF.js} +9 -9
- package/dist/client/assets/PullRequestCodePanel-CYLmbiv7.js +5 -0
- package/dist/client/assets/{Virtualizer-ClYwoP30.js → Virtualizer-NYdNfon2.js} +2 -2
- package/dist/client/assets/index-Bx4rqeUi.css +1 -0
- package/dist/client/assets/{index-CZhTqk2p.js → index-fNpsmaLQ.js} +61 -60
- package/dist/client/index.html +5 -5
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/PullRequestCodePanel-DwjjRPkc.js +0 -5
- package/dist/client/assets/index-BE83u7Db.css +0 -1
package/dist/bin.cjs
CHANGED
|
@@ -66289,7 +66289,7 @@ function normalizeNumberish(value) {
|
|
|
66289
66289
|
}
|
|
66290
66290
|
//#endregion
|
|
66291
66291
|
//#region package.json
|
|
66292
|
-
var version$1 = "0.13.
|
|
66292
|
+
var version$1 = "0.13.10";
|
|
66293
66293
|
//#endregion
|
|
66294
66294
|
//#region src/sentry.ts
|
|
66295
66295
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -88064,14 +88064,18 @@ function resolveRuntimeGitHubGrantAuthFromEnv(headers) {
|
|
|
88064
88064
|
}
|
|
88065
88065
|
function buildCmmdRuntimeGrantFetchRequest(auth, repoFullName) {
|
|
88066
88066
|
return {
|
|
88067
|
-
url: new URL(`/api/forge/runtimes/${encodeURIComponent(auth.runtimeId)}/
|
|
88067
|
+
url: new URL(`/api/forge/runtimes/${encodeURIComponent(auth.runtimeId)}/scm/credential`, resolveCommandAppUrl()).toString(),
|
|
88068
88068
|
init: {
|
|
88069
88069
|
method: "POST",
|
|
88070
88070
|
headers: {
|
|
88071
88071
|
Authorization: `Bearer ${auth.token}`,
|
|
88072
88072
|
"Content-Type": "application/json"
|
|
88073
88073
|
},
|
|
88074
|
-
body: JSON.stringify({
|
|
88074
|
+
body: JSON.stringify({
|
|
88075
|
+
provider: "github",
|
|
88076
|
+
host: "github.com",
|
|
88077
|
+
repository_path: repoFullName
|
|
88078
|
+
})
|
|
88075
88079
|
}
|
|
88076
88080
|
};
|
|
88077
88081
|
}
|
|
@@ -88533,10 +88537,19 @@ function fetchInstallationTokenForAuth(auth, repoFullName) {
|
|
|
88533
88537
|
ok: false,
|
|
88534
88538
|
...lastError
|
|
88535
88539
|
};
|
|
88536
|
-
if (tokenResp.ok)
|
|
88537
|
-
|
|
88538
|
-
token
|
|
88539
|
-
|
|
88540
|
+
if (tokenResp.ok) {
|
|
88541
|
+
const tokenData = yield* require_Schema$1.promise(() => tokenResp.json());
|
|
88542
|
+
const token = auth.kind === "cmmd-runtime-ticket" ? tokenData.credential : tokenData.token;
|
|
88543
|
+
if (typeof token === "string" && token.trim().length > 0) return {
|
|
88544
|
+
ok: true,
|
|
88545
|
+
token: token.trim()
|
|
88546
|
+
};
|
|
88547
|
+
return {
|
|
88548
|
+
ok: false,
|
|
88549
|
+
status: 502,
|
|
88550
|
+
error: "CMMD returned an invalid source-control credential response."
|
|
88551
|
+
};
|
|
88552
|
+
}
|
|
88540
88553
|
const err = yield* require_Schema$1.promise(() => tokenResp.json().catch(() => ({})));
|
|
88541
88554
|
lastError = {
|
|
88542
88555
|
status: tokenResp.status,
|
|
@@ -89458,23 +89471,38 @@ var GitHubBroker = class {
|
|
|
89458
89471
|
async cloneRepository(auth, input) {
|
|
89459
89472
|
const cloneInput = validateCloneInput(input);
|
|
89460
89473
|
if ("ok" in cloneInput) return cloneInput;
|
|
89461
|
-
|
|
89474
|
+
let { branch } = cloneInput;
|
|
89462
89475
|
const gitToken = await this.resolveInstallationToken(auth, input.repoFullName);
|
|
89463
89476
|
if (typeof gitToken !== "string") return gitToken;
|
|
89464
|
-
|
|
89477
|
+
try {
|
|
89478
|
+
await (0, node_fs_promises.mkdir)(input.destination);
|
|
89479
|
+
} catch (error) {
|
|
89480
|
+
if (isNodeErrorWithCode(error, "EEXIST")) return cloneDestinationExistsResult();
|
|
89481
|
+
return {
|
|
89482
|
+
ok: false,
|
|
89483
|
+
code: "GITHUB_CLONE_DESTINATION_CREATE_FAILED",
|
|
89484
|
+
error: "Could not create the clone destination."
|
|
89485
|
+
};
|
|
89486
|
+
}
|
|
89487
|
+
const initFailure = await this.runCloneGitStep(branch === null ? ["init", input.destination] : [
|
|
89465
89488
|
"init",
|
|
89466
89489
|
"-b",
|
|
89467
89490
|
branch,
|
|
89468
89491
|
input.destination
|
|
89469
89492
|
], "GITHUB_CLONE_INIT_FAILED", "Could not initialize the clone destination.");
|
|
89470
|
-
if (initFailure) return initFailure;
|
|
89493
|
+
if (initFailure) return removeFailedCloneDestination(input.destination, initFailure);
|
|
89471
89494
|
const configured = await this.configureProjectGitCredential({
|
|
89472
89495
|
cwd: input.destination,
|
|
89473
89496
|
repoFullName: input.repoFullName,
|
|
89474
89497
|
token: gitToken,
|
|
89475
89498
|
remoteMode: "add"
|
|
89476
89499
|
});
|
|
89477
|
-
if (!configured.ok) return configured;
|
|
89500
|
+
if (!configured.ok) return removeFailedCloneDestination(input.destination, configured);
|
|
89501
|
+
if (branch === null) {
|
|
89502
|
+
const defaultBranch = await this.resolveRemoteDefaultBranch(input.destination);
|
|
89503
|
+
if (typeof defaultBranch !== "string") return removeFailedCloneDestination(input.destination, defaultBranch);
|
|
89504
|
+
branch = defaultBranch;
|
|
89505
|
+
}
|
|
89478
89506
|
const fetchFailure = await this.runCloneGitStep([
|
|
89479
89507
|
"-C",
|
|
89480
89508
|
input.destination,
|
|
@@ -89484,7 +89512,7 @@ var GitHubBroker = class {
|
|
|
89484
89512
|
"origin",
|
|
89485
89513
|
branch
|
|
89486
89514
|
], "GITHUB_CLONE_FETCH_FAILED", "Could not fetch the requested repository branch.", { timeoutMs: 12e4 });
|
|
89487
|
-
if (fetchFailure) return fetchFailure;
|
|
89515
|
+
if (fetchFailure) return removeFailedCloneDestination(input.destination, fetchFailure);
|
|
89488
89516
|
const checkoutFailure = await this.runCloneGitStep([
|
|
89489
89517
|
"-C",
|
|
89490
89518
|
input.destination,
|
|
@@ -89493,7 +89521,7 @@ var GitHubBroker = class {
|
|
|
89493
89521
|
branch,
|
|
89494
89522
|
"FETCH_HEAD"
|
|
89495
89523
|
], "GITHUB_CLONE_CHECKOUT_FAILED", "Could not check out the requested repository branch.");
|
|
89496
|
-
if (checkoutFailure) return checkoutFailure;
|
|
89524
|
+
if (checkoutFailure) return removeFailedCloneDestination(input.destination, checkoutFailure);
|
|
89497
89525
|
return {
|
|
89498
89526
|
ok: true,
|
|
89499
89527
|
data: {
|
|
@@ -90103,7 +90131,7 @@ var GitHubBroker = class {
|
|
|
90103
90131
|
};
|
|
90104
90132
|
}
|
|
90105
90133
|
async resolveInstallationToken(auth, repoFullName) {
|
|
90106
|
-
const runtimeGrant = this.resolveRuntimeGrant();
|
|
90134
|
+
const runtimeGrant = this.resolveRuntimeGrant("github");
|
|
90107
90135
|
if (runtimeGrant) {
|
|
90108
90136
|
const token = await this.fetchRuntimeInstallationToken(runtimeGrant, repoFullName);
|
|
90109
90137
|
if (!token.ok) return token;
|
|
@@ -90488,7 +90516,7 @@ var GitHubBroker = class {
|
|
|
90488
90516
|
repoFullName
|
|
90489
90517
|
};
|
|
90490
90518
|
}
|
|
90491
|
-
resolveRuntimeGrant() {
|
|
90519
|
+
resolveRuntimeGrant(requiredScope = "github") {
|
|
90492
90520
|
if (this.runtimeRole !== "user-vm") return null;
|
|
90493
90521
|
const runtimeId = process.env.FORGE_CMMD_RUNTIME_ID?.trim();
|
|
90494
90522
|
if (!runtimeId) return null;
|
|
@@ -90498,7 +90526,7 @@ var GitHubBroker = class {
|
|
|
90498
90526
|
runtimeId,
|
|
90499
90527
|
machineId: identity.machineId,
|
|
90500
90528
|
credentialEpoch: identity.credentialEpoch,
|
|
90501
|
-
requiredScope
|
|
90529
|
+
requiredScope
|
|
90502
90530
|
});
|
|
90503
90531
|
return authority ? {
|
|
90504
90532
|
runtimeId,
|
|
@@ -90512,8 +90540,8 @@ var GitHubBroker = class {
|
|
|
90512
90540
|
token: legacyToken
|
|
90513
90541
|
} : null;
|
|
90514
90542
|
}
|
|
90515
|
-
runtimeGrantAuthContext() {
|
|
90516
|
-
const grant = this.resolveRuntimeGrant();
|
|
90543
|
+
runtimeGrantAuthContext(requiredScope = "github") {
|
|
90544
|
+
const grant = this.resolveRuntimeGrant(requiredScope);
|
|
90517
90545
|
if (grant === null) return null;
|
|
90518
90546
|
return {
|
|
90519
90547
|
sessionId: grant.sessionId ?? AuthSessionId.make(`cmmd-runtime:${grant.runtimeId}`),
|
|
@@ -90565,13 +90593,21 @@ var GitHubBroker = class {
|
|
|
90565
90593
|
};
|
|
90566
90594
|
}
|
|
90567
90595
|
async fetchRuntimeInstallationToken(grant, repoFullName) {
|
|
90568
|
-
|
|
90596
|
+
return this.fetchRuntimeCredential(grant, {
|
|
90597
|
+
url: makeUrl(this.commandAppUrl, `/api/forge/runtimes/${encodeURIComponent(grant.runtimeId)}/github/installation-token`),
|
|
90598
|
+
requestBody: { repo_full_name: repoFullName },
|
|
90599
|
+
responseField: "token",
|
|
90600
|
+
label: "GitHub installation token"
|
|
90601
|
+
});
|
|
90602
|
+
}
|
|
90603
|
+
async fetchRuntimeCredential(grant, input) {
|
|
90604
|
+
const response = await this.fetchImpl(input.url, {
|
|
90569
90605
|
method: "POST",
|
|
90570
90606
|
headers: {
|
|
90571
90607
|
Authorization: `Bearer ${grant.token}`,
|
|
90572
90608
|
"Content-Type": "application/json"
|
|
90573
90609
|
},
|
|
90574
|
-
body: JSON.stringify(
|
|
90610
|
+
body: JSON.stringify(input.requestBody),
|
|
90575
90611
|
signal: AbortSignal.timeout(GITHUB_BROKER_REQUEST_TIMEOUT_MS)
|
|
90576
90612
|
});
|
|
90577
90613
|
const body = await parseResponseBody(response);
|
|
@@ -90580,10 +90616,10 @@ var GitHubBroker = class {
|
|
|
90580
90616
|
status: response.status,
|
|
90581
90617
|
code: response.status === 401 ? "GITHUB_AUTH_REQUIRED" : "GITHUB_BROKER_REQUEST_FAILED",
|
|
90582
90618
|
...response.status === 401 ? { userActionRequired: "connect_github" } : {},
|
|
90583
|
-
error: errorFromBody(body,
|
|
90619
|
+
error: errorFromBody(body, `${input.label} request failed with status ${response.status}.`),
|
|
90584
90620
|
data: body
|
|
90585
90621
|
};
|
|
90586
|
-
const token = typeof body === "object" && body !== null ? body.
|
|
90622
|
+
const token = typeof body === "object" && body !== null ? body[input.responseField] : null;
|
|
90587
90623
|
if (typeof token !== "string" || token.trim().length === 0) return invalidInstallationTokenResult();
|
|
90588
90624
|
return {
|
|
90589
90625
|
ok: true,
|
|
@@ -90602,6 +90638,25 @@ var GitHubBroker = class {
|
|
|
90602
90638
|
const branch = result.result.stdout.trim();
|
|
90603
90639
|
return branch.length > 0 ? branch : null;
|
|
90604
90640
|
}
|
|
90641
|
+
async resolveRemoteDefaultBranch(cwd) {
|
|
90642
|
+
const result = await this.runGit([
|
|
90643
|
+
"-C",
|
|
90644
|
+
cwd,
|
|
90645
|
+
"ls-remote",
|
|
90646
|
+
"--symref",
|
|
90647
|
+
"origin",
|
|
90648
|
+
"HEAD"
|
|
90649
|
+
], { allowNonZeroExit: true });
|
|
90650
|
+
if (!isGitRunResult(result)) return result;
|
|
90651
|
+
if (result.result.code !== 0) return gitCommandFailure("GITHUB_DEFAULT_BRANCH_LOOKUP_FAILED", result.result.stderr, "Could not determine the repository default branch.");
|
|
90652
|
+
const branch = /^ref:\s+refs\/heads\/([^\s]+)\s+HEAD$/m.exec(result.result.stdout)?.[1];
|
|
90653
|
+
if (branch === void 0) return {
|
|
90654
|
+
ok: false,
|
|
90655
|
+
code: "GITHUB_DEFAULT_BRANCH_RESPONSE_INVALID",
|
|
90656
|
+
error: "GitHub did not return a valid default branch for the repository."
|
|
90657
|
+
};
|
|
90658
|
+
return validateGitBranchName(branch) ?? branch;
|
|
90659
|
+
}
|
|
90605
90660
|
};
|
|
90606
90661
|
function isCmmdCloudRuntimeModeEnv() {
|
|
90607
90662
|
return process.env.FORGE_CMMD_RUNTIME_MODE === "true" || process.env.FORGE_CMMD_RUNTIME_MODE === "1";
|
|
@@ -90686,20 +90741,40 @@ function validateCloneDestination(destination) {
|
|
|
90686
90741
|
code: "GITHUB_CLONE_DESTINATION_INVALID",
|
|
90687
90742
|
error: "An absolute clone destination is required."
|
|
90688
90743
|
};
|
|
90689
|
-
if ((0, node_fs.existsSync)(destination)) return
|
|
90744
|
+
if ((0, node_fs.existsSync)(destination)) return cloneDestinationExistsResult();
|
|
90745
|
+
return null;
|
|
90746
|
+
}
|
|
90747
|
+
function cloneDestinationExistsResult() {
|
|
90748
|
+
return {
|
|
90690
90749
|
ok: false,
|
|
90691
90750
|
code: "GITHUB_CLONE_DESTINATION_EXISTS",
|
|
90692
90751
|
error: "Clone destination already exists; choose a new empty path."
|
|
90693
90752
|
};
|
|
90694
|
-
|
|
90753
|
+
}
|
|
90754
|
+
function isNodeErrorWithCode(error, code) {
|
|
90755
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
90756
|
+
}
|
|
90757
|
+
async function removeFailedCloneDestination(destination, failure) {
|
|
90758
|
+
try {
|
|
90759
|
+
await (0, node_fs_promises.rm)(destination, {
|
|
90760
|
+
recursive: true,
|
|
90761
|
+
force: true
|
|
90762
|
+
});
|
|
90763
|
+
return failure;
|
|
90764
|
+
} catch {
|
|
90765
|
+
return {
|
|
90766
|
+
...failure,
|
|
90767
|
+
error: `${failure.error ?? "Clone failed."} The incomplete clone destination could not be removed.`
|
|
90768
|
+
};
|
|
90769
|
+
}
|
|
90695
90770
|
}
|
|
90696
90771
|
function validateCloneInput(input) {
|
|
90697
90772
|
const repoFullNameValidation = validateRepoFullName(input.repoFullName);
|
|
90698
90773
|
if (repoFullNameValidation) return repoFullNameValidation;
|
|
90699
90774
|
const destinationValidation = validateCloneDestination(input.destination);
|
|
90700
90775
|
if (destinationValidation) return destinationValidation;
|
|
90701
|
-
const branch = input.branch?.trim() ||
|
|
90702
|
-
return validateGitBranchName(branch) ?? { branch };
|
|
90776
|
+
const branch = input.branch?.trim() || null;
|
|
90777
|
+
return branch === null ? { branch } : validateGitBranchName(branch) ?? { branch };
|
|
90703
90778
|
}
|
|
90704
90779
|
function validateGitBranchName(branch) {
|
|
90705
90780
|
if (branch.length === 0 || branch.startsWith("-") || Array.from(branch).some((character) => {
|
|
@@ -93872,6 +93947,17 @@ const admitNormalizedDispatchCommand = (command, admit) => require_Schema$1.unin
|
|
|
93872
93947
|
//#region src/orchestration/bootstrapCommandCoordinator.ts
|
|
93873
93948
|
const MAX_COMPLETED_COMMANDS_PER_ENGINE = 256;
|
|
93874
93949
|
const commandsByEngine = /* @__PURE__ */ new WeakMap();
|
|
93950
|
+
const sealBootstrapCommand = (engine, commandId) => {
|
|
93951
|
+
const entry = commandsByEngine.get(engine)?.get(commandId);
|
|
93952
|
+
if (entry) entry.cancellable = false;
|
|
93953
|
+
};
|
|
93954
|
+
const cancelBootstrapCommand = (engine, threadId) => require_Schema$1.promise(async () => {
|
|
93955
|
+
const entry = [...commandsByEngine.get(engine)?.values() ?? []].find((candidate) => candidate.threadId === threadId && !candidate.completed && candidate.cancellable);
|
|
93956
|
+
if (!entry) return false;
|
|
93957
|
+
entry.controller.abort();
|
|
93958
|
+
await entry.promise.catch(() => void 0);
|
|
93959
|
+
return true;
|
|
93960
|
+
});
|
|
93875
93961
|
const toBootstrapError = (error) => require_Schema$1.is(OrchestrationDispatchCommandError)(error) ? error : new OrchestrationDispatchCommandError({
|
|
93876
93962
|
message: error instanceof Error ? error.message : "Bootstrap command failed.",
|
|
93877
93963
|
cause: error
|
|
@@ -93891,7 +93977,7 @@ const pruneCompletedCommands = (commands) => {
|
|
|
93891
93977
|
* the registry to one server runtime, so reconnects share work while separate
|
|
93892
93978
|
* runtimes remain isolated.
|
|
93893
93979
|
*/
|
|
93894
|
-
const runBootstrapCommand = (engine, commandId, bootstrapEffect) => {
|
|
93980
|
+
const runBootstrapCommand = (engine, commandId, bootstrapEffect, threadId) => {
|
|
93895
93981
|
let commands = commandsByEngine.get(engine);
|
|
93896
93982
|
if (commands === void 0) {
|
|
93897
93983
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -93904,16 +93990,21 @@ const runBootstrapCommand = (engine, commandId, bootstrapEffect) => {
|
|
|
93904
93990
|
});
|
|
93905
93991
|
pruneCompletedCommands(commands);
|
|
93906
93992
|
let entry;
|
|
93907
|
-
const
|
|
93993
|
+
const controller = new AbortController();
|
|
93994
|
+
const promise = Promise.resolve().then(() => require_Schema$1.runPromise(bootstrapEffect, { signal: controller.signal })).then((result) => {
|
|
93908
93995
|
entry.completed = true;
|
|
93909
93996
|
return result;
|
|
93910
93997
|
}, (error) => {
|
|
93911
|
-
|
|
93998
|
+
entry.completed = true;
|
|
93999
|
+
if (!controller.signal.aborted) commands.delete(commandId);
|
|
93912
94000
|
throw error;
|
|
93913
94001
|
});
|
|
93914
94002
|
entry = {
|
|
93915
94003
|
promise,
|
|
93916
|
-
completed: false
|
|
94004
|
+
completed: false,
|
|
94005
|
+
threadId,
|
|
94006
|
+
controller,
|
|
94007
|
+
cancellable: true
|
|
93917
94008
|
};
|
|
93918
94009
|
commands.set(commandId, entry);
|
|
93919
94010
|
return require_Schema$1.tryPromise({
|
|
@@ -93923,6 +94014,10 @@ const runBootstrapCommand = (engine, commandId, bootstrapEffect) => {
|
|
|
93923
94014
|
};
|
|
93924
94015
|
//#endregion
|
|
93925
94016
|
//#region src/orchestration/bootstrapDispatch.ts
|
|
94017
|
+
const interruptBootstrapTurnStart = (engine, command) => require_Schema$1.gen(function* () {
|
|
94018
|
+
if (yield* cancelBootstrapCommand(engine, command.threadId)) return { sequence: (yield* engine.getReadModel()).snapshotSequence };
|
|
94019
|
+
return yield* engine.dispatch(command);
|
|
94020
|
+
});
|
|
93926
94021
|
const MAX_BOOTSTRAP_OUTPUT_LINE_LENGTH = 1e3;
|
|
93927
94022
|
const toBootstrapDispatchCommandCauseError = (cause) => {
|
|
93928
94023
|
const error = require_Schema$1.squash(cause);
|
|
@@ -94009,6 +94104,7 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
94009
94104
|
const requestedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
94010
94105
|
const baseBranchLabel = bootstrapWorktree.baseBranch ?? "<default>";
|
|
94011
94106
|
const requestedPayload = {
|
|
94107
|
+
turnRequestedAt: input.command.createdAt,
|
|
94012
94108
|
projectCwd: bootstrapWorktree.projectCwd,
|
|
94013
94109
|
baseBranch: bootstrapWorktree.baseBranch,
|
|
94014
94110
|
branch: bootstrapWorktree.branch,
|
|
@@ -94029,6 +94125,16 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
94029
94125
|
branch: bootstrapWorktree.baseBranch,
|
|
94030
94126
|
newBranch: bootstrapWorktree.branch,
|
|
94031
94127
|
path: null,
|
|
94128
|
+
onStage: (update) => appendWorktreeActivity({
|
|
94129
|
+
orchestrationEngine: input.orchestrationEngine,
|
|
94130
|
+
threadId: input.command.threadId,
|
|
94131
|
+
commandId: CommandId.make(`server:worktree-stage:${input.command.commandId}:${crypto.randomUUID()}`),
|
|
94132
|
+
kind: "worktree.stage",
|
|
94133
|
+
summary: "Preparing worktree",
|
|
94134
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94135
|
+
payload: update,
|
|
94136
|
+
tone: "info"
|
|
94137
|
+
}).pipe(require_Schema$1.asVoid, require_Schema$1.ignore),
|
|
94032
94138
|
progress: {
|
|
94033
94139
|
onStdoutLine: (line) => {
|
|
94034
94140
|
const detail = truncateBootstrapOutputLine(line);
|
|
@@ -94068,6 +94174,7 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
94068
94174
|
}
|
|
94069
94175
|
}
|
|
94070
94176
|
}).pipe(require_Schema$1.catchCause((cause) => {
|
|
94177
|
+
if (require_Schema$1.hasInterruptsOnly(cause)) return require_Schema$1.failCause(cause);
|
|
94071
94178
|
const error = require_Schema$1.squash(cause);
|
|
94072
94179
|
const detail = error instanceof Error ? error.message : "Unknown worktree failure.";
|
|
94073
94180
|
return appendWorktreeActivity({
|
|
@@ -94194,7 +94301,16 @@ const dispatchBootstrapTurnStart = (input, command) => require_Schema$1.gen(func
|
|
|
94194
94301
|
worktreePath
|
|
94195
94302
|
}),
|
|
94196
94303
|
onSuccess: (setupResult) => {
|
|
94197
|
-
if (setupResult.status !== "started") return
|
|
94304
|
+
if (setupResult.status !== "started") return appendSetupScriptActivity({
|
|
94305
|
+
orchestrationEngine,
|
|
94306
|
+
threadId: command.threadId,
|
|
94307
|
+
commandId: bootstrapCommandId(command, "setup-script-skipped"),
|
|
94308
|
+
kind: "setup-script.skipped",
|
|
94309
|
+
summary: "No setup script configured",
|
|
94310
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94311
|
+
payload: {},
|
|
94312
|
+
tone: "info"
|
|
94313
|
+
}).pipe(require_Schema$1.asVoid, require_Schema$1.ignore);
|
|
94198
94314
|
return recordSetupScriptStarted({
|
|
94199
94315
|
requestedAt,
|
|
94200
94316
|
worktreePath,
|
|
@@ -94224,13 +94340,33 @@ const dispatchBootstrapTurnStart = (input, command) => require_Schema$1.gen(func
|
|
|
94224
94340
|
targetProjectCwd = preparedWorktree.projectCwd;
|
|
94225
94341
|
}
|
|
94226
94342
|
yield* runSetupProgram();
|
|
94343
|
+
if (bootstrap?.prepareWorktree) yield* appendWorktreeActivity({
|
|
94344
|
+
orchestrationEngine,
|
|
94345
|
+
threadId: command.threadId,
|
|
94346
|
+
commandId: bootstrapCommandId(command, "launch-agent-starting"),
|
|
94347
|
+
kind: "launch.agent-starting",
|
|
94348
|
+
summary: "Starting agent",
|
|
94349
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94350
|
+
payload: { setupRequested: bootstrap.runSetupScript === true },
|
|
94351
|
+
tone: "info"
|
|
94352
|
+
}).pipe(require_Schema$1.ignore);
|
|
94353
|
+
sealBootstrapCommand(orchestrationEngine, command.commandId);
|
|
94227
94354
|
return yield* orchestrationEngine.dispatch(finalTurnStartCommand);
|
|
94228
94355
|
});
|
|
94229
|
-
return yield* runBootstrapCommand(orchestrationEngine, command.commandId, bootstrapProgram.pipe(require_Schema$1.
|
|
94356
|
+
return yield* runBootstrapCommand(orchestrationEngine, command.commandId, bootstrapProgram.pipe(require_Schema$1.onInterrupt(() => appendWorktreeActivity({
|
|
94357
|
+
orchestrationEngine,
|
|
94358
|
+
threadId: command.threadId,
|
|
94359
|
+
commandId: bootstrapCommandId(command, "launch-cancelled"),
|
|
94360
|
+
kind: "launch.cancelled",
|
|
94361
|
+
summary: "Launch cancelled",
|
|
94362
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94363
|
+
payload: {},
|
|
94364
|
+
tone: "info"
|
|
94365
|
+
}).pipe(require_Schema$1.ignore)), require_Schema$1.catchCause((cause) => {
|
|
94230
94366
|
const dispatchError = toBootstrapDispatchCommandCauseError(cause);
|
|
94231
94367
|
if (require_Schema$1.hasInterruptsOnly(cause)) return require_Schema$1.fail(dispatchError);
|
|
94232
94368
|
return cleanupCreatedThread().pipe(require_Schema$1.flatMap(() => require_Schema$1.fail(dispatchError)));
|
|
94233
|
-
})));
|
|
94369
|
+
})), command.threadId);
|
|
94234
94370
|
});
|
|
94235
94371
|
//#endregion
|
|
94236
94372
|
//#region src/orchestration/Services/OrchestrationEngine.ts
|
|
@@ -100946,6 +101082,7 @@ function emptyConfig(source, path) {
|
|
|
100946
101082
|
terminals: [],
|
|
100947
101083
|
systemPackages: [],
|
|
100948
101084
|
secrets: [],
|
|
101085
|
+
repositoryDependencies: [],
|
|
100949
101086
|
issues: []
|
|
100950
101087
|
};
|
|
100951
101088
|
}
|
|
@@ -101031,6 +101168,7 @@ function readConfigFile(source, path) {
|
|
|
101031
101168
|
terminals: terminalsFromValue(parsed.terminals),
|
|
101032
101169
|
systemPackages: stringArray(parsed.systemPackages ?? parsed.aptPackages ?? parsed.packages),
|
|
101033
101170
|
secrets: stringArray(parsed.secrets ?? parsed.envSecrets),
|
|
101171
|
+
repositoryDependencies: stringArray(parsed.repositoryDependencies),
|
|
101034
101172
|
issues: []
|
|
101035
101173
|
};
|
|
101036
101174
|
}
|
|
@@ -101443,6 +101581,7 @@ const EMPTY_WORKSPACE_ENVIRONMENT_CONFIG = {
|
|
|
101443
101581
|
terminals: [],
|
|
101444
101582
|
systemPackages: [],
|
|
101445
101583
|
secrets: [],
|
|
101584
|
+
repositoryDependencies: [],
|
|
101446
101585
|
issues: []
|
|
101447
101586
|
};
|
|
101448
101587
|
function buildCwdCheck(cwdExists) {
|
|
@@ -106250,7 +106389,7 @@ const makeWsRpcLayer = (currentSessionId, currentUserId) => WsRpcGroup.toLayer(r
|
|
|
106250
106389
|
git,
|
|
106251
106390
|
gitStatusBroadcaster,
|
|
106252
106391
|
projectSetupScriptRunner
|
|
106253
|
-
}, normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand).pipe(require_Schema$1.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
|
|
106392
|
+
}, normalizedCommand) : (normalizedCommand.type === "thread.turn.interrupt" ? interruptBootstrapTurnStart(orchestrationEngine, normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand)).pipe(require_Schema$1.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
|
|
106254
106393
|
return startup.enqueueCommand(dispatchEffect).pipe(require_Schema$1.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
|
|
106255
106394
|
};
|
|
106256
106395
|
const loadServerConfig = require_Schema$1.gen(function* () {
|
|
@@ -151620,6 +151759,86 @@ async function attestCodexLocalAccountIdentity(input) {
|
|
|
151620
151759
|
return identity;
|
|
151621
151760
|
}
|
|
151622
151761
|
//#endregion
|
|
151762
|
+
//#region src/workspace/workspaceRepositoryDependencies.ts
|
|
151763
|
+
function repositoryFullName(value) {
|
|
151764
|
+
return value.trim().match(/^(?:https?:\/\/)?github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?\/?$/i)?.[1] ?? null;
|
|
151765
|
+
}
|
|
151766
|
+
function dependencyDestination(cloudProjectsRoot, repoFullName) {
|
|
151767
|
+
const root = (0, node_path.resolve)(cloudProjectsRoot);
|
|
151768
|
+
const destination = (0, node_path.resolve)((0, node_path.join)(root, (0, node_path.basename)(repoFullName)));
|
|
151769
|
+
const pathFromRoot = (0, node_path.relative)(root, destination);
|
|
151770
|
+
if (pathFromRoot.startsWith("..") || pathFromRoot === "") throw new Error(`Repository dependency ${repoFullName} has an unsafe destination.`);
|
|
151771
|
+
return destination;
|
|
151772
|
+
}
|
|
151773
|
+
async function readOriginFromGit(destination) {
|
|
151774
|
+
const result = await runProcess("git", [
|
|
151775
|
+
"-C",
|
|
151776
|
+
destination,
|
|
151777
|
+
"remote",
|
|
151778
|
+
"get-url",
|
|
151779
|
+
"origin"
|
|
151780
|
+
], {
|
|
151781
|
+
allowNonZeroExit: true,
|
|
151782
|
+
timeoutMs: 1e4
|
|
151783
|
+
});
|
|
151784
|
+
return result.code === 0 ? result.stdout.trim() : null;
|
|
151785
|
+
}
|
|
151786
|
+
function resolveRepositoryDependencies(declarations, cloudProjectsRoot) {
|
|
151787
|
+
const destinations = /* @__PURE__ */ new Set();
|
|
151788
|
+
return declarations.map((declaration) => {
|
|
151789
|
+
const repoFullName = repositoryFullName(declaration);
|
|
151790
|
+
if (repoFullName === null) throw new Error(`Unsupported repository dependency: ${declaration}`);
|
|
151791
|
+
const destination = dependencyDestination(cloudProjectsRoot, repoFullName);
|
|
151792
|
+
if (destinations.has(destination)) throw new Error(`Repository dependencies collide at ${destination}.`);
|
|
151793
|
+
destinations.add(destination);
|
|
151794
|
+
return {
|
|
151795
|
+
repoFullName,
|
|
151796
|
+
destination
|
|
151797
|
+
};
|
|
151798
|
+
});
|
|
151799
|
+
}
|
|
151800
|
+
async function prepareRepositoryDependency(input) {
|
|
151801
|
+
const { repoFullName, destination } = input.dependency;
|
|
151802
|
+
if ((0, node_fs.existsSync)(destination)) {
|
|
151803
|
+
const origin = await input.readOrigin(destination);
|
|
151804
|
+
const existingRepo = origin === null ? null : parseRepoFullNameFromRemoteUrl(origin);
|
|
151805
|
+
if (existingRepo?.toLowerCase() !== repoFullName.toLowerCase()) throw new Error(`Repository dependency destination ${destination} contains ${existingRepo ?? "no GitHub repository"} instead of ${repoFullName}.`);
|
|
151806
|
+
return {
|
|
151807
|
+
repoFullName,
|
|
151808
|
+
destination,
|
|
151809
|
+
outcome: "existing"
|
|
151810
|
+
};
|
|
151811
|
+
}
|
|
151812
|
+
const result = await input.broker.cloneRepository(input.auth, {
|
|
151813
|
+
repoFullName,
|
|
151814
|
+
destination
|
|
151815
|
+
});
|
|
151816
|
+
if (!result.ok) throw new Error(`Could not prepare repository dependency ${repoFullName}: ${result.error ?? result.code ?? "clone failed"}`);
|
|
151817
|
+
return {
|
|
151818
|
+
repoFullName,
|
|
151819
|
+
destination,
|
|
151820
|
+
outcome: "cloned"
|
|
151821
|
+
};
|
|
151822
|
+
}
|
|
151823
|
+
async function prepareWorkspaceRepositoryDependencies(input) {
|
|
151824
|
+
if (!input.runtimeMode) return [];
|
|
151825
|
+
const dependencies = resolveWorkspaceEnvironmentConfig(input.cwd).repositoryDependencies;
|
|
151826
|
+
if (dependencies.length === 0) return [];
|
|
151827
|
+
const broker = input.broker ?? new GitHubBroker();
|
|
151828
|
+
const auth = broker.runtimeGrantAuthContext("github");
|
|
151829
|
+
if (auth === null) throw new Error("Repository dependencies require an exact scoped runtime GitHub grant.");
|
|
151830
|
+
const readOrigin = input.readOrigin ?? readOriginFromGit;
|
|
151831
|
+
const resolved = resolveRepositoryDependencies(dependencies, input.cloudProjectsRoot);
|
|
151832
|
+
const prepared = [];
|
|
151833
|
+
for (const dependency of resolved) prepared.push(await prepareRepositoryDependency({
|
|
151834
|
+
dependency,
|
|
151835
|
+
broker,
|
|
151836
|
+
auth,
|
|
151837
|
+
readOrigin
|
|
151838
|
+
}));
|
|
151839
|
+
return prepared;
|
|
151840
|
+
}
|
|
151841
|
+
//#endregion
|
|
151623
151842
|
//#region src/codexAppServerManager.ts
|
|
151624
151843
|
const CODEX_LOGIN_STATUS_TIMEOUT_MS = 5e3;
|
|
151625
151844
|
const CODEX_SKILLS_LIST_TIMEOUT_MS = 4e3;
|
|
@@ -151954,6 +152173,11 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
|
|
|
151954
152173
|
let context;
|
|
151955
152174
|
try {
|
|
151956
152175
|
const resolvedCwd = input.cwd ?? process.cwd();
|
|
152176
|
+
await prepareWorkspaceRepositoryDependencies({
|
|
152177
|
+
cwd: resolvedCwd,
|
|
152178
|
+
cloudProjectsRoot: process.env.FORGE_CLOUD_PROJECTS_ROOT?.trim() || "/projects",
|
|
152179
|
+
runtimeMode: process.env.FORGE_CMMD_RUNTIME_MODE === "true"
|
|
152180
|
+
});
|
|
151957
152181
|
let workspacePreflightReport = runWorkspaceEnvironmentPreflight({
|
|
151958
152182
|
cwd: resolvedCwd,
|
|
151959
152183
|
env: process.env
|
|
@@ -217040,6 +217264,19 @@ const makeClaudeAdapter = require_Schema$1.fn("makeClaudeAdapter")(function* (op
|
|
|
217040
217264
|
const resumeState = readClaudeResumeState(input.resumeCursor);
|
|
217041
217265
|
const threadId = input.threadId;
|
|
217042
217266
|
const { existingResumeSessionId, newSessionId, sessionId } = yield* resolveClaudeStartSessionIds(resumeState);
|
|
217267
|
+
const workspaceCwd = input.cwd;
|
|
217268
|
+
if (workspaceCwd) yield* require_Schema$1.tryPromise({
|
|
217269
|
+
try: () => prepareWorkspaceRepositoryDependencies({
|
|
217270
|
+
cwd: workspaceCwd,
|
|
217271
|
+
cloudProjectsRoot: serverConfig.cloudProjectsRoot ?? "/projects",
|
|
217272
|
+
runtimeMode: serverConfig.forgeCmmdRuntimeMode === true
|
|
217273
|
+
}),
|
|
217274
|
+
catch: (cause) => new ProviderAdapterValidationError({
|
|
217275
|
+
provider: PROVIDER$11,
|
|
217276
|
+
operation: "startSession",
|
|
217277
|
+
issue: cause instanceof Error ? cause.message : "Could not prepare declared repository dependencies."
|
|
217278
|
+
})
|
|
217279
|
+
});
|
|
217043
217280
|
const runtimeContext = yield* require_Schema$1.context();
|
|
217044
217281
|
const runFork = require_Schema$1.runForkWith(runtimeContext);
|
|
217045
217282
|
const runPromise = require_Schema$1.runPromiseWith(runtimeContext);
|
|
@@ -233379,12 +233616,12 @@ const collectOutput = require_Schema$1.fn("collectOutput")(function* (input, str
|
|
|
233379
233616
|
let lineBuffer = "";
|
|
233380
233617
|
let truncated = false;
|
|
233381
233618
|
const emitCompleteLines = require_Schema$1.fn("emitCompleteLines")(function* (flush) {
|
|
233382
|
-
let newlineIndex = lineBuffer.
|
|
233619
|
+
let newlineIndex = lineBuffer.search(/[\r\n]/);
|
|
233383
233620
|
while (newlineIndex >= 0) {
|
|
233384
233621
|
const line = lineBuffer.slice(0, newlineIndex).replace(/\r$/, "");
|
|
233385
233622
|
lineBuffer = lineBuffer.slice(newlineIndex + 1);
|
|
233386
233623
|
if (line.length > 0 && onLine) yield* onLine(line);
|
|
233387
|
-
newlineIndex = lineBuffer.
|
|
233624
|
+
newlineIndex = lineBuffer.search(/[\r\n]/);
|
|
233388
233625
|
}
|
|
233389
233626
|
if (flush) {
|
|
233390
233627
|
const trailing = lineBuffer.replace(/\r$/, "");
|
|
@@ -233533,6 +233770,7 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
233533
233770
|
operation,
|
|
233534
233771
|
cwd,
|
|
233535
233772
|
args,
|
|
233773
|
+
...options.env ? { env: options.env } : {},
|
|
233536
233774
|
...options.stdin !== void 0 ? { stdin: options.stdin } : {},
|
|
233537
233775
|
allowNonZeroExit: true,
|
|
233538
233776
|
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
|
|
@@ -234256,12 +234494,19 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
234256
234494
|
};
|
|
234257
234495
|
});
|
|
234258
234496
|
const createWorktree = require_Schema$1.fn("createWorktree")(function* (input) {
|
|
234497
|
+
const report = (stage, status, detail) => input.onStage?.({
|
|
234498
|
+
stage,
|
|
234499
|
+
status,
|
|
234500
|
+
...detail ? { detail } : {}
|
|
234501
|
+
}) ?? require_Schema$1.void_;
|
|
234502
|
+
yield* report("resolve", "running");
|
|
234259
234503
|
const base = input.branch ?? (yield* resolveDefaultBaseBranch(input.cwd));
|
|
234260
234504
|
const startPoint = yield* resolveWorktreeStartPoint({
|
|
234261
234505
|
cwd: input.cwd,
|
|
234262
234506
|
base,
|
|
234263
234507
|
creatingNewBranch: input.newBranch !== void 0
|
|
234264
234508
|
});
|
|
234509
|
+
yield* report("resolve", "done", startPoint);
|
|
234265
234510
|
const targetBranch = input.newBranch ?? base;
|
|
234266
234511
|
const sanitizedBranch = targetBranch.replace(/\//g, "-");
|
|
234267
234512
|
const repoName = path.basename(input.cwd);
|
|
@@ -234273,7 +234518,10 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
234273
234518
|
limit: 200
|
|
234274
234519
|
})).branches.find((branch) => branch.isRemote !== true && branch.name === targetBranch && branch.worktreePath !== null && node_path.default.resolve(branch.worktreePath) === canonicalWorktreePath);
|
|
234275
234520
|
if (existingBranch?.worktreePath) {
|
|
234521
|
+
yield* report("checkout", "skipped", "Existing worktree");
|
|
234522
|
+
yield* report("dependencies", "running");
|
|
234276
234523
|
yield* setupSharedWorktreeDependencies(input.cwd, existingBranch.worktreePath);
|
|
234524
|
+
yield* report("dependencies", "done");
|
|
234277
234525
|
return { worktree: {
|
|
234278
234526
|
path: worktreePath,
|
|
234279
234527
|
branch: targetBranch
|
|
@@ -234292,11 +234540,19 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
234292
234540
|
worktreePath,
|
|
234293
234541
|
startPoint
|
|
234294
234542
|
];
|
|
234543
|
+
yield* report("checkout", "running");
|
|
234295
234544
|
yield* executeGit("GitCore.createWorktree", input.cwd, args, {
|
|
234296
234545
|
fallbackErrorMessage: "git worktree add failed",
|
|
234546
|
+
env: {
|
|
234547
|
+
GIT_PROGRESS_DELAY: "0",
|
|
234548
|
+
LC_ALL: "C"
|
|
234549
|
+
},
|
|
234297
234550
|
...input.progress ? { progress: input.progress } : {}
|
|
234298
234551
|
});
|
|
234552
|
+
yield* report("checkout", "done");
|
|
234553
|
+
yield* report("dependencies", "running");
|
|
234299
234554
|
yield* setupSharedWorktreeDependencies(input.cwd, worktreePath);
|
|
234555
|
+
yield* report("dependencies", "done");
|
|
234300
234556
|
return { worktree: {
|
|
234301
234557
|
path: worktreePath,
|
|
234302
234558
|
branch: targetBranch
|
|
@@ -297109,7 +297365,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
297109
297365
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
297110
297366
|
*/
|
|
297111
297367
|
function readBakedBuildCommit() {
|
|
297112
|
-
return "
|
|
297368
|
+
return "d9a524e82e63dd163e8f06083c14b5913b6fdf88";
|
|
297113
297369
|
}
|
|
297114
297370
|
async function resolveServerBuildCommit(input) {
|
|
297115
297371
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -298935,6 +299191,10 @@ const AuthSessionRepositoryLive = require_Schema$1.effect(AuthSessionRepository,
|
|
|
298935
299191
|
const SIGNING_SECRET_NAME = "server-signing-key";
|
|
298936
299192
|
const DEFAULT_SESSION_TTL = require_Schema$1.days(30);
|
|
298937
299193
|
const DEFAULT_WEBSOCKET_TOKEN_TTL = require_Schema$1.minutes(5);
|
|
299194
|
+
const toSessionCredentialError = (message) => (cause) => new SessionCredentialError({
|
|
299195
|
+
message,
|
|
299196
|
+
cause
|
|
299197
|
+
});
|
|
298938
299198
|
const SessionClaims = require_Schema$1.Struct({
|
|
298939
299199
|
v: require_Schema$1.Literal(1),
|
|
298940
299200
|
kind: require_Schema$1.Literal("session"),
|
|
@@ -298991,10 +299251,6 @@ const makeSessionCredentialService = require_Schema$1.gen(function* () {
|
|
|
298991
299251
|
port: serverConfig.port,
|
|
298992
299252
|
host: serverConfig.host
|
|
298993
299253
|
});
|
|
298994
|
-
const toSessionCredentialError = (message) => (cause) => new SessionCredentialError({
|
|
298995
|
-
message,
|
|
298996
|
-
cause
|
|
298997
|
-
});
|
|
298998
299254
|
const emitUpsert = (clientSession) => require_Path.publish(changesPubSub, {
|
|
298999
299255
|
type: "clientUpserted",
|
|
299000
299256
|
clientSession
|
|
@@ -299155,15 +299411,28 @@ const makeSessionCredentialService = require_Schema$1.gen(function* () {
|
|
|
299155
299411
|
if (require_Schema$1.isSome(row)) {
|
|
299156
299412
|
if (row.value.revokedAt !== null) return yield* new SessionCredentialError({ message: "Websocket session revoked." });
|
|
299157
299413
|
if (row.value.expiresAt.epochMilliseconds <= now) return yield* new SessionCredentialError({ message: "Websocket session expired." });
|
|
299158
|
-
} else
|
|
299414
|
+
} else {
|
|
299415
|
+
const cloudOwnerSession = serverConfig.forgeCloudShellMode === true && claims.method === "proxy-asserted" && forgeCloudOwnerSessionExpiresAt(claims.sid) !== null;
|
|
299416
|
+
if (cloudOwnerSession && isExpiredForgeCloudOwnerSession(claims.sid, now)) return yield* new SessionCredentialError({ message: "Websocket session expired." });
|
|
299417
|
+
if (statelessCookieSessions && (claims.method === "browser-session-cookie" || cloudOwnerSession)) return {
|
|
299418
|
+
sessionId: claims.sid,
|
|
299419
|
+
token,
|
|
299420
|
+
method: claims.method,
|
|
299421
|
+
client: createDefaultClientMetadata(),
|
|
299422
|
+
expiresAt: require_Schema$1.makeUnsafe(claims.exp),
|
|
299423
|
+
subject: claims.sub,
|
|
299424
|
+
role: claims.role
|
|
299425
|
+
};
|
|
299426
|
+
return yield* new SessionCredentialError({ message: "Unknown websocket session." });
|
|
299427
|
+
}
|
|
299159
299428
|
return {
|
|
299160
299429
|
sessionId: claims.sid,
|
|
299161
299430
|
token,
|
|
299162
|
-
method:
|
|
299163
|
-
client:
|
|
299164
|
-
expiresAt:
|
|
299165
|
-
subject:
|
|
299166
|
-
role:
|
|
299431
|
+
method: row.value.method,
|
|
299432
|
+
client: toClientMetadata(row.value.client),
|
|
299433
|
+
expiresAt: row.value.expiresAt,
|
|
299434
|
+
subject: row.value.subject,
|
|
299435
|
+
role: row.value.role
|
|
299167
299436
|
};
|
|
299168
299437
|
}).pipe(require_Schema$1.mapError((cause) => cause instanceof SessionCredentialError ? cause : new SessionCredentialError({
|
|
299169
299438
|
message: "Failed to verify websocket token.",
|
|
@@ -299441,6 +299710,18 @@ function verifyForgeCloudOwnerCallbackAssertion(assertion, config) {
|
|
|
299441
299710
|
//#endregion
|
|
299442
299711
|
//#region src/auth/Layers/ServerAuth.ts
|
|
299443
299712
|
const AUTHORIZATION_PREFIX = "Bearer ";
|
|
299713
|
+
function classifyWebSocketTokenFailure(cause) {
|
|
299714
|
+
switch (cause.message) {
|
|
299715
|
+
case "Malformed websocket token.": return "malformed";
|
|
299716
|
+
case "Invalid websocket token signature.": return "invalid_signature";
|
|
299717
|
+
case "Invalid websocket token payload.": return "invalid_payload";
|
|
299718
|
+
case "Websocket token expired.": return "expired_token";
|
|
299719
|
+
case "Websocket session revoked.": return "revoked_parent_session";
|
|
299720
|
+
case "Websocket session expired.": return "expired_parent_session";
|
|
299721
|
+
case "Unknown websocket session.": return "unknown_parent_session";
|
|
299722
|
+
default: return "verification_failed";
|
|
299723
|
+
}
|
|
299724
|
+
}
|
|
299444
299725
|
function toBootstrapExchangeAuthError(cause) {
|
|
299445
299726
|
if (cause.status === 500) return new AuthError({
|
|
299446
299727
|
message: "Failed to validate bootstrap credential.",
|
|
@@ -299743,7 +300024,6 @@ const makeServerAuth = require_Schema$1.gen(function* () {
|
|
|
299743
300024
|
expiresAt: require_Schema$1.toUtc(issued.expiresAt)
|
|
299744
300025
|
})));
|
|
299745
300026
|
const authenticateWebSocketUpgrade = (request) => require_Schema$1.gen(function* () {
|
|
299746
|
-
if (serverConfig.forgeCloudShellMode === true) return yield* authenticateRequest(request);
|
|
299747
300027
|
if (serverConfig.forgeCmmdRuntimeMode) {
|
|
299748
300028
|
if (serverConfig.forgeCmmdAuthRuntime) {
|
|
299749
300029
|
const authConfig = readCmmdAuthRuntimeConfig(serverConfig);
|
|
@@ -299800,7 +300080,7 @@ const makeServerAuth = require_Schema$1.gen(function* () {
|
|
|
299800
300080
|
const requestUrl = require_HttpServer.toURL(request);
|
|
299801
300081
|
if (require_Schema$1.isSome(requestUrl)) {
|
|
299802
300082
|
const websocketToken = readWebSocketUpgradeToken(requestUrl.value.searchParams);
|
|
299803
|
-
if (websocketToken) return yield* sessions.verifyWebSocketToken(websocketToken).pipe(require_Schema$1.map((session) => ({
|
|
300083
|
+
if (websocketToken) return yield* sessions.verifyWebSocketToken(websocketToken).pipe(require_Schema$1.tapError((cause) => require_Schema$1.logWarning("Rejected websocket token.").pipe(require_Schema$1.annotateLogs({ category: classifyWebSocketTokenFailure(cause) }))), require_Schema$1.map((session) => ({
|
|
299804
300084
|
sessionId: session.sessionId,
|
|
299805
300085
|
subject: session.subject,
|
|
299806
300086
|
method: session.method,
|
|
@@ -305889,7 +306169,7 @@ const orchestrationDispatchRouteLayer = add$1("POST", "/api/orchestration/dispat
|
|
|
305889
306169
|
}).pipe(require_Schema$1.mapError((cause) => new OrchestrationDispatchCommandError({
|
|
305890
306170
|
message: "Failed to dispatch orchestration command.",
|
|
305891
306171
|
cause
|
|
305892
|
-
}))) : orchestrationEngine.dispatch(normalizedCommand).pipe(require_Schema$1.mapError((cause) => new OrchestrationDispatchCommandError({
|
|
306172
|
+
}))) : (normalizedCommand.type === "thread.turn.interrupt" ? interruptBootstrapTurnStart(orchestrationEngine, normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand)).pipe(require_Schema$1.mapError((cause) => new OrchestrationDispatchCommandError({
|
|
305893
306173
|
message: "Failed to dispatch orchestration command.",
|
|
305894
306174
|
cause
|
|
305895
306175
|
})));
|