@cmmd-center/forge 0.10.6 → 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 +1214 -761
- package/dist/bin.mjs +1214 -759
- 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-njtnlFro.js → DiffPanel-BqOO3dsl.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-BiWRNb4k.js → DiffPanel.logic-Bzm8oiCr.js} +2 -2
- package/dist/client/assets/DiffPanelShell-DVVw1mR3.js +2531 -0
- package/dist/client/assets/{DiffWorkerPoolProvider-DWrja16U.js → DiffWorkerPoolProvider-BsMgSHbg.js} +8 -8
- package/dist/client/assets/{PullRequestCodePanel-CAaq9dk8.js → PullRequestCodePanel-DNrNrubs.js} +3 -3
- package/dist/client/assets/{Virtualizer-BXpiamky.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-DBIIL0ML.js → index-DCVtRkq1.js} +59 -59
- 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-AKUK0L-g.js +0 -2531
- package/dist/client/assets/index-T36rURmx.css +0 -1
package/dist/bin.mjs
CHANGED
|
@@ -24231,6 +24231,7 @@ const UsageBucket = Struct({
|
|
|
24231
24231
|
costSource: UsageCostSource,
|
|
24232
24232
|
records: NonNegativeInt,
|
|
24233
24233
|
unpricedRecords: NonNegativeInt,
|
|
24234
|
+
unreportedRecords: optional$4(NonNegativeInt),
|
|
24234
24235
|
sessions: NonNegativeInt,
|
|
24235
24236
|
runtimeId: optional$4(TrimmedNonEmptyString),
|
|
24236
24237
|
origin: optional$4(UsageBucketOrigin),
|
|
@@ -65120,7 +65121,7 @@ function normalizeNumberish(value) {
|
|
|
65120
65121
|
}
|
|
65121
65122
|
//#endregion
|
|
65122
65123
|
//#region package.json
|
|
65123
|
-
var version$1 = "0.10.
|
|
65124
|
+
var version$1 = "0.10.7";
|
|
65124
65125
|
//#endregion
|
|
65125
65126
|
//#region src/sentry.ts
|
|
65126
65127
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -70026,6 +70027,14 @@ function invalidateCachedCmmdWorkIntakeForIdentity(identityKey) {
|
|
|
70026
70027
|
*
|
|
70027
70028
|
* Bespoke routes (MCP/PAT transport, hybrid fallback, multipart) stay in
|
|
70028
70029
|
* http.ts and are NOT migrated here.
|
|
70030
|
+
*
|
|
70031
|
+
* A second, narrower entry point — `registerProxyHandler` / `ProxyHandlerRoute`
|
|
70032
|
+
* — covers routes whose middle (request parsing, the actual gateway call,
|
|
70033
|
+
* success shaping) cannot be expressed by the five `ProxyRoute` fields above,
|
|
70034
|
+
* while still sharing the same prologue: session auth, the CMMD-connection
|
|
70035
|
+
* gate, and the same `buildProxyErrorResponse` error mapping plus
|
|
70036
|
+
* `clearUnrecoverableCmmdAuthForSession` on an auth failure. See the type doc
|
|
70037
|
+
* below for the exact contract.
|
|
70029
70038
|
*/
|
|
70030
70039
|
/** Substitutes ":paramName" tokens in a path template from a params record. */
|
|
70031
70040
|
function substitutePath(template, params) {
|
|
@@ -70075,6 +70084,29 @@ function buildProxyErrorResponse(error) {
|
|
|
70075
70084
|
}
|
|
70076
70085
|
return jsonUnsafe({ error: "CMMD REST request failed." }, { status: 502 });
|
|
70077
70086
|
}
|
|
70087
|
+
/**
|
|
70088
|
+
* Clears every unrecoverable CMMD credential tied to this session, logging a
|
|
70089
|
+
* warning rather than failing the request if the clear itself errors — a
|
|
70090
|
+
* session that already has no usable credential must still get its 401,
|
|
70091
|
+
* not a 500 from a failed best-effort cleanup.
|
|
70092
|
+
*/
|
|
70093
|
+
function clearCmmdAuthAfterFailure(sessionId) {
|
|
70094
|
+
return clearUnrecoverableCmmdAuthForSession(sessionId).pipe(catch_((error) => logWarning$1("Failed to clear unrecoverable CMMD auth after CMMD auth failure.", {
|
|
70095
|
+
cause: error,
|
|
70096
|
+
sessionId
|
|
70097
|
+
})));
|
|
70098
|
+
}
|
|
70099
|
+
/**
|
|
70100
|
+
* The single "no usable CMMD credential" response: clears whatever
|
|
70101
|
+
* unrecoverable auth state this session is holding, then returns the
|
|
70102
|
+
* canonical `CMMD_AUTH_REQUIRED` body. Every prologue path that decides the
|
|
70103
|
+
* session has no way to reach CMMD — a missing PAT, a JWT that fails to
|
|
70104
|
+
* resolve, a bespoke gate elsewhere in http.ts — emits this same response so
|
|
70105
|
+
* the Shell only ever has one `CMMD_AUTH_REQUIRED` body to branch on.
|
|
70106
|
+
*/
|
|
70107
|
+
function respondCmmdConnectionRequired(sessionId) {
|
|
70108
|
+
return clearCmmdAuthAfterFailure(sessionId).pipe(as$3(buildProxyErrorResponse(new CmmdProxyAuthenticationRequiredError("CMMD connection required. Reconnect CMMD to continue."))));
|
|
70109
|
+
}
|
|
70078
70110
|
async function dispatchToProxy(method, jwt, cmmdPath, rawBody, orgId, searchParams) {
|
|
70079
70111
|
return cmmdGateway.request({
|
|
70080
70112
|
method,
|
|
@@ -70105,12 +70137,27 @@ function buildProxySearchParams(input) {
|
|
|
70105
70137
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
70106
70138
|
}
|
|
70107
70139
|
const _registeredRoutes = [];
|
|
70108
|
-
|
|
70109
|
-
|
|
70110
|
-
*
|
|
70111
|
-
|
|
70112
|
-
|
|
70113
|
-
|
|
70140
|
+
const _registeredLayers = [];
|
|
70141
|
+
/**
|
|
70142
|
+
* Layers produced by every registerProxyRoute call so far, in registration
|
|
70143
|
+
* order. Callers that want only the routes registered by their own module
|
|
70144
|
+
* should snapshot `.length` before their own registerProxyRoute calls run and
|
|
70145
|
+
* slice from that index — see command/http.ts's `cmmdProxyRouteLayers`.
|
|
70146
|
+
*
|
|
70147
|
+
* Typed via `ReturnType<typeof buildProxyRouteLayer>` (not `HttpRouter.add`
|
|
70148
|
+
* directly, and not `registerProxyRoute` itself — that would be circular
|
|
70149
|
+
* since registerProxyRoute pushes onto this same array): `buildProxyRouteLayer`
|
|
70150
|
+
* takes a concrete, non-generic `ProxyRoute` argument and never references
|
|
70151
|
+
* this array, so its return type is fully resolved independently. Referencing
|
|
70152
|
+
* the generic `HttpRouter.add` on its own instead collapses its unresolved E/R
|
|
70153
|
+
* type parameters to `unknown`, which then leaks into makeRoutesLayer's
|
|
70154
|
+
* requirements channel everywhere this array is spread.
|
|
70155
|
+
*/
|
|
70156
|
+
function registeredProxyRouteLayers() {
|
|
70157
|
+
return Object.freeze([..._registeredLayers]);
|
|
70158
|
+
}
|
|
70159
|
+
/** Builds the Effect HttpRouter layer for one route, with no registry side effects. */
|
|
70160
|
+
function buildProxyRouteLayer(route) {
|
|
70114
70161
|
const handler = gen(function* () {
|
|
70115
70162
|
const req = yield* HttpServerRequest;
|
|
70116
70163
|
const session = yield* (yield* ServerAuth).authenticateHttpRequest(req);
|
|
@@ -70133,23 +70180,14 @@ function registerProxyRoute(route) {
|
|
|
70133
70180
|
forceRefresh
|
|
70134
70181
|
});
|
|
70135
70182
|
const jwt = yield* resolveJwt();
|
|
70136
|
-
if (!jwt)
|
|
70137
|
-
yield* clearUnrecoverableCmmdAuthForSession(session.sessionId).pipe(catch_((error) => logWarning$1("Failed to clear unrecoverable CMMD auth after missing JWT.", {
|
|
70138
|
-
cause: error,
|
|
70139
|
-
sessionId: session.sessionId
|
|
70140
|
-
})));
|
|
70141
|
-
return buildProxyErrorResponse(new CmmdProxyAuthenticationRequiredError("CMMD connection required. Reconnect CMMD to continue."));
|
|
70142
|
-
}
|
|
70183
|
+
if (!jwt) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
70143
70184
|
let outcome = yield* promise(() => runProxy(() => dispatchToProxy(route.method, jwt, cmmdPath, rawBody, orgId, searchParams)));
|
|
70144
70185
|
if (!outcome.ok && outcome.error instanceof CmmdProxyAuthError) {
|
|
70145
70186
|
const refreshedJwt = yield* resolveJwt(true);
|
|
70146
70187
|
if (refreshedJwt && refreshedJwt !== jwt) outcome = yield* promise(() => runProxy(() => dispatchToProxy(route.method, refreshedJwt, cmmdPath, rawBody, orgId, searchParams)));
|
|
70147
70188
|
}
|
|
70148
70189
|
if (!outcome.ok) {
|
|
70149
|
-
if (outcome.error instanceof CmmdProxyAuthError || outcome.error instanceof CmmdProxyAuthenticationRequiredError) yield*
|
|
70150
|
-
cause: error,
|
|
70151
|
-
sessionId: session.sessionId
|
|
70152
|
-
})));
|
|
70190
|
+
if (outcome.error instanceof CmmdProxyAuthError || outcome.error instanceof CmmdProxyAuthenticationRequiredError) yield* clearCmmdAuthAfterFailure(session.sessionId);
|
|
70153
70191
|
return buildProxyErrorResponse(outcome.error);
|
|
70154
70192
|
}
|
|
70155
70193
|
const payload = route.responseShape === "passthrough" ? outcome.value : unwrapEnvelope$1(outcome.value);
|
|
@@ -70159,6 +70197,59 @@ function registerProxyRoute(route) {
|
|
|
70159
70197
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error)));
|
|
70160
70198
|
return add$1(route.method, route.forgePath, handler);
|
|
70161
70199
|
}
|
|
70200
|
+
/**
|
|
70201
|
+
* Generates an Effect HttpRouter layer for the given route and records it in
|
|
70202
|
+
* the registry (for auditing / tests, and so command/http.ts's
|
|
70203
|
+
* `cmmdProxyRouteLayers` can pick it up). The returned layer registers one
|
|
70204
|
+
* handler at forgePath.
|
|
70205
|
+
*/
|
|
70206
|
+
function registerProxyRoute(route) {
|
|
70207
|
+
_registeredRoutes.push(route);
|
|
70208
|
+
const layer = buildProxyRouteLayer(route);
|
|
70209
|
+
_registeredLayers.push(layer);
|
|
70210
|
+
return layer;
|
|
70211
|
+
}
|
|
70212
|
+
/**
|
|
70213
|
+
* Builds the bare handler Effect for one handler route (no `HttpRouter.add`
|
|
70214
|
+
* wrapping, no registry side effects) — exposed on its own so tests can
|
|
70215
|
+
* exercise it the same way they exercise every other bespoke handler in
|
|
70216
|
+
* http.ts: providing `HttpServerRequest` / `ServerAuth` directly and running
|
|
70217
|
+
* the Effect, without standing up a router.
|
|
70218
|
+
*/
|
|
70219
|
+
function buildProxyHandlerEffect(route) {
|
|
70220
|
+
return gen(function* () {
|
|
70221
|
+
const req = yield* HttpServerRequest;
|
|
70222
|
+
const session = yield* (yield* ServerAuth).authenticateHttpRequest(req);
|
|
70223
|
+
if (!readCommandAccessTokenForSession(session.sessionId)) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
70224
|
+
const parsed = yield* route.parse(req);
|
|
70225
|
+
if (!parsed.ok) return jsonUnsafe(parsed.body, { status: parsed.status });
|
|
70226
|
+
const result$4 = yield* route.run(parsed.value, { session }).pipe(result);
|
|
70227
|
+
if (isFailure$1(result$4)) {
|
|
70228
|
+
const error = result$4.failure;
|
|
70229
|
+
if (error instanceof CmmdProxyAuthError || error instanceof CmmdProxyAuthenticationRequiredError) yield* clearCmmdAuthAfterFailure(session.sessionId);
|
|
70230
|
+
return buildProxyErrorResponse(error);
|
|
70231
|
+
}
|
|
70232
|
+
return jsonUnsafe(result$4.success.body, { status: result$4.success.status });
|
|
70233
|
+
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error)));
|
|
70234
|
+
}
|
|
70235
|
+
const _registeredHandlerRoutes = [];
|
|
70236
|
+
/**
|
|
70237
|
+
* Builds the handler Effect for one route, mounts it via `HttpRouter.add` and
|
|
70238
|
+
* records that layer in the same registry `registerProxyRoute` uses (so
|
|
70239
|
+
* command/http.ts's `cmmdProxyRouteLayers` picks it up without a separate
|
|
70240
|
+
* mount list) — then returns the bare handler Effect rather than the layer,
|
|
70241
|
+
* so the caller can keep a single `__xHandlerForTests`-style export that
|
|
70242
|
+
* doubles as both the thing under test and the thing that gets mounted.
|
|
70243
|
+
*/
|
|
70244
|
+
function registerProxyHandler(route) {
|
|
70245
|
+
_registeredHandlerRoutes.push({
|
|
70246
|
+
method: route.method,
|
|
70247
|
+
forgePath: route.forgePath
|
|
70248
|
+
});
|
|
70249
|
+
const handler = buildProxyHandlerEffect(route);
|
|
70250
|
+
_registeredLayers.push(add$1(route.method, route.forgePath, handler));
|
|
70251
|
+
return handler;
|
|
70252
|
+
}
|
|
70162
70253
|
//#endregion
|
|
70163
70254
|
//#region src/connect/credentialRefresh.ts
|
|
70164
70255
|
async function refreshConnectCredential(deps) {
|
|
@@ -92271,6 +92362,172 @@ function classifyRuntimeReplicationHttpFailure(failure) {
|
|
|
92271
92362
|
};
|
|
92272
92363
|
}
|
|
92273
92364
|
//#endregion
|
|
92365
|
+
//#region src/runtimeReplication/runtimeLane.ts
|
|
92366
|
+
/**
|
|
92367
|
+
* Read a grant-lane response the way the gateway reads an owner-lane one: a
|
|
92368
|
+
* non-2xx becomes a `CmmdProxyRequestError` carrying the status and CMMD's
|
|
92369
|
+
* error code, so a caller can classify either lane's failure with one rule.
|
|
92370
|
+
*/
|
|
92371
|
+
async function parseRuntimeLaneResponse(response) {
|
|
92372
|
+
const text = await response.text();
|
|
92373
|
+
let body = null;
|
|
92374
|
+
if (text) try {
|
|
92375
|
+
body = JSON.parse(text);
|
|
92376
|
+
} catch {
|
|
92377
|
+
body = null;
|
|
92378
|
+
}
|
|
92379
|
+
if (!response.ok) {
|
|
92380
|
+
const code = readRuntimeReplicationErrorCode(body);
|
|
92381
|
+
throw new CmmdProxyRequestError(`CMMD runtime replication failed (${response.status})`, response.status, null, code ? { code } : null);
|
|
92382
|
+
}
|
|
92383
|
+
if (body === null) throw new Error("CMMD runtime replication returned an empty or invalid JSON response.");
|
|
92384
|
+
return body;
|
|
92385
|
+
}
|
|
92386
|
+
/**
|
|
92387
|
+
* One request on whichever lane the runtime holds. The caller has already
|
|
92388
|
+
* built the path for `lane.kind`; this only decides the transport and the
|
|
92389
|
+
* credential header, and normalises failures to the gateway's error classes.
|
|
92390
|
+
*/
|
|
92391
|
+
async function requestOnRuntimeLane(lane, request, transport = {}) {
|
|
92392
|
+
if (lane.kind === "owner-session") return (transport.gateway ?? cmmdGateway).request({
|
|
92393
|
+
method: request.method,
|
|
92394
|
+
jwt: lane.jwt,
|
|
92395
|
+
path: request.path,
|
|
92396
|
+
...request.body === void 0 ? {} : { body: request.body }
|
|
92397
|
+
});
|
|
92398
|
+
return parseRuntimeLaneResponse(await (transport.fetchImpl ?? fetch)(new URL(request.path, `${lane.controlPlaneUrl}/`), {
|
|
92399
|
+
method: request.method,
|
|
92400
|
+
headers: {
|
|
92401
|
+
authorization: `Bearer ${lane.grantToken}`,
|
|
92402
|
+
accept: "application/json",
|
|
92403
|
+
...request.body === void 0 ? {} : { "content-type": "application/json" }
|
|
92404
|
+
},
|
|
92405
|
+
...request.body === void 0 ? {} : { body: JSON.stringify(request.body) },
|
|
92406
|
+
...request.signal === void 0 ? {} : { signal: request.signal }
|
|
92407
|
+
}));
|
|
92408
|
+
}
|
|
92409
|
+
function mapRuntimeReplicationClientError(error, operation) {
|
|
92410
|
+
if (error instanceof CmmdProxyAuthError) return new RuntimeReplicationClientError({
|
|
92411
|
+
kind: "auth",
|
|
92412
|
+
code: "CMMD_AUTH_REQUIRED",
|
|
92413
|
+
detail: error.message
|
|
92414
|
+
});
|
|
92415
|
+
if (error instanceof CmmdProxyAuthenticationRequiredError) return new RuntimeReplicationClientError({
|
|
92416
|
+
kind: "auth",
|
|
92417
|
+
code: "CMMD_AUTH_REQUIRED",
|
|
92418
|
+
detail: error.message
|
|
92419
|
+
});
|
|
92420
|
+
if (error instanceof CmmdProxyPermissionError) return new RuntimeReplicationClientError({
|
|
92421
|
+
kind: "permanent",
|
|
92422
|
+
code: "CMMD_PERMISSION_DENIED",
|
|
92423
|
+
detail: error.message
|
|
92424
|
+
});
|
|
92425
|
+
if (error instanceof CmmdProxyRequestError) return new RuntimeReplicationClientError(classifyRuntimeReplicationHttpFailure({
|
|
92426
|
+
status: error.status,
|
|
92427
|
+
body: error.body,
|
|
92428
|
+
detail: error.detail ?? error.message,
|
|
92429
|
+
...operation ? { operation } : {}
|
|
92430
|
+
}));
|
|
92431
|
+
return new RuntimeReplicationClientError({
|
|
92432
|
+
kind: "retryable",
|
|
92433
|
+
code: "CMMD_UNAVAILABLE",
|
|
92434
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
92435
|
+
});
|
|
92436
|
+
}
|
|
92437
|
+
//#endregion
|
|
92438
|
+
//#region src/runtimeReplication/lifecycleIntentClient.ts
|
|
92439
|
+
/**
|
|
92440
|
+
* The runtime half of a lifecycle intent: a settle or un-settle a person asked
|
|
92441
|
+
* for while this runtime was offline, held by CMMD until the runtime lists it,
|
|
92442
|
+
* applies it through its own orchestration, and acknowledges it.
|
|
92443
|
+
*
|
|
92444
|
+
* Both lanes carry the same envelope (pinned equal in the contracts package),
|
|
92445
|
+
* so one client serves the desktop's owner-session lane and the cloud
|
|
92446
|
+
* runtime's grant lane; only the path family differs.
|
|
92447
|
+
*/
|
|
92448
|
+
const LIFECYCLE_INTENT_TIMEOUT = "10 seconds";
|
|
92449
|
+
const LifecycleIntentListEnvelope = Struct({ data: Struct({ intents: ArraySchema(Struct({
|
|
92450
|
+
runtimeId: String$1,
|
|
92451
|
+
threadId: String$1,
|
|
92452
|
+
action: Literals(["settle", "unsettle"]),
|
|
92453
|
+
requestedAt: String$1
|
|
92454
|
+
})) }) });
|
|
92455
|
+
const LifecycleIntentAcknowledgementEnvelope = Struct({ data: Struct({ acknowledged: Number$1 }) });
|
|
92456
|
+
const decodeListEnvelope = decodeUnknownSync(LifecycleIntentListEnvelope);
|
|
92457
|
+
const decodeAcknowledgementEnvelope = decodeUnknownSync(LifecycleIntentAcknowledgementEnvelope);
|
|
92458
|
+
function decodeLifecycleIntentListResponse(response) {
|
|
92459
|
+
return decodeListEnvelope(response).data;
|
|
92460
|
+
}
|
|
92461
|
+
function decodeLifecycleIntentAcknowledgementResponse(response) {
|
|
92462
|
+
return decodeAcknowledgementEnvelope(response).data;
|
|
92463
|
+
}
|
|
92464
|
+
/**
|
|
92465
|
+
* Ids arrive from runtime rows, not constrained to path-safe characters, so
|
|
92466
|
+
* they are encoded the way every other runtime-lane path builder encodes them.
|
|
92467
|
+
*/
|
|
92468
|
+
function lifecycleIntentPath(lane, operation) {
|
|
92469
|
+
const base = `/api/forge/context/${lane.kind === "grant" ? "runtime-replication" : "devices"}/runtimes/${encodeURIComponent(lane.runtimeId)}/thread-lifecycle-intents`;
|
|
92470
|
+
return operation === "ack" ? `${base}/ack` : base;
|
|
92471
|
+
}
|
|
92472
|
+
function timedOut(operation) {
|
|
92473
|
+
return new RuntimeReplicationClientError({
|
|
92474
|
+
kind: "retryable",
|
|
92475
|
+
code: "CMMD_TIMEOUT",
|
|
92476
|
+
detail: `CMMD lifecycle intent ${operation} timed out.`
|
|
92477
|
+
});
|
|
92478
|
+
}
|
|
92479
|
+
function decodeOrFail(response, decode, label) {
|
|
92480
|
+
return try_({
|
|
92481
|
+
try: () => decode(response),
|
|
92482
|
+
catch: (cause) => new RuntimeReplicationClientError({
|
|
92483
|
+
kind: "permanent",
|
|
92484
|
+
code: "CMMD_PROTOCOL_INVALID_RESPONSE",
|
|
92485
|
+
detail: `CMMD returned an invalid lifecycle intent ${label}: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
92486
|
+
})
|
|
92487
|
+
});
|
|
92488
|
+
}
|
|
92489
|
+
/**
|
|
92490
|
+
* Every pending intent for this runtime, or an empty list.
|
|
92491
|
+
*
|
|
92492
|
+
* 404 is an ordinary answer, not a failure: a CMMD that predates the route
|
|
92493
|
+
* has nothing pending for anyone, and a runtime it has not registered yet has
|
|
92494
|
+
* nothing pending either. Every other non-2xx is a typed error -- a signed-out
|
|
92495
|
+
* owner (auth) is the caller's to skip, an outage is the next tick's to retry.
|
|
92496
|
+
*/
|
|
92497
|
+
function listPendingLifecycleIntents(lane, transport) {
|
|
92498
|
+
return tryPromise({
|
|
92499
|
+
try: (signal) => requestOnRuntimeLane(lane, {
|
|
92500
|
+
method: "GET",
|
|
92501
|
+
path: lifecycleIntentPath(lane, "list"),
|
|
92502
|
+
signal
|
|
92503
|
+
}, transport),
|
|
92504
|
+
catch: (cause) => cause instanceof CmmdProxyRequestError && cause.status === 404 ? null : mapRuntimeReplicationClientError(cause)
|
|
92505
|
+
}).pipe(catch_((cause) => cause === null ? succeed(null) : fail(cause)), flatMap((response) => response === null ? succeed([]) : decodeOrFail(response, decodeLifecycleIntentListResponse, "list").pipe(map$3((list) => list.intents))), timeoutOrElse({
|
|
92506
|
+
duration: LIFECYCLE_INTENT_TIMEOUT,
|
|
92507
|
+
orElse: () => fail(timedOut("list"))
|
|
92508
|
+
}));
|
|
92509
|
+
}
|
|
92510
|
+
/**
|
|
92511
|
+
* Tell CMMD which intents were applied (or deliberately skipped), by thread
|
|
92512
|
+
* and requested time. CMMD drops only an intent whose requested time matches,
|
|
92513
|
+
* so a newer request recorded while this one was being applied survives.
|
|
92514
|
+
*/
|
|
92515
|
+
function acknowledgeLifecycleIntents(lane, intents, transport) {
|
|
92516
|
+
const body = { intents };
|
|
92517
|
+
return tryPromise({
|
|
92518
|
+
try: (signal) => requestOnRuntimeLane(lane, {
|
|
92519
|
+
method: "POST",
|
|
92520
|
+
path: lifecycleIntentPath(lane, "ack"),
|
|
92521
|
+
body,
|
|
92522
|
+
signal
|
|
92523
|
+
}, transport),
|
|
92524
|
+
catch: mapRuntimeReplicationClientError
|
|
92525
|
+
}).pipe(flatMap((response) => decodeOrFail(response, decodeLifecycleIntentAcknowledgementResponse, "acknowledgement")), timeoutOrElse({
|
|
92526
|
+
duration: LIFECYCLE_INTENT_TIMEOUT,
|
|
92527
|
+
orElse: () => fail(timedOut("ack"))
|
|
92528
|
+
}));
|
|
92529
|
+
}
|
|
92530
|
+
//#endregion
|
|
92274
92531
|
//#region src/runtimeReplication/runtimeReplicationGrantPolicy.ts
|
|
92275
92532
|
/**
|
|
92276
92533
|
* Chooses which CMMD grant a replication send should use: the in-memory
|
|
@@ -92366,26 +92623,11 @@ function runtimeReplicationDevicePath(input) {
|
|
|
92366
92623
|
const threadId = input.streamKey.slice(7);
|
|
92367
92624
|
return `${devicePath}/threads/${encodeURIComponent(threadId)}/events`;
|
|
92368
92625
|
}
|
|
92369
|
-
async function parseRuntimeReplicationResponse(response) {
|
|
92370
|
-
const text = await response.text();
|
|
92371
|
-
let body = null;
|
|
92372
|
-
if (text) try {
|
|
92373
|
-
body = JSON.parse(text);
|
|
92374
|
-
} catch {
|
|
92375
|
-
body = null;
|
|
92376
|
-
}
|
|
92377
|
-
if (!response.ok) {
|
|
92378
|
-
const code = readRuntimeReplicationErrorCode(body);
|
|
92379
|
-
throw new CmmdProxyRequestError(`CMMD runtime replication failed (${response.status})`, response.status, null, code ? { code } : null);
|
|
92380
|
-
}
|
|
92381
|
-
if (body === null) throw new Error("CMMD runtime replication returned an empty or invalid JSON response.");
|
|
92382
|
-
return body;
|
|
92383
|
-
}
|
|
92384
92626
|
async function requestRuntimeReplicationWithGrant(input, fetchImpl = fetch) {
|
|
92385
92627
|
const abortController = new AbortController();
|
|
92386
92628
|
const timeout = setTimeout(() => abortController.abort(), RUNTIME_REPLICATION_TIMEOUT_MS);
|
|
92387
92629
|
try {
|
|
92388
|
-
return await
|
|
92630
|
+
return await parseRuntimeLaneResponse(await fetchImpl(new URL(runtimeReplicationGrantPath(input), `${input.controlPlaneUrl}/`), {
|
|
92389
92631
|
method: input.operation === "inventory" ? "PUT" : "POST",
|
|
92390
92632
|
headers: {
|
|
92391
92633
|
authorization: `Bearer ${input.grantToken}`,
|
|
@@ -92398,34 +92640,6 @@ async function requestRuntimeReplicationWithGrant(input, fetchImpl = fetch) {
|
|
|
92398
92640
|
clearTimeout(timeout);
|
|
92399
92641
|
}
|
|
92400
92642
|
}
|
|
92401
|
-
function mapRuntimeReplicationClientError(error, operation) {
|
|
92402
|
-
if (error instanceof CmmdProxyAuthError) return new RuntimeReplicationClientError({
|
|
92403
|
-
kind: "auth",
|
|
92404
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
92405
|
-
detail: error.message
|
|
92406
|
-
});
|
|
92407
|
-
if (error instanceof CmmdProxyAuthenticationRequiredError) return new RuntimeReplicationClientError({
|
|
92408
|
-
kind: "auth",
|
|
92409
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
92410
|
-
detail: error.message
|
|
92411
|
-
});
|
|
92412
|
-
if (error instanceof CmmdProxyPermissionError) return new RuntimeReplicationClientError({
|
|
92413
|
-
kind: "permanent",
|
|
92414
|
-
code: "CMMD_PERMISSION_DENIED",
|
|
92415
|
-
detail: error.message
|
|
92416
|
-
});
|
|
92417
|
-
if (error instanceof CmmdProxyRequestError) return new RuntimeReplicationClientError(classifyRuntimeReplicationHttpFailure({
|
|
92418
|
-
status: error.status,
|
|
92419
|
-
body: error.body,
|
|
92420
|
-
detail: error.detail ?? error.message,
|
|
92421
|
-
...operation ? { operation } : {}
|
|
92422
|
-
}));
|
|
92423
|
-
return new RuntimeReplicationClientError({
|
|
92424
|
-
kind: "retryable",
|
|
92425
|
-
code: "CMMD_UNAVAILABLE",
|
|
92426
|
-
detail: error instanceof Error ? error.message : String(error)
|
|
92427
|
-
});
|
|
92428
|
-
}
|
|
92429
92643
|
function decodeRuntimeThreadAcknowledgementResponse(response) {
|
|
92430
92644
|
return decodeThreadAcknowledgement(response).data.acknowledgement;
|
|
92431
92645
|
}
|
|
@@ -92501,9 +92715,12 @@ function replicateWithOwnerSession(sql, input) {
|
|
|
92501
92715
|
const jwt = owner.jwt;
|
|
92502
92716
|
const path = runtimeReplicationDevicePath(input);
|
|
92503
92717
|
const response = yield* tryPromise({
|
|
92504
|
-
try: () =>
|
|
92718
|
+
try: () => requestOnRuntimeLane({
|
|
92719
|
+
kind: "owner-session",
|
|
92720
|
+
runtimeId: input.runtimeId,
|
|
92721
|
+
jwt
|
|
92722
|
+
}, {
|
|
92505
92723
|
method: input.operation === "inventory" ? "PUT" : "POST",
|
|
92506
|
-
jwt,
|
|
92507
92724
|
path,
|
|
92508
92725
|
body: input.payload
|
|
92509
92726
|
}),
|
|
@@ -92514,11 +92731,63 @@ function replicateWithOwnerSession(sql, input) {
|
|
|
92514
92731
|
return yield* decodeAcknowledgementOrFail(response, decodeRuntimeThreadAcknowledgementResponse, "transcript");
|
|
92515
92732
|
});
|
|
92516
92733
|
}
|
|
92734
|
+
/**
|
|
92735
|
+
* The lane this runtime holds right now, resolved per call because both
|
|
92736
|
+
* credentials rotate: the cloud grant is re-read from the control authority,
|
|
92737
|
+
* and the owner session is whichever sign-in is newest on this desktop.
|
|
92738
|
+
*/
|
|
92739
|
+
function resolveRuntimeLane(config, sql, input) {
|
|
92740
|
+
return gen(function* () {
|
|
92741
|
+
if (config.forgeCmmdRuntimeMode === true) {
|
|
92742
|
+
const cloudGrant = resolveCloudRuntimeReplicationGrant(config);
|
|
92743
|
+
if (!cloudGrant) return yield* new RuntimeReplicationClientError({
|
|
92744
|
+
kind: "auth",
|
|
92745
|
+
code: "CMMD_RUNTIME_GRANT_REQUIRED",
|
|
92746
|
+
detail: "Cloud runtime replication requires a canonical runtime ID, CMMD URL, and scoped runtime grant."
|
|
92747
|
+
});
|
|
92748
|
+
if (input.runtimeId !== cloudGrant.runtimeId) return yield* new RuntimeReplicationClientError({
|
|
92749
|
+
kind: "permanent",
|
|
92750
|
+
code: "CMMD_RUNTIME_ID_MISMATCH",
|
|
92751
|
+
detail: "The requested runtime does not match this cloud runtime identity."
|
|
92752
|
+
});
|
|
92753
|
+
return {
|
|
92754
|
+
kind: "grant",
|
|
92755
|
+
controlPlaneUrl: cloudGrant.controlPlaneUrl,
|
|
92756
|
+
runtimeId: cloudGrant.runtimeId,
|
|
92757
|
+
grantToken: cloudGrant.grantToken
|
|
92758
|
+
};
|
|
92759
|
+
}
|
|
92760
|
+
const owner = yield* resolveCmmdOwnerSessionCredential(sql, { logPrefix: input.logPrefix });
|
|
92761
|
+
if (owner.kind === "no-session") return yield* new RuntimeReplicationClientError({
|
|
92762
|
+
kind: "auth",
|
|
92763
|
+
code: "CMMD_AUTH_REQUIRED",
|
|
92764
|
+
detail: "CMMD sign-in is required for runtime replication."
|
|
92765
|
+
});
|
|
92766
|
+
if (owner.kind === "no-credential") return yield* new RuntimeReplicationClientError({
|
|
92767
|
+
kind: "auth",
|
|
92768
|
+
code: "CMMD_AUTH_REQUIRED",
|
|
92769
|
+
detail: "CMMD REST credentials are unavailable for runtime replication."
|
|
92770
|
+
});
|
|
92771
|
+
return {
|
|
92772
|
+
kind: "owner-session",
|
|
92773
|
+
runtimeId: input.runtimeId,
|
|
92774
|
+
jwt: owner.jwt
|
|
92775
|
+
};
|
|
92776
|
+
});
|
|
92777
|
+
}
|
|
92517
92778
|
const RuntimeReplicationClientLive = effect(RuntimeReplicationClient, gen(function* () {
|
|
92518
92779
|
const sql = yield* SqlClient;
|
|
92519
92780
|
const config = yield* ServerConfig;
|
|
92520
92781
|
const send = (input) => config.forgeCmmdRuntimeMode === true ? replicateWithRuntimeGrant(config, input) : replicateWithOwnerSession(sql, input);
|
|
92521
|
-
|
|
92782
|
+
const lane = (runtimeId) => resolveRuntimeLane(config, sql, {
|
|
92783
|
+
runtimeId,
|
|
92784
|
+
logPrefix: "lifecycle-intents"
|
|
92785
|
+
});
|
|
92786
|
+
return RuntimeReplicationClient.of({
|
|
92787
|
+
send,
|
|
92788
|
+
listPendingLifecycleIntents: ({ runtimeId }) => lane(runtimeId).pipe(flatMap((l) => listPendingLifecycleIntents(l))),
|
|
92789
|
+
acknowledgeLifecycleIntents: ({ runtimeId, intents }) => lane(runtimeId).pipe(flatMap((l) => acknowledgeLifecycleIntents(l, intents)))
|
|
92790
|
+
});
|
|
92522
92791
|
}));
|
|
92523
92792
|
//#endregion
|
|
92524
92793
|
//#region src/runtimeReplication/Services/RuntimeReplicationOutbox.ts
|
|
@@ -92836,6 +93105,14 @@ function stableReplicaDigest(...values) {
|
|
|
92836
93105
|
function replicaHydrationCommandId(runtimeId, generationId, threadId) {
|
|
92837
93106
|
return CommandId.make("runtime-replica-hydration:" + stableReplicaDigest(runtimeId, generationId, threadId));
|
|
92838
93107
|
}
|
|
93108
|
+
/**
|
|
93109
|
+
* One id per (runtime, thread, requested time): a restart between dispatch and
|
|
93110
|
+
* acknowledgement re-lists the same intent, and the engine's command receipts
|
|
93111
|
+
* turn the second dispatch into a no-op instead of a second settle.
|
|
93112
|
+
*/
|
|
93113
|
+
function lifecycleIntentCommandId(runtimeId, threadId, requestedAt) {
|
|
93114
|
+
return CommandId.make("lifecycle-intent:" + stableReplicaDigest(runtimeId, threadId, requestedAt));
|
|
93115
|
+
}
|
|
92839
93116
|
//#endregion
|
|
92840
93117
|
//#region src/runtimeReplication/protocol.ts
|
|
92841
93118
|
const EMPTY_RUNTIME_THREAD_HEAD_HASH = "sha256:47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU";
|
|
@@ -93785,6 +94062,21 @@ function totalTokens(totals) {
|
|
|
93785
94062
|
return totals.uncachedInputTokens + totals.cachedInputTokens + totals.cacheCreationTokens + totals.outputTokens;
|
|
93786
94063
|
}
|
|
93787
94064
|
/**
|
|
94065
|
+
* What a transcript record's own on-disk facts say it is a row of.
|
|
94066
|
+
*
|
|
94067
|
+
* Reuses exactly the facts `usageDrivers.ts`'s `isForgeAgent` reads to route a
|
|
94068
|
+
* record to the Forge agents lane, minus the "is this one of this
|
|
94069
|
+
* environment's own threads" gate: a Claude sidechain or a Codex subagent
|
|
94070
|
+
* rollout is a Subagent row regardless of which thread (if any) it hangs
|
|
94071
|
+
* under, so a subagent driven from outside Forge is still `subagent`, not a
|
|
94072
|
+
* plain Recorded-turn-shaped `turn`. Exported so the scan cache can recompute
|
|
94073
|
+
* the same value on decode instead of storing it as a redundant column.
|
|
94074
|
+
*/
|
|
94075
|
+
function transcriptRecordKind(provider, sidechain, rootSessionId) {
|
|
94076
|
+
if (provider === "claude") return sidechain === true ? "subagent" : "turn";
|
|
94077
|
+
return rootSessionId !== void 0 ? "subagent" : "turn";
|
|
94078
|
+
}
|
|
94079
|
+
/**
|
|
93788
94080
|
* Cheap substring gate applied before `JSON.parse`.
|
|
93789
94081
|
*
|
|
93790
94082
|
* Transcripts are mostly tool output; only a minority of lines carry usage. On
|
|
@@ -93853,6 +94145,7 @@ function parseClaudeLine(line, diagnostics) {
|
|
|
93853
94145
|
const dedupeKey = claudeDedupeKey(stringAt(messageRecord, "id"), stringAt(record, "requestId"));
|
|
93854
94146
|
const cost = record["costUSD"];
|
|
93855
94147
|
const launcher = stringAt(record, "entrypoint");
|
|
94148
|
+
const sidechain = record["isSidechain"] === true;
|
|
93856
94149
|
return {
|
|
93857
94150
|
provider: "claude",
|
|
93858
94151
|
timestampMs,
|
|
@@ -93861,8 +94154,9 @@ function parseClaudeLine(line, diagnostics) {
|
|
|
93861
94154
|
totals: claudeTokenBuckets(usageRecord) ?? EMPTY_TOTALS,
|
|
93862
94155
|
reportedCostUsd: typeof cost === "number" && Number.isFinite(cost) ? cost : null,
|
|
93863
94156
|
dedupeKey,
|
|
94157
|
+
kind: transcriptRecordKind("claude", sidechain, void 0),
|
|
93864
94158
|
...launcher === null ? {} : { launcher },
|
|
93865
|
-
...
|
|
94159
|
+
...sidechain ? { sidechain: true } : {}
|
|
93866
94160
|
};
|
|
93867
94161
|
}
|
|
93868
94162
|
function initialCodexScanState() {
|
|
@@ -93979,6 +94273,7 @@ function parseCodexTokenCount(record, payloadRecord, state) {
|
|
|
93979
94273
|
totals,
|
|
93980
94274
|
reportedCostUsd: null,
|
|
93981
94275
|
dedupeKey: null,
|
|
94276
|
+
kind: transcriptRecordKind("codex", void 0, state.rootSessionId),
|
|
93982
94277
|
...codexSessionFields(state)
|
|
93983
94278
|
};
|
|
93984
94279
|
}
|
|
@@ -94247,7 +94542,8 @@ var UsageAggregator = class {
|
|
|
94247
94542
|
origin,
|
|
94248
94543
|
sync,
|
|
94249
94544
|
runtimeId,
|
|
94250
|
-
driver
|
|
94545
|
+
driver,
|
|
94546
|
+
record.kind
|
|
94251
94547
|
].join("\0");
|
|
94252
94548
|
const existing = this.#buckets.get(key);
|
|
94253
94549
|
if (existing !== void 0) return existing;
|
|
@@ -94285,7 +94581,7 @@ var UsageAggregator = class {
|
|
|
94285
94581
|
finish() {
|
|
94286
94582
|
const buckets = [];
|
|
94287
94583
|
for (const [key, bucket] of this.#buckets) {
|
|
94288
|
-
const [day = "", hourStart = "", provider = "", model = "", origin = "", sync = "", runtimeId = "", driver = ""] = key.split("\0");
|
|
94584
|
+
const [day = "", hourStart = "", provider = "", model = "", origin = "", sync = "", runtimeId = "", driver = "", kind = ""] = key.split("\0");
|
|
94289
94585
|
buckets.push({
|
|
94290
94586
|
day,
|
|
94291
94587
|
...hourStart === "" ? {} : { hourStart },
|
|
@@ -94301,10 +94597,15 @@ var UsageAggregator = class {
|
|
|
94301
94597
|
origin,
|
|
94302
94598
|
...sync === "" ? {} : { sync },
|
|
94303
94599
|
...runtimeId === "" ? {} : { runtimeId },
|
|
94304
|
-
...driver === "" ? {} : { driver }
|
|
94600
|
+
...driver === "" ? {} : { driver },
|
|
94601
|
+
kind
|
|
94305
94602
|
});
|
|
94306
94603
|
}
|
|
94307
|
-
buckets.sort((a, b) =>
|
|
94604
|
+
buckets.sort((a, b) => {
|
|
94605
|
+
const left = bucketSortKey(a);
|
|
94606
|
+
const right = bucketSortKey(b);
|
|
94607
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
94608
|
+
});
|
|
94308
94609
|
return {
|
|
94309
94610
|
buckets,
|
|
94310
94611
|
duplicatesDropped: this.#duplicatesDropped,
|
|
@@ -94322,7 +94623,8 @@ function bucketSortKey(bucket) {
|
|
|
94322
94623
|
bucket.origin ?? "",
|
|
94323
94624
|
bucket.sync ?? "",
|
|
94324
94625
|
bucket.runtimeId ?? "",
|
|
94325
|
-
bucket.driver ?? ""
|
|
94626
|
+
bucket.driver ?? "",
|
|
94627
|
+
bucket.kind ?? ""
|
|
94326
94628
|
].join("\0");
|
|
94327
94629
|
}
|
|
94328
94630
|
/**
|
|
@@ -95311,6 +95613,7 @@ function syncOf(sequence, options, threadId, events) {
|
|
|
95311
95613
|
return sequence <= cursor.acknowledgedSequence ? "acknowledged" : "pending";
|
|
95312
95614
|
}
|
|
95313
95615
|
function recordOf(event, provider, sync, threadId, runtimeId) {
|
|
95616
|
+
const kind = event.usageKind ?? "turn";
|
|
95314
95617
|
return {
|
|
95315
95618
|
provider,
|
|
95316
95619
|
timestampMs: Date.parse(event.occurredAt),
|
|
@@ -95319,6 +95622,7 @@ function recordOf(event, provider, sync, threadId, runtimeId) {
|
|
|
95319
95622
|
totals: event.usage ?? EMPTY_TOTALS,
|
|
95320
95623
|
reportedCostUsd: null,
|
|
95321
95624
|
dedupeKey: `recorded:${threadId}:${event.turnId}:${event.usageKind ?? "turn"}:${event.subagentId ?? ""}:${event.model}`,
|
|
95625
|
+
kind,
|
|
95322
95626
|
origin: "recorded",
|
|
95323
95627
|
...sync === void 0 ? {} : { sync },
|
|
95324
95628
|
...runtimeId === void 0 ? {} : { runtimeId },
|
|
@@ -96039,6 +96343,22 @@ async function readTranscriptRecords(filePath, provider) {
|
|
|
96039
96343
|
//#endregion
|
|
96040
96344
|
//#region src/usage/usageScanCache.ts
|
|
96041
96345
|
/**
|
|
96346
|
+
* Durable per-file scan cache.
|
|
96347
|
+
*
|
|
96348
|
+
* Transcripts are append-only and a file that has not changed can never yield
|
|
96349
|
+
* different usage, so parsed records are keyed by `(size, mtime)` and reused.
|
|
96350
|
+
* Without this every server restart re-parses the whole window: seconds for a
|
|
96351
|
+
* 30-day scan, against milliseconds to reload this cache.
|
|
96352
|
+
*
|
|
96353
|
+
* Caching *per file* rather than per day is deliberate. It is timezone
|
|
96354
|
+
* independent, so changing the reporting zone does not invalidate anything, and
|
|
96355
|
+
* it keeps cross-file de-duplication exact: cached entries are de-duplicated
|
|
96356
|
+
* within their own file only, and the aggregator still applies the global
|
|
96357
|
+
* dedupe pass over the small surviving key set.
|
|
96358
|
+
*
|
|
96359
|
+
* @module usageScanCache
|
|
96360
|
+
*/
|
|
96361
|
+
/**
|
|
96042
96362
|
* Bumped whenever cached records could differ from what a fresh parse produces.
|
|
96043
96363
|
*
|
|
96044
96364
|
* Version 1 was written before `parseCodexLine` suppressed the parent history a
|
|
@@ -96184,6 +96504,7 @@ function decodeRecord(row, provider, tables) {
|
|
|
96184
96504
|
},
|
|
96185
96505
|
reportedCostUsd: finiteNumber(reportedCostUsd),
|
|
96186
96506
|
dedupeKey: typeof dedupeKey === "string" ? dedupeKey : null,
|
|
96507
|
+
kind: transcriptRecordKind(provider, session.sidechain, session.rootSessionId),
|
|
96187
96508
|
...session
|
|
96188
96509
|
};
|
|
96189
96510
|
}
|
|
@@ -99151,144 +99472,6 @@ function claudeWriteToken(env = process.env) {
|
|
|
99151
99472
|
return accessor.read(env);
|
|
99152
99473
|
}
|
|
99153
99474
|
//#endregion
|
|
99154
|
-
//#region src/usage/providerRateLimits.ts
|
|
99155
|
-
/**
|
|
99156
|
-
* In-process cache of the latest Claude 5h/7d rate-limit telemetry, decoded
|
|
99157
|
-
* from the genuine Claude Agent SDK's own `rate_limit_event` messages
|
|
99158
|
-
* (see ClaudeAdapter.ts). This is intentionally NOT a CMMD call site: CMMD
|
|
99159
|
-
* must never replay a personal Claude OAuth token against api.anthropic.com
|
|
99160
|
-
* from its own backend (see CMMD's personal-claude-delivery.ts) - the only
|
|
99161
|
-
* legitimate source for this data is the real in-VM SDK session reporting it
|
|
99162
|
-
* as a side effect of a real turn.
|
|
99163
|
-
*
|
|
99164
|
-
* Snapshots are fenced by the exact non-secret credential-generation hash.
|
|
99165
|
-
* A Forge process can outlive an account reconnect, so a process-wide singleton
|
|
99166
|
-
* without that fence can leak account A's windows into account B's session.
|
|
99167
|
-
* The request-scoped route that reads this
|
|
99168
|
-
* cache (apps/server/src/command/http.ts) is what actually forwards it to
|
|
99169
|
-
* CMMD, using the request's own authenticated session - a background event
|
|
99170
|
-
* pipeline has no such session to reuse safely.
|
|
99171
|
-
*/
|
|
99172
|
-
/**
|
|
99173
|
-
* The SDK only ever reports ONE window per event. Only `five_hour` and
|
|
99174
|
-
* `seven_day` map to the two windows the Usage page shows; the
|
|
99175
|
-
* per-model/overage variants (seven_day_opus, overage, ...) are ignored here
|
|
99176
|
-
* on purpose rather than silently overwriting the plain 7-day figure.
|
|
99177
|
-
*/
|
|
99178
|
-
function mapClaudeRateLimitInfo(info) {
|
|
99179
|
-
if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
|
|
99180
|
-
const kind = info.rateLimitType === "five_hour" ? "fiveHour" : info.rateLimitType === "seven_day" ? "sevenDay" : null;
|
|
99181
|
-
if (!kind) return null;
|
|
99182
|
-
return {
|
|
99183
|
-
kind,
|
|
99184
|
-
window: {
|
|
99185
|
-
usedPercent: Math.round(info.utilization * 100),
|
|
99186
|
-
resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
|
|
99187
|
-
status: info.status
|
|
99188
|
-
}
|
|
99189
|
-
};
|
|
99190
|
-
}
|
|
99191
|
-
const SEVEN_DAY_MODEL_PREFIX = "seven_day_";
|
|
99192
|
-
const SEVEN_DAY_OVERAGE_SUFFIX = "overage_included";
|
|
99193
|
-
function capitalizeModelSuffix(suffix) {
|
|
99194
|
-
return suffix.length === 0 ? suffix : suffix.charAt(0).toUpperCase() + suffix.slice(1);
|
|
99195
|
-
}
|
|
99196
|
-
/**
|
|
99197
|
-
* Maps a per-model weekly SDKRateLimitInfo (`seven_day_<model>`, e.g.
|
|
99198
|
-
* `seven_day_opus`) into a `ProviderUsageModelWindow`. `seven_day_overage_included`
|
|
99199
|
-
* is not a per-model window (it reports overage-inclusive quota, not a
|
|
99200
|
-
* specific model) and stays ignored here, same as plain `overage`.
|
|
99201
|
-
*/
|
|
99202
|
-
function mapClaudeModelRateLimitInfo(info) {
|
|
99203
|
-
if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
|
|
99204
|
-
if (!info.rateLimitType?.startsWith(SEVEN_DAY_MODEL_PREFIX)) return null;
|
|
99205
|
-
const suffix = info.rateLimitType.slice(10);
|
|
99206
|
-
if (suffix.length === 0 || suffix === SEVEN_DAY_OVERAGE_SUFFIX) return null;
|
|
99207
|
-
return {
|
|
99208
|
-
model: capitalizeModelSuffix(suffix),
|
|
99209
|
-
window: {
|
|
99210
|
-
usedPercent: Math.round(info.utilization * 100),
|
|
99211
|
-
resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
|
|
99212
|
-
status: info.status
|
|
99213
|
-
}
|
|
99214
|
-
};
|
|
99215
|
-
}
|
|
99216
|
-
const cachedSnapshots = /* @__PURE__ */ new Map();
|
|
99217
|
-
let localClaudeGenerationHash = null;
|
|
99218
|
-
function setLocalClaudeUsageGeneration(generationId) {
|
|
99219
|
-
localClaudeGenerationHash = createHash("sha256").update(generationId).digest("hex");
|
|
99220
|
-
}
|
|
99221
|
-
function currentClaudeUsageGenerationHash() {
|
|
99222
|
-
const value = process.env.FORGE_PERSONAL_CLAUDE_GENERATION_HASH?.trim() ?? "";
|
|
99223
|
-
return /^[a-f0-9]{64}$/.test(value) ? value : localClaudeGenerationHash;
|
|
99224
|
-
}
|
|
99225
|
-
function cacheKeyFor(generationHash, providerAccountId) {
|
|
99226
|
-
return providerAccountId ? `${providerAccountId}:${generationHash}` : generationHash;
|
|
99227
|
-
}
|
|
99228
|
-
/**
|
|
99229
|
-
* `observedAt` here is a placeholder, not an observation — it becomes
|
|
99230
|
-
* meaningful only once a standard (five_hour/seven_day) window actually
|
|
99231
|
-
* lands via `withStandardWindow`, which recomputes it from the retained
|
|
99232
|
-
* windows' own observation times. A per-model-only cache (no standard window
|
|
99233
|
-
* yet) still carries this placeholder, so callers should treat `observedAt`
|
|
99234
|
-
* as trustworthy only once `fiveHour` or `sevenDay` is non-null.
|
|
99235
|
-
*/
|
|
99236
|
-
function emptyCachedSnapshot(observedAt) {
|
|
99237
|
-
return {
|
|
99238
|
-
fiveHour: null,
|
|
99239
|
-
sevenDay: null,
|
|
99240
|
-
modelWindowsByModel: {},
|
|
99241
|
-
observedAt,
|
|
99242
|
-
fiveHourObservedAt: null,
|
|
99243
|
-
sevenDayObservedAt: null
|
|
99244
|
-
};
|
|
99245
|
-
}
|
|
99246
|
-
/** Oldest observation among the retained standard windows, so one fresh event cannot mask stale data. */
|
|
99247
|
-
function oldestObservedAt(fiveHourObservedAt, sevenDayObservedAt) {
|
|
99248
|
-
return [fiveHourObservedAt, sevenDayObservedAt].filter((value) => value !== null).toSorted()[0];
|
|
99249
|
-
}
|
|
99250
|
-
function withStandardWindow(previous, mapped, observedAt) {
|
|
99251
|
-
const isFiveHour = mapped.kind === "fiveHour";
|
|
99252
|
-
const fiveHourObservedAt = isFiveHour ? observedAt : previous.fiveHourObservedAt;
|
|
99253
|
-
const sevenDayObservedAt = isFiveHour ? previous.sevenDayObservedAt : observedAt;
|
|
99254
|
-
return {
|
|
99255
|
-
...previous,
|
|
99256
|
-
fiveHour: isFiveHour ? mapped.window : previous.fiveHour,
|
|
99257
|
-
sevenDay: isFiveHour ? previous.sevenDay : mapped.window,
|
|
99258
|
-
fiveHourObservedAt,
|
|
99259
|
-
sevenDayObservedAt,
|
|
99260
|
-
observedAt: oldestObservedAt(fiveHourObservedAt, sevenDayObservedAt)
|
|
99261
|
-
};
|
|
99262
|
-
}
|
|
99263
|
-
function withModelWindow(previous, mapped) {
|
|
99264
|
-
return {
|
|
99265
|
-
...previous,
|
|
99266
|
-
modelWindowsByModel: {
|
|
99267
|
-
...previous.modelWindowsByModel,
|
|
99268
|
-
[mapped.model]: mapped.window
|
|
99269
|
-
}
|
|
99270
|
-
};
|
|
99271
|
-
}
|
|
99272
|
-
/**
|
|
99273
|
-
* Merges a single-window update into the cached snapshot without clobbering
|
|
99274
|
-
* the other windows. A per-model weekly report (`seven_day_<model>`) merges
|
|
99275
|
-
* into `modelWindowsByModel` keyed by model, leaving every other model and
|
|
99276
|
-
* the plain five_hour/seven_day windows untouched.
|
|
99277
|
-
*/
|
|
99278
|
-
function recordClaudeRateLimitTelemetry(info, generationHash = currentClaudeUsageGenerationHash(), providerAccountId) {
|
|
99279
|
-
if (generationHash === null) return;
|
|
99280
|
-
const cacheKey = cacheKeyFor(generationHash, providerAccountId);
|
|
99281
|
-
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
99282
|
-
const previous = cachedSnapshots.get(cacheKey) ?? emptyCachedSnapshot(observedAt);
|
|
99283
|
-
const standard = mapClaudeRateLimitInfo(info);
|
|
99284
|
-
if (standard) {
|
|
99285
|
-
cachedSnapshots.set(cacheKey, withStandardWindow(previous, standard, observedAt));
|
|
99286
|
-
return;
|
|
99287
|
-
}
|
|
99288
|
-
const model = mapClaudeModelRateLimitInfo(info);
|
|
99289
|
-
if (model) cachedSnapshots.set(cacheKey, withModelWindow(previous, model));
|
|
99290
|
-
}
|
|
99291
|
-
//#endregion
|
|
99292
99475
|
//#region src/providerAuth/ClaudeDeviceAuth.ts
|
|
99293
99476
|
const AUTHORIZE_URL_PATTERN = /https:\/\/[^\s]*\/oauth\/authorize\?[^\s]+/u;
|
|
99294
99477
|
const ANSI_ESCAPE_PATTERN$1 = new RegExp(String.raw`\x1B\[[0-?]*[ -/]*[@-~]`, "gu");
|
|
@@ -99803,7 +99986,6 @@ async function finalizeClaudeCredentialSync(input) {
|
|
|
99803
99986
|
const providerAccountId = extractClaudeProviderAccountId(input.response);
|
|
99804
99987
|
const credentialGenerationId = extractClaudeCredentialGenerationId(input.response);
|
|
99805
99988
|
if (providerAccountId === null || credentialGenerationId === null) return null;
|
|
99806
|
-
if (input.auth.path === USER_CLAUDE_CREDENTIAL_PATH) setLocalClaudeUsageGeneration(credentialGenerationId);
|
|
99807
99989
|
return publishClaudeUsageAfterSync({
|
|
99808
99990
|
auth: input.auth,
|
|
99809
99991
|
providerAccountId,
|
|
@@ -146893,137 +147075,6 @@ const LocalAutomationRepositoryLive = effect(LocalAutomationRepository, gen(func
|
|
|
146893
147075
|
*/
|
|
146894
147076
|
var CodexAdapter = class extends Service$1()("forge/provider/Services/CodexAdapter") {};
|
|
146895
147077
|
//#endregion
|
|
146896
|
-
//#region ../../packages/shared/src/model.ts
|
|
146897
|
-
/** Check whether a capabilities object includes a given effort value. */
|
|
146898
|
-
function hasEffortLevel(caps, value) {
|
|
146899
|
-
return caps.reasoningEffortLevels.some((l) => l.value === value);
|
|
146900
|
-
}
|
|
146901
|
-
/** Return the default effort value for a capabilities object, or null if none. */
|
|
146902
|
-
function getDefaultEffort(caps) {
|
|
146903
|
-
return caps.reasoningEffortLevels.find((l) => l.isDefault)?.value ?? null;
|
|
146904
|
-
}
|
|
146905
|
-
/**
|
|
146906
|
-
* Resolve a raw effort option against capabilities.
|
|
146907
|
-
*
|
|
146908
|
-
* Returns the effective effort value — the explicit value if supported and not
|
|
146909
|
-
* prompt-injected, otherwise the model's default. Returns `undefined` only
|
|
146910
|
-
* when the model has no effort levels at all.
|
|
146911
|
-
*
|
|
146912
|
-
* Prompt-injected efforts (e.g. "ultrathink") are excluded because they are
|
|
146913
|
-
* applied via prompt text, not the effort API parameter.
|
|
146914
|
-
*/
|
|
146915
|
-
function resolveEffort(caps, raw) {
|
|
146916
|
-
const defaultValue = getDefaultEffort(caps);
|
|
146917
|
-
const trimmed = typeof raw === "string" ? raw.trim() : null;
|
|
146918
|
-
if (trimmed && !caps.promptInjectedEffortLevels.includes(trimmed) && hasEffortLevel(caps, trimmed)) return trimmed;
|
|
146919
|
-
return defaultValue ?? void 0;
|
|
146920
|
-
}
|
|
146921
|
-
/** Check whether a capabilities object includes a given context window value. */
|
|
146922
|
-
function hasContextWindowOption(caps, value) {
|
|
146923
|
-
return caps.contextWindowOptions.some((o) => o.value === value);
|
|
146924
|
-
}
|
|
146925
|
-
/** Return the default context window value, or `null` if none is defined. */
|
|
146926
|
-
function getDefaultContextWindow(caps) {
|
|
146927
|
-
return caps.contextWindowOptions.find((o) => o.isDefault)?.value ?? null;
|
|
146928
|
-
}
|
|
146929
|
-
/**
|
|
146930
|
-
* Resolve a raw `contextWindow` option against capabilities.
|
|
146931
|
-
*
|
|
146932
|
-
* Returns the effective context window value — the explicit value if supported,
|
|
146933
|
-
* otherwise the model's default. Returns `undefined` only when the model has
|
|
146934
|
-
* no context window options at all.
|
|
146935
|
-
*
|
|
146936
|
-
* Unlike effort levels (where the API has matching defaults), the context
|
|
146937
|
-
* window requires an explicit API suffix (e.g. `[1m]`), so we always preserve
|
|
146938
|
-
* the resolved value to avoid ambiguity between "user chose the default" and
|
|
146939
|
-
* "not specified".
|
|
146940
|
-
*/
|
|
146941
|
-
function resolveContextWindow(caps, raw) {
|
|
146942
|
-
const defaultValue = getDefaultContextWindow(caps);
|
|
146943
|
-
if (!raw) return defaultValue ?? void 0;
|
|
146944
|
-
return hasContextWindowOption(caps, raw) ? raw : defaultValue ?? void 0;
|
|
146945
|
-
}
|
|
146946
|
-
function normalizeCodexModelOptionsWithCapabilities(caps, modelOptions) {
|
|
146947
|
-
const reasoningEffort = resolveEffort(caps, modelOptions?.reasoningEffort);
|
|
146948
|
-
const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
|
|
146949
|
-
const nextOptions = {
|
|
146950
|
-
...reasoningEffort ? { reasoningEffort } : {},
|
|
146951
|
-
...fastMode !== void 0 ? { fastMode } : {}
|
|
146952
|
-
};
|
|
146953
|
-
return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
|
|
146954
|
-
}
|
|
146955
|
-
function normalizeClaudeModelOptionsWithCapabilities(caps, modelOptions) {
|
|
146956
|
-
const effort = resolveEffort(caps, modelOptions?.effort);
|
|
146957
|
-
const thinking = caps.supportsThinkingToggle ? modelOptions?.thinking : void 0;
|
|
146958
|
-
const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
|
|
146959
|
-
const contextWindow = resolveContextWindow(caps, modelOptions?.contextWindow);
|
|
146960
|
-
const nextOptions = {
|
|
146961
|
-
...thinking !== void 0 ? { thinking } : {},
|
|
146962
|
-
...effort ? { effort } : {},
|
|
146963
|
-
...fastMode !== void 0 ? { fastMode } : {},
|
|
146964
|
-
...contextWindow !== void 0 ? { contextWindow } : {}
|
|
146965
|
-
};
|
|
146966
|
-
return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
|
|
146967
|
-
}
|
|
146968
|
-
function normalizeModelSlug(model, provider = "codex") {
|
|
146969
|
-
if (typeof model !== "string") return null;
|
|
146970
|
-
const trimmed = model.trim();
|
|
146971
|
-
if (!trimmed) return null;
|
|
146972
|
-
const aliases = MODEL_SLUG_ALIASES_BY_PROVIDER[provider];
|
|
146973
|
-
const aliased = Object.prototype.hasOwnProperty.call(aliases, trimmed) ? aliases[trimmed] : void 0;
|
|
146974
|
-
return typeof aliased === "string" ? aliased : trimmed;
|
|
146975
|
-
}
|
|
146976
|
-
/** Trim a string, returning null for empty/missing values. */
|
|
146977
|
-
function trimOrNull(value) {
|
|
146978
|
-
if (typeof value !== "string") return null;
|
|
146979
|
-
return value.trim() || null;
|
|
146980
|
-
}
|
|
146981
|
-
/**
|
|
146982
|
-
* Resolve the actual API model identifier from a model selection.
|
|
146983
|
-
*
|
|
146984
|
-
* Provider-aware: each provider can map `contextWindow` (or other options)
|
|
146985
|
-
* to whatever the API requires — a model-id suffix, a separate parameter, etc.
|
|
146986
|
-
* The canonical slug stored in the selection stays unchanged so the
|
|
146987
|
-
* capabilities system keeps working.
|
|
146988
|
-
*
|
|
146989
|
-
* Expects `contextWindow` to already be resolved (via `resolveContextWindow`)
|
|
146990
|
-
* to the effective value, not stripped to `undefined` for defaults.
|
|
146991
|
-
*/
|
|
146992
|
-
function resolveApiModelId(modelSelection) {
|
|
146993
|
-
switch (modelSelection.provider) {
|
|
146994
|
-
case "claudeAgent": switch (modelSelection.options?.contextWindow) {
|
|
146995
|
-
case "1m": return `${modelSelection.model}[1m]`;
|
|
146996
|
-
default: return modelSelection.model;
|
|
146997
|
-
}
|
|
146998
|
-
default: return modelSelection.model;
|
|
146999
|
-
}
|
|
147000
|
-
}
|
|
147001
|
-
function applyClaudePromptEffortPrefix(text, effort) {
|
|
147002
|
-
const trimmed = text.trim();
|
|
147003
|
-
if (!trimmed) return trimmed;
|
|
147004
|
-
if (effort !== "ultrathink") return trimmed;
|
|
147005
|
-
if (trimmed.startsWith("Ultrathink:")) return trimmed;
|
|
147006
|
-
return `Ultrathink:\n${trimmed}`;
|
|
147007
|
-
}
|
|
147008
|
-
function getRawProviderOptionSelectionValue(selections, id) {
|
|
147009
|
-
return selections?.find((candidate) => candidate.id === id)?.value;
|
|
147010
|
-
}
|
|
147011
|
-
function getProviderOptionSelectionValue(selections, id) {
|
|
147012
|
-
return getRawProviderOptionSelectionValue(selections, id);
|
|
147013
|
-
}
|
|
147014
|
-
function getProviderOptionStringSelectionValue(selections, id) {
|
|
147015
|
-
const value = getProviderOptionSelectionValue(selections, id);
|
|
147016
|
-
return typeof value === "string" ? value : void 0;
|
|
147017
|
-
}
|
|
147018
|
-
function flatProviderOptions(selection) {
|
|
147019
|
-
if (!selection) return void 0;
|
|
147020
|
-
if (selection.provider !== "cursor" && selection.provider !== "opencode") return void 0;
|
|
147021
|
-
return selection.options;
|
|
147022
|
-
}
|
|
147023
|
-
function getModelSelectionStringOptionValue(selection, id) {
|
|
147024
|
-
return getProviderOptionStringSelectionValue(flatProviderOptions(selection), id);
|
|
147025
|
-
}
|
|
147026
|
-
//#endregion
|
|
147027
147078
|
//#region src/provider/codexCliVersion.ts
|
|
147028
147079
|
const CODEX_VERSION_PATTERN = /\bv?(\d+\.\d+(?:\.\d+)?(?:-[0-9A-Za-z.-]+)?)\b/;
|
|
147029
147080
|
const MINIMUM_CODEX_CLI_VERSION = "0.37.0";
|
|
@@ -147678,6 +147729,213 @@ async function probeCodexDiscovery(input) {
|
|
|
147678
147729
|
});
|
|
147679
147730
|
}
|
|
147680
147731
|
//#endregion
|
|
147732
|
+
//#region ../../packages/shared/src/model.ts
|
|
147733
|
+
/** Check whether a capabilities object includes a given effort value. */
|
|
147734
|
+
function hasEffortLevel(caps, value) {
|
|
147735
|
+
return caps.reasoningEffortLevels.some((l) => l.value === value);
|
|
147736
|
+
}
|
|
147737
|
+
/** Return the default effort value for a capabilities object, or null if none. */
|
|
147738
|
+
function getDefaultEffort(caps) {
|
|
147739
|
+
return caps.reasoningEffortLevels.find((l) => l.isDefault)?.value ?? null;
|
|
147740
|
+
}
|
|
147741
|
+
/**
|
|
147742
|
+
* Resolve a raw effort option against capabilities.
|
|
147743
|
+
*
|
|
147744
|
+
* Returns the effective effort value — the explicit value if supported and not
|
|
147745
|
+
* prompt-injected, otherwise the model's default. Returns `undefined` only
|
|
147746
|
+
* when the model has no effort levels at all.
|
|
147747
|
+
*
|
|
147748
|
+
* Prompt-injected efforts (e.g. "ultrathink") are excluded because they are
|
|
147749
|
+
* applied via prompt text, not the effort API parameter.
|
|
147750
|
+
*/
|
|
147751
|
+
function resolveEffort(caps, raw) {
|
|
147752
|
+
const defaultValue = getDefaultEffort(caps);
|
|
147753
|
+
const trimmed = typeof raw === "string" ? raw.trim() : null;
|
|
147754
|
+
if (trimmed && !caps.promptInjectedEffortLevels.includes(trimmed) && hasEffortLevel(caps, trimmed)) return trimmed;
|
|
147755
|
+
return defaultValue ?? void 0;
|
|
147756
|
+
}
|
|
147757
|
+
/** Check whether a capabilities object includes a given context window value. */
|
|
147758
|
+
function hasContextWindowOption(caps, value) {
|
|
147759
|
+
return caps.contextWindowOptions.some((o) => o.value === value);
|
|
147760
|
+
}
|
|
147761
|
+
/** Return the default context window value, or `null` if none is defined. */
|
|
147762
|
+
function getDefaultContextWindow(caps) {
|
|
147763
|
+
return caps.contextWindowOptions.find((o) => o.isDefault)?.value ?? null;
|
|
147764
|
+
}
|
|
147765
|
+
/**
|
|
147766
|
+
* Resolve a raw `contextWindow` option against capabilities.
|
|
147767
|
+
*
|
|
147768
|
+
* Returns the effective context window value — the explicit value if supported,
|
|
147769
|
+
* otherwise the model's default. Returns `undefined` only when the model has
|
|
147770
|
+
* no context window options at all.
|
|
147771
|
+
*
|
|
147772
|
+
* Unlike effort levels (where the API has matching defaults), the context
|
|
147773
|
+
* window requires an explicit API suffix (e.g. `[1m]`), so we always preserve
|
|
147774
|
+
* the resolved value to avoid ambiguity between "user chose the default" and
|
|
147775
|
+
* "not specified".
|
|
147776
|
+
*/
|
|
147777
|
+
function resolveContextWindow(caps, raw) {
|
|
147778
|
+
const defaultValue = getDefaultContextWindow(caps);
|
|
147779
|
+
if (!raw) return defaultValue ?? void 0;
|
|
147780
|
+
return hasContextWindowOption(caps, raw) ? raw : defaultValue ?? void 0;
|
|
147781
|
+
}
|
|
147782
|
+
function normalizeCodexModelOptionsWithCapabilities(caps, modelOptions) {
|
|
147783
|
+
const reasoningEffort = resolveEffort(caps, modelOptions?.reasoningEffort);
|
|
147784
|
+
const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
|
|
147785
|
+
const nextOptions = {
|
|
147786
|
+
...reasoningEffort ? { reasoningEffort } : {},
|
|
147787
|
+
...fastMode !== void 0 ? { fastMode } : {}
|
|
147788
|
+
};
|
|
147789
|
+
return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
|
|
147790
|
+
}
|
|
147791
|
+
function normalizeClaudeModelOptionsWithCapabilities(caps, modelOptions) {
|
|
147792
|
+
const effort = resolveEffort(caps, modelOptions?.effort);
|
|
147793
|
+
const thinking = caps.supportsThinkingToggle ? modelOptions?.thinking : void 0;
|
|
147794
|
+
const fastMode = caps.supportsFastMode ? modelOptions?.fastMode : void 0;
|
|
147795
|
+
const contextWindow = resolveContextWindow(caps, modelOptions?.contextWindow);
|
|
147796
|
+
const nextOptions = {
|
|
147797
|
+
...thinking !== void 0 ? { thinking } : {},
|
|
147798
|
+
...effort ? { effort } : {},
|
|
147799
|
+
...fastMode !== void 0 ? { fastMode } : {},
|
|
147800
|
+
...contextWindow !== void 0 ? { contextWindow } : {}
|
|
147801
|
+
};
|
|
147802
|
+
return Object.keys(nextOptions).length > 0 ? nextOptions : void 0;
|
|
147803
|
+
}
|
|
147804
|
+
function normalizeModelSlug(model, provider = "codex") {
|
|
147805
|
+
if (typeof model !== "string") return null;
|
|
147806
|
+
const trimmed = model.trim();
|
|
147807
|
+
if (!trimmed) return null;
|
|
147808
|
+
const aliases = MODEL_SLUG_ALIASES_BY_PROVIDER[provider];
|
|
147809
|
+
const aliased = Object.prototype.hasOwnProperty.call(aliases, trimmed) ? aliases[trimmed] : void 0;
|
|
147810
|
+
return typeof aliased === "string" ? aliased : trimmed;
|
|
147811
|
+
}
|
|
147812
|
+
/** Trim a string, returning null for empty/missing values. */
|
|
147813
|
+
function trimOrNull(value) {
|
|
147814
|
+
if (typeof value !== "string") return null;
|
|
147815
|
+
return value.trim() || null;
|
|
147816
|
+
}
|
|
147817
|
+
/**
|
|
147818
|
+
* Resolve the actual API model identifier from a model selection.
|
|
147819
|
+
*
|
|
147820
|
+
* Provider-aware: each provider can map `contextWindow` (or other options)
|
|
147821
|
+
* to whatever the API requires — a model-id suffix, a separate parameter, etc.
|
|
147822
|
+
* The canonical slug stored in the selection stays unchanged so the
|
|
147823
|
+
* capabilities system keeps working.
|
|
147824
|
+
*
|
|
147825
|
+
* Expects `contextWindow` to already be resolved (via `resolveContextWindow`)
|
|
147826
|
+
* to the effective value, not stripped to `undefined` for defaults.
|
|
147827
|
+
*/
|
|
147828
|
+
function resolveApiModelId(modelSelection) {
|
|
147829
|
+
switch (modelSelection.provider) {
|
|
147830
|
+
case "claudeAgent": switch (modelSelection.options?.contextWindow) {
|
|
147831
|
+
case "1m": return `${modelSelection.model}[1m]`;
|
|
147832
|
+
default: return modelSelection.model;
|
|
147833
|
+
}
|
|
147834
|
+
default: return modelSelection.model;
|
|
147835
|
+
}
|
|
147836
|
+
}
|
|
147837
|
+
function applyClaudePromptEffortPrefix(text, effort) {
|
|
147838
|
+
const trimmed = text.trim();
|
|
147839
|
+
if (!trimmed) return trimmed;
|
|
147840
|
+
if (effort !== "ultrathink") return trimmed;
|
|
147841
|
+
if (trimmed.startsWith("Ultrathink:")) return trimmed;
|
|
147842
|
+
return `Ultrathink:\n${trimmed}`;
|
|
147843
|
+
}
|
|
147844
|
+
function getRawProviderOptionSelectionValue(selections, id) {
|
|
147845
|
+
return selections?.find((candidate) => candidate.id === id)?.value;
|
|
147846
|
+
}
|
|
147847
|
+
function getProviderOptionSelectionValue(selections, id) {
|
|
147848
|
+
return getRawProviderOptionSelectionValue(selections, id);
|
|
147849
|
+
}
|
|
147850
|
+
function getProviderOptionStringSelectionValue(selections, id) {
|
|
147851
|
+
const value = getProviderOptionSelectionValue(selections, id);
|
|
147852
|
+
return typeof value === "string" ? value : void 0;
|
|
147853
|
+
}
|
|
147854
|
+
function flatProviderOptions(selection) {
|
|
147855
|
+
if (!selection) return void 0;
|
|
147856
|
+
if (selection.provider !== "cursor" && selection.provider !== "opencode") return void 0;
|
|
147857
|
+
return selection.options;
|
|
147858
|
+
}
|
|
147859
|
+
function getModelSelectionStringOptionValue(selection, id) {
|
|
147860
|
+
return getProviderOptionStringSelectionValue(flatProviderOptions(selection), id);
|
|
147861
|
+
}
|
|
147862
|
+
function acceptableModelSlug(value) {
|
|
147863
|
+
const trimmed = value?.trim();
|
|
147864
|
+
if (!trimmed || trimmed.length > 120) return;
|
|
147865
|
+
return trimmed;
|
|
147866
|
+
}
|
|
147867
|
+
/**
|
|
147868
|
+
* Order the credential's model scope: selected model first, then the catalog,
|
|
147869
|
+
* deduplicated and capped.
|
|
147870
|
+
*
|
|
147871
|
+
* Returns `undefined` when there is no catalog to widen to, which is the signal
|
|
147872
|
+
* to send the old single-model body. A slug CMMD would refuse is dropped rather
|
|
147873
|
+
* than sent, because one bad entry 400s the whole mint and takes the session
|
|
147874
|
+
* with it.
|
|
147875
|
+
*/
|
|
147876
|
+
function providerEgressModelScope(model, models) {
|
|
147877
|
+
const catalog = (models ?? []).map(acceptableModelSlug).filter((slug) => slug !== void 0);
|
|
147878
|
+
if (catalog.length === 0) return;
|
|
147879
|
+
const selected = acceptableModelSlug(model);
|
|
147880
|
+
const ordered = new Set(selected ? [selected] : []);
|
|
147881
|
+
for (const slug of catalog) {
|
|
147882
|
+
if (ordered.size >= 32) break;
|
|
147883
|
+
ordered.add(slug);
|
|
147884
|
+
}
|
|
147885
|
+
return [...ordered];
|
|
147886
|
+
}
|
|
147887
|
+
//#endregion
|
|
147888
|
+
//#region src/provider/codexCredentialModelScope.ts
|
|
147889
|
+
/**
|
|
147890
|
+
* Which Codex models one workspace egress credential has to cover.
|
|
147891
|
+
*
|
|
147892
|
+
* FOR-36501: the credential was scoped to the model the user picked, and the
|
|
147893
|
+
* Codex app-server holds one credential for the whole process. A turn on
|
|
147894
|
+
* gpt-6-astra that called `spawn_agent` with gpt-5.6-terra therefore lost the
|
|
147895
|
+
* child to a 401 before it spent a token. The subagent model is the model's own
|
|
147896
|
+
* choice in the tool arguments, so Forge cannot predict it and has to scope the
|
|
147897
|
+
* credential to the catalog a spawn can pick from.
|
|
147898
|
+
*
|
|
147899
|
+
* The catalog is the built-in Codex list, which is what the picker offers. It
|
|
147900
|
+
* includes the Spark model even though only a Pro account may call it: the
|
|
147901
|
+
* account snapshot is not resolved at issue time in workspace mode, and CMMD
|
|
147902
|
+
* still decides per call which models the account may use, so a slug in the
|
|
147903
|
+
* scope is permission to ask, never permission to spend.
|
|
147904
|
+
*/
|
|
147905
|
+
/**
|
|
147906
|
+
* Normalize a Codex model slug to the one the app-server and the mint route use.
|
|
147907
|
+
*
|
|
147908
|
+
* Lives here rather than in codexAppServerManager.ts so the catalog builder can
|
|
147909
|
+
* use it without importing the manager back. The manager re-exports it, which is
|
|
147910
|
+
* where every existing caller still reads it from.
|
|
147911
|
+
*/
|
|
147912
|
+
function normalizeCodexModelSlug(model, preferredId) {
|
|
147913
|
+
const normalized = normalizeModelSlug(model);
|
|
147914
|
+
if (!normalized) return;
|
|
147915
|
+
if (preferredId?.endsWith("-codex") && preferredId !== normalized) return preferredId;
|
|
147916
|
+
return normalized;
|
|
147917
|
+
}
|
|
147918
|
+
/** The model a proxy token is minted for when the thread names none. */
|
|
147919
|
+
function resolveCodexProviderProxyTokenModel(model) {
|
|
147920
|
+
const displaySlug = model?.trim().toLowerCase().replace(/\s+/g, "-");
|
|
147921
|
+
return normalizeCodexModelSlug(displaySlug) ?? "gpt-6-astra";
|
|
147922
|
+
}
|
|
147923
|
+
/** Every built-in Codex slug a `spawn_agent` call can name. */
|
|
147924
|
+
function codexCredentialModelCatalog() {
|
|
147925
|
+
return CODEX_BUILT_IN_MODELS.map((model) => normalizeCodexModelSlug(model.slug) ?? model.slug);
|
|
147926
|
+
}
|
|
147927
|
+
/**
|
|
147928
|
+
* The `models` list to mint a Codex session credential with.
|
|
147929
|
+
*
|
|
147930
|
+
* `undefined` means the catalog is unknown, and the caller then sends `model`
|
|
147931
|
+
* alone, exactly as before this card. That is the only safe answer: an empty
|
|
147932
|
+
* list would narrow the credential rather than widen it.
|
|
147933
|
+
*/
|
|
147934
|
+
function buildCodexCredentialModelScope(input) {
|
|
147935
|
+
const catalog = (input.catalogModels ?? codexCredentialModelCatalog()).map((slug) => normalizeCodexModelSlug(slug) ?? slug).filter((slug) => slug.trim().length > 0);
|
|
147936
|
+
return providerEgressModelScope(input.selectedModel, catalog);
|
|
147937
|
+
}
|
|
147938
|
+
//#endregion
|
|
147681
147939
|
//#region src/egress/providerDeliveryReceipt.ts
|
|
147682
147940
|
const PROVIDER_ACCOUNT_IDENTITY$2 = /^pai_v1_[A-Za-z0-9_-]{43}$/;
|
|
147683
147941
|
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;
|
|
@@ -147929,6 +148187,21 @@ function runtimeProviderEgressBaseUrl(provider, controlPlaneUrl) {
|
|
|
147929
148187
|
anthropic: "/api/provider-egress/anthropic"
|
|
147930
148188
|
}[provider]}`;
|
|
147931
148189
|
}
|
|
148190
|
+
/**
|
|
148191
|
+
* The model fields of a mint body.
|
|
148192
|
+
*
|
|
148193
|
+
* `model` stays the single selected model, which is what CMMD runs its
|
|
148194
|
+
* post-mint constraint check on. `models` appears only when the caller knows a
|
|
148195
|
+
* catalog, so a caller that does not know one sends exactly the body it sent
|
|
148196
|
+
* before FOR-36501.
|
|
148197
|
+
*/
|
|
148198
|
+
function providerEgressModelBodyFields(input) {
|
|
148199
|
+
const scope = providerEgressModelScope(input.model, input.models);
|
|
148200
|
+
return {
|
|
148201
|
+
...input.model ? { model: input.model } : {},
|
|
148202
|
+
...scope ? { models: scope } : {}
|
|
148203
|
+
};
|
|
148204
|
+
}
|
|
147932
148205
|
const issueProviderEgressToken = (input) => issueProviderEgressCredential(input).pipe(map$3((credential) => credential.token));
|
|
147933
148206
|
const issueProviderEgressCredential = (input) => tryPromise({
|
|
147934
148207
|
try: async () => {
|
|
@@ -147952,7 +148225,7 @@ async function issueCmmdRuntimeProviderEgressCredential(input) {
|
|
|
147952
148225
|
token: runtimeGrantToken,
|
|
147953
148226
|
body: JSON.stringify({
|
|
147954
148227
|
provider: input.provider,
|
|
147955
|
-
...input
|
|
148228
|
+
...providerEgressModelBodyFields(input),
|
|
147956
148229
|
...input.provider === "openai" && input.providerAccountId ? { provider_account_id: input.providerAccountId } : {}
|
|
147957
148230
|
})
|
|
147958
148231
|
});
|
|
@@ -148068,7 +148341,7 @@ function issueCmmdLocalUserProviderEgressCredential(input) {
|
|
|
148068
148341
|
},
|
|
148069
148342
|
body: JSON.stringify({
|
|
148070
148343
|
provider: input.provider,
|
|
148071
|
-
...input
|
|
148344
|
+
...providerEgressModelBodyFields(input),
|
|
148072
148345
|
...input.provider === "openai" && input.providerAccountId ? { provider_account_id: input.providerAccountId } : {},
|
|
148073
148346
|
client: "local-desktop",
|
|
148074
148347
|
sessionId,
|
|
@@ -148451,16 +148724,6 @@ function mapCodexRuntimeMode(runtimeMode) {
|
|
|
148451
148724
|
async function killChildTree(child) {
|
|
148452
148725
|
await killCodexChildProcess(child);
|
|
148453
148726
|
}
|
|
148454
|
-
function normalizeCodexModelSlug(model, preferredId) {
|
|
148455
|
-
const normalized = normalizeModelSlug(model);
|
|
148456
|
-
if (!normalized) return;
|
|
148457
|
-
if (preferredId?.endsWith("-codex") && preferredId !== normalized) return preferredId;
|
|
148458
|
-
return normalized;
|
|
148459
|
-
}
|
|
148460
|
-
function resolveCodexProviderProxyTokenModel(model) {
|
|
148461
|
-
const displaySlug = model?.trim().toLowerCase().replace(/\s+/g, "-");
|
|
148462
|
-
return normalizeCodexModelSlug(displaySlug) ?? "gpt-6-astra";
|
|
148463
|
-
}
|
|
148464
148727
|
function buildCodexCollaborationMode(input) {
|
|
148465
148728
|
if (input.interactionMode === void 0) return;
|
|
148466
148729
|
const model = normalizeCodexModelSlug(input.model) ?? "gpt-6-astra";
|
|
@@ -149011,9 +149274,11 @@ var CodexAppServerManager = class extends EventEmitter$1 {
|
|
|
149011
149274
|
const proxyConfig = getOpenAiProviderEgressProxyConfig({ allowLocalUser: true });
|
|
149012
149275
|
if (proxyConfig.mode === "disabled") return null;
|
|
149013
149276
|
if (proxyConfig.mode === "misconfigured") throw new ProviderEgressTokenError({ message: proxyConfig.message });
|
|
149277
|
+
const models = buildCodexCredentialModelScope({ selectedModel: input.model });
|
|
149014
149278
|
return await runPromise(issueProviderEgressCredential({
|
|
149015
149279
|
provider: "openai",
|
|
149016
149280
|
model: input.model,
|
|
149281
|
+
...models ? { models } : {},
|
|
149017
149282
|
threadId: input.threadId,
|
|
149018
149283
|
...input.providerAccountId ? { providerAccountId: input.providerAccountId } : {}
|
|
149019
149284
|
}));
|
|
@@ -207200,36 +207465,23 @@ function mapCodexThreadNameUpdatedEvent(event, canonicalThreadId, payload) {
|
|
|
207200
207465
|
}
|
|
207201
207466
|
}];
|
|
207202
207467
|
}
|
|
207203
|
-
/** One provider call's spend, from Codex's `last_token_usage`. */
|
|
207204
|
-
function codexTurnUsageDelta(value) {
|
|
207205
|
-
const usage = asObject$2(value);
|
|
207206
|
-
return codexUsageBuckets(usage?.last_token_usage ?? usage?.last, "call-delta");
|
|
207207
|
-
}
|
|
207208
207468
|
/**
|
|
207209
|
-
* One
|
|
207210
|
-
*
|
|
207211
|
-
*
|
|
207212
|
-
*
|
|
207469
|
+
* One provider call's spend, from Codex's `last_token_usage`. Reads the
|
|
207470
|
+
* buckets via `codexTokenBuckets`, the shared home of the Claude/Codex
|
|
207471
|
+
* disjointness rule (providerTokenBuckets.ts): Codex reports `input_tokens`
|
|
207472
|
+
* inclusive of the cached and cache-write portions, so the uncached bucket is
|
|
207473
|
+
* the remainder, and reasoning is reported inside output and surfaced
|
|
207474
|
+
* separately without being added again. Mirrors `parseCodexLine` in
|
|
207213
207475
|
* usage/usageTranscripts.ts so a Recorded turn and a scanned transcript agree
|
|
207214
207476
|
* on the same numbers.
|
|
207215
207477
|
*/
|
|
207216
|
-
function
|
|
207217
|
-
const
|
|
207218
|
-
|
|
207219
|
-
|
|
207220
|
-
|
|
207221
|
-
|
|
207222
|
-
|
|
207223
|
-
const outputTokens = int("output_tokens", "outputTokens");
|
|
207224
|
-
if (inputTokens + cachedInputTokens + cacheCreationTokens + outputTokens === 0) return void 0;
|
|
207225
|
-
return {
|
|
207226
|
-
scope,
|
|
207227
|
-
uncachedInputTokens: Math.max(0, inputTokens - cachedInputTokens - cacheCreationTokens),
|
|
207228
|
-
cachedInputTokens,
|
|
207229
|
-
cacheCreationTokens,
|
|
207230
|
-
outputTokens,
|
|
207231
|
-
reasoningTokens: Math.min(outputTokens, int("reasoning_output_tokens", "reasoningOutputTokens"))
|
|
207232
|
-
};
|
|
207478
|
+
function codexTurnUsageDelta(value) {
|
|
207479
|
+
const usage = asObject$2(value);
|
|
207480
|
+
const buckets = codexTokenBuckets(usage?.last_token_usage ?? usage?.last);
|
|
207481
|
+
return buckets ? {
|
|
207482
|
+
scope: "call-delta",
|
|
207483
|
+
...buckets
|
|
207484
|
+
} : void 0;
|
|
207233
207485
|
}
|
|
207234
207486
|
function mapCodexThreadTokenUsageEvent(event, canonicalThreadId, payload) {
|
|
207235
207487
|
const tokenUsage = asObject$2(payload?.tokenUsage);
|
|
@@ -207921,6 +208173,7 @@ const DEFAULT_PUBLIC_PROVIDER_ERROR = "CMMD is temporarily unavailable. Check th
|
|
|
207921
208173
|
function categorizePublicProviderError(message) {
|
|
207922
208174
|
if (!message) return null;
|
|
207923
208175
|
const m = message.toLowerCase();
|
|
208176
|
+
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.";
|
|
207924
208177
|
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.";
|
|
207925
208178
|
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.";
|
|
207926
208179
|
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.";
|
|
@@ -209769,9 +210022,6 @@ function buildClaudeSessionContext(input) {
|
|
|
209769
210022
|
query: input.queryRuntime,
|
|
209770
210023
|
streamFiber: void 0,
|
|
209771
210024
|
startedAt: input.startedAt,
|
|
209772
|
-
recordsPersonalUsageTelemetry: input.recordsPersonalUsageTelemetry,
|
|
209773
|
-
personalUsageGenerationHash: input.personalUsageGenerationHash,
|
|
209774
|
-
personalUsageProviderAccountId: input.personalUsageProviderAccountId,
|
|
209775
210025
|
basePermissionMode: input.permissionMode,
|
|
209776
210026
|
resumeSessionId: input.sessionId,
|
|
209777
210027
|
pendingApprovals: input.pendingApprovals,
|
|
@@ -210129,26 +210379,18 @@ function finiteNumberFieldOrZero(usage, key) {
|
|
|
210129
210379
|
}
|
|
210130
210380
|
/**
|
|
210131
210381
|
* The whole turn's spend from the SDK result message, cache split intact.
|
|
210132
|
-
*
|
|
210133
|
-
*
|
|
210134
|
-
*
|
|
210382
|
+
* Reads the buckets via `claudeTokenBuckets`, the shared home of the
|
|
210383
|
+
* Claude/Codex disjointness rule (providerTokenBuckets.ts): Claude reports
|
|
210384
|
+
* `input_tokens` exclusive of the cached and cache-creation portions, so the
|
|
210385
|
+
* buckets are already disjoint, and Claude does not report reasoning
|
|
210386
|
+
* separately.
|
|
210135
210387
|
*/
|
|
210136
210388
|
function claudeTurnUsageTotal(value) {
|
|
210137
|
-
const
|
|
210138
|
-
|
|
210139
|
-
const uncachedInputTokens = finiteNumberFieldOrZero(usage, "input_tokens");
|
|
210140
|
-
const cachedInputTokens = finiteNumberFieldOrZero(usage, "cache_read_input_tokens");
|
|
210141
|
-
const cacheCreationTokens = finiteNumberFieldOrZero(usage, "cache_creation_input_tokens");
|
|
210142
|
-
const outputTokens = finiteNumberFieldOrZero(usage, "output_tokens");
|
|
210143
|
-
if (uncachedInputTokens + cachedInputTokens + cacheCreationTokens + outputTokens <= 0) return;
|
|
210144
|
-
return {
|
|
210389
|
+
const buckets = claudeTokenBuckets(value);
|
|
210390
|
+
return buckets ? {
|
|
210145
210391
|
scope: "turn-total",
|
|
210146
|
-
|
|
210147
|
-
|
|
210148
|
-
cacheCreationTokens: Math.trunc(cacheCreationTokens),
|
|
210149
|
-
outputTokens: Math.trunc(outputTokens),
|
|
210150
|
-
reasoningTokens: 0
|
|
210151
|
-
};
|
|
210392
|
+
...buckets
|
|
210393
|
+
} : void 0;
|
|
210152
210394
|
}
|
|
210153
210395
|
const EMPTY_MODEL_USAGE_BUCKETS = {
|
|
210154
210396
|
uncachedInputTokens: 0,
|
|
@@ -210161,20 +210403,14 @@ function bucketsTotal(buckets) {
|
|
|
210161
210403
|
return buckets.uncachedInputTokens + buckets.cachedInputTokens + buckets.cacheCreationTokens + buckets.outputTokens;
|
|
210162
210404
|
}
|
|
210163
210405
|
/**
|
|
210164
|
-
* One `ModelUsage` entry as buckets
|
|
210165
|
-
* camelCase, unlike `result.usage`,
|
|
210166
|
-
* Claude reports `inputTokens` exclusive of the
|
|
210167
|
-
* portions, so the buckets are already disjoint, and
|
|
210406
|
+
* One `ModelUsage` entry as buckets, via `claudeTokenBuckets`. `ModelUsage`
|
|
210407
|
+
* names its fields in camelCase, unlike `result.usage`, but `claudeTokenBuckets`
|
|
210408
|
+
* already reads both spellings. Claude reports `inputTokens` exclusive of the
|
|
210409
|
+
* cached and cache-creation portions, so the buckets are already disjoint, and
|
|
210410
|
+
* it reports no reasoning.
|
|
210168
210411
|
*/
|
|
210169
210412
|
function claudeModelUsageBuckets(usage) {
|
|
210170
|
-
|
|
210171
|
-
return {
|
|
210172
|
-
uncachedInputTokens: Math.trunc(finiteNumberFieldOrZero(record, "inputTokens")),
|
|
210173
|
-
cachedInputTokens: Math.trunc(finiteNumberFieldOrZero(record, "cacheReadInputTokens")),
|
|
210174
|
-
cacheCreationTokens: Math.trunc(finiteNumberFieldOrZero(record, "cacheCreationInputTokens")),
|
|
210175
|
-
outputTokens: Math.trunc(finiteNumberFieldOrZero(record, "outputTokens")),
|
|
210176
|
-
reasoningTokens: 0
|
|
210177
|
-
};
|
|
210413
|
+
return claudeTokenBuckets(usage) ?? EMPTY_MODEL_USAGE_BUCKETS;
|
|
210178
210414
|
}
|
|
210179
210415
|
/**
|
|
210180
210416
|
* What each model spent during THIS turn, from the SDK's per-model totals.
|
|
@@ -211517,7 +211753,6 @@ const makeClaudeAdapter = fn$1("makeClaudeAdapter")(function* (options) {
|
|
|
211517
211753
|
return;
|
|
211518
211754
|
}
|
|
211519
211755
|
if (message.type === "rate_limit_event") {
|
|
211520
|
-
if (context.recordsPersonalUsageTelemetry) recordClaudeRateLimitTelemetry(message.rate_limit_info, context.personalUsageGenerationHash, context.personalUsageProviderAccountId);
|
|
211521
211756
|
yield* offerRuntimeEvent({
|
|
211522
211757
|
...base,
|
|
211523
211758
|
type: "account.rate-limits.updated",
|
|
@@ -212015,10 +212250,7 @@ const makeClaudeAdapter = fn$1("makeClaudeAdapter")(function* (options) {
|
|
|
212015
212250
|
inFlightTools,
|
|
212016
212251
|
resumeSessionAt: resumeState?.resumeSessionAt,
|
|
212017
212252
|
effectiveApiModelId: modelConfig.effectiveApiModelId,
|
|
212018
|
-
effectiveEffort: modelConfig.effectiveEffort
|
|
212019
|
-
recordsPersonalUsageTelemetry: sessionProvider === PROVIDER$11 && modelConfig.endpointProfile === void 0 && providerProxyCredential === null && !claudeSettings.anthropicBaseUrl && !claudeSettings.anthropicApiKey,
|
|
212020
|
-
personalUsageGenerationHash: currentClaudeUsageGenerationHash(),
|
|
212021
|
-
personalUsageProviderAccountId: modelConfig.modelSelection?.provider === "claudeAgent" ? modelConfig.modelSelection.providerAccountId : void 0
|
|
212253
|
+
effectiveEffort: modelConfig.effectiveEffort
|
|
212022
212254
|
});
|
|
212023
212255
|
yield* set$2(contextRef, context$4);
|
|
212024
212256
|
sessions.set(threadId, context$4);
|
|
@@ -284225,6 +284457,27 @@ const makeRuntimeDrainReporter = gen(function* () {
|
|
|
284225
284457
|
var RuntimeDrainReporter = class extends Service$1()("forge/runtimeDrain/RuntimeDrainReporter") {};
|
|
284226
284458
|
const RuntimeDrainReporterLive = effect(RuntimeDrainReporter, makeRuntimeDrainReporter);
|
|
284227
284459
|
//#endregion
|
|
284460
|
+
//#region src/usage/providerRateLimits.ts
|
|
284461
|
+
/**
|
|
284462
|
+
* The SDK only ever reports ONE window per event. Only `five_hour` and
|
|
284463
|
+
* `seven_day` map to the two windows the Usage page shows; the
|
|
284464
|
+
* per-model/overage variants (seven_day_opus, overage, ...) are ignored here
|
|
284465
|
+
* on purpose rather than silently overwriting the plain 7-day figure.
|
|
284466
|
+
*/
|
|
284467
|
+
function mapClaudeRateLimitInfo(info) {
|
|
284468
|
+
if (typeof info.utilization !== "number" || typeof info.resetsAt !== "number" || !info.status) return null;
|
|
284469
|
+
const kind = info.rateLimitType === "five_hour" ? "fiveHour" : info.rateLimitType === "seven_day" ? "sevenDay" : null;
|
|
284470
|
+
if (!kind) return null;
|
|
284471
|
+
return {
|
|
284472
|
+
kind,
|
|
284473
|
+
window: {
|
|
284474
|
+
usedPercent: Math.round(info.utilization * 100),
|
|
284475
|
+
resetsAt: (/* @__PURE__ */ new Date(info.resetsAt * 1e3)).toISOString(),
|
|
284476
|
+
status: info.status
|
|
284477
|
+
}
|
|
284478
|
+
};
|
|
284479
|
+
}
|
|
284480
|
+
//#endregion
|
|
284228
284481
|
//#region src/orchestration/Layers/ProviderRuntimeIngestion.ts
|
|
284229
284482
|
const providerTurnKey = (threadId, turnId) => `${threadId}:${turnId}`;
|
|
284230
284483
|
const providerCommandId = (event, tag) => CommandId.make(`provider:${event.eventId}:${tag}:${crypto.randomUUID()}`);
|
|
@@ -291239,7 +291492,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
291239
291492
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
291240
291493
|
*/
|
|
291241
291494
|
function readBakedBuildCommit() {
|
|
291242
|
-
return "
|
|
291495
|
+
return "9e352ae66ea610fd1916726270fce8a1ab138a3b";
|
|
291243
291496
|
}
|
|
291244
291497
|
async function resolveServerBuildCommit(input) {
|
|
291245
291498
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -300422,6 +300675,7 @@ function resolveWsUrl(baseUrl) {
|
|
|
300422
300675
|
const callCmmdTool = legacyCmmdToolBridge.callTool;
|
|
300423
300676
|
const extractMcpToolText = legacyCmmdToolBridge.extractText;
|
|
300424
300677
|
const isCmmdMcpAuthError = legacyCmmdToolBridge.isAuthError;
|
|
300678
|
+
const __cmmdProxyRouteLayersStartIndex = registeredProxyRouteLayers().length;
|
|
300425
300679
|
/**
|
|
300426
300680
|
* CMMD-side path for the PROJECT-keyed Forge Cloud catalog. Shared by the list
|
|
300427
300681
|
* proxy, the SSE poll-and-emit proxy, and the register/unregister proxies so the
|
|
@@ -300431,8 +300685,9 @@ const CMMD_CLOUD_PROJECTS_PATH = "/api/forge/context/cloud-projects";
|
|
|
300431
300685
|
const CMMD_RUNTIMES_PATH = "/api/forge/context/runtimes";
|
|
300432
300686
|
/**
|
|
300433
300687
|
* Authenticate the browser session and resolve the CMMD JWT to forward
|
|
300434
|
-
* upstream.
|
|
300435
|
-
* turns into
|
|
300688
|
+
* upstream. `jwt` is null when none could be resolved, which every caller
|
|
300689
|
+
* turns into `respondCmmdConnectionRequired(session.sessionId)` — the same
|
|
300690
|
+
* unified `CMMD_AUTH_REQUIRED` body and auth-clear the registry uses.
|
|
300436
300691
|
*
|
|
300437
300692
|
* Shared so the auth preamble is written once rather than once per proxy route.
|
|
300438
300693
|
*/
|
|
@@ -300440,11 +300695,14 @@ function makeCmmdProxyAccessTokenEffect(logPrefix) {
|
|
|
300440
300695
|
return gen(function* () {
|
|
300441
300696
|
const request = yield* HttpServerRequest;
|
|
300442
300697
|
const session = yield* (yield* ServerAuth).authenticateHttpRequest(request);
|
|
300443
|
-
return
|
|
300444
|
-
|
|
300445
|
-
|
|
300446
|
-
|
|
300447
|
-
|
|
300698
|
+
return {
|
|
300699
|
+
session,
|
|
300700
|
+
jwt: yield* resolveCmmdJwtForSession({
|
|
300701
|
+
sessionId: session.sessionId,
|
|
300702
|
+
subject: session.subject,
|
|
300703
|
+
logPrefix
|
|
300704
|
+
})
|
|
300705
|
+
};
|
|
300448
300706
|
});
|
|
300449
300707
|
}
|
|
300450
300708
|
var WorkIntakeSnapshotReadError = class extends TaggedErrorClass()("WorkIntakeSnapshotReadError", {
|
|
@@ -300524,32 +300782,19 @@ const cmmdProfileRouteLayer = add$1("GET", "/api/cmmd/profile", gen(function* ()
|
|
|
300524
300782
|
* `resolution`/`sinceTime`/`untilTime` when the page is drawing hours, which is
|
|
300525
300783
|
* what lets CMMD cut hour buckets rather than only days.
|
|
300526
300784
|
*/
|
|
300527
|
-
|
|
300785
|
+
registerProxyRoute({
|
|
300528
300786
|
forgePath: "/api/cmmd/usage/summary",
|
|
300529
300787
|
method: "GET",
|
|
300530
300788
|
cmmdPath: "/api/forge/context/usage/summary",
|
|
300531
300789
|
orgIdSource: "none"
|
|
300532
300790
|
});
|
|
300533
|
-
|
|
300534
|
-
* The workspace's CMMD plan: entitlements, the current period, and how much of
|
|
300535
|
-
* each metered allowance is left. This is subscription consumption, which is a
|
|
300536
|
-
* different question from the API-equivalent estimate the usage summary above
|
|
300537
|
-
* computes from transcripts.
|
|
300538
|
-
*
|
|
300539
|
-
* `orgIdSource` is `query` (FOR-36406): a plan belongs to an organization, and
|
|
300540
|
-
* without one CMMD answers for the user's default organization, which is their
|
|
300541
|
-
* personal space rather than the workspace their Environment runs in. The web
|
|
300542
|
-
* passes the Environment's organization as `?orgId=` and the registry turns it
|
|
300543
|
-
* into `X-Organization-ID`; without it CMMD still answers, for the default.
|
|
300544
|
-
*/
|
|
300545
|
-
const cmmdBillingRouteLayer = registerProxyRoute({
|
|
300791
|
+
registerProxyRoute({
|
|
300546
300792
|
forgePath: "/api/cmmd/billing",
|
|
300547
300793
|
method: "GET",
|
|
300548
300794
|
cmmdPath: "/api/forge/context/billing",
|
|
300549
300795
|
orgIdSource: "query"
|
|
300550
300796
|
});
|
|
300551
|
-
|
|
300552
|
-
const cmmdBillingSeriesRouteLayer = registerProxyRoute({
|
|
300797
|
+
registerProxyRoute({
|
|
300553
300798
|
forgePath: "/api/cmmd/billing/series",
|
|
300554
300799
|
method: "GET",
|
|
300555
300800
|
cmmdPath: "/api/forge/context/billing/series",
|
|
@@ -300587,6 +300832,15 @@ function runCmmdRestProxy(session, proxy, dependencies = {}) {
|
|
|
300587
300832
|
});
|
|
300588
300833
|
}
|
|
300589
300834
|
/**
|
|
300835
|
+
* Adapts `runCmmdRestProxy`'s `{ ok, value | error }` outcome into a
|
|
300836
|
+
* `ProxyHandlerRoute.run` result: the shared shape every converted handler's
|
|
300837
|
+
* `run` uses so it stays the three or so lines of the actual gateway call
|
|
300838
|
+
* plus response shaping, with resolve-and-retry left to `runCmmdRestProxy`.
|
|
300839
|
+
*/
|
|
300840
|
+
function runCmmdRestProxyAsHandlerResult(session, proxy, shape) {
|
|
300841
|
+
return runCmmdRestProxy(session, proxy).pipe(flatMap((outcome) => outcome.ok ? succeed(shape(outcome.value)) : fail(outcome.error)));
|
|
300842
|
+
}
|
|
300843
|
+
/**
|
|
300590
300844
|
* Forge-context REST responses wrap their payload in `{ data, meta, pagination? }`
|
|
300591
300845
|
* (see CMMD `sendForgeEnvelope`). Unwrap to the bare payload so handler response
|
|
300592
300846
|
* shapes match what the web client expected from the prior MCP text path.
|
|
@@ -300750,22 +301004,34 @@ function buildCreateBrainDocumentInput(payload) {
|
|
|
300750
301004
|
...payload.tags && payload.tags.length > 0 ? { tags: payload.tags } : {}
|
|
300751
301005
|
};
|
|
300752
301006
|
}
|
|
300753
|
-
|
|
300754
|
-
|
|
300755
|
-
|
|
300756
|
-
|
|
300757
|
-
|
|
300758
|
-
|
|
300759
|
-
|
|
301007
|
+
function parseCreateBrainDocRequest(request) {
|
|
301008
|
+
return request.json.pipe(orElseSucceed(() => null), map$3((rawBody) => {
|
|
301009
|
+
const payload = parseBrainDocPayload(rawBody);
|
|
301010
|
+
return payload ? {
|
|
301011
|
+
ok: true,
|
|
301012
|
+
value: payload
|
|
301013
|
+
} : {
|
|
301014
|
+
ok: false,
|
|
301015
|
+
status: 400,
|
|
301016
|
+
body: { error: "Invalid request: title (1-500 chars) and content (1-100k chars) are required." }
|
|
301017
|
+
};
|
|
301018
|
+
}));
|
|
301019
|
+
}
|
|
301020
|
+
registerProxyHandler({
|
|
301021
|
+
forgePath: "/api/cmmd/brain-docs",
|
|
301022
|
+
method: "POST",
|
|
301023
|
+
parse: parseCreateBrainDocRequest,
|
|
301024
|
+
run: (payload, { session }) => runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.createBrainDocument({
|
|
300760
301025
|
jwt,
|
|
300761
301026
|
document: buildCreateBrainDocumentInput(payload)
|
|
300762
|
-
}))
|
|
300763
|
-
|
|
300764
|
-
|
|
300765
|
-
|
|
300766
|
-
|
|
300767
|
-
|
|
300768
|
-
})
|
|
301027
|
+
}), (value) => ({
|
|
301028
|
+
status: 201,
|
|
301029
|
+
body: {
|
|
301030
|
+
success: true,
|
|
301031
|
+
doc: unwrapForgeEnvelope(value)
|
|
301032
|
+
}
|
|
301033
|
+
}))
|
|
301034
|
+
});
|
|
300769
301035
|
function normalizeOptionalNullableString(value, options) {
|
|
300770
301036
|
if (value === void 0) return void 0;
|
|
300771
301037
|
if (value === null) return null;
|
|
@@ -300819,46 +301085,77 @@ function buildUpdateTaskToolInput(payload) {
|
|
|
300819
301085
|
...payload.labels !== void 0 ? { tags: payload.labels } : {}
|
|
300820
301086
|
};
|
|
300821
301087
|
}
|
|
300822
|
-
|
|
300823
|
-
|
|
300824
|
-
|
|
300825
|
-
|
|
300826
|
-
|
|
300827
|
-
|
|
301088
|
+
function parseUpdateCmmdTaskRequest(request) {
|
|
301089
|
+
return request.json.pipe(orElseSucceed(() => null), map$3((rawBody) => {
|
|
301090
|
+
const payload = parseUpdateTaskPayload(rawBody);
|
|
301091
|
+
return payload ? {
|
|
301092
|
+
ok: true,
|
|
301093
|
+
value: payload
|
|
301094
|
+
} : {
|
|
301095
|
+
ok: false,
|
|
301096
|
+
status: 400,
|
|
301097
|
+
body: { error: "Invalid request: taskId is required and at least one update field must be provided." }
|
|
301098
|
+
};
|
|
301099
|
+
}));
|
|
301100
|
+
}
|
|
301101
|
+
function runUpdateCmmdTask(payload, { session }) {
|
|
300828
301102
|
const { taskId, ...patch } = buildUpdateTaskToolInput(payload);
|
|
300829
|
-
|
|
301103
|
+
return runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.updateTask({
|
|
300830
301104
|
jwt,
|
|
300831
301105
|
taskId: String(taskId),
|
|
300832
301106
|
patch
|
|
300833
|
-
}))
|
|
300834
|
-
if (restOutcome.ok) {
|
|
301107
|
+
}), (value) => {
|
|
300835
301108
|
invalidateCachedCmmdWorkIntakeForSession(session.sessionId);
|
|
300836
|
-
return
|
|
300837
|
-
|
|
300838
|
-
|
|
300839
|
-
|
|
300840
|
-
|
|
300841
|
-
|
|
300842
|
-
}
|
|
300843
|
-
|
|
300844
|
-
|
|
300845
|
-
|
|
300846
|
-
|
|
300847
|
-
|
|
300848
|
-
|
|
300849
|
-
|
|
300850
|
-
|
|
300851
|
-
|
|
301109
|
+
return {
|
|
301110
|
+
status: 200,
|
|
301111
|
+
body: {
|
|
301112
|
+
success: true,
|
|
301113
|
+
details: unwrapForgeEnvelope(value)
|
|
301114
|
+
}
|
|
301115
|
+
};
|
|
301116
|
+
});
|
|
301117
|
+
}
|
|
301118
|
+
registerProxyHandler({
|
|
301119
|
+
forgePath: "/api/cmmd/tasks/update",
|
|
301120
|
+
method: "POST",
|
|
301121
|
+
parse: parseUpdateCmmdTaskRequest,
|
|
301122
|
+
run: runUpdateCmmdTask
|
|
301123
|
+
});
|
|
301124
|
+
registerProxyHandler({
|
|
301125
|
+
forgePath: "/api/command/tasks/update",
|
|
301126
|
+
method: "POST",
|
|
301127
|
+
parse: parseUpdateCmmdTaskRequest,
|
|
301128
|
+
run: runUpdateCmmdTask
|
|
301129
|
+
});
|
|
301130
|
+
function parseAddCmmdTaskCommentRequest(request) {
|
|
301131
|
+
return request.json.pipe(orElseSucceed(() => null), map$3((rawBody) => {
|
|
301132
|
+
const payload = parseTaskCommentPayload(rawBody);
|
|
301133
|
+
return payload ? {
|
|
301134
|
+
ok: true,
|
|
301135
|
+
value: payload
|
|
301136
|
+
} : {
|
|
301137
|
+
ok: false,
|
|
301138
|
+
status: 400,
|
|
301139
|
+
body: { error: "taskId and content (max 2000 chars) are required." }
|
|
301140
|
+
};
|
|
301141
|
+
}));
|
|
301142
|
+
}
|
|
301143
|
+
registerProxyHandler({
|
|
301144
|
+
forgePath: "/api/cmmd/tasks/comment",
|
|
301145
|
+
method: "POST",
|
|
301146
|
+
parse: parseAddCmmdTaskCommentRequest,
|
|
301147
|
+
run: (payload, { session }) => runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.addTaskComment({
|
|
300852
301148
|
jwt,
|
|
300853
301149
|
taskId: payload.taskId,
|
|
300854
301150
|
content: payload.content
|
|
300855
|
-
}))
|
|
300856
|
-
|
|
300857
|
-
|
|
300858
|
-
|
|
300859
|
-
|
|
300860
|
-
|
|
300861
|
-
})
|
|
301151
|
+
}), (value) => ({
|
|
301152
|
+
status: 201,
|
|
301153
|
+
body: {
|
|
301154
|
+
success: true,
|
|
301155
|
+
details: unwrapForgeEnvelope(value)
|
|
301156
|
+
}
|
|
301157
|
+
}))
|
|
301158
|
+
});
|
|
300862
301159
|
function parseTaskCommentPayload(body) {
|
|
300863
301160
|
if (typeof body !== "object" || body === null) return null;
|
|
300864
301161
|
const b = body;
|
|
@@ -300887,23 +301184,38 @@ function normalizeTaskSearchParams(url) {
|
|
|
300887
301184
|
limit: Math.min(Number(url.searchParams.get("limit") ?? "20"), 50)
|
|
300888
301185
|
};
|
|
300889
301186
|
}
|
|
300890
|
-
|
|
300891
|
-
|
|
300892
|
-
|
|
300893
|
-
|
|
300894
|
-
|
|
300895
|
-
|
|
300896
|
-
|
|
300897
|
-
|
|
300898
|
-
|
|
300899
|
-
|
|
301187
|
+
function parseSearchCmmdTasksRequest(request) {
|
|
301188
|
+
return sync$1(() => ({
|
|
301189
|
+
ok: true,
|
|
301190
|
+
value: normalizeTaskSearchParams(new URL(request.url, "http://localhost"))
|
|
301191
|
+
}));
|
|
301192
|
+
}
|
|
301193
|
+
function runSearchCmmdTasks(search, { session }) {
|
|
301194
|
+
if (!search) return succeed({
|
|
301195
|
+
status: 200,
|
|
301196
|
+
body: {
|
|
301197
|
+
tasks: [],
|
|
301198
|
+
total: 0
|
|
301199
|
+
}
|
|
301200
|
+
});
|
|
301201
|
+
const accessToken = readCommandAccessTokenForSession(session.sessionId) ?? "";
|
|
301202
|
+
return promise(() => callCmmdTool(accessToken, "search_tasks", {
|
|
300900
301203
|
query: search.query,
|
|
300901
301204
|
limit: search.limit
|
|
300902
|
-
})))
|
|
300903
|
-
|
|
300904
|
-
|
|
300905
|
-
|
|
300906
|
-
|
|
301205
|
+
})).pipe(map$3((result) => ({
|
|
301206
|
+
status: 200,
|
|
301207
|
+
body: parseJsonObjectText(extractMcpToolText(result)) ?? {
|
|
301208
|
+
tasks: [],
|
|
301209
|
+
total: 0
|
|
301210
|
+
}
|
|
301211
|
+
})));
|
|
301212
|
+
}
|
|
301213
|
+
registerProxyHandler({
|
|
301214
|
+
forgePath: "/api/cmmd/tasks/search",
|
|
301215
|
+
method: "GET",
|
|
301216
|
+
parse: parseSearchCmmdTasksRequest,
|
|
301217
|
+
run: runSearchCmmdTasks
|
|
301218
|
+
});
|
|
300907
301219
|
function parseJsonObjectText(text) {
|
|
300908
301220
|
if (!text) return null;
|
|
300909
301221
|
try {
|
|
@@ -300917,23 +301229,47 @@ function parsePositiveIntegerId(value) {
|
|
|
300917
301229
|
const numericId = Number(value);
|
|
300918
301230
|
return Number.isInteger(numericId) && numericId > 0 ? numericId : null;
|
|
300919
301231
|
}
|
|
300920
|
-
|
|
300921
|
-
|
|
300922
|
-
|
|
300923
|
-
|
|
300924
|
-
|
|
300925
|
-
|
|
300926
|
-
|
|
300927
|
-
|
|
300928
|
-
|
|
301232
|
+
function parseGetCmmdTaskRequest(request) {
|
|
301233
|
+
return sync$1(() => {
|
|
301234
|
+
const taskId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 1);
|
|
301235
|
+
if (!taskId) return {
|
|
301236
|
+
ok: false,
|
|
301237
|
+
status: 400,
|
|
301238
|
+
body: { error: "Task ID is required." }
|
|
301239
|
+
};
|
|
301240
|
+
const numericId = parsePositiveIntegerId(taskId);
|
|
301241
|
+
if (!numericId) return {
|
|
301242
|
+
ok: false,
|
|
301243
|
+
status: 400,
|
|
301244
|
+
body: { error: "Invalid task ID." }
|
|
301245
|
+
};
|
|
301246
|
+
return {
|
|
301247
|
+
ok: true,
|
|
301248
|
+
value: numericId
|
|
301249
|
+
};
|
|
301250
|
+
});
|
|
301251
|
+
}
|
|
301252
|
+
function runGetCmmdTask(numericId, { session }) {
|
|
301253
|
+
return runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.getTask({
|
|
300929
301254
|
jwt,
|
|
300930
301255
|
taskId: String(numericId)
|
|
300931
|
-
}))
|
|
300932
|
-
|
|
300933
|
-
|
|
300934
|
-
|
|
300935
|
-
|
|
300936
|
-
}
|
|
301256
|
+
}), (value) => {
|
|
301257
|
+
const task = unwrapForgeEnvelope(value);
|
|
301258
|
+
return task === null || task === void 0 ? {
|
|
301259
|
+
status: 404,
|
|
301260
|
+
body: { error: "Task not found." }
|
|
301261
|
+
} : {
|
|
301262
|
+
status: 200,
|
|
301263
|
+
body: task
|
|
301264
|
+
};
|
|
301265
|
+
});
|
|
301266
|
+
}
|
|
301267
|
+
registerProxyHandler({
|
|
301268
|
+
forgePath: "/api/cmmd/tasks/:id",
|
|
301269
|
+
method: "GET",
|
|
301270
|
+
parse: parseGetCmmdTaskRequest,
|
|
301271
|
+
run: runGetCmmdTask
|
|
301272
|
+
});
|
|
300937
301273
|
function extractIdFromPath(pathname, fromEnd) {
|
|
300938
301274
|
const parts = pathname.split("/").filter(Boolean);
|
|
300939
301275
|
return parts[parts.length - fromEnd];
|
|
@@ -300945,22 +301281,37 @@ function decodePathSegment(segment) {
|
|
|
300945
301281
|
return null;
|
|
300946
301282
|
}
|
|
300947
301283
|
}
|
|
300948
|
-
|
|
300949
|
-
|
|
300950
|
-
|
|
300951
|
-
|
|
300952
|
-
|
|
300953
|
-
|
|
300954
|
-
|
|
301284
|
+
function parseGetCmmdTaskCommentsRequest(request) {
|
|
301285
|
+
return sync$1(() => {
|
|
301286
|
+
const taskId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
|
|
301287
|
+
return taskId ? {
|
|
301288
|
+
ok: true,
|
|
301289
|
+
value: taskId
|
|
301290
|
+
} : {
|
|
301291
|
+
ok: false,
|
|
301292
|
+
status: 400,
|
|
301293
|
+
body: { error: "Task ID is required." }
|
|
301294
|
+
};
|
|
301295
|
+
});
|
|
301296
|
+
}
|
|
301297
|
+
function runGetCmmdTaskComments(taskId, { session }) {
|
|
301298
|
+
return runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.listTaskComments({
|
|
300955
301299
|
jwt,
|
|
300956
301300
|
taskId
|
|
300957
|
-
}))
|
|
300958
|
-
|
|
300959
|
-
|
|
300960
|
-
|
|
300961
|
-
|
|
300962
|
-
|
|
300963
|
-
})
|
|
301301
|
+
}), (value) => {
|
|
301302
|
+
const data = unwrapForgeEnvelope(value);
|
|
301303
|
+
return {
|
|
301304
|
+
status: 200,
|
|
301305
|
+
body: { comments: Array.isArray(data) ? data : [] }
|
|
301306
|
+
};
|
|
301307
|
+
});
|
|
301308
|
+
}
|
|
301309
|
+
registerProxyHandler({
|
|
301310
|
+
forgePath: "/api/cmmd/tasks/:id/comments",
|
|
301311
|
+
method: "GET",
|
|
301312
|
+
parse: parseGetCmmdTaskCommentsRequest,
|
|
301313
|
+
run: runGetCmmdTaskComments
|
|
301314
|
+
});
|
|
300964
301315
|
function normalizeCommentList(value) {
|
|
300965
301316
|
if (Array.isArray(value)) return value;
|
|
300966
301317
|
if (!value || typeof value !== "object") return [];
|
|
@@ -301066,55 +301417,54 @@ const cmmdUpdateProjectRouteLayer = add$1("PATCH", "/api/cmmd/projects/:id", gen
|
|
|
301066
301417
|
project: outcome.value
|
|
301067
301418
|
}, { status: 200 });
|
|
301068
301419
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
|
|
301069
|
-
|
|
301420
|
+
registerProxyRoute({
|
|
301070
301421
|
forgePath: "/api/cmmd/projects/:id/repository",
|
|
301071
301422
|
method: "GET",
|
|
301072
301423
|
cmmdPath: "/api/forge/context/projects/:id/repository",
|
|
301073
301424
|
orgIdSource: "none",
|
|
301074
301425
|
responseShape: "unwrapData"
|
|
301075
301426
|
});
|
|
301076
|
-
|
|
301077
|
-
const cmmdListProjectRepositoriesRouteLayer = registerProxyRoute({
|
|
301427
|
+
registerProxyRoute({
|
|
301078
301428
|
forgePath: "/api/cmmd/projects/:projectId/repositories",
|
|
301079
301429
|
method: "GET",
|
|
301080
301430
|
cmmdPath: "/api/forge/context/projects/:projectId/repositories",
|
|
301081
301431
|
orgIdSource: "none",
|
|
301082
301432
|
responseShape: "unwrapData"
|
|
301083
301433
|
});
|
|
301084
|
-
|
|
301434
|
+
registerProxyRoute({
|
|
301085
301435
|
forgePath: "/api/cmmd/organizations/:id/members",
|
|
301086
301436
|
method: "GET",
|
|
301087
301437
|
cmmdPath: "/api/organizations/:id/members",
|
|
301088
301438
|
orgIdSource: "none",
|
|
301089
301439
|
responseShape: "unwrapData"
|
|
301090
301440
|
});
|
|
301091
|
-
|
|
301441
|
+
registerProxyRoute({
|
|
301092
301442
|
forgePath: "/api/cmmd/sim-host/hosts",
|
|
301093
301443
|
method: "GET",
|
|
301094
301444
|
cmmdPath: "/api/forge/context/sim-host/hosts",
|
|
301095
301445
|
responseShape: "unwrapData"
|
|
301096
301446
|
});
|
|
301097
|
-
|
|
301447
|
+
registerProxyRoute({
|
|
301098
301448
|
forgePath: "/api/cmmd/sim-host/leases",
|
|
301099
301449
|
method: "GET",
|
|
301100
301450
|
cmmdPath: "/api/forge/context/sim-host/leases",
|
|
301101
301451
|
responseShape: "unwrapData"
|
|
301102
301452
|
});
|
|
301103
|
-
|
|
301453
|
+
registerProxyRoute({
|
|
301104
301454
|
forgePath: "/api/cmmd/sim-host/leases",
|
|
301105
301455
|
method: "POST",
|
|
301106
301456
|
cmmdPath: "/api/forge/context/sim-host/leases",
|
|
301107
301457
|
responseShape: "unwrapData",
|
|
301108
301458
|
successStatus: 200
|
|
301109
301459
|
});
|
|
301110
|
-
|
|
301460
|
+
registerProxyRoute({
|
|
301111
301461
|
forgePath: "/api/cmmd/sim-host/leases/:leaseId/release",
|
|
301112
301462
|
method: "POST",
|
|
301113
301463
|
cmmdPath: "/api/forge/context/sim-host/leases/:leaseId/release",
|
|
301114
301464
|
responseShape: "unwrapData",
|
|
301115
301465
|
successStatus: 200
|
|
301116
301466
|
});
|
|
301117
|
-
|
|
301467
|
+
registerProxyRoute({
|
|
301118
301468
|
forgePath: "/api/cmmd/sim-host/leases/:leaseId/renew",
|
|
301119
301469
|
method: "POST",
|
|
301120
301470
|
cmmdPath: "/api/forge/context/sim-host/leases/:leaseId/renew",
|
|
@@ -301138,7 +301488,7 @@ function getMultipartContentType(headers) {
|
|
|
301138
301488
|
const contentType = headers["content-type"] ?? "";
|
|
301139
301489
|
return contentType.includes("multipart/form-data") ? contentType : null;
|
|
301140
301490
|
}
|
|
301141
|
-
|
|
301491
|
+
registerProxyRoute({
|
|
301142
301492
|
forgePath: "/api/cmmd/tasks/:id/attachments",
|
|
301143
301493
|
method: "GET",
|
|
301144
301494
|
cmmdPath: "/api/forge/context/tasks/:id/attachments",
|
|
@@ -301173,150 +301523,150 @@ const cmmdUpdateTaskCommentRouteLayer = add$1("PATCH", "/api/cmmd/tasks/:taskId/
|
|
|
301173
301523
|
...outcome.value
|
|
301174
301524
|
}, { status: 200 });
|
|
301175
301525
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
|
|
301176
|
-
|
|
301526
|
+
registerProxyRoute({
|
|
301177
301527
|
forgePath: "/api/cmmd/tasks/:taskId/comments/:commentId",
|
|
301178
301528
|
method: "DELETE",
|
|
301179
301529
|
cmmdPath: "/api/forge/context/tasks/:taskId/comments/:commentId",
|
|
301180
301530
|
orgIdSource: "none",
|
|
301181
301531
|
requestBody: "json"
|
|
301182
301532
|
});
|
|
301183
|
-
|
|
301533
|
+
registerProxyRoute({
|
|
301184
301534
|
forgePath: "/api/cmmd/projects/:projectId/agent-members",
|
|
301185
301535
|
method: "GET",
|
|
301186
301536
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members",
|
|
301187
301537
|
orgIdSource: "none",
|
|
301188
301538
|
responseShape: "unwrapData"
|
|
301189
301539
|
});
|
|
301190
|
-
|
|
301540
|
+
registerProxyRoute({
|
|
301191
301541
|
forgePath: "/api/cmmd/projects/:projectId/agent-members",
|
|
301192
301542
|
method: "POST",
|
|
301193
301543
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members",
|
|
301194
301544
|
orgIdSource: "none",
|
|
301195
301545
|
responseShape: "unwrapData"
|
|
301196
301546
|
});
|
|
301197
|
-
|
|
301547
|
+
registerProxyRoute({
|
|
301198
301548
|
forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId",
|
|
301199
301549
|
method: "GET",
|
|
301200
301550
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId",
|
|
301201
301551
|
orgIdSource: "none",
|
|
301202
301552
|
responseShape: "unwrapData"
|
|
301203
301553
|
});
|
|
301204
|
-
|
|
301554
|
+
registerProxyRoute({
|
|
301205
301555
|
forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId",
|
|
301206
301556
|
method: "PATCH",
|
|
301207
301557
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId",
|
|
301208
301558
|
orgIdSource: "none",
|
|
301209
301559
|
responseShape: "unwrapData"
|
|
301210
301560
|
});
|
|
301211
|
-
|
|
301561
|
+
registerProxyRoute({
|
|
301212
301562
|
forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId/retire",
|
|
301213
301563
|
method: "POST",
|
|
301214
301564
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId/retire",
|
|
301215
301565
|
orgIdSource: "none",
|
|
301216
301566
|
responseShape: "unwrapData"
|
|
301217
301567
|
});
|
|
301218
|
-
|
|
301568
|
+
registerProxyRoute({
|
|
301219
301569
|
forgePath: "/api/cmmd/projects/:projectId/agent-members/:memberId/instances",
|
|
301220
301570
|
method: "GET",
|
|
301221
301571
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members/:memberId/instances",
|
|
301222
301572
|
orgIdSource: "none",
|
|
301223
301573
|
responseShape: "unwrapData"
|
|
301224
301574
|
});
|
|
301225
|
-
|
|
301575
|
+
registerProxyRoute({
|
|
301226
301576
|
forgePath: "/api/cmmd/projects/:projectId/agent-members/consolidation/preview",
|
|
301227
301577
|
method: "POST",
|
|
301228
301578
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members/consolidation/preview",
|
|
301229
301579
|
orgIdSource: "none",
|
|
301230
301580
|
responseShape: "unwrapData"
|
|
301231
301581
|
});
|
|
301232
|
-
|
|
301582
|
+
registerProxyRoute({
|
|
301233
301583
|
forgePath: "/api/cmmd/projects/:projectId/agent-members/consolidation/apply",
|
|
301234
301584
|
method: "POST",
|
|
301235
301585
|
cmmdPath: "/api/forge/context/projects/:projectId/agent-members/consolidation/apply",
|
|
301236
301586
|
orgIdSource: "none",
|
|
301237
301587
|
responseShape: "unwrapData"
|
|
301238
301588
|
});
|
|
301239
|
-
|
|
301589
|
+
registerProxyRoute({
|
|
301240
301590
|
forgePath: "/api/cmmd/projects/:projectId/tasks/:taskId/assignment",
|
|
301241
301591
|
method: "PUT",
|
|
301242
301592
|
cmmdPath: "/api/forge/context/projects/:projectId/tasks/:taskId/assignment",
|
|
301243
301593
|
orgIdSource: "none",
|
|
301244
301594
|
responseShape: "unwrapData"
|
|
301245
301595
|
});
|
|
301246
|
-
|
|
301596
|
+
registerProxyRoute({
|
|
301247
301597
|
forgePath: "/api/cmmd/tasks",
|
|
301248
301598
|
method: "GET",
|
|
301249
301599
|
cmmdPath: "/api/forge/context/tasks"
|
|
301250
301600
|
});
|
|
301251
|
-
|
|
301601
|
+
registerProxyRoute({
|
|
301252
301602
|
forgePath: "/api/cmmd/tasks",
|
|
301253
301603
|
method: "POST",
|
|
301254
301604
|
cmmdPath: "/api/forge/context/tasks"
|
|
301255
301605
|
});
|
|
301256
|
-
|
|
301606
|
+
registerProxyRoute({
|
|
301257
301607
|
forgePath: "/api/cmmd/tasks/:id/archive",
|
|
301258
301608
|
method: "POST",
|
|
301259
301609
|
cmmdPath: "/api/forge/context/tasks/:id/archive",
|
|
301260
301610
|
orgIdSource: "none"
|
|
301261
301611
|
});
|
|
301262
|
-
|
|
301612
|
+
registerProxyRoute({
|
|
301263
301613
|
forgePath: "/api/cmmd/tasks/:id/unarchive",
|
|
301264
301614
|
method: "POST",
|
|
301265
301615
|
cmmdPath: "/api/forge/context/tasks/:id/unarchive",
|
|
301266
301616
|
orgIdSource: "none"
|
|
301267
301617
|
});
|
|
301268
|
-
|
|
301618
|
+
registerProxyRoute({
|
|
301269
301619
|
forgePath: "/api/cmmd/saved-views",
|
|
301270
301620
|
method: "GET",
|
|
301271
301621
|
cmmdPath: "/api/forge/context/saved-views",
|
|
301272
301622
|
orgIdSource: "none"
|
|
301273
301623
|
});
|
|
301274
|
-
|
|
301624
|
+
registerProxyRoute({
|
|
301275
301625
|
forgePath: "/api/cmmd/saved-views",
|
|
301276
301626
|
method: "POST",
|
|
301277
301627
|
cmmdPath: "/api/forge/context/saved-views",
|
|
301278
301628
|
orgIdSource: "none",
|
|
301279
301629
|
successStatus: 201
|
|
301280
301630
|
});
|
|
301281
|
-
|
|
301631
|
+
registerProxyRoute({
|
|
301282
301632
|
forgePath: "/api/cmmd/saved-views/import",
|
|
301283
301633
|
method: "POST",
|
|
301284
301634
|
cmmdPath: "/api/forge/context/saved-views/import",
|
|
301285
301635
|
orgIdSource: "none"
|
|
301286
301636
|
});
|
|
301287
|
-
|
|
301637
|
+
registerProxyRoute({
|
|
301288
301638
|
forgePath: "/api/cmmd/saved-views/:viewId",
|
|
301289
301639
|
method: "PATCH",
|
|
301290
301640
|
cmmdPath: "/api/forge/context/saved-views/:viewId",
|
|
301291
301641
|
orgIdSource: "none"
|
|
301292
301642
|
});
|
|
301293
|
-
|
|
301643
|
+
registerProxyRoute({
|
|
301294
301644
|
forgePath: "/api/cmmd/saved-views/:viewId",
|
|
301295
301645
|
method: "DELETE",
|
|
301296
301646
|
cmmdPath: "/api/forge/context/saved-views/:viewId",
|
|
301297
301647
|
orgIdSource: "none",
|
|
301298
301648
|
forwardSearchParams: true
|
|
301299
301649
|
});
|
|
301300
|
-
|
|
301650
|
+
registerProxyRoute({
|
|
301301
301651
|
forgePath: "/api/cmmd/projects",
|
|
301302
301652
|
method: "GET",
|
|
301303
301653
|
cmmdPath: "/api/forge/context/projects",
|
|
301304
301654
|
responseShape: "passthrough"
|
|
301305
301655
|
});
|
|
301306
|
-
|
|
301656
|
+
registerProxyRoute({
|
|
301307
301657
|
forgePath: "/api/cmmd/projects/:id",
|
|
301308
301658
|
method: "GET",
|
|
301309
301659
|
cmmdPath: "/api/forge/context/projects/:id",
|
|
301310
301660
|
orgIdSource: "none",
|
|
301311
301661
|
responseShape: "passthrough"
|
|
301312
301662
|
});
|
|
301313
|
-
|
|
301663
|
+
registerProxyRoute({
|
|
301314
301664
|
forgePath: "/api/cmmd/projects",
|
|
301315
301665
|
method: "POST",
|
|
301316
301666
|
cmmdPath: "/api/projects",
|
|
301317
301667
|
responseShape: "passthrough"
|
|
301318
301668
|
});
|
|
301319
|
-
|
|
301669
|
+
registerProxyRoute({
|
|
301320
301670
|
forgePath: "/api/cmmd/projects/:id",
|
|
301321
301671
|
method: "DELETE",
|
|
301322
301672
|
cmmdPath: "/api/forge/context/projects/:id",
|
|
@@ -301324,78 +301674,78 @@ const cmmdDeleteProjectRouteLayer = registerProxyRoute({
|
|
|
301324
301674
|
fixedSearchParams: { soft: "false" },
|
|
301325
301675
|
workIntakeInvalidation: "always"
|
|
301326
301676
|
});
|
|
301327
|
-
|
|
301677
|
+
registerProxyRoute({
|
|
301328
301678
|
forgePath: "/api/cmmd/projects/:id/move",
|
|
301329
301679
|
method: "POST",
|
|
301330
301680
|
cmmdPath: "/api/forge/context/projects/:id/move",
|
|
301331
301681
|
orgIdSource: "none",
|
|
301332
301682
|
responseShape: "unwrapData"
|
|
301333
301683
|
});
|
|
301334
|
-
|
|
301684
|
+
registerProxyRoute({
|
|
301335
301685
|
forgePath: "/api/cmmd/projects/:id/members",
|
|
301336
301686
|
method: "GET",
|
|
301337
301687
|
cmmdPath: "/api/forge/context/projects/:id/team"
|
|
301338
301688
|
});
|
|
301339
|
-
|
|
301689
|
+
registerProxyRoute({
|
|
301340
301690
|
forgePath: "/api/cmmd/projects/:id/milestones",
|
|
301341
301691
|
method: "GET",
|
|
301342
301692
|
cmmdPath: "/api/forge/context/projects/:id/milestones"
|
|
301343
301693
|
});
|
|
301344
|
-
|
|
301694
|
+
registerProxyRoute({
|
|
301345
301695
|
forgePath: "/api/cmmd/projects/:id/milestones",
|
|
301346
301696
|
method: "POST",
|
|
301347
301697
|
cmmdPath: "/api/forge/context/projects/:id/milestones",
|
|
301348
301698
|
orgIdSource: "none",
|
|
301349
301699
|
responseShape: "unwrapData"
|
|
301350
301700
|
});
|
|
301351
|
-
|
|
301701
|
+
registerProxyRoute({
|
|
301352
301702
|
forgePath: "/api/cmmd/projects/:id/milestones/:milestoneId",
|
|
301353
301703
|
method: "PATCH",
|
|
301354
301704
|
cmmdPath: "/api/forge/context/projects/:id/milestones/:milestoneId",
|
|
301355
301705
|
orgIdSource: "none",
|
|
301356
301706
|
responseShape: "unwrapData"
|
|
301357
301707
|
});
|
|
301358
|
-
|
|
301708
|
+
registerProxyRoute({
|
|
301359
301709
|
forgePath: "/api/cmmd/projects/:id/milestones/:milestoneId",
|
|
301360
301710
|
method: "DELETE",
|
|
301361
301711
|
cmmdPath: "/api/forge/context/projects/:id/milestones/:milestoneId",
|
|
301362
301712
|
orgIdSource: "none"
|
|
301363
301713
|
});
|
|
301364
|
-
|
|
301714
|
+
registerProxyRoute({
|
|
301365
301715
|
forgePath: "/api/cmmd/projects/:id/updates",
|
|
301366
301716
|
method: "GET",
|
|
301367
301717
|
cmmdPath: "/api/forge/context/projects/:id/updates",
|
|
301368
301718
|
orgIdSource: "none",
|
|
301369
301719
|
responseShape: "passthrough"
|
|
301370
301720
|
});
|
|
301371
|
-
|
|
301721
|
+
registerProxyRoute({
|
|
301372
301722
|
forgePath: "/api/cmmd/projects/:id/updates",
|
|
301373
301723
|
method: "POST",
|
|
301374
301724
|
cmmdPath: "/api/forge/context/projects/:id/updates",
|
|
301375
301725
|
orgIdSource: "none",
|
|
301376
301726
|
responseShape: "unwrapData"
|
|
301377
301727
|
});
|
|
301378
|
-
|
|
301728
|
+
registerProxyRoute({
|
|
301379
301729
|
forgePath: "/api/cmmd/projects/:id/updates/:updateId",
|
|
301380
301730
|
method: "PATCH",
|
|
301381
301731
|
cmmdPath: "/api/forge/context/projects/:id/updates/:updateId",
|
|
301382
301732
|
orgIdSource: "none",
|
|
301383
301733
|
responseShape: "unwrapData"
|
|
301384
301734
|
});
|
|
301385
|
-
|
|
301735
|
+
registerProxyRoute({
|
|
301386
301736
|
forgePath: "/api/cmmd/projects/:id/updates/:updateId",
|
|
301387
301737
|
method: "DELETE",
|
|
301388
301738
|
cmmdPath: "/api/forge/context/projects/:id/updates/:updateId",
|
|
301389
301739
|
orgIdSource: "none"
|
|
301390
301740
|
});
|
|
301391
|
-
|
|
301741
|
+
registerProxyRoute({
|
|
301392
301742
|
forgePath: "/api/cmmd/projects/:id/content/readability",
|
|
301393
301743
|
method: "POST",
|
|
301394
301744
|
cmmdPath: "/api/forge/context/projects/:id/content/readability",
|
|
301395
301745
|
orgIdSource: "none",
|
|
301396
301746
|
responseShape: "unwrapData"
|
|
301397
301747
|
});
|
|
301398
|
-
|
|
301748
|
+
registerProxyRoute({
|
|
301399
301749
|
forgePath: "/api/cmmd/projects/:projectId/task-drafts",
|
|
301400
301750
|
method: "POST",
|
|
301401
301751
|
cmmdPath: "/api/forge/context/projects/:projectId/task-drafts",
|
|
@@ -301403,7 +301753,7 @@ const cmmdCreateProjectTaskDraftRouteLayer = registerProxyRoute({
|
|
|
301403
301753
|
responseShape: "unwrapData",
|
|
301404
301754
|
successStatus: 201
|
|
301405
301755
|
});
|
|
301406
|
-
|
|
301756
|
+
registerProxyRoute({
|
|
301407
301757
|
forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId",
|
|
301408
301758
|
method: "GET",
|
|
301409
301759
|
cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId",
|
|
@@ -301411,7 +301761,7 @@ const cmmdGetProjectTaskDraftRouteLayer = registerProxyRoute({
|
|
|
301411
301761
|
responseShape: "unwrapData",
|
|
301412
301762
|
successStatus: 200
|
|
301413
301763
|
});
|
|
301414
|
-
|
|
301764
|
+
registerProxyRoute({
|
|
301415
301765
|
forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId",
|
|
301416
301766
|
method: "PATCH",
|
|
301417
301767
|
cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId",
|
|
@@ -301419,7 +301769,7 @@ const cmmdUpdateProjectTaskDraftRouteLayer = registerProxyRoute({
|
|
|
301419
301769
|
responseShape: "unwrapData",
|
|
301420
301770
|
successStatus: 200
|
|
301421
301771
|
});
|
|
301422
|
-
|
|
301772
|
+
registerProxyRoute({
|
|
301423
301773
|
forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId/preview",
|
|
301424
301774
|
method: "POST",
|
|
301425
301775
|
cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId/preview",
|
|
@@ -301427,7 +301777,7 @@ const cmmdPreviewProjectTaskDraftRouteLayer = registerProxyRoute({
|
|
|
301427
301777
|
responseShape: "unwrapData",
|
|
301428
301778
|
successStatus: 200
|
|
301429
301779
|
});
|
|
301430
|
-
|
|
301780
|
+
registerProxyRoute({
|
|
301431
301781
|
forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId/commit",
|
|
301432
301782
|
method: "POST",
|
|
301433
301783
|
cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId/commit",
|
|
@@ -301435,7 +301785,7 @@ const cmmdCommitProjectTaskDraftRouteLayer = registerProxyRoute({
|
|
|
301435
301785
|
responseShape: "unwrapData",
|
|
301436
301786
|
successStatus: 200
|
|
301437
301787
|
});
|
|
301438
|
-
|
|
301788
|
+
registerProxyRoute({
|
|
301439
301789
|
forgePath: "/api/cmmd/projects/:projectId/task-drafts/:draftId/discard",
|
|
301440
301790
|
method: "POST",
|
|
301441
301791
|
cmmdPath: "/api/forge/context/projects/:projectId/task-drafts/:draftId/discard",
|
|
@@ -301443,352 +301793,352 @@ const cmmdDiscardProjectTaskDraftRouteLayer = registerProxyRoute({
|
|
|
301443
301793
|
responseShape: "unwrapData",
|
|
301444
301794
|
successStatus: 200
|
|
301445
301795
|
});
|
|
301446
|
-
|
|
301796
|
+
registerProxyRoute({
|
|
301447
301797
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/plan",
|
|
301448
301798
|
method: "GET",
|
|
301449
301799
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/plan",
|
|
301450
301800
|
orgIdSource: "none"
|
|
301451
301801
|
});
|
|
301452
|
-
|
|
301802
|
+
registerProxyRoute({
|
|
301453
301803
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/authority/activate",
|
|
301454
301804
|
method: "POST",
|
|
301455
301805
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/authority/activate",
|
|
301456
301806
|
orgIdSource: "none",
|
|
301457
301807
|
responseShape: "unwrapData"
|
|
301458
301808
|
});
|
|
301459
|
-
|
|
301809
|
+
registerProxyRoute({
|
|
301460
301810
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/readiness",
|
|
301461
301811
|
method: "GET",
|
|
301462
301812
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/readiness",
|
|
301463
301813
|
orgIdSource: "none"
|
|
301464
301814
|
});
|
|
301465
|
-
|
|
301815
|
+
registerProxyRoute({
|
|
301466
301816
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/capabilities",
|
|
301467
301817
|
method: "GET",
|
|
301468
301818
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/capabilities",
|
|
301469
301819
|
orgIdSource: "none"
|
|
301470
301820
|
});
|
|
301471
|
-
|
|
301821
|
+
registerProxyRoute({
|
|
301472
301822
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/summary",
|
|
301473
301823
|
method: "GET",
|
|
301474
301824
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/summary",
|
|
301475
301825
|
orgIdSource: "none"
|
|
301476
301826
|
});
|
|
301477
|
-
|
|
301827
|
+
registerProxyRoute({
|
|
301478
301828
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/detail",
|
|
301479
301829
|
method: "GET",
|
|
301480
301830
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/detail",
|
|
301481
301831
|
orgIdSource: "none"
|
|
301482
301832
|
});
|
|
301483
|
-
|
|
301833
|
+
registerProxyRoute({
|
|
301484
301834
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/briefing",
|
|
301485
301835
|
method: "GET",
|
|
301486
301836
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/briefing",
|
|
301487
301837
|
orgIdSource: "none"
|
|
301488
301838
|
});
|
|
301489
|
-
|
|
301839
|
+
registerProxyRoute({
|
|
301490
301840
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/events",
|
|
301491
301841
|
method: "GET",
|
|
301492
301842
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/events",
|
|
301493
301843
|
orgIdSource: "none"
|
|
301494
301844
|
});
|
|
301495
|
-
|
|
301845
|
+
registerProxyRoute({
|
|
301496
301846
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/explain",
|
|
301497
301847
|
method: "GET",
|
|
301498
301848
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/explain",
|
|
301499
301849
|
orgIdSource: "none"
|
|
301500
301850
|
});
|
|
301501
|
-
|
|
301851
|
+
registerProxyRoute({
|
|
301502
301852
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/pause",
|
|
301503
301853
|
method: "POST",
|
|
301504
301854
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/pause",
|
|
301505
301855
|
orgIdSource: "none"
|
|
301506
301856
|
});
|
|
301507
|
-
|
|
301857
|
+
registerProxyRoute({
|
|
301508
301858
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/resume",
|
|
301509
301859
|
method: "POST",
|
|
301510
301860
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/resume",
|
|
301511
301861
|
orgIdSource: "none"
|
|
301512
301862
|
});
|
|
301513
|
-
|
|
301863
|
+
registerProxyRoute({
|
|
301514
301864
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/tasks/:taskId/reservations",
|
|
301515
301865
|
method: "POST",
|
|
301516
301866
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/tasks/:taskId/reservations",
|
|
301517
301867
|
orgIdSource: "none"
|
|
301518
301868
|
});
|
|
301519
|
-
|
|
301869
|
+
registerProxyRoute({
|
|
301520
301870
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/reservations/:reservationId/release",
|
|
301521
301871
|
method: "POST",
|
|
301522
301872
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/reservations/:reservationId/release",
|
|
301523
301873
|
orgIdSource: "none"
|
|
301524
301874
|
});
|
|
301525
|
-
|
|
301875
|
+
registerProxyRoute({
|
|
301526
301876
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/reconcile",
|
|
301527
301877
|
method: "POST",
|
|
301528
301878
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/reconcile",
|
|
301529
301879
|
orgIdSource: "none"
|
|
301530
301880
|
});
|
|
301531
|
-
|
|
301881
|
+
registerProxyRoute({
|
|
301532
301882
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/attention/:attentionId/resolve",
|
|
301533
301883
|
method: "POST",
|
|
301534
301884
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/attention/:attentionId/resolve",
|
|
301535
301885
|
orgIdSource: "none"
|
|
301536
301886
|
});
|
|
301537
|
-
|
|
301887
|
+
registerProxyRoute({
|
|
301538
301888
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/claim",
|
|
301539
301889
|
method: "POST",
|
|
301540
301890
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/claim",
|
|
301541
301891
|
orgIdSource: "none"
|
|
301542
301892
|
});
|
|
301543
|
-
|
|
301893
|
+
registerProxyRoute({
|
|
301544
301894
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/claim/renew",
|
|
301545
301895
|
method: "POST",
|
|
301546
301896
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/claim/renew",
|
|
301547
301897
|
orgIdSource: "none"
|
|
301548
301898
|
});
|
|
301549
|
-
|
|
301899
|
+
registerProxyRoute({
|
|
301550
301900
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/claim/yield",
|
|
301551
301901
|
method: "POST",
|
|
301552
301902
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/claim/yield",
|
|
301553
301903
|
orgIdSource: "none"
|
|
301554
301904
|
});
|
|
301555
|
-
|
|
301905
|
+
registerProxyRoute({
|
|
301556
301906
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/events/:eventId/acknowledge",
|
|
301557
301907
|
method: "POST",
|
|
301558
301908
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/events/:eventId/acknowledge",
|
|
301559
301909
|
orgIdSource: "none"
|
|
301560
301910
|
});
|
|
301561
|
-
|
|
301911
|
+
registerProxyRoute({
|
|
301562
301912
|
forgePath: "/api/cmmd/projects/:projectId/project-lead/controller/decisions",
|
|
301563
301913
|
method: "POST",
|
|
301564
301914
|
cmmdPath: "/api/forge/context/projects/:projectId/project-lead/controller/decisions",
|
|
301565
301915
|
orgIdSource: "none"
|
|
301566
301916
|
});
|
|
301567
|
-
|
|
301917
|
+
registerProxyRoute({
|
|
301568
301918
|
forgePath: "/api/cmmd/automations/presets",
|
|
301569
301919
|
method: "GET",
|
|
301570
301920
|
cmmdPath: "/api/forge/context/automations/presets",
|
|
301571
301921
|
orgIdSource: "none",
|
|
301572
301922
|
responseShape: "unwrapData"
|
|
301573
301923
|
});
|
|
301574
|
-
|
|
301924
|
+
registerProxyRoute({
|
|
301575
301925
|
forgePath: "/api/cmmd/automations/user/rules",
|
|
301576
301926
|
method: "GET",
|
|
301577
301927
|
cmmdPath: "/api/forge/context/automations/user/rules",
|
|
301578
301928
|
orgIdSource: "none",
|
|
301579
301929
|
responseShape: "unwrapData"
|
|
301580
301930
|
});
|
|
301581
|
-
|
|
301931
|
+
registerProxyRoute({
|
|
301582
301932
|
forgePath: "/api/cmmd/automations/user/rules",
|
|
301583
301933
|
method: "POST",
|
|
301584
301934
|
cmmdPath: "/api/forge/context/automations/user/rules",
|
|
301585
301935
|
orgIdSource: "none",
|
|
301586
301936
|
responseShape: "unwrapData"
|
|
301587
301937
|
});
|
|
301588
|
-
|
|
301938
|
+
registerProxyRoute({
|
|
301589
301939
|
forgePath: "/api/cmmd/automations/user/rules/:ruleId",
|
|
301590
301940
|
method: "PATCH",
|
|
301591
301941
|
cmmdPath: "/api/forge/context/automations/user/rules/:ruleId",
|
|
301592
301942
|
orgIdSource: "none",
|
|
301593
301943
|
responseShape: "unwrapData"
|
|
301594
301944
|
});
|
|
301595
|
-
|
|
301945
|
+
registerProxyRoute({
|
|
301596
301946
|
forgePath: "/api/cmmd/automations/user/rules/:ruleId/runs",
|
|
301597
301947
|
method: "GET",
|
|
301598
301948
|
cmmdPath: "/api/forge/context/automations/user/rules/:ruleId/runs",
|
|
301599
301949
|
orgIdSource: "none",
|
|
301600
301950
|
responseShape: "unwrapData"
|
|
301601
301951
|
});
|
|
301602
|
-
|
|
301952
|
+
registerProxyRoute({
|
|
301603
301953
|
forgePath: "/api/cmmd/automations/user/rules/:ruleId/runs",
|
|
301604
301954
|
method: "POST",
|
|
301605
301955
|
cmmdPath: "/api/forge/context/automations/user/rules/:ruleId/runs",
|
|
301606
301956
|
orgIdSource: "none",
|
|
301607
301957
|
responseShape: "unwrapData"
|
|
301608
301958
|
});
|
|
301609
|
-
|
|
301959
|
+
registerProxyRoute({
|
|
301610
301960
|
forgePath: "/api/cmmd/automations/projects/:projectId/rules",
|
|
301611
301961
|
method: "GET",
|
|
301612
301962
|
cmmdPath: "/api/forge/context/automations/projects/:projectId/rules",
|
|
301613
301963
|
orgIdSource: "query",
|
|
301614
301964
|
responseShape: "unwrapData"
|
|
301615
301965
|
});
|
|
301616
|
-
|
|
301966
|
+
registerProxyRoute({
|
|
301617
301967
|
forgePath: "/api/cmmd/automations/projects/:projectId/rules",
|
|
301618
301968
|
method: "POST",
|
|
301619
301969
|
cmmdPath: "/api/forge/context/automations/projects/:projectId/rules",
|
|
301620
301970
|
orgIdSource: "query",
|
|
301621
301971
|
responseShape: "unwrapData"
|
|
301622
301972
|
});
|
|
301623
|
-
|
|
301973
|
+
registerProxyRoute({
|
|
301624
301974
|
forgePath: "/api/cmmd/automations/projects/:projectId/rules/:ruleId",
|
|
301625
301975
|
method: "PATCH",
|
|
301626
301976
|
cmmdPath: "/api/forge/context/automations/projects/:projectId/rules/:ruleId",
|
|
301627
301977
|
orgIdSource: "query",
|
|
301628
301978
|
responseShape: "unwrapData"
|
|
301629
301979
|
});
|
|
301630
|
-
|
|
301980
|
+
registerProxyRoute({
|
|
301631
301981
|
forgePath: "/api/cmmd/automations/projects/:projectId/runs",
|
|
301632
301982
|
method: "GET",
|
|
301633
301983
|
cmmdPath: "/api/forge/context/automations/projects/:projectId/runs",
|
|
301634
301984
|
orgIdSource: "query",
|
|
301635
301985
|
responseShape: "unwrapData"
|
|
301636
301986
|
});
|
|
301637
|
-
|
|
301987
|
+
registerProxyRoute({
|
|
301638
301988
|
forgePath: "/api/cmmd/automations/projects/:projectId/tasks/:taskId/runs",
|
|
301639
301989
|
method: "POST",
|
|
301640
301990
|
cmmdPath: "/api/forge/context/automations/projects/:projectId/tasks/:taskId/runs",
|
|
301641
301991
|
orgIdSource: "query",
|
|
301642
301992
|
responseShape: "unwrapData"
|
|
301643
301993
|
});
|
|
301644
|
-
|
|
301994
|
+
registerProxyRoute({
|
|
301645
301995
|
forgePath: "/api/cmmd/automations/runs/:runId",
|
|
301646
301996
|
method: "GET",
|
|
301647
301997
|
cmmdPath: "/api/forge/context/automations/runs/:runId",
|
|
301648
301998
|
orgIdSource: "query",
|
|
301649
301999
|
responseShape: "unwrapData"
|
|
301650
302000
|
});
|
|
301651
|
-
|
|
302001
|
+
registerProxyRoute({
|
|
301652
302002
|
forgePath: "/api/cmmd/automations/runs/:runId/retry",
|
|
301653
302003
|
method: "POST",
|
|
301654
302004
|
cmmdPath: "/api/forge/context/automations/runs/:runId/retry",
|
|
301655
302005
|
orgIdSource: "query",
|
|
301656
302006
|
responseShape: "unwrapData"
|
|
301657
302007
|
});
|
|
301658
|
-
|
|
302008
|
+
registerProxyRoute({
|
|
301659
302009
|
forgePath: "/api/cmmd/automations/runs/:runId/cancel",
|
|
301660
302010
|
method: "POST",
|
|
301661
302011
|
cmmdPath: "/api/forge/context/automations/runs/:runId/cancel",
|
|
301662
302012
|
orgIdSource: "query",
|
|
301663
302013
|
responseShape: "unwrapData"
|
|
301664
302014
|
});
|
|
301665
|
-
|
|
302015
|
+
registerProxyRoute({
|
|
301666
302016
|
forgePath: "/api/cmmd/automations/runs/:runId/escalations/approve",
|
|
301667
302017
|
method: "POST",
|
|
301668
302018
|
cmmdPath: "/api/forge/context/automations/runs/:runId/escalations/approve",
|
|
301669
302019
|
orgIdSource: "query",
|
|
301670
302020
|
responseShape: "unwrapData"
|
|
301671
302021
|
});
|
|
301672
|
-
|
|
302022
|
+
registerProxyRoute({
|
|
301673
302023
|
forgePath: "/api/cmmd/automations/runs/:runId/escalations/reject",
|
|
301674
302024
|
method: "POST",
|
|
301675
302025
|
cmmdPath: "/api/forge/context/automations/runs/:runId/escalations/reject",
|
|
301676
302026
|
orgIdSource: "query",
|
|
301677
302027
|
responseShape: "unwrapData"
|
|
301678
302028
|
});
|
|
301679
|
-
|
|
302029
|
+
registerProxyRoute({
|
|
301680
302030
|
forgePath: "/api/cmmd/projects/:id/board",
|
|
301681
302031
|
method: "GET",
|
|
301682
302032
|
cmmdPath: "/api/forge/context/projects/:id/board",
|
|
301683
302033
|
orgIdSource: "none",
|
|
301684
302034
|
responseShape: "unwrapData"
|
|
301685
302035
|
});
|
|
301686
|
-
|
|
302036
|
+
registerProxyRoute({
|
|
301687
302037
|
forgePath: "/api/cmmd/projects/:id/task-workflow",
|
|
301688
302038
|
method: "GET",
|
|
301689
302039
|
cmmdPath: "/api/forge/context/projects/:id/task-workflow",
|
|
301690
302040
|
orgIdSource: "none",
|
|
301691
302041
|
responseShape: "unwrapData"
|
|
301692
302042
|
});
|
|
301693
|
-
|
|
302043
|
+
registerProxyRoute({
|
|
301694
302044
|
forgePath: "/api/cmmd/projects/:id/task-workflow",
|
|
301695
302045
|
method: "PUT",
|
|
301696
302046
|
cmmdPath: "/api/forge/context/projects/:id/task-workflow",
|
|
301697
302047
|
orgIdSource: "none",
|
|
301698
302048
|
responseShape: "unwrapData"
|
|
301699
302049
|
});
|
|
301700
|
-
|
|
302050
|
+
registerProxyRoute({
|
|
301701
302051
|
forgePath: "/api/cmmd/projects/:id/board",
|
|
301702
302052
|
method: "POST",
|
|
301703
302053
|
cmmdPath: "/api/forge/context/projects/:id/board",
|
|
301704
302054
|
orgIdSource: "none",
|
|
301705
302055
|
responseShape: "unwrapData"
|
|
301706
302056
|
});
|
|
301707
|
-
|
|
302057
|
+
registerProxyRoute({
|
|
301708
302058
|
forgePath: "/api/cmmd/projects/:id/board/:taskId",
|
|
301709
302059
|
method: "PATCH",
|
|
301710
302060
|
cmmdPath: "/api/forge/context/projects/:id/board/:taskId",
|
|
301711
302061
|
orgIdSource: "none",
|
|
301712
302062
|
responseShape: "unwrapData"
|
|
301713
302063
|
});
|
|
301714
|
-
|
|
302064
|
+
registerProxyRoute({
|
|
301715
302065
|
forgePath: "/api/cmmd/projects/:id/board/:taskId/status",
|
|
301716
302066
|
method: "PATCH",
|
|
301717
302067
|
cmmdPath: "/api/forge/context/projects/:id/board/:taskId/status",
|
|
301718
302068
|
orgIdSource: "none",
|
|
301719
302069
|
responseShape: "unwrapData"
|
|
301720
302070
|
});
|
|
301721
|
-
|
|
302071
|
+
registerProxyRoute({
|
|
301722
302072
|
forgePath: "/api/cmmd/projects/:id/board/:taskId/execution-options",
|
|
301723
302073
|
method: "GET",
|
|
301724
302074
|
cmmdPath: "/api/forge/context/projects/:id/board/:taskId/execution-options",
|
|
301725
302075
|
orgIdSource: "none",
|
|
301726
302076
|
responseShape: "unwrapData"
|
|
301727
302077
|
});
|
|
301728
|
-
|
|
302078
|
+
registerProxyRoute({
|
|
301729
302079
|
forgePath: "/api/cmmd/projects/:id/board/:taskId/work-sessions",
|
|
301730
302080
|
method: "POST",
|
|
301731
302081
|
cmmdPath: "/api/forge/context/projects/:id/board/:taskId/work-sessions",
|
|
301732
302082
|
orgIdSource: "none",
|
|
301733
302083
|
responseShape: "unwrapData"
|
|
301734
302084
|
});
|
|
301735
|
-
|
|
302085
|
+
registerProxyRoute({
|
|
301736
302086
|
forgePath: "/api/cmmd/projects/:id/work-sessions",
|
|
301737
302087
|
method: "GET",
|
|
301738
302088
|
cmmdPath: "/api/forge/context/projects/:id/work-sessions",
|
|
301739
302089
|
orgIdSource: "none",
|
|
301740
302090
|
responseShape: "unwrapData"
|
|
301741
302091
|
});
|
|
301742
|
-
|
|
302092
|
+
registerProxyRoute({
|
|
301743
302093
|
forgePath: "/api/cmmd/work-sessions/:workSessionId",
|
|
301744
302094
|
method: "GET",
|
|
301745
302095
|
cmmdPath: "/api/forge/context/work-sessions/:workSessionId",
|
|
301746
302096
|
orgIdSource: "none",
|
|
301747
302097
|
responseShape: "unwrapData"
|
|
301748
302098
|
});
|
|
301749
|
-
|
|
302099
|
+
registerProxyRoute({
|
|
301750
302100
|
forgePath: "/api/cmmd/work-sessions/:workSessionId",
|
|
301751
302101
|
method: "PATCH",
|
|
301752
302102
|
cmmdPath: "/api/forge/context/work-sessions/:workSessionId",
|
|
301753
302103
|
orgIdSource: "none",
|
|
301754
302104
|
responseShape: "unwrapData"
|
|
301755
302105
|
});
|
|
301756
|
-
|
|
302106
|
+
registerProxyRoute({
|
|
301757
302107
|
forgePath: "/api/cmmd/work-sessions/:workSessionId/threads",
|
|
301758
302108
|
method: "POST",
|
|
301759
302109
|
cmmdPath: "/api/forge/context/work-sessions/:workSessionId/threads",
|
|
301760
302110
|
orgIdSource: "none",
|
|
301761
302111
|
responseShape: "unwrapData"
|
|
301762
302112
|
});
|
|
301763
|
-
|
|
302113
|
+
registerProxyRoute({
|
|
301764
302114
|
forgePath: "/api/cmmd/tasks/:taskId/conversations",
|
|
301765
302115
|
method: "GET",
|
|
301766
302116
|
cmmdPath: "/api/forge/context/tasks/:taskId/conversations",
|
|
301767
302117
|
orgIdSource: "none",
|
|
301768
302118
|
responseShape: "unwrapData"
|
|
301769
302119
|
});
|
|
301770
|
-
|
|
302120
|
+
registerProxyRoute({
|
|
301771
302121
|
forgePath: "/api/cmmd/tasks/:taskId/conversations",
|
|
301772
302122
|
method: "POST",
|
|
301773
302123
|
cmmdPath: "/api/forge/context/tasks/:taskId/conversations",
|
|
301774
302124
|
orgIdSource: "none",
|
|
301775
302125
|
responseShape: "unwrapData"
|
|
301776
302126
|
});
|
|
301777
|
-
|
|
302127
|
+
registerProxyRoute({
|
|
301778
302128
|
forgePath: "/api/cmmd/tasks/:taskId/history",
|
|
301779
302129
|
method: "GET",
|
|
301780
302130
|
cmmdPath: "/api/forge/context/tasks/:taskId/history",
|
|
301781
302131
|
orgIdSource: "none",
|
|
301782
302132
|
responseShape: "unwrapData"
|
|
301783
302133
|
});
|
|
301784
|
-
|
|
302134
|
+
registerProxyRoute({
|
|
301785
302135
|
forgePath: "/api/cmmd/tasks/:taskId/pull-requests",
|
|
301786
302136
|
method: "PUT",
|
|
301787
302137
|
cmmdPath: "/api/forge/context/tasks/:taskId/pull-requests",
|
|
301788
302138
|
orgIdSource: "none",
|
|
301789
302139
|
responseShape: "unwrapData"
|
|
301790
302140
|
});
|
|
301791
|
-
const
|
|
302141
|
+
for (const path of [
|
|
301792
302142
|
"list",
|
|
301793
302143
|
"list-stats",
|
|
301794
302144
|
"detail",
|
|
@@ -301806,70 +302156,70 @@ const cmmdPullRequestRouteLayers = [
|
|
|
301806
302156
|
"thread/resolution",
|
|
301807
302157
|
"reviewers",
|
|
301808
302158
|
"reaction"
|
|
301809
|
-
]
|
|
302159
|
+
]) registerProxyRoute({
|
|
301810
302160
|
forgePath: `/api/cmmd/pull-requests/${path}`,
|
|
301811
302161
|
method: "POST",
|
|
301812
302162
|
cmmdPath: `/api/forge/context/pull-requests/${path}`,
|
|
301813
302163
|
orgIdSource: "none",
|
|
301814
302164
|
responseShape: "unwrapData"
|
|
301815
|
-
})
|
|
301816
|
-
|
|
302165
|
+
});
|
|
302166
|
+
registerProxyRoute({
|
|
301817
302167
|
forgePath: "/api/cmmd/tasks/:taskId/conversations/:conversationId",
|
|
301818
302168
|
method: "GET",
|
|
301819
302169
|
cmmdPath: "/api/forge/context/tasks/:taskId/conversations/:conversationId",
|
|
301820
302170
|
orgIdSource: "none",
|
|
301821
302171
|
responseShape: "unwrapData"
|
|
301822
302172
|
});
|
|
301823
|
-
|
|
302173
|
+
registerProxyRoute({
|
|
301824
302174
|
forgePath: "/api/cmmd/projects/:id/board/:taskId/spawn-forge-thread",
|
|
301825
302175
|
method: "POST",
|
|
301826
302176
|
cmmdPath: "/api/forge/context/projects/:id/board/:taskId/spawn-forge-thread",
|
|
301827
302177
|
orgIdSource: "none",
|
|
301828
302178
|
responseShape: "unwrapData"
|
|
301829
302179
|
});
|
|
301830
|
-
|
|
302180
|
+
registerProxyRoute({
|
|
301831
302181
|
forgePath: "/api/cmmd/work-items/board",
|
|
301832
302182
|
method: "GET",
|
|
301833
302183
|
cmmdPath: "/api/forge/context/work-items/board",
|
|
301834
302184
|
orgIdSource: "none",
|
|
301835
302185
|
responseShape: "unwrapData"
|
|
301836
302186
|
});
|
|
301837
|
-
|
|
302187
|
+
registerProxyRoute({
|
|
301838
302188
|
forgePath: "/api/cmmd/work-items/board",
|
|
301839
302189
|
method: "POST",
|
|
301840
302190
|
cmmdPath: "/api/forge/context/work-items/board",
|
|
301841
302191
|
orgIdSource: "none",
|
|
301842
302192
|
responseShape: "unwrapData"
|
|
301843
302193
|
});
|
|
301844
|
-
|
|
302194
|
+
registerProxyRoute({
|
|
301845
302195
|
forgePath: "/api/cmmd/feedback",
|
|
301846
302196
|
method: "POST",
|
|
301847
302197
|
cmmdPath: "/api/forge/context/feedback",
|
|
301848
302198
|
orgIdSource: "none",
|
|
301849
302199
|
responseShape: "unwrapData"
|
|
301850
302200
|
});
|
|
301851
|
-
|
|
302201
|
+
registerProxyRoute({
|
|
301852
302202
|
forgePath: "/api/cmmd/work-items/board/:taskId",
|
|
301853
302203
|
method: "PATCH",
|
|
301854
302204
|
cmmdPath: "/api/forge/context/work-items/board/:taskId",
|
|
301855
302205
|
orgIdSource: "none",
|
|
301856
302206
|
responseShape: "unwrapData"
|
|
301857
302207
|
});
|
|
301858
|
-
|
|
302208
|
+
registerProxyRoute({
|
|
301859
302209
|
forgePath: "/api/cmmd/work-items/board/:taskId/move",
|
|
301860
302210
|
method: "PATCH",
|
|
301861
302211
|
cmmdPath: "/api/forge/context/work-items/board/:taskId/move",
|
|
301862
302212
|
orgIdSource: "none",
|
|
301863
302213
|
responseShape: "unwrapData"
|
|
301864
302214
|
});
|
|
301865
|
-
|
|
302215
|
+
registerProxyRoute({
|
|
301866
302216
|
forgePath: "/api/cmmd/projects/:projectId/board/:taskId/move",
|
|
301867
302217
|
method: "PATCH",
|
|
301868
302218
|
cmmdPath: "/api/forge/context/projects/:projectId/board/:taskId/move",
|
|
301869
302219
|
orgIdSource: "none",
|
|
301870
302220
|
responseShape: "unwrapData"
|
|
301871
302221
|
});
|
|
301872
|
-
|
|
302222
|
+
registerProxyRoute({
|
|
301873
302223
|
forgePath: "/api/cmmd/projects/:projectId/board/:taskId/archive",
|
|
301874
302224
|
method: "POST",
|
|
301875
302225
|
cmmdPath: "/api/forge/context/projects/:projectId/board/:taskId/archive",
|
|
@@ -301877,7 +302227,7 @@ const cmmdArchiveProjectBoardTaskRouteLayer = registerProxyRoute({
|
|
|
301877
302227
|
responseShape: "unwrapData",
|
|
301878
302228
|
requestBody: "none"
|
|
301879
302229
|
});
|
|
301880
|
-
|
|
302230
|
+
registerProxyRoute({
|
|
301881
302231
|
forgePath: "/api/cmmd/projects/:projectId/board/:taskId/unarchive",
|
|
301882
302232
|
method: "POST",
|
|
301883
302233
|
cmmdPath: "/api/forge/context/projects/:projectId/board/:taskId/unarchive",
|
|
@@ -301885,7 +302235,7 @@ const cmmdUnarchiveProjectBoardTaskRouteLayer = registerProxyRoute({
|
|
|
301885
302235
|
responseShape: "unwrapData",
|
|
301886
302236
|
requestBody: "none"
|
|
301887
302237
|
});
|
|
301888
|
-
|
|
302238
|
+
registerProxyRoute({
|
|
301889
302239
|
forgePath: "/api/cmmd/work-items/board/:taskId/archive",
|
|
301890
302240
|
method: "POST",
|
|
301891
302241
|
cmmdPath: "/api/forge/context/work-items/board/:taskId/archive",
|
|
@@ -301893,7 +302243,7 @@ const cmmdArchiveCenterBoardTaskRouteLayer = registerProxyRoute({
|
|
|
301893
302243
|
responseShape: "unwrapData",
|
|
301894
302244
|
requestBody: "none"
|
|
301895
302245
|
});
|
|
301896
|
-
|
|
302246
|
+
registerProxyRoute({
|
|
301897
302247
|
forgePath: "/api/cmmd/work-items/board/:taskId/unarchive",
|
|
301898
302248
|
method: "POST",
|
|
301899
302249
|
cmmdPath: "/api/forge/context/work-items/board/:taskId/unarchive",
|
|
@@ -301901,109 +302251,109 @@ const cmmdUnarchiveCenterBoardTaskRouteLayer = registerProxyRoute({
|
|
|
301901
302251
|
responseShape: "unwrapData",
|
|
301902
302252
|
requestBody: "none"
|
|
301903
302253
|
});
|
|
301904
|
-
|
|
302254
|
+
registerProxyRoute({
|
|
301905
302255
|
forgePath: "/api/cmmd/campaigns",
|
|
301906
302256
|
method: "GET",
|
|
301907
302257
|
cmmdPath: "/api/forge/context/campaigns",
|
|
301908
302258
|
orgIdSource: "none",
|
|
301909
302259
|
responseShape: "passthrough"
|
|
301910
302260
|
});
|
|
301911
|
-
|
|
302261
|
+
registerProxyRoute({
|
|
301912
302262
|
forgePath: "/api/cmmd/campaigns/:id",
|
|
301913
302263
|
method: "GET",
|
|
301914
302264
|
cmmdPath: "/api/forge/context/campaigns/:id",
|
|
301915
302265
|
orgIdSource: "none",
|
|
301916
302266
|
responseShape: "passthrough"
|
|
301917
302267
|
});
|
|
301918
|
-
|
|
302268
|
+
registerProxyRoute({
|
|
301919
302269
|
forgePath: "/api/cmmd/campaigns",
|
|
301920
302270
|
method: "POST",
|
|
301921
302271
|
cmmdPath: "/api/projects/campaigns",
|
|
301922
302272
|
responseShape: "passthrough"
|
|
301923
302273
|
});
|
|
301924
|
-
|
|
302274
|
+
registerProxyRoute({
|
|
301925
302275
|
forgePath: "/api/cmmd/campaigns/:id",
|
|
301926
302276
|
method: "PUT",
|
|
301927
302277
|
cmmdPath: "/api/projects/campaigns/:id",
|
|
301928
302278
|
responseShape: "passthrough"
|
|
301929
302279
|
});
|
|
301930
|
-
|
|
302280
|
+
registerProxyRoute({
|
|
301931
302281
|
forgePath: "/api/cmmd/campaigns/:id",
|
|
301932
302282
|
method: "DELETE",
|
|
301933
302283
|
cmmdPath: "/api/projects/campaigns/:id",
|
|
301934
302284
|
orgIdSource: "none"
|
|
301935
302285
|
});
|
|
301936
|
-
|
|
302286
|
+
registerProxyRoute({
|
|
301937
302287
|
forgePath: "/api/cmmd/bootstrap",
|
|
301938
302288
|
method: "GET",
|
|
301939
302289
|
cmmdPath: "/api/forge/context/bootstrap",
|
|
301940
302290
|
orgIdSource: "none",
|
|
301941
302291
|
responseShape: "passthrough"
|
|
301942
302292
|
});
|
|
301943
|
-
|
|
302293
|
+
registerProxyRoute({
|
|
301944
302294
|
forgePath: "/api/cmmd/account/preferences",
|
|
301945
302295
|
method: "GET",
|
|
301946
302296
|
cmmdPath: "/api/forge/context/account/preferences",
|
|
301947
302297
|
orgIdSource: "none",
|
|
301948
302298
|
responseShape: "unwrapData"
|
|
301949
302299
|
});
|
|
301950
|
-
|
|
302300
|
+
registerProxyRoute({
|
|
301951
302301
|
forgePath: "/api/cmmd/account/preferences",
|
|
301952
302302
|
method: "PATCH",
|
|
301953
302303
|
cmmdPath: "/api/forge/context/account/preferences",
|
|
301954
302304
|
orgIdSource: "none",
|
|
301955
302305
|
responseShape: "unwrapData"
|
|
301956
302306
|
});
|
|
301957
|
-
|
|
302307
|
+
registerProxyRoute({
|
|
301958
302308
|
forgePath: "/api/cmmd/org/provider-policy",
|
|
301959
302309
|
method: "GET",
|
|
301960
302310
|
cmmdPath: "/api/forge/context/org/provider-policy",
|
|
301961
302311
|
orgIdSource: "none",
|
|
301962
302312
|
responseShape: "unwrapData"
|
|
301963
302313
|
});
|
|
301964
|
-
|
|
302314
|
+
registerProxyRoute({
|
|
301965
302315
|
forgePath: "/api/cmmd/chats",
|
|
301966
302316
|
method: "GET",
|
|
301967
302317
|
cmmdPath: "/api/forge/context/chats",
|
|
301968
302318
|
orgIdSource: "none",
|
|
301969
302319
|
responseShape: "unwrapData"
|
|
301970
302320
|
});
|
|
301971
|
-
|
|
302321
|
+
registerProxyRoute({
|
|
301972
302322
|
forgePath: "/api/cmmd/chats/:threadId",
|
|
301973
302323
|
method: "GET",
|
|
301974
302324
|
cmmdPath: "/api/forge/context/chats/:threadId",
|
|
301975
302325
|
orgIdSource: "none",
|
|
301976
302326
|
responseShape: "unwrapData"
|
|
301977
302327
|
});
|
|
301978
|
-
|
|
302328
|
+
registerProxyRoute({
|
|
301979
302329
|
forgePath: "/api/cmmd/devices",
|
|
301980
302330
|
method: "GET",
|
|
301981
302331
|
cmmdPath: "/api/forge/context/devices",
|
|
301982
302332
|
orgIdSource: "none",
|
|
301983
302333
|
responseShape: "unwrapData"
|
|
301984
302334
|
});
|
|
301985
|
-
|
|
302335
|
+
registerProxyRoute({
|
|
301986
302336
|
forgePath: "/api/cmmd/devices/register",
|
|
301987
302337
|
method: "POST",
|
|
301988
302338
|
cmmdPath: "/api/forge/context/devices/register",
|
|
301989
302339
|
orgIdSource: "none",
|
|
301990
302340
|
responseShape: "unwrapData"
|
|
301991
302341
|
});
|
|
301992
|
-
|
|
302342
|
+
registerProxyRoute({
|
|
301993
302343
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/heartbeat",
|
|
301994
302344
|
method: "POST",
|
|
301995
302345
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/heartbeat",
|
|
301996
302346
|
orgIdSource: "none",
|
|
301997
302347
|
responseShape: "unwrapData"
|
|
301998
302348
|
});
|
|
301999
|
-
|
|
302349
|
+
registerProxyRoute({
|
|
302000
302350
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/access-grants",
|
|
302001
302351
|
method: "POST",
|
|
302002
302352
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/access-grants",
|
|
302003
302353
|
orgIdSource: "none",
|
|
302004
302354
|
responseShape: "unwrapData"
|
|
302005
302355
|
});
|
|
302006
|
-
|
|
302356
|
+
registerProxyRoute({
|
|
302007
302357
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/access-grants/:grantId/revoke",
|
|
302008
302358
|
method: "POST",
|
|
302009
302359
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/access-grants/:grantId/revoke",
|
|
@@ -302011,46 +302361,60 @@ const cmmdRevokeRuntimeAccessRouteLayer = registerProxyRoute({
|
|
|
302011
302361
|
responseShape: "unwrapData",
|
|
302012
302362
|
successStatus: 200
|
|
302013
302363
|
});
|
|
302014
|
-
|
|
302364
|
+
registerProxyRoute({
|
|
302015
302365
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/relay-routes",
|
|
302016
302366
|
method: "POST",
|
|
302017
302367
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/relay-routes",
|
|
302018
302368
|
orgIdSource: "none",
|
|
302019
302369
|
responseShape: "unwrapData"
|
|
302020
302370
|
});
|
|
302021
|
-
|
|
302371
|
+
registerProxyRoute({
|
|
302022
302372
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/relay-action-grants",
|
|
302023
302373
|
method: "POST",
|
|
302024
302374
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/relay-action-grants",
|
|
302025
302375
|
orgIdSource: "none",
|
|
302026
302376
|
responseShape: "unwrapData"
|
|
302027
302377
|
});
|
|
302028
|
-
|
|
302378
|
+
registerProxyRoute({
|
|
302029
302379
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/inventory",
|
|
302030
302380
|
method: "PUT",
|
|
302031
302381
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/inventory",
|
|
302032
302382
|
orgIdSource: "none",
|
|
302033
302383
|
responseShape: "unwrapData"
|
|
302034
302384
|
});
|
|
302035
|
-
|
|
302385
|
+
registerProxyRoute({
|
|
302036
302386
|
forgePath: "/api/cmmd/runtime-inventory",
|
|
302037
302387
|
method: "GET",
|
|
302038
302388
|
cmmdPath: "/api/forge/context/runtime-inventory",
|
|
302039
302389
|
orgIdSource: "none",
|
|
302040
302390
|
responseShape: "unwrapData"
|
|
302041
302391
|
});
|
|
302392
|
+
registerProxyRoute({
|
|
302393
|
+
forgePath: "/api/cmmd/threads/:runtimeId/:threadId/lifecycle-intent",
|
|
302394
|
+
method: "PUT",
|
|
302395
|
+
cmmdPath: "/api/forge/context/threads/:runtimeId/:threadId/lifecycle-intent",
|
|
302396
|
+
orgIdSource: "none",
|
|
302397
|
+
requestBody: "json",
|
|
302398
|
+
responseShape: "unwrapData"
|
|
302399
|
+
});
|
|
302400
|
+
registerProxyRoute({
|
|
302401
|
+
forgePath: "/api/cmmd/threads/:runtimeId/:threadId/lifecycle-intent",
|
|
302402
|
+
method: "DELETE",
|
|
302403
|
+
cmmdPath: "/api/forge/context/threads/:runtimeId/:threadId/lifecycle-intent",
|
|
302404
|
+
orgIdSource: "none"
|
|
302405
|
+
});
|
|
302042
302406
|
/**
|
|
302043
302407
|
* Owner-scoped, bounded control-plane observation. This is intentionally
|
|
302044
302408
|
* separate from the runtime inventory publisher and never wakes a runtime.
|
|
302045
302409
|
*/
|
|
302046
|
-
|
|
302410
|
+
registerProxyRoute({
|
|
302047
302411
|
forgePath: "/api/cmmd/runtime-diagnostics/v2/runtimes/:runtimeId",
|
|
302048
302412
|
method: "GET",
|
|
302049
302413
|
cmmdPath: "/api/forge/context/runtime-diagnostics/v2/runtimes/:runtimeId",
|
|
302050
302414
|
orgIdSource: "none",
|
|
302051
302415
|
responseShape: "unwrapData"
|
|
302052
302416
|
});
|
|
302053
|
-
|
|
302417
|
+
registerProxyRoute({
|
|
302054
302418
|
forgePath: "/api/cmmd/auth-runtime",
|
|
302055
302419
|
method: "POST",
|
|
302056
302420
|
cmmdPath: "/api/forge/context/auth-runtime",
|
|
@@ -302058,21 +302422,21 @@ const cmmdProvisionAuthRuntimeRouteLayer = registerProxyRoute({
|
|
|
302058
302422
|
responseShape: "unwrapData",
|
|
302059
302423
|
requestBody: "none"
|
|
302060
302424
|
});
|
|
302061
|
-
|
|
302425
|
+
registerProxyRoute({
|
|
302062
302426
|
forgePath: "/api/cmmd/auth-runtime",
|
|
302063
302427
|
method: "GET",
|
|
302064
302428
|
cmmdPath: "/api/forge/context/auth-runtime",
|
|
302065
302429
|
orgIdSource: "none",
|
|
302066
302430
|
responseShape: "unwrapData"
|
|
302067
302431
|
});
|
|
302068
|
-
|
|
302432
|
+
registerProxyRoute({
|
|
302069
302433
|
forgePath: "/api/cmmd/auth-runtime",
|
|
302070
302434
|
method: "DELETE",
|
|
302071
302435
|
cmmdPath: "/api/forge/context/auth-runtime",
|
|
302072
302436
|
orgIdSource: "none",
|
|
302073
302437
|
responseShape: "unwrapData"
|
|
302074
302438
|
});
|
|
302075
|
-
|
|
302439
|
+
registerProxyRoute({
|
|
302076
302440
|
forgePath: "/api/cmmd/auth-runtime/connect",
|
|
302077
302441
|
method: "POST",
|
|
302078
302442
|
cmmdPath: "/api/forge/context/auth-runtime/connect",
|
|
@@ -302080,14 +302444,14 @@ const cmmdConnectAuthRuntimeRouteLayer = registerProxyRoute({
|
|
|
302080
302444
|
responseShape: "unwrapData",
|
|
302081
302445
|
requestBody: "none"
|
|
302082
302446
|
});
|
|
302083
|
-
|
|
302447
|
+
registerProxyRoute({
|
|
302084
302448
|
forgePath: "/api/cmmd/providers/accounts",
|
|
302085
302449
|
method: "GET",
|
|
302086
302450
|
cmmdPath: "/api/forge/context/providers/accounts",
|
|
302087
302451
|
orgIdSource: "none",
|
|
302088
302452
|
responseShape: "unwrapData"
|
|
302089
302453
|
});
|
|
302090
|
-
|
|
302454
|
+
registerProxyRoute({
|
|
302091
302455
|
forgePath: "/api/cmmd/providers/accounts/:id",
|
|
302092
302456
|
method: "DELETE",
|
|
302093
302457
|
cmmdPath: "/api/forge/context/providers/accounts/:id",
|
|
@@ -302095,23 +302459,29 @@ const cmmdDeleteProviderAccountRouteLayer = registerProxyRoute({
|
|
|
302095
302459
|
responseShape: "unwrapData",
|
|
302096
302460
|
requestBody: "none"
|
|
302097
302461
|
});
|
|
302098
|
-
|
|
302462
|
+
registerProxyRoute({
|
|
302099
302463
|
forgePath: "/api/cmmd/providers/accounts/default",
|
|
302100
302464
|
method: "PUT",
|
|
302101
302465
|
cmmdPath: "/api/forge/context/providers/accounts/default",
|
|
302102
302466
|
orgIdSource: "none",
|
|
302103
302467
|
responseShape: "unwrapData"
|
|
302104
302468
|
});
|
|
302105
|
-
|
|
302106
|
-
|
|
302107
|
-
|
|
302469
|
+
registerProxyHandler({
|
|
302470
|
+
forgePath: "/api/cmmd/providers/usage",
|
|
302471
|
+
method: "GET",
|
|
302472
|
+
parse: () => succeed({
|
|
302473
|
+
ok: true,
|
|
302474
|
+
value: void 0
|
|
302475
|
+
}),
|
|
302476
|
+
run: (_parsed, { session }) => runCmmdRestProxyAsHandlerResult(session, (jwt) => cmmdGateway.request({
|
|
302108
302477
|
method: "GET",
|
|
302109
302478
|
jwt,
|
|
302110
302479
|
path: "/api/forge/context/providers/usage"
|
|
302111
|
-
}))
|
|
302112
|
-
|
|
302113
|
-
|
|
302114
|
-
})
|
|
302480
|
+
}), (value) => ({
|
|
302481
|
+
status: 200,
|
|
302482
|
+
body: unwrapForgeEnvelope(value)
|
|
302483
|
+
}))
|
|
302484
|
+
});
|
|
302115
302485
|
function parseProviderUsageRefreshInput(rawBody) {
|
|
302116
302486
|
if (rawBody === null || typeof rawBody !== "object") return null;
|
|
302117
302487
|
const body = rawBody;
|
|
@@ -302193,56 +302563,56 @@ function makeRefreshProviderUsageHandler(dependencies = {}) {
|
|
|
302193
302563
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error)));
|
|
302194
302564
|
}
|
|
302195
302565
|
const cmmdRefreshProviderUsageRouteLayer = add$1("POST", "/api/cmmd/providers/usage/refresh", makeRefreshProviderUsageHandler());
|
|
302196
|
-
|
|
302566
|
+
registerProxyRoute({
|
|
302197
302567
|
forgePath: "/api/cmmd/providers/codex/credential",
|
|
302198
302568
|
method: "GET",
|
|
302199
302569
|
cmmdPath: "/api/forge/context/providers/codex/credential",
|
|
302200
302570
|
orgIdSource: "none",
|
|
302201
302571
|
responseShape: "unwrapData"
|
|
302202
302572
|
});
|
|
302203
|
-
|
|
302573
|
+
registerProxyRoute({
|
|
302204
302574
|
forgePath: "/api/cmmd/providers/codex/credential",
|
|
302205
302575
|
method: "DELETE",
|
|
302206
302576
|
cmmdPath: "/api/forge/context/providers/codex/credential",
|
|
302207
302577
|
orgIdSource: "none",
|
|
302208
302578
|
responseShape: "unwrapData"
|
|
302209
302579
|
});
|
|
302210
|
-
|
|
302580
|
+
registerProxyRoute({
|
|
302211
302581
|
forgePath: "/api/cmmd/providers/claude/credential",
|
|
302212
302582
|
method: "GET",
|
|
302213
302583
|
cmmdPath: "/api/forge/context/providers/claude/credential",
|
|
302214
302584
|
orgIdSource: "none",
|
|
302215
302585
|
responseShape: "unwrapData"
|
|
302216
302586
|
});
|
|
302217
|
-
|
|
302587
|
+
registerProxyRoute({
|
|
302218
302588
|
forgePath: "/api/cmmd/providers/claude/credential",
|
|
302219
302589
|
method: "DELETE",
|
|
302220
302590
|
cmmdPath: "/api/forge/context/providers/claude/credential",
|
|
302221
302591
|
orgIdSource: "none",
|
|
302222
302592
|
responseShape: "unwrapData"
|
|
302223
302593
|
});
|
|
302224
|
-
|
|
302594
|
+
registerProxyRoute({
|
|
302225
302595
|
forgePath: "/api/cmmd/providers/claude/runtime-readiness/:runtimeId",
|
|
302226
302596
|
method: "GET",
|
|
302227
302597
|
cmmdPath: "/api/forge/context/providers/claude/runtime-readiness/:runtimeId",
|
|
302228
302598
|
orgIdSource: "none",
|
|
302229
302599
|
responseShape: "unwrapData"
|
|
302230
302600
|
});
|
|
302231
|
-
|
|
302601
|
+
registerProxyRoute({
|
|
302232
302602
|
forgePath: "/api/cmmd/devices/runtimes/:runtimeId/threads/:threadId/events",
|
|
302233
302603
|
method: "POST",
|
|
302234
302604
|
cmmdPath: "/api/forge/context/devices/runtimes/:runtimeId/threads/:threadId/events",
|
|
302235
302605
|
orgIdSource: "none",
|
|
302236
302606
|
responseShape: "unwrapData"
|
|
302237
302607
|
});
|
|
302238
|
-
|
|
302608
|
+
registerProxyRoute({
|
|
302239
302609
|
forgePath: "/api/cmmd/threads/:runtimeId/:threadId",
|
|
302240
302610
|
method: "GET",
|
|
302241
302611
|
cmmdPath: "/api/forge/context/threads/:runtimeId/:threadId",
|
|
302242
302612
|
orgIdSource: "none",
|
|
302243
302613
|
responseShape: "unwrapData"
|
|
302244
302614
|
});
|
|
302245
|
-
|
|
302615
|
+
registerProxyRoute({
|
|
302246
302616
|
forgePath: "/api/cmmd/devices/:deviceId/rename",
|
|
302247
302617
|
method: "POST",
|
|
302248
302618
|
cmmdPath: "/api/forge/context/devices/:deviceId/rename",
|
|
@@ -302258,7 +302628,7 @@ const cmmdRenameDeviceRouteLayer = registerProxyRoute({
|
|
|
302258
302628
|
* the status and the code reach the browser unchanged, which is what lets the
|
|
302259
302629
|
* rename field say something specific instead of "something went wrong".
|
|
302260
302630
|
*/
|
|
302261
|
-
|
|
302631
|
+
registerProxyRoute({
|
|
302262
302632
|
forgePath: "/api/cmmd/forge-runtimes/:runtimeId/rename",
|
|
302263
302633
|
method: "POST",
|
|
302264
302634
|
cmmdPath: "/api/forge/context/runtimes/:runtimeId/rename",
|
|
@@ -302266,7 +302636,7 @@ const cmmdRenameForgeRuntimeRouteLayer = registerProxyRoute({
|
|
|
302266
302636
|
responseShape: "unwrapData",
|
|
302267
302637
|
successStatus: 200
|
|
302268
302638
|
});
|
|
302269
|
-
|
|
302639
|
+
registerProxyRoute({
|
|
302270
302640
|
forgePath: "/api/cmmd/devices/:deviceId/revoke",
|
|
302271
302641
|
method: "POST",
|
|
302272
302642
|
cmmdPath: "/api/forge/context/devices/:deviceId/revoke",
|
|
@@ -302275,24 +302645,21 @@ const cmmdRevokeDeviceRouteLayer = registerProxyRoute({
|
|
|
302275
302645
|
requestBody: "none",
|
|
302276
302646
|
successStatus: 200
|
|
302277
302647
|
});
|
|
302278
|
-
|
|
302648
|
+
registerProxyRoute({
|
|
302279
302649
|
forgePath: "/api/cmmd/connectors",
|
|
302280
302650
|
method: "GET",
|
|
302281
302651
|
cmmdPath: "/api/forge/context/connectors",
|
|
302282
302652
|
orgIdSource: "none"
|
|
302283
302653
|
});
|
|
302284
|
-
|
|
302654
|
+
registerProxyRoute({
|
|
302285
302655
|
forgePath: "/api/cmmd/connectors/:connectorId/install",
|
|
302286
302656
|
method: "POST",
|
|
302287
302657
|
cmmdPath: "/api/forge/context/connectors/:connectorId/install",
|
|
302288
302658
|
orgIdSource: "none"
|
|
302289
302659
|
});
|
|
302290
302660
|
const cmmdForgeCloudProjectsListRouteLayer = add$1("GET", "/api/cmmd/forge-cloud-projects", gen(function* () {
|
|
302291
|
-
const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects");
|
|
302292
|
-
if (!accessToken) return
|
|
302293
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302294
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302295
|
-
});
|
|
302661
|
+
const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects");
|
|
302662
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302296
302663
|
const upstreamUrl = `${resolveCommandAppUrl()}${CMMD_CLOUD_PROJECTS_PATH}`;
|
|
302297
302664
|
const upstreamOrError = yield* fetchCmmdUpstreamWithRetry(() => fetch(upstreamUrl, { headers: {
|
|
302298
302665
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -302303,10 +302670,7 @@ const cmmdForgeCloudProjectsListRouteLayer = add$1("GET", "/api/cmmd/forge-cloud
|
|
|
302303
302670
|
code: "CMMD_UNAVAILABLE"
|
|
302304
302671
|
}, { status: 503 });
|
|
302305
302672
|
const upstream = upstreamOrError.res;
|
|
302306
|
-
if (upstream.status === 401 || upstream.status === 403) return
|
|
302307
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302308
|
-
message: "CMMD authentication expired. Sign in again to continue."
|
|
302309
|
-
});
|
|
302673
|
+
if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302310
302674
|
const bodyOrError = yield* tryPromise(() => upstream.text()).pipe(map$3((text) => ({
|
|
302311
302675
|
ok: true,
|
|
302312
302676
|
text
|
|
@@ -302328,35 +302692,35 @@ const cmmdForgeCloudProjectsListRouteLayer = add$1("GET", "/api/cmmd/forge-cloud
|
|
|
302328
302692
|
headers: { "content-type": "application/json" }
|
|
302329
302693
|
});
|
|
302330
302694
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
|
|
302331
|
-
|
|
302695
|
+
registerProxyRoute({
|
|
302332
302696
|
forgePath: "/api/cmmd/forge-cloud-projects",
|
|
302333
302697
|
method: "POST",
|
|
302334
302698
|
cmmdPath: CMMD_CLOUD_PROJECTS_PATH,
|
|
302335
302699
|
orgIdSource: "none",
|
|
302336
302700
|
responseShape: "unwrapData"
|
|
302337
302701
|
});
|
|
302338
|
-
|
|
302702
|
+
registerProxyRoute({
|
|
302339
302703
|
forgePath: "/api/cmmd/forge-cloud-projects/:projectId",
|
|
302340
302704
|
method: "DELETE",
|
|
302341
302705
|
cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId`,
|
|
302342
302706
|
orgIdSource: "none",
|
|
302343
302707
|
responseShape: "unwrapData"
|
|
302344
302708
|
});
|
|
302345
|
-
|
|
302709
|
+
registerProxyRoute({
|
|
302346
302710
|
forgePath: "/api/cmmd/forge-cloud-projects/:projectId/lifecycle-preflight",
|
|
302347
302711
|
method: "GET",
|
|
302348
302712
|
cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId/lifecycle-preflight`,
|
|
302349
302713
|
orgIdSource: "none",
|
|
302350
302714
|
responseShape: "unwrapData"
|
|
302351
302715
|
});
|
|
302352
|
-
|
|
302716
|
+
registerProxyRoute({
|
|
302353
302717
|
forgePath: "/api/cmmd/forge-cloud-projects/:projectId/removal-preview",
|
|
302354
302718
|
method: "GET",
|
|
302355
302719
|
cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId/removal-preview`,
|
|
302356
302720
|
orgIdSource: "none",
|
|
302357
302721
|
responseShape: "unwrapData"
|
|
302358
302722
|
});
|
|
302359
|
-
|
|
302723
|
+
registerProxyRoute({
|
|
302360
302724
|
forgePath: "/api/cmmd/forge-cloud-projects/:projectId/removal",
|
|
302361
302725
|
method: "POST",
|
|
302362
302726
|
cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/:projectId/removal`,
|
|
@@ -302365,7 +302729,7 @@ const cmmdForgeCloudProjectRemovalRouteLayer = registerProxyRoute({
|
|
|
302365
302729
|
successStatus: 202,
|
|
302366
302730
|
workIntakeInvalidation: "completedPermanentRemoval"
|
|
302367
302731
|
});
|
|
302368
|
-
|
|
302732
|
+
registerProxyRoute({
|
|
302369
302733
|
forgePath: "/api/cmmd/forge-cloud-project-removals/:operationId",
|
|
302370
302734
|
method: "GET",
|
|
302371
302735
|
cmmdPath: `${CMMD_CLOUD_PROJECTS_PATH}/removals/:operationId`,
|
|
@@ -302429,11 +302793,8 @@ function makeFetchCloudProjectsFrameEffect(upstreamUrl, accessToken) {
|
|
|
302429
302793
|
})).pipe(catch_(() => succeed(null)));
|
|
302430
302794
|
}
|
|
302431
302795
|
const cmmdForgeCloudProjectsEventsRouteLayer = add$1("GET", "/api/cmmd/forge-cloud-projects/events", gen(function* () {
|
|
302432
|
-
const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects/events");
|
|
302433
|
-
if (!accessToken) return
|
|
302434
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302435
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302436
|
-
});
|
|
302796
|
+
const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-cloud-projects/events");
|
|
302797
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302437
302798
|
const fetchCloudProjectsFrame = makeFetchCloudProjectsFrameEffect(`${resolveCommandAppUrl()}${CMMD_CLOUD_PROJECTS_PATH}`, accessToken);
|
|
302438
302799
|
const dataStream = concat$2(fromEffect(fetchCloudProjectsFrame), tick(FORGE_RUNTIMES_POLL_INTERVAL).pipe(mapEffect$1(() => fetchCloudProjectsFrame))).pipe(filter$2((frame) => frame !== null));
|
|
302439
302800
|
const keepaliveStream = tick(FORGE_RUNTIMES_KEEPALIVE_INTERVAL).pipe(map$7(() => FORGE_RUNTIMES_KEEPALIVE_FRAME));
|
|
@@ -302505,11 +302866,8 @@ function fetchCmmdUpstreamWithRetry(send, policy = "idempotent") {
|
|
|
302505
302866
|
}
|
|
302506
302867
|
const cmmdForgeRuntimesEnsureRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/ensure", gen(function* () {
|
|
302507
302868
|
const request = yield* HttpServerRequest;
|
|
302508
|
-
const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/ensure");
|
|
302509
|
-
if (!accessToken) return
|
|
302510
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302511
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302512
|
-
});
|
|
302869
|
+
const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/ensure");
|
|
302870
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302513
302871
|
const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(catch_(() => succeed({}))));
|
|
302514
302872
|
if (!scopedBody) return jsonUnsafe({ error: "A valid organizationId is required when organization scope is provided." }, { status: 400 });
|
|
302515
302873
|
const upstreamUrl = `${resolveCommandAppUrl()}/api/forge/context/runtimes/ensure`;
|
|
@@ -302528,10 +302886,7 @@ const cmmdForgeRuntimesEnsureRouteLayer = add$1("POST", "/api/cmmd/forge-runtime
|
|
|
302528
302886
|
code: "CMMD_UNAVAILABLE"
|
|
302529
302887
|
}, { status: 503 });
|
|
302530
302888
|
const upstream = upstreamOrError.res;
|
|
302531
|
-
if (upstream.status === 401 || upstream.status === 403) return
|
|
302532
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302533
|
-
message: "CMMD authentication expired. Sign in again to continue."
|
|
302534
|
-
});
|
|
302889
|
+
if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302535
302890
|
const bodyOrError = yield* tryPromise(() => upstream.text()).pipe(map$3((text) => ({
|
|
302536
302891
|
ok: true,
|
|
302537
302892
|
text
|
|
@@ -302555,11 +302910,8 @@ const cmmdForgeRuntimesEnsureRouteLayer = add$1("POST", "/api/cmmd/forge-runtime
|
|
|
302555
302910
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
|
|
302556
302911
|
const cmmdForgeRuntimesConnectRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/:runtimeId/connect", gen(function* () {
|
|
302557
302912
|
const request = yield* HttpServerRequest;
|
|
302558
|
-
const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/connect");
|
|
302559
|
-
if (!accessToken) return
|
|
302560
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302561
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302562
|
-
});
|
|
302913
|
+
const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/connect");
|
|
302914
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302563
302915
|
const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
|
|
302564
302916
|
if (!runtimeId) return jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
|
|
302565
302917
|
const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(catch_(() => succeed({}))));
|
|
@@ -302580,10 +302932,7 @@ const cmmdForgeRuntimesConnectRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
|
|
|
302580
302932
|
code: "CMMD_UNAVAILABLE"
|
|
302581
302933
|
}, { status: 503 });
|
|
302582
302934
|
const upstream = upstreamOrError.res;
|
|
302583
|
-
if (upstream.status === 401 || upstream.status === 403) return
|
|
302584
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302585
|
-
message: "CMMD authentication expired. Sign in again to continue."
|
|
302586
|
-
});
|
|
302935
|
+
if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302587
302936
|
const bodyOrError = yield* tryPromise(() => upstream.text()).pipe(map$3((text) => ({
|
|
302588
302937
|
ok: true,
|
|
302589
302938
|
text
|
|
@@ -302607,11 +302956,8 @@ const cmmdForgeRuntimesConnectRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
|
|
|
302607
302956
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
|
|
302608
302957
|
const cmmdForgeRuntimesStatusRouteLayer = add$1("GET", "/api/cmmd/forge-runtimes/:runtimeId/status", gen(function* () {
|
|
302609
302958
|
const request = yield* HttpServerRequest;
|
|
302610
|
-
const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/status");
|
|
302611
|
-
if (!accessToken) return
|
|
302612
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302613
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302614
|
-
});
|
|
302959
|
+
const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/status");
|
|
302960
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302615
302961
|
const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
|
|
302616
302962
|
if (!runtimeId) return jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
|
|
302617
302963
|
const upstreamUrl = `${resolveCommandAppUrl()}/api/forge/context/runtimes/${encodeURIComponent(runtimeId)}/status`;
|
|
@@ -302627,10 +302973,7 @@ const cmmdForgeRuntimesStatusRouteLayer = add$1("GET", "/api/cmmd/forge-runtimes
|
|
|
302627
302973
|
code: "CMMD_UNAVAILABLE"
|
|
302628
302974
|
}, { status: 503 });
|
|
302629
302975
|
const upstream = upstreamOrError.res;
|
|
302630
|
-
if (upstream.status === 401 || upstream.status === 403) return
|
|
302631
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302632
|
-
message: "CMMD authentication expired. Sign in again to continue."
|
|
302633
|
-
});
|
|
302976
|
+
if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302634
302977
|
const bodyOrError = yield* tryPromise(() => upstream.text()).pipe(map$3((text) => ({
|
|
302635
302978
|
ok: true,
|
|
302636
302979
|
text
|
|
@@ -302661,10 +303004,7 @@ function makeCmmdForgeRuntimesLifecycleHandler(action) {
|
|
|
302661
303004
|
subject: session.subject,
|
|
302662
303005
|
logPrefix: `forge-runtimes/${action}`
|
|
302663
303006
|
});
|
|
302664
|
-
if (!accessToken) return
|
|
302665
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302666
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302667
|
-
});
|
|
303007
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302668
303008
|
const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
|
|
302669
303009
|
if (!runtimeId) return jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
|
|
302670
303010
|
const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(catch_(() => succeed({}))));
|
|
@@ -302685,10 +303025,7 @@ function makeCmmdForgeRuntimesLifecycleHandler(action) {
|
|
|
302685
303025
|
code: "CMMD_UNAVAILABLE"
|
|
302686
303026
|
}, { status: 503 });
|
|
302687
303027
|
const upstream = upstreamOrError.res;
|
|
302688
|
-
if (upstream.status === 401 || upstream.status === 403) return
|
|
302689
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302690
|
-
message: "CMMD authentication expired. Sign in again to continue."
|
|
302691
|
-
});
|
|
303028
|
+
if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302692
303029
|
const bodyOrError = yield* tryPromise(() => upstream.text()).pipe(map$3((text) => ({
|
|
302693
303030
|
ok: true,
|
|
302694
303031
|
text
|
|
@@ -302721,11 +303058,8 @@ const cmmdForgeRuntimesRecycleRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
|
|
|
302721
303058
|
const cmmdForgeRuntimesUpdateCommitRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/:runtimeId/update-commit", __cmmdForgeRuntimesUpdateCommitHandlerForTests);
|
|
302722
303059
|
const cmmdForgeRuntimesDestroyRouteLayer = add$1("POST", "/api/cmmd/forge-runtimes/:runtimeId/destroy", gen(function* () {
|
|
302723
303060
|
const request = yield* HttpServerRequest;
|
|
302724
|
-
const accessToken = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/destroy");
|
|
302725
|
-
if (!accessToken) return
|
|
302726
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302727
|
-
message: "CMMD authentication is required. Sign in again to continue."
|
|
302728
|
-
});
|
|
303061
|
+
const { session, jwt: accessToken } = yield* makeCmmdProxyAccessTokenEffect("forge-runtimes/destroy");
|
|
303062
|
+
if (!accessToken) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302729
303063
|
const runtimeId = extractIdFromPath(new URL(request.url, "http://localhost").pathname, 2);
|
|
302730
303064
|
if (!runtimeId) return jsonUnsafe({ error: "Runtime ID is required." }, { status: 400 });
|
|
302731
303065
|
const scopedBody = splitCmmdRuntimeOrganizationScope(yield* request.json.pipe(catch_(() => succeed({}))));
|
|
@@ -302746,10 +303080,7 @@ const cmmdForgeRuntimesDestroyRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
|
|
|
302746
303080
|
code: "CMMD_UNAVAILABLE"
|
|
302747
303081
|
}, { status: 503 });
|
|
302748
303082
|
const upstream = upstreamOrError.res;
|
|
302749
|
-
if (upstream.status === 401 || upstream.status === 403) return
|
|
302750
|
-
code: "CMMD_AUTH_REQUIRED",
|
|
302751
|
-
message: "CMMD authentication expired. Sign in again to continue."
|
|
302752
|
-
});
|
|
303083
|
+
if (upstream.status === 401 || upstream.status === 403) return yield* respondCmmdConnectionRequired(session.sessionId);
|
|
302753
303084
|
const bodyOrError = yield* tryPromise(() => upstream.text()).pipe(map$3((text) => ({
|
|
302754
303085
|
ok: true,
|
|
302755
303086
|
text
|
|
@@ -302771,6 +303102,7 @@ const cmmdForgeRuntimesDestroyRouteLayer = add$1("POST", "/api/cmmd/forge-runtim
|
|
|
302771
303102
|
headers: { "content-type": "application/json" }
|
|
302772
303103
|
});
|
|
302773
303104
|
}).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
|
|
303105
|
+
const cmmdProxyRouteLayers = registeredProxyRouteLayers().slice(__cmmdProxyRouteLayersStartIndex);
|
|
302774
303106
|
//#endregion
|
|
302775
303107
|
//#region src/cmmdData/projectTeamProxyRoutes.ts
|
|
302776
303108
|
const cmmdListWorkspaceMembersRouteLayer = registerProxyRoute({
|
|
@@ -304013,6 +304345,103 @@ function recordRuntimeReplicationOutboxDiagnostics(diagnostics, now = Date.now()
|
|
|
304013
304345
|
]).pipe(asVoid);
|
|
304014
304346
|
}
|
|
304015
304347
|
//#endregion
|
|
304348
|
+
//#region src/runtimeReplication/pendingLifecycleIntents.ts
|
|
304349
|
+
/**
|
|
304350
|
+
* The newest moment a person or a turn touched this thread, mirroring the
|
|
304351
|
+
* client's `threadLastActivityAt` over the full thread rather than its shell:
|
|
304352
|
+
* the shell's `latestUserMessageAt` is projected from exactly these messages.
|
|
304353
|
+
*/
|
|
304354
|
+
function readModelThreadLastActivityAt(thread) {
|
|
304355
|
+
const candidates = [
|
|
304356
|
+
...thread.messages.filter((message) => message.role === "user").map((m) => m.createdAt),
|
|
304357
|
+
thread.latestTurn?.requestedAt,
|
|
304358
|
+
thread.latestTurn?.startedAt,
|
|
304359
|
+
thread.latestTurn?.completedAt
|
|
304360
|
+
];
|
|
304361
|
+
let latest = null;
|
|
304362
|
+
let latestTimestamp = Number.NEGATIVE_INFINITY;
|
|
304363
|
+
for (const candidate of candidates) {
|
|
304364
|
+
if (candidate === null || candidate === void 0) continue;
|
|
304365
|
+
const timestamp = Date.parse(candidate);
|
|
304366
|
+
if (timestamp > latestTimestamp) {
|
|
304367
|
+
latest = candidate;
|
|
304368
|
+
latestTimestamp = timestamp;
|
|
304369
|
+
}
|
|
304370
|
+
}
|
|
304371
|
+
return latest;
|
|
304372
|
+
}
|
|
304373
|
+
function intentIsSpent(thread, intent) {
|
|
304374
|
+
const lastActivityAt = readModelThreadLastActivityAt(thread);
|
|
304375
|
+
if (lastActivityAt === null) return false;
|
|
304376
|
+
const activity = Date.parse(lastActivityAt);
|
|
304377
|
+
const requested = Date.parse(intent.requestedAt);
|
|
304378
|
+
return Number.isFinite(activity) && Number.isFinite(requested) && activity > requested;
|
|
304379
|
+
}
|
|
304380
|
+
function commandFor(runtimeId, intent) {
|
|
304381
|
+
const commandId = lifecycleIntentCommandId(runtimeId, intent.threadId, intent.requestedAt);
|
|
304382
|
+
const threadId = ThreadId.make(intent.threadId);
|
|
304383
|
+
return intent.action === "settle" ? {
|
|
304384
|
+
type: "thread.settle",
|
|
304385
|
+
commandId,
|
|
304386
|
+
threadId,
|
|
304387
|
+
settledOverride: "settled"
|
|
304388
|
+
} : {
|
|
304389
|
+
type: "thread.unsettle",
|
|
304390
|
+
commandId,
|
|
304391
|
+
threadId
|
|
304392
|
+
};
|
|
304393
|
+
}
|
|
304394
|
+
const applyOne = fn$1("applyLifecycleIntent")(function* (runtimeId, intent, dependencies) {
|
|
304395
|
+
const base = {
|
|
304396
|
+
runtimeId,
|
|
304397
|
+
threadId: intent.threadId,
|
|
304398
|
+
action: intent.action,
|
|
304399
|
+
requestedAt: intent.requestedAt
|
|
304400
|
+
};
|
|
304401
|
+
const report = (outcome, detail) => dependencies.log({
|
|
304402
|
+
...base,
|
|
304403
|
+
outcome,
|
|
304404
|
+
...detail === void 0 ? {} : { detail }
|
|
304405
|
+
}).pipe(as$3(outcome));
|
|
304406
|
+
const thread = (yield* dependencies.getReadModel()).threads.find((candidate) => candidate.id === intent.threadId);
|
|
304407
|
+
if (thread === void 0) return yield* report("missing-thread");
|
|
304408
|
+
if (intentIsSpent(thread, intent)) return yield* report("spent");
|
|
304409
|
+
return yield* dependencies.dispatch(commandFor(runtimeId, intent)).pipe(flatMap(() => report("applied")), catch_((error) => error._tag === "OrchestrationCommandInvariantError" || error._tag === "OrchestrationCommandPreviouslyRejectedError" ? report("refused", error.detail) : report("failed", error.message)));
|
|
304410
|
+
});
|
|
304411
|
+
/**
|
|
304412
|
+
* One tick: list, apply each, acknowledge everything that got an answer.
|
|
304413
|
+
*
|
|
304414
|
+
* A signed-out owner is not an error to retry into the log every five
|
|
304415
|
+
* minutes; it is a state the desktop leaves when someone signs in, so it is
|
|
304416
|
+
* logged once at info and the tick ends. Any other listing or acknowledgement
|
|
304417
|
+
* failure is returned typed, and the intents stay pending on CMMD.
|
|
304418
|
+
*/
|
|
304419
|
+
function applyPendingLifecycleIntents(input, dependencies) {
|
|
304420
|
+
return gen(function* () {
|
|
304421
|
+
const intents = yield* dependencies.listPending();
|
|
304422
|
+
if (intents.length === 0) return;
|
|
304423
|
+
const answered = [];
|
|
304424
|
+
for (const intent of intents) if ((yield* applyOne(input.runtimeId, intent, dependencies)) !== "failed") answered.push({
|
|
304425
|
+
threadId: intent.threadId,
|
|
304426
|
+
requestedAt: intent.requestedAt
|
|
304427
|
+
});
|
|
304428
|
+
if (answered.length === 0) return;
|
|
304429
|
+
yield* dependencies.acknowledge(answered);
|
|
304430
|
+
}).pipe(catch_((error) => error.kind === "auth" ? logInfo("Lifecycle intents skipped: CMMD sign-in is required.", {
|
|
304431
|
+
runtimeId: input.runtimeId,
|
|
304432
|
+
code: error.code
|
|
304433
|
+
}) : fail(error)));
|
|
304434
|
+
}
|
|
304435
|
+
/**
|
|
304436
|
+
* One structured line per intent, so a row that "came back" after a wake can
|
|
304437
|
+
* be explained from the log: applied, refused by the decider, or spent by
|
|
304438
|
+
* newer activity.
|
|
304439
|
+
*/
|
|
304440
|
+
function logLifecycleIntentOutcome(outcome) {
|
|
304441
|
+
const message = `Lifecycle intent ${outcome.outcome}.`;
|
|
304442
|
+
return outcome.outcome === "refused" || outcome.outcome === "failed" ? logWarning$1(message, outcome) : logInfo(message, outcome);
|
|
304443
|
+
}
|
|
304444
|
+
//#endregion
|
|
304016
304445
|
//#region src/runtimeReplication/processOutboxItem.ts
|
|
304017
304446
|
function publicationMetricAttributes(item, outcome, failure) {
|
|
304018
304447
|
return {
|
|
@@ -304209,6 +304638,31 @@ const RuntimeReplicationLive = effect(RuntimeReplication, gen(function* () {
|
|
|
304209
304638
|
}).pipe(asVoid, catchCause((cause) => logError("Runtime replication reconciliation failed.", { cause })));
|
|
304210
304639
|
const heartbeat = enqueueAll.pipe(repeat(spaced("5 minutes")), forkScoped);
|
|
304211
304640
|
/**
|
|
304641
|
+
* Settle and un-settle requests a person recorded in CMMD while this
|
|
304642
|
+
* runtime was offline. The first tick runs at once, which is the
|
|
304643
|
+
* startup case (this phase starts after the orchestration reactors);
|
|
304644
|
+
* every heartbeat after that picks up requests made while awake. The
|
|
304645
|
+
* tick handles its own expected failures; the supervisor restarts the
|
|
304646
|
+
* schedule if it ever dies between ticks.
|
|
304647
|
+
*/
|
|
304648
|
+
const lifecycleIntents = runSupervisedRepeat({
|
|
304649
|
+
label: "Lifecycle intent applier",
|
|
304650
|
+
work: applyPendingLifecycleIntents({ runtimeId }, {
|
|
304651
|
+
listPending: () => client.listPendingLifecycleIntents({ runtimeId }),
|
|
304652
|
+
acknowledge: (intents) => client.acknowledgeLifecycleIntents({
|
|
304653
|
+
runtimeId,
|
|
304654
|
+
intents
|
|
304655
|
+
}),
|
|
304656
|
+
dispatch: engine.dispatch,
|
|
304657
|
+
getReadModel: engine.getReadModel,
|
|
304658
|
+
log: logLifecycleIntentOutcome
|
|
304659
|
+
}).pipe(catchCause((cause) => logError("Lifecycle intent tick failed.", {
|
|
304660
|
+
cause,
|
|
304661
|
+
runtimeId
|
|
304662
|
+
}))),
|
|
304663
|
+
interval: "5 minutes"
|
|
304664
|
+
}).pipe(forkScoped);
|
|
304665
|
+
/**
|
|
304212
304666
|
* Closes and reports whatever Active Hour interval is currently open,
|
|
304213
304667
|
* every 5 minutes -- the same cadence as the inventory heartbeat, not
|
|
304214
304668
|
* because the two are related, but because it is a reasonable default
|
|
@@ -304227,6 +304681,7 @@ const RuntimeReplicationLive = effect(RuntimeReplication, gen(function* () {
|
|
|
304227
304681
|
reactor,
|
|
304228
304682
|
providerRegistry.streamChanges.pipe(debounce$1("250 millis"), mapEffect$1(() => enqueueAll, { concurrency: 1 }), runDrain, forkScoped),
|
|
304229
304683
|
heartbeat,
|
|
304684
|
+
lifecycleIntents,
|
|
304230
304685
|
activeHourFlush,
|
|
304231
304686
|
gen(function* () {
|
|
304232
304687
|
yield* outbox.recover();
|
|
@@ -313627,7 +314082,7 @@ const MiscRuntimeLayerLive = mergeAll(AnalyticsServiceLayerLive, OpenLive, Serve
|
|
|
313627
314082
|
const RuntimeDependenciesWithoutPullRequestsLive = ReactorLayerLive.pipe(provideMerge(CheckpointingLayerLive), provideMerge(GitLayerLive), provideMerge(OrchestrationLayerLive), provideMerge(ProviderLayerLive), provideMerge(TerminalLayerLive), provideMerge(AgentBrowserManagerLive), provideMerge(mergeAll(ThreadDevRuntimeLive, DevTunnelLive.pipe(provide$1(ThreadDevRuntimeLive)))), provideMerge(PersistenceLayerLive), provideMerge(KeybindingsLive), provideMerge(ProviderRegistryLive), provideMerge(mergeAll(ServerSettingsLive, UsageServiceLive.pipe(provide$1(ServerSettingsLive), provide$1(UsageSessionLookupLive), provide$1(UsageRecordedSourceLive.pipe(provide$1(OrchestrationLayerLive), provide$1(RuntimeReplicationOutboxLive), provide$1(ProviderSessionRuntimeRepositoryLive), provide$1(TextGenerationSessionRepositoryLive)))))), provideMerge(WorkspaceLayerLive), provideMerge(WorkspaceReadinessStateLive), provideMerge(ProjectFaviconResolverLive), provideMerge(RepositoryIdentityResolverLive), provideMerge(ServerEnvironmentLive), provideMerge(AuthLayerLive), provideMerge(ServerSecretStoreLayerLive), provideMerge(mergeAll(CloudRedisCoordinationLive, CloudStateSyncLive.pipe(provide$1(PersistenceLayerLive)))), provideMerge(MiscRuntimeLayerLive));
|
|
313628
314083
|
const RuntimeDependenciesLive = pullRequestServiceFactoryLayer.pipe(provideMerge(RuntimeDependenciesWithoutPullRequestsLive), provideMerge(cmmdProjectIdentityResolverLive.pipe(provide$1(RuntimeDependenciesWithoutPullRequestsLive))), provideMerge(pullRequestProviderRuntimeLive));
|
|
313629
314084
|
const RuntimeServicesLive = ServerRuntimeStartupLive.pipe(provideMerge(RuntimeDependenciesLive));
|
|
313630
|
-
const makeRoutesLayer = 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,
|
|
314085
|
+
const makeRoutesLayer = 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(provide$1(browserApiCorsLayer));
|
|
313631
314086
|
const runServer = launch$1(unwrap(gen(function* () {
|
|
313632
314087
|
const config = yield* ServerConfig;
|
|
313633
314088
|
fixPath({ preferProcessPath: config.forgeCmmdRuntimeMode === true });
|