@cmmd-center/forge 0.13.7 → 0.13.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 +408 -69
- package/dist/bin.mjs +432 -93
- package/dist/client/assets/{CanvasPanel-C21OO2qi.js → CanvasPanel-z0F-jdf1.js} +2 -2
- package/dist/client/assets/{CompositeItem-naFGUtSL.js → CompositeItem-P9UVXCKv.js} +2 -2
- package/dist/client/assets/{DiffPanel-D_YC838v.js → DiffPanel-DTiRv6A3.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-Bqk_6nE1.js → DiffPanel.logic-BrHjYrbX.js} +2 -2
- package/dist/client/assets/{DiffPanelShell-D1KMJc9z.js → DiffPanelShell-CivZRVc4.js} +114 -114
- package/dist/client/assets/{DiffWorkerPoolProvider-B5tF5UEc.js → DiffWorkerPoolProvider-Vm64F-i1.js} +10 -10
- package/dist/client/assets/{PullRequestCodePanel-ClD3ZXbi.js → PullRequestCodePanel-DJPvOmkY.js} +3 -3
- package/dist/client/assets/{Virtualizer-cvcMb_IQ.js → Virtualizer-CJivXWYL.js} +2 -2
- package/dist/client/assets/{canvasStateStore-CpNOSHBt.js → canvasStateStore-CdQxd2aO.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-DdH7K490.js → cmmdAuthRedirect-Bp1uQaQ9.js} +2 -2
- package/dist/client/assets/{index-BE83u7Db.css → index-DTtOLoW6.css} +1 -1
- package/dist/client/assets/index-TdSTLuh4.js +154 -0
- package/dist/client/assets/{popover-BajtiGgk.js → popover-CUSlb3eK.js} +2 -2
- package/dist/client/assets/{src-D6fBWY6U.js → src-BL-mOkT1.js} +2 -2
- package/dist/client/assets/{toggle-BRNCUuRT.js → toggle-BREV66nT.js} +2 -2
- package/dist/client/index.html +11 -11
- package/dist/forge-build.json +1 -1
- package/dist/{open-D8mGyWmt.mjs → open-FIgTDosf.mjs} +3 -3
- package/package.json +1 -1
- package/dist/client/assets/index-yLc4LtMp.js +0 -153
package/dist/bin.cjs
CHANGED
|
@@ -27083,6 +27083,23 @@ function encodeCmmdRuntimeThreadLifecycleMetadata(lifecycle) {
|
|
|
27083
27083
|
} };
|
|
27084
27084
|
}
|
|
27085
27085
|
//#endregion
|
|
27086
|
+
//#region ../../packages/contracts/src/cmmdRuntimeThreadGoal.ts
|
|
27087
|
+
function encodeCmmdRuntimeThreadGoalMetadata(goal) {
|
|
27088
|
+
return { forgeGoal: {
|
|
27089
|
+
schemaVersion: 1,
|
|
27090
|
+
goal: goal.goal
|
|
27091
|
+
} };
|
|
27092
|
+
}
|
|
27093
|
+
function decodeCmmdRuntimeThreadGoalMetadata(metadata) {
|
|
27094
|
+
const value = metadata?.forgeGoal;
|
|
27095
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
27096
|
+
const record = value;
|
|
27097
|
+
const goal = record.goal;
|
|
27098
|
+
if (record.schemaVersion !== 1 || goal !== null && typeof goal !== "string") return null;
|
|
27099
|
+
if (typeof goal === "string" && goal.trim().length === 0) return null;
|
|
27100
|
+
return { goal };
|
|
27101
|
+
}
|
|
27102
|
+
//#endregion
|
|
27086
27103
|
//#region ../../packages/contracts/src/cmmdRuntimeThreadWorkspace.ts
|
|
27087
27104
|
function encodeCmmdRuntimeThreadWorkspaceMetadata(workspace) {
|
|
27088
27105
|
return { forgeWorkspace: {
|
|
@@ -66272,7 +66289,7 @@ function normalizeNumberish(value) {
|
|
|
66272
66289
|
}
|
|
66273
66290
|
//#endregion
|
|
66274
66291
|
//#region package.json
|
|
66275
|
-
var version$1 = "0.13.
|
|
66292
|
+
var version$1 = "0.13.9";
|
|
66276
66293
|
//#endregion
|
|
66277
66294
|
//#region src/sentry.ts
|
|
66278
66295
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -88047,14 +88064,18 @@ function resolveRuntimeGitHubGrantAuthFromEnv(headers) {
|
|
|
88047
88064
|
}
|
|
88048
88065
|
function buildCmmdRuntimeGrantFetchRequest(auth, repoFullName) {
|
|
88049
88066
|
return {
|
|
88050
|
-
url: new URL(`/api/forge/runtimes/${encodeURIComponent(auth.runtimeId)}/
|
|
88067
|
+
url: new URL(`/api/forge/runtimes/${encodeURIComponent(auth.runtimeId)}/scm/credential`, resolveCommandAppUrl()).toString(),
|
|
88051
88068
|
init: {
|
|
88052
88069
|
method: "POST",
|
|
88053
88070
|
headers: {
|
|
88054
88071
|
Authorization: `Bearer ${auth.token}`,
|
|
88055
88072
|
"Content-Type": "application/json"
|
|
88056
88073
|
},
|
|
88057
|
-
body: JSON.stringify({
|
|
88074
|
+
body: JSON.stringify({
|
|
88075
|
+
provider: "github",
|
|
88076
|
+
host: "github.com",
|
|
88077
|
+
repository_path: repoFullName
|
|
88078
|
+
})
|
|
88058
88079
|
}
|
|
88059
88080
|
};
|
|
88060
88081
|
}
|
|
@@ -88516,10 +88537,19 @@ function fetchInstallationTokenForAuth(auth, repoFullName) {
|
|
|
88516
88537
|
ok: false,
|
|
88517
88538
|
...lastError
|
|
88518
88539
|
};
|
|
88519
|
-
if (tokenResp.ok)
|
|
88520
|
-
|
|
88521
|
-
token
|
|
88522
|
-
|
|
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
|
+
}
|
|
88523
88553
|
const err = yield* require_Schema$1.promise(() => tokenResp.json().catch(() => ({})));
|
|
88524
88554
|
lastError = {
|
|
88525
88555
|
status: tokenResp.status,
|
|
@@ -89441,23 +89471,38 @@ var GitHubBroker = class {
|
|
|
89441
89471
|
async cloneRepository(auth, input) {
|
|
89442
89472
|
const cloneInput = validateCloneInput(input);
|
|
89443
89473
|
if ("ok" in cloneInput) return cloneInput;
|
|
89444
|
-
|
|
89474
|
+
let { branch } = cloneInput;
|
|
89445
89475
|
const gitToken = await this.resolveInstallationToken(auth, input.repoFullName);
|
|
89446
89476
|
if (typeof gitToken !== "string") return gitToken;
|
|
89447
|
-
|
|
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] : [
|
|
89448
89488
|
"init",
|
|
89449
89489
|
"-b",
|
|
89450
89490
|
branch,
|
|
89451
89491
|
input.destination
|
|
89452
89492
|
], "GITHUB_CLONE_INIT_FAILED", "Could not initialize the clone destination.");
|
|
89453
|
-
if (initFailure) return initFailure;
|
|
89493
|
+
if (initFailure) return removeFailedCloneDestination(input.destination, initFailure);
|
|
89454
89494
|
const configured = await this.configureProjectGitCredential({
|
|
89455
89495
|
cwd: input.destination,
|
|
89456
89496
|
repoFullName: input.repoFullName,
|
|
89457
89497
|
token: gitToken,
|
|
89458
89498
|
remoteMode: "add"
|
|
89459
89499
|
});
|
|
89460
|
-
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
|
+
}
|
|
89461
89506
|
const fetchFailure = await this.runCloneGitStep([
|
|
89462
89507
|
"-C",
|
|
89463
89508
|
input.destination,
|
|
@@ -89467,7 +89512,7 @@ var GitHubBroker = class {
|
|
|
89467
89512
|
"origin",
|
|
89468
89513
|
branch
|
|
89469
89514
|
], "GITHUB_CLONE_FETCH_FAILED", "Could not fetch the requested repository branch.", { timeoutMs: 12e4 });
|
|
89470
|
-
if (fetchFailure) return fetchFailure;
|
|
89515
|
+
if (fetchFailure) return removeFailedCloneDestination(input.destination, fetchFailure);
|
|
89471
89516
|
const checkoutFailure = await this.runCloneGitStep([
|
|
89472
89517
|
"-C",
|
|
89473
89518
|
input.destination,
|
|
@@ -89476,7 +89521,7 @@ var GitHubBroker = class {
|
|
|
89476
89521
|
branch,
|
|
89477
89522
|
"FETCH_HEAD"
|
|
89478
89523
|
], "GITHUB_CLONE_CHECKOUT_FAILED", "Could not check out the requested repository branch.");
|
|
89479
|
-
if (checkoutFailure) return checkoutFailure;
|
|
89524
|
+
if (checkoutFailure) return removeFailedCloneDestination(input.destination, checkoutFailure);
|
|
89480
89525
|
return {
|
|
89481
89526
|
ok: true,
|
|
89482
89527
|
data: {
|
|
@@ -90086,9 +90131,9 @@ var GitHubBroker = class {
|
|
|
90086
90131
|
};
|
|
90087
90132
|
}
|
|
90088
90133
|
async resolveInstallationToken(auth, repoFullName) {
|
|
90089
|
-
const runtimeGrant = this.resolveRuntimeGrant();
|
|
90134
|
+
const runtimeGrant = this.resolveRuntimeGrant("scm");
|
|
90090
90135
|
if (runtimeGrant) {
|
|
90091
|
-
const token = await this.
|
|
90136
|
+
const token = await this.fetchRuntimeScmCredential(runtimeGrant, repoFullName);
|
|
90092
90137
|
if (!token.ok) return token;
|
|
90093
90138
|
return token.token ?? invalidInstallationTokenResult();
|
|
90094
90139
|
}
|
|
@@ -90471,7 +90516,7 @@ var GitHubBroker = class {
|
|
|
90471
90516
|
repoFullName
|
|
90472
90517
|
};
|
|
90473
90518
|
}
|
|
90474
|
-
resolveRuntimeGrant() {
|
|
90519
|
+
resolveRuntimeGrant(requiredScope = "github") {
|
|
90475
90520
|
if (this.runtimeRole !== "user-vm") return null;
|
|
90476
90521
|
const runtimeId = process.env.FORGE_CMMD_RUNTIME_ID?.trim();
|
|
90477
90522
|
if (!runtimeId) return null;
|
|
@@ -90481,7 +90526,7 @@ var GitHubBroker = class {
|
|
|
90481
90526
|
runtimeId,
|
|
90482
90527
|
machineId: identity.machineId,
|
|
90483
90528
|
credentialEpoch: identity.credentialEpoch,
|
|
90484
|
-
requiredScope
|
|
90529
|
+
requiredScope
|
|
90485
90530
|
});
|
|
90486
90531
|
return authority ? {
|
|
90487
90532
|
runtimeId,
|
|
@@ -90495,8 +90540,8 @@ var GitHubBroker = class {
|
|
|
90495
90540
|
token: legacyToken
|
|
90496
90541
|
} : null;
|
|
90497
90542
|
}
|
|
90498
|
-
runtimeGrantAuthContext() {
|
|
90499
|
-
const grant = this.resolveRuntimeGrant();
|
|
90543
|
+
runtimeGrantAuthContext(requiredScope = "github") {
|
|
90544
|
+
const grant = this.resolveRuntimeGrant(requiredScope);
|
|
90500
90545
|
if (grant === null) return null;
|
|
90501
90546
|
return {
|
|
90502
90547
|
sessionId: grant.sessionId ?? AuthSessionId.make(`cmmd-runtime:${grant.runtimeId}`),
|
|
@@ -90548,13 +90593,33 @@ var GitHubBroker = class {
|
|
|
90548
90593
|
};
|
|
90549
90594
|
}
|
|
90550
90595
|
async fetchRuntimeInstallationToken(grant, repoFullName) {
|
|
90551
|
-
|
|
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 fetchRuntimeScmCredential(grant, repoFullName) {
|
|
90604
|
+
return this.fetchRuntimeCredential(grant, {
|
|
90605
|
+
url: makeUrl(this.commandAppUrl, `/api/forge/runtimes/${encodeURIComponent(grant.runtimeId)}/scm/credential`),
|
|
90606
|
+
requestBody: {
|
|
90607
|
+
provider: "github",
|
|
90608
|
+
host: "github.com",
|
|
90609
|
+
repository_path: repoFullName
|
|
90610
|
+
},
|
|
90611
|
+
responseField: "credential",
|
|
90612
|
+
label: "GitHub source-control credential"
|
|
90613
|
+
});
|
|
90614
|
+
}
|
|
90615
|
+
async fetchRuntimeCredential(grant, input) {
|
|
90616
|
+
const response = await this.fetchImpl(input.url, {
|
|
90552
90617
|
method: "POST",
|
|
90553
90618
|
headers: {
|
|
90554
90619
|
Authorization: `Bearer ${grant.token}`,
|
|
90555
90620
|
"Content-Type": "application/json"
|
|
90556
90621
|
},
|
|
90557
|
-
body: JSON.stringify(
|
|
90622
|
+
body: JSON.stringify(input.requestBody),
|
|
90558
90623
|
signal: AbortSignal.timeout(GITHUB_BROKER_REQUEST_TIMEOUT_MS)
|
|
90559
90624
|
});
|
|
90560
90625
|
const body = await parseResponseBody(response);
|
|
@@ -90563,10 +90628,10 @@ var GitHubBroker = class {
|
|
|
90563
90628
|
status: response.status,
|
|
90564
90629
|
code: response.status === 401 ? "GITHUB_AUTH_REQUIRED" : "GITHUB_BROKER_REQUEST_FAILED",
|
|
90565
90630
|
...response.status === 401 ? { userActionRequired: "connect_github" } : {},
|
|
90566
|
-
error: errorFromBody(body,
|
|
90631
|
+
error: errorFromBody(body, `${input.label} request failed with status ${response.status}.`),
|
|
90567
90632
|
data: body
|
|
90568
90633
|
};
|
|
90569
|
-
const token = typeof body === "object" && body !== null ? body.
|
|
90634
|
+
const token = typeof body === "object" && body !== null ? body[input.responseField] : null;
|
|
90570
90635
|
if (typeof token !== "string" || token.trim().length === 0) return invalidInstallationTokenResult();
|
|
90571
90636
|
return {
|
|
90572
90637
|
ok: true,
|
|
@@ -90585,6 +90650,25 @@ var GitHubBroker = class {
|
|
|
90585
90650
|
const branch = result.result.stdout.trim();
|
|
90586
90651
|
return branch.length > 0 ? branch : null;
|
|
90587
90652
|
}
|
|
90653
|
+
async resolveRemoteDefaultBranch(cwd) {
|
|
90654
|
+
const result = await this.runGit([
|
|
90655
|
+
"-C",
|
|
90656
|
+
cwd,
|
|
90657
|
+
"ls-remote",
|
|
90658
|
+
"--symref",
|
|
90659
|
+
"origin",
|
|
90660
|
+
"HEAD"
|
|
90661
|
+
], { allowNonZeroExit: true });
|
|
90662
|
+
if (!isGitRunResult(result)) return result;
|
|
90663
|
+
if (result.result.code !== 0) return gitCommandFailure("GITHUB_DEFAULT_BRANCH_LOOKUP_FAILED", result.result.stderr, "Could not determine the repository default branch.");
|
|
90664
|
+
const branch = /^ref:\s+refs\/heads\/([^\s]+)\s+HEAD$/m.exec(result.result.stdout)?.[1];
|
|
90665
|
+
if (branch === void 0) return {
|
|
90666
|
+
ok: false,
|
|
90667
|
+
code: "GITHUB_DEFAULT_BRANCH_RESPONSE_INVALID",
|
|
90668
|
+
error: "GitHub did not return a valid default branch for the repository."
|
|
90669
|
+
};
|
|
90670
|
+
return validateGitBranchName(branch) ?? branch;
|
|
90671
|
+
}
|
|
90588
90672
|
};
|
|
90589
90673
|
function isCmmdCloudRuntimeModeEnv() {
|
|
90590
90674
|
return process.env.FORGE_CMMD_RUNTIME_MODE === "true" || process.env.FORGE_CMMD_RUNTIME_MODE === "1";
|
|
@@ -90669,20 +90753,40 @@ function validateCloneDestination(destination) {
|
|
|
90669
90753
|
code: "GITHUB_CLONE_DESTINATION_INVALID",
|
|
90670
90754
|
error: "An absolute clone destination is required."
|
|
90671
90755
|
};
|
|
90672
|
-
if ((0, node_fs.existsSync)(destination)) return
|
|
90756
|
+
if ((0, node_fs.existsSync)(destination)) return cloneDestinationExistsResult();
|
|
90757
|
+
return null;
|
|
90758
|
+
}
|
|
90759
|
+
function cloneDestinationExistsResult() {
|
|
90760
|
+
return {
|
|
90673
90761
|
ok: false,
|
|
90674
90762
|
code: "GITHUB_CLONE_DESTINATION_EXISTS",
|
|
90675
90763
|
error: "Clone destination already exists; choose a new empty path."
|
|
90676
90764
|
};
|
|
90677
|
-
|
|
90765
|
+
}
|
|
90766
|
+
function isNodeErrorWithCode(error, code) {
|
|
90767
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
90768
|
+
}
|
|
90769
|
+
async function removeFailedCloneDestination(destination, failure) {
|
|
90770
|
+
try {
|
|
90771
|
+
await (0, node_fs_promises.rm)(destination, {
|
|
90772
|
+
recursive: true,
|
|
90773
|
+
force: true
|
|
90774
|
+
});
|
|
90775
|
+
return failure;
|
|
90776
|
+
} catch {
|
|
90777
|
+
return {
|
|
90778
|
+
...failure,
|
|
90779
|
+
error: `${failure.error ?? "Clone failed."} The incomplete clone destination could not be removed.`
|
|
90780
|
+
};
|
|
90781
|
+
}
|
|
90678
90782
|
}
|
|
90679
90783
|
function validateCloneInput(input) {
|
|
90680
90784
|
const repoFullNameValidation = validateRepoFullName(input.repoFullName);
|
|
90681
90785
|
if (repoFullNameValidation) return repoFullNameValidation;
|
|
90682
90786
|
const destinationValidation = validateCloneDestination(input.destination);
|
|
90683
90787
|
if (destinationValidation) return destinationValidation;
|
|
90684
|
-
const branch = input.branch?.trim() ||
|
|
90685
|
-
return validateGitBranchName(branch) ?? { branch };
|
|
90788
|
+
const branch = input.branch?.trim() || null;
|
|
90789
|
+
return branch === null ? { branch } : validateGitBranchName(branch) ?? { branch };
|
|
90686
90790
|
}
|
|
90687
90791
|
function validateGitBranchName(branch) {
|
|
90688
90792
|
if (branch.length === 0 || branch.startsWith("-") || Array.from(branch).some((character) => {
|
|
@@ -93855,6 +93959,17 @@ const admitNormalizedDispatchCommand = (command, admit) => require_Schema$1.unin
|
|
|
93855
93959
|
//#region src/orchestration/bootstrapCommandCoordinator.ts
|
|
93856
93960
|
const MAX_COMPLETED_COMMANDS_PER_ENGINE = 256;
|
|
93857
93961
|
const commandsByEngine = /* @__PURE__ */ new WeakMap();
|
|
93962
|
+
const sealBootstrapCommand = (engine, commandId) => {
|
|
93963
|
+
const entry = commandsByEngine.get(engine)?.get(commandId);
|
|
93964
|
+
if (entry) entry.cancellable = false;
|
|
93965
|
+
};
|
|
93966
|
+
const cancelBootstrapCommand = (engine, threadId) => require_Schema$1.promise(async () => {
|
|
93967
|
+
const entry = [...commandsByEngine.get(engine)?.values() ?? []].find((candidate) => candidate.threadId === threadId && !candidate.completed && candidate.cancellable);
|
|
93968
|
+
if (!entry) return false;
|
|
93969
|
+
entry.controller.abort();
|
|
93970
|
+
await entry.promise.catch(() => void 0);
|
|
93971
|
+
return true;
|
|
93972
|
+
});
|
|
93858
93973
|
const toBootstrapError = (error) => require_Schema$1.is(OrchestrationDispatchCommandError)(error) ? error : new OrchestrationDispatchCommandError({
|
|
93859
93974
|
message: error instanceof Error ? error.message : "Bootstrap command failed.",
|
|
93860
93975
|
cause: error
|
|
@@ -93874,7 +93989,7 @@ const pruneCompletedCommands = (commands) => {
|
|
|
93874
93989
|
* the registry to one server runtime, so reconnects share work while separate
|
|
93875
93990
|
* runtimes remain isolated.
|
|
93876
93991
|
*/
|
|
93877
|
-
const runBootstrapCommand = (engine, commandId, bootstrapEffect) => {
|
|
93992
|
+
const runBootstrapCommand = (engine, commandId, bootstrapEffect, threadId) => {
|
|
93878
93993
|
let commands = commandsByEngine.get(engine);
|
|
93879
93994
|
if (commands === void 0) {
|
|
93880
93995
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -93887,16 +94002,21 @@ const runBootstrapCommand = (engine, commandId, bootstrapEffect) => {
|
|
|
93887
94002
|
});
|
|
93888
94003
|
pruneCompletedCommands(commands);
|
|
93889
94004
|
let entry;
|
|
93890
|
-
const
|
|
94005
|
+
const controller = new AbortController();
|
|
94006
|
+
const promise = Promise.resolve().then(() => require_Schema$1.runPromise(bootstrapEffect, { signal: controller.signal })).then((result) => {
|
|
93891
94007
|
entry.completed = true;
|
|
93892
94008
|
return result;
|
|
93893
94009
|
}, (error) => {
|
|
93894
|
-
|
|
94010
|
+
entry.completed = true;
|
|
94011
|
+
if (!controller.signal.aborted) commands.delete(commandId);
|
|
93895
94012
|
throw error;
|
|
93896
94013
|
});
|
|
93897
94014
|
entry = {
|
|
93898
94015
|
promise,
|
|
93899
|
-
completed: false
|
|
94016
|
+
completed: false,
|
|
94017
|
+
threadId,
|
|
94018
|
+
controller,
|
|
94019
|
+
cancellable: true
|
|
93900
94020
|
};
|
|
93901
94021
|
commands.set(commandId, entry);
|
|
93902
94022
|
return require_Schema$1.tryPromise({
|
|
@@ -93906,6 +94026,10 @@ const runBootstrapCommand = (engine, commandId, bootstrapEffect) => {
|
|
|
93906
94026
|
};
|
|
93907
94027
|
//#endregion
|
|
93908
94028
|
//#region src/orchestration/bootstrapDispatch.ts
|
|
94029
|
+
const interruptBootstrapTurnStart = (engine, command) => require_Schema$1.gen(function* () {
|
|
94030
|
+
if (yield* cancelBootstrapCommand(engine, command.threadId)) return { sequence: (yield* engine.getReadModel()).snapshotSequence };
|
|
94031
|
+
return yield* engine.dispatch(command);
|
|
94032
|
+
});
|
|
93909
94033
|
const MAX_BOOTSTRAP_OUTPUT_LINE_LENGTH = 1e3;
|
|
93910
94034
|
const toBootstrapDispatchCommandCauseError = (cause) => {
|
|
93911
94035
|
const error = require_Schema$1.squash(cause);
|
|
@@ -93992,6 +94116,7 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
93992
94116
|
const requestedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
93993
94117
|
const baseBranchLabel = bootstrapWorktree.baseBranch ?? "<default>";
|
|
93994
94118
|
const requestedPayload = {
|
|
94119
|
+
turnRequestedAt: input.command.createdAt,
|
|
93995
94120
|
projectCwd: bootstrapWorktree.projectCwd,
|
|
93996
94121
|
baseBranch: bootstrapWorktree.baseBranch,
|
|
93997
94122
|
branch: bootstrapWorktree.branch,
|
|
@@ -94012,6 +94137,16 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
94012
94137
|
branch: bootstrapWorktree.baseBranch,
|
|
94013
94138
|
newBranch: bootstrapWorktree.branch,
|
|
94014
94139
|
path: null,
|
|
94140
|
+
onStage: (update) => appendWorktreeActivity({
|
|
94141
|
+
orchestrationEngine: input.orchestrationEngine,
|
|
94142
|
+
threadId: input.command.threadId,
|
|
94143
|
+
commandId: CommandId.make(`server:worktree-stage:${input.command.commandId}:${crypto.randomUUID()}`),
|
|
94144
|
+
kind: "worktree.stage",
|
|
94145
|
+
summary: "Preparing worktree",
|
|
94146
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94147
|
+
payload: update,
|
|
94148
|
+
tone: "info"
|
|
94149
|
+
}).pipe(require_Schema$1.asVoid, require_Schema$1.ignore),
|
|
94015
94150
|
progress: {
|
|
94016
94151
|
onStdoutLine: (line) => {
|
|
94017
94152
|
const detail = truncateBootstrapOutputLine(line);
|
|
@@ -94051,6 +94186,7 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
94051
94186
|
}
|
|
94052
94187
|
}
|
|
94053
94188
|
}).pipe(require_Schema$1.catchCause((cause) => {
|
|
94189
|
+
if (require_Schema$1.hasInterruptsOnly(cause)) return require_Schema$1.failCause(cause);
|
|
94054
94190
|
const error = require_Schema$1.squash(cause);
|
|
94055
94191
|
const detail = error instanceof Error ? error.message : "Unknown worktree failure.";
|
|
94056
94192
|
return appendWorktreeActivity({
|
|
@@ -94177,7 +94313,16 @@ const dispatchBootstrapTurnStart = (input, command) => require_Schema$1.gen(func
|
|
|
94177
94313
|
worktreePath
|
|
94178
94314
|
}),
|
|
94179
94315
|
onSuccess: (setupResult) => {
|
|
94180
|
-
if (setupResult.status !== "started") return
|
|
94316
|
+
if (setupResult.status !== "started") return appendSetupScriptActivity({
|
|
94317
|
+
orchestrationEngine,
|
|
94318
|
+
threadId: command.threadId,
|
|
94319
|
+
commandId: bootstrapCommandId(command, "setup-script-skipped"),
|
|
94320
|
+
kind: "setup-script.skipped",
|
|
94321
|
+
summary: "No setup script configured",
|
|
94322
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94323
|
+
payload: {},
|
|
94324
|
+
tone: "info"
|
|
94325
|
+
}).pipe(require_Schema$1.asVoid, require_Schema$1.ignore);
|
|
94181
94326
|
return recordSetupScriptStarted({
|
|
94182
94327
|
requestedAt,
|
|
94183
94328
|
worktreePath,
|
|
@@ -94207,13 +94352,33 @@ const dispatchBootstrapTurnStart = (input, command) => require_Schema$1.gen(func
|
|
|
94207
94352
|
targetProjectCwd = preparedWorktree.projectCwd;
|
|
94208
94353
|
}
|
|
94209
94354
|
yield* runSetupProgram();
|
|
94355
|
+
if (bootstrap?.prepareWorktree) yield* appendWorktreeActivity({
|
|
94356
|
+
orchestrationEngine,
|
|
94357
|
+
threadId: command.threadId,
|
|
94358
|
+
commandId: bootstrapCommandId(command, "launch-agent-starting"),
|
|
94359
|
+
kind: "launch.agent-starting",
|
|
94360
|
+
summary: "Starting agent",
|
|
94361
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94362
|
+
payload: { setupRequested: bootstrap.runSetupScript === true },
|
|
94363
|
+
tone: "info"
|
|
94364
|
+
}).pipe(require_Schema$1.ignore);
|
|
94365
|
+
sealBootstrapCommand(orchestrationEngine, command.commandId);
|
|
94210
94366
|
return yield* orchestrationEngine.dispatch(finalTurnStartCommand);
|
|
94211
94367
|
});
|
|
94212
|
-
return yield* runBootstrapCommand(orchestrationEngine, command.commandId, bootstrapProgram.pipe(require_Schema$1.
|
|
94368
|
+
return yield* runBootstrapCommand(orchestrationEngine, command.commandId, bootstrapProgram.pipe(require_Schema$1.onInterrupt(() => appendWorktreeActivity({
|
|
94369
|
+
orchestrationEngine,
|
|
94370
|
+
threadId: command.threadId,
|
|
94371
|
+
commandId: bootstrapCommandId(command, "launch-cancelled"),
|
|
94372
|
+
kind: "launch.cancelled",
|
|
94373
|
+
summary: "Launch cancelled",
|
|
94374
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
94375
|
+
payload: {},
|
|
94376
|
+
tone: "info"
|
|
94377
|
+
}).pipe(require_Schema$1.ignore)), require_Schema$1.catchCause((cause) => {
|
|
94213
94378
|
const dispatchError = toBootstrapDispatchCommandCauseError(cause);
|
|
94214
94379
|
if (require_Schema$1.hasInterruptsOnly(cause)) return require_Schema$1.fail(dispatchError);
|
|
94215
94380
|
return cleanupCreatedThread().pipe(require_Schema$1.flatMap(() => require_Schema$1.fail(dispatchError)));
|
|
94216
|
-
})));
|
|
94381
|
+
})), command.threadId);
|
|
94217
94382
|
});
|
|
94218
94383
|
//#endregion
|
|
94219
94384
|
//#region src/orchestration/Services/OrchestrationEngine.ts
|
|
@@ -95094,7 +95259,7 @@ function hasValidRuntimeIdentity(value) {
|
|
|
95094
95259
|
}
|
|
95095
95260
|
function decodeRuntime$1(value) {
|
|
95096
95261
|
if (!isRecord$19(value) || !hasValidRuntimeIdentity(value)) return null;
|
|
95097
|
-
if (!nullableString(value.endpointUrl) || value.endpointUrl !== null && !URL.canParse(value.endpointUrl) || !nullableInteger(value.deviceId) || !nullableString(value.workspaceRoot) || !nullableString(value.githubRepoFullName) || !(value.lastSeenAt === null || isIsoDateTime(value.lastSeenAt)) || !(value.metadata === null || isRecord$19(value.metadata))) return null;
|
|
95262
|
+
if (!nullableString(value.endpointUrl) || value.endpointUrl !== null && !URL.canParse(value.endpointUrl) || !nullableInteger(value.deviceId) || !nullableString(value.workspaceRoot) || !nullableString(value.githubRepoFullName) || !(value.lastSeenAt === null || isIsoDateTime(value.lastSeenAt)) || !(value.metadata === void 0 || value.metadata === null || isRecord$19(value.metadata))) return null;
|
|
95098
95263
|
return value;
|
|
95099
95264
|
}
|
|
95100
95265
|
function decodeProject(value) {
|
|
@@ -95107,7 +95272,7 @@ function decodeProject(value) {
|
|
|
95107
95272
|
};
|
|
95108
95273
|
}
|
|
95109
95274
|
function decodeThread$1(value) {
|
|
95110
|
-
if (!isRecord$19(value) || !isNonBlankString(value.threadId) || typeof value.title !== "string" || !isReplicaThreadStatus(value.status) || !nullableString(value.model) || !nullableString(value.branch) || !(value.lastActivityAt === null || isIsoDateTime(value.lastActivityAt))) return null;
|
|
95275
|
+
if (!isRecord$19(value) || !isNonBlankString(value.threadId) || typeof value.title !== "string" || !isReplicaThreadStatus(value.status) || !nullableString(value.model) || !nullableString(value.branch) || !(value.lastActivityAt === null || isIsoDateTime(value.lastActivityAt)) || !(value.metadata === void 0 || value.metadata === null || isRecord$19(value.metadata))) return null;
|
|
95111
95276
|
return value;
|
|
95112
95277
|
}
|
|
95113
95278
|
function decodeSummary(value) {
|
|
@@ -95462,18 +95627,27 @@ function runtimeThreadFinalGenerationId(runtimeId, streamKey, events) {
|
|
|
95462
95627
|
function canonicalKindFields(event) {
|
|
95463
95628
|
switch (event.kind) {
|
|
95464
95629
|
case "user_message":
|
|
95465
|
-
case "assistant_message": return
|
|
95630
|
+
case "assistant_message": return canonicalMessageFields(event);
|
|
95466
95631
|
case "activity_summary":
|
|
95467
95632
|
case "error_summary": return { summary: event.summary };
|
|
95468
95633
|
case "turn_status": return { status: event.status };
|
|
95469
|
-
case "tool_call": return
|
|
95470
|
-
summary: event.summary,
|
|
95471
|
-
status: event.status,
|
|
95472
|
-
...event.payload !== void 0 ? { payload: event.payload } : {}
|
|
95473
|
-
};
|
|
95634
|
+
case "tool_call": return canonicalToolCallFields(event);
|
|
95474
95635
|
case "turn_usage": return canonicalTurnUsageFields(event);
|
|
95475
95636
|
}
|
|
95476
95637
|
}
|
|
95638
|
+
function canonicalMessageFields(event) {
|
|
95639
|
+
return {
|
|
95640
|
+
text: event.text,
|
|
95641
|
+
...event.payload === void 0 ? {} : { payload: event.payload }
|
|
95642
|
+
};
|
|
95643
|
+
}
|
|
95644
|
+
function canonicalToolCallFields(event) {
|
|
95645
|
+
return {
|
|
95646
|
+
summary: event.summary,
|
|
95647
|
+
status: event.status,
|
|
95648
|
+
...event.payload === void 0 ? {} : { payload: event.payload }
|
|
95649
|
+
};
|
|
95650
|
+
}
|
|
95477
95651
|
/**
|
|
95478
95652
|
* The usage row's attribution as canonical fields, matching CMMD's
|
|
95479
95653
|
* `forgeUsageRowAttributionFields`: present only when the publisher named them,
|
|
@@ -95615,8 +95789,21 @@ function eventsMatchAcknowledgement(events, acknowledgedSequence) {
|
|
|
95615
95789
|
return acknowledgedSequence === expectedSequence - 1;
|
|
95616
95790
|
}
|
|
95617
95791
|
//#endregion
|
|
95792
|
+
//#region src/runtimeReplication/replicaMessagePayload.ts
|
|
95793
|
+
function decodeReplicaMessageAttachments(payload) {
|
|
95794
|
+
if (payload === null || typeof payload !== "object" || !("attachments" in payload)) return;
|
|
95795
|
+
const attachments = payload.attachments;
|
|
95796
|
+
if (!Array.isArray(attachments)) return void 0;
|
|
95797
|
+
const decoded = attachments.filter(require_Schema$1.is(ChatAttachment));
|
|
95798
|
+
return decoded.length > 0 ? decoded : void 0;
|
|
95799
|
+
}
|
|
95800
|
+
function messageAttachmentPayload(message) {
|
|
95801
|
+
return message.attachments && message.attachments.length > 0 ? { payload: { attachments: message.attachments } } : {};
|
|
95802
|
+
}
|
|
95803
|
+
//#endregion
|
|
95618
95804
|
//#region src/runtimeReplication/replicaHydrationMapping.ts
|
|
95619
95805
|
function replicaMessage(runtimeId, generationId, event) {
|
|
95806
|
+
const attachments = decodeReplicaMessageAttachments(event.payload);
|
|
95620
95807
|
return {
|
|
95621
95808
|
id: MessageId.make(encodeReplicaSourceMessageId({
|
|
95622
95809
|
sequence: event.sequence,
|
|
@@ -95629,7 +95816,8 @@ function replicaMessage(runtimeId, generationId, event) {
|
|
|
95629
95816
|
turnId: null,
|
|
95630
95817
|
streaming: false,
|
|
95631
95818
|
createdAt: event.occurredAt,
|
|
95632
|
-
updatedAt: event.occurredAt
|
|
95819
|
+
updatedAt: event.occurredAt,
|
|
95820
|
+
...attachments ? { attachments: [...attachments] } : {}
|
|
95633
95821
|
};
|
|
95634
95822
|
}
|
|
95635
95823
|
function replicaTurnUsage(event) {
|
|
@@ -95662,11 +95850,15 @@ function replicaEventBase(event) {
|
|
|
95662
95850
|
function replicaTextEvent(event, base) {
|
|
95663
95851
|
switch (event.kind) {
|
|
95664
95852
|
case "user_message":
|
|
95665
|
-
case "assistant_message":
|
|
95666
|
-
|
|
95667
|
-
|
|
95668
|
-
|
|
95669
|
-
|
|
95853
|
+
case "assistant_message": {
|
|
95854
|
+
const attachments = decodeReplicaMessageAttachments(event.payload);
|
|
95855
|
+
return {
|
|
95856
|
+
...base,
|
|
95857
|
+
kind: event.kind,
|
|
95858
|
+
text: event.text,
|
|
95859
|
+
...attachments ? { payload: { attachments } } : {}
|
|
95860
|
+
};
|
|
95861
|
+
}
|
|
95670
95862
|
case "activity_summary":
|
|
95671
95863
|
case "error_summary": return {
|
|
95672
95864
|
...base,
|
|
@@ -95776,7 +95968,7 @@ function replicaToOrchestrationThread(input) {
|
|
|
95776
95968
|
status: archived ? "archived" : "idle",
|
|
95777
95969
|
workerRole: null,
|
|
95778
95970
|
pendingAutoCreatePrompt: null,
|
|
95779
|
-
goal: null,
|
|
95971
|
+
goal: decodeCmmdRuntimeThreadGoalMetadata(detail.thread.metadata)?.goal ?? null,
|
|
95780
95972
|
titleRegeneration: null
|
|
95781
95973
|
}
|
|
95782
95974
|
};
|
|
@@ -97313,7 +97505,8 @@ function serializeReplicaMessage(message) {
|
|
|
97313
97505
|
occurredAt: message.createdAt,
|
|
97314
97506
|
...source.turnId === void 0 ? {} : { turnId: source.turnId },
|
|
97315
97507
|
kind: message.role === "user" ? "user_message" : "assistant_message",
|
|
97316
|
-
text: message.text
|
|
97508
|
+
text: message.text,
|
|
97509
|
+
...messageAttachmentPayload(message)
|
|
97317
97510
|
}
|
|
97318
97511
|
};
|
|
97319
97512
|
}
|
|
@@ -97373,7 +97566,8 @@ function serializeRuntimeInventory(snapshot, providerInventory) {
|
|
|
97373
97566
|
settledAt: thread.settledAt ?? null,
|
|
97374
97567
|
settledOverride: thread.settledOverride ?? null
|
|
97375
97568
|
}),
|
|
97376
|
-
...encodeCmmdRuntimeThreadWorkspaceMetadata({ worktreePath: thread.worktreePath })
|
|
97569
|
+
...encodeCmmdRuntimeThreadWorkspaceMetadata({ worktreePath: thread.worktreePath }),
|
|
97570
|
+
...encodeCmmdRuntimeThreadGoalMetadata({ goal: thread.goal })
|
|
97377
97571
|
}
|
|
97378
97572
|
})),
|
|
97379
97573
|
metadata: {
|
|
@@ -97408,7 +97602,8 @@ function orderedLocalMessageEvent(message, content) {
|
|
|
97408
97602
|
occurredAt: canonicalRuntimeEventTimestamp(message.createdAt),
|
|
97409
97603
|
...eventTurn(message.turnId),
|
|
97410
97604
|
kind: message.role === "user" ? "user_message" : "assistant_message",
|
|
97411
|
-
text: content
|
|
97605
|
+
text: content,
|
|
97606
|
+
...messageAttachmentPayload(message)
|
|
97412
97607
|
}
|
|
97413
97608
|
};
|
|
97414
97609
|
}
|
|
@@ -100899,6 +101094,7 @@ function emptyConfig(source, path) {
|
|
|
100899
101094
|
terminals: [],
|
|
100900
101095
|
systemPackages: [],
|
|
100901
101096
|
secrets: [],
|
|
101097
|
+
repositoryDependencies: [],
|
|
100902
101098
|
issues: []
|
|
100903
101099
|
};
|
|
100904
101100
|
}
|
|
@@ -100984,6 +101180,7 @@ function readConfigFile(source, path) {
|
|
|
100984
101180
|
terminals: terminalsFromValue(parsed.terminals),
|
|
100985
101181
|
systemPackages: stringArray(parsed.systemPackages ?? parsed.aptPackages ?? parsed.packages),
|
|
100986
101182
|
secrets: stringArray(parsed.secrets ?? parsed.envSecrets),
|
|
101183
|
+
repositoryDependencies: stringArray(parsed.repositoryDependencies),
|
|
100987
101184
|
issues: []
|
|
100988
101185
|
};
|
|
100989
101186
|
}
|
|
@@ -101396,6 +101593,7 @@ const EMPTY_WORKSPACE_ENVIRONMENT_CONFIG = {
|
|
|
101396
101593
|
terminals: [],
|
|
101397
101594
|
systemPackages: [],
|
|
101398
101595
|
secrets: [],
|
|
101596
|
+
repositoryDependencies: [],
|
|
101399
101597
|
issues: []
|
|
101400
101598
|
};
|
|
101401
101599
|
function buildCwdCheck(cwdExists) {
|
|
@@ -106203,7 +106401,7 @@ const makeWsRpcLayer = (currentSessionId, currentUserId) => WsRpcGroup.toLayer(r
|
|
|
106203
106401
|
git,
|
|
106204
106402
|
gitStatusBroadcaster,
|
|
106205
106403
|
projectSetupScriptRunner
|
|
106206
|
-
}, normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand).pipe(require_Schema$1.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
|
|
106404
|
+
}, 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")));
|
|
106207
106405
|
return startup.enqueueCommand(dispatchEffect).pipe(require_Schema$1.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
|
|
106208
106406
|
};
|
|
106209
106407
|
const loadServerConfig = require_Schema$1.gen(function* () {
|
|
@@ -151573,6 +151771,86 @@ async function attestCodexLocalAccountIdentity(input) {
|
|
|
151573
151771
|
return identity;
|
|
151574
151772
|
}
|
|
151575
151773
|
//#endregion
|
|
151774
|
+
//#region src/workspace/workspaceRepositoryDependencies.ts
|
|
151775
|
+
function repositoryFullName(value) {
|
|
151776
|
+
return value.trim().match(/^(?:https?:\/\/)?github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+?)(?:\.git)?\/?$/i)?.[1] ?? null;
|
|
151777
|
+
}
|
|
151778
|
+
function dependencyDestination(cloudProjectsRoot, repoFullName) {
|
|
151779
|
+
const root = (0, node_path.resolve)(cloudProjectsRoot);
|
|
151780
|
+
const destination = (0, node_path.resolve)((0, node_path.join)(root, (0, node_path.basename)(repoFullName)));
|
|
151781
|
+
const pathFromRoot = (0, node_path.relative)(root, destination);
|
|
151782
|
+
if (pathFromRoot.startsWith("..") || pathFromRoot === "") throw new Error(`Repository dependency ${repoFullName} has an unsafe destination.`);
|
|
151783
|
+
return destination;
|
|
151784
|
+
}
|
|
151785
|
+
async function readOriginFromGit(destination) {
|
|
151786
|
+
const result = await runProcess("git", [
|
|
151787
|
+
"-C",
|
|
151788
|
+
destination,
|
|
151789
|
+
"remote",
|
|
151790
|
+
"get-url",
|
|
151791
|
+
"origin"
|
|
151792
|
+
], {
|
|
151793
|
+
allowNonZeroExit: true,
|
|
151794
|
+
timeoutMs: 1e4
|
|
151795
|
+
});
|
|
151796
|
+
return result.code === 0 ? result.stdout.trim() : null;
|
|
151797
|
+
}
|
|
151798
|
+
function resolveRepositoryDependencies(declarations, cloudProjectsRoot) {
|
|
151799
|
+
const destinations = /* @__PURE__ */ new Set();
|
|
151800
|
+
return declarations.map((declaration) => {
|
|
151801
|
+
const repoFullName = repositoryFullName(declaration);
|
|
151802
|
+
if (repoFullName === null) throw new Error(`Unsupported repository dependency: ${declaration}`);
|
|
151803
|
+
const destination = dependencyDestination(cloudProjectsRoot, repoFullName);
|
|
151804
|
+
if (destinations.has(destination)) throw new Error(`Repository dependencies collide at ${destination}.`);
|
|
151805
|
+
destinations.add(destination);
|
|
151806
|
+
return {
|
|
151807
|
+
repoFullName,
|
|
151808
|
+
destination
|
|
151809
|
+
};
|
|
151810
|
+
});
|
|
151811
|
+
}
|
|
151812
|
+
async function prepareRepositoryDependency(input) {
|
|
151813
|
+
const { repoFullName, destination } = input.dependency;
|
|
151814
|
+
if ((0, node_fs.existsSync)(destination)) {
|
|
151815
|
+
const origin = await input.readOrigin(destination);
|
|
151816
|
+
const existingRepo = origin === null ? null : parseRepoFullNameFromRemoteUrl(origin);
|
|
151817
|
+
if (existingRepo?.toLowerCase() !== repoFullName.toLowerCase()) throw new Error(`Repository dependency destination ${destination} contains ${existingRepo ?? "no GitHub repository"} instead of ${repoFullName}.`);
|
|
151818
|
+
return {
|
|
151819
|
+
repoFullName,
|
|
151820
|
+
destination,
|
|
151821
|
+
outcome: "existing"
|
|
151822
|
+
};
|
|
151823
|
+
}
|
|
151824
|
+
const result = await input.broker.cloneRepository(input.auth, {
|
|
151825
|
+
repoFullName,
|
|
151826
|
+
destination
|
|
151827
|
+
});
|
|
151828
|
+
if (!result.ok) throw new Error(`Could not prepare repository dependency ${repoFullName}: ${result.error ?? result.code ?? "clone failed"}`);
|
|
151829
|
+
return {
|
|
151830
|
+
repoFullName,
|
|
151831
|
+
destination,
|
|
151832
|
+
outcome: "cloned"
|
|
151833
|
+
};
|
|
151834
|
+
}
|
|
151835
|
+
async function prepareWorkspaceRepositoryDependencies(input) {
|
|
151836
|
+
if (!input.runtimeMode) return [];
|
|
151837
|
+
const dependencies = resolveWorkspaceEnvironmentConfig(input.cwd).repositoryDependencies;
|
|
151838
|
+
if (dependencies.length === 0) return [];
|
|
151839
|
+
const broker = input.broker ?? new GitHubBroker();
|
|
151840
|
+
const auth = broker.runtimeGrantAuthContext("scm");
|
|
151841
|
+
if (auth === null) throw new Error("Repository dependencies require an exact scoped runtime SCM grant.");
|
|
151842
|
+
const readOrigin = input.readOrigin ?? readOriginFromGit;
|
|
151843
|
+
const resolved = resolveRepositoryDependencies(dependencies, input.cloudProjectsRoot);
|
|
151844
|
+
const prepared = [];
|
|
151845
|
+
for (const dependency of resolved) prepared.push(await prepareRepositoryDependency({
|
|
151846
|
+
dependency,
|
|
151847
|
+
broker,
|
|
151848
|
+
auth,
|
|
151849
|
+
readOrigin
|
|
151850
|
+
}));
|
|
151851
|
+
return prepared;
|
|
151852
|
+
}
|
|
151853
|
+
//#endregion
|
|
151576
151854
|
//#region src/codexAppServerManager.ts
|
|
151577
151855
|
const CODEX_LOGIN_STATUS_TIMEOUT_MS = 5e3;
|
|
151578
151856
|
const CODEX_SKILLS_LIST_TIMEOUT_MS = 4e3;
|
|
@@ -151907,6 +152185,11 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
|
|
|
151907
152185
|
let context;
|
|
151908
152186
|
try {
|
|
151909
152187
|
const resolvedCwd = input.cwd ?? process.cwd();
|
|
152188
|
+
await prepareWorkspaceRepositoryDependencies({
|
|
152189
|
+
cwd: resolvedCwd,
|
|
152190
|
+
cloudProjectsRoot: process.env.FORGE_CLOUD_PROJECTS_ROOT?.trim() || "/projects",
|
|
152191
|
+
runtimeMode: process.env.FORGE_CMMD_RUNTIME_MODE === "true"
|
|
152192
|
+
});
|
|
151910
152193
|
let workspacePreflightReport = runWorkspaceEnvironmentPreflight({
|
|
151911
152194
|
cwd: resolvedCwd,
|
|
151912
152195
|
env: process.env
|
|
@@ -216993,6 +217276,19 @@ const makeClaudeAdapter = require_Schema$1.fn("makeClaudeAdapter")(function* (op
|
|
|
216993
217276
|
const resumeState = readClaudeResumeState(input.resumeCursor);
|
|
216994
217277
|
const threadId = input.threadId;
|
|
216995
217278
|
const { existingResumeSessionId, newSessionId, sessionId } = yield* resolveClaudeStartSessionIds(resumeState);
|
|
217279
|
+
const workspaceCwd = input.cwd;
|
|
217280
|
+
if (workspaceCwd) yield* require_Schema$1.tryPromise({
|
|
217281
|
+
try: () => prepareWorkspaceRepositoryDependencies({
|
|
217282
|
+
cwd: workspaceCwd,
|
|
217283
|
+
cloudProjectsRoot: serverConfig.cloudProjectsRoot ?? "/projects",
|
|
217284
|
+
runtimeMode: serverConfig.forgeCmmdRuntimeMode === true
|
|
217285
|
+
}),
|
|
217286
|
+
catch: (cause) => new ProviderAdapterValidationError({
|
|
217287
|
+
provider: PROVIDER$11,
|
|
217288
|
+
operation: "startSession",
|
|
217289
|
+
issue: cause instanceof Error ? cause.message : "Could not prepare declared repository dependencies."
|
|
217290
|
+
})
|
|
217291
|
+
});
|
|
216996
217292
|
const runtimeContext = yield* require_Schema$1.context();
|
|
216997
217293
|
const runFork = require_Schema$1.runForkWith(runtimeContext);
|
|
216998
217294
|
const runPromise = require_Schema$1.runPromiseWith(runtimeContext);
|
|
@@ -233332,12 +233628,12 @@ const collectOutput = require_Schema$1.fn("collectOutput")(function* (input, str
|
|
|
233332
233628
|
let lineBuffer = "";
|
|
233333
233629
|
let truncated = false;
|
|
233334
233630
|
const emitCompleteLines = require_Schema$1.fn("emitCompleteLines")(function* (flush) {
|
|
233335
|
-
let newlineIndex = lineBuffer.
|
|
233631
|
+
let newlineIndex = lineBuffer.search(/[\r\n]/);
|
|
233336
233632
|
while (newlineIndex >= 0) {
|
|
233337
233633
|
const line = lineBuffer.slice(0, newlineIndex).replace(/\r$/, "");
|
|
233338
233634
|
lineBuffer = lineBuffer.slice(newlineIndex + 1);
|
|
233339
233635
|
if (line.length > 0 && onLine) yield* onLine(line);
|
|
233340
|
-
newlineIndex = lineBuffer.
|
|
233636
|
+
newlineIndex = lineBuffer.search(/[\r\n]/);
|
|
233341
233637
|
}
|
|
233342
233638
|
if (flush) {
|
|
233343
233639
|
const trailing = lineBuffer.replace(/\r$/, "");
|
|
@@ -233486,6 +233782,7 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
233486
233782
|
operation,
|
|
233487
233783
|
cwd,
|
|
233488
233784
|
args,
|
|
233785
|
+
...options.env ? { env: options.env } : {},
|
|
233489
233786
|
...options.stdin !== void 0 ? { stdin: options.stdin } : {},
|
|
233490
233787
|
allowNonZeroExit: true,
|
|
233491
233788
|
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
|
|
@@ -234209,12 +234506,19 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
234209
234506
|
};
|
|
234210
234507
|
});
|
|
234211
234508
|
const createWorktree = require_Schema$1.fn("createWorktree")(function* (input) {
|
|
234509
|
+
const report = (stage, status, detail) => input.onStage?.({
|
|
234510
|
+
stage,
|
|
234511
|
+
status,
|
|
234512
|
+
...detail ? { detail } : {}
|
|
234513
|
+
}) ?? require_Schema$1.void_;
|
|
234514
|
+
yield* report("resolve", "running");
|
|
234212
234515
|
const base = input.branch ?? (yield* resolveDefaultBaseBranch(input.cwd));
|
|
234213
234516
|
const startPoint = yield* resolveWorktreeStartPoint({
|
|
234214
234517
|
cwd: input.cwd,
|
|
234215
234518
|
base,
|
|
234216
234519
|
creatingNewBranch: input.newBranch !== void 0
|
|
234217
234520
|
});
|
|
234521
|
+
yield* report("resolve", "done", startPoint);
|
|
234218
234522
|
const targetBranch = input.newBranch ?? base;
|
|
234219
234523
|
const sanitizedBranch = targetBranch.replace(/\//g, "-");
|
|
234220
234524
|
const repoName = path.basename(input.cwd);
|
|
@@ -234226,7 +234530,10 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
234226
234530
|
limit: 200
|
|
234227
234531
|
})).branches.find((branch) => branch.isRemote !== true && branch.name === targetBranch && branch.worktreePath !== null && node_path.default.resolve(branch.worktreePath) === canonicalWorktreePath);
|
|
234228
234532
|
if (existingBranch?.worktreePath) {
|
|
234533
|
+
yield* report("checkout", "skipped", "Existing worktree");
|
|
234534
|
+
yield* report("dependencies", "running");
|
|
234229
234535
|
yield* setupSharedWorktreeDependencies(input.cwd, existingBranch.worktreePath);
|
|
234536
|
+
yield* report("dependencies", "done");
|
|
234230
234537
|
return { worktree: {
|
|
234231
234538
|
path: worktreePath,
|
|
234232
234539
|
branch: targetBranch
|
|
@@ -234245,11 +234552,19 @@ const makeGitCore = require_Schema$1.fn("makeGitCore")(function* (options) {
|
|
|
234245
234552
|
worktreePath,
|
|
234246
234553
|
startPoint
|
|
234247
234554
|
];
|
|
234555
|
+
yield* report("checkout", "running");
|
|
234248
234556
|
yield* executeGit("GitCore.createWorktree", input.cwd, args, {
|
|
234249
234557
|
fallbackErrorMessage: "git worktree add failed",
|
|
234558
|
+
env: {
|
|
234559
|
+
GIT_PROGRESS_DELAY: "0",
|
|
234560
|
+
LC_ALL: "C"
|
|
234561
|
+
},
|
|
234250
234562
|
...input.progress ? { progress: input.progress } : {}
|
|
234251
234563
|
});
|
|
234564
|
+
yield* report("checkout", "done");
|
|
234565
|
+
yield* report("dependencies", "running");
|
|
234252
234566
|
yield* setupSharedWorktreeDependencies(input.cwd, worktreePath);
|
|
234567
|
+
yield* report("dependencies", "done");
|
|
234253
234568
|
return { worktree: {
|
|
234254
234569
|
path: worktreePath,
|
|
234255
234570
|
branch: targetBranch
|
|
@@ -297062,7 +297377,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
297062
297377
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
297063
297378
|
*/
|
|
297064
297379
|
function readBakedBuildCommit() {
|
|
297065
|
-
return "
|
|
297380
|
+
return "339f0da718657526651ad84cacb841446f1bb38b";
|
|
297066
297381
|
}
|
|
297067
297382
|
async function resolveServerBuildCommit(input) {
|
|
297068
297383
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -298888,6 +299203,10 @@ const AuthSessionRepositoryLive = require_Schema$1.effect(AuthSessionRepository,
|
|
|
298888
299203
|
const SIGNING_SECRET_NAME = "server-signing-key";
|
|
298889
299204
|
const DEFAULT_SESSION_TTL = require_Schema$1.days(30);
|
|
298890
299205
|
const DEFAULT_WEBSOCKET_TOKEN_TTL = require_Schema$1.minutes(5);
|
|
299206
|
+
const toSessionCredentialError = (message) => (cause) => new SessionCredentialError({
|
|
299207
|
+
message,
|
|
299208
|
+
cause
|
|
299209
|
+
});
|
|
298891
299210
|
const SessionClaims = require_Schema$1.Struct({
|
|
298892
299211
|
v: require_Schema$1.Literal(1),
|
|
298893
299212
|
kind: require_Schema$1.Literal("session"),
|
|
@@ -298944,10 +299263,6 @@ const makeSessionCredentialService = require_Schema$1.gen(function* () {
|
|
|
298944
299263
|
port: serverConfig.port,
|
|
298945
299264
|
host: serverConfig.host
|
|
298946
299265
|
});
|
|
298947
|
-
const toSessionCredentialError = (message) => (cause) => new SessionCredentialError({
|
|
298948
|
-
message,
|
|
298949
|
-
cause
|
|
298950
|
-
});
|
|
298951
299266
|
const emitUpsert = (clientSession) => require_Path.publish(changesPubSub, {
|
|
298952
299267
|
type: "clientUpserted",
|
|
298953
299268
|
clientSession
|
|
@@ -299108,15 +299423,28 @@ const makeSessionCredentialService = require_Schema$1.gen(function* () {
|
|
|
299108
299423
|
if (require_Schema$1.isSome(row)) {
|
|
299109
299424
|
if (row.value.revokedAt !== null) return yield* new SessionCredentialError({ message: "Websocket session revoked." });
|
|
299110
299425
|
if (row.value.expiresAt.epochMilliseconds <= now) return yield* new SessionCredentialError({ message: "Websocket session expired." });
|
|
299111
|
-
} else
|
|
299426
|
+
} else {
|
|
299427
|
+
const cloudOwnerSession = serverConfig.forgeCloudShellMode === true && claims.method === "proxy-asserted" && forgeCloudOwnerSessionExpiresAt(claims.sid) !== null;
|
|
299428
|
+
if (cloudOwnerSession && isExpiredForgeCloudOwnerSession(claims.sid, now)) return yield* new SessionCredentialError({ message: "Websocket session expired." });
|
|
299429
|
+
if (statelessCookieSessions && (claims.method === "browser-session-cookie" || cloudOwnerSession)) return {
|
|
299430
|
+
sessionId: claims.sid,
|
|
299431
|
+
token,
|
|
299432
|
+
method: claims.method,
|
|
299433
|
+
client: createDefaultClientMetadata(),
|
|
299434
|
+
expiresAt: require_Schema$1.makeUnsafe(claims.exp),
|
|
299435
|
+
subject: claims.sub,
|
|
299436
|
+
role: claims.role
|
|
299437
|
+
};
|
|
299438
|
+
return yield* new SessionCredentialError({ message: "Unknown websocket session." });
|
|
299439
|
+
}
|
|
299112
299440
|
return {
|
|
299113
299441
|
sessionId: claims.sid,
|
|
299114
299442
|
token,
|
|
299115
|
-
method:
|
|
299116
|
-
client:
|
|
299117
|
-
expiresAt:
|
|
299118
|
-
subject:
|
|
299119
|
-
role:
|
|
299443
|
+
method: row.value.method,
|
|
299444
|
+
client: toClientMetadata(row.value.client),
|
|
299445
|
+
expiresAt: row.value.expiresAt,
|
|
299446
|
+
subject: row.value.subject,
|
|
299447
|
+
role: row.value.role
|
|
299120
299448
|
};
|
|
299121
299449
|
}).pipe(require_Schema$1.mapError((cause) => cause instanceof SessionCredentialError ? cause : new SessionCredentialError({
|
|
299122
299450
|
message: "Failed to verify websocket token.",
|
|
@@ -299394,6 +299722,18 @@ function verifyForgeCloudOwnerCallbackAssertion(assertion, config) {
|
|
|
299394
299722
|
//#endregion
|
|
299395
299723
|
//#region src/auth/Layers/ServerAuth.ts
|
|
299396
299724
|
const AUTHORIZATION_PREFIX = "Bearer ";
|
|
299725
|
+
function classifyWebSocketTokenFailure(cause) {
|
|
299726
|
+
switch (cause.message) {
|
|
299727
|
+
case "Malformed websocket token.": return "malformed";
|
|
299728
|
+
case "Invalid websocket token signature.": return "invalid_signature";
|
|
299729
|
+
case "Invalid websocket token payload.": return "invalid_payload";
|
|
299730
|
+
case "Websocket token expired.": return "expired_token";
|
|
299731
|
+
case "Websocket session revoked.": return "revoked_parent_session";
|
|
299732
|
+
case "Websocket session expired.": return "expired_parent_session";
|
|
299733
|
+
case "Unknown websocket session.": return "unknown_parent_session";
|
|
299734
|
+
default: return "verification_failed";
|
|
299735
|
+
}
|
|
299736
|
+
}
|
|
299397
299737
|
function toBootstrapExchangeAuthError(cause) {
|
|
299398
299738
|
if (cause.status === 500) return new AuthError({
|
|
299399
299739
|
message: "Failed to validate bootstrap credential.",
|
|
@@ -299696,7 +300036,6 @@ const makeServerAuth = require_Schema$1.gen(function* () {
|
|
|
299696
300036
|
expiresAt: require_Schema$1.toUtc(issued.expiresAt)
|
|
299697
300037
|
})));
|
|
299698
300038
|
const authenticateWebSocketUpgrade = (request) => require_Schema$1.gen(function* () {
|
|
299699
|
-
if (serverConfig.forgeCloudShellMode === true) return yield* authenticateRequest(request);
|
|
299700
300039
|
if (serverConfig.forgeCmmdRuntimeMode) {
|
|
299701
300040
|
if (serverConfig.forgeCmmdAuthRuntime) {
|
|
299702
300041
|
const authConfig = readCmmdAuthRuntimeConfig(serverConfig);
|
|
@@ -299753,7 +300092,7 @@ const makeServerAuth = require_Schema$1.gen(function* () {
|
|
|
299753
300092
|
const requestUrl = require_HttpServer.toURL(request);
|
|
299754
300093
|
if (require_Schema$1.isSome(requestUrl)) {
|
|
299755
300094
|
const websocketToken = readWebSocketUpgradeToken(requestUrl.value.searchParams);
|
|
299756
|
-
if (websocketToken) return yield* sessions.verifyWebSocketToken(websocketToken).pipe(require_Schema$1.map((session) => ({
|
|
300095
|
+
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) => ({
|
|
299757
300096
|
sessionId: session.sessionId,
|
|
299758
300097
|
subject: session.subject,
|
|
299759
300098
|
method: session.method,
|
|
@@ -305842,7 +306181,7 @@ const orchestrationDispatchRouteLayer = add$1("POST", "/api/orchestration/dispat
|
|
|
305842
306181
|
}).pipe(require_Schema$1.mapError((cause) => new OrchestrationDispatchCommandError({
|
|
305843
306182
|
message: "Failed to dispatch orchestration command.",
|
|
305844
306183
|
cause
|
|
305845
|
-
}))) : orchestrationEngine.dispatch(normalizedCommand).pipe(require_Schema$1.mapError((cause) => new OrchestrationDispatchCommandError({
|
|
306184
|
+
}))) : (normalizedCommand.type === "thread.turn.interrupt" ? interruptBootstrapTurnStart(orchestrationEngine, normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand)).pipe(require_Schema$1.mapError((cause) => new OrchestrationDispatchCommandError({
|
|
305846
306185
|
message: "Failed to dispatch orchestration command.",
|
|
305847
306186
|
cause
|
|
305848
306187
|
})));
|