@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.
- package/dist/bin.cjs +1294 -795
- package/dist/bin.mjs +1293 -792
- package/dist/client/assets/{CanvasPanel-Dr4I7MnM.js → CanvasPanel-ECmvVI7T.js} +2 -2
- package/dist/client/assets/{CompositeItem-Cj6_oAlz.js → CompositeItem-8hzrVacr.js} +2 -2
- package/dist/client/assets/{DiffPanel-CsMWXFsK.js → DiffPanel-BqOO3dsl.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-Cyp3p58B.js → DiffPanel.logic-Bzm8oiCr.js} +2 -2
- package/dist/client/assets/DiffPanelShell-DVVw1mR3.js +2531 -0
- package/dist/client/assets/{DiffWorkerPoolProvider-DOF7ypo1.js → DiffWorkerPoolProvider-BsMgSHbg.js} +8 -8
- package/dist/client/assets/{PullRequestCodePanel-BuK0wrXE.js → PullRequestCodePanel-DNrNrubs.js} +3 -3
- package/dist/client/assets/{Virtualizer-CQJMsfKa.js → Virtualizer-RRV_x18w.js} +2 -2
- package/dist/client/assets/{canvasStateStore-DncdOQ4J.js → canvasStateStore-3EN8RaUf.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-DWiMDVzN.js → cmmdAuthRedirect-DwPtzhq9.js} +2 -2
- package/dist/client/assets/index-D22UpSjv.css +1 -0
- package/dist/client/assets/{index-C6vF1RSl.js → index-DCVtRkq1.js} +56 -56
- package/dist/client/assets/{src-CtyKlVph.js → src-DZBONdiY.js} +2 -2
- package/dist/client/assets/{toggle-pTm2fPLg.js → toggle-mQ7UG7Dd.js} +2 -2
- package/dist/client/assets/{useTriggerFocusGuards-B4Ejoaox.js → useTriggerFocusGuards-BUEnX8xa.js} +2 -2
- package/dist/client/index.html +11 -11
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/DiffPanelShell-h78vZ6dX.js +0 -2531
- 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 `/
|
|
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.
|
|
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:
|
|
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
|
-
|
|
70379
|
-
*
|
|
70380
|
-
|
|
70381
|
-
|
|
70382
|
-
|
|
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*
|
|
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
|
|
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: () =>
|
|
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
|
-
|
|
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
|
-
...
|
|
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) =>
|
|
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
|
-
* /
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
207557
|
-
*
|
|
207558
|
-
*
|
|
207559
|
-
*
|
|
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
|
|
207564
|
-
const
|
|
207565
|
-
|
|
207566
|
-
|
|
207567
|
-
|
|
207568
|
-
|
|
207569
|
-
|
|
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 (
|
|
207603
|
-
* `
|
|
207604
|
-
*
|
|
207605
|
-
*
|
|
207606
|
-
*
|
|
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
|
|
208855
|
+
const PERSONAL_CLAUDE_IN_VM_MARKER_NAME = ".forge-personal-claude-in-vm";
|
|
208558
208856
|
function markerPath(env) {
|
|
208559
|
-
|
|
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)(
|
|
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
|
-
*
|
|
210472
|
-
*
|
|
210473
|
-
*
|
|
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
|
|
210477
|
-
|
|
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
|
-
|
|
210486
|
-
|
|
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
|
|
210504
|
-
* camelCase, unlike `result.usage`,
|
|
210505
|
-
* Claude reports `inputTokens` exclusive of the
|
|
210506
|
-
* portions, so the buckets are already disjoint, and
|
|
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
|
-
|
|
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
|
-
|
|
227590
|
+
const retryable = !isRuntimeUnavailable(readiness) && (refreshing || [
|
|
227304
227591
|
"pending",
|
|
227305
227592
|
"claimed",
|
|
227306
227593
|
"activating"
|
|
227307
|
-
].includes(readiness.deliveryStatus)
|
|
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 (
|
|
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
|
-
* `/
|
|
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
|
|
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 "
|
|
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.
|
|
300987
|
-
* turns into
|
|
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
|
|
300996
|
-
|
|
300997
|
-
|
|
300998
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
301307
|
-
|
|
301308
|
-
|
|
301309
|
-
|
|
301310
|
-
|
|
301311
|
-
|
|
301312
|
-
|
|
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
|
-
|
|
301317
|
-
|
|
301318
|
-
|
|
301319
|
-
|
|
301320
|
-
|
|
301321
|
-
})
|
|
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
|
-
|
|
301376
|
-
|
|
301377
|
-
|
|
301378
|
-
|
|
301379
|
-
|
|
301380
|
-
|
|
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
|
-
|
|
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
|
|
301390
|
-
|
|
301391
|
-
|
|
301392
|
-
|
|
301393
|
-
|
|
301394
|
-
|
|
301395
|
-
}
|
|
301396
|
-
|
|
301397
|
-
|
|
301398
|
-
|
|
301399
|
-
|
|
301400
|
-
|
|
301401
|
-
|
|
301402
|
-
|
|
301403
|
-
|
|
301404
|
-
|
|
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
|
-
|
|
301410
|
-
|
|
301411
|
-
|
|
301412
|
-
|
|
301413
|
-
|
|
301414
|
-
})
|
|
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
|
-
|
|
301444
|
-
|
|
301445
|
-
|
|
301446
|
-
|
|
301447
|
-
|
|
301448
|
-
|
|
301449
|
-
|
|
301450
|
-
|
|
301451
|
-
|
|
301452
|
-
|
|
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
|
-
|
|
301457
|
-
|
|
301458
|
-
|
|
301459
|
-
|
|
301460
|
-
}
|
|
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
|
-
|
|
301475
|
-
|
|
301476
|
-
|
|
301477
|
-
|
|
301478
|
-
|
|
301479
|
-
|
|
301480
|
-
|
|
301481
|
-
|
|
301482
|
-
|
|
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
|
-
|
|
301487
|
-
|
|
301488
|
-
|
|
301489
|
-
|
|
301490
|
-
}
|
|
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
|
-
|
|
301503
|
-
|
|
301504
|
-
|
|
301505
|
-
|
|
301506
|
-
|
|
301507
|
-
|
|
301508
|
-
|
|
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
|
-
|
|
301513
|
-
|
|
301514
|
-
|
|
301515
|
-
|
|
301516
|
-
|
|
301517
|
-
|
|
301518
|
-
}
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
302195
|
+
registerProxyRoute({
|
|
301802
302196
|
forgePath: "/api/cmmd/tasks",
|
|
301803
302197
|
method: "GET",
|
|
301804
302198
|
cmmdPath: "/api/forge/context/tasks"
|
|
301805
302199
|
});
|
|
301806
|
-
|
|
302200
|
+
registerProxyRoute({
|
|
301807
302201
|
forgePath: "/api/cmmd/tasks",
|
|
301808
302202
|
method: "POST",
|
|
301809
302203
|
cmmdPath: "/api/forge/context/tasks"
|
|
301810
302204
|
});
|
|
301811
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
302262
|
+
registerProxyRoute({
|
|
301869
302263
|
forgePath: "/api/cmmd/projects",
|
|
301870
302264
|
method: "POST",
|
|
301871
302265
|
cmmdPath: "/api/projects",
|
|
301872
302266
|
responseShape: "passthrough"
|
|
301873
302267
|
});
|
|
301874
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
]
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
302661
|
-
|
|
302662
|
-
|
|
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
|
-
|
|
302668
|
-
|
|
302669
|
-
})
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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 ?? "/
|
|
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."));
|