@cmmd-center/forge 0.13.43 → 0.13.45
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 +146 -60
- package/dist/bin.mjs +185 -84
- package/dist/client/assets/{DiffPanel-C3mlJrVS.js → DiffPanel-Bn_XagA5.js} +2 -2
- package/dist/client/assets/{DiffPanel.logic-BX3ANdaS.js → DiffPanel.logic-BHJKg1bv.js} +2 -2
- package/dist/client/assets/{DiffPanelShell-DHVT3aie.js → DiffPanelShell-DFspB3po.js} +103 -103
- package/dist/client/assets/{DiffWorkerPoolProvider-d_Ad37qh.js → DiffWorkerPoolProvider-QNjpRYlc.js} +2 -2
- package/dist/client/assets/{PullRequestCodePanel-D-KmpGSW.js → PullRequestCodePanel-AYQxo9Xg.js} +2 -2
- package/dist/client/assets/{Virtualizer-RtB8FTNU.js → Virtualizer-cy0aLqwi.js} +2 -2
- package/dist/client/assets/{index-vCGDqsO-.js → index-IBzz5pAu.js} +11 -11
- package/dist/client/index.html +4 -4
- package/dist/forge-build.json +1 -1
- package/dist/{open-2-reBrpv.mjs → open-yHTUkd2Y.mjs} +3 -3
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -23,7 +23,7 @@ import { createCipheriv, createDecipheriv, createHash, createHmac, createPublicK
|
|
|
23
23
|
import * as FS$1 from "node:fs";
|
|
24
24
|
import fs, { accessSync, chmodSync, constants, createReadStream, existsSync, mkdirSync, mkdtempSync, promises, readFile, readFileSync, readdir, readdirSync, realpathSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
25
25
|
import * as NodeOS from "node:os";
|
|
26
|
-
import
|
|
26
|
+
import os, { homedir, networkInterfaces, tmpdir } from "node:os";
|
|
27
27
|
import * as Path$1 from "node:path";
|
|
28
28
|
import path, { basename, delimiter, dirname, extname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
29
29
|
import { pathToFileURL } from "node:url";
|
|
@@ -50560,7 +50560,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
50560
50560
|
const min = forceColor || 0;
|
|
50561
50561
|
if (env.TERM === "dumb") return min;
|
|
50562
50562
|
if (process$1.platform === "win32") {
|
|
50563
|
-
const osRelease =
|
|
50563
|
+
const osRelease = os.release().split(".");
|
|
50564
50564
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
50565
50565
|
return 1;
|
|
50566
50566
|
}
|
|
@@ -53003,7 +53003,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
53003
53003
|
exports.processDetector = void 0;
|
|
53004
53004
|
const api_1 = (init_esm$1(), __toCommonJS(esm_exports$1));
|
|
53005
53005
|
const semconv_1 = require_semconv$1();
|
|
53006
|
-
const os$
|
|
53006
|
+
const os$4 = __require("os");
|
|
53007
53007
|
/**
|
|
53008
53008
|
* ProcessDetector will be used to detect the resources related current process running
|
|
53009
53009
|
* and being instrumented from the NodeJS Process module.
|
|
@@ -53025,7 +53025,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
53025
53025
|
};
|
|
53026
53026
|
if (process.argv.length > 1) attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
|
|
53027
53027
|
try {
|
|
53028
|
-
const userInfo = os$
|
|
53028
|
+
const userInfo = os$4.userInfo();
|
|
53029
53029
|
attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
|
|
53030
53030
|
} catch (e) {
|
|
53031
53031
|
api_1.diag.debug(`error obtaining process owner: ${e}`);
|
|
@@ -65948,7 +65948,7 @@ function normalizeNumberish(value) {
|
|
|
65948
65948
|
}
|
|
65949
65949
|
//#endregion
|
|
65950
65950
|
//#region package.json
|
|
65951
|
-
var version$1 = "0.13.
|
|
65951
|
+
var version$1 = "0.13.45";
|
|
65952
65952
|
//#endregion
|
|
65953
65953
|
//#region src/sentry.ts
|
|
65954
65954
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -75830,7 +75830,7 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
|
|
|
75830
75830
|
var fs$6 = __require("fs");
|
|
75831
75831
|
var path$5 = __require("path");
|
|
75832
75832
|
var url$1 = __require("url");
|
|
75833
|
-
var os$
|
|
75833
|
+
var os$3 = __require("os");
|
|
75834
75834
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
75835
75835
|
var vars = process.config && process.config.variables || {};
|
|
75836
75836
|
var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
|
|
@@ -75838,8 +75838,8 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
|
|
|
75838
75838
|
var abi = versions.modules;
|
|
75839
75839
|
if (versions.deno || process.isBun) abi = "unsupported";
|
|
75840
75840
|
var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
|
|
75841
|
-
var arch = process.env.npm_config_arch || os$
|
|
75842
|
-
var platform = process.env.npm_config_platform || os$
|
|
75841
|
+
var arch = process.env.npm_config_arch || os$3.arch();
|
|
75842
|
+
var platform = process.env.npm_config_platform || os$3.platform();
|
|
75843
75843
|
var libc = process.env.LIBC || (isMusl(platform) ? "musl" : "glibc");
|
|
75844
75844
|
var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
|
|
75845
75845
|
var uv = (versions.uv || "").split(".")[0];
|
|
@@ -93527,7 +93527,7 @@ const launchDetached = (launch) => gen(function* () {
|
|
|
93527
93527
|
});
|
|
93528
93528
|
const OpenLive = effect(Open, gen(function* () {
|
|
93529
93529
|
const open = yield* tryPromise({
|
|
93530
|
-
try: () => import("./open-
|
|
93530
|
+
try: () => import("./open-yHTUkd2Y.mjs"),
|
|
93531
93531
|
catch: (cause) => new OpenError$1({
|
|
93532
93532
|
message: "failed to load browser opener",
|
|
93533
93533
|
cause
|
|
@@ -94146,7 +94146,7 @@ const prepareBootstrapWorktree = (input) => gen(function* () {
|
|
|
94146
94146
|
projectCwd: bootstrapWorktree.projectCwd
|
|
94147
94147
|
};
|
|
94148
94148
|
});
|
|
94149
|
-
const dispatchBootstrapTurnStart = (input, command) => gen(function* () {
|
|
94149
|
+
const dispatchBootstrapTurnStart$1 = (input, command) => gen(function* () {
|
|
94150
94150
|
const { orchestrationEngine, git, gitStatusBroadcaster, projectSetupScriptRunner } = input;
|
|
94151
94151
|
const bootstrap = command.bootstrap;
|
|
94152
94152
|
const { bootstrap: _bootstrap, ...finalTurnStartCommand } = command;
|
|
@@ -94296,6 +94296,48 @@ const dispatchBootstrapTurnStart = (input, command) => gen(function* () {
|
|
|
94296
94296
|
})), command.threadId);
|
|
94297
94297
|
});
|
|
94298
94298
|
//#endregion
|
|
94299
|
+
//#region src/orchestration/Services/SpriteTaskHoldReactor.ts
|
|
94300
|
+
/**
|
|
94301
|
+
* SpriteTaskHoldReactor - keeps a Fly.io Sprite awake while a turn is running.
|
|
94302
|
+
*
|
|
94303
|
+
* Reacts to provider turn lifecycle events and holds the sprite's run open for
|
|
94304
|
+
* the duration of each turn. See `sprite/spriteTaskHold.ts` for the measurements
|
|
94305
|
+
* and the ordering rule this depends on.
|
|
94306
|
+
*
|
|
94307
|
+
* @module SpriteTaskHoldReactor
|
|
94308
|
+
*/
|
|
94309
|
+
/**
|
|
94310
|
+
* SpriteTaskHoldReactor - Service tag for the sprite task hold worker.
|
|
94311
|
+
*/
|
|
94312
|
+
var SpriteTaskHoldReactor = class extends Service$1()("forge/orchestration/Services/SpriteTaskHoldReactor") {};
|
|
94313
|
+
//#endregion
|
|
94314
|
+
//#region src/orchestration/bootstrapLaunch.ts
|
|
94315
|
+
/**
|
|
94316
|
+
* The entry point for launching a thread: a bootstrap turn start, held awake.
|
|
94317
|
+
*
|
|
94318
|
+
* A launch creates the thread, adds the worktree and starts the setup script before the first
|
|
94319
|
+
* provider event exists, so no turn hold covers it. On a sprite with nothing connected that
|
|
94320
|
+
* work advances at about 1.7% of wall clock (`sprite/spriteTaskHold.ts`). A person who sends a
|
|
94321
|
+
* first message and closes the tab would otherwise wait most of an hour for a one-minute
|
|
94322
|
+
* install.
|
|
94323
|
+
*
|
|
94324
|
+
* Callers import the dispatch from here. `bootstrapDispatch.ts` stays unaware of sprites.
|
|
94325
|
+
*/
|
|
94326
|
+
/**
|
|
94327
|
+
* Runs a launch with the sprite held awake. A launch that fails or is cancelled releases the
|
|
94328
|
+
* hold. One that succeeds keeps it: the reactor hands over to the turn's own hold when the turn
|
|
94329
|
+
* starts, and the hold's refresh budget ends it if the turn never does. Where no reactor is
|
|
94330
|
+
* wired the launch runs unchanged.
|
|
94331
|
+
*/
|
|
94332
|
+
const withLaunchHold = (threadId, launch) => gen(function* () {
|
|
94333
|
+
const reactor = yield* serviceOption(SpriteTaskHoldReactor);
|
|
94334
|
+
if (isNone(reactor)) return yield* launch;
|
|
94335
|
+
const release = () => reactor.value.releaseLaunch(threadId);
|
|
94336
|
+
return yield* uninterruptible(reactor.value.holdLaunch(threadId)).pipe(andThen(yieldNow), andThen(launch), onError$1(release));
|
|
94337
|
+
});
|
|
94338
|
+
/** `dispatchBootstrapTurnStart` from `bootstrapDispatch.ts`, with the launch held awake. */
|
|
94339
|
+
const dispatchBootstrapTurnStart = (input, command) => withLaunchHold(String(command.threadId), dispatchBootstrapTurnStart$1(input, command));
|
|
94340
|
+
//#endregion
|
|
94299
94341
|
//#region src/orchestration/Services/OrchestrationEngine.ts
|
|
94300
94342
|
/**
|
|
94301
94343
|
* OrchestrationEngineService - Service tag for orchestration engine access.
|
|
@@ -191003,7 +191045,7 @@ var Vce = {
|
|
|
191003
191045
|
function Ve() {
|
|
191004
191046
|
return Vce;
|
|
191005
191047
|
}
|
|
191006
|
-
var Us =
|
|
191048
|
+
var Us = os.homedir(), lk = os.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
|
|
191007
191049
|
let t = path.join(Us, "Library");
|
|
191008
191050
|
return {
|
|
191009
191051
|
data: path.join(t, "Application Support", e),
|
|
@@ -201203,12 +201245,12 @@ function qZ(e, t) {
|
|
|
201203
201245
|
}
|
|
201204
201246
|
return n;
|
|
201205
201247
|
}
|
|
201206
|
-
var os$
|
|
201248
|
+
var os$2 = "https://code.claude.com/docs/en", kKe = [
|
|
201207
201249
|
{
|
|
201208
201250
|
matches: (e) => e.path === "permissions.defaultMode" && e.code === "invalid_value",
|
|
201209
201251
|
tip: {
|
|
201210
201252
|
suggestion: "Valid modes: \"acceptEdits\" (ask before file changes), \"plan\" (analysis only), \"bypassPermissions\" (auto-accept all), or \"default\" (standard behavior)",
|
|
201211
|
-
docLink: `${os$
|
|
201253
|
+
docLink: `${os$2}/iam#permission-modes`
|
|
201212
201254
|
}
|
|
201213
201255
|
},
|
|
201214
201256
|
{
|
|
@@ -201223,7 +201265,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
201223
201265
|
matches: (e) => e.path.startsWith("env.") && e.code === "invalid_type",
|
|
201224
201266
|
tip: {
|
|
201225
201267
|
suggestion: "Environment variables must be strings. Wrap numbers and booleans in quotes. Example: \"DEBUG\": \"true\", \"PORT\": \"3000\"",
|
|
201226
|
-
docLink: `${os$
|
|
201268
|
+
docLink: `${os$2}/settings#environment-variables`
|
|
201227
201269
|
}
|
|
201228
201270
|
},
|
|
201229
201271
|
{
|
|
@@ -201234,14 +201276,14 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
201234
201276
|
matches: (e) => e.path.startsWith("hooks.") && e.code === "invalid_key",
|
|
201235
201277
|
tip: {
|
|
201236
201278
|
suggestion: "Not a recognized hook event. Common events: PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop. Check spelling and capitalization.",
|
|
201237
|
-
docLink: `${os$
|
|
201279
|
+
docLink: `${os$2}/hooks`
|
|
201238
201280
|
}
|
|
201239
201281
|
},
|
|
201240
201282
|
{
|
|
201241
201283
|
matches: (e) => /\.hooks\.\d+\.command$/.test(e.path) && e.code === "invalid_type" && e.received === "undefined",
|
|
201242
201284
|
tip: {
|
|
201243
201285
|
suggestion: "Command hooks require `command`. For exec form (no shell), set `command` to the executable and `args` to its arguments: {\"type\": \"command\", \"command\": \"echo\", \"args\": [\"hi\"]}. For shell form, set `command` to the full shell string: {\"type\": \"command\", \"command\": \"echo hi\"}.",
|
|
201244
|
-
docLink: `${os$
|
|
201286
|
+
docLink: `${os$2}/hooks#exec-form-and-shell-form`
|
|
201245
201287
|
}
|
|
201246
201288
|
},
|
|
201247
201289
|
{
|
|
@@ -201256,7 +201298,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
201256
201298
|
matches: (e) => e.code === "unrecognized_keys",
|
|
201257
201299
|
tip: {
|
|
201258
201300
|
suggestion: "Check for typos or refer to the documentation for valid fields",
|
|
201259
|
-
docLink: `${os$
|
|
201301
|
+
docLink: `${os$2}/settings`
|
|
201260
201302
|
}
|
|
201261
201303
|
},
|
|
201262
201304
|
{
|
|
@@ -201271,13 +201313,13 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
201271
201313
|
matches: (e) => e.path === "permissions.additionalDirectories" && e.code === "invalid_type",
|
|
201272
201314
|
tip: {
|
|
201273
201315
|
suggestion: "Must be an array of directory paths. Example: [\"~/projects\", \"/tmp/workspace\"]. You can also use --add-dir flag or /add-dir command",
|
|
201274
|
-
docLink: `${os$
|
|
201316
|
+
docLink: `${os$2}/iam#working-directories`
|
|
201275
201317
|
}
|
|
201276
201318
|
}
|
|
201277
201319
|
], AKe = {
|
|
201278
|
-
permissions: `${os$
|
|
201279
|
-
env: `${os$
|
|
201280
|
-
hooks: `${os$
|
|
201320
|
+
permissions: `${os$2}/iam#configuring-permissions`,
|
|
201321
|
+
env: `${os$2}/settings#environment-variables`,
|
|
201322
|
+
hooks: `${os$2}/hooks`
|
|
201281
201323
|
};
|
|
201282
201324
|
function GZ(e) {
|
|
201283
201325
|
let t = kKe.find((r) => r.matches(e));
|
|
@@ -210734,7 +210776,8 @@ async function listCatalog(resolveJwt, scope) {
|
|
|
210734
210776
|
catalogVersion: data.catalogVersion,
|
|
210735
210777
|
capabilitySessionId: data.capabilitySessionId,
|
|
210736
210778
|
capabilityToken: data.capabilityToken,
|
|
210737
|
-
expiresAt: data.expiresAt
|
|
210779
|
+
expiresAt: data.expiresAt,
|
|
210780
|
+
...data.codewebMcp ? { codewebMcp: data.codewebMcp } : {}
|
|
210738
210781
|
};
|
|
210739
210782
|
} catch (error) {
|
|
210740
210783
|
return {
|
|
@@ -210829,7 +210872,8 @@ async function resolveCmmdSidekickToolCatalog(resolveJwt, threadId) {
|
|
|
210829
210872
|
const catalog = await session.getCatalog();
|
|
210830
210873
|
return {
|
|
210831
210874
|
session,
|
|
210832
|
-
tools: catalog.ok ? catalog.tools : []
|
|
210875
|
+
tools: catalog.ok ? catalog.tools : [],
|
|
210876
|
+
...catalog.ok && catalog.codewebMcp ? { codewebMcp: catalog.codewebMcp } : {}
|
|
210833
210877
|
};
|
|
210834
210878
|
}
|
|
210835
210879
|
//#endregion
|
|
@@ -214452,6 +214496,18 @@ function createComputerMcpServer(computerManager, threadId) {
|
|
|
214452
214496
|
*/
|
|
214453
214497
|
const CODEWEB_MCP_SERVER_NAME = "codeweb";
|
|
214454
214498
|
const CODEWEB_MCP_SERVER_URL = "https://codeweb.cmmd.ai/mcp";
|
|
214499
|
+
/**
|
|
214500
|
+
* CMMD's grant is the primary control for the CodeWeb injection (ADR-011:
|
|
214501
|
+
* CMMD decides, Forge relays, the same pattern as the Sidekick tools). A
|
|
214502
|
+
* grant present in the catalog response decides, even when it disagrees with
|
|
214503
|
+
* the local setting. Absent grant (CMMD unreachable, auth failure, or an
|
|
214504
|
+
* older CMMD without the field, CMMD#4882) falls back to
|
|
214505
|
+
* `ServerSettings.codewebMcp` so deployments without the grant channel
|
|
214506
|
+
* (local/dev) keep a working switch.
|
|
214507
|
+
*/
|
|
214508
|
+
function resolveCodewebMcpEnabled(input) {
|
|
214509
|
+
return input.grant ? input.grant.enabled : input.setting;
|
|
214510
|
+
}
|
|
214455
214511
|
//#endregion
|
|
214456
214512
|
//#region src/cmmdData/cmmdContextMcpServer.ts
|
|
214457
214513
|
/**
|
|
@@ -215329,7 +215385,10 @@ function buildClaudeMcpServers(input) {
|
|
|
215329
215385
|
[GITHUB_MCP_SERVER_NAME]: createGitHubMcpServer(input.runBrokeredGitHubTool, input.threadId, input.serverSettings),
|
|
215330
215386
|
...input.computerManager ? { [COMPUTER_MCP_SERVER_NAME]: createComputerMcpServer(input.computerManager, input.threadId) } : {},
|
|
215331
215387
|
...input.cmmdSidekickTools ? { "cmmd-sidekick-tools": createCmmdSidekickToolsMcpServer(input.cmmdSidekickTools.session, input.cmmdSidekickTools.tools) } : {},
|
|
215332
|
-
...
|
|
215388
|
+
...resolveCodewebMcpEnabled({
|
|
215389
|
+
grant: input.codewebMcpGrant,
|
|
215390
|
+
setting: input.serverSettings.codewebMcp
|
|
215391
|
+
}) ? { [CODEWEB_MCP_SERVER_NAME]: {
|
|
215333
215392
|
type: "http",
|
|
215334
215393
|
url: CODEWEB_MCP_SERVER_URL
|
|
215335
215394
|
} } : {}
|
|
@@ -215357,18 +215416,11 @@ function createCmmdPatResolver(threadId) {
|
|
|
215357
215416
|
return readCommandAccessTokenForSession(ownerSessionId);
|
|
215358
215417
|
};
|
|
215359
215418
|
}
|
|
215360
|
-
/**
|
|
215361
|
-
* Fetches CMMD's permitted Sidekick-tool catalog once for this session, via
|
|
215362
|
-
* the resolver shared with `CodexAdapter.ts` (`resolveCmmdSidekickToolCatalog`).
|
|
215363
|
-
*
|
|
215364
|
-
* The MCP server's tool list must be static at construction time, so the
|
|
215365
|
-
* catalog is fetched here rather than lazily inside a tool call. A failure
|
|
215366
|
-
* (no CMMD session, no permitted tools, upstream error) just means the
|
|
215367
|
-
* server is omitted this turn — CMMD remains free to grant a different
|
|
215368
|
-
* catalog on the next one.
|
|
215369
|
-
*/
|
|
215370
215419
|
function resolveCmmdSidekickTools(resolveJwt, threadId) {
|
|
215371
|
-
return promise(() => resolveCmmdSidekickToolCatalog(resolveJwt, threadId)).pipe(map$3((resolved) =>
|
|
215420
|
+
return promise(() => resolveCmmdSidekickToolCatalog(resolveJwt, threadId)).pipe(map$3((resolved) => ({
|
|
215421
|
+
registration: resolved.tools.length > 0 ? resolved : null,
|
|
215422
|
+
codewebMcpGrant: resolved.codewebMcp
|
|
215423
|
+
})));
|
|
215372
215424
|
}
|
|
215373
215425
|
function buildDevServerToolDeps(input) {
|
|
215374
215426
|
return {
|
|
@@ -217553,7 +217605,7 @@ const makeClaudeAdapter = fn$1("makeClaudeAdapter")(function* (options) {
|
|
|
217553
217605
|
readThreadAuth: (targetThreadId) => runWithSqlRuntimeContext(readThreadAuthSession(targetThreadId)),
|
|
217554
217606
|
resolveJwt: (options) => runWithSqlRuntimeContext(resolveCmmdJwtForSession(options))
|
|
217555
217607
|
});
|
|
217556
|
-
const
|
|
217608
|
+
const cmmdSidekickResolution = yield* resolveCmmdSidekickTools(resolveCmmdSidekickJwtForSession, threadId);
|
|
217557
217609
|
const devServerToolDeps = buildDevServerToolDeps({
|
|
217558
217610
|
threadDevRuntime,
|
|
217559
217611
|
devTunnel,
|
|
@@ -217618,7 +217670,8 @@ const makeClaudeAdapter = fn$1("makeClaudeAdapter")(function* (options) {
|
|
|
217618
217670
|
computerManager,
|
|
217619
217671
|
resolveCmmdPat,
|
|
217620
217672
|
devServerToolDeps,
|
|
217621
|
-
cmmdSidekickTools,
|
|
217673
|
+
cmmdSidekickTools: cmmdSidekickResolution.registration,
|
|
217674
|
+
codewebMcpGrant: cmmdSidekickResolution.codewebMcpGrant,
|
|
217622
217675
|
runBrokeredGitHubTool,
|
|
217623
217676
|
serverSettings
|
|
217624
217677
|
}), threadId);
|
|
@@ -222421,14 +222474,18 @@ function formatConfigOptionValue(value) {
|
|
|
222421
222474
|
/**
|
|
222422
222475
|
* Builds the `mcpServers` payload for session/new and session/load.
|
|
222423
222476
|
*
|
|
222424
|
-
* CodeWeb (ADR-011) is injected only when
|
|
222425
|
-
*
|
|
222477
|
+
* CodeWeb (ADR-011) is injected only when CMMD's grant (primary control,
|
|
222478
|
+
* CMMD#4882) or, absent a grant, the relayed local setting enables it, AND
|
|
222479
|
+
* the agent advertised `mcpCapabilities.http` in initialize (the schema
|
|
222426
222480
|
* defaults it to false). Sending an http entry to an agent that cannot
|
|
222427
222481
|
* consume it would at best be dropped, at worst error the session, so both
|
|
222428
222482
|
* gates must pass; anything else stays an empty payload.
|
|
222429
222483
|
*/
|
|
222430
222484
|
function buildAcpMcpServers(input) {
|
|
222431
|
-
if (!
|
|
222485
|
+
if (!resolveCodewebMcpEnabled({
|
|
222486
|
+
grant: input.codewebMcpGrant,
|
|
222487
|
+
setting: input.codewebMcpEnabled
|
|
222488
|
+
})) return [];
|
|
222432
222489
|
if (input.agentCapabilities?.mcpCapabilities?.http !== true) return [];
|
|
222433
222490
|
return [{
|
|
222434
222491
|
type: "http",
|
|
@@ -222583,6 +222640,7 @@ const makeAcpSessionRuntime = (options) => gen(function* () {
|
|
|
222583
222640
|
let sessionSetupResult;
|
|
222584
222641
|
const mcpServers = buildAcpMcpServers({
|
|
222585
222642
|
codewebMcpEnabled: options.codewebMcp === true,
|
|
222643
|
+
...options.codewebMcpGrant ? { codewebMcpGrant: options.codewebMcpGrant } : {},
|
|
222586
222644
|
agentCapabilities: initializeResult.agentCapabilities
|
|
222587
222645
|
});
|
|
222588
222646
|
if (options.resumeSessionId) {
|
|
@@ -240501,8 +240559,13 @@ var SpriteTaskHoldManager = class {
|
|
|
240501
240559
|
activeTurnIds() {
|
|
240502
240560
|
return [...this.#holds.keys()];
|
|
240503
240561
|
}
|
|
240504
|
-
|
|
240562
|
+
/**
|
|
240563
|
+
* `maxRefreshes` bounds a hold that has no terminal event of its own, such as a launch
|
|
240564
|
+
* whose turn may never start. When the budget is spent the hold releases itself.
|
|
240565
|
+
*/
|
|
240566
|
+
async acquire(turnId, threadId = null, options = {}) {
|
|
240505
240567
|
if (this.#holds.has(turnId)) return;
|
|
240568
|
+
let refreshesLeft = options.maxRefreshes ?? Number.POSITIVE_INFINITY;
|
|
240506
240569
|
const name = spriteTaskHoldName(this.#config.namePrefix, turnId);
|
|
240507
240570
|
const hold = {
|
|
240508
240571
|
name,
|
|
@@ -240526,6 +240589,11 @@ var SpriteTaskHoldManager = class {
|
|
|
240526
240589
|
if (hold.released || this.#holds.get(turnId) !== hold) return;
|
|
240527
240590
|
hold.refresher = this.#timer.setInterval(() => {
|
|
240528
240591
|
if (hold.inFlight.size > 0) return;
|
|
240592
|
+
if (refreshesLeft <= 0) {
|
|
240593
|
+
if (this.#holds.get(turnId) === hold) this.release(turnId);
|
|
240594
|
+
return;
|
|
240595
|
+
}
|
|
240596
|
+
refreshesLeft -= 1;
|
|
240529
240597
|
const refresh = this.#transport.put(name, 300).catch((cause) => this.#onError(`failed to refresh sprite task hold for turn ${turnId}`, cause));
|
|
240530
240598
|
hold.inFlight.add(refresh);
|
|
240531
240599
|
refresh.finally(() => hold.inFlight.delete(refresh));
|
|
@@ -269232,7 +269300,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
|
|
|
269232
269300
|
var dgram = __require("dgram");
|
|
269233
269301
|
var thunky = require_thunky();
|
|
269234
269302
|
var events = __require("events");
|
|
269235
|
-
var os = __require("os");
|
|
269303
|
+
var os$1 = __require("os");
|
|
269236
269304
|
var noop = function() {};
|
|
269237
269305
|
module.exports = function(opts) {
|
|
269238
269306
|
if (!opts) opts = {};
|
|
@@ -269363,14 +269431,14 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
|
|
|
269363
269431
|
return that;
|
|
269364
269432
|
};
|
|
269365
269433
|
function defaultInterface() {
|
|
269366
|
-
var networks = os.networkInterfaces();
|
|
269434
|
+
var networks = os$1.networkInterfaces();
|
|
269367
269435
|
var names = Object.keys(networks);
|
|
269368
269436
|
for (var i = 0; i < names.length; i++) {
|
|
269369
269437
|
var net = networks[names[i]];
|
|
269370
269438
|
for (var j = 0; j < net.length; j++) {
|
|
269371
269439
|
var iface = net[j];
|
|
269372
269440
|
if (isIPv4(iface.family) && !iface.internal) {
|
|
269373
|
-
if (os.platform() === "darwin" && names[i] === "en0") return iface.address;
|
|
269441
|
+
if (os$1.platform() === "darwin" && names[i] === "en0") return iface.address;
|
|
269374
269442
|
return "0.0.0.0";
|
|
269375
269443
|
}
|
|
269376
269444
|
}
|
|
@@ -269378,7 +269446,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
|
|
|
269378
269446
|
return "127.0.0.1";
|
|
269379
269447
|
}
|
|
269380
269448
|
function allInterfaces() {
|
|
269381
|
-
var networks = os.networkInterfaces();
|
|
269449
|
+
var networks = os$1.networkInterfaces();
|
|
269382
269450
|
var names = Object.keys(networks);
|
|
269383
269451
|
var res = [];
|
|
269384
269452
|
for (var i = 0; i < names.length; i++) {
|
|
@@ -286581,21 +286649,6 @@ var ProviderRuntimeIngestionService = class extends Service$1()("forge/orchestra
|
|
|
286581
286649
|
//#region src/orchestration/Services/PlanTaskCreationReactor.ts
|
|
286582
286650
|
var PlanTaskCreationReactor = class extends Service$1()("forge/orchestration/Services/PlanTaskCreationReactor") {};
|
|
286583
286651
|
//#endregion
|
|
286584
|
-
//#region src/orchestration/Services/SpriteTaskHoldReactor.ts
|
|
286585
|
-
/**
|
|
286586
|
-
* SpriteTaskHoldReactor - keeps a Fly.io Sprite awake while a turn is running.
|
|
286587
|
-
*
|
|
286588
|
-
* Reacts to provider turn lifecycle events and holds the sprite's run open for
|
|
286589
|
-
* the duration of each turn. See `sprite/spriteTaskHold.ts` for the measurements
|
|
286590
|
-
* and the ordering rule this depends on.
|
|
286591
|
-
*
|
|
286592
|
-
* @module SpriteTaskHoldReactor
|
|
286593
|
-
*/
|
|
286594
|
-
/**
|
|
286595
|
-
* SpriteTaskHoldReactor - Service tag for the sprite task hold worker.
|
|
286596
|
-
*/
|
|
286597
|
-
var SpriteTaskHoldReactor = class extends Service$1()("forge/orchestration/Services/SpriteTaskHoldReactor") {};
|
|
286598
|
-
//#endregion
|
|
286599
286652
|
//#region src/persistence/Services/ProjectionProjects.ts
|
|
286600
286653
|
/**
|
|
286601
286654
|
* ProjectionProjectRepository - Projection repository interface for projects.
|
|
@@ -293097,34 +293150,82 @@ const CheckpointReactorLive = effect(CheckpointReactor, gen(function* () {
|
|
|
293097
293150
|
drain: worker.drain
|
|
293098
293151
|
};
|
|
293099
293152
|
}));
|
|
293153
|
+
//#endregion
|
|
293154
|
+
//#region src/orchestration/Layers/SpriteTaskHoldReactor.ts
|
|
293155
|
+
/**
|
|
293156
|
+
* Holds the sprite awake for the duration of every agent turn.
|
|
293157
|
+
*
|
|
293158
|
+
* A sprite's cgroup freezes ~1s after the last inbound request, so a turn that
|
|
293159
|
+
* nobody is watching advances at ~1.7% of wall clock. A task hold restores it to
|
|
293160
|
+
* 100%. Measurements and the release-ordering rule live in
|
|
293161
|
+
* `sprite/spriteTaskHold.ts`; the platform contract is documented in
|
|
293162
|
+
* `docs/specs/2026-07-30-sprites-platform-ground-truth.md` §1.
|
|
293163
|
+
*
|
|
293164
|
+
* This subscribes to the same provider event stream CheckpointReactor uses, so
|
|
293165
|
+
* it is provider-agnostic: codex, claude and every other adapter emit
|
|
293166
|
+
* `turn.started` / `turn.completed` through `ProviderService.streamEvents`.
|
|
293167
|
+
*/
|
|
293168
|
+
/**
|
|
293169
|
+
* A launch hold refreshes every 60 s, so this budget is about ten minutes. A launch whose turn
|
|
293170
|
+
* never starts, because the provider refused it or the process died first, has no event to
|
|
293171
|
+
* release it. The budget is what stops that hold from keeping the sprite billing.
|
|
293172
|
+
*/
|
|
293173
|
+
const LAUNCH_HOLD_MAX_REFRESHES = 10;
|
|
293174
|
+
/** The hold id of a thread's launch. One launch per thread, so the thread names it. */
|
|
293175
|
+
const launchHoldId = (threadId) => `launch-${threadId}`;
|
|
293100
293176
|
const SpriteTaskHoldReactorLive = effect(SpriteTaskHoldReactor, gen(function* () {
|
|
293101
293177
|
const providerService = yield* ProviderService;
|
|
293102
293178
|
const manager = makeSpriteTaskHoldManager(process.env, (message, cause) => {
|
|
293103
293179
|
runFork(logWarning$1(message, { cause: cause instanceof Error ? cause.message : cause }));
|
|
293104
293180
|
});
|
|
293181
|
+
const launchCallers = /* @__PURE__ */ new Map();
|
|
293182
|
+
const start = fn$1("start")(function* () {
|
|
293183
|
+
if (manager === null) return;
|
|
293184
|
+
yield* forkScoped(runForEach(providerService.streamEvents, (event) => {
|
|
293185
|
+
if (event.type === "turn.started") {
|
|
293186
|
+
const turnId = event.turnId;
|
|
293187
|
+
if (turnId === void 0) return void_$1;
|
|
293188
|
+
return promise(async () => {
|
|
293189
|
+
await manager.acquire(String(turnId), String(event.threadId));
|
|
293190
|
+
launchCallers.delete(String(event.threadId));
|
|
293191
|
+
await manager.release(launchHoldId(String(event.threadId)));
|
|
293192
|
+
});
|
|
293193
|
+
}
|
|
293194
|
+
if (event.type === "turn.completed") {
|
|
293195
|
+
const turnId = event.turnId;
|
|
293196
|
+
if (turnId === void 0) return void_$1;
|
|
293197
|
+
return promise(() => manager.release(String(turnId)));
|
|
293198
|
+
}
|
|
293199
|
+
if (event.type === "turn.aborted") {
|
|
293200
|
+
const turnId = event.turnId;
|
|
293201
|
+
if (turnId === void 0) return void_$1;
|
|
293202
|
+
return promise(() => manager.release(String(turnId)));
|
|
293203
|
+
}
|
|
293204
|
+
if (event.type === "session.exited") {
|
|
293205
|
+
launchCallers.delete(String(event.threadId));
|
|
293206
|
+
return promise(() => manager.releaseThread(String(event.threadId)));
|
|
293207
|
+
}
|
|
293208
|
+
return void_$1;
|
|
293209
|
+
}));
|
|
293210
|
+
});
|
|
293211
|
+
/** Takes the launch hold for one more caller. The budget bounds a launch that never starts a turn. */
|
|
293212
|
+
const holdLaunch = (threadId) => promise(async () => {
|
|
293213
|
+
if (manager === null) return;
|
|
293214
|
+
launchCallers.set(threadId, (launchCallers.get(threadId) ?? 0) + 1);
|
|
293215
|
+
await manager.acquire(launchHoldId(threadId), threadId, { maxRefreshes: LAUNCH_HOLD_MAX_REFRESHES });
|
|
293216
|
+
});
|
|
293217
|
+
/** Lets one caller go. The hold itself is released when the last caller has let go. */
|
|
293218
|
+
const releaseLaunch = (threadId) => promise(async () => {
|
|
293219
|
+
if (manager === null) return;
|
|
293220
|
+
const remaining = (launchCallers.get(threadId) ?? 1) - 1;
|
|
293221
|
+
if (remaining > 0) return void launchCallers.set(threadId, remaining);
|
|
293222
|
+
launchCallers.delete(threadId);
|
|
293223
|
+
await manager.release(launchHoldId(threadId));
|
|
293224
|
+
});
|
|
293105
293225
|
return {
|
|
293106
|
-
start
|
|
293107
|
-
|
|
293108
|
-
|
|
293109
|
-
if (event.type === "turn.started") {
|
|
293110
|
-
const turnId = event.turnId;
|
|
293111
|
-
if (turnId === void 0) return void_$1;
|
|
293112
|
-
return promise(() => manager.acquire(String(turnId), String(event.threadId)));
|
|
293113
|
-
}
|
|
293114
|
-
if (event.type === "turn.completed") {
|
|
293115
|
-
const turnId = event.turnId;
|
|
293116
|
-
if (turnId === void 0) return void_$1;
|
|
293117
|
-
return promise(() => manager.release(String(turnId)));
|
|
293118
|
-
}
|
|
293119
|
-
if (event.type === "turn.aborted") {
|
|
293120
|
-
const turnId = event.turnId;
|
|
293121
|
-
if (turnId === void 0) return void_$1;
|
|
293122
|
-
return promise(() => manager.release(String(turnId)));
|
|
293123
|
-
}
|
|
293124
|
-
if (event.type === "session.exited") return promise(() => manager.releaseThread(String(event.threadId)));
|
|
293125
|
-
return void_$1;
|
|
293126
|
-
}));
|
|
293127
|
-
}),
|
|
293226
|
+
start,
|
|
293227
|
+
holdLaunch,
|
|
293228
|
+
releaseLaunch,
|
|
293128
293229
|
releaseAll: promise(() => manager === null ? Promise.resolve() : manager.releaseAll())
|
|
293129
293230
|
};
|
|
293130
293231
|
}));
|
|
@@ -297239,7 +297340,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
297239
297340
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
297240
297341
|
*/
|
|
297241
297342
|
function readBakedBuildCommit() {
|
|
297242
|
-
return "
|
|
297343
|
+
return "8ada8bfccfb8a4b0827961f304821e7b11249865";
|
|
297243
297344
|
}
|
|
297244
297345
|
async function resolveServerBuildCommit(input) {
|
|
297245
297346
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -321840,7 +321941,7 @@ const connectLoginCommand = make$34("login", {
|
|
|
321840
321941
|
})).json();
|
|
321841
321942
|
},
|
|
321842
321943
|
openBrowser: async (url) => {
|
|
321843
|
-
const open = (await import("./open-
|
|
321944
|
+
const open = (await import("./open-yHTUkd2Y.mjs")).default;
|
|
321844
321945
|
await open(url);
|
|
321845
321946
|
return true;
|
|
321846
321947
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as r,Wa as i}from"./Stream-mUTFnSY9.js";import{Al as a,Fn as o,Gc as s,Hr as c,Jc as l,Qr as u,Rr as d,Sr as f,Tn as p,Uc as m,Xr as h,_r as g,d as _,fn as v,fr as y,gr as b,i as x,is as S,jn as C,l as w,m as T,ms as E,n as D,qc as O,qt as k,r as A,u as j,za as M,zr as N}from"./DiffPanelShell-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as r,Wa as i}from"./Stream-mUTFnSY9.js";import{Al as a,Fn as o,Gc as s,Hr as c,Jc as l,Qr as u,Rr as d,Sr as f,Tn as p,Uc as m,Xr as h,_r as g,d as _,fn as v,fr as y,gr as b,i as x,is as S,jn as C,l as w,m as T,ms as E,n as D,qc as O,qt as k,r as A,u as j,za as M,zr as N}from"./DiffPanelShell-DFspB3po.js";import{hn as P}from"./CompositeItem-DZBAkVp1.js";import{a as F,c as I,f as L,i as R,l as z,m as B,n as V,o as H,p as U,r as W,s as G,t as K}from"./Virtualizer-cy0aLqwi.js";import{Dn as q,at as J,it as ee}from"./src-rKJju-ZW.js";import{a as te,c as ne,d as re,h as ie,i as ae,l as oe,m as se,n as ce,o as Y,p as le,r as ue,s as de,t as fe,u as pe}from"./DiffPanel.logic-BHJKg1bv.js";var X=e(i(),1),me=typeof window>`u`?X.useEffect:X.useLayoutEffect;function he({fileDiff:e,options:t,editorOptions:n,lineAnnotations:r,selectedLines:i,prerenderedHTML:a,metrics:o,hasGutterRenderUtility:s,hasCustomHeader:c,disableWorkerPool:l,edit:u}){let d=V(),f=i!==void 0,p=(0,X.useContext)(x),m=j(),h=(0,X.useRef)(null),g=_(n=>{if(n!=null){if(h.current!=null)throw Error(`useFileDiffInstance: An instance should not already exist when a node is created`);d==null?h.current=new re(Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),l?void 0:p,!0):h.current=new pe(Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),d,o,l?void 0:p,!0),h.current.hydrate({fileDiff:e,fileContainer:n,lineAnnotations:r,prerenderedHTML:a})}else{if(h.current==null)throw Error(`useFileDiffInstance: A FileDiff instance should exist when unmounting`);h.current.cleanUp(),h.current=null}});return me(()=>{let{current:n}=h;if(n==null)return;let a=Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),o=a!==void 0&&!k(n.options,a);n.setOptions(a),n.render({forceRender:o,fileDiff:e,lineAnnotations:r}),i!==void 0&&n.setSelectedLines(i)}),me(()=>{if(u&&h.current!=null){if(m===void 0)throw Error(`FileDiff: EditContext is not attached`);let e=m(n??{});if(e==null)throw Error(`FileDiff: EditProvider.createEditor must return an editor instance`);try{return e.edit(h.current)}catch(t){throw e.cleanUp(),t}}},[u]),{ref:g,getHoveredLine:(0,X.useCallback)(()=>h.current?.getHoveredLine(),[])}}function Z({options:e,controlledSelection:t,hasCustomHeader:n,hasGutterRenderUtility:r}){return t||r||n?{...e,controlledSelection:t,renderCustomHeader:n?w:e?.renderCustomHeader,renderGutterUtility:r?w:e?.renderGutterUtility}:e}var Q=r();function ge({fileDiff:e,options:t,editorOptions:n,metrics:r,lineAnnotations:i,selectedLines:a,className:o,style:s,prerenderedHTML:c,renderAnnotation:l,renderCustomHeader:u,renderHeaderPrefix:d,renderHeaderFilenameSuffix:f,renderHeaderMetadata:p,renderGutterUtility:m,disableWorkerPool:h=!1,edit:g=!1}){let{ref:_,getHoveredLine:y}=he({fileDiff:e,options:t,editorOptions:n,metrics:r,lineAnnotations:i,selectedLines:a,prerenderedHTML:c,hasGutterRenderUtility:m!=null,hasCustomHeader:u!=null,disableWorkerPool:h,edit:g});return(0,Q.jsx)(v,{ref:_,className:o,style:s,children:W(oe({fileDiff:e,renderCustomHeader:u,renderHeaderPrefix:d,renderHeaderFilenameSuffix:f,renderHeaderMetadata:p,renderAnnotation:l,renderGutterUtility:m,lineAnnotations:i,getHoveredLine:y}),c)})}var $=t();function _e(e){return e.fromTurnCount===0?q(ee)({threadId:e.threadId,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`fullThreadDiff`,input:e}))):q(J)({threadId:e.threadId,fromTurnCount:e.fromTurnCount,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`turnDiff`,input:e})))}function ve(e){return e instanceof Error?e.message:typeof e==`string`?e:``}function ye(e){let t=ve(e).trim();if(t.length===0)return`Failed to load checkpoint diff.`;let n=t.toLowerCase();if(n.includes(`not a git repository`))return`Turn diffs are unavailable because this project is not a git repository.`;if(n.includes(`checkpoint unavailable for thread`)||n.includes(`checkpoint invariant violation`)){let e=t.indexOf(`:`);if(e>=0){let n=t.slice(e+1).trim();if(n.length>0)return n}}return t}function be(e){let t=ve(e).toLowerCase();return t.includes(`exceeds current turn count`)||t.includes(`checkpoint is unavailable for turn`)||t.includes(`filesystem checkpoint is unavailable`)}function xe(e){let t=_e(e);return O({queryKey:M.checkpointDiff(e),queryFn:async({signal:n})=>{if(!e.environmentId||!e.threadId||t._tag===`None`)throw Error(`Checkpoint diff is unavailable.`);let r=c(e.environmentId);try{return t.value.kind===`fullThreadDiff`?await r.orchestration.getFullThreadDiff(t.value.input,{signal:n}):await r.orchestration.getTurnDiff(t.value.input,{signal:n})}catch(e){throw Error(ye(e),{cause:e})}},enabled:(e.enabled??!0)&&!!e.environmentId&&!!e.threadId&&t._tag===`Some`,staleTime:1/0,retry:(e,t)=>be(t)?e<12:e<3,retryDelay:(e,t)=>be(t)?Math.min(5e3,250*2**(e-1)):Math.min(1e3,100*2**(e-1))})}function Se(e){if(!(!e.canScrollLeft&&!e.canScrollRight))return{maskImage:`linear-gradient(to right, ${e.canScrollLeft?`transparent 24px, black 72px`:`black`}, ${e.canScrollRight?`black calc(100% - 72px), transparent calc(100% - 24px)`:`black`})`}}function Ce(e){return e instanceof Error?e.message:e?`Failed to load checkpoint diff.`:null}function we(e){return{environmentId:e.environmentId??null,threadId:e.threadId,fromTurnCount:e.range?.fromTurnCount??null,toTurnCount:e.range?.toTurnCount??null,cacheScope:e.selectedTurnId?`turn:${e.selectedTurnId}`:e.conversationCacheScope,enabled:e.enabled}}function Te(){let e=(0,$.c)(8),t=(0,X.useRef)(null),[n,r]=(0,X.useState)(!1),[i,a]=(0,X.useState)(!1),o;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(o=()=>{let e=t.current;if(!e){r(!1),a(!1);return}let n=de({scrollLeft:e.scrollLeft,scrollWidth:e.scrollWidth,clientWidth:e.clientWidth});r(n.canScrollLeft),a(n.canScrollRight)},e[0]=o):o=e[0];let s=o,c;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(c=e=>{t.current?.scrollBy({left:e,behavior:`smooth`})},e[1]=c):c=e[1];let l=c,u;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(u=e=>{let n=t.current;n&&ne({scrollWidth:n.scrollWidth,clientWidth:n.clientWidth,deltaX:e.deltaX,deltaY:e.deltaY})&&(e.preventDefault(),n.scrollBy({left:e.deltaY,behavior:`auto`}))},e[2]=u):u=e[2];let d=u,f,p;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(f=()=>{let e=t.current;if(!e)return;let n=window.requestAnimationFrame(s),r=()=>s();e.addEventListener(`scroll`,r,{passive:!0});let i=new ResizeObserver(()=>s());return i.observe(e),()=>{window.cancelAnimationFrame(n),e.removeEventListener(`scroll`,r),i.disconnect()}},p=[s],e[3]=f,e[4]=p):(f=e[3],p=e[4]),(0,X.useEffect)(f,p);let m;return e[5]!==n||e[6]!==i?(m={ref:t,canScrollLeft:n,canScrollRight:i,scrollBy:l,onWheel:d,remeasure:s},e[5]=n,e[6]=i,e[7]=m):m=e[7],m}function Ee(e,t){let n=(0,$.c)(5),r;n[0]===e.current?r=n[1]:(r=()=>{(e.current?.querySelector(`[data-turn-chip-selected='true']`))?.scrollIntoView({block:`nearest`,inline:`nearest`,behavior:`smooth`})},n[0]=e.current,n[1]=r);let i;n[2]!==e||n[3]!==t?(i=[e,t],n[2]=e,n[3]=t,n[4]=i):i=n[4],(0,X.useEffect)(r,i)}var De=`
|
|
2
2
|
[data-diffs-header],
|
|
3
3
|
[data-diff],
|
|
4
4
|
[data-file],
|
|
@@ -61,4 +61,4 @@ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as
|
|
|
61
61
|
text-decoration-color: currentColor;
|
|
62
62
|
}
|
|
63
63
|
`;function Oe(e){let t=(0,$.c)(44),{mode:n}=e,r=n===void 0?`inline`:n,{resolvedTheme:i}=b(),a=g(),[c,l]=(0,X.useState)(`stacked`),[u,d]=(0,X.useState)(a.diffWordWrap),h=(0,X.useRef)(null),_=(0,X.useRef)(!1),v=Te(),{activeCwd:y,activeThread:x,bodyState:S,diffOpen:C,inferredCheckpointTurnCountByTurnId:w,orderedTurnDiffSummaries:T,renderableFiles:E,renderablePatch:D,selectedFilePath:O,selectedTurn:k,selectedTurnId:j}=Le(i),M,P;t[0]!==C||t[1]!==a.diffWordWrap?(M=()=>{C&&!_.current&&d(a.diffWordWrap),_.current=C},P=[C,a.diffWordWrap],t[0]=C,t[1]=a.diffWordWrap,t[2]=M,t[3]=P):(M=t[2],P=t[3]),(0,X.useEffect)(M,P);let F;t[4]===O?F=t[5]:(F=()=>{!O||!h.current||Array.from(h.current.querySelectorAll(`[data-diff-file-path]`)).find(e=>e.dataset.diffFilePath===O)?.scrollIntoView({block:`nearest`})},t[4]=O,t[5]=F);let I;t[6]!==E||t[7]!==O?(I=[O,E],t[6]=E,t[7]=O,t[8]=I):I=t[8],(0,X.useEffect)(F,I);let L;t[9]===y?L=t[10]:(L=e=>{let t=f();if(!t)return;let n=y?p(e,y):e;N(t,n).catch(ke)},t[9]=y,t[10]=L);let R=L,z;t[11]===x?z=t[12]:(z=e=>{x&&o.getState().openDiff(s(m(x.environmentId,x.id)),e)},t[11]=x,t[12]=z);let B=z,V;t[13]===x?V=t[14]:(V=()=>{x&&o.getState().openDiff(s(m(x.environmentId,x.id)))},t[13]=x,t[14]=V);let H=V,U;t[15]===v.remeasure?U=t[16]:(U=()=>{let e=window.requestAnimationFrame(v.remeasure);return()=>window.cancelAnimationFrame(e)},t[15]=v.remeasure,t[16]=U);let W;t[17]!==T||t[18]!==j||t[19]!==v.remeasure?(W=[T,j,v.remeasure],t[17]=T,t[18]=j,t[19]=v.remeasure,t[20]=W):W=t[20],(0,X.useEffect)(U,W),Ee(v.ref,k?.turnId??j);let G;t[21]!==c||t[22]!==u||t[23]!==w||t[24]!==T||t[25]!==B||t[26]!==H||t[27]!==k||t[28]!==j||t[29]!==a||t[30]!==v?(G=(0,Q.jsx)(Ae,{diffRenderMode:c,diffWordWrap:u,inferredCheckpointTurnCountByTurnId:w,orderedTurnDiffSummaries:T,selectTurn:B,selectWholeConversation:H,selectedTurn:k,selectedTurnId:j,setDiffRenderMode:l,setDiffWordWrap:d,settings:a,turnStrip:v}),t[21]=c,t[22]=u,t[23]=w,t[24]=T,t[25]=B,t[26]=H,t[27]=k,t[28]=j,t[29]=a,t[30]=v,t[31]=G):G=t[31];let K=G,q;t[32]!==S||t[33]!==c||t[34]!==u||t[35]!==R||t[36]!==E||t[37]!==D||t[38]!==i?(q=(0,Q.jsx)(je,{bodyState:S,diffRenderMode:c,diffWordWrap:u,openDiffFileInEditor:R,patchViewportRef:h,renderableFiles:E,renderablePatch:D,resolvedTheme:i}),t[32]=S,t[33]=c,t[34]=u,t[35]=R,t[36]=E,t[37]=D,t[38]=i,t[39]=q):q=t[39];let J;return t[40]!==K||t[41]!==r||t[42]!==q?(J=(0,Q.jsx)(A,{mode:r,header:K,children:q}),t[40]=K,t[41]=r,t[42]=q,t[43]=J):J=t[43],J}function ke(e){console.warn(`Failed to open diff file in editor.`,e)}function Ae(e){let t=(0,$.c)(59),{diffRenderMode:n,diffWordWrap:r,inferredCheckpointTurnCountByTurnId:i,orderedTurnDiffSummaries:a,selectTurn:o,selectWholeConversation:s,selectedTurn:c,selectedTurnId:l,setDiffRenderMode:u,setDiffWordWrap:d,settings:f,turnStrip:p}=e,m,h;t[0]===p?(m=t[1],h=t[2]):(m=(0,Q.jsx)(Be,{direction:`left`,strip:p}),h=(0,Q.jsx)(Be,{direction:`right`,strip:p}),t[0]=p,t[1]=m,t[2]=h);let g=p.ref,_;t[3]!==p.canScrollLeft||t[4]!==p.canScrollRight?(_=Se({canScrollLeft:p.canScrollLeft,canScrollRight:p.canScrollRight}),t[3]=p.canScrollLeft,t[4]=p.canScrollRight,t[5]=_):_=t[5];let v=p.onWheel,y=l===null,b=l===null?`border-border bg-accent text-accent-foreground`:`border-border/70 bg-background/70 text-muted-foreground/80 hover:border-border hover:text-foreground/80`,x;t[6]===b?x=t[7]:(x=P(`rounded-md border px-2 py-1 text-left transition-colors`,b),t[6]=b,t[7]=x);let S;t[8]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,Q.jsx)(`div`,{className:`text-[10px] leading-tight font-medium`,children:`All turns`}),t[8]=S):S=t[8];let C;t[9]===x?C=t[10]:(C=(0,Q.jsx)(`div`,{className:x,children:S}),t[9]=x,t[10]=C);let w;t[11]!==s||t[12]!==C||t[13]!==y?(w=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,"data-turn-chip-selected":y,children:C}),t[11]=s,t[12]=C,t[13]=y,t[14]=w):w=t[14];let T;if(t[15]!==i||t[16]!==a||t[17]!==o||t[18]!==c?.turnId||t[19]!==f){let e;t[21]!==i||t[22]!==o||t[23]!==c?.turnId||t[24]!==f?(e=e=>(0,Q.jsx)(Ve,{summary:e,selected:e.turnId===c?.turnId,turnCount:e.checkpointTurnCount??i[e.turnId],timestampFormat:f.timestampFormat,onSelect:o},e.turnId),t[21]=i,t[22]=o,t[23]=c?.turnId,t[24]=f,t[25]=e):e=t[25],T=a.map(e),t[15]=i,t[16]=a,t[17]=o,t[18]=c?.turnId,t[19]=f,t[20]=T}else T=t[20];let E;t[26]!==w||t[27]!==T||t[28]!==_||t[29]!==p.onWheel||t[30]!==p.ref?(E=(0,Q.jsxs)(`div`,{ref:g,className:`turn-chip-strip flex gap-1 overflow-x-auto px-8 py-0.5`,style:_,onWheel:v,children:[w,T]}),t[26]=w,t[27]=T,t[28]=_,t[29]=p.onWheel,t[30]=p.ref,t[31]=E):E=t[31];let D;t[32]!==m||t[33]!==E||t[34]!==h?(D=(0,Q.jsxs)(`div`,{className:`relative min-w-0 flex-1 [-webkit-app-region:no-drag]`,children:[m,h,E]}),t[32]=m,t[33]=E,t[34]=h,t[35]=D):D=t[35];let O;t[36]===n?O=t[37]:(O=[n],t[36]=n,t[37]=O);let k;t[38]===u?k=t[39]:(k=e=>{let t=e[0];(t===`stacked`||t===`split`)&&u(t)},t[38]=u,t[39]=k);let A;t[40]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,Q.jsx)(R,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,Q.jsx)(se,{className:`size-3`})}),t[40]=A):A=t[40];let j;t[41]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,Q.jsx)(R,{"aria-label":`Split diff view`,value:`split`,children:(0,Q.jsx)(ie,{className:`size-3`})}),t[41]=j):j=t[41];let M;t[42]!==O||t[43]!==k?(M=(0,Q.jsxs)(F,{className:`shrink-0`,variant:`outline`,size:`xs`,value:O,onValueChange:k,children:[A,j]}),t[42]=O,t[43]=k,t[44]=M):M=t[44];let N=r?`Disable diff line wrapping`:`Enable diff line wrapping`,I=r?`Disable line wrapping`:`Enable line wrapping`,L;t[45]===d?L=t[46]:(L=e=>{d(!!e)},t[45]=d,t[46]=L);let z;t[47]===Symbol.for(`react.memo_cache_sentinel`)?(z=(0,Q.jsx)(le,{className:`size-3`}),t[47]=z):z=t[47];let B;t[48]!==r||t[49]!==N||t[50]!==I||t[51]!==L?(B=(0,Q.jsx)(R,{"aria-label":N,title:I,variant:`outline`,size:`xs`,pressed:r,onPressedChange:L,children:z}),t[48]=r,t[49]=N,t[50]=I,t[51]=L,t[52]=B):B=t[52];let V;t[53]!==M||t[54]!==B?(V=(0,Q.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 [-webkit-app-region:no-drag]`,children:[M,B]}),t[53]=M,t[54]=B,t[55]=V):V=t[55];let H;return t[56]!==D||t[57]!==V?(H=(0,Q.jsxs)(Q.Fragment,{children:[D,V]}),t[56]=D,t[57]=V,t[58]=H):H=t[58],H}function je(e){let t=(0,$.c)(18),{bodyState:n,diffRenderMode:r,diffWordWrap:i,openDiffFileInEditor:a,patchViewportRef:o,renderableFiles:s,renderablePatch:c,resolvedTheme:l}=e;if(n.kind===`no-thread`){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`Select a thread to inspect turn diffs.`}),t[0]=e):e=t[0],e}if(n.kind===`not-git-repo`){let e;return t[1]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`Turn diffs are unavailable because this project is not a git repository.`}),t[1]=e):e=t[1],e}if(n.kind===`no-completed-turns`){let e;return t[2]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`No completed turns yet.`}),t[2]=e):e=t[2],e}let u;t[3]!==n.error||t[4]!==c?(u=n.error&&!c&&(0,Q.jsx)(`div`,{className:`px-3`,children:(0,Q.jsx)(`p`,{className:`mb-2 text-[11px] text-destructive-foreground`,children:n.error})}),t[3]=n.error,t[4]=c,t[5]=u):u=t[5];let d;t[6]!==n||t[7]!==r||t[8]!==i||t[9]!==a||t[10]!==s||t[11]!==c||t[12]!==l?(d=c?c.kind===`files`?(0,Q.jsx)(K,{className:`diff-render-surface h-full min-h-0 overflow-auto px-2 pb-2`,config:{overscrollSize:600,intersectionObserverMargin:1200},children:s.map(e=>{let t=Y(e),n=`${fe(e)}:${l}`;return(0,Q.jsx)(`div`,{"data-diff-file-path":t,className:`diff-render-file mb-2 rounded-md first:mt-2 last:mb-0`,onClickCapture:e=>{(e.nativeEvent.composedPath?.()??[]).some(Me)&&a(t)},children:(0,Q.jsx)(ge,{fileDiff:e,options:{diffStyle:r===`split`?`split`:`unified`,lineDiffType:`none`,overflow:i?`wrap`:`scroll`,theme:T(l),themeType:l,unsafeCSS:De}})},n)})}):(0,Q.jsx)(`div`,{className:`h-full overflow-auto p-2`,children:(0,Q.jsxs)(`div`,{className:`space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] text-muted-foreground/75`,children:c.reason}),(0,Q.jsx)(`pre`,{className:P(`max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-[11px] leading-relaxed text-muted-foreground/90`,i?`overflow-auto whitespace-pre-wrap wrap-break-word`:`overflow-auto`),children:c.text})]})}):(0,Q.jsx)(Re,{bodyState:n}),t[6]=n,t[7]=r,t[8]=i,t[9]=a,t[10]=s,t[11]=c,t[12]=l,t[13]=d):d=t[13];let f;return t[14]!==o||t[15]!==u||t[16]!==d?(f=(0,Q.jsx)(Q.Fragment,{children:(0,Q.jsxs)(`div`,{ref:o,className:`diff-panel-viewport min-h-0 min-w-0 flex-1 overflow-hidden`,children:[u,d]})}),t[14]=o,t[15]=u,t[16]=d,t[17]=f):f=t[17],f}function Me(e){return e instanceof Element&&e.hasAttribute(`data-title`)}function Ne(e){let t=(0,$.c)(2),{children:n}=e,r;return t[0]===n?r=t[1]:(r=(0,Q.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:n}),t[0]=n,t[1]=r),r}function Pe(){let e=(0,$.c)(19),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={strict:!1,select:Ie},e[0]=t):t=e[0];let n=a(t),r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r={strict:!1,select:Fe},e[1]=r):r=e[1];let i=B(r),o=i.rightPanel===`diff`,s=n?.threadId??null,c,l;e[2]===n?l=e[3]:(l=C(n),e[2]=n,e[3]=l),c=l;let u=E(c),f=He(u),p=u?.worktreePath,m=f?.cwd,h;e[4]!==p||e[5]!==m?(h=I({threadWorktreePath:p,projectCwd:m}),e[4]=p,e[5]=m,e[6]=h):h=e[6];let g=h,_=u?.environmentId??null,v=g??null,y;e[7]!==_||e[8]!==v?(y={environmentId:_,cwd:v},e[7]=_,e[8]=v,e[9]=y):y=e[9];let b=d(y),x;e[10]===b.data?x=e[11]:(x=z(b.data),e[10]=b.data,e[11]=x);let S=x,w;return e[12]!==g||e[13]!==u||e[14]!==s||e[15]!==o||e[16]!==i||e[17]!==S?(w={activeThread:u,activeThreadId:s,activeCwd:g,isGitRepo:S,diffSearch:i,diffOpen:o},e[12]=g,e[13]=u,e[14]=s,e[15]=o,e[16]=i,e[17]=S,e[18]=w):w=e[18],w}function Fe(e){return G(e)}function Ie(e){return h(e)}function Le(e){let{activeThread:t,activeThreadId:n,activeCwd:r,isGitRepo:i,diffSearch:a,diffOpen:o}=Pe(),{turnDiffSummaries:s,inferredCheckpointTurnCountByTurnId:c}=H(t),u=a.diffTurnId??null,d=u===null?null:a.diffFilePath??null,{activeCheckpointRange:f,conversationCacheScope:p,orderedTurnDiffSummaries:m,selectedTurn:h}=(0,X.useMemo)(()=>te({summaries:s,inferredCheckpointTurnCountByTurnId:c,selectedTurnId:u}),[c,u,s]),g=l(xe(we({environmentId:t?.environmentId,threadId:n,range:f,selectedTurnId:h?.turnId,conversationCacheScope:p,enabled:i}))),_=g.isLoading,v=Ce(g.error),y=g.data?.diff,b=typeof y==`string`&&y.trim().length===0,{emptyDiffMessage:x}=(0,X.useMemo)(()=>ae(h),[h]),S=(0,X.useMemo)(()=>ce(y,`diff-panel:${e}`),[e,y]),C=(0,X.useMemo)(()=>Ue(S),[S]);return{activeCwd:r,activeThread:t,bodyState:ue({hasActiveThread:!!t,isGitRepo:i,turnSummaryCount:m.length,checkpointDiffError:v,hasRenderablePatch:!!S,isLoadingCheckpointDiff:_,hasNoNetChanges:b,emptyDiffMessage:x}),diffOpen:o,inferredCheckpointTurnCountByTurnId:c,orderedTurnDiffSummaries:m,renderableFiles:C,renderablePatch:S,selectedFilePath:d,selectedTurn:h,selectedTurnId:u}}function Re(e){let t=(0,$.c)(4),{bodyState:n}=e;if(n.kind===`loading`){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(D,{label:`Loading checkpoint diff...`}),t[0]=e):e=t[0],e}let r;t[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,Q.jsx)(L,{className:`size-7 text-muted-foreground/25`}),t[1]=r):r=t[1];let i=n.kind===`empty`?n.message:`No diff is available for this range.`,a;return t[2]===i?a=t[3]:(a=(0,Q.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-2 px-5 py-2 text-center`,children:[r,(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground/70`,children:i})]}),t[2]=i,t[3]=a),a}var ze=180;function Be(e){let t=(0,$.c)(14),{direction:n,strip:r}=e,i=n===`left`,a=i?r.canScrollLeft:r.canScrollRight,o=i?U:u,s=i?`left-0`:`right-0`,c=a?`border-border/70 hover:border-border hover:text-foreground`:`cursor-not-allowed border-border/40 text-muted-foreground/40`,l;t[0]!==s||t[1]!==c?(l=P(`absolute top-1/2 z-20 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md border bg-background/90 text-muted-foreground transition-colors`,s,c),t[0]=s,t[1]=c,t[2]=l):l=t[2];let d;t[3]!==i||t[4]!==r?(d=()=>r.scrollBy(i?-180:ze),t[3]=i,t[4]=r,t[5]=d):d=t[5];let f=!a,p=`Scroll turn list ${n}`,m;t[6]===o?m=t[7]:(m=(0,Q.jsx)(o,{className:`size-3.5`}),t[6]=o,t[7]=m);let h;return t[8]!==l||t[9]!==d||t[10]!==f||t[11]!==p||t[12]!==m?(h=(0,Q.jsx)(`button`,{type:`button`,className:l,onClick:d,disabled:f,"aria-label":p,children:m}),t[8]=l,t[9]=d,t[10]=f,t[11]=p,t[12]=m,t[13]=h):h=t[13],h}function Ve(e){let t=(0,$.c)(23),{summary:n,selected:r,turnCount:i,timestampFormat:a,onSelect:o}=e,s;t[0]!==o||t[1]!==n.turnId?(s=()=>o(n.turnId),t[0]=o,t[1]=n.turnId,t[2]=s):s=t[2];let c=n.turnId,l=r?`border-border bg-accent text-accent-foreground`:`border-border/70 bg-background/70 text-muted-foreground/80 hover:border-border hover:text-foreground/80`,u;t[3]===l?u=t[4]:(u=P(`rounded-md border px-2 py-1 text-left transition-colors`,l),t[3]=l,t[4]=u);let d=i??`?`,f;t[5]===d?f=t[6]:(f=(0,Q.jsxs)(`span`,{className:`text-[10px] leading-tight font-medium`,children:[`Turn `,d]}),t[5]=d,t[6]=f);let p;t[7]!==n.completedAt||t[8]!==a?(p=y(n.completedAt,a),t[7]=n.completedAt,t[8]=a,t[9]=p):p=t[9];let m;t[10]===p?m=t[11]:(m=(0,Q.jsx)(`span`,{className:`text-[9px] leading-tight opacity-70`,children:p}),t[10]=p,t[11]=m);let h;t[12]!==f||t[13]!==m?(h=(0,Q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[f,m]}),t[12]=f,t[13]=m,t[14]=h):h=t[14];let g;t[15]!==u||t[16]!==h?(g=(0,Q.jsx)(`div`,{className:u,children:h}),t[15]=u,t[16]=h,t[17]=g):g=t[17];let _;return t[18]!==r||t[19]!==n.turnId||t[20]!==s||t[21]!==g?(_=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,title:c,"data-turn-chip-selected":r,children:g}),t[18]=r,t[19]=n.turnId,t[20]=s,t[21]=g,t[22]=_):_=t[22],_}function He(e){let t=(0,$.c)(3),n=e?.environmentId,r=e?.projectId,i;return t[0]!==n||t[1]!==r?(i=e=>n&&r?S(e,{environmentId:n,projectId:r}):void 0,t[0]=n,t[1]=r,t[2]=i):i=t[2],E(i)}function Ue(e){return!e||e.kind!==`files`?[]:e.files.toSorted((e,t)=>Y(e).localeCompare(Y(t),void 0,{numeric:!0,sensitivity:`base`}))}export{Oe as default};
|
|
64
|
-
//# sourceMappingURL=DiffPanel-
|
|
64
|
+
//# sourceMappingURL=DiffPanel-Bn_XagA5.js.map
|