@cmmd-center/forge 0.10.5 → 0.10.7

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.
Files changed (22) hide show
  1. package/dist/bin.cjs +1294 -795
  2. package/dist/bin.mjs +1293 -792
  3. package/dist/client/assets/{CanvasPanel-Dr4I7MnM.js → CanvasPanel-ECmvVI7T.js} +2 -2
  4. package/dist/client/assets/{CompositeItem-Cj6_oAlz.js → CompositeItem-8hzrVacr.js} +2 -2
  5. package/dist/client/assets/{DiffPanel-CsMWXFsK.js → DiffPanel-BqOO3dsl.js} +3 -3
  6. package/dist/client/assets/{DiffPanel.logic-Cyp3p58B.js → DiffPanel.logic-Bzm8oiCr.js} +2 -2
  7. package/dist/client/assets/DiffPanelShell-DVVw1mR3.js +2531 -0
  8. package/dist/client/assets/{DiffWorkerPoolProvider-DOF7ypo1.js → DiffWorkerPoolProvider-BsMgSHbg.js} +8 -8
  9. package/dist/client/assets/{PullRequestCodePanel-BuK0wrXE.js → PullRequestCodePanel-DNrNrubs.js} +3 -3
  10. package/dist/client/assets/{Virtualizer-CQJMsfKa.js → Virtualizer-RRV_x18w.js} +2 -2
  11. package/dist/client/assets/{canvasStateStore-DncdOQ4J.js → canvasStateStore-3EN8RaUf.js} +2 -2
  12. package/dist/client/assets/{cmmdAuthRedirect-DWiMDVzN.js → cmmdAuthRedirect-DwPtzhq9.js} +2 -2
  13. package/dist/client/assets/index-D22UpSjv.css +1 -0
  14. package/dist/client/assets/{index-C6vF1RSl.js → index-DCVtRkq1.js} +56 -56
  15. package/dist/client/assets/{src-CtyKlVph.js → src-DZBONdiY.js} +2 -2
  16. package/dist/client/assets/{toggle-pTm2fPLg.js → toggle-mQ7UG7Dd.js} +2 -2
  17. package/dist/client/assets/{useTriggerFocusGuards-B4Ejoaox.js → useTriggerFocusGuards-BUEnX8xa.js} +2 -2
  18. package/dist/client/index.html +11 -11
  19. package/dist/forge-build.json +1 -1
  20. package/package.json +1 -1
  21. package/dist/client/assets/DiffPanelShell-h78vZ6dX.js +0 -2531
  22. package/dist/client/assets/index-T36rURmx.css +0 -1
