@cmmd-center/forge 0.13.47 → 0.13.49

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 CHANGED
@@ -21300,7 +21300,8 @@ require_Schema$1.Literals([
21300
21300
  "deprecation.notice",
21301
21301
  "files.persisted",
21302
21302
  "runtime.warning",
21303
- "runtime.error"
21303
+ "runtime.error",
21304
+ "codeweb.workspace.required"
21304
21305
  ]);
21305
21306
  const SessionStartedType = require_Schema$1.Literal("session.started");
21306
21307
  const SessionConfiguredType = require_Schema$1.Literal("session.configured");
@@ -21346,6 +21347,7 @@ const McpOauthCompletedType = require_Schema$1.Literal("mcp.oauth.completed");
21346
21347
  const ModelReroutedType = require_Schema$1.Literal("model.rerouted");
21347
21348
  const ConfigWarningType = require_Schema$1.Literal("config.warning");
21348
21349
  const DeprecationNoticeType = require_Schema$1.Literal("deprecation.notice");
21350
+ const CodewebWorkspaceRequiredType = require_Schema$1.Literal("codeweb.workspace.required");
21349
21351
  const FilesPersistedType = require_Schema$1.Literal("files.persisted");
21350
21352
  const RuntimeWarningType = require_Schema$1.Literal("runtime.warning");
21351
21353
  const RuntimeErrorType = require_Schema$1.Literal("runtime.error");
@@ -21641,6 +21643,12 @@ const DeprecationNoticePayload = require_Schema$1.Struct({
21641
21643
  summary: TrimmedNonEmptyStringSchema$2,
21642
21644
  details: require_Schema$1.optional(TrimmedNonEmptyStringSchema$2)
21643
21645
  });