package/dist/bin.cjs CHANGED
@@ -24457,6 +24457,7 @@ const UsageBucket = require_Schema$1.Struct({
24457
24457
  costSource: UsageCostSource,
24458
24458
  records: NonNegativeInt,
24459
24459
  unpricedRecords: NonNegativeInt,
24460
+ unreportedRecords: require_Schema$1.optional(NonNegativeInt),
24460
24461
  sessions: NonNegativeInt,
24461
24462
  runtimeId: require_Schema$1.optional(TrimmedNonEmptyString),
24462
24463
  origin: require_Schema$1.optional(UsageBucketOrigin),
@@ -26340,7 +26341,7 @@ function acceptCmmdProjectPatchField(field, raw) {
26340
26341
  //#region ../../packages/contracts/src/cloud.ts
26341
26342
  /**
26342
26343
  * One entry returned by `GET /api/cloud/available-folders` — a candidate
26343
- * subdirectory of the managed runtime's `cloudProjectsRoot` (typically `/data/Projects`)
26344
+ * subdirectory of the managed runtime's `cloudProjectsRoot` (typically `/projects`)
26344
26345
  * that the SPA can offer in the cloud-mode "Register existing folder" picker.
26345
26346
  */
26346
26347
  const CloudAvailableFolder = require_Schema$1.Struct({
@@ -65378,7 +65379,7 @@ function normalizeNumberish(value) {
65378
65379
  }
65379
65380
  //#endregion
65380
65381
  //#region package.json
65381
- var version$1 = "0.10.5";
65382
+ var version$1 = "0.10.7";
65382
65383
  //#endregion
65383
65384
  //#region src/sentry.ts
65384
65385
  const SERVER_APP_NAME = "forge-server";
@@ -68163,6 +68164,15 @@ function parsePersistedServerObservabilitySettings(raw) {
68163
68164
  * @module ServerConfig
68164
68165
  */
68165
68166
  const DEFAULT_PORT = 13773;
68167
+ /**
68168
+ * Where a managed cloud runtime keeps the user's checkouts when
68169
+ * FORGE_CLOUD_PROJECTS_ROOT is not set. CMMD seeds every sprite checkout under
68170
+ * /projects (forge-guest-layout.ts on the CMMD side) and passes that value in
68171
+ * the Service env, so this default only matters for a server started without
68172
+ * it. It used to be a path under the Fly-era mounted volume; on a sprite the
68173
+ * two repos disagreed and every local-checkout turn was refused (FOR-36484).
68174
+ */
68175
+ const DEFAULT_CLOUD_PROJECTS_ROOT = "/projects";
68166
68176
  const RuntimeMode = require_Schema$1.Literals(["web", "desktop"]);
68167
68177
  require_Schema$1.Literals(["browser", "headless"]);
68168
68178
  const deriveServerPaths = require_Schema$1.fn(function* (baseDir, _devUrl, _mode) {
@@ -68288,7 +68298,7 @@ var ServerConfig = class ServerConfig extends require_Schema$1.Service()("forge/
68288
68298
  forgeCodexHomePath: void 0,
68289
68299
  forgeClaudeConfigPath: void 0,
68290
68300
  forgeApexBaseUrl: void 0,
68291
- cloudProjectsRoot: "/data/Projects",
68301
+ cloudProjectsRoot: DEFAULT_CLOUD_PROJECTS_ROOT,
68292
68302
  ...overrides
68293
68303
  };
68294
68304
  }));
@@ -70295,6 +70305,14 @@ function invalidateCachedCmmdWorkIntakeForIdentity(identityKey) {
70295
70305
  *
70296
70306
  * Bespoke routes (MCP/PAT transport, hybrid fallback, multipart) stay in
70297
70307
  * http.ts and are NOT migrated here.
70308
+ *
70309
+ * A second, narrower entry point — `registerProxyHandler` / `ProxyHandlerRoute`
70310
+ * — covers routes whose middle (request parsing, the actual gateway call,
70311
+ * success shaping) cannot be expressed by the five `ProxyRoute` fields above,
70312
+ * while still sharing the same prologue: session auth, the CMMD-connection
70313
+ * gate, and the same `buildProxyErrorResponse` error mapping plus
70314
+ * `clearUnrecoverableCmmdAuthForSession` on an auth failure. See the type doc
70315
+ * below for the exact contract.
70298
70316
  */
70299
70317
  /** Substitutes ":paramName" tokens in a path template from a params record. */
70300
70318
  function substitutePath(template, params) {
@@ -70344,6 +70362,29 @@ function buildProxyErrorResponse(error) {
70344
70362
  }
70345
70363
  return require_HttpServer.jsonUnsafe({ error: "CMMD REST request failed." }, { status: 502 });
70346
70364
  }
70365
+ /**
70366
+ * Clears every unrecoverable CMMD credential tied to this session, logging a
70367
+ * warning rather than failing the request if the clear itself errors — a
70368
+ * session that already has no usable credential must still get its 401,
70369
+ * not a 500 from a failed best-effort cleanup.
70370
+ */
70371
+ function clearCmmdAuthAfterFailure(sessionId) {
70372
+ return clearUnrecoverableCmmdAuthForSession(sessionId).pipe(require_Schema$1.catch_((error) => require_Schema$1.logWarning("Failed to clear unrecoverable CMMD auth after CMMD auth failure.", {
70373
+ cause: error,
70374
+ sessionId
70375
+ })));
70376
+ }
70377
+ /**
70378
+ * The single "no usable CMMD credential" response: clears whatever
70379
+ * unrecoverable auth state this session is holding, then returns the
70380
+ * canonical `CMMD_AUTH_REQUIRED` body. Every prologue path that decides the
70381
+ * session has no way to reach CMMD — a missing PAT, a JWT that fails to
70382
+ * resolve, a bespoke gate elsewhere in http.ts — emits this same response so
70383
+ * the Shell only ever has one `CMMD_AUTH_REQUIRED` body to branch on.
70384
+ */
70385
+ function respondCmmdConnectionRequired(sessionId) {
70386
+ return clearCmmdAuthAfterFailure(sessionId).pipe(require_Schema$1.as(buildProxyErrorResponse(new CmmdProxyAuthenticationRequiredError("CMMD connection required. Reconnect CMMD to continue."))));
70387
+ }
70347
70388
  async function dispatchToProxy(method, jwt, cmmdPath, rawBody, orgId, searchParams) {
70348
70389
  return cmmdGateway.request({
70349
70390
  method,
@@ -70374,12 +70415,27 @@ function buildProxySearchParams(input) {
70374
70415
  return Object.keys(result).length > 0 ? result : void 0;
70375
70416
  }
70376
70417
  const _registeredRoutes = [];
70377
- /**
70378
- * Generates an Effect HttpRouter layer for the given route.
70379
- * The returned layer registers one handler at forgePath.
70380
- */
70381
- function registerProxyRoute(route) {
70382
- _registeredRoutes.push(route);
70418
+ const _registeredLayers = [];
70419
+ /**
70420
+ * Layers produced by every registerProxyRoute call so far, in registration
70421
+ * order. Callers that want only the routes registered by their own module
70422
+ * should snapshot `.length` before their own registerProxyRoute calls run and
70423
+ * slice from that index — see command/http.ts's `cmmdProxyRouteLayers`.
70424
+ *
70425
+ * Typed via `ReturnType<typeof buildProxyRouteLayer>` (not `HttpRouter.add`
70426
+ * directly, and not `registerProxyRoute` itself — that would be circular
70427
+ * since registerProxyRoute pushes onto this same array): `buildProxyRouteLayer`
70428
+ * takes a concrete, non-generic `ProxyRoute` argument and never references
70429
+ * this array, so its return type is fully resolved independently. Referencing
70430
+ * the generic `HttpRouter.add` on its own instead collapses its unresolved E/R
70431
+ * type parameters to `unknown`, which then leaks into makeRoutesLayer's
70432
+ * requirements channel everywhere this array is spread.
70433
+ */
70434
+ function registeredProxyRouteLayers() {
70435
+ return Object.freeze([..._registeredLayers]);
70436
+ }
70437
+ /** Builds the Effect HttpRouter layer for one route, with no registry side effects. */
70438
+ function buildProxyRouteLayer(route) {
70383
70439
  const handler = require_Schema$1.gen(function* () {
70384
70440
  const req = yield* require_HttpServer.HttpServerRequest;
70385
70441
  const session = yield* (yield* ServerAuth).authenticateHttpRequest(req);
@@ -70402,23 +70458,14 @@ function registerProxyRoute(route) {
70402
70458
  forceRefresh
70403
70459
  });
70404
70460
  const jwt = yield* resolveJwt();
70405
- if (!jwt) {
70406
- yield* clearUnrecoverableCmmdAuthForSession(session.sessionId).pipe(require_Schema$1.catch_((error) => require_Schema$1.logWarning("Failed to clear unrecoverable CMMD auth after missing JWT.", {
70407
- cause: error,
70408
- sessionId: session.sessionId
70409
- })));
70410
- return buildProxyErrorResponse(new CmmdProxyAuthenticationRequiredError("CMMD connection required. Reconnect CMMD to continue."));
70411
- }
70461
+ if (!jwt) return yield* respondCmmdConnectionRequired(session.sessionId);
70412
70462
  let outcome = yield* require_Schema$1.promise(() => runProxy(() => dispatchToProxy(route.method, jwt, cmmdPath, rawBody, orgId, searchParams)));
70413
70463
  if (!outcome.ok && outcome.error instanceof CmmdProxyAuthError) {
70414
70464
  const refreshedJwt = yield* resolveJwt(true);
70415
70465
  if (refreshedJwt && refreshedJwt !== jwt) outcome = yield* require_Schema$1.promise(() => runProxy(() => dispatchToProxy(route.method, refreshedJwt, cmmdPath, rawBody, orgId, searchParams)));
70416
70466
  }
70417
70467
  if (!outcome.ok) {
70418
- if (outcome.error instanceof CmmdProxyAuthError || outcome.error instanceof CmmdProxyAuthenticationRequiredError) yield* clearUnrecoverableCmmdAuthForSession(session.sessionId).pipe(require_Schema$1.catch_((error) => require_Schema$1.logWarning("Failed to clear unrecoverable CMMD auth after REST 401.", {
70419
- cause: error,
70420
- sessionId: session.sessionId
70421
- })));
70468
+ if (outcome.error instanceof CmmdProxyAuthError || outcome.error instanceof CmmdProxyAuthenticationRequiredError) yield* clearCmmdAuthAfterFailure(session.sessionId);
70422
70469
  return buildProxyErrorResponse(outcome.error);
70423
70470
  }
70424
70471
  const payload = route.responseShape === "passthrough" ? outcome.value : unwrapEnvelope$1(outcome.value);
@@ -70429,6 +70476,59 @@ function registerProxyRoute(route) {
70429
70476
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error)));
70430
70477
  return add$1(route.method, route.forgePath, handler);
70431
70478
  }
70479
+ /**
70480
+ * Generates an Effect HttpRouter layer for the given route and records it in
70481
+ * the registry (for auditing / tests, and so command/http.ts's
70482
+ * `cmmdProxyRouteLayers` can pick it up). The returned layer registers one
70483
+ * handler at forgePath.
70484
+ */
70485
+ function registerProxyRoute(route) {
70486
+ _registeredRoutes.push(route);
70487
+ const layer = buildProxyRouteLayer(route);
70488
+ _registeredLayers.push(layer);
70489
+ return layer;
70490
+ }
70491
+ /**
70492
+ * Builds the bare handler Effect for one handler route (no `HttpRouter.add`
70493
+ * wrapping, no registry side effects) — exposed on its own so tests can
70494
+ * exercise it the same way they exercise every other bespoke handler in
70495
+ * http.ts: providing `HttpServerRequest` / `ServerAuth` directly and running
70496
+ * the Effect, without standing up a router.
70497
+ */
70498
+ function buildProxyHandlerEffect(route) {
70499
+ return require_Schema$1.gen(function* () {
70500
+ const req = yield* require_HttpServer.HttpServerRequest;
70501
+ const session = yield* (yield* ServerAuth).authenticateHttpRequest(req);
70502
+ if (!readCommandAccessTokenForSession(session.sessionId)) return yield* respondCmmdConnectionRequired(session.sessionId);
70503
+ const parsed = yield* route.parse(req);
70504
+ if (!parsed.ok) return require_HttpServer.jsonUnsafe(parsed.body, { status: parsed.status });
70505
+ const result$4 = yield* route.run(parsed.value, { session }).pipe(require_Schema$1.result);
70506
+ if (require_Schema$1.isFailure$1(result$4)) {
70507
+ const error = result$4.failure;
70508
+ if (error instanceof CmmdProxyAuthError || error instanceof CmmdProxyAuthenticationRequiredError) yield* clearCmmdAuthAfterFailure(session.sessionId);
70509
+ return buildProxyErrorResponse(error);
70510
+ }
70511
+ return require_HttpServer.jsonUnsafe(result$4.success.body, { status: result$4.success.status });
70512
+ }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error)));
70513
+ }
70514
+ const _registeredHandlerRoutes = [];
70515
+ /**
70516
+ * Builds the handler Effect for one route, mounts it via `HttpRouter.add` and
70517
+ * records that layer in the same registry `registerProxyRoute` uses (so
70518
+ * command/http.ts's `cmmdProxyRouteLayers` picks it up without a separate
70519
+ * mount list) — then returns the bare handler Effect rather than the layer,
70520
+ * so the caller can keep a single `__xHandlerForTests`-style export that
70521
+ * doubles as both the thing under test and the thing that gets mounted.
70522
+ */
70523
+ function registerProxyHandler(route) {
70524
+ _registeredHandlerRoutes.push({
70525
+ method: route.method,
70526
+ forgePath: route.forgePath
70527
+ });
70528
+ const handler = buildProxyHandlerEffect(route);
70529
+ _registeredLayers.push(add$1(route.method, route.forgePath, handler));
70530
+ return handler;
70531
+ }
70432
70532
  //#endregion
70433
70533
  //#region src/connect/credentialRefresh.ts
70434
70534
  async function refreshConnectCredential(deps) {
@@ -92602,6 +92702,172 @@ function classifyRuntimeReplicationHttpFailure(failure) {
92602
92702
  };
92603
92703
  }
92604
92704
  //#endregion
92705
+ //#region src/runtimeReplication/runtimeLane.ts
92706
+ /**
92707
+ * Read a grant-lane response the way the gateway reads an owner-lane one: a
92708
+ * non-2xx becomes a `CmmdProxyRequestError` carrying the status and CMMD's
92709
+ * error code, so a caller can classify either lane's failure with one rule.
92710
+ */
92711
+ async function parseRuntimeLaneResponse(response) {
92712
+ const text = await response.text();
92713
+ let body = null;
92714
+ if (text) try {
92715
+ body = JSON.parse(text);
92716
+ } catch {
92717
+ body = null;
92718
+ }
92719
+ if (!response.ok) {
92720
+ const code = readRuntimeReplicationErrorCode(body);
92721
+ throw new CmmdProxyRequestError(`CMMD runtime replication failed (${response.status})`, response.status, null, code ? { code } : null);
92722
+ }
92723
+ if (body === null) throw new Error("CMMD runtime replication returned an empty or invalid JSON response.");
92724
+ return body;
92725
+ }
92726
+ /**
92727
+ * One request on whichever lane the runtime holds. The caller has already
92728
+ * built the path for `lane.kind`; this only decides the transport and the
92729
+ * credential header, and normalises failures to the gateway's error classes.
92730
+ */
92731
+ async function requestOnRuntimeLane(lane, request, transport = {}) {
92732
+ if (lane.kind === "owner-session") return (transport.gateway ?? cmmdGateway).request({
92733
+ method: request.method,
92734
+ jwt: lane.jwt,
92735
+ path: request.path,
92736
+ ...request.body === void 0 ? {} : { body: request.body }
92737
+ });
92738
+ return parseRuntimeLaneResponse(await (transport.fetchImpl ?? fetch)(new URL(request.path, `${lane.controlPlaneUrl}/`), {
92739
+ method: request.method,
92740
+ headers: {
92741
+ authorization: `Bearer ${lane.grantToken}`,
92742
+ accept: "application/json",
92743
+ ...request.body === void 0 ? {} : { "content-type": "application/json" }
92744
+ },
92745
+ ...request.body === void 0 ? {} : { body: JSON.stringify(request.body) },
92746
+ ...request.signal === void 0 ? {} : { signal: request.signal }
92747
+ }));
92748
+ }
92749
+ function mapRuntimeReplicationClientError(error, operation) {
92750
+ if (error instanceof CmmdProxyAuthError) return new RuntimeReplicationClientError({
92751
+ kind: "auth",
92752
+ code: "CMMD_AUTH_REQUIRED",
92753
+ detail: error.message
92754
+ });
92755
+ if (error instanceof CmmdProxyAuthenticationRequiredError) return new RuntimeReplicationClientError({
92756
+ kind: "auth",
92757
+ code: "CMMD_AUTH_REQUIRED",
92758
+ detail: error.message
92759
+ });
92760
+ if (error instanceof CmmdProxyPermissionError) return new RuntimeReplicationClientError({
92761
+ kind: "permanent",
92762
+ code: "CMMD_PERMISSION_DENIED",
92763
+ detail: error.message
92764
+ });
92765
+ if (error instanceof CmmdProxyRequestError) return new RuntimeReplicationClientError(classifyRuntimeReplicationHttpFailure({
92766
+ status: error.status,
92767
+ body: error.body,
92768
+ detail: error.detail ?? error.message,
92769
+ ...operation ? { operation } : {}
92770
+ }));
92771
+ return new RuntimeReplicationClientError({
92772
+ kind: "retryable",
92773
+ code: "CMMD_UNAVAILABLE",
92774
+ detail: error instanceof Error ? error.message : String(error)
92775
+ });
92776
+ }
92777
+ //#endregion
92778
+ //#region src/runtimeReplication/lifecycleIntentClient.ts
92779
+ /**
92780
+ * The runtime half of a lifecycle intent: a settle or un-settle a person asked
92781
+ * for while this runtime was offline, held by CMMD until the runtime lists it,
92782
+ * applies it through its own orchestration, and acknowledges it.
92783
+ *
92784
+ * Both lanes carry the same envelope (pinned equal in the contracts package),
92785
+ * so one client serves the desktop's owner-session lane and the cloud
92786
+ * runtime's grant lane; only the path family differs.
92787
+ */
92788
+ const LIFECYCLE_INTENT_TIMEOUT = "10 seconds";
92789
+ const LifecycleIntentListEnvelope = require_Schema$1.Struct({ data: require_Schema$1.Struct({ intents: require_Schema$1.ArraySchema(require_Schema$1.Struct({
92790
+ runtimeId: require_Schema$1.String,
92791
+ threadId: require_Schema$1.String,
92792
+ action: require_Schema$1.Literals(["settle", "unsettle"]),
92793
+ requestedAt: require_Schema$1.String
92794
+ })) }) });
92795
+ const LifecycleIntentAcknowledgementEnvelope = require_Schema$1.Struct({ data: require_Schema$1.Struct({ acknowledged: require_Schema$1.Number }) });
92796
+ const decodeListEnvelope = require_Schema$1.decodeUnknownSync(LifecycleIntentListEnvelope);
92797
+ const decodeAcknowledgementEnvelope = require_Schema$1.decodeUnknownSync(LifecycleIntentAcknowledgementEnvelope);
92798
+ function decodeLifecycleIntentListResponse(response) {
92799
+ return decodeListEnvelope(response).data;
92800
+ }
92801
+ function decodeLifecycleIntentAcknowledgementResponse(response) {
92802
+ return decodeAcknowledgementEnvelope(response).data;
92803
+ }
92804
+ /**
92805
+ * Ids arrive from runtime rows, not constrained to path-safe characters, so
92806
+ * they are encoded the way every other runtime-lane path builder encodes them.
92807
+ */
92808
+ function lifecycleIntentPath(lane, operation) {
92809
+ const base = `/api/forge/context/${lane.kind === "grant" ? "runtime-replication" : "devices"}/runtimes/${encodeURIComponent(lane.runtimeId)}/thread-lifecycle-intents`;
92810
+ return operation === "ack" ? `${base}/ack` : base;
92811
+ }
92812
+ function timedOut(operation) {
92813
+ return new RuntimeReplicationClientError({
92814
+ kind: "retryable",
92815
+ code: "CMMD_TIMEOUT",
92816
+ detail: `CMMD lifecycle intent ${operation} timed out.`
92817
+ });
92818
+ }
92819
+ function decodeOrFail(response, decode, label) {
92820
+ return require_Schema$1.try_({
92821
+ try: () => decode(response),
92822
+ catch: (cause) => new RuntimeReplicationClientError({
92823
+ kind: "permanent",
92824
+ code: "CMMD_PROTOCOL_INVALID_RESPONSE",
92825
+ detail: `CMMD returned an invalid lifecycle intent ${label}: ${cause instanceof Error ? cause.message : String(cause)}`
92826
+ })
92827
+ });
92828
+ }
92829
+ /**
92830
+ * Every pending intent for this runtime, or an empty list.
92831
+ *
92832
+ * 404 is an ordinary answer, not a failure: a CMMD that predates the route
92833
+ * has nothing pending for anyone, and a runtime it has not registered yet has
92834
+ * nothing pending either. Every other non-2xx is a typed error -- a signed-out
92835
+ * owner (auth) is the caller's to skip, an outage is the next tick's to retry.
92836
+ */
92837
+ function listPendingLifecycleIntents(lane, transport) {
92838
+ return require_Schema$1.tryPromise({
92839
+ try: (signal) => requestOnRuntimeLane(lane, {
92840
+ method: "GET",
92841
+ path: lifecycleIntentPath(lane, "list"),
92842
+ signal
92843
+ }, transport),
92844
+ catch: (cause) => cause instanceof CmmdProxyRequestError && cause.status === 404 ? null : mapRuntimeReplicationClientError(cause)
92845
+ }).pipe(require_Schema$1.catch_((cause) => cause === null ? require_Schema$1.succeed(null) : require_Schema$1.fail(cause)), require_Schema$1.flatMap((response) => response === null ? require_Schema$1.succeed([]) : decodeOrFail(response, decodeLifecycleIntentListResponse, "list").pipe(require_Schema$1.map((list) => list.intents))), require_Schema$1.timeoutOrElse({
92846
+ duration: LIFECYCLE_INTENT_TIMEOUT,
92847
+ orElse: () => require_Schema$1.fail(timedOut("list"))
92848
+ }));
92849
+ }
92850
+ /**
92851
+ * Tell CMMD which intents were applied (or deliberately skipped), by thread
92852
+ * and requested time. CMMD drops only an intent whose requested time matches,
92853
+ * so a newer request recorded while this one was being applied survives.
92854
+ */
92855
+ function acknowledgeLifecycleIntents(lane, intents, transport) {
92856
+ const body = { intents };
92857
+ return require_Schema$1.tryPromise({
92858
+ try: (signal) => requestOnRuntimeLane(lane, {
92859
+ method: "POST",
92860
+ path: lifecycleIntentPath(lane, "ack"),
92861
+ body,
92862
+ signal
92863
+ }, transport),
92864
+ catch: mapRuntimeReplicationClientError
92865
+ }).pipe(require_Schema$1.flatMap((response) => decodeOrFail(response, decodeLifecycleIntentAcknowledgementResponse, "acknowledgement")), require_Schema$1.timeoutOrElse({
92866
+ duration: LIFECYCLE_INTENT_TIMEOUT,
92867
+ orElse: () => require_Schema$1.fail(timedOut("ack"))
92868
+ }));
92869
+ }
92870
+ //#endregion
92605
92871
  //#region src/runtimeReplication/runtimeReplicationGrantPolicy.ts
92606
92872
  /**
92607
92873
  * Chooses which CMMD grant a replication send should use: the in-memory
@@ -92707,26 +92973,11 @@ function runtimeReplicationDevicePath(input) {
92707
92973
  const threadId = input.streamKey.slice(7);
92708
92974
  return `${devicePath}/threads/${encodeURIComponent(threadId)}/events`;
92709
92975
  }
92710
- async function parseRuntimeReplicationResponse(response) {
92711
- const text = await response.text();
92712
- let body = null;
92713
- if (text) try {
92714
- body = JSON.parse(text);
92715
- } catch {
92716
- body = null;
92717
- }
92718
- if (!response.ok) {
92719
- const code = readRuntimeReplicationErrorCode(body);
92720
- throw new CmmdProxyRequestError(`CMMD runtime replication failed (${response.status})`, response.status, null, code ? { code } : null);
92721
- }
92722
- if (body === null) throw new Error("CMMD runtime replication returned an empty or invalid JSON response.");
92723
- return body;
92724
- }
92725
92976
  async function requestRuntimeReplicationWithGrant(input, fetchImpl = fetch) {
92726
92977
  const abortController = new AbortController();
92727
92978
  const timeout = setTimeout(() => abortController.abort(), RUNTIME_REPLICATION_TIMEOUT_MS);
92728
92979
  try {
92729
- return await parseRuntimeReplicationResponse(await fetchImpl(new URL(runtimeReplicationGrantPath(input), `${input.controlPlaneUrl}/`), {
92980
+ return await parseRuntimeLaneResponse(await fetchImpl(new URL(runtimeReplicationGrantPath(input), `${input.controlPlaneUrl}/`), {
92730
92981
  method: input.operation === "inventory" ? "PUT" : "POST",
92731
92982
  headers: {
92732
92983
  authorization: `Bearer ${input.grantToken}`,
@@ -92739,34 +92990,6 @@ async function requestRuntimeReplicationWithGrant(input, fetchImpl = fetch) {
92739
92990
  clearTimeout(timeout);
92740
92991
  }
92741
92992
  }
92742
- function mapRuntimeReplicationClientError(error, operation) {
92743
- if (error instanceof CmmdProxyAuthError) return new RuntimeReplicationClientError({
92744
- kind: "auth",
92745
- code: "CMMD_AUTH_REQUIRED",
92746
- detail: error.message
92747
- });
92748
- if (error instanceof CmmdProxyAuthenticationRequiredError) return new RuntimeReplicationClientError({
92749
- kind: "auth",
92750
- code: "CMMD_AUTH_REQUIRED",
92751
- detail: error.message
92752
- });
92753
- if (error instanceof CmmdProxyPermissionError) return new RuntimeReplicationClientError({
92754
- kind: "permanent",
92755
- code: "CMMD_PERMISSION_DENIED",
92756
- detail: error.message
92757
- });
92758
- if (error instanceof CmmdProxyRequestError) return new RuntimeReplicationClientError(classifyRuntimeReplicationHttpFailure({
92759
- status: error.status,
92760
- body: error.body,
92761
- detail: error.detail ?? error.message,
92762
- ...operation ? { operation } : {}
92763
- }));
92764
- return new RuntimeReplicationClientError({
92765
- kind: "retryable",
92766
- code: "CMMD_UNAVAILABLE",
92767
- detail: error instanceof Error ? error.message : String(error)
92768
- });
92769
- }
92770
92993
  function decodeRuntimeThreadAcknowledgementResponse(response) {
92771
92994
  return decodeThreadAcknowledgement(response).data.acknowledgement;
92772
92995
  }
@@ -92842,9 +93065,12 @@ function replicateWithOwnerSession(sql, input) {
92842
93065
  const jwt = owner.jwt;
92843
93066
  const path = runtimeReplicationDevicePath(input);
92844
93067
  const response = yield* require_Schema$1.tryPromise({
92845
- try: () => cmmdGateway.request({
93068
+ try: () => requestOnRuntimeLane({
93069
+ kind: "owner-session",
93070
+ runtimeId: input.runtimeId,
93071
+ jwt
93072
+ }, {
92846
93073
  method: input.operation === "inventory" ? "PUT" : "POST",
92847
- jwt,
92848
93074
  path,
92849
93075
  body: input.payload
92850
93076
  }),
@@ -92855,11 +93081,63 @@ function replicateWithOwnerSession(sql, input) {
92855
93081
  return yield* decodeAcknowledgementOrFail(response, decodeRuntimeThreadAcknowledgementResponse, "transcript");
92856
93082
  });
92857
93083
  }
93084
+ /**
93085
+ * The lane this runtime holds right now, resolved per call because both
93086
+ * credentials rotate: the cloud grant is re-read from the control authority,
93087
+ * and the owner session is whichever sign-in is newest on this desktop.
93088
+ */
93089
+ function resolveRuntimeLane(config, sql, input) {
93090
+ return require_Schema$1.gen(function* () {
93091
+ if (config.forgeCmmdRuntimeMode === true) {
93092
+ const cloudGrant = resolveCloudRuntimeReplicationGrant(config);
93093
+ if (!cloudGrant) return yield* new RuntimeReplicationClientError({
93094
+ kind: "auth",
93095
+ code: "CMMD_RUNTIME_GRANT_REQUIRED",
93096
+ detail: "Cloud runtime replication requires a canonical runtime ID, CMMD URL, and scoped runtime grant."
93097
+ });
93098
+ if (input.runtimeId !== cloudGrant.runtimeId) return yield* new RuntimeReplicationClientError({
93099
+ kind: "permanent",
93100
+ code: "CMMD_RUNTIME_ID_MISMATCH",
93101
+ detail: "The requested runtime does not match this cloud runtime identity."
93102
+ });
93103
+ return {
93104
+ kind: "grant",
93105
+ controlPlaneUrl: cloudGrant.controlPlaneUrl,
93106
+ runtimeId: cloudGrant.runtimeId,
93107
+ grantToken: cloudGrant.grantToken
93108
+ };
93109
+ }
93110
+ const owner = yield* resolveCmmdOwnerSessionCredential(sql, { logPrefix: input.logPrefix });
93111
+ if (owner.kind === "no-session") return yield* new RuntimeReplicationClientError({
93112
+ kind: "auth",
93113
+ code: "CMMD_AUTH_REQUIRED",
93114
+ detail: "CMMD sign-in is required for runtime replication."
93115
+ });
93116
+ if (owner.kind === "no-credential") return yield* new RuntimeReplicationClientError({
93117
+ kind: "auth",
93118
+ code: "CMMD_AUTH_REQUIRED",
93119
+ detail: "CMMD REST credentials are unavailable for runtime replication."
93120
+ });
93121
+ return {
93122
+ kind: "owner-session",
93123
+ runtimeId: input.runtimeId,
93124
+ jwt: owner.jwt
93125
+ };
93126
+ });
93127
+ }
92858
93128
  const RuntimeReplicationClientLive = require_Schema$1.effect(RuntimeReplicationClient, require_Schema$1.gen(function* () {
92859
93129
  const sql = yield* require_SqlError.SqlClient;
92860
93130
  const config = yield* ServerConfig;
92861
93131
  const send = (input) => config.forgeCmmdRuntimeMode === true ? replicateWithRuntimeGrant(config, input) : replicateWithOwnerSession(sql, input);
92862
- return RuntimeReplicationClient.of({ send });
93132
+ const lane = (runtimeId) => resolveRuntimeLane(config, sql, {
93133
+ runtimeId,
93134
+ logPrefix: "lifecycle-intents"
93135
+ });
93136
+ return RuntimeReplicationClient.of({
93137
+ send,
93138
+ listPendingLifecycleIntents: ({ runtimeId }) => lane(runtimeId).pipe(require_Schema$1.flatMap((l) => listPendingLifecycleIntents(l))),
93139
+ acknowledgeLifecycleIntents: ({ runtimeId, intents }) => lane(runtimeId).pipe(require_Schema$1.flatMap((l) => acknowledgeLifecycleIntents(l, intents)))
93140
+ });
92863
93141
  }));
92864
93142
  //#endregion
92865
93143
  //#region src/runtimeReplication/Services/RuntimeReplicationOutbox.ts
@@ -93177,6 +93455,14 @@ function stableReplicaDigest(...values) {
93177
93455
  function replicaHydrationCommandId(runtimeId, generationId, threadId) {
93178
93456
  return CommandId.make("runtime-replica-hydration:" + stableReplicaDigest(runtimeId, generationId, threadId));
93179
93457
  }
93458
+ /**
93459
+ * One id per (runtime, thread, requested time): a restart between dispatch and
93460
+ * acknowledgement re-lists the same intent, and the engine's command receipts
93461
+ * turn the second dispatch into a no-op instead of a second settle.
93462
+ */
93463
+ function lifecycleIntentCommandId(runtimeId, threadId, requestedAt) {
93464
+ return CommandId.make("lifecycle-intent:" + stableReplicaDigest(runtimeId, threadId, requestedAt));
93465
+ }
93180
93466
  //#endregion
93181
93467
  //#region src/runtimeReplication/protocol.ts
93182
93468
  const EMPTY_RUNTIME_THREAD_HEAD_HASH = "sha256:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU";
@@ -94127,6 +94413,21 @@ function totalTokens(totals) {
94127
94413
  return totals.uncachedInputTokens + totals.cachedInputTokens + totals.cacheCreationTokens + totals.outputTokens;
94128
94414
  }
94129
94415
  /**
94416
+ * What a transcript record's own on-disk facts say it is a row of.
94417
+ *
94418
+ * Reuses exactly the facts `usageDrivers.ts`'s `isForgeAgent` reads to route a
94419
+ * record to the Forge agents lane, minus the "is this one of this
94420
+ * environment's own threads" gate: a Claude sidechain or a Codex subagent
94421
+ * rollout is a Subagent row regardless of which thread (if any) it hangs
94422
+ * under, so a subagent driven from outside Forge is still `subagent`, not a
94423
+ * plain Recorded-turn-shaped `turn`. Exported so the scan cache can recompute
94424
+ * the same value on decode instead of storing it as a redundant column.
94425
+ */
94426
+ function transcriptRecordKind(provider, sidechain, rootSessionId) {
94427
+ if (provider === "claude") return sidechain === true ? "subagent" : "turn";
94428
+ return rootSessionId !== void 0 ? "subagent" : "turn";
94429
+ }
94430
+ /**
94130
94431
  * Cheap substring gate applied before `JSON.parse`.
94131
94432
  *
94132
94433
  * Transcripts are mostly tool output; only a minority of lines carry usage. On
@@ -94195,6 +94496,7 @@ function parseClaudeLine(line, diagnostics) {
94195
94496
  const dedupeKey = claudeDedupeKey(stringAt(messageRecord, "id"), stringAt(record, "requestId"));
94196
94497
  const cost = record["costUSD"];
94197
94498
  const launcher = stringAt(record, "entrypoint");
94499
+ const sidechain = record["isSidechain"] === true;
94198
94500
  return {
94199
94501
  provider: "claude",
94200
94502
  timestampMs,
@@ -94203,8 +94505,9 @@ function parseClaudeLine(line, diagnostics) {
94203
94505
  totals: claudeTokenBuckets(usageRecord) ?? EMPTY_TOTALS,
94204
94506
  reportedCostUsd: typeof cost === "number" && Number.isFinite(cost) ? cost : null,
94205
94507
  dedupeKey,
94508
+ kind: transcriptRecordKind("claude", sidechain, void 0),
94206
94509
  ...launcher === null ? {} : { launcher },
94207
- ...record["isSidechain"] === true ? { sidechain: true } : {}
94510
+ ...sidechain ? { sidechain: true } : {}
94208
94511
  };
94209
94512
  }
94210
94513
  function initialCodexScanState() {
@@ -94321,6 +94624,7 @@ function parseCodexTokenCount(record, payloadRecord, state) {
94321
94624
  totals,
94322
94625
  reportedCostUsd: null,
94323
94626
  dedupeKey: null,
94627
+ kind: transcriptRecordKind("codex", void 0, state.rootSessionId),
94324
94628
  ...codexSessionFields(state)
94325
94629
  };
94326
94630
  }
@@ -94589,7 +94893,8 @@ var UsageAggregator = class {
94589
94893
  origin,
94590
94894
  sync,
94591
94895
  runtimeId,
94592
- driver
94896
+ driver,
94897
+ record.kind
94593
94898
  ].join("\0");
94594
94899
  const existing = this.#buckets.get(key);
94595
94900
  if (existing !== void 0) return existing;
@@ -94627,7 +94932,7 @@ var UsageAggregator = class {
94627
94932
  finish() {
94628
94933
  const buckets = [];
94629
94934
  for (const [key, bucket] of this.#buckets) {
94630
- const [day = "", hourStart = "", provider = "", model = "", origin = "", sync = "", runtimeId = "", driver = ""] = key.split("\0");
94935
+ const [day = "", hourStart = "", provider = "", model = "", origin = "", sync = "", runtimeId = "", driver = "", kind = ""] = key.split("\0");
94631
94936
  buckets.push({
94632
94937
  day,
94633
94938
  ...hourStart === "" ? {} : { hourStart },
@@ -94643,10 +94948,15 @@ var UsageAggregator = class {
94643
94948
  origin,
94644
94949
  ...sync === "" ? {} : { sync },
94645
94950
  ...runtimeId === "" ? {} : { runtimeId },
94646
- ...driver === "" ? {} : { driver }
94951
+ ...driver === "" ? {} : { driver },
94952
+ kind
94647
94953
  });
94648
94954
  }
94649
- buckets.sort((a, b) => bucketSortKey(a).localeCompare(bucketSortKey(b)));
94955
+ buckets.sort((a, b) => {
94956
+ const left = bucketSortKey(a);
94957
+ const right = bucketSortKey(b);
94958
+ return left < right ? -1 : left > right ? 1 : 0;
94959
+ });
94650
94960
  return {
94651
94961
  buckets,
94652
94962
  duplicatesDropped: this.#duplicatesDropped,
@@ -94664,7 +94974,8 @@ function bucketSortKey(bucket) {
94664
94974
  bucket.origin ?? "",
94665
94975
  bucket.sync ?? "",
94666
94976
  bucket.runtimeId ?? "",
94667
- bucket.driver ?? ""
94977
+ bucket.driver ?? "",
94978
+ bucket.kind ?? ""
94668
94979
  ].join("\0");
94669
94980
  }
94670
94981
  /**
@@ -95653,6 +95964,7 @@ function syncOf(sequence, options, threadId, events) {
95653
95964
  return sequence <= cursor.acknowledgedSequence ? "acknowledged" : "pending";
95654
95965
  }
95655
95966
  function recordOf(event, provider, sync, threadId, runtimeId) {
95967
+ const kind = event.usageKind ?? "turn";
95656
95968
  return {
95657
95969
  provider,
95658
95970
  timestampMs: Date.parse(event.occurredAt),
@@ -95661,6 +95973,7 @@ function recordOf(event, provider, sync, threadId, runtimeId) {
95661
95973
  totals: event.usage ?? EMPTY_TOTALS,
95662
95974
  reportedCostUsd: null,
95663
95975
  dedupeKey: `recorded:${threadId}:${event.turnId}:${event.usageKind ?? "turn"}:${event.subagentId ?? ""}:${event.model}`,
95976
+ kind,
95664
95977
  origin: "recorded",
95665
95978
  ...sync === void 0 ? {} : { sync },
95666
95979
  ...runtimeId === void 0 ? {} : { runtimeId },
@@ -96382,6 +96695,22 @@ async function readTranscriptRecords(filePath, provider) {
96382
96695
  //#endregion
96383
96696
  //#region src/usage/usageScanCache.ts
96384
96697
  /**
96698
+ * Durable per-file scan cache.
96699
+ *
96700
+ * Transcripts are append-only and a file that has not changed can never yield
96701
+ * different usage, so parsed records are keyed by `(size, mtime)` and reused.
96702
+ * Without this every server restart re-parses the whole window: seconds for a
96703
+ * 30-day scan, against milliseconds to reload this cache.
96704
+ *
96705
+ * Caching *per file* rather than per day is deliberate. It is timezone
96706
+ * independent, so changing the reporting zone does not invalidate anything, and
96707
+ * it keeps cross-file de-duplication exact: cached entries are de-duplicated
96708
+ * within their own file only, and the aggregator still applies the global
96709
+ * dedupe pass over the small surviving key set.
96710
+ *
96711
+ * @module usageScanCache
96712
+ */
96713
+ /**
96385
96714
  * Bumped whenever cached records could differ from what a fresh parse produces.
96386
96715
  *
96387
96716
  * Version 1 was written before `parseCodexLine` suppressed the parent history a
@@ -96527,6 +96856,7 @@ function decodeRecord(row, provider, tables) {
96527
96856
  },
96528
96857
  reportedCostUsd: finiteNumber(reportedCostUsd),
96529
96858
  dedupeKey: typeof dedupeKey === "string" ? dedupeKey : null,
96859
+ kind: transcriptRecordKind(provider, session.sidechain, session.rootSessionId),
96530
96860
  ...session
96531
96861
  };
96532
96862
  }
@@ -97491,7 +97821,7 @@ const resolveAutoBootstrapWelcomeTargets = require_Schema$1.gen(function* () {
97491
97821
  /**
97492
97822
  * Cloud-mode project recovery — runs only on cloud execution runtimes.
97493
97823
  * Scans `cloudProjectsRoot` (default
97494
- * /data/Projects) for git-repo subdirectories and registers any not yet in
97824
+ * /projects) for git-repo subdirectories and registers any not yet in
97495
97825
  * the orchestration engine. This is the cloud-mode replacement for the
97496
97826
  * gated `autoBootstrapProjectFromCwd` path: managed runtimes whose volume
97497
97827
  * already holds cloned repos surface them in the sidebar after restart.
@@ -99499,144 +99829,6 @@ function claudeWriteToken(env = process.env) {
99499
99829
  return accessor.read(env);
99500
99830
  }
99501
99831
  //#endregion
99502
- //#region src/usage/providerRateLimits.ts
99503
- /**
99504
- * In-process cache of the latest Claude 5h/7d rate-limit telemetry, decoded
99505
- * from the genuine Claude Agent SDK's own `rate_limit_event` messages
99506
- * (see ClaudeAdapter.ts). This is intentionally NOT a CMMD call site: CMMD
99507
- * must never replay a personal Claude OAuth token against api.anthropic.com
99508
- * from its own backend (see CMMD's personal-claude-delivery.ts) - the only
99509
- * legitimate source for this data is the real in-VM SDK session reporting it
99510
- * as a side effect of a real turn.
99511
- *
99512
- * Snapshots are fenced by the exact non-secret credential-generation hash.
99513
- * A Forge process can outlive an account reconnect, so a process-wide singleton
99514
- * without that fence can leak account A's windows into account B's session.
99515
- * The request-scoped route that reads this
99516
- * cache (apps/server/src/command/http.ts) is what actually forwards it to
99517
- * CMMD, using the request's own authenticated session - a background event
99518
- * pipeline has no such session to reuse safely.
99519
- */
99520
- /**
99521
- * The SDK only ever reports ONE window per event. Only `five_hour` and
99522
- * `seven_day` map to the two windows the Usage page shows; the
99523
- * per-model/overage variants (seven_day_opus, overage, ...) are ignored here
99524
- * on purpose rather than silently overwriting the plain 7-day figure.
99525
- */
99526
- function mapClaudeRateLimitInfo(info) {
99527
- if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
99528
- const kind = info.rateLimitType === "five_hour" ? "fiveHour" : info.rateLimitType === "seven_day" ? "sevenDay" : null;
99529
- if (!kind) return null;
99530
- return {
99531
- kind,
99532
- window: {
99533
- usedPercent: Math.round(info.utilization * 100),
99534
- resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
99535
- status: info.status
99536
- }
99537
- };
99538
- }
99539
- const SEVEN_DAY_MODEL_PREFIX = "seven_day_";
99540
- const SEVEN_DAY_OVERAGE_SUFFIX = "overage_included";
99541
- function capitalizeModelSuffix(suffix) {
99542
- return suffix.length === 0 ? suffix : suffix.charAt(0).toUpperCase() + suffix.slice(1);
99543
- }
99544
- /**
99545
- * Maps a per-model weekly SDKRateLimitInfo (`seven_day_<model>`, e.g.
99546
- * `seven_day_opus`) into a `ProviderUsageModelWindow`. `seven_day_overage_included`
99547
- * is not a per-model window (it reports overage-inclusive quota, not a
99548
- * specific model) and stays ignored here, same as plain `overage`.
99549
- */
99550
- function mapClaudeModelRateLimitInfo(info) {
99551
- if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
99552
- if (!info.rateLimitType?.startsWith(SEVEN_DAY_MODEL_PREFIX)) return null;
99553
- const suffix = info.rateLimitType.slice(10);
99554
- if (suffix.length === 0 || suffix === SEVEN_DAY_OVERAGE_SUFFIX) return null;
99555
- return {
99556
- model: capitalizeModelSuffix(suffix),
99557
- window: {
99558
- usedPercent: Math.round(info.utilization * 100),
99559
- resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
99560
- status: info.status
99561
- }
99562
- };
99563
- }
99564
- const cachedSnapshots = /* @__PURE__ */ new Map();
99565
- let localClaudeGenerationHash = null;
99566
- function setLocalClaudeUsageGeneration(generationId) {
99567
- localClaudeGenerationHash = (0, node_crypto.createHash)("sha256").update(generationId).digest("hex");
99568
- }
99569
- function currentClaudeUsageGenerationHash() {
99570
- const value = process.env.FORGE_PERSONAL_CLAUDE_GENERATION_HASH?.trim() ?? "";
99571
- return /^[a-f0-9]{64}$/.test(value) ? value : localClaudeGenerationHash;
99572
- }
99573
- function cacheKeyFor(generationHash, providerAccountId) {
99574
- return providerAccountId ? `${providerAccountId}:${generationHash}` : generationHash;
99575
- }
99576
- /**
99577
- * `observedAt` here is a placeholder, not an observation — it becomes
99578
- * meaningful only once a standard (five_hour/seven_day) window actually
99579
- * lands via `withStandardWindow`, which recomputes it from the retained
99580
- * windows' own observation times. A per-model-only cache (no standard window
99581
- * yet) still carries this placeholder, so callers should treat `observedAt`
99582
- * as trustworthy only once `fiveHour` or `sevenDay` is non-null.
99583
- */
99584
- function emptyCachedSnapshot(observedAt) {
99585
- return {
99586
- fiveHour: null,
99587
- sevenDay: null,
99588
- modelWindowsByModel: {},
99589
- observedAt,
99590
- fiveHourObservedAt: null,
99591
- sevenDayObservedAt: null
99592
- };
99593
- }
99594
- /** Oldest observation among the retained standard windows, so one fresh event cannot mask stale data. */
99595
- function oldestObservedAt(fiveHourObservedAt, sevenDayObservedAt) {
99596
- return [fiveHourObservedAt, sevenDayObservedAt].filter((value) => value !== null).toSorted()[0];
99597
- }
99598
- function withStandardWindow(previous, mapped, observedAt) {
99599
- const isFiveHour = mapped.kind === "fiveHour";
99600
- const fiveHourObservedAt = isFiveHour ? observedAt : previous.fiveHourObservedAt;
99601
- const sevenDayObservedAt = isFiveHour ? previous.sevenDayObservedAt : observedAt;
99602
- return {
99603
- ...previous,
99604
- fiveHour: isFiveHour ? mapped.window : previous.fiveHour,
99605
- sevenDay: isFiveHour ? previous.sevenDay : mapped.window,
99606
- fiveHourObservedAt,
99607
- sevenDayObservedAt,
99608
- observedAt: oldestObservedAt(fiveHourObservedAt, sevenDayObservedAt)
99609
- };
99610
- }
99611
- function withModelWindow(previous, mapped) {
99612
- return {
99613
- ...previous,
99614
- modelWindowsByModel: {
99615
- ...previous.modelWindowsByModel,
99616
- [mapped.model]: mapped.window
99617
- }
99618
- };
99619
- }
99620
- /**
99621
- * Merges a single-window update into the cached snapshot without clobbering
99622
- * the other windows. A per-model weekly report (`seven_day_<model>`) merges
99623
- * into `modelWindowsByModel` keyed by model, leaving every other model and
99624
- * the plain five_hour/seven_day windows untouched.
99625
- */
99626
- function recordClaudeRateLimitTelemetry(info, generationHash = currentClaudeUsageGenerationHash(), providerAccountId) {
99627
- if (generationHash === null) return;
99628
- const cacheKey = cacheKeyFor(generationHash, providerAccountId);
99629
- const observedAt = (/* @__PURE__ */ new Date()).toISOString();
99630
- const previous = cachedSnapshots.get(cacheKey) ?? emptyCachedSnapshot(observedAt);
99631
- const standard = mapClaudeRateLimitInfo(info);
99632
- if (standard) {
99633
- cachedSnapshots.set(cacheKey, withStandardWindow(previous, standard, observedAt));
99634
- return;
99635
- }
99636
- const model = mapClaudeModelRateLimitInfo(info);
99637
- if (model) cachedSnapshots.set(cacheKey, withModelWindow(previous, model));
99638
- }
99639
- //#endregion
99640
99832
  //#region src/providerAuth/ClaudeDeviceAuth.ts
99641
99833
  const AUTHORIZE_URL_PATTERN = /https:\/\/[^\s]*\/oauth\/authorize\?[^\s]+/u;
99642
99834
  const ANSI_ESCAPE_PATTERN$1 = new RegExp(String.raw`\x1B\[[0-?]*[ -/]*[@-~]`, "gu");
@@ -100151,7 +100343,6 @@ async function finalizeClaudeCredentialSync(input) {
100151
100343
  const providerAccountId = extractClaudeProviderAccountId(input.response);
100152
100344
  const credentialGenerationId = extractClaudeCredentialGenerationId(input.response);
100153
100345
  if (providerAccountId === null || credentialGenerationId === null) return null;
100154
- if (input.auth.path === USER_CLAUDE_CREDENTIAL_PATH) setLocalClaudeUsageGeneration(credentialGenerationId);
100155
100346
  return publishClaudeUsageAfterSync({
100156
100347
  auth: input.auth,
100157
100348
  providerAccountId,
@@ -147267,137 +147458,6 @@ const LocalAutomationRepositoryLive = require_Schema$1.effect(LocalAutomationRep
147267
147458
  */
147268
147459
  var CodexAdapter = class extends require_Schema$1.Service()("forge/provider/Services/CodexAdapter") {};
147269
147460
  //#endregion
147270
- //#region ../../packages/shared/src/model.ts
147271
- /** Check whether a capabilities object includes a given effort value. */
147272
- function hasEffortLevel(caps, value) {
147273
- return caps.reasoningEffortLevels.some((l) => l.value === value);
147274
- }
147275
- /** Return the default effort value for a capabilities object, or null if none. */
147276
- function getDefaultEffort(caps) {
147277
- return caps.reasoningEffortLevels.find((l) => l.isDefault)?.value ?? null;
147278
- }
147279
- /**
147280
- * Resolve a raw effort option against capabilities.
147281
- *
147282
- * Returns the effective effort value — the explicit value if supported and not
147283
- * prompt-injected, otherwise the model's default. Returns `undefined` only
147284
- * when the model has no effort levels at all.
147285
- *
147286
- * Prompt-injected efforts (e.g. "ultrathink") are excluded because they are
147287
- * applied via prompt text, not the effort API parameter.
147288
- */
147289
- function resolveEffort(caps, raw) {
147290
- const defaultValue = getDefaultEffort(caps);
147291
- const trimmed = typeof raw === "string" ? raw.trim() : null;
147292
- if (trimmed && !caps.promptInjectedEffortLevels.includes(trimmed) && hasEffortLevel(caps, trimmed)) return trimmed;
147293
- return defaultValue ?? void 0;
147294
- }
147295
- /** Check whether a capabilities object includes a given context window value. */
147296
- function hasContextWindowOption(caps, value) {
147297
- return caps.contextWindowOptions.some((o) => o.value === value);
147298
- }
147299
- /** Return the default context window value, or `null` if none is defined. */
147300
- function getDefaultContextWindow(caps) {
147301
- return caps.contextWindowOptions.find((o) => o.isDefault)?.value ?? null;
147302
- }
147303
- /**
147304
- * Resolve a raw `contextWindow` option against capabilities.
147305
- *
147306
- * Returns the effective context window value — the explicit value if supported,
147307
- * otherwise the model's default. Returns `undefined` only when the model has
147308
- * no context window options at all.
147309
- *
147310
- * Unlike effort levels (where the API has matching defaults), the context
147311
- * window requires an explicit API suffix (e.g. `[1m]`), so we always preserve
147312
- * the resolved value to avoid ambiguity between "user chose the default" and
147313
- * "not specified".
147314
- */
147315
- function resolveContextWindow(caps, raw) {
147316
- const defaultValue = getDefaultContextWindow(caps);
147317
- if (!raw) return defaultValue ?? void 0;
147318
- return hasContextWindowOption(caps, raw) ? raw : defaultValue ?? void 0;
147319
- }
147320
- function normalizeCodexModelOptionsWithCapabilities(caps, modelOptions) {
147321
- const reasoningEffort = resolveEffort(caps, modelOptions?.reasoningEffort);
147322
- const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
147323
- const nextOptions = {
147324
- ...reasoningEffort ? { reasoningEffort } : {},
147325
- ...fastMode !== void 0 ? { fastMode } : {}
147326
- };
147327
- return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
147328
- }
147329
- function normalizeClaudeModelOptionsWithCapabilities(caps, modelOptions) {
147330
- const effort = resolveEffort(caps, modelOptions?.effort);
147331
- const thinking = caps.supportsThinkingToggle ? modelOptions?.thinking : void 0;
147332
- const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
147333
- const contextWindow = resolveContextWindow(caps, modelOptions?.contextWindow);
147334
- const nextOptions = {
147335
- ...thinking !== void 0 ? { thinking } : {},
147336
- ...effort ? { effort } : {},
147337
- ...fastMode !== void 0 ? { fastMode } : {},
147338
- ...contextWindow !== void 0 ? { contextWindow } : {}
147339
- };
147340
- return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
147341
- }
147342
- function normalizeModelSlug(model, provider = "codex") {
147343
- if (typeof model !== "string") return null;
147344
- const trimmed = model.trim();
147345
- if (!trimmed) return null;
147346
- const aliases = MODEL_SLUG_ALIASES_BY_PROVIDER[provider];
147347
- const aliased = Object.prototype.hasOwnProperty.call(aliases, trimmed) ? aliases[trimmed] : void 0;
147348
- return typeof aliased === "string" ? aliased : trimmed;
147349
- }
147350
- /** Trim a string, returning null for empty/missing values. */
147351
- function trimOrNull(value) {
147352
- if (typeof value !== "string") return null;
147353
- return value.trim() || null;
147354
- }
147355
- /**
147356
- * Resolve the actual API model identifier from a model selection.
147357
- *
147358
- * Provider-aware: each provider can map `contextWindow` (or other options)
147359
- * to whatever the API requires — a model-id suffix, a separate parameter, etc.
147360
- * The canonical slug stored in the selection stays unchanged so the
147361
- * capabilities system keeps working.
147362
- *
147363
- * Expects `contextWindow` to already be resolved (via `resolveContextWindow`)
147364
- * to the effective value, not stripped to `undefined` for defaults.
147365
- */
147366
- function resolveApiModelId(modelSelection) {
147367
- switch (modelSelection.provider) {
147368
- case "claudeAgent": switch (modelSelection.options?.contextWindow) {
147369
- case "1m": return `${modelSelection.model}[1m]`;
147370
- default: return modelSelection.model;
147371
- }
147372
- default: return modelSelection.model;
147373
- }
147374
- }
147375
- function applyClaudePromptEffortPrefix(text, effort) {
147376
- const trimmed = text.trim();
147377
- if (!trimmed) return trimmed;
147378
- if (effort !== "ultrathink") return trimmed;
147379
- if (trimmed.startsWith("Ultrathink:")) return trimmed;
147380
- return `Ultrathink:\n${trimmed}`;
147381
- }
147382
- function getRawProviderOptionSelectionValue(selections, id) {
147383
- return selections?.find((candidate) => candidate.id === id)?.value;
147384
- }
147385
- function getProviderOptionSelectionValue(selections, id) {
147386
- return getRawProviderOptionSelectionValue(selections, id);
147387
- }
147388
- function getProviderOptionStringSelectionValue(selections, id) {
147389
- const value = getProviderOptionSelectionValue(selections, id);
147390
- return typeof value === "string" ? value : void 0;
147391
- }
147392
- function flatProviderOptions(selection) {
147393
- if (!selection) return void 0;
147394
- if (selection.provider !== "cursor" && selection.provider !== "opencode") return void 0;
147395
- return selection.options;
147396
- }
147397
- function getModelSelectionStringOptionValue(selection, id) {
147398
- return getProviderOptionStringSelectionValue(flatProviderOptions(selection), id);
147399
- }
147400
- //#endregion
147401
147461
  //#region src/provider/codexCliVersion.ts
147402
147462
  const CODEX_VERSION_PATTERN = /\bv?(\d+\.\d+(?:\.\d+)?(?:-[0-9A-Za-z.-]+)?)\b/;
147403
147463
  const MINIMUM_CODEX_CLI_VERSION = "0.37.0";
@@ -148052,6 +148112,213 @@ async function probeCodexDiscovery(input) {
148052
148112
  });
148053
148113
  }
148054
148114
  //#endregion
148115
+ //#region ../../packages/shared/src/model.ts
148116
+ /** Check whether a capabilities object includes a given effort value. */
148117
+ function hasEffortLevel(caps, value) {
148118
+ return caps.reasoningEffortLevels.some((l) => l.value === value);
148119
+ }
148120
+ /** Return the default effort value for a capabilities object, or null if none. */
148121
+ function getDefaultEffort(caps) {
148122
+ return caps.reasoningEffortLevels.find((l) => l.isDefault)?.value ?? null;
148123
+ }
148124
+ /**
148125
+ * Resolve a raw effort option against capabilities.
148126
+ *
148127
+ * Returns the effective effort value — the explicit value if supported and not
148128
+ * prompt-injected, otherwise the model's default. Returns `undefined` only
148129
+ * when the model has no effort levels at all.
148130
+ *
148131
+ * Prompt-injected efforts (e.g. "ultrathink") are excluded because they are
148132
+ * applied via prompt text, not the effort API parameter.
148133
+ */
148134
+ function resolveEffort(caps, raw) {
148135
+ const defaultValue = getDefaultEffort(caps);
148136
+ const trimmed = typeof raw === "string" ? raw.trim() : null;
148137
+ if (trimmed && !caps.promptInjectedEffortLevels.includes(trimmed) && hasEffortLevel(caps, trimmed)) return trimmed;
148138
+ return defaultValue ?? void 0;
148139
+ }
148140
+ /** Check whether a capabilities object includes a given context window value. */
148141
+ function hasContextWindowOption(caps, value) {
148142
+ return caps.contextWindowOptions.some((o) => o.value === value);
148143
+ }
148144
+ /** Return the default context window value, or `null` if none is defined. */
148145
+ function getDefaultContextWindow(caps) {
148146
+ return caps.contextWindowOptions.find((o) => o.isDefault)?.value ?? null;
148147
+ }
148148
+ /**
148149
+ * Resolve a raw `contextWindow` option against capabilities.
148150
+ *
148151
+ * Returns the effective context window value — the explicit value if supported,
148152
+ * otherwise the model's default. Returns `undefined` only when the model has
148153
+ * no context window options at all.
148154
+ *
148155
+ * Unlike effort levels (where the API has matching defaults), the context
148156
+ * window requires an explicit API suffix (e.g. `[1m]`), so we always preserve
148157
+ * the resolved value to avoid ambiguity between "user chose the default" and
148158
+ * "not specified".
148159
+ */
148160
+ function resolveContextWindow(caps, raw) {
148161
+ const defaultValue = getDefaultContextWindow(caps);
148162
+ if (!raw) return defaultValue ?? void 0;
148163
+ return hasContextWindowOption(caps, raw) ? raw : defaultValue ?? void 0;
148164
+ }
148165
+ function normalizeCodexModelOptionsWithCapabilities(caps, modelOptions) {
148166
+ const reasoningEffort = resolveEffort(caps, modelOptions?.reasoningEffort);
148167
+ const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
148168
+ const nextOptions = {
148169
+ ...reasoningEffort ? { reasoningEffort } : {},
148170
+ ...fastMode !== void 0 ? { fastMode } : {}
148171
+ };
148172
+ return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
148173
+ }
148174
+ function normalizeClaudeModelOptionsWithCapabilities(caps, modelOptions) {
148175
+ const effort = resolveEffort(caps, modelOptions?.effort);
148176
+ const thinking = caps.supportsThinkingToggle ? modelOptions?.thinking : void 0;
148177
+ const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
148178
+ const contextWindow = resolveContextWindow(caps, modelOptions?.contextWindow);
148179
+ const nextOptions = {
148180
+ ...thinking !== void 0 ? { thinking } : {},
148181
+ ...effort ? { effort } : {},
148182
+ ...fastMode !== void 0 ? { fastMode } : {},
148183
+ ...contextWindow !== void 0 ? { contextWindow } : {}
148184
+ };
148185
+ return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
148186
+ }
148187
+ function normalizeModelSlug(model, provider = "codex") {
148188
+ if (typeof model !== "string") return null;
148189
+ const trimmed = model.trim();
148190
+ if (!trimmed) return null;
148191
+ const aliases = MODEL_SLUG_ALIASES_BY_PROVIDER[provider];
148192
+ const aliased = Object.prototype.hasOwnProperty.call(aliases, trimmed) ? aliases[trimmed] : void 0;
148193
+ return typeof aliased === "string" ? aliased : trimmed;
148194
+ }
148195
+ /** Trim a string, returning null for empty/missing values. */
148196
+ function trimOrNull(value) {
148197
+ if (typeof value !== "string") return null;
148198
+ return value.trim() || null;
148199
+ }
148200
+ /**
148201
+ * Resolve the actual API model identifier from a model selection.
148202
+ *
148203
+ * Provider-aware: each provider can map `contextWindow` (or other options)
148204
+ * to whatever the API requires — a model-id suffix, a separate parameter, etc.
148205
+ * The canonical slug stored in the selection stays unchanged so the
148206
+ * capabilities system keeps working.
148207
+ *
148208
+ * Expects `contextWindow` to already be resolved (via `resolveContextWindow`)
148209
+ * to the effective value, not stripped to `undefined` for defaults.
148210
+ */
148211
+ function resolveApiModelId(modelSelection) {
148212
+ switch (modelSelection.provider) {
148213
+ case "claudeAgent": switch (modelSelection.options?.contextWindow) {
148214
+ case "1m": return `${modelSelection.model}[1m]`;
148215
+ default: return modelSelection.model;
148216
+ }
148217
+ default: return modelSelection.model;
148218
+ }
148219
+ }
148220
+ function applyClaudePromptEffortPrefix(text, effort) {
148221
+ const trimmed = text.trim();
148222
+ if (!trimmed) return trimmed;
148223
+ if (effort !== "ultrathink") return trimmed;
148224
+ if (trimmed.startsWith("Ultrathink:")) return trimmed;
148225
+ return `Ultrathink:\n${trimmed}`;
148226
+ }
148227
+ function getRawProviderOptionSelectionValue(selections, id) {
148228
+ return selections?.find((candidate) => candidate.id === id)?.value;
148229
+ }
148230
+ function getProviderOptionSelectionValue(selections, id) {
148231
+ return getRawProviderOptionSelectionValue(selections, id);
148232
+ }
148233
+ function getProviderOptionStringSelectionValue(selections, id) {
148234
+ const value = getProviderOptionSelectionValue(selections, id);
148235
+ return typeof value === "string" ? value : void 0;
148236
+ }
148237
+ function flatProviderOptions(selection) {
148238
+ if (!selection) return void 0;
148239
+ if (selection.provider !== "cursor" && selection.provider !== "opencode") return void 0;
148240
+ return selection.options;
148241
+ }
148242
+ function getModelSelectionStringOptionValue(selection, id) {
148243
+ return getProviderOptionStringSelectionValue(flatProviderOptions(selection), id);
148244
+ }
148245
+ function acceptableModelSlug(value) {
148246
+ const trimmed = value?.trim();
148247
+ if (!trimmed || trimmed.length > 120) return;
148248
+ return trimmed;
148249
+ }
148250
+ /**
148251
+ * Order the credential's model scope: selected model first, then the catalog,
148252
+ * deduplicated and capped.
148253
+ *
148254
+ * Returns `undefined` when there is no catalog to widen to, which is the signal
148255
+ * to send the old single-model body. A slug CMMD would refuse is dropped rather
148256
+ * than sent, because one bad entry 400s the whole mint and takes the session
148257
+ * with it.
148258
+ */
148259
+ function providerEgressModelScope(model, models) {
148260
+ const catalog = (models ?? []).map(acceptableModelSlug).filter((slug) => slug !== void 0);
148261
+ if (catalog.length === 0) return;
148262
+ const selected = acceptableModelSlug(model);
148263
+ const ordered = new Set(selected ? [selected] : []);
148264
+ for (const slug of catalog) {
148265
+ if (ordered.size >= 32) break;
148266
+ ordered.add(slug);
148267
+ }
148268
+ return [...ordered];
148269
+ }
148270
+ //#endregion
148271
+ //#region src/provider/codexCredentialModelScope.ts
148272
+ /**
148273
+ * Which Codex models one workspace egress credential has to cover.
148274
+ *
148275
+ * FOR-36501: the credential was scoped to the model the user picked, and the
148276
+ * Codex app-server holds one credential for the whole process. A turn on
148277
+ * gpt-6-astra that called `spawn_agent` with gpt-5.6-terra therefore lost the
148278
+ * child to a 401 before it spent a token. The subagent model is the model's own
148279
+ * choice in the tool arguments, so Forge cannot predict it and has to scope the
148280
+ * credential to the catalog a spawn can pick from.
148281
+ *
148282
+ * The catalog is the built-in Codex list, which is what the picker offers. It
148283
+ * includes the Spark model even though only a Pro account may call it: the
148284
+ * account snapshot is not resolved at issue time in workspace mode, and CMMD
148285
+ * still decides per call which models the account may use, so a slug in the
148286
+ * scope is permission to ask, never permission to spend.
148287
+ */
148288
+ /**
148289
+ * Normalize a Codex model slug to the one the app-server and the mint route use.
148290
+ *
148291
+ * Lives here rather than in codexAppServerManager.ts so the catalog builder can
148292
+ * use it without importing the manager back. The manager re-exports it, which is
148293
+ * where every existing caller still reads it from.
148294
+ */
148295
+ function normalizeCodexModelSlug(model, preferredId) {
148296
+ const normalized = normalizeModelSlug(model);
148297
+ if (!normalized) return;
148298
+ if (preferredId?.endsWith("-codex") && preferredId !== normalized) return preferredId;
148299
+ return normalized;
148300
+ }
148301
+ /** The model a proxy token is minted for when the thread names none. */
148302
+ function resolveCodexProviderProxyTokenModel(model) {
148303
+ const displaySlug = model?.trim().toLowerCase().replace(/\s+/g, "-");
148304
+ return normalizeCodexModelSlug(displaySlug) ?? "gpt-6-astra";
148305
+ }
148306
+ /** Every built-in Codex slug a `spawn_agent` call can name. */
148307
+ function codexCredentialModelCatalog() {
148308
+ return CODEX_BUILT_IN_MODELS.map((model) => normalizeCodexModelSlug(model.slug) ?? model.slug);
148309
+ }
148310
+ /**
148311
+ * The `models` list to mint a Codex session credential with.
148312
+ *
148313
+ * `undefined` means the catalog is unknown, and the caller then sends `model`
148314
+ * alone, exactly as before this card. That is the only safe answer: an empty
148315
+ * list would narrow the credential rather than widen it.
148316
+ */
148317
+ function buildCodexCredentialModelScope(input) {
148318
+ const catalog = (input.catalogModels ?? codexCredentialModelCatalog()).map((slug) => normalizeCodexModelSlug(slug) ?? slug).filter((slug) => slug.trim().length > 0);
148319
+ return providerEgressModelScope(input.selectedModel, catalog);
148320
+ }
148321
+ //#endregion
148055
148322
  //#region src/egress/providerDeliveryReceipt.ts
148056
148323
  const PROVIDER_ACCOUNT_IDENTITY$2 = /^pai_v1_[A-Za-z0-9_-]{43}$/;
148057
148324
  const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
@@ -148303,6 +148570,21 @@ function runtimeProviderEgressBaseUrl(provider, controlPlaneUrl) {
148303
148570
  anthropic: "/api/provider-egress/anthropic"
148304
148571
  }[provider]}`;
148305
148572
  }
148573
+ /**
148574
+ * The model fields of a mint body.
148575
+ *
148576
+ * `model` stays the single selected model, which is what CMMD runs its
148577
+ * post-mint constraint check on. `models` appears only when the caller knows a
148578
+ * catalog, so a caller that does not know one sends exactly the body it sent
148579
+ * before FOR-36501.
148580
+ */
148581
+ function providerEgressModelBodyFields(input) {
148582
+ const scope = providerEgressModelScope(input.model, input.models);
148583
+ return {
148584
+ ...input.model ? { model: input.model } : {},
148585
+ ...scope ? { models: scope } : {}
148586
+ };
148587
+ }
148306
148588
  const issueProviderEgressToken = (input) => issueProviderEgressCredential(input).pipe(require_Schema$1.map((credential) => credential.token));
148307
148589
  const issueProviderEgressCredential = (input) => require_Schema$1.tryPromise({
148308
148590
  try: async () => {
@@ -148326,7 +148608,7 @@ async function issueCmmdRuntimeProviderEgressCredential(input) {
148326
148608
  token: runtimeGrantToken,
148327
148609
  body: JSON.stringify({
148328
148610
  provider: input.provider,
148329
- ...input.model ? { model: input.model } : {},
148611
+ ...providerEgressModelBodyFields(input),
148330
148612
  ...input.provider === "openai" && input.providerAccountId ? { provider_account_id: input.providerAccountId } : {}
148331
148613
  })
148332
148614
  });
@@ -148442,7 +148724,7 @@ function issueCmmdLocalUserProviderEgressCredential(input) {
148442
148724
  },
148443
148725
  body: JSON.stringify({
148444
148726
  provider: input.provider,
148445
- ...input.model ? { model: input.model } : {},
148727
+ ...providerEgressModelBodyFields(input),
148446
148728
  ...input.provider === "openai" && input.providerAccountId ? { provider_account_id: input.providerAccountId } : {},
148447
148729
  client: "local-desktop",
148448
148730
  sessionId,
@@ -148825,16 +149107,6 @@ function mapCodexRuntimeMode(runtimeMode) {
148825
149107
  async function killChildTree(child) {
148826
149108
  await killCodexChildProcess(child);
148827
149109
  }
148828
- function normalizeCodexModelSlug(model, preferredId) {
148829
- const normalized = normalizeModelSlug(model);
148830
- if (!normalized) return;
148831
- if (preferredId?.endsWith("-codex") && preferredId !== normalized) return preferredId;
148832
- return normalized;
148833
- }
148834
- function resolveCodexProviderProxyTokenModel(model) {
148835
- const displaySlug = model?.trim().toLowerCase().replace(/\s+/g, "-");
148836
- return normalizeCodexModelSlug(displaySlug) ?? "gpt-6-astra";
148837
- }
148838
149110
  function buildCodexCollaborationMode(input) {
148839
149111
  if (input.interactionMode === void 0) return;
148840
149112
  const model = normalizeCodexModelSlug(input.model) ?? "gpt-6-astra";
@@ -149385,9 +149657,11 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
149385
149657
  const proxyConfig = getOpenAiProviderEgressProxyConfig({ allowLocalUser: true });
149386
149658
  if (proxyConfig.mode === "disabled") return null;
149387
149659
  if (proxyConfig.mode === "misconfigured") throw new ProviderEgressTokenError({ message: proxyConfig.message });
149660
+ const models = buildCodexCredentialModelScope({ selectedModel: input.model });
149388
149661
  return await require_Schema$1.runPromise(issueProviderEgressCredential({
149389
149662
  provider: "openai",
149390
149663
  model: input.model,
149664
+ ...models ? { models } : {},
149391
149665
  threadId: input.threadId,
149392
149666
  ...input.providerAccountId ? { providerAccountId: input.providerAccountId } : {}
149393
149667
  }));
@@ -149780,13 +150054,40 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
149780
150054
  if (!providerConversationId) return;
149781
150055
  return context.collabReceiverTurns.get(providerConversationId);
149782
150056
  }
150057
+ /**
150058
+ * The child threads one thread item says the turn spawned.
150059
+ *
150060
+ * Two item shapes name a child, and which one arrives depends on the Codex
150061
+ * build. `CollabAgentToolCallThreadItem` lists `receiverThreadIds`, which
150062
+ * "in case of spawn operation ... corresponds to the newly spawned agent".
150063
+ * `SubAgentActivityThreadItem` names a single `agentThreadId` and is what a
150064
+ * `spawn_agent` call reports on codex-cli 0.152/0.153: measured on the
150065
+ * packaged desktop on 2026-09-06, the spawn arrived as `SubAgentActivity`
150066
+ * (`kind: started`) and the only collab tool call that followed was the
150067
+ * `wait`, whose `receiverThreadIds` was empty. Reading only the collab item
150068
+ * left the child unmapped, so its spend was published as a second turn row
150069
+ * under the child's own turn id instead of a subagent row under the parent's.
150070
+ *
150071
+ * `SubAgentActivityThreadItem` has no `model` field, so a `completed` report
150072
+ * for a child a collab call already named must not blank the model out; the
150073
+ * caller's `model ?? known` merge is what keeps it.
150074
+ */
150075
+ readSpawnedThreadIds(item, itemType) {
150076
+ if (itemType === "subAgentActivity") {
150077
+ const agentThreadId = this.readString(item, "agentThreadId");
150078
+ return agentThreadId ? [agentThreadId] : [];
150079
+ }
150080
+ if (itemType !== "collabAgentToolCall") return [];
150081
+ return this.readArray(item, "receiverThreadIds")?.map((value) => typeof value === "string" ? value : null).filter((value) => value !== null) ?? [];
150082
+ }
149783
150083
  rememberCollabReceiverTurns(context, params, parentTurnId) {
149784
150084
  if (!parentTurnId) return;
149785
150085
  const payload = this.readObject(params);
149786
150086
  const item = this.readObject(payload, "item") ?? payload;
149787
- if ((this.readString(item, "type") ?? this.readString(item, "kind")) !== "collabAgentToolCall") return;
150087
+ const itemType = this.readString(item, "type") ?? this.readString(item, "kind");
150088
+ const receiverThreadIds = this.readSpawnedThreadIds(item, itemType);
150089
+ if (receiverThreadIds.length === 0) return;
149788
150090
  const model = this.readString(item, "model");
149789
- const receiverThreadIds = this.readArray(item, "receiverThreadIds")?.map((value) => typeof value === "string" ? value : null).filter((value) => value !== null) ?? [];
149790
150091
  for (const receiverThreadId of receiverThreadIds) {
149791
150092
  const known = context.collabReceiverTurns.get(receiverThreadId)?.model;
149792
150093
  const resolved = model ?? known;
@@ -149802,8 +150103,8 @@ var CodexAppServerManager = class extends node_events.EventEmitter {
149802
150103
  * Codex reports a child thread's tokens on the parent's own connection:
149803
150104
  * `ThreadTokenUsageUpdatedNotification` requires `threadId` and `turnId` and
149804
150105
  * names the child thread for a child, and `Thread.parentThreadId` is "only
149805
- * set if this thread is a subagent" (codex 0.144.6 app-server protocol
149806
- * schema). Every other child notification is suppressed so it cannot replace
150106
+ * set if this thread is a subagent" (still true of the codex-cli 0.153
150107
+ * app-server protocol schema). Every other child notification is suppressed so it cannot replace
149807
150108
  * the parent turn; this one is not, because the tokens belong on the ledger.
149808
150109
  * The method is Forge's own rather than the protocol's, because the payload
149809
150110
  * carries what the Usage row needs rather than what the notification held.
@@ -207547,36 +207848,23 @@ function mapCodexThreadNameUpdatedEvent(event, canonicalThreadId, payload) {
207547
207848
  }
207548
207849
  }];
207549
207850
  }
207550
- /** One provider call's spend, from Codex's `last_token_usage`. */
207551
- function codexTurnUsageDelta(value) {
207552
- const usage = asObject$2(value);
207553
- return codexUsageBuckets(usage?.last_token_usage ?? usage?.last, "call-delta");
207554
- }
207555
207851
  /**
207556
- * One Codex token report in Forge's disjoint buckets. Codex reports
207557
- * `input_tokens` inclusive of the cached and cache-write portions, so the
207558
- * uncached bucket is the remainder; reasoning is reported inside output and is
207559
- * surfaced separately without being added again. Mirrors `parseCodexLine` in
207852
+ * One provider call's spend, from Codex's `last_token_usage`. Reads the
207853
+ * buckets via `codexTokenBuckets`, the shared home of the Claude/Codex
207854
+ * disjointness rule (providerTokenBuckets.ts): Codex reports `input_tokens`
207855
+ * inclusive of the cached and cache-write portions, so the uncached bucket is
207856
+ * the remainder, and reasoning is reported inside output and surfaced
207857
+ * separately without being added again. Mirrors `parseCodexLine` in
207560
207858
  * usage/usageTranscripts.ts so a Recorded turn and a scanned transcript agree
207561
207859
  * on the same numbers.
207562
207860
  */
207563
- function codexUsageBuckets(value, scope) {
207564
- const lastUsage = asObject$2(value);
207565
- if (!lastUsage) return void 0;
207566
- const int = (key, alt) => Math.max(0, Math.trunc(asNumber(lastUsage[key]) ?? asNumber(lastUsage[alt]) ?? 0));
207567
- const inputTokens = int("input_tokens", "inputTokens");
207568
- const cachedInputTokens = int("cached_input_tokens", "cachedInputTokens");
207569
- const cacheCreationTokens = int("cache_write_input_tokens", "cacheWriteInputTokens");
207570
- const outputTokens = int("output_tokens", "outputTokens");
207571
- if (inputTokens + cachedInputTokens + cacheCreationTokens + outputTokens === 0) return void 0;
207572
- return {
207573
- scope,
207574
- uncachedInputTokens: Math.max(0, inputTokens - cachedInputTokens - cacheCreationTokens),
207575
- cachedInputTokens,
207576
- cacheCreationTokens,
207577
- outputTokens,
207578
- reasoningTokens: Math.min(outputTokens, int("reasoning_output_tokens", "reasoningOutputTokens"))
207579
- };
207861
+ function codexTurnUsageDelta(value) {
207862
+ const usage = asObject$2(value);
207863
+ const buckets = codexTokenBuckets(usage?.last_token_usage ?? usage?.last);
207864
+ return buckets ? {
207865
+ scope: "call-delta",
207866
+ ...buckets
207867
+ } : void 0;
207580
207868
  }
207581
207869
  function mapCodexThreadTokenUsageEvent(event, canonicalThreadId, payload) {
207582
207870
  const tokenUsage = asObject$2(payload?.tokenUsage);
@@ -207599,11 +207887,14 @@ function mapCodexThreadTokenUsageEvent(event, canonicalThreadId, payload) {
207599
207887
  *
207600
207888
  * The source is the live app-server protocol, not a rollout read: Codex sends
207601
207889
  * `thread/tokenUsage/updated` for a child thread on the parent's own
207602
- * connection (0.144.6 schema: `ThreadTokenUsageUpdatedNotification` requires
207603
- * `threadId` and `turnId`, `Thread.parentThreadId` is set only for a subagent,
207604
- * and `CollabAgentToolCallThreadItem` names `receiverThreadIds` and the
207605
- * spawned agent's `model`), and `codexAppServerManager` already tracked those
207606
- * child threads to route their notifications onto the parent turn.
207890
+ * connection (`ThreadTokenUsageUpdatedNotification` requires `threadId` and
207891
+ * `turnId`, and `Thread.parentThreadId` is set only for a subagent), and
207892
+ * `codexAppServerManager` already tracked those child threads to route their
207893
+ * notifications onto the parent turn. It learns a child from whichever item
207894
+ * the running Codex build uses to announce a spawn: the
207895
+ * `receiverThreadIds` of a `CollabAgentToolCallThreadItem`, which also names
207896
+ * the spawned agent's `model`, or the `agentThreadId` of a
207897
+ * `SubAgentActivityThreadItem`, which names no model.
207607
207898
  *
207608
207899
  * The row carries no context-meter snapshot and no `turnUsage`: the parent's
207609
207900
  * own row is never re-summed with its children. It carries the call's delta
@@ -208267,6 +208558,7 @@ const DEFAULT_PUBLIC_PROVIDER_ERROR = "CMMD is temporarily unavailable. Check th
208267
208558
  function categorizePublicProviderError(message) {
208268
208559
  if (!message) return null;
208269
208560
  const m = message.toLowerCase();
208561
+ if (/\bforge_provider_model_not_allowed\b/.test(m) || /\bnot\s+scoped\s+to\s+the\s+requested\s+model\b/.test(m)) return "The workspace AI credential does not cover the model this turn asked for. Retry, or pick that model for the thread.";
208270
208562
  if (/\bmodel\b[\s\S]*\b(not\s+(found|available|supported)|does\s+not\s+exist|unsupported|invalid|unknown)\b/.test(m) || /\b(unsupported|unknown|invalid)\b[\s\S]*\bmodel\b/.test(m) || /\b(model_not_found|invalid_model|model_not_supported)\b/.test(m)) return "The selected model isn't available right now. Pick a different model and retry.";
208271
208563
  if (/\b(rate[\s-]?limit|too\s+many\s+requests|quota|insufficient_quota)\b/.test(m) || /\b429\b/.test(m)) return "The AI service is rate-limited or out of quota. Wait a moment and retry.";
208272
208564
  if (/\b(unauthorized|forbidden|authentication\s+(failed|error|required)|invalid\s+api\s+key|expired\s+(token|credential))\b/.test(m) || /\b40[13]\b/.test(m)) return "Workspace AI authentication failed. Reconnect the workspace and retry.";
@@ -208490,7 +208782,8 @@ const CODE_BY_UPSTREAM_REASON$1 = {
208490
208782
  credential_expired_refreshing: "CREDENTIAL_EXPIRED_REFRESHING",
208491
208783
  credential_reconnect_required: "CREDENTIAL_RECONNECT_REQUIRED",
208492
208784
  credential_not_connected: "CREDENTIAL_RECONNECT_REQUIRED",
208493
- credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED"
208785
+ credential_generation_not_applied: "CREDENTIAL_GENERATION_NOT_APPLIED",
208786
+ runtime_unavailable: "RUNTIME_UNAVAILABLE"
208494
208787
  };
208495
208788
  const CLAUDE_NATIVE_CREDENTIAL_UNUSABLE_COPY = "The delivered Claude credential is unavailable or unusable in this runtime.";
208496
208789
  /**
@@ -208553,10 +208846,17 @@ function claudeNativeCredentialUnusableMessage() {
208553
208846
  * CMMD writes this marker when it activates a personal Claude subscription
208554
208847
  * inside a running sprite. Activation always happens after boot, so a
208555
208848
  * boot-time env var alone cannot reflect it (FOR-36249).
208849
+ *
208850
+ * CMMD names the file in the Service env (FORGE_PERSONAL_CLAUDE_MARKER_PATH).
208851
+ * Without that, the marker sits directly under FORGE_HOME, which is the same
208852
+ * guest home CMMD derives every sprite path from. A server with neither has no
208853
+ * sprite home to look in, and a desktop never has a marker, so it reads none.
208556
208854
  */
208557
- const PERSONAL_CLAUDE_IN_VM_MARKER_PATH = "/data/.forge-personal-claude-in-vm";
208855
+ const PERSONAL_CLAUDE_IN_VM_MARKER_NAME = ".forge-personal-claude-in-vm";
208558
208856
  function markerPath(env) {
208559
- return env.FORGE_PERSONAL_CLAUDE_MARKER_PATH || PERSONAL_CLAUDE_IN_VM_MARKER_PATH;
208857
+ if (env.FORGE_PERSONAL_CLAUDE_MARKER_PATH) return env.FORGE_PERSONAL_CLAUDE_MARKER_PATH;
208858
+ if (env.FORGE_HOME) return (0, node_path.join)(env.FORGE_HOME, PERSONAL_CLAUDE_IN_VM_MARKER_NAME);
208859
+ return null;
208560
208860
  }
208561
208861
  /**
208562
208862
  * True when this runtime should offer the personal Claude subscription lane.
@@ -208569,8 +208869,10 @@ function markerPath(env) {
208569
208869
  */
208570
208870
  function personalClaudeInVmEnabled(env = process.env) {
208571
208871
  if (env.FORGE_PERSONAL_CLAUDE_IN_VM === "true") return true;
208872
+ const marker = markerPath(env);
208873
+ if (!marker) return false;
208572
208874
  try {
208573
- return (0, node_fs.existsSync)(markerPath(env));
208875
+ return (0, node_fs.existsSync)(marker);
208574
208876
  } catch {
208575
208877
  return false;
208576
208878
  }
@@ -210108,9 +210410,6 @@ function buildClaudeSessionContext(input) {
210108
210410
  query: input.queryRuntime,
210109
210411
  streamFiber: void 0,
210110
210412
  startedAt: input.startedAt,
210111
- recordsPersonalUsageTelemetry: input.recordsPersonalUsageTelemetry,
210112
- personalUsageGenerationHash: input.personalUsageGenerationHash,
210113
- personalUsageProviderAccountId: input.personalUsageProviderAccountId,
210114
210413
  basePermissionMode: input.permissionMode,
210115
210414
  resumeSessionId: input.sessionId,
210116
210415
  pendingApprovals: input.pendingApprovals,
@@ -210468,26 +210767,18 @@ function finiteNumberFieldOrZero(usage, key) {
210468
210767
  }
210469
210768
  /**
210470
210769
  * The whole turn's spend from the SDK result message, cache split intact.
210471
- * Claude reports `input_tokens` exclusive of the cached and cache-creation
210472
- * portions, so the buckets are already disjoint. Claude does not report
210473
- * reasoning separately.
210770
+ * Reads the buckets via `claudeTokenBuckets`, the shared home of the
210771
+ * Claude/Codex disjointness rule (providerTokenBuckets.ts): Claude reports
210772
+ * `input_tokens` exclusive of the cached and cache-creation portions, so the
210773
+ * buckets are already disjoint, and Claude does not report reasoning
210774
+ * separately.
210474
210775
  */
210475
210776
  function claudeTurnUsageTotal(value) {
210476
- const usage = asClaudeUsageRecord(value);
210477
- if (!usage) return void 0;
210478
- const uncachedInputTokens = finiteNumberFieldOrZero(usage, "input_tokens");
210479
- const cachedInputTokens = finiteNumberFieldOrZero(usage, "cache_read_input_tokens");
210480
- const cacheCreationTokens = finiteNumberFieldOrZero(usage, "cache_creation_input_tokens");
210481
- const outputTokens = finiteNumberFieldOrZero(usage, "output_tokens");
210482
- if (uncachedInputTokens + cachedInputTokens + cacheCreationTokens + outputTokens <= 0) return;
210483
- return {
210777
+ const buckets = claudeTokenBuckets(value);
210778
+ return buckets ? {
210484
210779
  scope: "turn-total",
210485
- uncachedInputTokens: Math.trunc(uncachedInputTokens),
210486
- cachedInputTokens: Math.trunc(cachedInputTokens),
210487
- cacheCreationTokens: Math.trunc(cacheCreationTokens),
210488
- outputTokens: Math.trunc(outputTokens),
210489
- reasoningTokens: 0
210490
- };
210780
+ ...buckets
210781
+ } : void 0;
210491
210782
  }
210492
210783
  const EMPTY_MODEL_USAGE_BUCKETS = {
210493
210784
  uncachedInputTokens: 0,
@@ -210500,20 +210791,14 @@ function bucketsTotal(buckets) {
210500
210791
  return buckets.uncachedInputTokens + buckets.cachedInputTokens + buckets.cacheCreationTokens + buckets.outputTokens;
210501
210792
  }
210502
210793
  /**
210503
- * One `ModelUsage` entry as buckets. `ModelUsage` names its fields in
210504
- * camelCase, unlike `result.usage`, so this cannot share `claudeTurnUsageTotal`.
210505
- * Claude reports `inputTokens` exclusive of the cached and cache-creation
210506
- * portions, so the buckets are already disjoint, and it reports no reasoning.
210794
+ * One `ModelUsage` entry as buckets, via `claudeTokenBuckets`. `ModelUsage`
210795
+ * names its fields in camelCase, unlike `result.usage`, but `claudeTokenBuckets`
210796
+ * already reads both spellings. Claude reports `inputTokens` exclusive of the
210797
+ * cached and cache-creation portions, so the buckets are already disjoint, and
210798
+ * it reports no reasoning.
210507
210799
  */
210508
210800
  function claudeModelUsageBuckets(usage) {
210509
- const record = usage;
210510
- return {
210511
- uncachedInputTokens: Math.trunc(finiteNumberFieldOrZero(record, "inputTokens")),
210512
- cachedInputTokens: Math.trunc(finiteNumberFieldOrZero(record, "cacheReadInputTokens")),
210513
- cacheCreationTokens: Math.trunc(finiteNumberFieldOrZero(record, "cacheCreationInputTokens")),
210514
- outputTokens: Math.trunc(finiteNumberFieldOrZero(record, "outputTokens")),
210515
- reasoningTokens: 0
210516
- };
210801
+ return claudeTokenBuckets(usage) ?? EMPTY_MODEL_USAGE_BUCKETS;
210517
210802
  }
210518
210803
  /**
210519
210804
  * What each model spent during THIS turn, from the SDK's per-model totals.
@@ -211857,7 +212142,6 @@ const makeClaudeAdapter = require_Schema$1.fn("makeClaudeAdapter")(function* (op
211857
212142
  return;
211858
212143
  }
211859
212144
  if (message.type === "rate_limit_event") {
211860
- if (context.recordsPersonalUsageTelemetry) recordClaudeRateLimitTelemetry(message.rate_limit_info, context.personalUsageGenerationHash, context.personalUsageProviderAccountId);
211861
212145
  yield* offerRuntimeEvent({
211862
212146
  ...base,
211863
212147
  type: "account.rate-limits.updated",
@@ -212355,10 +212639,7 @@ const makeClaudeAdapter = require_Schema$1.fn("makeClaudeAdapter")(function* (op
212355
212639
  inFlightTools,
212356
212640
  resumeSessionAt: resumeState?.resumeSessionAt,
212357
212641
  effectiveApiModelId: modelConfig.effectiveApiModelId,
212358
- effectiveEffort: modelConfig.effectiveEffort,
212359
- recordsPersonalUsageTelemetry: sessionProvider === PROVIDER$11 && modelConfig.endpointProfile === void 0 && providerProxyCredential === null && !claudeSettings.anthropicBaseUrl && !claudeSettings.anthropicApiKey,
212360
- personalUsageGenerationHash: currentClaudeUsageGenerationHash(),
212361
- personalUsageProviderAccountId: modelConfig.modelSelection?.provider === "claudeAgent" ? modelConfig.modelSelection.providerAccountId : void 0
212642
+ effectiveEffort: modelConfig.effectiveEffort
212362
212643
  });
212363
212644
  yield* require_HttpServer.set(contextRef, context$4);
212364
212645
  sessions.set(threadId, context$4);
@@ -227181,7 +227462,8 @@ const CLAUDE_READINESS_COPY = {
227181
227462
  failed: "Claude native runtime setup could not be applied. Reconnect Claude in Settings.",
227182
227463
  invalid: "Claude native runtime readiness is no longer valid. Reconnect Claude in Settings.",
227183
227464
  unavailable: "Claude native runtime readiness could not be verified.",
227184
- generationMismatch: "Claude native runtime generation does not match CMMD readiness."
227465
+ generationMismatch: "Claude native runtime generation does not match CMMD readiness.",
227466
+ environmentUnavailable: "This Environment is not running, so Claude cannot run on it. Restart the Environment, then try again."
227185
227467
  };
227186
227468
  var ClaudeRuntimeReadinessError = class extends Error {
227187
227469
  constructor(safeIssue, retryable = false, retryProfile = "default") {
@@ -227251,6 +227533,7 @@ async function withReadinessRetry(attempt) {
227251
227533
  */
227252
227534
  function readinessReasonIssue(readiness) {
227253
227535
  const code = claudeReadinessReasonCode(readiness.reason);
227536
+ if (code === "RUNTIME_UNAVAILABLE") return CLAUDE_READINESS_COPY.environmentUnavailable;
227254
227537
  if (code === "CREDENTIAL_RECONNECT_REQUIRED") return CLAUDE_READINESS_COPY.invalid;
227255
227538
  if (code === "CREDENTIAL_GENERATION_NOT_APPLIED") return CLAUDE_READINESS_COPY.applying;
227256
227539
  if (code !== "CREDENTIAL_EXPIRED_REFRESHING") return null;
@@ -227261,6 +227544,10 @@ function readinessReasonIssue(readiness) {
227261
227544
  function isCredentialRefreshInFlight(readiness) {
227262
227545
  return claudeReadinessReasonCode(readiness.reason) === "CREDENTIAL_EXPIRED_REFRESHING";
227263
227546
  }
227547
+ /** True when CMMD says the runtime itself cannot take a delivery (CMMD-36473). */
227548
+ function isRuntimeUnavailable(readiness) {
227549
+ return claudeReadinessReasonCode(readiness.reason) === "RUNTIME_UNAVAILABLE";
227550
+ }
227264
227551
  function readinessFailureIssue(readiness) {
227265
227552
  const reasonIssue = readinessReasonIssue(readiness);
227266
227553
  if (reasonIssue !== null) return reasonIssue;
@@ -227300,11 +227587,12 @@ function verifiedClaudeDeliveryBinding(readiness, authority) {
227300
227587
  function appliedClaudeGeneration(readiness) {
227301
227588
  if (readiness.connected !== true || readiness.deliveryStatus !== "applied" || readiness.nativeExecutable !== true || typeof readiness.generationId !== "string" || readiness.generationId.trim().length === 0) {
227302
227589
  const refreshing = isCredentialRefreshInFlight(readiness);
227303
- throw new ClaudeRuntimeReadinessError(readinessFailureIssue(readiness), refreshing || [
227590
+ const retryable = !isRuntimeUnavailable(readiness) && (refreshing || [
227304
227591
  "pending",
227305
227592
  "claimed",
227306
227593
  "activating"
227307
- ].includes(readiness.deliveryStatus), refreshing ? "credentialRefresh" : "default");
227594
+ ].includes(readiness.deliveryStatus));
227595
+ throw new ClaudeRuntimeReadinessError(readinessFailureIssue(readiness), retryable, refreshing ? "credentialRefresh" : "default");
227308
227596
  }
227309
227597
  return readiness.generationId;
227310
227598
  }
@@ -228462,15 +228750,15 @@ const collectOutput = require_Schema$1.fn("collectOutput")(function* (input, str
228462
228750
  /**
228463
228751
  * Adds a `safe.directory` exception to a git child environment.
228464
228752
  *
228465
- * Forge runs git against workspaces on a mounted volume (`/data/Projects/...` on
228466
- * Fly). A volume mount replaces the build-time ownership of its mountpoint, so a
228753
+ * Forge runs git against workspaces on a mounted volume (`<cloudProjectsRoot>/...`
228754
+ * on Fly). A volume mount replaces the build-time ownership of its mountpoint, so a
228467
228755
  * repository there can be owned by a uid other than the server's, and git then
228468
228756
  * refuses EVERY command against it with "detected dubious ownership" — the
228469
228757
  * FORGE-2T failure in `CheckpointStore.captureCheckpoint`.
228470
228758
  *
228471
228759
  * The exception has to be `*`, verified against git 2.43:
228472
228760
  * - git compares `safe.directory` entries literally, so a prefix such as
228473
- * `/data/Projects/*` does not match the repository at all.
228761
+ * `/projects/*` does not match the repository at all.
228474
228762
  * - the value must name the DISCOVERED REPOSITORY ROOT, which is an ancestor of
228475
228763
  * `cwd` whenever a command runs from a subdirectory. Resolving that root means
228476
228764
  * asking git, which is the command being refused.
@@ -284643,6 +284931,27 @@ const makeRuntimeDrainReporter = require_Schema$1.gen(function* () {
284643
284931
  var RuntimeDrainReporter = class extends require_Schema$1.Service()("forge/runtimeDrain/RuntimeDrainReporter") {};
284644
284932
  const RuntimeDrainReporterLive = require_Schema$1.effect(RuntimeDrainReporter, makeRuntimeDrainReporter);
284645
284933
  //#endregion
284934
+ //#region src/usage/providerRateLimits.ts
284935
+ /**
284936
+ * The SDK only ever reports ONE window per event. Only `five_hour` and
284937
+ * `seven_day` map to the two windows the Usage page shows; the
284938
+ * per-model/overage variants (seven_day_opus, overage, ...) are ignored here
284939
+ * on purpose rather than silently overwriting the plain 7-day figure.
284940
+ */
284941
+ function mapClaudeRateLimitInfo(info) {
284942
+ if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
284943
+ const kind = info.rateLimitType === "five_hour" ? "fiveHour" : info.rateLimitType === "seven_day" ? "sevenDay" : null;
284944
+ if (!kind) return null;
284945
+ return {
284946
+ kind,
284947
+ window: {
284948
+ usedPercent: Math.round(info.utilization * 100),
284949
+ resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
284950
+ status: info.status
284951
+ }
284952
+ };
284953
+ }
284954
+ //#endregion
284646
284955
  //#region src/orchestration/Layers/ProviderRuntimeIngestion.ts
284647
284956
  const providerTurnKey = (threadId, turnId) => `${threadId}:${turnId}`;
284648
284957
  const providerCommandId = (event, tag) => CommandId.make(`provider:${event.eventId}:${tag}:${crypto.randomUUID()}`);
@@ -291412,7 +291721,7 @@ const ServerLoggerLive = require_Schema$1.gen(function* () {
291412
291721
  * Observed live on a Forge Cloud sprite (2026-07-25): the browser opens
291413
291722
  * `wss://<sprite>.sprites.app/ws?routeKey=…&runtimeTicket=<JWT>`, and the HTTP
291414
291723
  * instrumentation records `url.full` / `url.query` verbatim. The ticket then
291415
- * lands in `/data/userdata/logs/server.trace.ndjson` at mode 644 — readable by
291724
+ * lands in `<FORGE_HOME>/userdata/logs/server.trace.ndjson` at mode 644 — readable by
291416
291725
  * the same user the agent runs as — and the URL also crosses fly.io's edge,
291417
291726
  * where infrastructure we do not control may log it.
291418
291727
  *
@@ -291709,7 +292018,7 @@ function resolveBuildCommitFromEnv(env) {
291709
292018
  * environment descriptor down instead of reporting an honest "unknown".
291710
292019
  */
291711
292020
  function readBakedBuildCommit() {
291712
- return "3a8f4c1280c7611f1850f146a6792e13b754bb4b";
292021
+ return "9e352ae66ea610fd1916726270fce8a1ab138a3b";
291713
292022
  }
291714
292023
  async function resolveServerBuildCommit(input) {
291715
292024
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -299761,16 +300070,6 @@ function describeDispatchCause(cause) {
299761
300070
  if (deepest === void 0 || deepest.length <= DISPATCH_CAUSE_DETAIL_LIMIT) return deepest;
299762
300071
  return `${deepest.slice(0, DISPATCH_CAUSE_DETAIL_LIMIT)}...`;
299763
300072
  }
299764
- /**
299765
- * Where automation-created projects live when the caller does not say.
299766
- *
299767
- * This is the documented default of the `cloudProjectsRoot` setting
299768
- * (FORGE_CLOUD_PROJECTS_ROOT, see cli.ts) and exists only for direct callers
299769
- * such as tests. Every HTTP route passes the CONFIGURED value instead: reading
299770
- * the default here is what made a runtime configured with any other root create
299771
- * its automation projects in a directory nothing else read.
299772
- */
299773
- const DEFAULT_CLOUD_PROJECTS_ROOT = "/data/Projects";
299774
300073
  const respondToOrchestrationHttpError = (error) => require_Schema$1.gen(function* () {
299775
300074
  if (error._tag === "OrchestrationGetSnapshotError") {
299776
300075
  yield* require_Schema$1.logError("orchestration http route failed", {
@@ -300974,6 +301273,7 @@ function resolveWsUrl(baseUrl) {
300974
301273
  const callCmmdTool = legacyCmmdToolBridge.callTool;
300975
301274
  const extractMcpToolText = legacyCmmdToolBridge.extractText;
300976
301275
  const isCmmdMcpAuthError = legacyCmmdToolBridge.isAuthError;
301276
+ const __cmmdProxyRouteLayersStartIndex = registeredProxyRouteLayers().length;
300977
301277
  /**
300978
301278
  * CMMD-side path for the PROJECT-keyed Forge Cloud catalog. Shared by the list
300979
301279
  * proxy, the SSE poll-and-emit proxy, and the register/unregister proxies so the
@@ -300983,8 +301283,9 @@ const CMMD_CLOUD_PROJECTS_PATH = "/api/forge/context/cloud-projects";
300983
301283
  const CMMD_RUNTIMES_PATH = "/api/forge/context/runtimes";
300984
301284
  /**
300985
301285
  * Authenticate the browser session and resolve the CMMD JWT to forward
300986
- * upstream. Returns null when no token could be resolved, which every caller
300987
- * turns into a CMMD_AUTH_REQUIRED response.
301286
+ * upstream. `jwt` is null when none could be resolved, which every caller
301287
+ * turns into `respondCmmdConnectionRequired(session.sessionId)` — the same
301288
+ * unified `CMMD_AUTH_REQUIRED` body and auth-clear the registry uses.
300988
301289
  *
300989
301290
  * Shared so the auth preamble is written once rather than once per proxy route.
300990
301291
  */
@@ -300992,11 +301293,14 @@ function makeCmmdProxyAccessTokenEffect(logPrefix) {
300992
301293
  return require_Schema$1.gen(function* () {
300993
301294
  const request = yield* require_HttpServer.HttpServerRequest;
300994
301295
  const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
300995
- return yield* resolveCmmdJwtForSession({
300996
- sessionId: session.sessionId,
300997
- subject: session.subject,
300998
- logPrefix
300999
- });
301296
+ return {
301297
+ session,
301298
+ jwt: yield* resolveCmmdJwtForSession({
301299
+ sessionId: session.sessionId,
301300
+ subject: session.subject,
301301
+ logPrefix
301302
+ })
301303
+ };
301000
301304
  });
301001
301305
  }
301002
301306
  var WorkIntakeSnapshotReadError = class extends require_Schema$1.TaggedErrorClass()("WorkIntakeSnapshotReadError", {
@@ -301076,32 +301380,19 @@ const cmmdProfileRouteLayer = add$1("GET", "/api/cmmd/profile", require_Schema$1
301076
301380
  * `resolution`/`sinceTime`/`untilTime` when the page is drawing hours, which is
301077
301381
  * what lets CMMD cut hour buckets rather than only days.
301078
301382
  */
301079
- const cmmdUsageSummaryRouteLayer = registerProxyRoute({
301383
+ registerProxyRoute({
301080
301384
  forgePath: "/api/cmmd/usage/summary",
301081
301385
  method: "GET",
301082
301386
  cmmdPath: "/api/forge/context/usage/summary",
301083
301387
  orgIdSource: "none"
301084
301388
  });
301085
- /**
301086
- * The workspace's CMMD plan: entitlements, the current period, and how much of
301087
- * each metered allowance is left. This is subscription consumption, which is a
301088
- * different question from the API-equivalent estimate the usage summary above
301089
- * computes from transcripts.
301090
- *
301091
- * `orgIdSource` is `query` (FOR-36406): a plan belongs to an organization, and
301092
- * without one CMMD answers for the user's default organization, which is their
301093
- * personal space rather than the workspace their Environment runs in. The web
301094
- * passes the Environment's organization as `?orgId=` and the registry turns it
301095
- * into `X-Organization-ID`; without it CMMD still answers, for the default.
301096
- */
301097
- const cmmdBillingRouteLayer = registerProxyRoute({
301389
+ registerProxyRoute({
301098
301390
  forgePath: "/api/cmmd/billing",
301099
301391
  method: "GET",
301100
301392
  cmmdPath: "/api/forge/context/billing",
301101
301393
  orgIdSource: "query"
301102
301394
  });
301103
- /** Per-day consumption across that period, so the remaining figure gets a shape. */
301104
- const cmmdBillingSeriesRouteLayer = registerProxyRoute({
301395
+ registerProxyRoute({
301105
301396
  forgePath: "/api/cmmd/billing/series",
301106
301397
  method: "GET",
301107
301398
  cmmdPath: "/api/forge/context/billing/series",
@@ -301139,6 +301430,15 @@ function runCmmdRestProxy(session, proxy, dependencies = {}) {
301139
301430
  });
301140
301431
  }
301141
301432
  /**
301433
+ * Adapts `runCmmdRestProxy`'s `{ ok, value | error }` outcome into a
301434
+ * `ProxyHandlerRoute.run` result: the shared shape every converted handler's
301435
+ * `run` uses so it stays the three or so lines of the actual gateway call
301436
+ * plus response shaping, with resolve-and-retry left to `runCmmdRestProxy`.
301437
+ */
301438
+ function runCmmdRestProxyAsHandlerResult(session, proxy, shape) {
301439
+ return runCmmdRestProxy(session, proxy).pipe(require_Schema$1.flatMap((outcome) => outcome.ok ? require_Schema$1.succeed(shape(outcome.value)) : require_Schema$1.fail(outcome.error)));
301440
+ }
301441
+ /**
301142
301442
  * Forge-context REST responses wrap their payload in `{ data, meta, pagination? }`
301143
301443
  * (see CMMD `sendForgeEnvelope`). Unwrap to the bare payload so handler response
301144
301444
  * shapes match what the web client expected from the prior MCP text path.
@@ -301303,22 +301603,34 @@ function buildCreateBrainDocumentInput(payload) {
301303
301603
  ...payload.tags && payload.tags.length > 0 ? { tags: payload.tags } : {}
301304
301604
  };
301305
301605
  }
301306
- const cmmdCreateBrainDocRouteLayer = add$1("POST", "/api/cmmd/brain-docs", require_Schema$1.gen(function* () {
301307
- const request = yield* require_HttpServer.HttpServerRequest;
301308
- const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
301309
- if (!readCommandAccessTokenForSession(session.sessionId)) return require_HttpServer.jsonUnsafe({ error: "CMMD account not connected. Log in via the connections panel." }, { status: 401 });
301310
- const payload = parseBrainDocPayload(yield* request.json);
301311
- if (!payload) return require_HttpServer.jsonUnsafe({ error: "Invalid request: title (1-500 chars) and content (1-100k chars) are required." }, { status: 400 });
301312
- const restOutcome = yield* runCmmdRestProxy(session, (jwt) => cmmdGateway.createBrainDocument({
301606
+ function parseCreateBrainDocRequest(request) {
301607
+ return request.json.pipe(require_Schema$1.orElseSucceed(() => null), require_Schema$1.map((rawBody) => {
301608
+ const payload = parseBrainDocPayload(rawBody);
301609
+ return payload ? {
301610
+ ok: true,
301611
+ value: payload
301612
+ } : {
301613
+ ok: false,
301614
+ status: 400,
301615
+ body: { error: "Invalid request: title (1-500 chars) and content (1-100k chars) are required." }
301616
+ };
301617
+ }));
301618
+ }
301619
+ registerProxyHandler({
301620
+ forgePath: "/api/cmmd/brain-docs",
301621
+ method: "POST",
301622
+ parse: parseCreateBrainDocRequest,
301623
+ run: (payload, { session }) => runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.createBrainDocument({
301313
301624
  jwt,
301314
301625
  document: buildCreateBrainDocumentInput(payload)
301315
- }));
301316
- if (restOutcome.ok) return require_HttpServer.jsonUnsafe({
301317
- success: true,
301318
- doc: unwrapForgeEnvelope(restOutcome.value)
301319
- }, { status: 201 });
301320
- return buildProxyErrorResponse(restOutcome.error);
301321
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301626
+ }), (value) => ({
301627
+ status: 201,
301628
+ body: {
301629
+ success: true,
301630
+ doc: unwrapForgeEnvelope(value)
301631
+ }
301632
+ }))
301633
+ });
301322
301634
  function normalizeOptionalNullableString(value, options) {
301323
301635
  if (value === void 0) return void 0;
301324
301636
  if (value === null) return null;
@@ -301372,46 +301684,77 @@ function buildUpdateTaskToolInput(payload) {
301372
301684
  ...payload.labels !== void 0 ? { tags: payload.labels } : {}
301373
301685
  };
301374
301686
  }
301375
- const updateCmmdTaskHandler = require_Schema$1.gen(function* () {
301376
- const request = yield* require_HttpServer.HttpServerRequest;
301377
- const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
301378
- if (!readCommandAccessTokenForSession(session.sessionId)) return require_HttpServer.jsonUnsafe({ error: "CMMD account not connected. Log in via the connections panel." }, { status: 401 });
301379
- const payload = parseUpdateTaskPayload(yield* request.json);
301380
- if (!payload) return require_HttpServer.jsonUnsafe({ error: "Invalid request: taskId is required and at least one update field must be provided." }, { status: 400 });
301687
+ function parseUpdateCmmdTaskRequest(request) {
301688
+ return request.json.pipe(require_Schema$1.orElseSucceed(() => null), require_Schema$1.map((rawBody) => {
301689
+ const payload = parseUpdateTaskPayload(rawBody);
301690
+ return payload ? {
301691
+ ok: true,
301692
+ value: payload
301693
+ } : {
301694
+ ok: false,
301695
+ status: 400,
301696
+ body: { error: "Invalid request: taskId is required and at least one update field must be provided." }
301697
+ };
301698
+ }));
301699
+ }
301700
+ function runUpdateCmmdTask(payload, { session }) {
301381
301701
  const { taskId, ...patch } = buildUpdateTaskToolInput(payload);
301382
- const restOutcome = yield* runCmmdRestProxy(session, (jwt) => cmmdGateway.updateTask({
301702
+ return runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.updateTask({
301383
301703
  jwt,
301384
301704
  taskId: String(taskId),
301385
301705
  patch
301386
- }));
301387
- if (restOutcome.ok) {
301706
+ }), (value) => {
301388
301707
  invalidateCachedCmmdWorkIntakeForSession(session.sessionId);
301389
- return require_HttpServer.jsonUnsafe({
301390
- success: true,
301391
- details: unwrapForgeEnvelope(restOutcome.value)
301392
- }, { status: 200 });
301393
- }
301394
- return buildProxyErrorResponse(restOutcome.error);
301395
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error)));
301396
- const cmmdUpdateTaskRouteLayer = add$1("POST", "/api/cmmd/tasks/update", updateCmmdTaskHandler);
301397
- const commandUpdateTaskRouteLayer = add$1("POST", "/api/command/tasks/update", updateCmmdTaskHandler);
301398
- const cmmdAddTaskCommentRouteLayer = add$1("POST", "/api/cmmd/tasks/comment", require_Schema$1.gen(function* () {
301399
- const request = yield* require_HttpServer.HttpServerRequest;
301400
- const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
301401
- const payload = parseTaskCommentPayload(yield* request.json);
301402
- if (!payload) return require_HttpServer.jsonUnsafe({ error: "taskId and content (max 2000 chars) are required." }, { status: 400 });
301403
- if (!readCommandAccessTokenForSession(session.sessionId)) return require_HttpServer.jsonUnsafe({ error: "CMMD account not connected. Log in via the connections panel." }, { status: 401 });
301404
- const restOutcome = yield* runCmmdRestProxy(session, (jwt) => cmmdGateway.addTaskComment({
301708
+ return {
301709
+ status: 200,
301710
+ body: {
301711
+ success: true,
301712
+ details: unwrapForgeEnvelope(value)
301713
+ }
301714
+ };
301715
+ });
301716
+ }
301717
+ registerProxyHandler({
301718
+ forgePath: "/api/cmmd/tasks/update",
301719
+ method: "POST",
301720
+ parse: parseUpdateCmmdTaskRequest,
301721
+ run: runUpdateCmmdTask
301722
+ });
301723
+ registerProxyHandler({
301724
+ forgePath: "/api/command/tasks/update",
301725
+ method: "POST",
301726
+ parse: parseUpdateCmmdTaskRequest,
301727
+ run: runUpdateCmmdTask
301728
+ });
301729
+ function parseAddCmmdTaskCommentRequest(request) {
301730
+ return request.json.pipe(require_Schema$1.orElseSucceed(() => null), require_Schema$1.map((rawBody) => {
301731
+ const payload = parseTaskCommentPayload(rawBody);
301732
+ return payload ? {
301733
+ ok: true,
301734
+ value: payload
301735
+ } : {
301736
+ ok: false,
301737
+ status: 400,
301738
+ body: { error: "taskId and content (max 2000 chars) are required." }
301739
+ };
301740
+ }));
301741
+ }
301742
+ registerProxyHandler({
301743
+ forgePath: "/api/cmmd/tasks/comment",
301744
+ method: "POST",
301745
+ parse: parseAddCmmdTaskCommentRequest,
301746
+ run: (payload, { session }) => runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.addTaskComment({
301405
301747
  jwt,
301406
301748
  taskId: payload.taskId,
301407
301749
  content: payload.content
301408
- }));
301409
- if (restOutcome.ok) return require_HttpServer.jsonUnsafe({
301410
- success: true,
301411
- details: unwrapForgeEnvelope(restOutcome.value)
301412
- }, { status: 201 });
301413
- return buildProxyErrorResponse(restOutcome.error);
301414
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301750
+ }), (value) => ({
301751
+ status: 201,
301752
+ body: {
301753
+ success: true,
301754
+ details: unwrapForgeEnvelope(value)
301755
+ }
301756
+ }))
301757
+ });
301415
301758
  function parseTaskCommentPayload(body) {
301416
301759
  if (typeof body !== "object" || body === null) return null;
301417
301760
  const b = body;
@@ -301440,24 +301783,38 @@ function normalizeTaskSearchParams(url) {
301440
301783
  limit: Math.min(Number(url.searchParams.get("limit") ?? "20"), 50)
301441
301784
  };
301442
301785
  }
301443
- const cmmdSearchTasksRouteLayer = add$1("GET", "/api/cmmd/tasks/search", require_Schema$1.gen(function* () {
301444
- const request = yield* require_HttpServer.HttpServerRequest;
301445
- const accessToken = readCommandAccessTokenForSession((yield* (yield* ServerAuth).authenticateHttpRequest(request)).sessionId);
301446
- if (!accessToken) return require_HttpServer.jsonUnsafe({ error: "CMMD account not connected. Log in via the connections panel." }, { status: 401 });
301447
- const search = normalizeTaskSearchParams(new URL(request.url, "http://localhost"));
301448
- if (!search) return require_HttpServer.jsonUnsafe({
301449
- tasks: [],
301450
- total: 0
301451
- }, { status: 200 });
301452
- const parsed = parseJsonObjectText(extractMcpToolText(yield* require_Schema$1.promise(() => callCmmdTool(accessToken, "search_tasks", {
301786
+ function parseSearchCmmdTasksRequest(request) {
301787
+ return require_Schema$1.sync(() => ({
301788
+ ok: true,
301789
+ value: normalizeTaskSearchParams(new URL(request.url, "http://localhost"))
301790
+ }));
301791
+ }
301792
+ function runSearchCmmdTasks(search, { session }) {
301793
+ if (!search) return require_Schema$1.succeed({
301794
+ status: 200,
301795
+ body: {
301796
+ tasks: [],
301797
+ total: 0
301798
+ }
301799
+ });
301800
+ const accessToken = readCommandAccessTokenForSession(session.sessionId) ?? "";
301801
+ return require_Schema$1.promise(() => callCmmdTool(accessToken, "search_tasks", {
301453
301802
  query: search.query,
301454
301803
  limit: search.limit
301455
- }))));
301456
- return require_HttpServer.jsonUnsafe(parsed ?? {
301457
- tasks: [],
301458
- total: 0
301459
- }, { status: 200 });
301460
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301804
+ })).pipe(require_Schema$1.map((result) => ({
301805
+ status: 200,
301806
+ body: parseJsonObjectText(extractMcpToolText(result)) ?? {
301807
+ tasks: [],
301808
+ total: 0
301809
+ }
301810
+ })));
301811
+ }
301812
+ registerProxyHandler({
301813
+ forgePath: "/api/cmmd/tasks/search",
301814
+ method: "GET",
301815
+ parse: parseSearchCmmdTasksRequest,
301816
+ run: runSearchCmmdTasks
301817
+ });
301461
301818
  function parseJsonObjectText(text) {
301462
301819
  if (!text) return null;
301463
301820
  try {
@@ -301471,23 +301828,47 @@ function parsePositiveIntegerId(value) {
301471
301828
  const numericId = Number(value);
301472
301829
  return Number.isInteger(numericId) && numericId > 0 ? numericId : null;
301473
301830
  }
301474
- const cmmdGetTaskRouteLayer = add$1("GET", "/api/cmmd/tasks/:id", require_Schema$1.gen(function* () {
301475
- const request = yield* require_HttpServer.HttpServerRequest;
301476
- const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
301477
- if (!readCommandAccessTokenForSession(session.sessionId)) return require_HttpServer.jsonUnsafe({ error: "CMMD account not connected. Log in via the connections panel." }, { status: 401 });
301478
- const taskId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 1);
301479
- if (!taskId) return require_HttpServer.jsonUnsafe({ error: "Task ID is required." }, { status: 400 });
301480
- const numericId = parsePositiveIntegerId(taskId);
301481
- if (!numericId) return require_HttpServer.jsonUnsafe({ error: "Invalid task ID." }, { status: 400 });
301482
- const restOutcome = yield* runCmmdRestProxy(session, (jwt) => cmmdGateway.getTask({
301831
+ function parseGetCmmdTaskRequest(request) {
301832
+ return require_Schema$1.sync(() => {
301833
+ const taskId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 1);
301834
+ if (!taskId) return {
301835
+ ok: false,
301836
+ status: 400,
301837
+ body: { error: "Task ID is required." }
301838
+ };
301839
+ const numericId = parsePositiveIntegerId(taskId);
301840
+ if (!numericId) return {
301841
+ ok: false,
301842
+ status: 400,
301843
+ body: { error: "Invalid task ID." }
301844
+ };
301845
+ return {
301846
+ ok: true,
301847
+ value: numericId
301848
+ };
301849
+ });
301850
+ }
301851
+ function runGetCmmdTask(numericId, { session }) {
301852
+ return runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.getTask({
301483
301853
  jwt,
301484
301854
  taskId: String(numericId)
301485
- }));
301486
- if (!restOutcome.ok) return buildProxyErrorResponse(restOutcome.error);
301487
- const task = unwrapForgeEnvelope(restOutcome.value);
301488
- if (task === null || task === void 0) return require_HttpServer.jsonUnsafe({ error: "Task not found." }, { status: 404 });
301489
- return require_HttpServer.jsonUnsafe(task, { status: 200 });
301490
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301855
+ }), (value) => {
301856
+ const task = unwrapForgeEnvelope(value);
301857
+ return task === null || task === void 0 ? {
301858
+ status: 404,
301859
+ body: { error: "Task not found." }
301860
+ } : {
301861
+ status: 200,
301862
+ body: task
301863
+ };
301864
+ });
301865
+ }
301866
+ registerProxyHandler({
301867
+ forgePath: "/api/cmmd/tasks/:id",
301868
+ method: "GET",
301869
+ parse: parseGetCmmdTaskRequest,
301870
+ run: runGetCmmdTask
301871
+ });
301491
301872
  function extractIdFromPath(pathname, fromEnd) {
301492
301873
  const parts = pathname.split("/").filter(Boolean);
301493
301874
  return parts[parts.length - fromEnd];
@@ -301499,23 +301880,37 @@ function decodePathSegment(segment) {
301499
301880
  return null;
301500
301881
  }
301501
301882
  }
301502
- const cmmdGetTaskCommentsRouteLayer = add$1("GET", "/api/cmmd/tasks/:id/comments", require_Schema$1.gen(function* () {
301503
- const request = yield* require_HttpServer.HttpServerRequest;
301504
- const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
301505
- const taskId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
301506
- if (!taskId) return require_HttpServer.jsonUnsafe({ error: "Task ID is required." }, { status: 400 });
301507
- if (!readCommandAccessTokenForSession(session.sessionId)) return require_HttpServer.jsonUnsafe({ error: "CMMD account not connected. Log in via the connections panel." }, { status: 401 });
301508
- const restOutcome = yield* runCmmdRestProxy(session, (jwt) => cmmdGateway.listTaskComments({
301883
+ function parseGetCmmdTaskCommentsRequest(request) {
301884
+ return require_Schema$1.sync(() => {
301885
+ const taskId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
301886
+ return taskId ? {
301887
+ ok: true,
301888
+ value: taskId
301889
+ } : {
301890
+ ok: false,
301891
+ status: 400,
301892
+ body: { error: "Task ID is required." }
301893
+ };
301894
+ });
301895
+ }
301896
+ function runGetCmmdTaskComments(taskId, { session }) {
301897
+ return runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.listTaskComments({
301509
301898
  jwt,
301510
301899
  taskId
301511
- }));
301512
- if (restOutcome.ok) {
301513
- const data = unwrapForgeEnvelope(restOutcome.value);
301514
- const comments = Array.isArray(data) ? data : [];
301515
- return require_HttpServer.jsonUnsafe({ comments }, { status: 200 });
301516
- }
301517
- return buildProxyErrorResponse(restOutcome.error);
301518
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301900
+ }), (value) => {
301901
+ const data = unwrapForgeEnvelope(value);
301902
+ return {
301903
+ status: 200,
301904
+ body: { comments: Array.isArray(data) ? data : [] }
301905
+ };
301906
+ });
301907
+ }
301908
+ registerProxyHandler({
301909
+ forgePath: "/api/cmmd/tasks/:id/comments",
301910
+ method: "GET",
301911
+ parse: parseGetCmmdTaskCommentsRequest,
301912
+ run: runGetCmmdTaskComments
301913
+ });
301519
301914
  function normalizeCommentList(value) {
301520
301915
  if (Array.isArray(value)) return value;
301521
301916
  if (!value || typeof value !== "object") return [];
@@ -301621,55 +302016,54 @@ const cmmdUpdateProjectRouteLayer = add$1("PATCH", "/api/cmmd/projects/:id", req
301621
302016
  project: outcome.value
301622
302017
  }, { status: 200 });
301623
302018
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301624
- const cmmdGetProjectRepositoryRouteLayer = registerProxyRoute({
302019
+ registerProxyRoute({
301625
302020
  forgePath: "/api/cmmd/projects/:id/repository",
301626
302021
  method: "GET",
301627
302022
  cmmdPath: "/api/forge/context/projects/:id/repository",
301628
302023
  orgIdSource: "none",
301629
302024
  responseShape: "unwrapData"
301630
302025
  });
301631
- /** Canonical repository identity; unlike the singular route above, this is not execution-link state. */
301632
- const cmmdListProjectRepositoriesRouteLayer = registerProxyRoute({
302026
+ registerProxyRoute({
301633
302027
  forgePath: "/api/cmmd/projects/:projectId/repositories",
301634
302028
  method: "GET",
301635
302029
  cmmdPath: "/api/forge/context/projects/:projectId/repositories",
301636
302030
  orgIdSource: "none",
301637
302031
  responseShape: "unwrapData"
301638
302032
  });
301639
- const cmmdGetOrgMembersRouteLayer = registerProxyRoute({
302033
+ registerProxyRoute({
301640
302034
  forgePath: "/api/cmmd/organizations/:id/members",
301641
302035
  method: "GET",
301642
302036
  cmmdPath: "/api/organizations/:id/members",
301643
302037
  orgIdSource: "none",
301644
302038
  responseShape: "unwrapData"
301645
302039
  });
301646
- const cmmdSimHostsRouteLayer = registerProxyRoute({
302040
+ registerProxyRoute({
301647
302041
  forgePath: "/api/cmmd/sim-host/hosts",
301648
302042
  method: "GET",
301649
302043
  cmmdPath: "/api/forge/context/sim-host/hosts",
301650
302044
  responseShape: "unwrapData"
301651
302045
  });
301652
- const cmmdSimLeaseReadRouteLayer = registerProxyRoute({
302046
+ registerProxyRoute({
301653
302047
  forgePath: "/api/cmmd/sim-host/leases",
301654
302048
  method: "GET",
301655
302049
  cmmdPath: "/api/forge/context/sim-host/leases",
301656
302050
  responseShape: "unwrapData"
301657
302051
  });
301658
- const cmmdSimLeaseClaimRouteLayer = registerProxyRoute({
302052
+ registerProxyRoute({
301659
302053
  forgePath: "/api/cmmd/sim-host/leases",
301660
302054
  method: "POST",
301661
302055
  cmmdPath: "/api/forge/context/sim-host/leases",
301662
302056
  responseShape: "unwrapData",
301663
302057
  successStatus: 200
301664
302058
  });
301665
- const cmmdSimLeaseReleaseRouteLayer = registerProxyRoute({
302059
+ registerProxyRoute({
301666
302060
  forgePath: "/api/cmmd/sim-host/leases/:leaseId/release",
301667
302061
  method: "POST",
301668
302062
  cmmdPath: "/api/forge/context/sim-host/leases/:leaseId/release",
301669
302063
  responseShape: "unwrapData",
301670
302064
  successStatus: 200
301671
302065
  });
301672
- const cmmdSimLeaseRenewRouteLayer = registerProxyRoute({
302066
+ registerProxyRoute({
301673
302067
  forgePath: "/api/cmmd/sim-host/leases/:leaseId/renew",
301674
302068
  method: "POST",
301675
302069
  cmmdPath: "/api/forge/context/sim-host/leases/:leaseId/renew",
@@ -301693,7 +302087,7 @@ function getMultipartContentType(headers) {
301693
302087
  const contentType = headers["content-type"] ?? "";
301694
302088
  return contentType.includes("multipart/form-data") ? contentType : null;
301695
302089
  }
301696
- const cmmdGetTaskAttachmentsRouteLayer = registerProxyRoute({
302090
+ registerProxyRoute({
301697
302091
  forgePath: "/api/cmmd/tasks/:id/attachments",
301698
302092
  method: "GET",
301699
302093
  cmmdPath: "/api/forge/context/tasks/:id/attachments",
@@ -301728,150 +302122,150 @@ const cmmdUpdateTaskCommentRouteLayer = add$1("PATCH", "/api/cmmd/tasks/:taskId/
301728
302122
  ...outcome.value
301729
302123
  }, { status: 200 });
301730
302124
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
301731
- const cmmdDeleteTaskCommentRouteLayer = registerProxyRoute({
302125
+ registerProxyRoute({
301732
302126
  forgePath: "/api/cmmd/tasks/:taskId/comments/:commentId",
301733
302127
  method: "DELETE",
301734
302128
  cmmdPath: "/api/forge/context/tasks/:taskId/comments/:commentId",
301735
302129
  orgIdSource: "none",
301736
302130
  requestBody: "json"
301737
302131
  });
301738
- const cmmdListProjectAgentMembersRouteLayer = registerProxyRoute({
302132
+ registerProxyRoute({
301739
302133
  forgePath: "/api/cmmd/projects/:projectId/agent-members",
301740
302134
  method: "GET",
301741
302135
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members",
301742
302136
  orgIdSource: "none",
301743
302137
  responseShape: "unwrapData"
301744
302138
  });
301745
- const cmmdCreateProjectAgentMemberRouteLayer = registerProxyRoute({
302139
+ registerProxyRoute({
301746
302140
  forgePath: "/api/cmmd/projects/:projectId/agent-members",
301747
302141
  method: "POST",
301748
302142
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members",
301749
302143
  orgIdSource: "none",
301750
302144
  responseShape: "unwrapData"
301751
302145
  });
301752
- const cmmdGetProjectAgentMemberRouteLayer = registerProxyRoute({
302146
+ registerProxyRoute({
301753
302147
  forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId",
301754
302148
  method: "GET",
301755
302149
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId",
301756
302150
  orgIdSource: "none",
301757
302151
  responseShape: "unwrapData"
301758
302152
  });
301759
- const cmmdRenameProjectAgentMemberRouteLayer = registerProxyRoute({
302153
+ registerProxyRoute({
301760
302154
  forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId",
301761
302155
  method: "PATCH",
301762
302156
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId",
301763
302157
  orgIdSource: "none",
301764
302158
  responseShape: "unwrapData"
301765
302159
  });
301766
- const cmmdRetireProjectAgentMemberRouteLayer = registerProxyRoute({
302160
+ registerProxyRoute({
301767
302161
  forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId/retire",
301768
302162
  method: "POST",
301769
302163
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId/retire",
301770
302164
  orgIdSource: "none",
301771
302165
  responseShape: "unwrapData"
301772
302166
  });
301773
- const cmmdListProjectAgentMemberInstancesRouteLayer = registerProxyRoute({
302167
+ registerProxyRoute({
301774
302168
  forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId/instances",
301775
302169
  method: "GET",
301776
302170
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId/instances",
301777
302171
  orgIdSource: "none",
301778
302172
  responseShape: "unwrapData"
301779
302173
  });
301780
- const cmmdPreviewProjectAgentMemberConsolidationRouteLayer = registerProxyRoute({
302174
+ registerProxyRoute({
301781
302175
  forgePath: "/api/cmmd/projects/:projectId/agent-members/consolidation/preview",
301782
302176
  method: "POST",
301783
302177
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members/consolidation/preview",
301784
302178
  orgIdSource: "none",
301785
302179
  responseShape: "unwrapData"
301786
302180
  });
301787
- const cmmdApplyProjectAgentMemberConsolidationRouteLayer = registerProxyRoute({
302181
+ registerProxyRoute({
301788
302182
  forgePath: "/api/cmmd/projects/:projectId/agent-members/consolidation/apply",
301789
302183
  method: "POST",
301790
302184
  cmmdPath: "/api/forge/context/projects/:projectId/agent-members/consolidation/apply",
301791
302185
  orgIdSource: "none",
301792
302186
  responseShape: "unwrapData"
301793
302187
  });
301794
- const cmmdPutProjectTaskAssignmentRouteLayer = registerProxyRoute({
302188
+ registerProxyRoute({
301795
302189
  forgePath: "/api/cmmd/projects/:projectId/tasks/:taskId/assignment",
301796
302190
  method: "PUT",
301797
302191
  cmmdPath: "/api/forge/context/projects/:projectId/tasks/:taskId/assignment",
301798
302192
  orgIdSource: "none",
301799
302193
  responseShape: "unwrapData"
301800
302194
  });
301801
- const cmmdListTasksRouteLayer = registerProxyRoute({
302195
+ registerProxyRoute({
301802
302196
  forgePath: "/api/cmmd/tasks",
301803
302197
  method: "GET",
301804
302198
  cmmdPath: "/api/forge/context/tasks"
301805
302199
  });
301806
- const cmmdCreateTaskRouteLayer = registerProxyRoute({
302200
+ registerProxyRoute({
301807
302201
  forgePath: "/api/cmmd/tasks",
301808
302202
  method: "POST",
301809
302203
  cmmdPath: "/api/forge/context/tasks"
301810
302204
  });
301811
- const cmmdArchiveTaskRouteLayer = registerProxyRoute({
302205
+ registerProxyRoute({
301812
302206
  forgePath: "/api/cmmd/tasks/:id/archive",
301813
302207
  method: "POST",
301814
302208
  cmmdPath: "/api/forge/context/tasks/:id/archive",
301815
302209
  orgIdSource: "none"
301816
302210
  });
301817
- const cmmdUnarchiveTaskRouteLayer = registerProxyRoute({
302211
+ registerProxyRoute({
301818
302212
  forgePath: "/api/cmmd/tasks/:id/unarchive",
301819
302213
  method: "POST",
301820
302214
  cmmdPath: "/api/forge/context/tasks/:id/unarchive",
301821
302215
  orgIdSource: "none"
301822
302216
  });
301823
- const cmmdListSavedViewsRouteLayer = registerProxyRoute({
302217
+ registerProxyRoute({
301824
302218
  forgePath: "/api/cmmd/saved-views",
301825
302219
  method: "GET",
301826
302220
  cmmdPath: "/api/forge/context/saved-views",
301827
302221
  orgIdSource: "none"
301828
302222
  });
301829
- const cmmdCreateSavedViewRouteLayer = registerProxyRoute({
302223
+ registerProxyRoute({
301830
302224
  forgePath: "/api/cmmd/saved-views",
301831
302225
  method: "POST",
301832
302226
  cmmdPath: "/api/forge/context/saved-views",
301833
302227
  orgIdSource: "none",
301834
302228
  successStatus: 201
301835
302229
  });
301836
- const cmmdImportSavedViewRouteLayer = registerProxyRoute({
302230
+ registerProxyRoute({
301837
302231
  forgePath: "/api/cmmd/saved-views/import",
301838
302232
  method: "POST",
301839
302233
  cmmdPath: "/api/forge/context/saved-views/import",
301840
302234
  orgIdSource: "none"
301841
302235
  });
301842
- const cmmdUpdateSavedViewRouteLayer = registerProxyRoute({
302236
+ registerProxyRoute({
301843
302237
  forgePath: "/api/cmmd/saved-views/:viewId",
301844
302238
  method: "PATCH",
301845
302239
  cmmdPath: "/api/forge/context/saved-views/:viewId",
301846
302240
  orgIdSource: "none"
301847
302241
  });
301848
- const cmmdDeleteSavedViewRouteLayer = registerProxyRoute({
302242
+ registerProxyRoute({
301849
302243
  forgePath: "/api/cmmd/saved-views/:viewId",
301850
302244
  method: "DELETE",
301851
302245
  cmmdPath: "/api/forge/context/saved-views/:viewId",
301852
302246
  orgIdSource: "none",
301853
302247
  forwardSearchParams: true
301854
302248
  });
301855
- const cmmdListProjectsRouteLayer = registerProxyRoute({
302249
+ registerProxyRoute({
301856
302250
  forgePath: "/api/cmmd/projects",
301857
302251
  method: "GET",
301858
302252
  cmmdPath: "/api/forge/context/projects",
301859
302253
  responseShape: "passthrough"
301860
302254
  });
301861
- const cmmdGetProjectRouteLayer = registerProxyRoute({
302255
+ registerProxyRoute({
301862
302256
  forgePath: "/api/cmmd/projects/:id",
301863
302257
  method: "GET",
301864
302258
  cmmdPath: "/api/forge/context/projects/:id",
301865
302259
  orgIdSource: "none",
301866
302260
  responseShape: "passthrough"
301867
302261
  });
301868
- const cmmdCreateProjectRouteLayer = registerProxyRoute({
302262
+ registerProxyRoute({
301869
302263
  forgePath: "/api/cmmd/projects",
301870
302264
  method: "POST",
301871
302265
  cmmdPath: "/api/projects",
301872
302266
  responseShape: "passthrough"
301873
302267
  });
301874
- const cmmdDeleteProjectRouteLayer = registerProxyRoute({
302268
+ registerProxyRoute({
301875
302269
  forgePath: "/api/cmmd/projects/:id",
301876
302270
  method: "DELETE",
301877
302271
  cmmdPath: "/api/forge/context/projects/:id",
@@ -301879,78 +302273,78 @@ const cmmdDeleteProjectRouteLayer = registerProxyRoute({
301879
302273
  fixedSearchParams: { soft: "false" },
301880
302274
  workIntakeInvalidation: "always"
301881
302275
  });
301882
- const cmmdMoveProjectRouteLayer = registerProxyRoute({
302276
+ registerProxyRoute({
301883
302277
  forgePath: "/api/cmmd/projects/:id/move",
301884
302278
  method: "POST",
301885
302279
  cmmdPath: "/api/forge/context/projects/:id/move",
301886
302280
  orgIdSource: "none",
301887
302281
  responseShape: "unwrapData"
301888
302282
  });
301889
- const cmmdGetProjectMembersRouteLayer = registerProxyRoute({
302283
+ registerProxyRoute({
301890
302284
  forgePath: "/api/cmmd/projects/:id/members",
301891
302285
  method: "GET",
301892
302286
  cmmdPath: "/api/forge/context/projects/:id/team"
301893
302287
  });
301894
- const cmmdGetProjectMilestonesRouteLayer = registerProxyRoute({
302288
+ registerProxyRoute({
301895
302289
  forgePath: "/api/cmmd/projects/:id/milestones",
301896
302290
  method: "GET",
301897
302291
  cmmdPath: "/api/forge/context/projects/:id/milestones"
301898
302292
  });
301899
- const cmmdCreateProjectMilestoneRouteLayer = registerProxyRoute({
302293
+ registerProxyRoute({
301900
302294
  forgePath: "/api/cmmd/projects/:id/milestones",
301901
302295
  method: "POST",
301902
302296
  cmmdPath: "/api/forge/context/projects/:id/milestones",
301903
302297
  orgIdSource: "none",
301904
302298
  responseShape: "unwrapData"
301905
302299
  });
301906
- const cmmdUpdateProjectMilestoneRouteLayer = registerProxyRoute({
302300
+ registerProxyRoute({
301907
302301
  forgePath: "/api/cmmd/projects/:id/milestones/:milestoneId",
301908
302302
  method: "PATCH",
301909
302303
  cmmdPath: "/api/forge/context/projects/:id/milestones/:milestoneId",
301910
302304
  orgIdSource: "none",
301911
302305
  responseShape: "unwrapData"
301912
302306
  });
301913
- const cmmdDeleteProjectMilestoneRouteLayer = registerProxyRoute({
302307
+ registerProxyRoute({
301914
302308
  forgePath: "/api/cmmd/projects/:id/milestones/:milestoneId",
301915
302309
  method: "DELETE",
301916
302310
  cmmdPath: "/api/forge/context/projects/:id/milestones/:milestoneId",
301917
302311
  orgIdSource: "none"
301918
302312
  });
301919
- const cmmdGetProjectUpdatesRouteLayer = registerProxyRoute({
302313
+ registerProxyRoute({
301920
302314
  forgePath: "/api/cmmd/projects/:id/updates",
301921
302315
  method: "GET",
301922
302316
  cmmdPath: "/api/forge/context/projects/:id/updates",
301923
302317
  orgIdSource: "none",
301924
302318
  responseShape: "passthrough"
301925
302319
  });
301926
- const cmmdCreateProjectUpdateRouteLayer = registerProxyRoute({
302320
+ registerProxyRoute({
301927
302321
  forgePath: "/api/cmmd/projects/:id/updates",
301928
302322
  method: "POST",
301929
302323
  cmmdPath: "/api/forge/context/projects/:id/updates",
301930
302324
  orgIdSource: "none",
301931
302325
  responseShape: "unwrapData"
301932
302326
  });
301933
- const cmmdUpdateProjectUpdateRouteLayer = registerProxyRoute({
302327
+ registerProxyRoute({
301934
302328
  forgePath: "/api/cmmd/projects/:id/updates/:updateId",
301935
302329
  method: "PATCH",
301936
302330
  cmmdPath: "/api/forge/context/projects/:id/updates/:updateId",
301937
302331
  orgIdSource: "none",
301938
302332
  responseShape: "unwrapData"
301939
302333
  });
301940
- const cmmdDeleteProjectUpdateRouteLayer = registerProxyRoute({
302334
+ registerProxyRoute({
301941
302335
  forgePath: "/api/cmmd/projects/:id/updates/:updateId",
301942
302336
  method: "DELETE",
301943
302337
  cmmdPath: "/api/forge/context/projects/:id/updates/:updateId",
301944
302338
  orgIdSource: "none"
301945
302339
  });
301946
- const cmmdImproveProjectContentRouteLayer = registerProxyRoute({
302340
+ registerProxyRoute({
301947
302341
  forgePath: "/api/cmmd/projects/:id/content/readability",
301948
302342
  method: "POST",
301949
302343
  cmmdPath: "/api/forge/context/projects/:id/content/readability",
301950
302344
  orgIdSource: "none",
301951
302345
  responseShape: "unwrapData"
301952
302346
  });
301953
- const cmmdCreateProjectTaskDraftRouteLayer = registerProxyRoute({
302347
+ registerProxyRoute({
301954
302348
  forgePath: "/api/cmmd/projects/:projectId/task-drafts",
301955
302349
  method: "POST",
301956
302350
  cmmdPath: "/api/forge/context/projects/:projectId/task-drafts",
@@ -301958,7 +302352,7 @@ const cmmdCreateProjectTaskDraftRouteLayer = registerProxyRoute({
301958
302352
  responseShape: "unwrapData",
301959
302353
  successStatus: 201
301960
302354
  });
301961
- const cmmdGetProjectTaskDraftRouteLayer = registerProxyRoute({
302355
+ registerProxyRoute({
301962
302356
  forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId",
301963
302357
  method: "GET",
301964
302358
  cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId",
@@ -301966,7 +302360,7 @@ const cmmdGetProjectTaskDraftRouteLayer = registerProxyRoute({
301966
302360
  responseShape: "unwrapData",
301967
302361
  successStatus: 200
301968
302362
  });
301969
- const cmmdUpdateProjectTaskDraftRouteLayer = registerProxyRoute({
302363
+ registerProxyRoute({
301970
302364
  forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId",
301971
302365
  method: "PATCH",
301972
302366
  cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId",
@@ -301974,7 +302368,7 @@ const cmmdUpdateProjectTaskDraftRouteLayer = registerProxyRoute({
301974
302368
  responseShape: "unwrapData",
301975
302369
  successStatus: 200
301976
302370
  });
301977
- const cmmdPreviewProjectTaskDraftRouteLayer = registerProxyRoute({
302371
+ registerProxyRoute({
301978
302372
  forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId/preview",
301979
302373
  method: "POST",
301980
302374
  cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId/preview",
@@ -301982,7 +302376,7 @@ const cmmdPreviewProjectTaskDraftRouteLayer = registerProxyRoute({
301982
302376
  responseShape: "unwrapData",
301983
302377
  successStatus: 200
301984
302378
  });
301985
- const cmmdCommitProjectTaskDraftRouteLayer = registerProxyRoute({
302379
+ registerProxyRoute({
301986
302380
  forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId/commit",
301987
302381
  method: "POST",
301988
302382
  cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId/commit",
@@ -301990,7 +302384,7 @@ const cmmdCommitProjectTaskDraftRouteLayer = registerProxyRoute({
301990
302384
  responseShape: "unwrapData",
301991
302385
  successStatus: 200
301992
302386
  });
301993
- const cmmdDiscardProjectTaskDraftRouteLayer = registerProxyRoute({
302387
+ registerProxyRoute({
301994
302388
  forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId/discard",
301995
302389
  method: "POST",
301996
302390
  cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId/discard",
@@ -301998,352 +302392,352 @@ const cmmdDiscardProjectTaskDraftRouteLayer = registerProxyRoute({
301998
302392
  responseShape: "unwrapData",
301999
302393
  successStatus: 200
302000
302394
  });
302001
- const cmmdGetProjectLeadPlanRouteLayer = registerProxyRoute({
302395
+ registerProxyRoute({
302002
302396
  forgePath: "/api/cmmd/projects/:projectId/project-lead/plan",
302003
302397
  method: "GET",
302004
302398
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/plan",
302005
302399
  orgIdSource: "none"
302006
302400
  });
302007
- const cmmdActivateProjectLeadAuthorityRouteLayer = registerProxyRoute({
302401
+ registerProxyRoute({
302008
302402
  forgePath: "/api/cmmd/projects/:projectId/project-lead/authority/activate",
302009
302403
  method: "POST",
302010
302404
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/authority/activate",
302011
302405
  orgIdSource: "none",
302012
302406
  responseShape: "unwrapData"
302013
302407
  });
302014
- const cmmdGetProjectLeadReadinessRouteLayer = registerProxyRoute({
302408
+ registerProxyRoute({
302015
302409
  forgePath: "/api/cmmd/projects/:projectId/project-lead/readiness",
302016
302410
  method: "GET",
302017
302411
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/readiness",
302018
302412
  orgIdSource: "none"
302019
302413
  });
302020
- const cmmdGetProjectLeadCapabilitiesRouteLayer = registerProxyRoute({
302414
+ registerProxyRoute({
302021
302415
  forgePath: "/api/cmmd/projects/:projectId/project-lead/capabilities",
302022
302416
  method: "GET",
302023
302417
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/capabilities",
302024
302418
  orgIdSource: "none"
302025
302419
  });
302026
- const cmmdGetProjectLeadSummaryRouteLayer = registerProxyRoute({
302420
+ registerProxyRoute({
302027
302421
  forgePath: "/api/cmmd/projects/:projectId/project-lead/summary",
302028
302422
  method: "GET",
302029
302423
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/summary",
302030
302424
  orgIdSource: "none"
302031
302425
  });
302032
- const cmmdGetProjectLeadDetailRouteLayer = registerProxyRoute({
302426
+ registerProxyRoute({
302033
302427
  forgePath: "/api/cmmd/projects/:projectId/project-lead/detail",
302034
302428
  method: "GET",
302035
302429
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/detail",
302036
302430
  orgIdSource: "none"
302037
302431
  });
302038
- const cmmdGetProjectLeadBriefingRouteLayer = registerProxyRoute({
302432
+ registerProxyRoute({
302039
302433
  forgePath: "/api/cmmd/projects/:projectId/project-lead/briefing",
302040
302434
  method: "GET",
302041
302435
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/briefing",
302042
302436
  orgIdSource: "none"
302043
302437
  });
302044
- const cmmdListProjectLeadEventsRouteLayer = registerProxyRoute({
302438
+ registerProxyRoute({
302045
302439
  forgePath: "/api/cmmd/projects/:projectId/project-lead/events",
302046
302440
  method: "GET",
302047
302441
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/events",
302048
302442
  orgIdSource: "none"
302049
302443
  });
302050
- const cmmdExplainProjectLeadRouteLayer = registerProxyRoute({
302444
+ registerProxyRoute({
302051
302445
  forgePath: "/api/cmmd/projects/:projectId/project-lead/explain",
302052
302446
  method: "GET",
302053
302447
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/explain",
302054
302448
  orgIdSource: "none"
302055
302449
  });
302056
- const cmmdPauseProjectLeadRouteLayer = registerProxyRoute({
302450
+ registerProxyRoute({
302057
302451
  forgePath: "/api/cmmd/projects/:projectId/project-lead/pause",
302058
302452
  method: "POST",
302059
302453
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/pause",
302060
302454
  orgIdSource: "none"
302061
302455
  });
302062
- const cmmdResumeProjectLeadRouteLayer = registerProxyRoute({
302456
+ registerProxyRoute({
302063
302457
  forgePath: "/api/cmmd/projects/:projectId/project-lead/resume",
302064
302458
  method: "POST",
302065
302459
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/resume",
302066
302460
  orgIdSource: "none"
302067
302461
  });
302068
- const cmmdReserveProjectLeadTaskRouteLayer = registerProxyRoute({
302462
+ registerProxyRoute({
302069
302463
  forgePath: "/api/cmmd/projects/:projectId/project-lead/tasks/:taskId/reservations",
302070
302464
  method: "POST",
302071
302465
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/tasks/:taskId/reservations",
302072
302466
  orgIdSource: "none"
302073
302467
  });
302074
- const cmmdReleaseProjectLeadReservationRouteLayer = registerProxyRoute({
302468
+ registerProxyRoute({
302075
302469
  forgePath: "/api/cmmd/projects/:projectId/project-lead/reservations/:reservationId/release",
302076
302470
  method: "POST",
302077
302471
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/reservations/:reservationId/release",
302078
302472
  orgIdSource: "none"
302079
302473
  });
302080
- const cmmdReconcileProjectLeadRouteLayer = registerProxyRoute({
302474
+ registerProxyRoute({
302081
302475
  forgePath: "/api/cmmd/projects/:projectId/project-lead/reconcile",
302082
302476
  method: "POST",
302083
302477
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/reconcile",
302084
302478
  orgIdSource: "none"
302085
302479
  });
302086
- const cmmdResolveProjectLeadAttentionRouteLayer = registerProxyRoute({
302480
+ registerProxyRoute({
302087
302481
  forgePath: "/api/cmmd/projects/:projectId/project-lead/attention/:attentionId/resolve",
302088
302482
  method: "POST",
302089
302483
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/attention/:attentionId/resolve",
302090
302484
  orgIdSource: "none"
302091
302485
  });
302092
- const cmmdClaimProjectLeadControllerRouteLayer = registerProxyRoute({
302486
+ registerProxyRoute({
302093
302487
  forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/claim",
302094
302488
  method: "POST",
302095
302489
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/claim",
302096
302490
  orgIdSource: "none"
302097
302491
  });
302098
- const cmmdRenewProjectLeadControllerClaimRouteLayer = registerProxyRoute({
302492
+ registerProxyRoute({
302099
302493
  forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/claim/renew",
302100
302494
  method: "POST",
302101
302495
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/claim/renew",
302102
302496
  orgIdSource: "none"
302103
302497
  });
302104
- const cmmdYieldProjectLeadControllerClaimRouteLayer = registerProxyRoute({
302498
+ registerProxyRoute({
302105
302499
  forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/claim/yield",
302106
302500
  method: "POST",
302107
302501
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/claim/yield",
302108
302502
  orgIdSource: "none"
302109
302503
  });
302110
- const cmmdAcknowledgeProjectLeadControllerEventRouteLayer = registerProxyRoute({
302504
+ registerProxyRoute({
302111
302505
  forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/events/:eventId/acknowledge",
302112
302506
  method: "POST",
302113
302507
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/events/:eventId/acknowledge",
302114
302508
  orgIdSource: "none"
302115
302509
  });
302116
- const cmmdRecordProjectLeadControllerDecisionRouteLayer = registerProxyRoute({
302510
+ registerProxyRoute({
302117
302511
  forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/decisions",
302118
302512
  method: "POST",
302119
302513
  cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/decisions",
302120
302514
  orgIdSource: "none"
302121
302515
  });
302122
- const cmmdListForgeAutomationPresetsRouteLayer = registerProxyRoute({
302516
+ registerProxyRoute({
302123
302517
  forgePath: "/api/cmmd/automations/presets",
302124
302518
  method: "GET",
302125
302519
  cmmdPath: "/api/forge/context/automations/presets",
302126
302520
  orgIdSource: "none",
302127
302521
  responseShape: "unwrapData"
302128
302522
  });
302129
- const cmmdListUserForgeAutomationRulesRouteLayer = registerProxyRoute({
302523
+ registerProxyRoute({
302130
302524
  forgePath: "/api/cmmd/automations/user/rules",
302131
302525
  method: "GET",
302132
302526
  cmmdPath: "/api/forge/context/automations/user/rules",
302133
302527
  orgIdSource: "none",
302134
302528
  responseShape: "unwrapData"
302135
302529
  });
302136
- const cmmdCreateUserForgeAutomationRuleRouteLayer = registerProxyRoute({
302530
+ registerProxyRoute({
302137
302531
  forgePath: "/api/cmmd/automations/user/rules",
302138
302532
  method: "POST",
302139
302533
  cmmdPath: "/api/forge/context/automations/user/rules",
302140
302534
  orgIdSource: "none",
302141
302535
  responseShape: "unwrapData"
302142
302536
  });
302143
- const cmmdUpdateUserForgeAutomationRuleRouteLayer = registerProxyRoute({
302537
+ registerProxyRoute({
302144
302538
  forgePath: "/api/cmmd/automations/user/rules/:ruleId",
302145
302539
  method: "PATCH",
302146
302540
  cmmdPath: "/api/forge/context/automations/user/rules/:ruleId",
302147
302541
  orgIdSource: "none",
302148
302542
  responseShape: "unwrapData"
302149
302543
  });
302150
- const cmmdListUserForgeAutomationRunsRouteLayer = registerProxyRoute({
302544
+ registerProxyRoute({
302151
302545
  forgePath: "/api/cmmd/automations/user/rules/:ruleId/runs",
302152
302546
  method: "GET",
302153
302547
  cmmdPath: "/api/forge/context/automations/user/rules/:ruleId/runs",
302154
302548
  orgIdSource: "none",
302155
302549
  responseShape: "unwrapData"
302156
302550
  });
302157
- const cmmdStartUserForgeAutomationRunRouteLayer = registerProxyRoute({
302551
+ registerProxyRoute({
302158
302552
  forgePath: "/api/cmmd/automations/user/rules/:ruleId/runs",
302159
302553
  method: "POST",
302160
302554
  cmmdPath: "/api/forge/context/automations/user/rules/:ruleId/runs",
302161
302555
  orgIdSource: "none",
302162
302556
  responseShape: "unwrapData"
302163
302557
  });
302164
- const cmmdListForgeAutomationRulesRouteLayer = registerProxyRoute({
302558
+ registerProxyRoute({
302165
302559
  forgePath: "/api/cmmd/automations/projects/:projectId/rules",
302166
302560
  method: "GET",
302167
302561
  cmmdPath: "/api/forge/context/automations/projects/:projectId/rules",
302168
302562
  orgIdSource: "query",
302169
302563
  responseShape: "unwrapData"
302170
302564
  });
302171
- const cmmdCreateForgeAutomationRuleRouteLayer = registerProxyRoute({
302565
+ registerProxyRoute({
302172
302566
  forgePath: "/api/cmmd/automations/projects/:projectId/rules",
302173
302567
  method: "POST",
302174
302568
  cmmdPath: "/api/forge/context/automations/projects/:projectId/rules",
302175
302569
  orgIdSource: "query",
302176
302570
  responseShape: "unwrapData"
302177
302571
  });
302178
- const cmmdUpdateForgeAutomationRuleRouteLayer = registerProxyRoute({
302572
+ registerProxyRoute({
302179
302573
  forgePath: "/api/cmmd/automations/projects/:projectId/rules/:ruleId",
302180
302574
  method: "PATCH",
302181
302575
  cmmdPath: "/api/forge/context/automations/projects/:projectId/rules/:ruleId",
302182
302576
  orgIdSource: "query",
302183
302577
  responseShape: "unwrapData"
302184
302578
  });
302185
- const cmmdListForgeAutomationRunsRouteLayer = registerProxyRoute({
302579
+ registerProxyRoute({
302186
302580
  forgePath: "/api/cmmd/automations/projects/:projectId/runs",
302187
302581
  method: "GET",
302188
302582
  cmmdPath: "/api/forge/context/automations/projects/:projectId/runs",
302189
302583
  orgIdSource: "query",
302190
302584
  responseShape: "unwrapData"
302191
302585
  });
302192
- const cmmdStartForgeAutomationRunRouteLayer = registerProxyRoute({
302586
+ registerProxyRoute({
302193
302587
  forgePath: "/api/cmmd/automations/projects/:projectId/tasks/:taskId/runs",
302194
302588
  method: "POST",
302195
302589
  cmmdPath: "/api/forge/context/automations/projects/:projectId/tasks/:taskId/runs",
302196
302590
  orgIdSource: "query",
302197
302591
  responseShape: "unwrapData"
302198
302592
  });
302199
- const cmmdGetForgeAutomationRunRouteLayer = registerProxyRoute({
302593
+ registerProxyRoute({
302200
302594
  forgePath: "/api/cmmd/automations/runs/:runId",
302201
302595
  method: "GET",
302202
302596
  cmmdPath: "/api/forge/context/automations/runs/:runId",
302203
302597
  orgIdSource: "query",
302204
302598
  responseShape: "unwrapData"
302205
302599
  });
302206
- const cmmdRetryForgeAutomationRunRouteLayer = registerProxyRoute({
302600
+ registerProxyRoute({
302207
302601
  forgePath: "/api/cmmd/automations/runs/:runId/retry",
302208
302602
  method: "POST",
302209
302603
  cmmdPath: "/api/forge/context/automations/runs/:runId/retry",
302210
302604
  orgIdSource: "query",
302211
302605
  responseShape: "unwrapData"
302212
302606
  });
302213
- const cmmdCancelForgeAutomationRunRouteLayer = registerProxyRoute({
302607
+ registerProxyRoute({
302214
302608
  forgePath: "/api/cmmd/automations/runs/:runId/cancel",
302215
302609
  method: "POST",
302216
302610
  cmmdPath: "/api/forge/context/automations/runs/:runId/cancel",
302217
302611
  orgIdSource: "query",
302218
302612
  responseShape: "unwrapData"
302219
302613
  });
302220
- const cmmdApproveForgeAutomationEscalationRouteLayer = registerProxyRoute({
302614
+ registerProxyRoute({
302221
302615
  forgePath: "/api/cmmd/automations/runs/:runId/escalations/approve",
302222
302616
  method: "POST",
302223
302617
  cmmdPath: "/api/forge/context/automations/runs/:runId/escalations/approve",
302224
302618
  orgIdSource: "query",
302225
302619
  responseShape: "unwrapData"
302226
302620
  });
302227
- const cmmdRejectForgeAutomationEscalationRouteLayer = registerProxyRoute({
302621
+ registerProxyRoute({
302228
302622
  forgePath: "/api/cmmd/automations/runs/:runId/escalations/reject",
302229
302623
  method: "POST",
302230
302624
  cmmdPath: "/api/forge/context/automations/runs/:runId/escalations/reject",
302231
302625
  orgIdSource: "query",
302232
302626
  responseShape: "unwrapData"
302233
302627
  });
302234
- const cmmdListProjectBoardRouteLayer = registerProxyRoute({
302628
+ registerProxyRoute({
302235
302629
  forgePath: "/api/cmmd/projects/:id/board",
302236
302630
  method: "GET",
302237
302631
  cmmdPath: "/api/forge/context/projects/:id/board",
302238
302632
  orgIdSource: "none",
302239
302633
  responseShape: "unwrapData"
302240
302634
  });
302241
- const cmmdGetProjectTaskWorkflowRouteLayer = registerProxyRoute({
302635
+ registerProxyRoute({
302242
302636
  forgePath: "/api/cmmd/projects/:id/task-workflow",
302243
302637
  method: "GET",
302244
302638
  cmmdPath: "/api/forge/context/projects/:id/task-workflow",
302245
302639
  orgIdSource: "none",
302246
302640
  responseShape: "unwrapData"
302247
302641
  });
302248
- const cmmdUpdateProjectTaskWorkflowRouteLayer = registerProxyRoute({
302642
+ registerProxyRoute({
302249
302643
  forgePath: "/api/cmmd/projects/:id/task-workflow",
302250
302644
  method: "PUT",
302251
302645
  cmmdPath: "/api/forge/context/projects/:id/task-workflow",
302252
302646
  orgIdSource: "none",
302253
302647
  responseShape: "unwrapData"
302254
302648
  });
302255
- const cmmdCreateProjectBoardTaskRouteLayer = registerProxyRoute({
302649
+ registerProxyRoute({
302256
302650
  forgePath: "/api/cmmd/projects/:id/board",
302257
302651
  method: "POST",
302258
302652
  cmmdPath: "/api/forge/context/projects/:id/board",
302259
302653
  orgIdSource: "none",
302260
302654
  responseShape: "unwrapData"
302261
302655
  });
302262
- const cmmdUpdateProjectBoardTaskRouteLayer = registerProxyRoute({
302656
+ registerProxyRoute({
302263
302657
  forgePath: "/api/cmmd/projects/:id/board/:taskId",
302264
302658
  method: "PATCH",
302265
302659
  cmmdPath: "/api/forge/context/projects/:id/board/:taskId",
302266
302660
  orgIdSource: "none",
302267
302661
  responseShape: "unwrapData"
302268
302662
  });
302269
- const cmmdUpdateProjectBoardTaskStatusRouteLayer = registerProxyRoute({
302663
+ registerProxyRoute({
302270
302664
  forgePath: "/api/cmmd/projects/:id/board/:taskId/status",
302271
302665
  method: "PATCH",
302272
302666
  cmmdPath: "/api/forge/context/projects/:id/board/:taskId/status",
302273
302667
  orgIdSource: "none",
302274
302668
  responseShape: "unwrapData"
302275
302669
  });
302276
- const cmmdListTaskExecutionOptionsRouteLayer = registerProxyRoute({
302670
+ registerProxyRoute({
302277
302671
  forgePath: "/api/cmmd/projects/:id/board/:taskId/execution-options",
302278
302672
  method: "GET",
302279
302673
  cmmdPath: "/api/forge/context/projects/:id/board/:taskId/execution-options",
302280
302674
  orgIdSource: "none",
302281
302675
  responseShape: "unwrapData"
302282
302676
  });
302283
- const cmmdCreateTaskWorkSessionRouteLayer = registerProxyRoute({
302677
+ registerProxyRoute({
302284
302678
  forgePath: "/api/cmmd/projects/:id/board/:taskId/work-sessions",
302285
302679
  method: "POST",
302286
302680
  cmmdPath: "/api/forge/context/projects/:id/board/:taskId/work-sessions",
302287
302681
  orgIdSource: "none",
302288
302682
  responseShape: "unwrapData"
302289
302683
  });
302290
- const cmmdListProjectWorkSessionsRouteLayer = registerProxyRoute({
302684
+ registerProxyRoute({
302291
302685
  forgePath: "/api/cmmd/projects/:id/work-sessions",
302292
302686
  method: "GET",
302293
302687
  cmmdPath: "/api/forge/context/projects/:id/work-sessions",
302294
302688
  orgIdSource: "none",
302295
302689
  responseShape: "unwrapData"
302296
302690
  });
302297
- const cmmdGetWorkSessionRouteLayer = registerProxyRoute({
302691
+ registerProxyRoute({
302298
302692
  forgePath: "/api/cmmd/work-sessions/:workSessionId",
302299
302693
  method: "GET",
302300
302694
  cmmdPath: "/api/forge/context/work-sessions/:workSessionId",
302301
302695
  orgIdSource: "none",
302302
302696
  responseShape: "unwrapData"
302303
302697
  });
302304
- const cmmdUpdateWorkSessionRouteLayer = registerProxyRoute({
302698
+ registerProxyRoute({
302305
302699
  forgePath: "/api/cmmd/work-sessions/:workSessionId",
302306
302700
  method: "PATCH",
302307
302701
  cmmdPath: "/api/forge/context/work-sessions/:workSessionId",
302308
302702
  orgIdSource: "none",
302309
302703
  responseShape: "unwrapData"
302310
302704
  });
302311
- const cmmdAttachWorkSessionThreadRouteLayer = registerProxyRoute({
302705
+ registerProxyRoute({
302312
302706
  forgePath: "/api/cmmd/work-sessions/:workSessionId/threads",
302313
302707
  method: "POST",
302314
302708
  cmmdPath: "/api/forge/context/work-sessions/:workSessionId/threads",
302315
302709
  orgIdSource: "none",
302316
302710
  responseShape: "unwrapData"
302317
302711
  });
302318
- const cmmdListTaskConversationsRouteLayer = registerProxyRoute({
302712
+ registerProxyRoute({
302319
302713
  forgePath: "/api/cmmd/tasks/:taskId/conversations",
302320
302714
  method: "GET",
302321
302715
  cmmdPath: "/api/forge/context/tasks/:taskId/conversations",
302322
302716
  orgIdSource: "none",
302323
302717
  responseShape: "unwrapData"
302324
302718
  });
302325
- const cmmdLinkTaskConversationRouteLayer = registerProxyRoute({
302719
+ registerProxyRoute({
302326
302720
  forgePath: "/api/cmmd/tasks/:taskId/conversations",
302327
302721
  method: "POST",
302328
302722
  cmmdPath: "/api/forge/context/tasks/:taskId/conversations",
302329
302723
  orgIdSource: "none",
302330
302724
  responseShape: "unwrapData"
302331
302725
  });
302332
- const cmmdGetTaskHistoryRouteLayer = registerProxyRoute({
302726
+ registerProxyRoute({
302333
302727
  forgePath: "/api/cmmd/tasks/:taskId/history",
302334
302728
  method: "GET",
302335
302729
  cmmdPath: "/api/forge/context/tasks/:taskId/history",
302336
302730
  orgIdSource: "none",
302337
302731
  responseShape: "unwrapData"
302338
302732
  });
302339
- const cmmdUpsertTaskPullRequestRouteLayer = registerProxyRoute({
302733
+ registerProxyRoute({
302340
302734
  forgePath: "/api/cmmd/tasks/:taskId/pull-requests",
302341
302735
  method: "PUT",
302342
302736
  cmmdPath: "/api/forge/context/tasks/:taskId/pull-requests",
302343
302737
  orgIdSource: "none",
302344
302738
  responseShape: "unwrapData"
302345
302739
  });
302346
- const cmmdPullRequestRouteLayers = [
302740
+ for (const path of [
302347
302741
  "list",
302348
302742
  "list-stats",
302349
302743
  "detail",
@@ -302361,70 +302755,70 @@ const cmmdPullRequestRouteLayers = [
302361
302755
  "thread/resolution",
302362
302756
  "reviewers",
302363
302757
  "reaction"
302364
- ].map((path) => registerProxyRoute({
302758
+ ]) registerProxyRoute({
302365
302759
  forgePath: `/api/cmmd/pull-requests/${path}`,
302366
302760
  method: "POST",
302367
302761
  cmmdPath: `/api/forge/context/pull-requests/${path}`,
302368
302762
  orgIdSource: "none",
302369
302763
  responseShape: "unwrapData"
302370
- }));
302371
- const cmmdGetTaskConversationRouteLayer = registerProxyRoute({
302764
+ });
302765
+ registerProxyRoute({
302372
302766
  forgePath: "/api/cmmd/tasks/:taskId/conversations/:conversationId",
302373
302767
  method: "GET",
302374
302768
  cmmdPath: "/api/forge/context/tasks/:taskId/conversations/:conversationId",
302375
302769
  orgIdSource: "none",
302376
302770
  responseShape: "unwrapData"
302377
302771
  });
302378
- const cmmdSpawnForgeThreadFromBoardTaskRouteLayer = registerProxyRoute({
302772
+ registerProxyRoute({
302379
302773
  forgePath: "/api/cmmd/projects/:id/board/:taskId/spawn-forge-thread",
302380
302774
  method: "POST",
302381
302775
  cmmdPath: "/api/forge/context/projects/:id/board/:taskId/spawn-forge-thread",
302382
302776
  orgIdSource: "none",
302383
302777
  responseShape: "unwrapData"
302384
302778
  });
302385
- const cmmdListCenterBoardRouteLayer = registerProxyRoute({
302779
+ registerProxyRoute({
302386
302780
  forgePath: "/api/cmmd/work-items/board",
302387
302781
  method: "GET",
302388
302782
  cmmdPath: "/api/forge/context/work-items/board",
302389
302783
  orgIdSource: "none",
302390
302784
  responseShape: "unwrapData"
302391
302785
  });
302392
- const cmmdCreateCenterBoardTaskRouteLayer = registerProxyRoute({
302786
+ registerProxyRoute({
302393
302787
  forgePath: "/api/cmmd/work-items/board",
302394
302788
  method: "POST",
302395
302789
  cmmdPath: "/api/forge/context/work-items/board",
302396
302790
  orgIdSource: "none",
302397
302791
  responseShape: "unwrapData"
302398
302792
  });
302399
- const cmmdCreateFeedbackRouteLayer = registerProxyRoute({
302793
+ registerProxyRoute({
302400
302794
  forgePath: "/api/cmmd/feedback",
302401
302795
  method: "POST",
302402
302796
  cmmdPath: "/api/forge/context/feedback",
302403
302797
  orgIdSource: "none",
302404
302798
  responseShape: "unwrapData"
302405
302799
  });
302406
- const cmmdUpdateCenterBoardTaskRouteLayer = registerProxyRoute({
302800
+ registerProxyRoute({
302407
302801
  forgePath: "/api/cmmd/work-items/board/:taskId",
302408
302802
  method: "PATCH",
302409
302803
  cmmdPath: "/api/forge/context/work-items/board/:taskId",
302410
302804
  orgIdSource: "none",
302411
302805
  responseShape: "unwrapData"
302412
302806
  });
302413
- const cmmdMoveCenterBoardTaskRouteLayer = registerProxyRoute({
302807
+ registerProxyRoute({
302414
302808
  forgePath: "/api/cmmd/work-items/board/:taskId/move",
302415
302809
  method: "PATCH",
302416
302810
  cmmdPath: "/api/forge/context/work-items/board/:taskId/move",
302417
302811
  orgIdSource: "none",
302418
302812
  responseShape: "unwrapData"
302419
302813
  });
302420
- const cmmdMoveProjectBoardTaskRouteLayer = registerProxyRoute({
302814
+ registerProxyRoute({
302421
302815
  forgePath: "/api/cmmd/projects/:projectId/board/:taskId/move",
302422
302816
  method: "PATCH",
302423
302817
  cmmdPath: "/api/forge/context/projects/:projectId/board/:taskId/move",
302424
302818
  orgIdSource: "none",
302425
302819
  responseShape: "unwrapData"
302426
302820
  });
302427
- const cmmdArchiveProjectBoardTaskRouteLayer = registerProxyRoute({
302821
+ registerProxyRoute({
302428
302822
  forgePath: "/api/cmmd/projects/:projectId/board/:taskId/archive",
302429
302823
  method: "POST",
302430
302824
  cmmdPath: "/api/forge/context/projects/:projectId/board/:taskId/archive",
@@ -302432,7 +302826,7 @@ const cmmdArchiveProjectBoardTaskRouteLayer = registerProxyRoute({
302432
302826
  responseShape: "unwrapData",
302433
302827
  requestBody: "none"
302434
302828
  });
302435
- const cmmdUnarchiveProjectBoardTaskRouteLayer = registerProxyRoute({
302829
+ registerProxyRoute({
302436
302830
  forgePath: "/api/cmmd/projects/:projectId/board/:taskId/unarchive",
302437
302831
  method: "POST",
302438
302832
  cmmdPath: "/api/forge/context/projects/:projectId/board/:taskId/unarchive",
@@ -302440,7 +302834,7 @@ const cmmdUnarchiveProjectBoardTaskRouteLayer = registerProxyRoute({
302440
302834
  responseShape: "unwrapData",
302441
302835
  requestBody: "none"
302442
302836
  });
302443
- const cmmdArchiveCenterBoardTaskRouteLayer = registerProxyRoute({
302837
+ registerProxyRoute({
302444
302838
  forgePath: "/api/cmmd/work-items/board/:taskId/archive",
302445
302839
  method: "POST",
302446
302840
  cmmdPath: "/api/forge/context/work-items/board/:taskId/archive",
@@ -302448,7 +302842,7 @@ const cmmdArchiveCenterBoardTaskRouteLayer = registerProxyRoute({
302448
302842
  responseShape: "unwrapData",
302449
302843
  requestBody: "none"
302450
302844
  });
302451
- const cmmdUnarchiveCenterBoardTaskRouteLayer = registerProxyRoute({
302845
+ registerProxyRoute({
302452
302846
  forgePath: "/api/cmmd/work-items/board/:taskId/unarchive",
302453
302847
  method: "POST",
302454
302848
  cmmdPath: "/api/forge/context/work-items/board/:taskId/unarchive",
@@ -302456,109 +302850,109 @@ const cmmdUnarchiveCenterBoardTaskRouteLayer = registerProxyRoute({
302456
302850
  responseShape: "unwrapData",
302457
302851
  requestBody: "none"
302458
302852
  });
302459
- const cmmdListCampaignsRouteLayer = registerProxyRoute({
302853
+ registerProxyRoute({
302460
302854
  forgePath: "/api/cmmd/campaigns",
302461
302855
  method: "GET",
302462
302856
  cmmdPath: "/api/forge/context/campaigns",
302463
302857
  orgIdSource: "none",
302464
302858
  responseShape: "passthrough"
302465
302859
  });
302466
- const cmmdGetCampaignRouteLayer = registerProxyRoute({
302860
+ registerProxyRoute({
302467
302861
  forgePath: "/api/cmmd/campaigns/:id",
302468
302862
  method: "GET",
302469
302863
  cmmdPath: "/api/forge/context/campaigns/:id",
302470
302864
  orgIdSource: "none",
302471
302865
  responseShape: "passthrough"
302472
302866
  });
302473
- const cmmdCreateCampaignRouteLayer = registerProxyRoute({
302867
+ registerProxyRoute({
302474
302868
  forgePath: "/api/cmmd/campaigns",
302475
302869
  method: "POST",
302476
302870
  cmmdPath: "/api/projects/campaigns",
302477
302871
  responseShape: "passthrough"
302478
302872
  });
302479
- const cmmdUpdateCampaignRouteLayer = registerProxyRoute({
302873
+ registerProxyRoute({
302480
302874
  forgePath: "/api/cmmd/campaigns/:id",
302481
302875
  method: "PUT",
302482
302876
  cmmdPath: "/api/projects/campaigns/:id",
302483
302877
  responseShape: "passthrough"
302484
302878
  });
302485
- const cmmdDeleteCampaignRouteLayer = registerProxyRoute({
302879
+ registerProxyRoute({
302486
302880
  forgePath: "/api/cmmd/campaigns/:id",
302487
302881
  method: "DELETE",
302488
302882
  cmmdPath: "/api/projects/campaigns/:id",
302489
302883
  orgIdSource: "none"
302490
302884
  });
302491
- const cmmdBootstrapRouteLayer = registerProxyRoute({
302885
+ registerProxyRoute({
302492
302886
  forgePath: "/api/cmmd/bootstrap",
302493
302887
  method: "GET",
302494
302888
  cmmdPath: "/api/forge/context/bootstrap",
302495
302889
  orgIdSource: "none",
302496
302890
  responseShape: "passthrough"
302497
302891
  });
302498
- const cmmdGetAccountPreferencesRouteLayer = registerProxyRoute({
302892
+ registerProxyRoute({
302499
302893
  forgePath: "/api/cmmd/account/preferences",
302500
302894
  method: "GET",
302501
302895
  cmmdPath: "/api/forge/context/account/preferences",
302502
302896
  orgIdSource: "none",
302503
302897
  responseShape: "unwrapData"
302504
302898
  });
302505
- const cmmdUpdateAccountPreferencesRouteLayer = registerProxyRoute({
302899
+ registerProxyRoute({
302506
302900
  forgePath: "/api/cmmd/account/preferences",
302507
302901
  method: "PATCH",
302508
302902
  cmmdPath: "/api/forge/context/account/preferences",
302509
302903
  orgIdSource: "none",
302510
302904
  responseShape: "unwrapData"
302511
302905
  });
302512
- const cmmdGetOrgProviderPolicyRouteLayer = registerProxyRoute({
302906
+ registerProxyRoute({
302513
302907
  forgePath: "/api/cmmd/org/provider-policy",
302514
302908
  method: "GET",
302515
302909
  cmmdPath: "/api/forge/context/org/provider-policy",
302516
302910
  orgIdSource: "none",
302517
302911
  responseShape: "unwrapData"
302518
302912
  });
302519
- const cmmdListChatsRouteLayer = registerProxyRoute({
302913
+ registerProxyRoute({
302520
302914
  forgePath: "/api/cmmd/chats",
302521
302915
  method: "GET",
302522
302916
  cmmdPath: "/api/forge/context/chats",
302523
302917
  orgIdSource: "none",
302524
302918
  responseShape: "unwrapData"
302525
302919
  });
302526
- const cmmdGetChatRouteLayer = registerProxyRoute({
302920
+ registerProxyRoute({
302527
302921
  forgePath: "/api/cmmd/chats/:threadId",
302528
302922
  method: "GET",
302529
302923
  cmmdPath: "/api/forge/context/chats/:threadId",
302530
302924
  orgIdSource: "none",
302531
302925
  responseShape: "unwrapData"
302532
302926
  });
302533
- const cmmdListDevicesRouteLayer = registerProxyRoute({
302927
+ registerProxyRoute({
302534
302928
  forgePath: "/api/cmmd/devices",
302535
302929
  method: "GET",
302536
302930
  cmmdPath: "/api/forge/context/devices",
302537
302931
  orgIdSource: "none",
302538
302932
  responseShape: "unwrapData"
302539
302933
  });
302540
- const cmmdRegisterDeviceRouteLayer = registerProxyRoute({
302934
+ registerProxyRoute({
302541
302935
  forgePath: "/api/cmmd/devices/register",
302542
302936
  method: "POST",
302543
302937
  cmmdPath: "/api/forge/context/devices/register",
302544
302938
  orgIdSource: "none",
302545
302939
  responseShape: "unwrapData"
302546
302940
  });
302547
- const cmmdHeartbeatRuntimeRouteLayer = registerProxyRoute({
302941
+ registerProxyRoute({
302548
302942
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/heartbeat",
302549
302943
  method: "POST",
302550
302944
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/heartbeat",
302551
302945
  orgIdSource: "none",
302552
302946
  responseShape: "unwrapData"
302553
302947
  });
302554
- const cmmdGrantRuntimeAccessRouteLayer = registerProxyRoute({
302948
+ registerProxyRoute({
302555
302949
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/access-grants",
302556
302950
  method: "POST",
302557
302951
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/access-grants",
302558
302952
  orgIdSource: "none",
302559
302953
  responseShape: "unwrapData"
302560
302954
  });
302561
- const cmmdRevokeRuntimeAccessRouteLayer = registerProxyRoute({
302955
+ registerProxyRoute({
302562
302956
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/access-grants/:grantId/revoke",
302563
302957
  method: "POST",
302564
302958
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/access-grants/:grantId/revoke",
@@ -302566,46 +302960,60 @@ const cmmdRevokeRuntimeAccessRouteLayer = registerProxyRoute({
302566
302960
  responseShape: "unwrapData",
302567
302961
  successStatus: 200
302568
302962
  });
302569
- const cmmdCreateRelayControlRouteLayer = registerProxyRoute({
302963
+ registerProxyRoute({
302570
302964
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/relay-routes",
302571
302965
  method: "POST",
302572
302966
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/relay-routes",
302573
302967
  orgIdSource: "none",
302574
302968
  responseShape: "unwrapData"
302575
302969
  });
302576
- const cmmdCreateRelayActionGrantRouteLayer = registerProxyRoute({
302970
+ registerProxyRoute({
302577
302971
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/relay-action-grants",
302578
302972
  method: "POST",
302579
302973
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/relay-action-grants",
302580
302974
  orgIdSource: "none",
302581
302975
  responseShape: "unwrapData"
302582
302976
  });
302583
- const cmmdReplaceRuntimeInventoryRouteLayer = registerProxyRoute({
302977
+ registerProxyRoute({
302584
302978
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/inventory",
302585
302979
  method: "PUT",
302586
302980
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/inventory",
302587
302981
  orgIdSource: "none",
302588
302982
  responseShape: "unwrapData"
302589
302983
  });
302590
- const cmmdListRuntimeInventoryRouteLayer = registerProxyRoute({
302984
+ registerProxyRoute({
302591
302985
  forgePath: "/api/cmmd/runtime-inventory",
302592
302986
  method: "GET",
302593
302987
  cmmdPath: "/api/forge/context/runtime-inventory",
302594
302988
  orgIdSource: "none",
302595
302989
  responseShape: "unwrapData"
302596
302990
  });
302991
+ registerProxyRoute({
302992
+ forgePath: "/api/cmmd/threads/:runtimeId/:threadId/lifecycle-intent",
302993
+ method: "PUT",
302994
+ cmmdPath: "/api/forge/context/threads/:runtimeId/:threadId/lifecycle-intent",
302995
+ orgIdSource: "none",
302996
+ requestBody: "json",
302997
+ responseShape: "unwrapData"
302998
+ });
302999
+ registerProxyRoute({
303000
+ forgePath: "/api/cmmd/threads/:runtimeId/:threadId/lifecycle-intent",
303001
+ method: "DELETE",
303002
+ cmmdPath: "/api/forge/context/threads/:runtimeId/:threadId/lifecycle-intent",
303003
+ orgIdSource: "none"
303004
+ });
302597
303005
  /**
302598
303006
  * Owner-scoped, bounded control-plane observation. This is intentionally
302599
303007
  * separate from the runtime inventory publisher and never wakes a runtime.
302600
303008
  */
302601
- const cmmdGetRuntimeDiagnosticsRouteLayer = registerProxyRoute({
303009
+ registerProxyRoute({
302602
303010
  forgePath: "/api/cmmd/runtime-diagnostics/v2/runtimes/:runtimeId",
302603
303011
  method: "GET",
302604
303012
  cmmdPath: "/api/forge/context/runtime-diagnostics/v2/runtimes/:runtimeId",
302605
303013
  orgIdSource: "none",
302606
303014
  responseShape: "unwrapData"
302607
303015
  });
302608
- const cmmdProvisionAuthRuntimeRouteLayer = registerProxyRoute({
303016
+ registerProxyRoute({
302609
303017
  forgePath: "/api/cmmd/auth-runtime",
302610
303018
  method: "POST",
302611
303019
  cmmdPath: "/api/forge/context/auth-runtime",
@@ -302613,21 +303021,21 @@ const cmmdProvisionAuthRuntimeRouteLayer = registerProxyRoute({
302613
303021
  responseShape: "unwrapData",
302614
303022
  requestBody: "none"
302615
303023
  });
302616
- const cmmdGetAuthRuntimeRouteLayer = registerProxyRoute({
303024
+ registerProxyRoute({
302617
303025
  forgePath: "/api/cmmd/auth-runtime",
302618
303026
  method: "GET",
302619
303027
  cmmdPath: "/api/forge/context/auth-runtime",
302620
303028
  orgIdSource: "none",
302621
303029
  responseShape: "unwrapData"
302622
303030
  });
302623
- const cmmdDestroyAuthRuntimeRouteLayer = registerProxyRoute({
303031
+ registerProxyRoute({
302624
303032
  forgePath: "/api/cmmd/auth-runtime",
302625
303033
  method: "DELETE",
302626
303034
  cmmdPath: "/api/forge/context/auth-runtime",
302627
303035
  orgIdSource: "none",
302628
303036
  responseShape: "unwrapData"
302629
303037
  });
302630
- const cmmdConnectAuthRuntimeRouteLayer = registerProxyRoute({
303038
+ registerProxyRoute({
302631
303039
  forgePath: "/api/cmmd/auth-runtime/connect",
302632
303040
  method: "POST",
302633
303041
  cmmdPath: "/api/forge/context/auth-runtime/connect",
@@ -302635,14 +303043,14 @@ const cmmdConnectAuthRuntimeRouteLayer = registerProxyRoute({
302635
303043
  responseShape: "unwrapData",
302636
303044
  requestBody: "none"
302637
303045
  });
302638
- const cmmdGetProviderAccountsRouteLayer = registerProxyRoute({
303046
+ registerProxyRoute({
302639
303047
  forgePath: "/api/cmmd/providers/accounts",
302640
303048
  method: "GET",
302641
303049
  cmmdPath: "/api/forge/context/providers/accounts",
302642
303050
  orgIdSource: "none",
302643
303051
  responseShape: "unwrapData"
302644
303052
  });
302645
- const cmmdDeleteProviderAccountRouteLayer = registerProxyRoute({
303053
+ registerProxyRoute({
302646
303054
  forgePath: "/api/cmmd/providers/accounts/:id",
302647
303055
  method: "DELETE",
302648
303056
  cmmdPath: "/api/forge/context/providers/accounts/:id",
@@ -302650,23 +303058,29 @@ const cmmdDeleteProviderAccountRouteLayer = registerProxyRoute({
302650
303058
  responseShape: "unwrapData",
302651
303059
  requestBody: "none"
302652
303060
  });
302653
- const cmmdSetProviderAccountDefaultRouteLayer = registerProxyRoute({
303061
+ registerProxyRoute({
302654
303062
  forgePath: "/api/cmmd/providers/accounts/default",
302655
303063
  method: "PUT",
302656
303064
  cmmdPath: "/api/forge/context/providers/accounts/default",
302657
303065
  orgIdSource: "none",
302658
303066
  responseShape: "unwrapData"
302659
303067
  });
302660
- const cmmdGetProviderUsageRouteLayer = add$1("GET", "/api/cmmd/providers/usage", require_Schema$1.gen(function* () {
302661
- const request = yield* require_HttpServer.HttpServerRequest;
302662
- const outcome = yield* runCmmdRestProxy(yield* (yield* ServerAuth).authenticateHttpRequest(request), (jwt) => cmmdGateway.request({
303068
+ registerProxyHandler({
303069
+ forgePath: "/api/cmmd/providers/usage",
303070
+ method: "GET",
303071
+ parse: () => require_Schema$1.succeed({
303072
+ ok: true,
303073
+ value: void 0
303074
+ }),
303075
+ run: (_parsed, { session }) => runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.request({
302663
303076
  method: "GET",
302664
303077
  jwt,
302665
303078
  path: "/api/forge/context/providers/usage"
302666
- }));
302667
- if (!outcome.ok) return buildProxyErrorResponse(outcome.error);
302668
- return require_HttpServer.jsonUnsafe(unwrapForgeEnvelope(outcome.value), { status: 200 });
302669
- }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
303079
+ }), (value) => ({
303080
+ status: 200,
303081
+ body: unwrapForgeEnvelope(value)
303082
+ }))
303083
+ });
302670
303084
  function parseProviderUsageRefreshInput(rawBody) {
302671
303085
  if (rawBody === null || typeof rawBody !== "object") return null;
302672
303086
  const body = rawBody;
@@ -302748,56 +303162,56 @@ function makeRefreshProviderUsageHandler(dependencies = {}) {
302748
303162
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error)));
302749
303163
  }
302750
303164
  const cmmdRefreshProviderUsageRouteLayer = add$1("POST", "/api/cmmd/providers/usage/refresh", makeRefreshProviderUsageHandler());
302751
- const cmmdGetUserCodexCredentialRouteLayer = registerProxyRoute({
303165
+ registerProxyRoute({
302752
303166
  forgePath: "/api/cmmd/providers/codex/credential",
302753
303167
  method: "GET",
302754
303168
  cmmdPath: "/api/forge/context/providers/codex/credential",
302755
303169
  orgIdSource: "none",
302756
303170
  responseShape: "unwrapData"
302757
303171
  });
302758
- const cmmdDeleteUserCodexCredentialRouteLayer = registerProxyRoute({
303172
+ registerProxyRoute({
302759
303173
  forgePath: "/api/cmmd/providers/codex/credential",
302760
303174
  method: "DELETE",
302761
303175
  cmmdPath: "/api/forge/context/providers/codex/credential",
302762
303176
  orgIdSource: "none",
302763
303177
  responseShape: "unwrapData"
302764
303178
  });
302765
- const cmmdGetUserClaudeCredentialRouteLayer = registerProxyRoute({
303179
+ registerProxyRoute({
302766
303180
  forgePath: "/api/cmmd/providers/claude/credential",
302767
303181
  method: "GET",
302768
303182
  cmmdPath: "/api/forge/context/providers/claude/credential",
302769
303183
  orgIdSource: "none",
302770
303184
  responseShape: "unwrapData"
302771
303185
  });
302772
- const cmmdDeleteUserClaudeCredentialRouteLayer = registerProxyRoute({
303186
+ registerProxyRoute({
302773
303187
  forgePath: "/api/cmmd/providers/claude/credential",
302774
303188
  method: "DELETE",
302775
303189
  cmmdPath: "/api/forge/context/providers/claude/credential",
302776
303190
  orgIdSource: "none",
302777
303191
  responseShape: "unwrapData"
302778
303192
  });
302779
- const cmmdGetClaudeRuntimeReadinessRouteLayer = registerProxyRoute({
303193
+ registerProxyRoute({
302780
303194
  forgePath: "/api/cmmd/providers/claude/runtime-readiness/:runtimeId",
302781
303195
  method: "GET",
302782
303196
  cmmdPath: "/api/forge/context/providers/claude/runtime-readiness/:runtimeId",
302783
303197
  orgIdSource: "none",
302784
303198
  responseShape: "unwrapData"
302785
303199
  });
302786
- const cmmdAppendRuntimeThreadEventsRouteLayer = registerProxyRoute({
303200
+ registerProxyRoute({
302787
303201
  forgePath: "/api/cmmd/devices/runtimes/:runtimeId/threads/:threadId/events",
302788
303202
  method: "POST",
302789
303203
  cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/threads/:threadId/events",
302790
303204
  orgIdSource: "none",
302791
303205
  responseShape: "unwrapData"
302792
303206
  });
302793
- const cmmdGetRuntimeThreadReplicaRouteLayer = registerProxyRoute({
303207
+ registerProxyRoute({
302794
303208
  forgePath: "/api/cmmd/threads/:runtimeId/:threadId",
302795
303209
  method: "GET",
302796
303210
  cmmdPath: "/api/forge/context/threads/:runtimeId/:threadId",
302797
303211
  orgIdSource: "none",
302798
303212
  responseShape: "unwrapData"
302799
303213
  });
302800
- const cmmdRenameDeviceRouteLayer = registerProxyRoute({
303214
+ registerProxyRoute({
302801
303215
  forgePath: "/api/cmmd/devices/:deviceId/rename",
302802
303216
  method: "POST",
302803
303217
  cmmdPath: "/api/forge/context/devices/:deviceId/rename",
@@ -302813,7 +303227,7 @@ const cmmdRenameDeviceRouteLayer = registerProxyRoute({
302813
303227
  * the status and the code reach the browser unchanged, which is what lets the
302814
303228
  * rename field say something specific instead of "something went wrong".
302815
303229
  */
302816
- const cmmdRenameForgeRuntimeRouteLayer = registerProxyRoute({
303230
+ registerProxyRoute({
302817
303231
  forgePath: "/api/cmmd/forge-runtimes/:runtimeId/rename",
302818
303232
  method: "POST",
302819
303233
  cmmdPath: "/api/forge/context/runtimes/:runtimeId/rename",
@@ -302821,7 +303235,7 @@ const cmmdRenameForgeRuntimeRouteLayer = registerProxyRoute({
302821
303235
  responseShape: "unwrapData",
302822
303236
  successStatus: 200
302823
303237
  });
302824
- const cmmdRevokeDeviceRouteLayer = registerProxyRoute({
303238
+ registerProxyRoute({
302825
303239
  forgePath: "/api/cmmd/devices/:deviceId/revoke",
302826
303240
  method: "POST",
302827
303241
  cmmdPath: "/api/forge/context/devices/:deviceId/revoke",
@@ -302830,24 +303244,21 @@ const cmmdRevokeDeviceRouteLayer = registerProxyRoute({
302830
303244
  requestBody: "none",
302831
303245
  successStatus: 200
302832
303246
  });
302833
- const cmmdListConnectorsRouteLayer = registerProxyRoute({
303247
+ registerProxyRoute({
302834
303248
  forgePath: "/api/cmmd/connectors",
302835
303249
  method: "GET",
302836
303250
  cmmdPath: "/api/forge/context/connectors",
302837
303251
  orgIdSource: "none"
302838
303252
  });
302839
- const cmmdInstallConnectorRouteLayer = registerProxyRoute({
303253
+ registerProxyRoute({
302840
303254
  forgePath: "/api/cmmd/connectors/:connectorId/install",
302841
303255
  method: "POST",
302842
303256
  cmmdPath: "/api/forge/context/connectors/:connectorId/install",
302843
303257
  orgIdSource: "none"
302844
303258
  });
302845
303259
  const cmmdForgeCloudProjectsListRouteLayer = add$1("GET", "/api/cmmd/forge-cloud-projects", require_Schema$1.gen(function* () {
302846
- const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects");
302847
- if (!accessToken) return buildCmmdAuthErrorResponse({
302848
- code: "CMMD_AUTH_REQUIRED",
302849
- message: "CMMD authentication is required. Sign in again to continue."
302850
- });
303260
+ const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects");
303261
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
302851
303262
  const upstreamUrl = `${resolveCommandAppUrl()}${CMMD_CLOUD_PROJECTS_PATH}`;
302852
303263
  const upstreamOrError = yield* fetchCmmdUpstreamWithRetry(() => fetch(upstreamUrl, { headers: {
302853
303264
  Authorization: `Bearer ${accessToken}`,
@@ -302858,10 +303269,7 @@ const cmmdForgeCloudProjectsListRouteLayer = add$1("GET", "/api/cmmd/forge-cloud
302858
303269
  code: "CMMD_UNAVAILABLE"
302859
303270
  }, { status: 503 });
302860
303271
  const upstream = upstreamOrError.res;
302861
- if (upstream.status === 401 || upstream.status === 403) return buildCmmdAuthErrorResponse({
302862
- code: "CMMD_AUTH_REQUIRED",
302863
- message: "CMMD authentication expired. Sign in again to continue."
302864
- });
303272
+ if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
302865
303273
  const bodyOrError = yield* require_Schema$1.tryPromise(() => upstream.text()).pipe(require_Schema$1.map((text) => ({
302866
303274
  ok: true,
302867
303275
  text
@@ -302883,35 +303291,35 @@ const cmmdForgeCloudProjectsListRouteLayer = add$1("GET", "/api/cmmd/forge-cloud
302883
303291
  headers: { "content-type": "application/json" }
302884
303292
  });
302885
303293
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
302886
- const cmmdForgeCloudProjectRegisterRouteLayer = registerProxyRoute({
303294
+ registerProxyRoute({
302887
303295
  forgePath: "/api/cmmd/forge-cloud-projects",
302888
303296
  method: "POST",
302889
303297
  cmmdPath: CMMD_CLOUD_PROJECTS_PATH,
302890
303298
  orgIdSource: "none",
302891
303299
  responseShape: "unwrapData"
302892
303300
  });
302893
- const cmmdForgeCloudProjectUnregisterRouteLayer = registerProxyRoute({
303301
+ registerProxyRoute({
302894
303302
  forgePath: "/api/cmmd/forge-cloud-projects/:projectId",
302895
303303
  method: "DELETE",
302896
303304
  cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId`,
302897
303305
  orgIdSource: "none",
302898
303306
  responseShape: "unwrapData"
302899
303307
  });
302900
- const cmmdForgeCloudProjectLifecyclePreflightRouteLayer = registerProxyRoute({
303308
+ registerProxyRoute({
302901
303309
  forgePath: "/api/cmmd/forge-cloud-projects/:projectId/lifecycle-preflight",
302902
303310
  method: "GET",
302903
303311
  cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId/lifecycle-preflight`,
302904
303312
  orgIdSource: "none",
302905
303313
  responseShape: "unwrapData"
302906
303314
  });
302907
- const cmmdForgeCloudProjectRemovalPreviewRouteLayer = registerProxyRoute({
303315
+ registerProxyRoute({
302908
303316
  forgePath: "/api/cmmd/forge-cloud-projects/:projectId/removal-preview",
302909
303317
  method: "GET",
302910
303318
  cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId/removal-preview`,
302911
303319
  orgIdSource: "none",
302912
303320
  responseShape: "unwrapData"
302913
303321
  });
302914
- const cmmdForgeCloudProjectRemovalRouteLayer = registerProxyRoute({
303322
+ registerProxyRoute({
302915
303323
  forgePath: "/api/cmmd/forge-cloud-projects/:projectId/removal",
302916
303324
  method: "POST",
302917
303325
  cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId/removal`,
@@ -302920,7 +303328,7 @@ const cmmdForgeCloudProjectRemovalRouteLayer = registerProxyRoute({
302920
303328
  successStatus: 202,
302921
303329
  workIntakeInvalidation: "completedPermanentRemoval"
302922
303330
  });
302923
- const cmmdForgeCloudProjectRemovalReceiptRouteLayer = registerProxyRoute({
303331
+ registerProxyRoute({
302924
303332
  forgePath: "/api/cmmd/forge-cloud-project-removals/:operationId",
302925
303333
  method: "GET",
302926
303334
  cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/removals/:operationId`,
@@ -302984,11 +303392,8 @@ function makeFetchCloudProjectsFrameEffect(upstreamUrl, accessToken) {
302984
303392
  })).pipe(require_Schema$1.catch_(() => require_Schema$1.succeed(null)));
302985
303393
  }
302986
303394
  const cmmdForgeCloudProjectsEventsRouteLayer = add$1("GET", "/api/cmmd/forge-cloud-projects/events", require_Schema$1.gen(function* () {
302987
- const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects/events");
302988
- if (!accessToken) return buildCmmdAuthErrorResponse({
302989
- code: "CMMD_AUTH_REQUIRED",
302990
- message: "CMMD authentication is required. Sign in again to continue."
302991
- });
303395
+ const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects/events");
303396
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
302992
303397
  const fetchCloudProjectsFrame = makeFetchCloudProjectsFrameEffect(`${resolveCommandAppUrl()}${CMMD_CLOUD_PROJECTS_PATH}`, accessToken);
302993
303398
  const dataStream = require_Path.concat(require_Path.fromEffect(fetchCloudProjectsFrame), require_Path.tick(FORGE_RUNTIMES_POLL_INTERVAL).pipe(require_Path.mapEffect(() => fetchCloudProjectsFrame))).pipe(require_Path.filter((frame) => frame !== null));
302994
303399
  const keepaliveStream = require_Path.tick(FORGE_RUNTIMES_KEEPALIVE_INTERVAL).pipe(require_Path.map(() => FORGE_RUNTIMES_KEEPALIVE_FRAME));
@@ -303061,11 +303466,8 @@ function fetchCmmdUpstreamWithRetry(send, policy = "idempotent") {
303061
303466
  }
303062
303467
  const cmmdForgeRuntimesEnsureRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/ensure", require_Schema$1.gen(function* () {
303063
303468
  const request = yield* require_HttpServer.HttpServerRequest;
303064
- const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/ensure");
303065
- if (!accessToken) return buildCmmdAuthErrorResponse({
303066
- code: "CMMD_AUTH_REQUIRED",
303067
- message: "CMMD authentication is required. Sign in again to continue."
303068
- });
303469
+ const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/ensure");
303470
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
303069
303471
  const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(require_Schema$1.catch_(() => require_Schema$1.succeed({}))));
303070
303472
  if (!scopedBody) return require_HttpServer.jsonUnsafe({ error: "A valid organizationId is required when organization scope is provided." }, { status: 400 });
303071
303473
  const upstreamUrl = `${resolveCommandAppUrl()}/api/forge/context/runtimes/ensure`;
@@ -303084,10 +303486,7 @@ const cmmdForgeRuntimesEnsureRouteLayer = add$1("POST", "/api/cmmd/forge-runtime
303084
303486
  code: "CMMD_UNAVAILABLE"
303085
303487
  }, { status: 503 });
303086
303488
  const upstream = upstreamOrError.res;
303087
- if (upstream.status === 401 || upstream.status === 403) return buildCmmdAuthErrorResponse({
303088
- code: "CMMD_AUTH_REQUIRED",
303089
- message: "CMMD authentication expired. Sign in again to continue."
303090
- });
303489
+ if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
303091
303490
  const bodyOrError = yield* require_Schema$1.tryPromise(() => upstream.text()).pipe(require_Schema$1.map((text) => ({
303092
303491
  ok: true,
303093
303492
  text
@@ -303111,11 +303510,8 @@ const cmmdForgeRuntimesEnsureRouteLayer = add$1("POST", "/api/cmmd/forge-runtime
303111
303510
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
303112
303511
  const cmmdForgeRuntimesConnectRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/:runtimeId/connect", require_Schema$1.gen(function* () {
303113
303512
  const request = yield* require_HttpServer.HttpServerRequest;
303114
- const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/connect");
303115
- if (!accessToken) return buildCmmdAuthErrorResponse({
303116
- code: "CMMD_AUTH_REQUIRED",
303117
- message: "CMMD authentication is required. Sign in again to continue."
303118
- });
303513
+ const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/connect");
303514
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
303119
303515
  const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
303120
303516
  if (!runtimeId) return require_HttpServer.jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
303121
303517
  const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(require_Schema$1.catch_(() => require_Schema$1.succeed({}))));
@@ -303136,10 +303532,7 @@ const cmmdForgeRuntimesConnectRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
303136
303532
  code: "CMMD_UNAVAILABLE"
303137
303533
  }, { status: 503 });
303138
303534
  const upstream = upstreamOrError.res;
303139
- if (upstream.status === 401 || upstream.status === 403) return buildCmmdAuthErrorResponse({
303140
- code: "CMMD_AUTH_REQUIRED",
303141
- message: "CMMD authentication expired. Sign in again to continue."
303142
- });
303535
+ if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
303143
303536
  const bodyOrError = yield* require_Schema$1.tryPromise(() => upstream.text()).pipe(require_Schema$1.map((text) => ({
303144
303537
  ok: true,
303145
303538
  text
@@ -303163,11 +303556,8 @@ const cmmdForgeRuntimesConnectRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
303163
303556
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
303164
303557
  const cmmdForgeRuntimesStatusRouteLayer = add$1("GET", "/api/cmmd/forge-runtimes/:runtimeId/status", require_Schema$1.gen(function* () {
303165
303558
  const request = yield* require_HttpServer.HttpServerRequest;
303166
- const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/status");
303167
- if (!accessToken) return buildCmmdAuthErrorResponse({
303168
- code: "CMMD_AUTH_REQUIRED",
303169
- message: "CMMD authentication is required. Sign in again to continue."
303170
- });
303559
+ const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/status");
303560
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
303171
303561
  const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
303172
303562
  if (!runtimeId) return require_HttpServer.jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
303173
303563
  const upstreamUrl = `${resolveCommandAppUrl()}/api/forge/context/runtimes/${encodeURIComponent(runtimeId)}/status`;
@@ -303183,10 +303573,7 @@ const cmmdForgeRuntimesStatusRouteLayer = add$1("GET", "/api/cmmd/forge-runtimes
303183
303573
  code: "CMMD_UNAVAILABLE"
303184
303574
  }, { status: 503 });
303185
303575
  const upstream = upstreamOrError.res;
303186
- if (upstream.status === 401 || upstream.status === 403) return buildCmmdAuthErrorResponse({
303187
- code: "CMMD_AUTH_REQUIRED",
303188
- message: "CMMD authentication expired. Sign in again to continue."
303189
- });
303576
+ if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
303190
303577
  const bodyOrError = yield* require_Schema$1.tryPromise(() => upstream.text()).pipe(require_Schema$1.map((text) => ({
303191
303578
  ok: true,
303192
303579
  text
@@ -303217,10 +303604,7 @@ function makeCmmdForgeRuntimesLifecycleHandler(action) {
303217
303604
  subject: session.subject,
303218
303605
  logPrefix: `forge-runtimes/${action}`
303219
303606
  });
303220
- if (!accessToken) return buildCmmdAuthErrorResponse({
303221
- code: "CMMD_AUTH_REQUIRED",
303222
- message: "CMMD authentication is required. Sign in again to continue."
303223
- });
303607
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
303224
303608
  const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
303225
303609
  if (!runtimeId) return require_HttpServer.jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
303226
303610
  const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(require_Schema$1.catch_(() => require_Schema$1.succeed({}))));
@@ -303241,10 +303625,7 @@ function makeCmmdForgeRuntimesLifecycleHandler(action) {
303241
303625
  code: "CMMD_UNAVAILABLE"
303242
303626
  }, { status: 503 });
303243
303627
  const upstream = upstreamOrError.res;
303244
- if (upstream.status === 401 || upstream.status === 403) return buildCmmdAuthErrorResponse({
303245
- code: "CMMD_AUTH_REQUIRED",
303246
- message: "CMMD authentication expired. Sign in again to continue."
303247
- });
303628
+ if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
303248
303629
  const bodyOrError = yield* require_Schema$1.tryPromise(() => upstream.text()).pipe(require_Schema$1.map((text) => ({
303249
303630
  ok: true,
303250
303631
  text
@@ -303277,11 +303658,8 @@ const cmmdForgeRuntimesRecycleRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
303277
303658
  const cmmdForgeRuntimesUpdateCommitRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/:runtimeId/update-commit", __cmmdForgeRuntimesUpdateCommitHandlerForTests);
303278
303659
  const cmmdForgeRuntimesDestroyRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/:runtimeId/destroy", require_Schema$1.gen(function* () {
303279
303660
  const request = yield* require_HttpServer.HttpServerRequest;
303280
- const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/destroy");
303281
- if (!accessToken) return buildCmmdAuthErrorResponse({
303282
- code: "CMMD_AUTH_REQUIRED",
303283
- message: "CMMD authentication is required. Sign in again to continue."
303284
- });
303661
+ const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/destroy");
303662
+ if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
303285
303663
  const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
303286
303664
  if (!runtimeId) return require_HttpServer.jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
303287
303665
  const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(require_Schema$1.catch_(() => require_Schema$1.succeed({}))));
@@ -303302,10 +303680,7 @@ const cmmdForgeRuntimesDestroyRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
303302
303680
  code: "CMMD_UNAVAILABLE"
303303
303681
  }, { status: 503 });
303304
303682
  const upstream = upstreamOrError.res;
303305
- if (upstream.status === 401 || upstream.status === 403) return buildCmmdAuthErrorResponse({
303306
- code: "CMMD_AUTH_REQUIRED",
303307
- message: "CMMD authentication expired. Sign in again to continue."
303308
- });
303683
+ if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
303309
303684
  const bodyOrError = yield* require_Schema$1.tryPromise(() => upstream.text()).pipe(require_Schema$1.map((text) => ({
303310
303685
  ok: true,
303311
303686
  text
@@ -303327,6 +303702,7 @@ const cmmdForgeRuntimesDestroyRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
303327
303702
  headers: { "content-type": "application/json" }
303328
303703
  });
303329
303704
  }).pipe(require_Schema$1.catchTag("AuthError", (error) => respondToAuthError(error))));
303705
+ const cmmdProxyRouteLayers = registeredProxyRouteLayers().slice(__cmmdProxyRouteLayersStartIndex);
303330
303706
  //#endregion
303331
303707
  //#region src/cmmdData/projectTeamProxyRoutes.ts
303332
303708
  const cmmdListWorkspaceMembersRouteLayer = registerProxyRoute({
@@ -304569,6 +304945,103 @@ function recordRuntimeReplicationOutboxDiagnostics(diagnostics, now = Date.now()
304569
304945
  ]).pipe(require_Schema$1.asVoid);
304570
304946
  }
304571
304947
  //#endregion
304948
+ //#region src/runtimeReplication/pendingLifecycleIntents.ts
304949
+ /**
304950
+ * The newest moment a person or a turn touched this thread, mirroring the
304951
+ * client's `threadLastActivityAt` over the full thread rather than its shell:
304952
+ * the shell's `latestUserMessageAt` is projected from exactly these messages.
304953
+ */
304954
+ function readModelThreadLastActivityAt(thread) {
304955
+ const candidates = [
304956
+ ...thread.messages.filter((message) => message.role === "user").map((m) => m.createdAt),
304957
+ thread.latestTurn?.requestedAt,
304958
+ thread.latestTurn?.startedAt,
304959
+ thread.latestTurn?.completedAt
304960
+ ];
304961
+ let latest = null;
304962
+ let latestTimestamp = Number.NEGATIVE_INFINITY;
304963
+ for (const candidate of candidates) {
304964
+ if (candidate === null || candidate === void 0) continue;
304965
+ const timestamp = Date.parse(candidate);
304966
+ if (timestamp > latestTimestamp) {
304967
+ latest = candidate;
304968
+ latestTimestamp = timestamp;
304969
+ }
304970
+ }
304971
+ return latest;
304972
+ }
304973
+ function intentIsSpent(thread, intent) {
304974
+ const lastActivityAt = readModelThreadLastActivityAt(thread);
304975
+ if (lastActivityAt === null) return false;
304976
+ const activity = Date.parse(lastActivityAt);
304977
+ const requested = Date.parse(intent.requestedAt);
304978
+ return Number.isFinite(activity) && Number.isFinite(requested) && activity > requested;
304979
+ }
304980
+ function commandFor(runtimeId, intent) {
304981
+ const commandId = lifecycleIntentCommandId(runtimeId, intent.threadId, intent.requestedAt);
304982
+ const threadId = ThreadId.make(intent.threadId);
304983
+ return intent.action === "settle" ? {
304984
+ type: "thread.settle",
304985
+ commandId,
304986
+ threadId,
304987
+ settledOverride: "settled"
304988
+ } : {
304989
+ type: "thread.unsettle",
304990
+ commandId,
304991
+ threadId
304992
+ };
304993
+ }
304994
+ const applyOne = require_Schema$1.fn("applyLifecycleIntent")(function* (runtimeId, intent, dependencies) {
304995
+ const base = {
304996
+ runtimeId,
304997
+ threadId: intent.threadId,
304998
+ action: intent.action,
304999
+ requestedAt: intent.requestedAt
305000
+ };
305001
+ const report = (outcome, detail) => dependencies.log({
305002
+ ...base,
305003
+ outcome,
305004
+ ...detail === void 0 ? {} : { detail }
305005
+ }).pipe(require_Schema$1.as(outcome));
305006
+ const thread = (yield* dependencies.getReadModel()).threads.find((candidate) => candidate.id === intent.threadId);
305007
+ if (thread === void 0) return yield* report("missing-thread");
305008
+ if (intentIsSpent(thread, intent)) return yield* report("spent");
305009
+ return yield* dependencies.dispatch(commandFor(runtimeId, intent)).pipe(require_Schema$1.flatMap(() => report("applied")), require_Schema$1.catch_((error) => error._tag === "OrchestrationCommandInvariantError" || error._tag === "OrchestrationCommandPreviouslyRejectedError" ? report("refused", error.detail) : report("failed", error.message)));
305010
+ });
305011
+ /**
305012
+ * One tick: list, apply each, acknowledge everything that got an answer.
305013
+ *
305014
+ * A signed-out owner is not an error to retry into the log every five
305015
+ * minutes; it is a state the desktop leaves when someone signs in, so it is
305016
+ * logged once at info and the tick ends. Any other listing or acknowledgement
305017
+ * failure is returned typed, and the intents stay pending on CMMD.
305018
+ */
305019
+ function applyPendingLifecycleIntents(input, dependencies) {
305020
+ return require_Schema$1.gen(function* () {
305021
+ const intents = yield* dependencies.listPending();
305022
+ if (intents.length === 0) return;
305023
+ const answered = [];
305024
+ for (const intent of intents) if ((yield* applyOne(input.runtimeId, intent, dependencies)) !== "failed") answered.push({
305025
+ threadId: intent.threadId,
305026
+ requestedAt: intent.requestedAt
305027
+ });
305028
+ if (answered.length === 0) return;
305029
+ yield* dependencies.acknowledge(answered);
305030
+ }).pipe(require_Schema$1.catch_((error) => error.kind === "auth" ? require_Schema$1.logInfo("Lifecycle intents skipped: CMMD sign-in is required.", {
305031
+ runtimeId: input.runtimeId,
305032
+ code: error.code
305033
+ }) : require_Schema$1.fail(error)));
305034
+ }
305035
+ /**
305036
+ * One structured line per intent, so a row that "came back" after a wake can
305037
+ * be explained from the log: applied, refused by the decider, or spent by
305038
+ * newer activity.
305039
+ */
305040
+ function logLifecycleIntentOutcome(outcome) {
305041
+ const message = `Lifecycle intent ${outcome.outcome}.`;
305042
+ return outcome.outcome === "refused" || outcome.outcome === "failed" ? require_Schema$1.logWarning(message, outcome) : require_Schema$1.logInfo(message, outcome);
305043
+ }
305044
+ //#endregion
304572
305045
  //#region src/runtimeReplication/processOutboxItem.ts
304573
305046
  function publicationMetricAttributes(item, outcome, failure) {
304574
305047
  return {
@@ -304765,6 +305238,31 @@ const RuntimeReplicationLive = require_Schema$1.effect(RuntimeReplication, requi
304765
305238
  }).pipe(require_Schema$1.asVoid, require_Schema$1.catchCause((cause) => require_Schema$1.logError("Runtime replication reconciliation failed.", { cause })));
304766
305239
  const heartbeat = enqueueAll.pipe(require_Schema$1.repeat(require_Schema$1.spaced("5 minutes")), require_Schema$1.forkScoped);
304767
305240
  /**
305241
+ * Settle and un-settle requests a person recorded in CMMD while this
305242
+ * runtime was offline. The first tick runs at once, which is the
305243
+ * startup case (this phase starts after the orchestration reactors);
305244
+ * every heartbeat after that picks up requests made while awake. The
305245
+ * tick handles its own expected failures; the supervisor restarts the
305246
+ * schedule if it ever dies between ticks.
305247
+ */
305248
+ const lifecycleIntents = runSupervisedRepeat({
305249
+ label: "Lifecycle intent applier",
305250
+ work: applyPendingLifecycleIntents({ runtimeId }, {
305251
+ listPending: () => client.listPendingLifecycleIntents({ runtimeId }),
305252
+ acknowledge: (intents) => client.acknowledgeLifecycleIntents({
305253
+ runtimeId,
305254
+ intents
305255
+ }),
305256
+ dispatch: engine.dispatch,
305257
+ getReadModel: engine.getReadModel,
305258
+ log: logLifecycleIntentOutcome
305259
+ }).pipe(require_Schema$1.catchCause((cause) => require_Schema$1.logError("Lifecycle intent tick failed.", {
305260
+ cause,
305261
+ runtimeId
305262
+ }))),
305263
+ interval: "5 minutes"
305264
+ }).pipe(require_Schema$1.forkScoped);
305265
+ /**
304768
305266
  * Closes and reports whatever Active Hour interval is currently open,
304769
305267
  * every 5 minutes -- the same cadence as the inventory heartbeat, not
304770
305268
  * because the two are related, but because it is a reasonable default
@@ -304819,6 +305317,7 @@ const RuntimeReplicationLive = require_Schema$1.effect(RuntimeReplication, requi
304819
305317
  reactor,
304820
305318
  providerReactor,
304821
305319
  heartbeat,
305320
+ lifecycleIntents,
304822
305321
  activeHourFlush,
304823
305322
  worker,
304824
305323
  observeOutbox
@@ -314234,7 +314733,7 @@ const MiscRuntimeLayerLive = require_Schema$1.mergeAll(AnalyticsServiceLayerLive
314234
314733
  const RuntimeDependenciesWithoutPullRequestsLive = ReactorLayerLive.pipe(require_Schema$1.provideMerge(CheckpointingLayerLive), require_Schema$1.provideMerge(GitLayerLive), require_Schema$1.provideMerge(OrchestrationLayerLive), require_Schema$1.provideMerge(ProviderLayerLive), require_Schema$1.provideMerge(TerminalLayerLive), require_Schema$1.provideMerge(AgentBrowserManagerLive), require_Schema$1.provideMerge(require_Schema$1.mergeAll(ThreadDevRuntimeLive, DevTunnelLive.pipe(require_Schema$1.provide$1(ThreadDevRuntimeLive)))), require_Schema$1.provideMerge(PersistenceLayerLive), require_Schema$1.provideMerge(KeybindingsLive), require_Schema$1.provideMerge(ProviderRegistryLive), require_Schema$1.provideMerge(require_Schema$1.mergeAll(ServerSettingsLive, UsageServiceLive.pipe(require_Schema$1.provide$1(ServerSettingsLive), require_Schema$1.provide$1(UsageSessionLookupLive), require_Schema$1.provide$1(UsageRecordedSourceLive.pipe(require_Schema$1.provide$1(OrchestrationLayerLive), require_Schema$1.provide$1(RuntimeReplicationOutboxLive), require_Schema$1.provide$1(ProviderSessionRuntimeRepositoryLive), require_Schema$1.provide$1(TextGenerationSessionRepositoryLive)))))), require_Schema$1.provideMerge(WorkspaceLayerLive), require_Schema$1.provideMerge(WorkspaceReadinessStateLive), require_Schema$1.provideMerge(ProjectFaviconResolverLive), require_Schema$1.provideMerge(RepositoryIdentityResolverLive), require_Schema$1.provideMerge(ServerEnvironmentLive), require_Schema$1.provideMerge(AuthLayerLive), require_Schema$1.provideMerge(ServerSecretStoreLayerLive), require_Schema$1.provideMerge(require_Schema$1.mergeAll(CloudRedisCoordinationLive, CloudStateSyncLive.pipe(require_Schema$1.provide$1(PersistenceLayerLive)))), require_Schema$1.provideMerge(MiscRuntimeLayerLive));
314235
314734
  const RuntimeDependenciesLive = pullRequestServiceFactoryLayer.pipe(require_Schema$1.provideMerge(RuntimeDependenciesWithoutPullRequestsLive), require_Schema$1.provideMerge(cmmdProjectIdentityResolverLive.pipe(require_Schema$1.provide$1(RuntimeDependenciesWithoutPullRequestsLive))), require_Schema$1.provideMerge(pullRequestProviderRuntimeLive));
314236
314735
  const RuntimeServicesLive = ServerRuntimeStartupLive.pipe(require_Schema$1.provideMerge(RuntimeDependenciesLive));
314237
- const makeRoutesLayer = require_Schema$1.mergeAll(authBearerBootstrapRouteLayer, authBootstrapRouteLayer, authCommandBearerBootstrapRouteLayer, authCommandBootstrapRouteLayer, authOAuthTokenExchangeRouteLayer, authWebSocketTicketRouteLayer, authCmmdOAuthDeviceRouteLayer, authCmmdOAuthTokenRouteLayer, authCmmdPasswordTokenRouteLayer, authClientsRevokeOthersRouteLayer, authClientsRevokeRouteLayer, authClientsRouteLayer, authLogoutRouteLayer, authPairingLinksRevokeRouteLayer, authPairingLinksRouteLayer, authPairingCredentialRouteLayer, authSessionRouteLayer, authWebSocketTokenRouteLayer, authWebLoginRouteLayer, authWebCallbackRouteLayer, desktopLocalWebBridgePublishRouteLayer, desktopLocalWebBridgeBootstrapRouteLayer, desktopRelayControlPlaneRouteLayer, apiDocsHtmlRouteLayer, apiDocsOpenApiRouteLayer, pulseSignalStateListRouteLayer, pulseSignalStateUpsertRouteLayer, cmmdProfileRouteLayer, cmmdCreateBrainDocRouteLayer, cmmdUpdateTaskRouteLayer, cmmdUpsertTaskPullRequestRouteLayer, ...cmmdPullRequestRouteLayers, cmmdAddTaskCommentRouteLayer, cmmdWorkIntakeRouteLayer, cmmdWsTokenRouteLayer, cmmdSearchTasksRouteLayer, cmmdGetTaskCommentsRouteLayer, cmmdGetProjectCommentsRouteLayer, cmmdAddProjectCommentRouteLayer, cmmdUpdateProjectRouteLayer, cmmdGetOrgMembersRouteLayer, cmmdSimHostsRouteLayer, cmmdSimLeaseReadRouteLayer, cmmdSimLeaseClaimRouteLayer, cmmdSimLeaseReleaseRouteLayer, cmmdSimLeaseRenewRouteLayer, cmmdUploadTaskAttachmentRouteLayer, cmmdGetTaskAttachmentsRouteLayer, cmmdUpdateTaskCommentRouteLayer, cmmdDeleteTaskCommentRouteLayer, cmmdGetProjectRepositoryRouteLayer, cmmdListProjectRepositoriesRouteLayer, cmmdArchiveTaskRouteLayer, cmmdUnarchiveTaskRouteLayer, cmmdListTasksRouteLayer, cmmdCreateTaskRouteLayer, cmmdListCampaignsRouteLayer, cmmdGetCampaignRouteLayer, cmmdCreateCampaignRouteLayer, cmmdUpdateCampaignRouteLayer, cmmdDeleteCampaignRouteLayer, cmmdListSavedViewsRouteLayer, cmmdCreateSavedViewRouteLayer, cmmdImportSavedViewRouteLayer, cmmdUpdateSavedViewRouteLayer, cmmdDeleteSavedViewRouteLayer, cmmdListProjectsRouteLayer, cmmdGetProjectRouteLayer, cmmdCreateProjectRouteLayer, cmmdDeleteProjectRouteLayer, cmmdMoveProjectRouteLayer, cmmdGetProjectMembersRouteLayer, cmmdListWorkspaceMembersRouteLayer, cmmdAddProjectMemberRouteLayer, cmmdGetProjectMilestonesRouteLayer, cmmdCreateProjectMilestoneRouteLayer, cmmdUpdateProjectMilestoneRouteLayer, cmmdDeleteProjectMilestoneRouteLayer, cmmdGetProjectUpdatesRouteLayer, cmmdCreateProjectUpdateRouteLayer, cmmdUpdateProjectUpdateRouteLayer, cmmdDeleteProjectUpdateRouteLayer, cmmdImproveProjectContentRouteLayer, cmmdCreateProjectTaskDraftRouteLayer, cmmdGetProjectTaskDraftRouteLayer, cmmdUpdateProjectTaskDraftRouteLayer, cmmdPreviewProjectTaskDraftRouteLayer, cmmdCommitProjectTaskDraftRouteLayer, cmmdDiscardProjectTaskDraftRouteLayer, cmmdGetProjectLeadPlanRouteLayer, cmmdActivateProjectLeadAuthorityRouteLayer, cmmdGetProjectLeadReadinessRouteLayer, cmmdGetProjectLeadCapabilitiesRouteLayer, cmmdGetProjectLeadSummaryRouteLayer, cmmdGetProjectLeadDetailRouteLayer, cmmdGetProjectLeadBriefingRouteLayer, cmmdListProjectLeadEventsRouteLayer, cmmdExplainProjectLeadRouteLayer, cmmdPauseProjectLeadRouteLayer, cmmdResumeProjectLeadRouteLayer, cmmdReserveProjectLeadTaskRouteLayer, cmmdReleaseProjectLeadReservationRouteLayer, cmmdReconcileProjectLeadRouteLayer, cmmdResolveProjectLeadAttentionRouteLayer, cmmdClaimProjectLeadControllerRouteLayer, cmmdRenewProjectLeadControllerClaimRouteLayer, cmmdYieldProjectLeadControllerClaimRouteLayer, cmmdAcknowledgeProjectLeadControllerEventRouteLayer, cmmdRecordProjectLeadControllerDecisionRouteLayer, cmmdListForgeAutomationPresetsRouteLayer, cmmdListUserForgeAutomationRulesRouteLayer, cmmdCreateUserForgeAutomationRuleRouteLayer, cmmdUpdateUserForgeAutomationRuleRouteLayer, cmmdListUserForgeAutomationRunsRouteLayer, cmmdStartUserForgeAutomationRunRouteLayer, cmmdListForgeAutomationRulesRouteLayer, cmmdCreateForgeAutomationRuleRouteLayer, cmmdUpdateForgeAutomationRuleRouteLayer, cmmdListForgeAutomationRunsRouteLayer, cmmdStartForgeAutomationRunRouteLayer, cmmdGetForgeAutomationRunRouteLayer, cmmdRetryForgeAutomationRunRouteLayer, cmmdCancelForgeAutomationRunRouteLayer, cmmdApproveForgeAutomationEscalationRouteLayer, cmmdRejectForgeAutomationEscalationRouteLayer, cmmdListProjectAgentMembersRouteLayer, cmmdCreateProjectAgentMemberRouteLayer, cmmdGetProjectAgentMemberRouteLayer, cmmdRenameProjectAgentMemberRouteLayer, cmmdRetireProjectAgentMemberRouteLayer, cmmdUpdateProjectAgentMemberAvatarRouteLayer, cmmdListProjectAgentMemberInstancesRouteLayer, cmmdPreviewProjectAgentMemberConsolidationRouteLayer, cmmdApplyProjectAgentMemberConsolidationRouteLayer, cmmdPutProjectTaskAssignmentRouteLayer, cmmdListProjectBoardRouteLayer, cmmdGetProjectTaskWorkflowRouteLayer, cmmdUpdateProjectTaskWorkflowRouteLayer, cmmdCreateProjectBoardTaskRouteLayer, cmmdUpdateProjectBoardTaskRouteLayer, cmmdUpdateProjectBoardTaskStatusRouteLayer, cmmdListTaskExecutionOptionsRouteLayer, cmmdCreateTaskWorkSessionRouteLayer, cmmdListProjectWorkSessionsRouteLayer, cmmdGetWorkSessionRouteLayer, cmmdUpdateWorkSessionRouteLayer, cmmdAttachWorkSessionThreadRouteLayer, cmmdListTaskConversationsRouteLayer, cmmdLinkTaskConversationRouteLayer, cmmdGetTaskHistoryRouteLayer, cmmdGetTaskConversationRouteLayer, cmmdSpawnForgeThreadFromBoardTaskRouteLayer, cmmdListCenterBoardRouteLayer, cmmdCreateCenterBoardTaskRouteLayer, cmmdCreateFeedbackRouteLayer, cmmdUpdateCenterBoardTaskRouteLayer, cmmdMoveCenterBoardTaskRouteLayer, cmmdMoveProjectBoardTaskRouteLayer, cmmdArchiveProjectBoardTaskRouteLayer, cmmdUnarchiveProjectBoardTaskRouteLayer, cmmdArchiveCenterBoardTaskRouteLayer, cmmdUnarchiveCenterBoardTaskRouteLayer, cmmdBootstrapRouteLayer, cmmdGetAccountPreferencesRouteLayer, cmmdUpdateAccountPreferencesRouteLayer, cmmdGetOrgProviderPolicyRouteLayer, cmmdListChatsRouteLayer, cmmdGetChatRouteLayer, cmmdListDevicesRouteLayer, runtimeReplicationStatusRouteLayer, cmmdRegisterDeviceRouteLayer, cmmdHeartbeatRuntimeRouteLayer, cmmdGrantRuntimeAccessRouteLayer, cmmdRevokeRuntimeAccessRouteLayer, cmmdCreateRelayControlRouteLayer, cmmdCreateRelayActionGrantRouteLayer, cmmdReplaceRuntimeInventoryRouteLayer, cmmdListRuntimeInventoryRouteLayer, cmmdGetRuntimeDiagnosticsRouteLayer, cmmdProvisionAuthRuntimeRouteLayer, cmmdGetAuthRuntimeRouteLayer, cmmdDestroyAuthRuntimeRouteLayer, cmmdConnectAuthRuntimeRouteLayer, cmmdGetProviderAccountsRouteLayer, cmmdDeleteProviderAccountRouteLayer, cmmdSetProviderAccountDefaultRouteLayer, cmmdGetProviderUsageRouteLayer, cmmdRefreshProviderUsageRouteLayer, cmmdGetUserCodexCredentialRouteLayer, cmmdDeleteUserCodexCredentialRouteLayer, cmmdGetUserClaudeCredentialRouteLayer, cmmdDeleteUserClaudeCredentialRouteLayer, cmmdGetClaudeRuntimeReadinessRouteLayer, cmmdAppendRuntimeThreadEventsRouteLayer, cmmdGetRuntimeThreadReplicaRouteLayer, cmmdRenameDeviceRouteLayer, cmmdRevokeDeviceRouteLayer, cmmdInstallConnectorRouteLayer, cmmdListConnectorsRouteLayer, cmmdForgeCloudProjectsListRouteLayer, cmmdForgeCloudProjectsEventsRouteLayer, cmmdForgeCloudProjectRegisterRouteLayer, cmmdForgeCloudProjectUnregisterRouteLayer, cmmdForgeCloudProjectLifecyclePreflightRouteLayer, cmmdForgeCloudProjectRemovalRouteLayer, cmmdForgeCloudProjectRemovalPreviewRouteLayer, cmmdForgeCloudProjectRemovalReceiptRouteLayer, cmmdForgeRuntimesEnsureRouteLayer, cmmdForgeRuntimesConnectRouteLayer, ownerRuntimeCodexReadinessRouteLayer, cmmdForgeRuntimesStatusRouteLayer, cmmdForgeRuntimesStartRouteLayer, cmmdForgeRuntimesStopRouteLayer, cmmdForgeRuntimesRecycleRouteLayer, cmmdForgeRuntimesUpdateCommitRouteLayer, cmmdForgeRuntimesDestroyRouteLayer, cmmdRenameForgeRuntimeRouteLayer, cmmdGetTaskRouteLayer, commandUpdateTaskRouteLayer, mobileProviderCatalogRouteLayer, cmmdUsageSummaryRouteLayer, cmmdBillingRouteLayer, cmmdBillingSeriesRouteLayer, attachmentsRouteLayer, orchestrationDispatchRouteLayer, orchestrationCmmdWorkRunEventRouteLayer, orchestrationAutomationStartThreadRouteLayer, orchestrationAutomationRebindRouteLayer, orchestrationAutomationTerminalReconcileRouteLayer, mobileGitRunStackedActionRouteLayer, pullRequestDiffRouteLayer, orchestrationSnapshotRouteLayer, localAutomationListRouteLayer, localAutomationCreateRouteLayer, localAutomationUpdateRouteLayer, localAutomationDeleteRouteLayer, localAutomationRunRouteLayer, otlpTracesProxyRouteLayer, devTunnelProxyRouteLayer, devTunnelLocalPortProxyRouteLayer, projectFaviconRouteLayer, serverEnvironmentRouteLayer, browserWebRtcReadinessRouteLayer, staticAndDevRouteLayer, githubStatusRouteLayer, githubAuthorizeUrlRouteLayer, githubDisconnectRouteLayer, githubReposRouteLayer, githubCloneRouteLayer, githubCloneJobStartRouteLayer, githubCloneJobStatusRouteLayer, githubRefreshCredentialsRouteLayer, githubToolConfirmationApproveRouteLayer, projectLinkGetRouteLayer, projectLinkListRouteLayer, projectLinkSetRouteLayer, projectLinkDeleteRouteLayer, cmmdWorkspacesRouteLayer, cmmdCampaignsRouteLayer, cmmdProjectLinksRouteLayer, cmmdEnsureGitHubProjectContextRouteLayer, cmmdProjectRepositoryEnsureRouteLayer, cmmdProjectsGetRouteLayer, cmmdProjectsCreateRouteLayer, workspaceReadinessRouteLayer, runtimeLivenessRouteLayer, claudeNativeGenerationProofRouteLayer, claudeUsageRouteLayer, codexRuntimeProviderReadinessRouteLayer, runtimeDiagnosticsRouteLayer, cloudFoldersRouteLayer, cloudProjectCreateRouteLayer, gitUrlCloneRouteLayer, websocketRpcRouteLayer).pipe(require_Schema$1.provide$1(browserApiCorsLayer));
314736
+ const makeRoutesLayer = require_Schema$1.mergeAll(authBearerBootstrapRouteLayer, authBootstrapRouteLayer, authCommandBearerBootstrapRouteLayer, authCommandBootstrapRouteLayer, authOAuthTokenExchangeRouteLayer, authWebSocketTicketRouteLayer, authCmmdOAuthDeviceRouteLayer, authCmmdOAuthTokenRouteLayer, authCmmdPasswordTokenRouteLayer, authClientsRevokeOthersRouteLayer, authClientsRevokeRouteLayer, authClientsRouteLayer, authLogoutRouteLayer, authPairingLinksRevokeRouteLayer, authPairingLinksRouteLayer, authPairingCredentialRouteLayer, authSessionRouteLayer, authWebSocketTokenRouteLayer, authWebLoginRouteLayer, authWebCallbackRouteLayer, desktopLocalWebBridgePublishRouteLayer, desktopLocalWebBridgeBootstrapRouteLayer, desktopRelayControlPlaneRouteLayer, apiDocsHtmlRouteLayer, apiDocsOpenApiRouteLayer, pulseSignalStateListRouteLayer, pulseSignalStateUpsertRouteLayer, cmmdProfileRouteLayer, ...cmmdProxyRouteLayers, cmmdWorkIntakeRouteLayer, cmmdWsTokenRouteLayer, cmmdGetProjectCommentsRouteLayer, cmmdAddProjectCommentRouteLayer, cmmdUpdateProjectRouteLayer, cmmdUploadTaskAttachmentRouteLayer, cmmdUpdateTaskCommentRouteLayer, cmmdListWorkspaceMembersRouteLayer, cmmdAddProjectMemberRouteLayer, cmmdUpdateProjectAgentMemberAvatarRouteLayer, runtimeReplicationStatusRouteLayer, cmmdRefreshProviderUsageRouteLayer, cmmdForgeCloudProjectsListRouteLayer, cmmdForgeCloudProjectsEventsRouteLayer, cmmdForgeRuntimesEnsureRouteLayer, cmmdForgeRuntimesConnectRouteLayer, ownerRuntimeCodexReadinessRouteLayer, cmmdForgeRuntimesStatusRouteLayer, cmmdForgeRuntimesStartRouteLayer, cmmdForgeRuntimesStopRouteLayer, cmmdForgeRuntimesRecycleRouteLayer, cmmdForgeRuntimesUpdateCommitRouteLayer, cmmdForgeRuntimesDestroyRouteLayer, mobileProviderCatalogRouteLayer, attachmentsRouteLayer, orchestrationDispatchRouteLayer, orchestrationCmmdWorkRunEventRouteLayer, orchestrationAutomationStartThreadRouteLayer, orchestrationAutomationRebindRouteLayer, orchestrationAutomationTerminalReconcileRouteLayer, mobileGitRunStackedActionRouteLayer, pullRequestDiffRouteLayer, orchestrationSnapshotRouteLayer, localAutomationListRouteLayer, localAutomationCreateRouteLayer, localAutomationUpdateRouteLayer, localAutomationDeleteRouteLayer, localAutomationRunRouteLayer, otlpTracesProxyRouteLayer, devTunnelProxyRouteLayer, devTunnelLocalPortProxyRouteLayer, projectFaviconRouteLayer, serverEnvironmentRouteLayer, browserWebRtcReadinessRouteLayer, staticAndDevRouteLayer, githubStatusRouteLayer, githubAuthorizeUrlRouteLayer, githubDisconnectRouteLayer, githubReposRouteLayer, githubCloneRouteLayer, githubCloneJobStartRouteLayer, githubCloneJobStatusRouteLayer, githubRefreshCredentialsRouteLayer, githubToolConfirmationApproveRouteLayer, projectLinkGetRouteLayer, projectLinkListRouteLayer, projectLinkSetRouteLayer, projectLinkDeleteRouteLayer, cmmdWorkspacesRouteLayer, cmmdCampaignsRouteLayer, cmmdProjectLinksRouteLayer, cmmdEnsureGitHubProjectContextRouteLayer, cmmdProjectRepositoryEnsureRouteLayer, cmmdProjectsGetRouteLayer, cmmdProjectsCreateRouteLayer, workspaceReadinessRouteLayer, runtimeLivenessRouteLayer, claudeNativeGenerationProofRouteLayer, claudeUsageRouteLayer, codexRuntimeProviderReadinessRouteLayer, runtimeDiagnosticsRouteLayer, cloudFoldersRouteLayer, cloudProjectCreateRouteLayer, gitUrlCloneRouteLayer, websocketRpcRouteLayer).pipe(require_Schema$1.provide$1(browserApiCorsLayer));
314238
314737
  const makeServerLayer = require_Schema$1.unwrap(require_Schema$1.gen(function* () {
314239
314738
  const config = yield* ServerConfig;
314240
314739
  fixPath({ preferProcessPath: config.forgeCmmdRuntimeMode === true });
@@ -314748,7 +315247,7 @@ const resolveServerConfig = (flags, cliLogLevel, options) => require_Schema$1.ge
314748
315247
  forgeCodexHomePath: env.forgeCodexHomePath,
314749
315248
  forgeClaudeConfigPath: env.forgeClaudeConfigPath,
314750
315249
  forgeApexBaseUrl: env.forgeApexBaseUrl,
314751
- cloudProjectsRoot: env.cloudProjectsRoot ?? "/data/Projects"
315250
+ cloudProjectsRoot: env.cloudProjectsRoot ?? "/projects"
314752
315251
  };
314753
315252
  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."));
314754
315253
  if (config.forgeCloudShellMode === true && !isEd25519PublicKey(config.forgeCloudOwnerAssertionPublicKey ?? "")) return yield* require_Schema$1.die(/* @__PURE__ */ new Error("FORGE_CMMD_CLOUD_OWNER_ASSERTION_PUBLIC_KEY must be a valid Ed25519 public key in cloud-shell mode."));