21646
+ /**
21647
+ * CodeWeb's mint answered `workspace_required` (forge#3408): the person must
21648
+ * open the signed, single-use URL once to pick a Workspace. Forge surfaces
21649
+ * it instead of seating an unauthenticated CodeWeb server.
21650
+ */
21651
+ const CodewebWorkspaceRequiredPayload = require_Schema$1.Struct({ chooseWorkspaceUrl: require_Schema$1.String });
21644
21652
  const FilesPersistedPayload = require_Schema$1.Struct({
21645
21653
  files: require_Schema$1.ArraySchema(require_Schema$1.Struct({
21646
21654
  filename: TrimmedNonEmptyStringSchema$2,
@@ -21880,6 +21888,11 @@ const ProviderRuntimeDeprecationNoticeEvent = require_Schema$1.Struct({
21880
21888
  type: DeprecationNoticeType,
21881
21889
  payload: DeprecationNoticePayload
21882
21890
  });
21891
+ const ProviderRuntimeCodewebWorkspaceRequiredEvent = require_Schema$1.Struct({
21892
+ ...ProviderRuntimeEventBase.fields,
21893
+ type: CodewebWorkspaceRequiredType,
21894
+ payload: CodewebWorkspaceRequiredPayload
21895
+ });
21883
21896
  const ProviderRuntimeFilesPersistedEvent = require_Schema$1.Struct({
21884
21897
  ...ProviderRuntimeEventBase.fields,
21885
21898
  type: FilesPersistedType,
@@ -21940,6 +21953,7 @@ require_Schema$1.Union([
21940
21953
  ProviderRuntimeModelReroutedEvent,
21941
21954
  ProviderRuntimeConfigWarningEvent,
21942
21955
  ProviderRuntimeDeprecationNoticeEvent,
21956
+ ProviderRuntimeCodewebWorkspaceRequiredEvent,
21943
21957
  ProviderRuntimeFilesPersistedEvent,
21944
21958
  ProviderRuntimeWarningEvent,
21945
21959
  ProviderRuntimeErrorEvent
@@ -27009,12 +27023,12 @@ function encodeCmmdRuntimeThreadWorkspaceMetadata(workspace) {
27009
27023
  }
27010
27024
  //#endregion
27011
27025
  //#region ../../packages/contracts/src/cmmdRuntimeToolActivity.ts
27012
- function isRecord$23(value) {
27026
+ function isRecord$24(value) {
27013
27027
  return value !== null && typeof value === "object" && !Array.isArray(value);
27014
27028
  }
27015
27029
  function encodeCmmdRuntimeToolActivityPayload(kind, payload) {
27016
27030
  return {
27017
- ...isRecord$23(payload) ? payload : { sourcePayload: payload },
27031
+ ...isRecord$24(payload) ? payload : { sourcePayload: payload },
27018
27032
  forgeToolActivity: {
27019
27033
  schemaVersion: 1,
27020
27034
  source: "native",
@@ -27037,7 +27051,7 @@ const WORKTREE_LAUNCH_ACTIVITY_KINDS = new Set([
27037
27051
  ]);
27038
27052
  function encodeCmmdRuntimeWorktreeLaunchActivityPayload(kind, payload) {
27039
27053
  return {
27040
- ...isRecord$23(payload) ? payload : { sourcePayload: payload },
27054
+ ...isRecord$24(payload) ? payload : { sourcePayload: payload },
27041
27055
  forgeWorktreeLaunchActivity: {
27042
27056
  schemaVersion: 1,
27043
27057
  source: "native",
@@ -27057,7 +27071,7 @@ function isCmmdRuntimeWorktreeLaunchActivityKind(kind) {
27057
27071
  const CMMD_RUNTIME_PLAN_ACTIVITY_KIND = "turn.plan.updated";
27058
27072
  function encodeCmmdRuntimePlanActivityPayload(kind, payload) {
27059
27073
  return {
27060
- ...isRecord$23(payload) ? payload : { sourcePayload: payload },
27074
+ ...isRecord$24(payload) ? payload : { sourcePayload: payload },
27061
27075
  forgePlanActivity: {
27062
27076
  schemaVersion: 1,
27063
27077
  source: "native",
@@ -27066,15 +27080,15 @@ function encodeCmmdRuntimePlanActivityPayload(kind, payload) {
27066
27080
  };
27067
27081
  }
27068
27082
  function decodeCmmdRuntimePlanActivity(payload) {
27069
- if (!isRecord$23(payload)) return null;
27083
+ if (!isRecord$24(payload)) return null;
27070
27084
  const metadata = payload["forgePlanActivity"];
27071
- if (!isRecord$23(metadata)) return null;
27085
+ if (!isRecord$24(metadata)) return null;
27072
27086
  if (metadata["schemaVersion"] !== 1 || metadata["source"] !== "native" || metadata["kind"] !== "turn.plan.updated") return null;
27073
27087
  const rawPlan = payload["plan"];
27074
27088
  return {
27075
27089
  kind: CMMD_RUNTIME_PLAN_ACTIVITY_KIND,
27076
27090
  plan: Array.isArray(rawPlan) ? rawPlan.flatMap((entry) => {
27077
- if (!isRecord$23(entry)) return [];
27091
+ if (!isRecord$24(entry)) return [];
27078
27092
  const step = entry["step"];
27079
27093
  const status = entry["status"];
27080
27094
  if (typeof step !== "string" || step.trim().length === 0) return [];
@@ -31098,13 +31112,13 @@ async function completePendingDesktopRelayIdentityRotation(input) {
31098
31112
  }
31099
31113
  //#endregion
31100
31114
  //#region ../../packages/relay-host/src/internal/desktopRelayJws.ts
31101
- function isRecord$22(value) {
31115
+ function isRecord$23(value) {
31102
31116
  return typeof value === "object" && value !== null && !Array.isArray(value);
31103
31117
  }
31104
31118
  function decodeBase64UrlJson$1(value) {
31105
31119
  try {
31106
31120
  const decoded = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
31107
- return isRecord$22(decoded) ? decoded : null;
31121
+ return isRecord$23(decoded) ? decoded : null;
31108
31122
  } catch {
31109
31123
  return null;
31110
31124
  }
@@ -31258,11 +31272,11 @@ var DesktopRelayControlPlaneError = class extends Error {
31258
31272
  this.name = "DesktopRelayControlPlaneError";
31259
31273
  }
31260
31274
  };
31261
- function isRecord$21(value) {
31275
+ function isRecord$22(value) {
31262
31276
  return typeof value === "object" && value !== null && !Array.isArray(value);
31263
31277
  }
31264
31278
  function parseErrorPayload(value) {
31265
- return isRecord$21(value) ? value : {};
31279
+ return isRecord$22(value) ? value : {};
31266
31280
  }
31267
31281
  function messageFromErrorPayload(payload, fallback) {
31268
31282
  return typeof payload.error === "string" && payload.error.trim().length > 0 ? payload.error.trim() : fallback;
@@ -31360,7 +31374,7 @@ async function postControlPlane(input) {
31360
31374
  const errorPayload = parseErrorPayload(payload);
31361
31375
  throw new DesktopRelayControlPlaneError(typeof errorPayload.code === "string" && errorPayload.code.trim().length > 0 ? errorPayload.code.trim() : `CMMD_HTTP_${response.status}`, messageFromErrorPayload(errorPayload, `CMMD relay request failed (${response.status}).`), response.status === 408 || response.status === 429 || response.status >= 500);
31362
31376
  }
31363
- if (!isRecord$21(payload) || !("data" in payload)) throw new DesktopRelayControlPlaneError("CONTROL_PLANE_INVALID_RESPONSE", "CMMD returned an invalid Forge relay response.", false);
31377
+ if (!isRecord$22(payload) || !("data" in payload)) throw new DesktopRelayControlPlaneError("CONTROL_PLANE_INVALID_RESPONSE", "CMMD returned an invalid Forge relay response.", false);
31364
31378
  return payload.data;
31365
31379
  }
31366
31380
  function resolveRegisteredDevice(input) {
@@ -66243,7 +66257,7 @@ function normalizeNumberish(value) {
66243
66257
  }
66244
66258
  //#endregion
66245
66259
  //#region package.json
66246
- var version$1 = "0.13.47";
66260
+ var version$1 = "0.13.49";
66247
66261
  //#endregion
66248
66262
  //#region src/sentry.ts
66249
66263
  const SERVER_APP_NAME = "forge-server";
@@ -69730,6 +69744,7 @@ var ServerConfig = class ServerConfig extends require_Schema$1.Service()("forge/
69730
69744
  forgeCodexHomePath: void 0,
69731
69745
  forgeClaudeConfigPath: void 0,
69732
69746
  forgeApexBaseUrl: void 0,
69747
+ codewebServiceToken: void 0,
69733
69748
  cloudProjectsRoot: DEFAULT_CLOUD_PROJECTS_ROOT,
69734
69749
  ...overrides
69735
69750
  };
@@ -72942,12 +72957,12 @@ function resolveDesktopRelayControlPlaneTarget(path, configuredRuntimeId) {
72942
72957
  code: "RELAY_OPERATION_DENIED"
72943
72958
  };
72944
72959
  }
72945
- function isRecord$20(value) {
72960
+ function isRecord$21(value) {
72946
72961
  return typeof value === "object" && value !== null && !Array.isArray(value);
72947
72962
  }
72948
72963
  function relayControlPlaneBodyMatchesRuntime(path, body, configuredRuntimeId) {
72949
72964
  if (path !== "/api/forge/context/devices/register") return true;
72950
- if (!isRecord$20(body) || !isRecord$20(body.runtime)) return false;
72965
+ if (!isRecord$21(body) || !isRecord$21(body.runtime)) return false;
72951
72966
  return body.runtime.runtimeId === configuredRuntimeId;
72952
72967
  }
72953
72968
  /** Matches the client id `connect login` used, so CMMD accepts the refresh. */
@@ -72962,7 +72977,7 @@ function forbiddenResponse() {
72962
72977
  return errorResponse(403, "RELAY_BRIDGE_FORBIDDEN", "Desktop relay bridge access denied.");
72963
72978
  }
72964
72979
  function relayProxyErrorResponse(error) {
72965
- if (error instanceof CmmdProxyRequestError && isRecord$20(error.body)) {
72980
+ if (error instanceof CmmdProxyRequestError && isRecord$21(error.body)) {
72966
72981
  const code = typeof error.body.code === "string" ? error.body.code : error.code;
72967
72982
  const message = typeof error.body.error === "string" ? error.body.error : error.detail;
72968
72983
  return errorResponse(error.status >= 500 ? 502 : error.status, code, message ?? "CMMD relay coordination failed.");
@@ -77521,10 +77536,10 @@ var CheckpointDiffQuery = class extends require_Schema$1.Service()("forge/checkp
77521
77536
  * Forge server with neither configured has no attached desktop, which is a
77522
77537
  * normal configuration for web and cloud — not an error.
77523
77538
  */
77524
- const DEFAULT_TIMEOUT_MS$5 = 15e3;
77539
+ const DEFAULT_TIMEOUT_MS$6 = 15e3;
77525
77540
  function createHostBridgeComputerManager(options) {
77526
77541
  const fetchImpl = options.fetchImpl ?? fetch;
77527
- const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS$5;
77542
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS$6;
77528
77543
  return { execute: async ({ command }) => {
77529
77544
  const response = await fetchImpl(`${options.url}/agent-computer/host-bridge`, {
77530
77545
  method: "POST",
@@ -77675,7 +77690,7 @@ async function recordDisplayToWebm(input) {
77675
77690
  * permission.
77676
77691
  */
77677
77692
  const DEFAULT_DISPLAY = ":99";
77678
- const DEFAULT_TIMEOUT_MS$4 = 15e3;
77693
+ const DEFAULT_TIMEOUT_MS$5 = 15e3;
77679
77694
  /** Screenshots are megabytes of PNG on stdout; the 1 MB execFile default truncates them. */
77680
77695
  const SCREENSHOT_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
77681
77696
  const TYPE_DELAY_MS = 12;
@@ -77976,7 +77991,7 @@ async function executeDisplaySurfaceCommand(command, deps) {
77976
77991
  }
77977
77992
  function createX11ComputerManager(options = {}) {
77978
77993
  const display = options.display ?? DEFAULT_DISPLAY;
77979
- const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS$4;
77994
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS$5;
77980
77995
  const runner = options.runner ?? defaultRunner(display, timeoutMs);
77981
77996
  const launcher = options.launcher ?? defaultLauncher();
77982
77997
  const launch = async (file, args) => {
@@ -95491,7 +95506,7 @@ const REPLICA_THREAD_STATUSES = [
95491
95506
  ];
95492
95507
  //#endregion
95493
95508
  //#region src/runtimeReplication/replicaDecodeModel.ts
95494
- function isRecord$19(value) {
95509
+ function isRecord$20(value) {
95495
95510
  return typeof value === "object" && value !== null && !Array.isArray(value);
95496
95511
  }
95497
95512
  function isNonBlankString(value) {
@@ -95511,7 +95526,7 @@ function nullableInteger(value) {
95511
95526
  return value === null || typeof value === "number" && Number.isSafeInteger(value);
95512
95527
  }
95513
95528
  function unwrapEnvelope(payload, expectedDomain) {
95514
- if (!isRecord$19(payload) || !isRecord$19(payload.meta) || !isRecord$19(payload.data)) return null;
95529
+ if (!isRecord$20(payload) || !isRecord$20(payload.meta) || !isRecord$20(payload.data)) return null;
95515
95530
  const { domain, timestamp, version } = payload.meta;
95516
95531
  if (!isNonBlankString(domain) || expectedDomain !== void 0 && domain !== expectedDomain || version !== "1.0" || !isIsoDateTime(timestamp)) return null;
95517
95532
  return payload.data;
@@ -95524,12 +95539,12 @@ function hasValidRuntimeIdentity(value) {
95524
95539
  ].includes(String(value.runtimeKind)) && typeof value.displayName === "string" && typeof value.status === "string";
95525
95540
  }
95526
95541
  function decodeRuntime$1(value) {
95527
- if (!isRecord$19(value) || !hasValidRuntimeIdentity(value)) return null;
95528
- 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;
95542
+ if (!isRecord$20(value) || !hasValidRuntimeIdentity(value)) return null;
95543
+ 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$20(value.metadata))) return null;
95529
95544
  return value;
95530
95545
  }
95531
95546
  function decodeProject(value) {
95532
- if (!isRecord$19(value) || !isNonBlankString(value.projectId) || typeof value.title !== "string" || !nullableString(value.githubRepoFullName) || !nullableString(value.branch)) return null;
95547
+ if (!isRecord$20(value) || !isNonBlankString(value.projectId) || typeof value.title !== "string" || !nullableString(value.githubRepoFullName) || !nullableString(value.branch)) return null;
95533
95548
  return {
95534
95549
  projectId: value.projectId,
95535
95550
  title: value.title,
@@ -95538,11 +95553,11 @@ function decodeProject(value) {
95538
95553
  };
95539
95554
  }
95540
95555
  function decodeThread$1(value) {
95541
- 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;
95556
+ if (!isRecord$20(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$20(value.metadata))) return null;
95542
95557
  return value;
95543
95558
  }
95544
95559
  function decodeSummary(value) {
95545
- if (!isRecord$19(value) || !nullableString(value.conversationId)) return null;
95560
+ if (!isRecord$20(value) || !nullableString(value.conversationId)) return null;
95546
95561
  const project = decodeProject(value.project);
95547
95562
  const thread = decodeThread$1(value.thread);
95548
95563
  return project === null || thread === null ? null : {
@@ -95653,7 +95668,7 @@ function isNonNegativeInt(value) {
95653
95668
  /** `usage` is null for an Unreported turn, otherwise exactly the five buckets. */
95654
95669
  function isValidTurnUsageTokens(value) {
95655
95670
  if (value === null) return true;
95656
- if (!isRecord$19(value)) return false;
95671
+ if (!isRecord$20(value)) return false;
95657
95672
  return turnUsageTokenKeys.every((key) => isNonNegativeInt(value[key])) && Object.keys(value).every((key) => turnUsageTokenKeys.includes(key));
95658
95673
  }
95659
95674
  /** The row itself: no text, no status, and the turn it belongs to. */
@@ -95662,7 +95677,7 @@ function hasValidTurnUsageEnvelope(value) {
95662
95677
  }
95663
95678
  /** What the row records: who ran it, what it spent, and what it says of itself. */
95664
95679
  function hasValidTurnUsageRecord(payload) {
95665
- return isRecord$19(payload) && isNonBlankString(payload.provider) && isNonBlankString(payload.model) && "usage" in payload && isValidTurnUsageTokens(payload.usage) && hasValidTurnUsageAttribution(payload);
95680
+ return isRecord$20(payload) && isNonBlankString(payload.provider) && isNonBlankString(payload.model) && "usage" in payload && isValidTurnUsageTokens(payload.usage) && hasValidTurnUsageAttribution(payload);
95666
95681
  }
95667
95682
  /** A turn_usage row: no text, no status, and its record in `payload`. */
95668
95683
  function hasValidTurnUsagePayload(value) {
@@ -95699,7 +95714,7 @@ function hasValidEventPayload(value) {
95699
95714
  return isNonBlankString(value.text) && value.status === null;
95700
95715
  }
95701
95716
  function decodeEvent$1(value) {
95702
- if (!isRecord$19(value) || !hasValidEventFields(value) || !hasValidEventPayload(value)) return null;
95717
+ if (!isRecord$20(value) || !hasValidEventFields(value) || !hasValidEventPayload(value)) return null;
95703
95718
  return value;
95704
95719
  }
95705
95720
  function decodeEvents(data) {
@@ -95720,11 +95735,11 @@ function decodeReplicaThreadDetail(payload) {
95720
95735
  const thread = decodeThread$1(data.thread);
95721
95736
  const reachability = decodeReachability(data.reachability);
95722
95737
  const events = decodeEvents(data);
95723
- if (runtime === null || project === null || thread === null || reachability === null || events === null || !isRecord$19(data.execution) || typeof data.execution.available !== "boolean" || ![
95738
+ if (runtime === null || project === null || thread === null || reachability === null || events === null || !isRecord$20(data.execution) || typeof data.execution.available !== "boolean" || ![
95724
95739
  null,
95725
95740
  "runtime_offline",
95726
95741
  "runtime_unavailable"
95727
- ].includes(data.execution.reason) || (data.execution.available ? data.execution.reason !== null : data.execution.reason === null) || !isRecord$19(data.replication) || data.replication.protocolVersion !== 2 || !isNonBlankString(data.replication.generationId) || !Number.isSafeInteger(data.replication.acknowledgedSequence) || Number(data.replication.acknowledgedSequence) < 0 || !isNonBlankString(data.replication.headHash)) return null;
95742
+ ].includes(data.execution.reason) || (data.execution.available ? data.execution.reason !== null : data.execution.reason === null) || !isRecord$20(data.replication) || data.replication.protocolVersion !== 2 || !isNonBlankString(data.replication.generationId) || !Number.isSafeInteger(data.replication.acknowledgedSequence) || Number(data.replication.acknowledgedSequence) < 0 || !isNonBlankString(data.replication.headHash)) return null;
95728
95743
  return {
95729
95744
  conversationId: data.conversationId,
95730
95745
  runtime,
@@ -96800,7 +96815,7 @@ function resolveRuntimeReplicationRuntimeId(config) {
96800
96815
  }
96801
96816
  //#endregion
96802
96817
  //#region src/usage/providerTokenBuckets.ts
96803
- function isRecord$18(value) {
96818
+ function isRecord$19(value) {
96804
96819
  return typeof value === "object" && value !== null && !Array.isArray(value);
96805
96820
  }
96806
96821
  function count(record, ...keys) {
@@ -96821,7 +96836,7 @@ function reportedOrNull(tokens) {
96821
96836
  * the app server sends camelCase.
96822
96837
  */
96823
96838
  function codexTokenBuckets(value) {
96824
- if (!isRecord$18(value)) return null;
96839
+ if (!isRecord$19(value)) return null;
96825
96840
  const inputTokens = count(value, "input_tokens", "inputTokens");
96826
96841
  const cachedInputTokens = count(value, "cached_input_tokens", "cachedInputTokens");
96827
96842
  const cacheCreationTokens = count(value, "cache_write_input_tokens", "cacheWriteInputTokens");
@@ -96840,7 +96855,7 @@ function codexTokenBuckets(value) {
96840
96855
  * tokens into output and does not break them out, so reasoning stays zero.
96841
96856
  */
96842
96857
  function claudeTokenBuckets(value) {
96843
- if (!isRecord$18(value)) return null;
96858
+ if (!isRecord$19(value)) return null;
96844
96859
  return reportedOrNull({
96845
96860
  uncachedInputTokens: count(value, "input_tokens", "inputTokens"),
96846
96861
  cachedInputTokens: count(value, "cache_read_input_tokens", "cacheReadInputTokens"),
@@ -97782,7 +97797,7 @@ const replicaTurnStatuses = new Set([
97782
97797
  "cancelled",
97783
97798
  "interrupted"
97784
97799
  ]);
97785
- function isRecord$17(value) {
97800
+ function isRecord$18(value) {
97786
97801
  return typeof value === "object" && value !== null && !Array.isArray(value);
97787
97802
  }
97788
97803
  function replicaSourceSequence(value) {
@@ -97795,7 +97810,7 @@ function replicaSourceTurn(sourceTurnId) {
97795
97810
  return typeof sourceTurnId === "string" && sourceTurnId.length > 0 ? { turnId: sourceTurnId } : {};
97796
97811
  }
97797
97812
  function replicaActivitySource(activity) {
97798
- if (!activity.kind.startsWith("replica.") || !isRecord$17(activity.payload)) return null;
97813
+ if (!activity.kind.startsWith("replica.") || !isRecord$18(activity.payload)) return null;
97799
97814
  const sourceSequence = replicaSourceSequence(activity.sequence);
97800
97815
  const eventId = replicaSourceEventId(activity.payload.sourceEventId);
97801
97816
  if (sourceSequence === null || eventId === null) return null;
@@ -97808,7 +97823,7 @@ function replicaActivitySource(activity) {
97808
97823
  }
97809
97824
  function replicaSummaryEvent(activity, source) {
97810
97825
  if (activity.kind !== "replica.activity_summary" && activity.kind !== "replica.error_summary") return null;
97811
- const sourceText = isRecord$17(activity.payload) ? activity.payload.text : null;
97826
+ const sourceText = isRecord$18(activity.payload) ? activity.payload.text : null;
97812
97827
  return {
97813
97828
  sourceSequence: source.sourceSequence,
97814
97829
  event: {
@@ -97821,7 +97836,7 @@ function replicaSummaryEvent(activity, source) {
97821
97836
  };
97822
97837
  }
97823
97838
  function replicaTurnEvent(activity, source) {
97824
- const status = isRecord$17(activity.payload) ? activity.payload.status : null;
97839
+ const status = isRecord$18(activity.payload) ? activity.payload.status : null;
97825
97840
  if (activity.kind !== "replica.turn_status" || !replicaTurnStatuses.has(status)) return null;
97826
97841
  return {
97827
97842
  sourceSequence: source.sourceSequence,
@@ -97835,7 +97850,7 @@ function replicaTurnEvent(activity, source) {
97835
97850
  };
97836
97851
  }
97837
97852
  function replicaToolCallEvent(activity, source) {
97838
- if (activity.kind !== "replica.tool_call" || !isRecord$17(activity.payload)) return null;
97853
+ if (activity.kind !== "replica.tool_call" || !isRecord$18(activity.payload)) return null;
97839
97854
  const sourceText = activity.payload.text;
97840
97855
  const status = activity.payload.status;
97841
97856
  if (typeof sourceText !== "string" || typeof status !== "string") return null;
@@ -97853,9 +97868,9 @@ function replicaToolCallEvent(activity, source) {
97853
97868
  };
97854
97869
  }
97855
97870
  function replicaTurnUsageEvent(activity, source) {
97856
- if (activity.kind !== "replica.turn_usage" || !isRecord$17(activity.payload)) return null;
97871
+ if (activity.kind !== "replica.turn_usage" || !isRecord$18(activity.payload)) return null;
97857
97872
  const usage = activity.payload.payload;
97858
- if (!("turnId" in source.turn) || !isRecord$17(usage)) return null;
97873
+ if (!("turnId" in source.turn) || !isRecord$18(usage)) return null;
97859
97874
  const provider = usage.provider;
97860
97875
  const model = usage.model;
97861
97876
  if (typeof provider !== "string" || typeof model !== "string" || !("usage" in usage)) return null;
@@ -98724,9 +98739,9 @@ function isUsageSessionLookupRuntimeNotFound(error) {
98724
98739
  async function isRuntimeNotFoundResponse(response) {
98725
98740
  if (response.status !== 404) return false;
98726
98741
  const body = await response.json().catch(() => null);
98727
- return isRecord$16(body) && body["code"] === "RUNTIME_NOT_FOUND";
98742
+ return isRecord$17(body) && body["code"] === "RUNTIME_NOT_FOUND";
98728
98743
  }
98729
- function isRecord$16(value) {
98744
+ function isRecord$17(value) {
98730
98745
  return typeof value === "object" && value !== null;
98731
98746
  }
98732
98747
  /**
@@ -98738,11 +98753,11 @@ function isRecord$16(value) {
98738
98753
  * no count on the page saying so.
98739
98754
  */
98740
98755
  function decodeHeldSessions(body) {
98741
- const held = isRecord$16(body) && isRecord$16(body["data"]) ? body["data"]["held"] : void 0;
98756
+ const held = isRecord$17(body) && isRecord$17(body["data"]) ? body["data"]["held"] : void 0;
98742
98757
  if (!Array.isArray(held)) throw new Error("The usage session lookup returned an invalid body.");
98743
98758
  return held.map((row) => {
98744
- const providerSessionId = isRecord$16(row) ? row["providerSessionId"] : void 0;
98745
- const runtimeId = isRecord$16(row) ? row["runtimeId"] : void 0;
98759
+ const providerSessionId = isRecord$17(row) ? row["providerSessionId"] : void 0;
98760
+ const runtimeId = isRecord$17(row) ? row["runtimeId"] : void 0;
98746
98761
  if (typeof providerSessionId !== "string" || typeof runtimeId !== "string") throw new Error("The usage session lookup returned an invalid held row.");
98747
98762
  return {
98748
98763
  providerSessionId,
@@ -101557,7 +101572,7 @@ function emptyConfig(source, path) {
101557
101572
  issues: []
101558
101573
  };
101559
101574
  }
101560
- function isRecord$15(value) {
101575
+ function isRecord$16(value) {
101561
101576
  return typeof value === "object" && value !== null && !Array.isArray(value);
101562
101577
  }
101563
101578
  function stringArray(value) {
@@ -101585,7 +101600,7 @@ function terminalsFromValue(value) {
101585
101600
  name: `Terminal ${index + 1}`,
101586
101601
  command: terminal.trim()
101587
101602
  }];
101588
- if (!isRecord$15(terminal)) return [];
101603
+ if (!isRecord$16(terminal)) return [];
101589
101604
  const command = typeof terminal.command === "string" ? terminal.command.trim() : "";
101590
101605
  if (!command) return [];
101591
101606
  return [{
@@ -101624,7 +101639,7 @@ function readConfigFile(source, path) {
101624
101639
  }]
101625
101640
  };
101626
101641
  }
101627
- if (!isRecord$15(parsed)) return {
101642
+ if (!isRecord$16(parsed)) return {
101628
101643
  ...emptyConfig(source, path),
101629
101644
  issues: [{
101630
101645
  severity: "blocked",
@@ -102794,7 +102809,7 @@ const CLAUDE_IDENTITY_KEYS = new Set([
102794
102809
  "credentialGenerationId"
102795
102810
  ]);
102796
102811
  const CLAUDE_IDENTITY_OPTIONAL_KEYS = new Set(["providerAccountIdentity"]);
102797
- function isRecord$14(value) {
102812
+ function isRecord$15(value) {
102798
102813
  return typeof value === "object" && value !== null && !Array.isArray(value);
102799
102814
  }
102800
102815
  function isStrictRfc3339DateTime(value) {
@@ -102823,7 +102838,7 @@ function hasAllowedKeys(value, required, optional) {
102823
102838
  return keys.every((key) => required.has(key) || optional.has(key)) && [...required].every((key) => keys.includes(key));
102824
102839
  }
102825
102840
  function parseDeliveryIdentity(value, provider) {
102826
- if (!isRecord$14(value)) return null;
102841
+ if (!isRecord$15(value)) return null;
102827
102842
  if (provider === "openai") return parseCodexDeliveryIdentity(value);
102828
102843
  if (provider === "anthropic") return parseClaudeDeliveryIdentity(value);
102829
102844
  return null;
@@ -102858,7 +102873,7 @@ function parseClaudeDeliveryIdentity(value) {
102858
102873
  };
102859
102874
  }
102860
102875
  function parseProviderRuntimeDeliveryReceipt(value, expected) {
102861
- if (!isRecord$14(value) || !hasExactKeys$2(value, RECEIPT_KEYS)) return null;
102876
+ if (!isRecord$15(value) || !hasExactKeys$2(value, RECEIPT_KEYS)) return null;
102862
102877
  const identity = parseDeliveryIdentity(value.identity, expected.provider);
102863
102878
  if (!identity || typeof value.receiptId !== "string" || value.receiptId.length === 0 || value.receiptId.length > 256 || value.runtimeId !== expected.runtimeId || value.machineId !== expected.machineId || value.credentialEpoch !== expected.credentialEpoch || !Number.isInteger(value.credentialEpoch) || value.credentialEpoch < 0 || !isStrictRfc3339DateTime(value.issuedAt) || value.expiresAt !== expected.expiresAt || value.expiresAt !== null && !isStrictRfc3339DateTime(value.expiresAt)) return null;
102864
102879
  return {
@@ -102880,8 +102895,8 @@ function providerDeliveryBindingFromReceipt(receipt) {
102880
102895
  };
102881
102896
  }
102882
102897
  function readProviderDeliveryBinding(value) {
102883
- if (!isRecord$14(value) || !hasExactKeys$2(value, BINDING_KEYS)) return null;
102884
- const identityProvider = isRecord$14(value.identity) ? value.identity.provider : void 0;
102898
+ if (!isRecord$15(value) || !hasExactKeys$2(value, BINDING_KEYS)) return null;
102899
+ const identityProvider = isRecord$15(value.identity) ? value.identity.provider : void 0;
102885
102900
  const tokenProvider = identityProvider === "codex" ? "openai" : identityProvider === "claude" ? "anthropic" : null;
102886
102901
  if (!tokenProvider) return null;
102887
102902
  const identity = parseDeliveryIdentity(value.identity, tokenProvider);
@@ -150233,12 +150248,12 @@ function decodeProviderKind(providerName, operation) {
150233
150248
  detail: `Unknown persisted provider '${providerName}'.`
150234
150249
  }));
150235
150250
  }
150236
- function isRecord$13(value) {
150251
+ function isRecord$14(value) {
150237
150252
  return value !== null && typeof value === "object" && !Array.isArray(value);
150238
150253
  }
150239
150254
  function mergeRuntimePayload(existing, next) {
150240
150255
  if (next === void 0) return existing ?? null;
150241
- if (isRecord$13(existing) && isRecord$13(next)) return {
150256
+ if (isRecord$14(existing) && isRecord$14(next)) return {
150242
150257
  ...existing,
150243
150258
  ...next
150244
150259
  };
@@ -152210,7 +152225,7 @@ const PAGINATION_KEYS = new Set([
152210
152225
  "total",
152211
152226
  "hasMore"
152212
152227
  ]);
152213
- function isRecord$12(value) {
152228
+ function isRecord$13(value) {
152214
152229
  return typeof value === "object" && value !== null && !Array.isArray(value);
152215
152230
  }
152216
152231
  function hasOnlyKeys(value, allowed) {
@@ -152223,17 +152238,17 @@ function isRfc3339(value) {
152223
152238
  return typeof value === "string" && RFC3339.test(value) && Number.isFinite(Date.parse(value));
152224
152239
  }
152225
152240
  function isEnvelopeMeta(value) {
152226
- if (!isRecord$12(value) || !hasExactKeys$1(value, META_KEYS)) return false;
152241
+ if (!isRecord$13(value) || !hasExactKeys$1(value, META_KEYS)) return false;
152227
152242
  return typeof value.domain === "string" && value.domain.length > 0 && isRfc3339(value.timestamp) && typeof value.version === "string" && value.version.length > 0;
152228
152243
  }
152229
152244
  function isPagination(value) {
152230
- if (!isRecord$12(value) || !hasExactKeys$1(value, PAGINATION_KEYS)) return false;
152245
+ if (!isRecord$13(value) || !hasExactKeys$1(value, PAGINATION_KEYS)) return false;
152231
152246
  return Number.isInteger(value.page) && value.page >= 0 && Number.isInteger(value.limit) && value.limit >= 0 && Number.isInteger(value.total) && value.total >= 0 && typeof value.hasMore === "boolean";
152232
152247
  }
152233
152248
  function readLocalProviderAccountId(authJson) {
152234
152249
  try {
152235
152250
  const value = JSON.parse(authJson);
152236
- if (!isRecord$12(value) || value.auth_mode !== "chatgpt" || !isRecord$12(value.tokens)) return null;
152251
+ if (!isRecord$13(value) || value.auth_mode !== "chatgpt" || !isRecord$13(value.tokens)) return null;
152237
152252
  const providerAccountId = value.tokens.account_id;
152238
152253
  if (typeof providerAccountId !== "string") return null;
152239
152254
  const normalized = providerAccountId.trim();
@@ -152246,13 +152261,13 @@ function resolveLocalAuthJsonPath(homePath) {
152246
152261
  return (0, node_path.join)(homePath?.trim() || process.env.CODEX_HOME?.trim() || (0, node_path.join)((0, node_os.homedir)(), ".codex"), "auth.json");
152247
152262
  }
152248
152263
  function parseCodexAccountIdentityEnvelope(value) {
152249
- if (!isRecord$12(value) || !hasOnlyKeys(value, ENVELOPE_KEYS)) return null;
152264
+ if (!isRecord$13(value) || !hasOnlyKeys(value, ENVELOPE_KEYS)) return null;
152250
152265
  if (!("data" in value) || !("meta" in value) || !isEnvelopeMeta(value.meta)) return null;
152251
152266
  if (value.pagination !== void 0 && !isPagination(value.pagination)) return null;
152252
152267
  return readCodexAccountIdentity(value.data);
152253
152268
  }
152254
152269
  function readCodexAccountIdentity(value) {
152255
- if (!isRecord$12(value) || !hasExactKeys$1(value, IDENTITY_KEYS)) return null;
152270
+ if (!isRecord$13(value) || !hasExactKeys$1(value, IDENTITY_KEYS)) return null;
152256
152271
  if (value.kind !== "provider_account" || value.provider !== "codex" || typeof value.providerAccountIdentity !== "string" || !PROVIDER_ACCOUNT_IDENTITY$1.test(value.providerAccountIdentity)) return null;
152257
152272
  return {
152258
152273
  kind: "provider_account",
@@ -211530,7 +211545,7 @@ function isShellSafeCommandPath(command) {
211530
211545
  }
211531
211546
  //#endregion
211532
211547
  //#region src/provider/providerSnapshot.ts
211533
- const DEFAULT_TIMEOUT_MS$3 = 4e3;
211548
+ const DEFAULT_TIMEOUT_MS$4 = 4e3;
211534
211549
  function resolveForgeBrowserSkillPath(cwd = process.cwd()) {
211535
211550
  const candidates = [
211536
211551
  node_path.resolve(cwd, ".agents/skills/browser/SKILL.md"),
@@ -214029,8 +214044,8 @@ function cliSelectsOsStore(input) {
214029
214044
  if (input.env[CLAUDE_FORCE_OS_CREDENTIAL_STORE_ENV] === "1") return true;
214030
214045
  const config = readConfig(input);
214031
214046
  if (config === null) return false;
214032
- const features = isRecord$11(config.parsed) ? config.parsed[CACHED_FEATURES_KEY] : void 0;
214033
- const flag = isRecord$11(features) ? features[OS_STORE_FLAG_KEY] : void 0;
214047
+ const features = isRecord$12(config.parsed) ? config.parsed[CACHED_FEATURES_KEY] : void 0;
214048
+ const flag = isRecord$12(features) ? features[OS_STORE_FLAG_KEY] : void 0;
214034
214049
  return typeof flag === "boolean" ? flag : null;
214035
214050
  }
214036
214051
  /**
@@ -214058,7 +214073,7 @@ function hasSessionBus(input) {
214058
214073
  const runtimeDirectory = input.env.XDG_RUNTIME_DIR?.trim();
214059
214074
  return runtimeDirectory ? input.fileExists((0, node_path.join)(runtimeDirectory, "bus")) : false;
214060
214075
  }
214061
- function isRecord$11(value) {
214076
+ function isRecord$12(value) {
214062
214077
  return typeof value === "object" && value !== null && !Array.isArray(value);
214063
214078
  }
214064
214079
  //#endregion
@@ -214729,7 +214744,7 @@ const checkClaudeProviderStatus = require_Schema$1.fn("checkClaudeProviderStatus
214729
214744
  const capabilitiesProbeInput = claudeCapabilitiesProbeInput(claudeSettings.binaryPath, effectiveConfigPath);
214730
214745
  const discovery = yield* resolveClaudeDiscovery(capabilitiesProbeInput, resolveSlashCommands, resolveModels);
214731
214746
  const models = modelsForClaudeCliVersion(providerModelsFromSettings(resolveClaudeProviderModels(discovery.models), PROVIDER$12, claudeSettings.customModels, DEFAULT_CLAUDE_MODEL_CAPABILITIES, endpointProfileDisplayNames(claudeSettings)), parsedVersion);
214732
- const authProbe = yield* runClaudeCommand(["auth", "status"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$3), require_Schema$1.result);
214747
+ const authProbe = yield* runClaudeCommand(["auth", "status"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$4), require_Schema$1.result);
214733
214748
  return yield* withClaudeCredentialAnswers(buildClaudeProviderFromAuthProbe({
214734
214749
  authProbe,
214735
214750
  authMetadata: yield* resolveClaudeAuthMetadata(authProbe, capabilitiesProbeInput, resolveSubscriptionType),
@@ -214775,7 +214790,7 @@ const makePendingClaudeProvider = (claudeSettings) => {
214775
214790
  * A refresh can wait behind a check that already holds the provider's refresh
214776
214791
  * permit before running its own, so it gets two check budgets.
214777
214792
  */
214778
- const CREDENTIAL_ANSWER_REFRESH_TIMEOUT_MS = 2 * (CLAUDE_VERSION_PROBE_TIMEOUT_MS + CAPABILITIES_PROBE_TIMEOUT_MS$1 + DEFAULT_TIMEOUT_MS$3);
214793
+ const CREDENTIAL_ANSWER_REFRESH_TIMEOUT_MS = 2 * (CLAUDE_VERSION_PROBE_TIMEOUT_MS + CAPABILITIES_PROBE_TIMEOUT_MS$1 + DEFAULT_TIMEOUT_MS$4);
214779
214794
  /** The gap after each answer refresh, and the pause before a restart. */
214780
214795
  const CREDENTIAL_ANSWER_REFRESH_SPACING = require_Schema$1.seconds(1);
214781
214796
  /**
@@ -214940,6 +214955,114 @@ function resolveCodewebMcpEnabled(input) {
214940
214955
  return input.grant ? input.grant.enabled : input.setting;
214941
214956
  }
214942
214957
  //#endregion
214958
+ //#region src/codeweb/AgentTokenMint.ts
214959
+ /**
214960
+ * CodeWeb Agent Token mint client (forge#3408; contract CodeWeb#175/#179).
214961
+ *
214962
+ * ADR-011: the person never runs a browser dance for tokens when the mint
214963
+ * succeeds. Forge mints silently at session construction with the shared
214964
+ * service credential and the caller's CMMD identity, and holds the returned
214965
+ * plaintext only in memory for that session — CodeWeb returns it exactly
214966
+ * once and this module never logs it.
214967
+ *
214968
+ * Every failure mode folds into a closed result union instead of throwing:
214969
+ * a CodeWeb outage must never fail (or even delay beyond the timeout) a
214970
+ * session start.
214971
+ *
214972
+ * @module AgentTokenMint
214973
+ */
214974
+ /** The mint endpoint lives beside the MCP server on the same CodeWeb host. */
214975
+ const CODEWEB_MINT_URL = new URL("/forge/agent-tokens", CODEWEB_MCP_SERVER_URL).toString();
214976
+ /** Bounded so a CodeWeb outage cannot stall session construction (ADR-011). */
214977
+ const DEFAULT_TIMEOUT_MS$3 = 3e3;
214978
+ function createCodewebAgentTokenMintClient(input) {
214979
+ const fetchImpl = input.fetchImpl ?? fetch;
214980
+ const timeoutMs = input.timeoutMs ?? DEFAULT_TIMEOUT_MS$3;
214981
+ return { mint: async ({ cmmdUserId }) => {
214982
+ try {
214983
+ const response = await fetchImpl(CODEWEB_MINT_URL, {
214984
+ method: "POST",
214985
+ headers: {
214986
+ "X-Forge-Service-Token": input.serviceToken,
214987
+ "Content-Type": "application/json"
214988
+ },
214989
+ body: JSON.stringify({ cmmd_user_id: cmmdUserId }),
214990
+ signal: AbortSignal.timeout(timeoutMs)
214991
+ });
214992
+ return parseMintResponse(response.status, await response.json());
214993
+ } catch {
214994
+ return { status: "unavailable" };
214995
+ }
214996
+ } };
214997
+ }
214998
+ function parseMintResponse(httpStatus, body) {
214999
+ if (httpStatus === 404) return { status: "unknown_identity" };
215000
+ if (!isRecord$11(body)) return { status: "unavailable" };
215001
+ if (body["status"] === "minted" && typeof body["token"] === "string") return {
215002
+ status: "minted",
215003
+ token: body["token"]
215004
+ };
215005
+ if (body["status"] === "already_issued") return { status: "already_issued" };
215006
+ if (body["status"] === "workspace_required" && typeof body["choose_workspace_url"] === "string") return {
215007
+ status: "workspace_required",
215008
+ chooseWorkspaceUrl: body["choose_workspace_url"]
215009
+ };
215010
+ return { status: "unavailable" };
215011
+ }
215012
+ function isRecord$11(value) {
215013
+ return typeof value === "object" && value !== null;
215014
+ }
215015
+ //#endregion
215016
+ //#region src/codeweb/CodewebMcpSessionAuth.ts
215017
+ /**
215018
+ * Per-session CodeWeb MCP auth decision (forge#3408).
215019
+ *
215020
+ * Runs once at session construction when the CodeWeb injection is enabled:
215021
+ * resolves the owning CMMD identity for the thread, mints an Agent Token
215022
+ * with the shared service credential, and classifies the outcome. The
215023
+ * classification decides what the provider surfaces:
215024
+ *
215025
+ * - `authorized` — carry `Authorization: Bearer <token>` on the entry.
215026
+ * - `ungated` — register without credentials: no CMMD identity or service
215027
+ * credential is available (local/dev), or CodeWeb already issued a token
215028
+ * Forge does not hold (`already_issued`, `unknown_identity`). The
215029
+ * client-side MCP OAuth challenge (CodeWeb#22) is the recovery path that
215030
+ * keeps tools usable in the same session.
215031
+ * - `workspace_required` — omit the entry and surface the one-time
215032
+ * choose-your-Workspace link instead. Registering an unauthenticated
215033
+ * server for a user who provably cannot authenticate would only burn
215034
+ * agent turns on 401s; the surfaced link is the actionable step, and the
215035
+ * next session mints silently.
215036
+ * - `omitted` — the mint endpoint was unreachable or answered unexpectedly.
215037
+ * Fail closed to no entry for this session: a broken mint must not seat a
215038
+ * permanently-failing server in every session. ADR-011: session start
215039
+ * never depends on CodeWeb being up.
215040
+ *
215041
+ * @module CodewebMcpSessionAuth
215042
+ */
215043
+ function resolveCodewebMcpInjection(input) {
215044
+ if (!input.enabled) return require_Schema$1.succeed({ kind: "disabled" });
215045
+ const ownerSessionId = readThreadSessionId(input.threadId);
215046
+ const cmmdUserId = ownerSessionId === null ? null : readCmmdUserIdentityForSession(ownerSessionId)?.id ?? null;
215047
+ if (cmmdUserId === null || input.serviceToken === void 0) return require_Schema$1.succeed({ kind: "ungated" });
215048
+ const mintClient = input.mintClient ?? createCodewebAgentTokenMintClient({ serviceToken: input.serviceToken });
215049
+ return require_Schema$1.promise(() => mintClient.mint({ cmmdUserId })).pipe(require_Schema$1.map((mint) => {
215050
+ switch (mint.status) {
215051
+ case "minted": return {
215052
+ kind: "authorized",
215053
+ bearerToken: mint.token
215054
+ };
215055
+ case "workspace_required": return {
215056
+ kind: "workspace_required",
215057
+ chooseWorkspaceUrl: mint.chooseWorkspaceUrl
215058
+ };
215059
+ case "already_issued":
215060
+ case "unknown_identity": return { kind: "ungated" };
215061
+ case "unavailable": return { kind: "omitted" };
215062
+ }
215063
+ }));
215064
+ }
215065
+ //#endregion
214943
215066
  //#region src/cmmdData/cmmdContextMcpServer.ts
214944
215067
  /**
214945
215068
  * CMMD Context MCP server (in-process, read-only).
@@ -215816,14 +215939,30 @@ function buildClaudeMcpServers(input) {
215816
215939
  [GITHUB_MCP_SERVER_NAME]: createGitHubMcpServer(input.runBrokeredGitHubTool, input.threadId, input.serverSettings),
215817
215940
  ...input.computerManager ? { [COMPUTER_MCP_SERVER_NAME]: createComputerMcpServer(input.computerManager, input.threadId) } : {},
215818
215941
  ...input.cmmdSidekickTools ? { "cmmd-sidekick-tools": createCmmdSidekickToolsMcpServer(input.cmmdSidekickTools.session, input.cmmdSidekickTools.tools) } : {},
215819
- ...resolveCodewebMcpEnabled({
215820
- grant: input.codewebMcpGrant,
215821
- setting: input.serverSettings.codewebMcp
215822
- }) ? { [CODEWEB_MCP_SERVER_NAME]: {
215942
+ ...codewebEntryForInjection(input.codewebMcpInjection)
215943
+ };
215944
+ }
215945
+ /**
215946
+ * CodeWeb entry per the session auth decision: `authorized` carries the
215947
+ * minted Agent Token (plaintext appears exactly once, held in memory for
215948
+ * this session); `ungated` registers without credentials so the client-side
215949
+ * MCP OAuth challenge can run; `workspace_required` and `omitted` seat
215950
+ * nothing — the surfaced link and the next session's mint retry are the
215951
+ * recovery paths.
215952
+ */
215953
+ function codewebEntryForInjection(injection) {
215954
+ switch (injection.kind) {
215955
+ case "authorized": return { [CODEWEB_MCP_SERVER_NAME]: {
215956
+ type: "http",
215957
+ url: CODEWEB_MCP_SERVER_URL,
215958
+ headers: { Authorization: `Bearer ${injection.bearerToken}` }
215959
+ } };
215960
+ case "ungated": return { [CODEWEB_MCP_SERVER_NAME]: {
215823
215961
  type: "http",
215824
215962
  url: CODEWEB_MCP_SERVER_URL
215825
- } } : {}
215826
- };
215963
+ } };
215964
+ default: return {};
215965
+ }
215827
215966
  }
215828
215967
  function claudeQueryWorkingDirectoryOptions(cwd) {
215829
215968
  return cwd ? {
@@ -218063,6 +218202,25 @@ const makeClaudeAdapter = require_Schema$1.fn("makeClaudeAdapter")(function* (op
218063
218202
  detail: error.message,
218064
218203
  cause: error
218065
218204
  })));
218205
+ const codewebMcpInjection = yield* resolveCodewebMcpInjection({
218206
+ enabled: resolveCodewebMcpEnabled({
218207
+ grant: cmmdSidekickResolution.codewebMcpGrant,
218208
+ setting: serverSettings.codewebMcp
218209
+ }),
218210
+ threadId,
218211
+ serviceToken: serverConfig.codewebServiceToken
218212
+ });
218213
+ if (codewebMcpInjection.kind === "workspace_required") {
218214
+ const stamp = yield* makeEventStamp();
218215
+ yield* offerRuntimeEvent({
218216
+ type: "codeweb.workspace.required",
218217
+ eventId: stamp.eventId,
218218
+ provider: PROVIDER$11,
218219
+ createdAt: stamp.createdAt,
218220
+ threadId,
218221
+ payload: { chooseWorkspaceUrl: codewebMcpInjection.chooseWorkspaceUrl }
218222
+ });
218223
+ }
218066
218224
  const claudeSettings = serverSettings.providers.claudeAgent;
218067
218225
  const claudeBinaryPath = claudeSettings.binaryPath;
218068
218226
  const { selectedAccountIdentity, claudeCredentialDirectory } = yield* resolveSelectedCredentialDirectory(input, resumeState, claudeBinaryPath);
@@ -218103,7 +218261,7 @@ const makeClaudeAdapter = require_Schema$1.fn("makeClaudeAdapter")(function* (op
218103
218261
  resolveCmmdPat,
218104
218262
  devServerToolDeps,
218105
218263
  cmmdSidekickTools: cmmdSidekickResolution.registration,
218106
- codewebMcpGrant: cmmdSidekickResolution.codewebMcpGrant,
218264
+ codewebMcpInjection,
218107
218265
  runBrokeredGitHubTool,
218108
218266
  serverSettings
218109
218267
  }), threadId);
@@ -222929,7 +223087,10 @@ function buildAcpMcpServers(input) {
222929
223087
  type: "http",
222930
223088
  name: CODEWEB_MCP_SERVER_NAME,
222931
223089
  url: CODEWEB_MCP_SERVER_URL,
222932
- headers: []
223090
+ headers: input.codewebBearerToken ? [{
223091
+ name: "Authorization",
223092
+ value: `Bearer ${input.codewebBearerToken}`
223093
+ }] : []
222933
223094
  }];
222934
223095
  }
222935
223096
  var AcpSessionRuntime = class AcpSessionRuntime extends require_Schema$1.Service()("forge/provider/acp/AcpSessionRuntime") {
@@ -223445,7 +223606,7 @@ const checkCursorProviderStatus = require_Schema$1.fn("checkCursorProviderStatus
223445
223606
  message: "Cursor is disabled in Forge settings."
223446
223607
  }
223447
223608
  });
223448
- const versionProbe = yield* runCursorCommand(cursorSettings.binaryPath, ["--version"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$3), require_Schema$1.result);
223609
+ const versionProbe = yield* runCursorCommand(cursorSettings.binaryPath, ["--version"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$4), require_Schema$1.result);
223449
223610
  if (require_Schema$1.isFailure$1(versionProbe)) {
223450
223611
  const error = versionProbe.failure;
223451
223612
  return buildServerProvider({
@@ -289706,6 +289867,16 @@ function runtimeStatusEventToActivities(event) {
289706
289867
  summary: "Runtime error",
289707
289868
  payload: { message: truncateDetail(event.payload.message) }
289708
289869
  }];
289870
+ case "codeweb.workspace.required": return [{
289871
+ ...activityBase(event),
289872
+ tone: "info",
289873
+ kind: "codeweb.workspace.required",
289874
+ summary: "CodeWeb: choose your Workspace to enable its tools",
289875
+ payload: {
289876
+ detail: `One-time setup: open ${event.payload.chooseWorkspaceUrl} to choose your CodeWeb Workspace, then retry.`,
289877
+ chooseWorkspaceUrl: event.payload.chooseWorkspaceUrl
289878
+ }
289879
+ }];
289709
289880
  case "runtime.warning": return [{
289710
289881
  ...activityBase(event),
289711
289882
  tone: "info",
@@ -294603,7 +294774,7 @@ const checkOpenCodeProviderStatus = require_Schema$1.fn("checkOpenCodeProviderSt
294603
294774
  message: "OpenCode is disabled in Forge settings."
294604
294775
  }
294605
294776
  });
294606
- const versionProbe = yield* runOpenCodeCommand(opencodeSettings.binaryPath, ["--version"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$3), require_Schema$1.result);
294777
+ const versionProbe = yield* runOpenCodeCommand(opencodeSettings.binaryPath, ["--version"]).pipe(require_Schema$1.timeoutOption(DEFAULT_TIMEOUT_MS$4), require_Schema$1.result);
294607
294778
  if (require_Schema$1.isFailure$1(versionProbe)) {
294608
294779
  const error = versionProbe.failure;
294609
294780
  return buildServerProvider({
@@ -297894,7 +298065,7 @@ function resolveBuildCommitFromEnv(env) {
297894
298065
  * environment descriptor down instead of reporting an honest "unknown".
297895
298066
  */
297896
298067
  function readBakedBuildCommit() {
297897
- return "bf940e8514ec9d856e44ea77ff6adb64b709146a";
298068
+ return "efe4f61b3d4a7de342d1d80983113ff48dd26235";
297898
298069
  }
297899
298070
  async function resolveServerBuildCommit(input) {
297900
298071
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -322008,6 +322179,7 @@ const EnvServerConfig = require_Config.all({
322008
322179
  forgeCodexHomePath: require_Config.string("FORGE_CODEX_HOME").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
322009
322180
  forgeClaudeConfigPath: require_Config.string("FORGE_CLAUDE_CONFIG_PATH").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
322010
322181
  forgeApexBaseUrl: require_Config.string("FORGE_APEX_BASE_URL").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
322182
+ codewebServiceToken: require_Config.string("FORGE_CODEWEB_SERVICE_TOKEN").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
322011
322183
  browserWebRtcIceServers: require_Config.string("FORGE_BROWSER_WEBRTC_ICE_SERVERS").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
322012
322184
  browserWebRtcCloudflareTurnKeyId: require_Config.string("FORGE_BROWSER_WEBRTC_CLOUDFLARE_TURN_KEY_ID").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
322013
322185
  browserWebRtcCloudflareTurnKeyApiToken: require_Config.string("FORGE_BROWSER_WEBRTC_CLOUDFLARE_TURN_KEY_API_TOKEN").pipe(require_Config.option, require_Config.map(require_Schema$1.getOrUndefined$1)),
@@ -322203,6 +322375,7 @@ const resolveServerConfig = (flags, cliLogLevel, options) => require_Schema$1.ge
322203
322375
  forgeCodexHomePath: env.forgeCodexHomePath,
322204
322376
  forgeClaudeConfigPath: env.forgeClaudeConfigPath,
322205
322377
  forgeApexBaseUrl: env.forgeApexBaseUrl,
322378
+ codewebServiceToken: env.codewebServiceToken,
322206
322379
  cloudProjectsRoot: env.cloudProjectsRoot ?? "/projects"
322207
322380
  };
322208
322381
  if (config.forgeCloudShellMode === true && (!config.forgeCloudOwnerAssertionPublicKey?.trim() || !config.forgeCloudOwnerAssertionKeyId?.trim())) return yield* require_Schema$1.die(/* @__PURE__ */ new Error("FORGE_CMMD_CLOUD_OWNER_ASSERTION_PUBLIC_KEY and FORGE_CMMD_CLOUD_OWNER_ASSERTION_KEY_ID are required in cloud-shell mode; runtime ticket keys are not accepted for Cloud owner assertions."));
@@ -322311,16 +322484,16 @@ const findActiveProjectTarget = require_Schema$1.fn("findActiveProjectTarget")(f
322311
322484
  workspaceRoot: resolved.workspaceRoot
322312
322485
  };
322313
322486
  });
322314
- const fetchLiveOrchestrationSnapshot = (origin, bearerToken$1) => runLiveServerRequest(require_HttpServer.get(`${origin}/api/orchestration/snapshot`).pipe(require_HttpServer.acceptJson, require_HttpServer.bearerToken(bearerToken$1)), require_HttpServer.matchStatus({
322487
+ const fetchLiveOrchestrationSnapshot = (origin, bearerToken$2) => runLiveServerRequest(require_HttpServer.get(`${origin}/api/orchestration/snapshot`).pipe(require_HttpServer.acceptJson, require_HttpServer.bearerToken(bearerToken$2)), require_HttpServer.matchStatus({
322315
322488
  "2xx": decodeOrchestrationReadModelResponse,
322316
322489
  orElse: (response) => readErrorMessageFromResponse(response).pipe(require_Schema$1.flatMap((message) => require_Schema$1.fail(new Error(message))))
322317
322490
  }));
322318
322491
  const ProjectLeadExplanationEnvelope = require_Schema$1.Struct({ data: ProjectLeadExplanationSchema });
322319
- const fetchLiveProjectLeadExplanation = (origin, bearerToken$3, projectId) => runLiveServerRequest(require_HttpServer.get(`${origin}/api/cmmd/projects/${projectId}/project-lead/explain`).pipe(require_HttpServer.acceptJson, require_HttpServer.bearerToken(bearerToken$3)), require_HttpServer.matchStatus({
322492
+ const fetchLiveProjectLeadExplanation = (origin, bearerToken$1, projectId) => runLiveServerRequest(require_HttpServer.get(`${origin}/api/cmmd/projects/${projectId}/project-lead/explain`).pipe(require_HttpServer.acceptJson, require_HttpServer.bearerToken(bearerToken$1)), require_HttpServer.matchStatus({
322320
322493
  "2xx": (response) => require_HttpServer.schemaBodyJson$1(ProjectLeadExplanationEnvelope)(response).pipe(require_Schema$1.map((body) => body.data)),
322321
322494
  orElse: (response) => readErrorMessageFromResponse(response).pipe(require_Schema$1.flatMap((message) => require_Schema$1.fail(new Error(message))))
322322
322495
  }));
322323
- const dispatchLiveOrchestrationCommand = (origin, bearerToken$2, command) => require_HttpServer.post(`${origin}/api/orchestration/dispatch`).pipe(require_HttpServer.acceptJson, require_HttpServer.bearerToken(bearerToken$2), require_HttpServer.bodyJson(command), require_Schema$1.flatMap((request) => runLiveServerRequest(request, require_HttpServer.matchStatus({
322496
+ const dispatchLiveOrchestrationCommand = (origin, bearerToken$3, command) => require_HttpServer.post(`${origin}/api/orchestration/dispatch`).pipe(require_HttpServer.acceptJson, require_HttpServer.bearerToken(bearerToken$3), require_HttpServer.bodyJson(command), require_Schema$1.flatMap((request) => runLiveServerRequest(request, require_HttpServer.matchStatus({
322324
322497
  "2xx": () => require_Schema$1.void_,
322325
322498
  orElse: (response) => readErrorMessageFromResponse(response).pipe(require_Schema$1.flatMap((message) => require_Schema$1.fail(new Error(message))))
322326
322499
  }))));