@cmmd-center/forge 0.13.15 → 0.13.17
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 +258 -836
- package/dist/bin.mjs +228 -806
- package/dist/client/assets/{CanvasPanel-RpD9Eh_S.js → CanvasPanel-uofZ5KUR.js} +2 -2
- package/dist/client/assets/{CompositeItem-DEIBUHJR.js → CompositeItem-C5YSRi5B.js} +2 -2
- package/dist/client/assets/{DiffPanel-D-NIms_l.js → DiffPanel-DBxERq43.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-DwoeNGnH.js → DiffPanel.logic-CVvbOj4s.js} +2 -2
- package/dist/client/assets/DiffPanelShell-3FSe-Ixv.js +2533 -0
- package/dist/client/assets/{DiffWorkerPoolProvider-DHNvSWPo.js → DiffWorkerPoolProvider-DGz1EBXf.js} +9 -9
- package/dist/client/assets/PullRequestCodePanel-BsTzlXhi.js +5 -0
- package/dist/client/assets/{Virtualizer-Cm4G15Gy.js → Virtualizer-BABEZSz9.js} +2 -2
- package/dist/client/assets/{canvasStateStore-NrAxDqvM.js → canvasStateStore-IBP3QM_C.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-BahlX0gF.js → cmmdAuthRedirect-Ck1QfYaS.js} +2 -2
- package/dist/client/assets/index-DBkypII5.js +153 -0
- package/dist/client/assets/index-EZbGVDT4.css +1 -0
- package/dist/client/assets/{popover-Z8Tvl-OD.js → popover-BQaoSlk7.js} +2 -2
- package/dist/client/assets/{src-BU7yHzO9.js → src-Bj8vTcnP.js} +2 -2
- package/dist/client/assets/{toggle-CWYdWYBn.js → toggle-CE2NHkQL.js} +2 -2
- package/dist/client/index.html +11 -11
- package/dist/forge-build.json +1 -1
- package/dist/runtimeBootstrap.cjs +1 -1
- package/dist/runtimeBootstrap.mjs +1 -1
- package/dist/{runtimeControlAuthority-BkVB0uAA.cjs → runtimeControlAuthority-DCitZFTk.cjs} +3 -1
- package/dist/{runtimeControlAuthority-E_kdeD_P.mjs → runtimeControlAuthority-DpRIoWqP.mjs} +3 -1
- package/package.json +1 -1
- package/dist/client/assets/DiffPanelShell-BI5poBl7.js +0 -2532
- package/dist/client/assets/PullRequestCodePanel-apgvV8hi.js +0 -5
- package/dist/client/assets/index-C3pC5t1K.css +0 -1
- package/dist/client/assets/index-DdqgGbOQ.js +0 -154
package/dist/bin.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { a as make$51, i as keys, n as getOption, o as makeWith$1, r as invalida
|
|
|
11
11
|
import { S as layer$9, _ as defaultEscape, a as DeadlockError, b as makeCompiler$1, c as SqlError, d as UnknownError, g as custom, h as make$52, i as ConstraintError, l as SqlSyntaxError, m as SqlClient, n as AuthorizationError, o as LockTimeoutError, r as ConnectionError, s as SerializationError, t as AuthenticationError, u as StatementTimeoutError, v as defaultTransforms, y as fragment } from "./SqlError-BMBkezUO.mjs";
|
|
12
12
|
import { r as wrapper_default, t as Mime_default } from "./Mime-Dq9IoNiV.mjs";
|
|
13
13
|
import { a as diag, c as SpanKind$1, d as TraceFlags, f as ROOT_CONTEXT, i as propagation, l as isSpanContextValid, m as DiagLogLevel, n as init_esm$1, o as context$1, p as createContextKey, r as trace, s as SpanStatusCode, t as esm_exports$1 } from "./esm-wLIF-u3N.mjs";
|
|
14
|
-
import { a as verifyCmmdAuthRuntimeTicket, c as verifyCmmdRuntimeTicket, d as runtimeGrantToken, f as setRuntimeGrantToken, i as sendRuntimeControlHeartbeat, l as verifyCmmdRuntimeTicketRefreshProof, n as bootstrapRuntimeControlAuthorityFromNarrowGrant, o as verifyCmmdClaudeReadinessTicket, p as createReadOnceFileTokenAccessor, r as readRuntimeControlAuthority, s as verifyCmmdClaudeUsageTicket, t as bootstrapRuntimeControlAuthority, u as verifyCmmdScopedRuntimePayload } from "./runtimeControlAuthority-
|
|
14
|
+
import { a as verifyCmmdAuthRuntimeTicket, c as verifyCmmdRuntimeTicket, d as runtimeGrantToken, f as setRuntimeGrantToken, i as sendRuntimeControlHeartbeat, l as verifyCmmdRuntimeTicketRefreshProof, n as bootstrapRuntimeControlAuthorityFromNarrowGrant, o as verifyCmmdClaudeReadinessTicket, p as createReadOnceFileTokenAccessor, r as readRuntimeControlAuthority, s as verifyCmmdClaudeUsageTicket, t as bootstrapRuntimeControlAuthority, u as verifyCmmdScopedRuntimePayload } from "./runtimeControlAuthority-DpRIoWqP.mjs";
|
|
15
15
|
import { n as PtySpawnError, t as PtyAdapter } from "./PTY-BzdbZ0Ym.mjs";
|
|
16
16
|
import { createRequire } from "node:module";
|
|
17
17
|
import * as HE from "node:child_process";
|
|
@@ -25521,160 +25521,6 @@ const WorkspaceEnsureScratchResult = Struct({
|
|
|
25521
25521
|
workspaceRoot: String$1,
|
|
25522
25522
|
title: String$1
|
|
25523
25523
|
});
|
|
25524
|
-
const CodeGraphRelation = Literals([
|
|
25525
|
-
"contains",
|
|
25526
|
-
"imports",
|
|
25527
|
-
"calls",
|
|
25528
|
-
"imports_from",
|
|
25529
|
-
"method",
|
|
25530
|
-
"references",
|
|
25531
|
-
"re_exports",
|
|
25532
|
-
"indirect_call",
|
|
25533
|
-
"dynamic_import",
|
|
25534
|
-
"inherits",
|
|
25535
|
-
"rationale_for",
|
|
25536
|
-
"implements",
|
|
25537
|
-
"cites",
|
|
25538
|
-
"triggers"
|
|
25539
|
-
]);
|
|
25540
|
-
const CodeGraphConfidence = Literals(["EXTRACTED", "INFERRED"]);
|
|
25541
|
-
const CodeGraphEdgeClass = Literals([
|
|
25542
|
-
"containment",
|
|
25543
|
-
"dependency",
|
|
25544
|
-
"behavior"
|
|
25545
|
-
]);
|
|
25546
|
-
/**
|
|
25547
|
-
* Relation to drawn class. Exhaustive over CODE_GRAPH_RELATIONS by construction
|
|
25548
|
-
* — `codeGraph.test.ts` fails if a relation is added without a class.
|
|
25549
|
-
*/
|
|
25550
|
-
const CODE_GRAPH_RELATION_CLASS = {
|
|
25551
|
-
contains: "containment",
|
|
25552
|
-
method: "containment",
|
|
25553
|
-
imports: "dependency",
|
|
25554
|
-
imports_from: "dependency",
|
|
25555
|
-
re_exports: "dependency",
|
|
25556
|
-
dynamic_import: "dependency",
|
|
25557
|
-
inherits: "dependency",
|
|
25558
|
-
implements: "dependency",
|
|
25559
|
-
calls: "behavior",
|
|
25560
|
-
indirect_call: "behavior",
|
|
25561
|
-
references: "behavior",
|
|
25562
|
-
triggers: "behavior",
|
|
25563
|
-
cites: "behavior",
|
|
25564
|
-
rationale_for: "behavior"
|
|
25565
|
-
};
|
|
25566
|
-
const CodeGraphNodeKind = Literals(["file", "symbol"]);
|
|
25567
|
-
/**
|
|
25568
|
-
* One community, positioned.
|
|
25569
|
-
*
|
|
25570
|
-
* Positions are computed server-side and are stable for a given graph build, so
|
|
25571
|
-
* the map does not rearrange itself between openings. A map you have to re-learn
|
|
25572
|
-
* every time is not a map.
|
|
25573
|
-
*/
|
|
25574
|
-
const CodeGraphRegion = Struct({
|
|
25575
|
-
id: NonNegativeInt,
|
|
25576
|
-
label: TrimmedNonEmptyString,
|
|
25577
|
-
nodeCount: PositiveInt,
|
|
25578
|
-
x: Number$1,
|
|
25579
|
-
y: Number$1
|
|
25580
|
-
});
|
|
25581
|
-
/** An aggregated edge between two regions, weighted by how many edges cross. */
|
|
25582
|
-
const CodeGraphRegionLink = Struct({
|
|
25583
|
-
source: NonNegativeInt,
|
|
25584
|
-
target: NonNegativeInt,
|
|
25585
|
-
weight: PositiveInt
|
|
25586
|
-
});
|
|
25587
|
-
/**
|
|
25588
|
-
* The default view: the whole repository as ~120 named regions.
|
|
25589
|
-
*
|
|
25590
|
-
* `truncatedRegions` is not decoration. When a graph has more regions than the
|
|
25591
|
-
* map shows, the surface says so — a view that silently drops a third of the
|
|
25592
|
-
* codebase while looking complete is the failure mode this field exists to
|
|
25593
|
-
* prevent.
|
|
25594
|
-
*/
|
|
25595
|
-
const CodeGraphSummary = Struct({
|
|
25596
|
-
repoLabel: TrimmedNonEmptyString,
|
|
25597
|
-
builtAtCommit: NullOr(String$1),
|
|
25598
|
-
nodeCount: NonNegativeInt,
|
|
25599
|
-
edgeCount: NonNegativeInt,
|
|
25600
|
-
extractedEdgeCount: NonNegativeInt,
|
|
25601
|
-
inferredEdgeCount: NonNegativeInt,
|
|
25602
|
-
regionCount: NonNegativeInt,
|
|
25603
|
-
regions: ArraySchema(CodeGraphRegion),
|
|
25604
|
-
links: ArraySchema(CodeGraphRegionLink),
|
|
25605
|
-
truncatedRegions: NonNegativeInt
|
|
25606
|
-
});
|
|
25607
|
-
/** A node as it appears in a list, a search result, or a neighborhood. */
|
|
25608
|
-
const CodeGraphNodeSummary = Struct({
|
|
25609
|
-
id: TrimmedNonEmptyString,
|
|
25610
|
-
label: TrimmedNonEmptyString,
|
|
25611
|
-
kind: CodeGraphNodeKind,
|
|
25612
|
-
sourceFile: NullOr(String$1),
|
|
25613
|
-
sourceLocation: NullOr(String$1),
|
|
25614
|
-
regionId: NullOr(NonNegativeInt),
|
|
25615
|
-
regionLabel: NullOr(String$1),
|
|
25616
|
-
degree: NonNegativeInt
|
|
25617
|
-
});
|
|
25618
|
-
/** One edge, carrying both the exact relation and the class it is drawn as. */
|
|
25619
|
-
const CodeGraphEdgeView = Struct({
|
|
25620
|
-
source: TrimmedNonEmptyString,
|
|
25621
|
-
target: TrimmedNonEmptyString,
|
|
25622
|
-
relation: CodeGraphRelation,
|
|
25623
|
-
edgeClass: CodeGraphEdgeClass,
|
|
25624
|
-
confidence: CodeGraphConfidence,
|
|
25625
|
-
confidenceScore: Number$1
|
|
25626
|
-
});
|
|
25627
|
-
/**
|
|
25628
|
-
* One node and what surrounds it — the view a person actually works in.
|
|
25629
|
-
*
|
|
25630
|
-
* `truncated` fires when a hub's fan-out exceeds the cap. A god node with
|
|
25631
|
-
* thousands of edges must degrade to "showing 150 of 2,310", never to a frozen
|
|
25632
|
-
* tab or a quietly partial picture.
|
|
25633
|
-
*/
|
|
25634
|
-
const CodeGraphNeighborhood = Struct({
|
|
25635
|
-
root: CodeGraphNodeSummary,
|
|
25636
|
-
nodes: ArraySchema(CodeGraphNodeSummary),
|
|
25637
|
-
edges: ArraySchema(CodeGraphEdgeView),
|
|
25638
|
-
depth: PositiveInt,
|
|
25639
|
-
truncated: Boolean$1,
|
|
25640
|
-
omittedCount: NonNegativeInt
|
|
25641
|
-
});
|
|
25642
|
-
const CodeGraphSearchResult = Struct({
|
|
25643
|
-
nodes: ArraySchema(CodeGraphNodeSummary),
|
|
25644
|
-
truncated: Boolean$1
|
|
25645
|
-
});
|
|
25646
|
-
const CodeGraphSummaryInput = Struct({ cwd: TrimmedNonEmptyString });
|
|
25647
|
-
const CodeGraphNeighborhoodInput = Struct({
|
|
25648
|
-
cwd: TrimmedNonEmptyString,
|
|
25649
|
-
nodeId: TrimmedNonEmptyString,
|
|
25650
|
-
depth: optional$4(PositiveInt)
|
|
25651
|
-
});
|
|
25652
|
-
const CodeGraphSearchInput = Struct({
|
|
25653
|
-
cwd: TrimmedNonEmptyString,
|
|
25654
|
-
query: TrimmedNonEmptyString,
|
|
25655
|
-
limit: optional$4(PositiveInt)
|
|
25656
|
-
});
|
|
25657
|
-
/** Where the extractor writes, relative to the project root. */
|
|
25658
|
-
const CODE_GRAPH_ARTIFACT_PATH = "graphify-out/graph.json";
|
|
25659
|
-
/**
|
|
25660
|
-
* No graph in this checkout, or one that cannot be read.
|
|
25661
|
-
*
|
|
25662
|
-
* Distinct from a read failure on purpose: "not indexed yet" is the normal
|
|
25663
|
-
* first-run state and gets an action, while a malformed or unreadable artifact
|
|
25664
|
-
* is a fault and gets an explanation. Collapsing them would tell a user with a
|
|
25665
|
-
* corrupt file to run a build they have already run.
|
|
25666
|
-
*/
|
|
25667
|
-
var CodeGraphUnavailableError = class extends TaggedErrorClass()("CodeGraphUnavailableError", {
|
|
25668
|
-
reason: Literals([
|
|
25669
|
-
"missing",
|
|
25670
|
-
"unreadable",
|
|
25671
|
-
"malformed",
|
|
25672
|
-
"lfs-pointer"
|
|
25673
|
-
]),
|
|
25674
|
-
message: String$1
|
|
25675
|
-
}) {};
|
|
25676
|
-
/** A node id that is not in this graph — usually a stale link into a rebuilt graph. */
|
|
25677
|
-
var CodeGraphNodeNotFoundError = class extends TaggedErrorClass()("CodeGraphNodeNotFoundError", { nodeId: String$1 }) {};
|
|
25678
25524
|
//#endregion
|
|
25679
25525
|
//#region ../../packages/contracts/src/relay.ts
|
|
25680
25526
|
const RELAY_PROTOCOL_FAMILY = "forge-relay";
|
|
@@ -26055,9 +25901,6 @@ const WS_METHODS = {
|
|
|
26055
25901
|
projectsWriteFile: "projects.writeFile",
|
|
26056
25902
|
projectCheckoutDeletionPreview: "projectCheckoutDeletion.preview",
|
|
26057
25903
|
projectCheckoutDeletionExecute: "projectCheckoutDeletion.execute",
|
|
26058
|
-
codeGraphSummary: "codeGraph.summary",
|
|
26059
|
-
codeGraphNeighborhood: "codeGraph.neighborhood",
|
|
26060
|
-
codeGraphSearch: "codeGraph.search",
|
|
26061
25904
|
workspaceReadFile: "workspace.readFile",
|
|
26062
25905
|
workspaceBeginWriteFile: "workspace.beginWriteFile",
|
|
26063
25906
|
workspaceWriteFileChunk: "workspace.writeFileChunk",
|
|
@@ -26343,21 +26186,6 @@ const WsProjectCheckoutDeletionExecuteRpc = make$30(WS_METHODS.projectCheckoutDe
|
|
|
26343
26186
|
payload: ProjectCheckoutDeletionExecuteInput,
|
|
26344
26187
|
success: ProjectCheckoutDeletionResult
|
|
26345
26188
|
});
|
|
26346
|
-
const WsCodeGraphSummaryRpc = make$30(WS_METHODS.codeGraphSummary, {
|
|
26347
|
-
payload: CodeGraphSummaryInput,
|
|
26348
|
-
success: CodeGraphSummary,
|
|
26349
|
-
error: CodeGraphUnavailableError
|
|
26350
|
-
});
|
|
26351
|
-
const WsCodeGraphNeighborhoodRpc = make$30(WS_METHODS.codeGraphNeighborhood, {
|
|
26352
|
-
payload: CodeGraphNeighborhoodInput,
|
|
26353
|
-
success: CodeGraphNeighborhood,
|
|
26354
|
-
error: Union([CodeGraphUnavailableError, CodeGraphNodeNotFoundError])
|
|
26355
|
-
});
|
|
26356
|
-
const WsCodeGraphSearchRpc = make$30(WS_METHODS.codeGraphSearch, {
|
|
26357
|
-
payload: CodeGraphSearchInput,
|
|
26358
|
-
success: CodeGraphSearchResult,
|
|
26359
|
-
error: CodeGraphUnavailableError
|
|
26360
|
-
});
|
|
26361
26189
|
const WsWorkspaceReadFileRpc = make$30(WS_METHODS.workspaceReadFile, {
|
|
26362
26190
|
payload: BulkTransferReadFileInput,
|
|
26363
26191
|
success: BulkTransferStreamEvent,
|
|
@@ -26807,7 +26635,7 @@ const WsRpcGroup = make$29(WsServerGetConfigRpc, WsServerRefreshProvidersRpc, Ws
|
|
|
26807
26635
|
payload: UsageSummaryInput,
|
|
26808
26636
|
success: UsageSummary,
|
|
26809
26637
|
error: UsageReadError
|
|
26810
|
-
}), WsPullRequestsListRpc, WsPullRequestsListStatsRpc, WsPullRequestsDetailRpc, WsPullRequestsActivityRpc, WsPullRequestsThreadCommentsRpc, WsPullRequestsDiffFileContentsRpc, WsPullRequestsRunActionRpc, WsPullRequestsUpdateRpc, WsPullRequestsCommentRpc, WsPullRequestsUpdateCommentRpc, WsPullRequestsSubmitReviewRpc, WsPullRequestsReplyToThreadRpc, WsPullRequestsSetThreadResolutionRpc, WsPullRequestsSetReactionRpc, WsPullRequestsInvalidateRpc, WsPullRequestsReviewerCandidatesRpc, WsPullRequestsRequestReviewersRpc, WsProjectsSearchContentsRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsProjectCheckoutDeletionPreviewRpc, WsProjectCheckoutDeletionExecuteRpc,
|
|
26638
|
+
}), WsPullRequestsListRpc, WsPullRequestsListStatsRpc, WsPullRequestsDetailRpc, WsPullRequestsActivityRpc, WsPullRequestsThreadCommentsRpc, WsPullRequestsDiffFileContentsRpc, WsPullRequestsRunActionRpc, WsPullRequestsUpdateRpc, WsPullRequestsCommentRpc, WsPullRequestsUpdateCommentRpc, WsPullRequestsSubmitReviewRpc, WsPullRequestsReplyToThreadRpc, WsPullRequestsSetThreadResolutionRpc, WsPullRequestsSetReactionRpc, WsPullRequestsInvalidateRpc, WsPullRequestsReviewerCandidatesRpc, WsPullRequestsRequestReviewersRpc, WsProjectsSearchContentsRpc, WsProjectsSearchEntriesRpc, WsProjectsWriteFileRpc, WsProjectCheckoutDeletionPreviewRpc, WsProjectCheckoutDeletionExecuteRpc, WsWorkspaceReadFileRpc, WsWorkspaceBeginWriteFileRpc, WsWorkspaceWriteFileChunkRpc, WsWorkspaceCommitWriteFileRpc, WsWorkspaceCancelWriteFileRpc, WsShellOpenInEditorRpc, WsSubscribeGitStatusRpc, WsGitPullRpc, WsGitRefreshStatusRpc, WsGitRunStackedActionRpc, WsGitResolvePullRequestRpc, WsGitPreparePullRequestThreadRpc, WsGitListBranchesRpc, WsVcsListRefsRpc, WsVcsRefreshStatusRpc, WsSubscribeVcsStatusRpc, WsVcsPullRpc, WsVcsCreateWorktreeRpc, WsVcsRemoveWorktreeRpc, WsVcsCreateRefRpc, WsVcsSwitchRefRpc, WsVcsInitRpc, WsGitCreateWorktreeRpc, WsGitRemoveWorktreeRpc, WsGitCreateBranchRpc, WsGitCheckoutRpc, WsGitInitRpc, WsFilesystemBrowseRpc, WsProjectsReadFileRpc, WsReviewGetDiffPreviewRpc, WsCloudListRuntimesRpc, WsTerminalOpenRpc, WsTerminalAttachRpc, WsTerminalWriteRpc, WsTerminalResizeRpc, WsTerminalSignalRpc, WsTerminalClearRpc, WsTerminalRestartRpc, WsTerminalCloseRpc, WsBrowserOpenSessionRpc, WsBrowserListSessionsRpc, WsBrowserCloseSessionRpc, WsBrowserGetSessionRpc, WsBrowserCommandRpc, WsBrowserClearBrowsingDataRpc, WsBrowserAttachDisplayRpc, WsBrowserAddDisplayIceCandidateRpc, WsComputerInputRpc, WsDevTunnelRegisterRpc, WsDevTunnelUnregisterRpc, WsDevTunnelListRpc, WsThreadDevRuntimeGetRpc, WsThreadDevRuntimeAllocatePortRpc, WsThreadDevRuntimeReleaseRpc, WsWorkspaceEnvironmentPreflightRpc, WsWorkspaceEnsureScratchRpc, WsSubscribeTerminalEventsRpc, WsSubscribeTerminalMetadataRpc, WsProjectsListEntriesRpc, WsServerDiscoverSourceControlRpc, WsServerReportClientActivityRpc, WsSubscribeBrowserEventsRpc, WsSubscribeServerConfigRpc, WsSubscribeServerLifecycleRpc, WsSubscribeAuthAccessRpc, WsSubscribeWorkspaceReadinessRpc, WsOrchestrationDispatchCommandRpc, WsOrchestrationGetTurnDiffRpc, WsOrchestrationGetFullThreadDiffRpc, WsOrchestrationStreamTurnDiffRpc, WsOrchestrationStreamFullThreadDiffRpc, WsOrchestrationReplayEventsRpc, WsOrchestrationGetArchivedShellSnapshotRpc, WsOrchestrationSubscribeShellRpc, WsOrchestrationSubscribeThreadRpc, make$30(WS_METHODS.assetsCreateUrl, {
|
|
26811
26639
|
payload: AssetsRpcSchemas.createUrl.input,
|
|
26812
26640
|
success: AssetsRpcSchemas.createUrl.output,
|
|
26813
26641
|
error: AssetAccessError
|
|
@@ -31496,21 +31324,6 @@ const RELAY_METHOD_POLICY_BASES = [
|
|
|
31496
31324
|
requiredScope: "runtime.read",
|
|
31497
31325
|
deliveryClass: "read"
|
|
31498
31326
|
},
|
|
31499
|
-
{
|
|
31500
|
-
method: WS_METHODS.codeGraphSummary,
|
|
31501
|
-
requiredScope: "workspace.read",
|
|
31502
|
-
deliveryClass: "read"
|
|
31503
|
-
},
|
|
31504
|
-
{
|
|
31505
|
-
method: WS_METHODS.codeGraphNeighborhood,
|
|
31506
|
-
requiredScope: "workspace.read",
|
|
31507
|
-
deliveryClass: "read"
|
|
31508
|
-
},
|
|
31509
|
-
{
|
|
31510
|
-
method: WS_METHODS.codeGraphSearch,
|
|
31511
|
-
requiredScope: "workspace.read",
|
|
31512
|
-
deliveryClass: "read"
|
|
31513
|
-
},
|
|
31514
31327
|
{
|
|
31515
31328
|
method: WS_METHODS.projectsWriteFile,
|
|
31516
31329
|
requiredScope: "workspace.write",
|
|
@@ -66123,7 +65936,7 @@ function normalizeNumberish(value) {
|
|
|
66123
65936
|
}
|
|
66124
65937
|
//#endregion
|
|
66125
65938
|
//#region package.json
|
|
66126
|
-
var version$1 = "0.13.
|
|
65939
|
+
var version$1 = "0.13.17";
|
|
66127
65940
|
//#endregion
|
|
66128
65941
|
//#region src/sentry.ts
|
|
66129
65942
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -67161,7 +66974,7 @@ function toPersistenceDecodeDefect(operation) {
|
|
|
67161
66974
|
const isPersistenceError = (u) => is$1(PersistenceSqlError)(u) || is$1(PersistenceDecodeError)(u);
|
|
67162
66975
|
//#endregion
|
|
67163
66976
|
//#region src/cmmdConnection/CmmdConnectionStore.ts
|
|
67164
|
-
const cache
|
|
66977
|
+
const cache = /* @__PURE__ */ new Map();
|
|
67165
66978
|
const jwtCache = /* @__PURE__ */ new Map();
|
|
67166
66979
|
const jwtExpiryCache = /* @__PURE__ */ new Map();
|
|
67167
66980
|
const refreshTokenCache = /* @__PURE__ */ new Map();
|
|
@@ -67302,7 +67115,7 @@ const hydrateCommandAccessTokenStore = gen(function* () {
|
|
|
67302
67115
|
session_grant AS "sessionGrant"
|
|
67303
67116
|
FROM command_access_tokens
|
|
67304
67117
|
`.pipe(mapError(toPersistenceSqlError("CommandAccessTokenStore.hydrate:query")))).pipe(mapError(toPersistenceDecodeError("CommandAccessTokenStore.hydrate:decodeRows")));
|
|
67305
|
-
cache
|
|
67118
|
+
cache.clear();
|
|
67306
67119
|
jwtCache.clear();
|
|
67307
67120
|
jwtExpiryCache.clear();
|
|
67308
67121
|
refreshTokenCache.clear();
|
|
@@ -67312,7 +67125,7 @@ const hydrateCommandAccessTokenStore = gen(function* () {
|
|
|
67312
67125
|
try: () => {
|
|
67313
67126
|
for (const row of decoded) {
|
|
67314
67127
|
const sessionId = row.sessionId;
|
|
67315
|
-
cache
|
|
67128
|
+
cache.set(sessionId, decodeSensitiveValue(ACCESS_TOKEN_SCOPE, row.accessToken));
|
|
67316
67129
|
const jwtToken = decryptNullable(JWT_TOKEN_SCOPE, row.jwtToken);
|
|
67317
67130
|
if (jwtToken) jwtCache.set(sessionId, jwtToken);
|
|
67318
67131
|
if (row.jwtExpiresAt) jwtExpiryCache.set(sessionId, row.jwtExpiresAt);
|
|
@@ -67332,7 +67145,7 @@ const hydrateCommandAccessTokenStore = gen(function* () {
|
|
|
67332
67145
|
* Returns `null` when the session has no paired CMMD token.
|
|
67333
67146
|
*/
|
|
67334
67147
|
function readCommandAccessTokenForSession(sessionId) {
|
|
67335
|
-
return cache
|
|
67148
|
+
return cache.get(sessionId) ?? null;
|
|
67336
67149
|
}
|
|
67337
67150
|
const threadSessions = /* @__PURE__ */ new Map();
|
|
67338
67151
|
/**
|
|
@@ -67709,7 +67522,7 @@ const promoteMostRecentOwnerCommandAuthToSession = (sessionId) => gen(function*
|
|
|
67709
67522
|
cmmd_user_identity = excluded.cmmd_user_identity,
|
|
67710
67523
|
updated_at = excluded.updated_at
|
|
67711
67524
|
`.pipe(mapError(toPersistenceSqlError("CommandAccessTokenStore.promoteLatestOwnerAuth:upsert")));
|
|
67712
|
-
cache
|
|
67525
|
+
cache.set(sessionId, accessToken);
|
|
67713
67526
|
if (jwtToken) jwtCache.set(sessionId, jwtToken);
|
|
67714
67527
|
else jwtCache.delete(sessionId);
|
|
67715
67528
|
if (row.jwtExpiresAt) jwtExpiryCache.set(sessionId, row.jwtExpiresAt);
|
|
@@ -67754,7 +67567,7 @@ const setCommandAccessTokenForSession = (sessionId, accessToken) => gen(function
|
|
|
67754
67567
|
access_token = excluded.access_token,
|
|
67755
67568
|
updated_at = excluded.updated_at
|
|
67756
67569
|
`.pipe(mapError(toPersistenceSqlError("CommandAccessTokenStore.set:query")));
|
|
67757
|
-
cache
|
|
67570
|
+
cache.set(sessionId, token);
|
|
67758
67571
|
});
|
|
67759
67572
|
/**
|
|
67760
67573
|
* Remove the PAT for a session from both durable persistence and the in-memory cache.
|
|
@@ -67767,7 +67580,7 @@ const clearCommandAccessTokenForSession = (sessionId) => gen(function* () {
|
|
|
67767
67580
|
forgetCommandAccessTokenCachesForSession(sessionId);
|
|
67768
67581
|
});
|
|
67769
67582
|
function forgetCommandAccessTokenCachesForSession(sessionId) {
|
|
67770
|
-
cache
|
|
67583
|
+
cache.delete(sessionId);
|
|
67771
67584
|
jwtCache.delete(sessionId);
|
|
67772
67585
|
jwtExpiryCache.delete(sessionId);
|
|
67773
67586
|
refreshTokenCache.delete(sessionId);
|
|
@@ -77318,500 +77131,6 @@ const makeSocketProtocol = /* @__PURE__ */ gen(function* () {
|
|
|
77318
77131
|
};
|
|
77319
77132
|
});
|
|
77320
77133
|
//#endregion
|
|
77321
|
-
//#region src/codeGraph/aggregate.ts
|
|
77322
|
-
/**
|
|
77323
|
-
* Turning a 26 MB graph into slices small enough to draw.
|
|
77324
|
-
*
|
|
77325
|
-
* Pure functions over an already-parsed graph, deliberately free of Effect, the
|
|
77326
|
-
* filesystem and the RPC layer, so the interesting parts — capping, ranking,
|
|
77327
|
-
* hub suppression — are testable without a runtime or a fixture file on disk.
|
|
77328
|
-
*
|
|
77329
|
-
* The whole module exists because of one number: this repo's graph is 34,102
|
|
77330
|
-
* nodes and 86,347 edges. Nothing here ever returns more than a few hundred of
|
|
77331
|
-
* either. A view that tries to show everything shows nothing.
|
|
77332
|
-
*/
|
|
77333
|
-
function pushInto(map, key, link) {
|
|
77334
|
-
const existing = map.get(key);
|
|
77335
|
-
if (existing === void 0) {
|
|
77336
|
-
map.set(key, [link]);
|
|
77337
|
-
return;
|
|
77338
|
-
}
|
|
77339
|
-
existing.push(link);
|
|
77340
|
-
}
|
|
77341
|
-
function isKnownRelation(relation) {
|
|
77342
|
-
return Object.hasOwn(CODE_GRAPH_RELATION_CLASS, relation);
|
|
77343
|
-
}
|
|
77344
|
-
/**
|
|
77345
|
-
* Index a parsed graph once so every later query is a map lookup.
|
|
77346
|
-
*
|
|
77347
|
-
* Edges naming a node the artifact does not define are dropped rather than
|
|
77348
|
-
* synthesised. Graphify does emit these — a call into a module outside the scan
|
|
77349
|
-
* root — and inventing a placeholder node for one would put a file in the map
|
|
77350
|
-
* that is not in the repository.
|
|
77351
|
-
*/
|
|
77352
|
-
function indexGraph(raw, repoLabel) {
|
|
77353
|
-
const nodes = /* @__PURE__ */ new Map();
|
|
77354
|
-
for (const node of raw.nodes) nodes.set(node.id, node);
|
|
77355
|
-
const outbound = /* @__PURE__ */ new Map();
|
|
77356
|
-
const inbound = /* @__PURE__ */ new Map();
|
|
77357
|
-
const degree = /* @__PURE__ */ new Map();
|
|
77358
|
-
const unknownRelations = /* @__PURE__ */ new Set();
|
|
77359
|
-
let extractedEdgeCount = 0;
|
|
77360
|
-
let inferredEdgeCount = 0;
|
|
77361
|
-
let edgeCount = 0;
|
|
77362
|
-
for (const link of raw.links) {
|
|
77363
|
-
if (!nodes.has(link.source) || !nodes.has(link.target)) continue;
|
|
77364
|
-
const relation = link.relation ?? "";
|
|
77365
|
-
if (relation !== "" && !isKnownRelation(relation)) {
|
|
77366
|
-
unknownRelations.add(relation);
|
|
77367
|
-
continue;
|
|
77368
|
-
}
|
|
77369
|
-
edgeCount += 1;
|
|
77370
|
-
if (link.confidence === "INFERRED") inferredEdgeCount += 1;
|
|
77371
|
-
else extractedEdgeCount += 1;
|
|
77372
|
-
pushInto(outbound, link.source, link);
|
|
77373
|
-
pushInto(inbound, link.target, link);
|
|
77374
|
-
degree.set(link.source, (degree.get(link.source) ?? 0) + 1);
|
|
77375
|
-
degree.set(link.target, (degree.get(link.target) ?? 0) + 1);
|
|
77376
|
-
}
|
|
77377
|
-
return {
|
|
77378
|
-
repoLabel,
|
|
77379
|
-
builtAtCommit: raw.built_at_commit ?? null,
|
|
77380
|
-
nodes,
|
|
77381
|
-
outbound,
|
|
77382
|
-
inbound,
|
|
77383
|
-
degree,
|
|
77384
|
-
edgeCount,
|
|
77385
|
-
extractedEdgeCount,
|
|
77386
|
-
inferredEdgeCount,
|
|
77387
|
-
unknownRelations: [...unknownRelations].toSorted()
|
|
77388
|
-
};
|
|
77389
|
-
}
|
|
77390
|
-
/**
|
|
77391
|
-
* Deterministic sunflower placement.
|
|
77392
|
-
*
|
|
77393
|
-
* A phyllotaxis spiral rather than a force simulation, for three reasons: it
|
|
77394
|
-
* needs no dependency, it is O(n), and — the one that actually matters — it is
|
|
77395
|
-
* *stable*. The same graph opens to the same picture every time, so the spatial
|
|
77396
|
-
* memory a person builds up survives closing the panel. A force layout reshuffles
|
|
77397
|
-
* on every mount and quietly costs them that.
|
|
77398
|
-
*
|
|
77399
|
-
* Index 0 lands nearest the centre, so ordering regions by size puts the
|
|
77400
|
-
* architectural core where the eye starts.
|
|
77401
|
-
*/
|
|
77402
|
-
function spiralPosition(index, total) {
|
|
77403
|
-
const goldenAngle = Math.PI * (3 - Math.sqrt(5));
|
|
77404
|
-
const radius = total <= 1 ? 0 : Math.sqrt(index / (total - 1));
|
|
77405
|
-
const angle = index * goldenAngle;
|
|
77406
|
-
return {
|
|
77407
|
-
x: .5 + radius * Math.cos(angle) * .44,
|
|
77408
|
-
y: .5 + radius * Math.sin(angle) * .44
|
|
77409
|
-
};
|
|
77410
|
-
}
|
|
77411
|
-
/** Group nodes into their communities, and remember which community each is in. */
|
|
77412
|
-
function accumulateRegions(graph) {
|
|
77413
|
-
const accumulators = /* @__PURE__ */ new Map();
|
|
77414
|
-
const regionOfNode = /* @__PURE__ */ new Map();
|
|
77415
|
-
for (const node of graph.nodes.values()) {
|
|
77416
|
-
const community = node.community;
|
|
77417
|
-
if (community === void 0) continue;
|
|
77418
|
-
regionOfNode.set(node.id, community);
|
|
77419
|
-
const existing = accumulators.get(community);
|
|
77420
|
-
if (existing === void 0) {
|
|
77421
|
-
accumulators.set(community, {
|
|
77422
|
-
id: community,
|
|
77423
|
-
label: node.community_name ?? `Region ${String(community)}`,
|
|
77424
|
-
nodeCount: 1
|
|
77425
|
-
});
|
|
77426
|
-
continue;
|
|
77427
|
-
}
|
|
77428
|
-
existing.nodeCount += 1;
|
|
77429
|
-
}
|
|
77430
|
-
return {
|
|
77431
|
-
ordered: [...accumulators.values()].toSorted((a, b) => b.nodeCount - a.nodeCount || a.id - b.id),
|
|
77432
|
-
regionOfNode
|
|
77433
|
-
};
|
|
77434
|
-
}
|
|
77435
|
-
/**
|
|
77436
|
-
* Collapse node-level edges into weighted links between drawn regions.
|
|
77437
|
-
*
|
|
77438
|
-
* Undirected: "these two areas talk" is the question at this altitude, and
|
|
77439
|
-
* drawing both arcs doubles the ink for no added meaning.
|
|
77440
|
-
*/
|
|
77441
|
-
function aggregateRegionLinks(graph, regionOfNode, shownIds) {
|
|
77442
|
-
const linkWeights = /* @__PURE__ */ new Map();
|
|
77443
|
-
for (const links of graph.outbound.values()) for (const link of links) {
|
|
77444
|
-
const from = regionOfNode.get(link.source);
|
|
77445
|
-
const to = regionOfNode.get(link.target);
|
|
77446
|
-
if (from === void 0 || to === void 0 || from === to) continue;
|
|
77447
|
-
if (!shownIds.has(from) || !shownIds.has(to)) continue;
|
|
77448
|
-
const key = `${String(Math.min(from, to))}:${String(Math.max(from, to))}`;
|
|
77449
|
-
linkWeights.set(key, (linkWeights.get(key) ?? 0) + 1);
|
|
77450
|
-
}
|
|
77451
|
-
return [...linkWeights.entries()].map(([key, weight]) => {
|
|
77452
|
-
const [source, target] = key.split(":");
|
|
77453
|
-
return {
|
|
77454
|
-
source: Number(source),
|
|
77455
|
-
target: Number(target),
|
|
77456
|
-
weight
|
|
77457
|
-
};
|
|
77458
|
-
});
|
|
77459
|
-
}
|
|
77460
|
-
/**
|
|
77461
|
-
* The default view: the repository as named regions.
|
|
77462
|
-
*
|
|
77463
|
-
* Regions come from graphify's own community detection, and their names come
|
|
77464
|
-
* from the community's hub node — so a region is labelled `AIGateway.ts` or
|
|
77465
|
-
* `IStorage`, something a person recognises, rather than "Community 469".
|
|
77466
|
-
*/
|
|
77467
|
-
function buildSummary(graph) {
|
|
77468
|
-
const { ordered, regionOfNode } = accumulateRegions(graph);
|
|
77469
|
-
const shown = ordered.slice(0, 120);
|
|
77470
|
-
const shownIds = new Set(shown.map((region) => region.id));
|
|
77471
|
-
const regions = shown.map((region, index) => {
|
|
77472
|
-
const position = spiralPosition(index, shown.length);
|
|
77473
|
-
return {
|
|
77474
|
-
id: region.id,
|
|
77475
|
-
label: region.label,
|
|
77476
|
-
nodeCount: region.nodeCount,
|
|
77477
|
-
x: position.x,
|
|
77478
|
-
y: position.y
|
|
77479
|
-
};
|
|
77480
|
-
});
|
|
77481
|
-
return {
|
|
77482
|
-
repoLabel: graph.repoLabel,
|
|
77483
|
-
builtAtCommit: graph.builtAtCommit,
|
|
77484
|
-
nodeCount: graph.nodes.size,
|
|
77485
|
-
edgeCount: graph.edgeCount,
|
|
77486
|
-
extractedEdgeCount: graph.extractedEdgeCount,
|
|
77487
|
-
inferredEdgeCount: graph.inferredEdgeCount,
|
|
77488
|
-
regionCount: ordered.length,
|
|
77489
|
-
regions,
|
|
77490
|
-
links: aggregateRegionLinks(graph, regionOfNode, shownIds),
|
|
77491
|
-
truncatedRegions: Math.max(0, ordered.length - shown.length)
|
|
77492
|
-
};
|
|
77493
|
-
}
|
|
77494
|
-
function summariseNode(graph, node) {
|
|
77495
|
-
return {
|
|
77496
|
-
id: node.id,
|
|
77497
|
-
label: node.label ?? node.id,
|
|
77498
|
-
kind: node._callable === true ? "symbol" : "file",
|
|
77499
|
-
sourceFile: node.source_file ?? null,
|
|
77500
|
-
sourceLocation: node.source_location ?? null,
|
|
77501
|
-
regionId: node.community ?? null,
|
|
77502
|
-
regionLabel: node.community_name ?? null,
|
|
77503
|
-
degree: graph.degree.get(node.id) ?? 0
|
|
77504
|
-
};
|
|
77505
|
-
}
|
|
77506
|
-
function toEdgeView(link) {
|
|
77507
|
-
const relation = link.relation ?? "";
|
|
77508
|
-
if (!isKnownRelation(relation)) return null;
|
|
77509
|
-
const confidence = link.confidence === "INFERRED" ? "INFERRED" : "EXTRACTED";
|
|
77510
|
-
return {
|
|
77511
|
-
source: link.source,
|
|
77512
|
-
target: link.target,
|
|
77513
|
-
relation,
|
|
77514
|
-
edgeClass: CODE_GRAPH_RELATION_CLASS[relation],
|
|
77515
|
-
confidence,
|
|
77516
|
-
confidenceScore: link.confidence_score ?? 1
|
|
77517
|
-
};
|
|
77518
|
-
}
|
|
77519
|
-
/**
|
|
77520
|
-
* Pull one node's neighbours into the result; return how many it had to drop.
|
|
77521
|
-
*
|
|
77522
|
-
* Split out of `buildNeighborhood` because the two read differently: the caller
|
|
77523
|
-
* owns *how far to walk*, this owns *what one step collects*. Together they sat
|
|
77524
|
-
* well past the repo's cognitive-complexity gate.
|
|
77525
|
-
*/
|
|
77526
|
-
/** Links touching a node, most-connected neighbour first. */
|
|
77527
|
-
function rankNeighbourLinks(graph, current) {
|
|
77528
|
-
return [...graph.outbound.get(current) ?? [], ...graph.inbound.get(current) ?? []].toSorted((a, b) => {
|
|
77529
|
-
const aOther = a.source === current ? a.target : a.source;
|
|
77530
|
-
const bOther = b.source === current ? b.target : b.source;
|
|
77531
|
-
return (graph.degree.get(bOther) ?? 0) - (graph.degree.get(aOther) ?? 0);
|
|
77532
|
-
});
|
|
77533
|
-
}
|
|
77534
|
-
/** Take a neighbour into the result. False means the budget is spent. */
|
|
77535
|
-
function admitNeighbour(state, id, node) {
|
|
77536
|
-
if (state.included.has(id)) return true;
|
|
77537
|
-
if (state.included.size >= 150) return false;
|
|
77538
|
-
state.included.set(id, node);
|
|
77539
|
-
state.next.push(id);
|
|
77540
|
-
return true;
|
|
77541
|
-
}
|
|
77542
|
-
/** Record an edge once, dropping any relation this build cannot classify. */
|
|
77543
|
-
function recordEdge(state, link) {
|
|
77544
|
-
const edgeKey = `${link.source}>${link.target}:${link.relation ?? ""}`;
|
|
77545
|
-
if (state.seenEdges.has(edgeKey)) return;
|
|
77546
|
-
const view = toEdgeView(link);
|
|
77547
|
-
if (view === null) return;
|
|
77548
|
-
state.seenEdges.add(edgeKey);
|
|
77549
|
-
state.edges.push(view);
|
|
77550
|
-
}
|
|
77551
|
-
/**
|
|
77552
|
-
* Pull one node's neighbours into the result; return how many it had to drop.
|
|
77553
|
-
*
|
|
77554
|
-
* Split out of `buildNeighborhood` because the two read differently: the caller
|
|
77555
|
-
* owns *how far to walk*, this owns *what one step collects*.
|
|
77556
|
-
*/
|
|
77557
|
-
function expandNode(graph, current, state) {
|
|
77558
|
-
let omitted = 0;
|
|
77559
|
-
for (const link of rankNeighbourLinks(graph, current)) {
|
|
77560
|
-
const other = link.source === current ? link.target : link.source;
|
|
77561
|
-
const otherNode = graph.nodes.get(other);
|
|
77562
|
-
if (otherNode === void 0) continue;
|
|
77563
|
-
if (!admitNeighbour(state, other, otherNode)) {
|
|
77564
|
-
omitted += 1;
|
|
77565
|
-
continue;
|
|
77566
|
-
}
|
|
77567
|
-
recordEdge(state, link);
|
|
77568
|
-
}
|
|
77569
|
-
return omitted;
|
|
77570
|
-
}
|
|
77571
|
-
/**
|
|
77572
|
-
* One node and what surrounds it.
|
|
77573
|
-
*
|
|
77574
|
-
* Two caps, and they do different jobs. `CODE_GRAPH_MAX_NEIGHBORS` bounds the
|
|
77575
|
-
* answer so the canvas stays drawable. `CODE_GRAPH_MAX_FANOUT` bounds the
|
|
77576
|
-
* *traversal*: a hub is included as a neighbor but never expanded through, so
|
|
77577
|
-
* one `logger.ts` in the second ring cannot drag the entire repository in
|
|
77578
|
-
* behind it. Without the second cap the first one is reached instantly and the
|
|
77579
|
-
* result is 150 arbitrary nodes rather than the 150 nearest ones.
|
|
77580
|
-
*/
|
|
77581
|
-
function buildNeighborhood(graph, nodeId, requestedDepth) {
|
|
77582
|
-
const root = graph.nodes.get(nodeId);
|
|
77583
|
-
if (root === void 0) return null;
|
|
77584
|
-
const depth = Math.min(Math.max(1, requestedDepth), 2);
|
|
77585
|
-
const included = new Map([[root.id, root]]);
|
|
77586
|
-
const seenEdges = /* @__PURE__ */ new Set();
|
|
77587
|
-
const edges = [];
|
|
77588
|
-
let omittedCount = 0;
|
|
77589
|
-
let frontier = [root.id];
|
|
77590
|
-
for (let level = 0; level < depth; level += 1) {
|
|
77591
|
-
const next = [];
|
|
77592
|
-
for (const current of frontier) {
|
|
77593
|
-
const fanout = graph.degree.get(current) ?? 0;
|
|
77594
|
-
if (current !== root.id && fanout > 200) continue;
|
|
77595
|
-
omittedCount += expandNode(graph, current, {
|
|
77596
|
-
included,
|
|
77597
|
-
seenEdges,
|
|
77598
|
-
edges,
|
|
77599
|
-
next
|
|
77600
|
-
});
|
|
77601
|
-
}
|
|
77602
|
-
frontier = next;
|
|
77603
|
-
if (frontier.length === 0) break;
|
|
77604
|
-
}
|
|
77605
|
-
const nodes = [...included.values()].filter((node) => node.id !== root.id).map((node) => summariseNode(graph, node)).toSorted((a, b) => b.degree - a.degree || a.label.localeCompare(b.label));
|
|
77606
|
-
return {
|
|
77607
|
-
root: summariseNode(graph, root),
|
|
77608
|
-
nodes,
|
|
77609
|
-
edges: edges.filter((edge) => included.has(edge.source) && included.has(edge.target)),
|
|
77610
|
-
depth,
|
|
77611
|
-
truncated: omittedCount > 0,
|
|
77612
|
-
omittedCount
|
|
77613
|
-
};
|
|
77614
|
-
}
|
|
77615
|
-
/**
|
|
77616
|
-
* Rank one node against a query: lower is better, negative means no match.
|
|
77617
|
-
*
|
|
77618
|
-
* A file-path hit ranks last because "the query appears somewhere in this path"
|
|
77619
|
-
* is much weaker evidence than "this thing is called that".
|
|
77620
|
-
*/
|
|
77621
|
-
function matchScore(node, query) {
|
|
77622
|
-
const label = (node.label ?? node.id).toLowerCase();
|
|
77623
|
-
if (label === query) return 0;
|
|
77624
|
-
if (label.startsWith(query)) return 1;
|
|
77625
|
-
if (label.includes(query)) return 2;
|
|
77626
|
-
return (node.source_file ?? "").toLowerCase().includes(query) ? 3 : -1;
|
|
77627
|
-
}
|
|
77628
|
-
/**
|
|
77629
|
-
* Find a node by name or path.
|
|
77630
|
-
*
|
|
77631
|
-
* Entry to this surface is search, not the canvas — you usually arrive already
|
|
77632
|
-
* knowing what you are looking for, and clicking around 34,000 nodes to find it
|
|
77633
|
-
* is not a workflow. Ranking is exact, then prefix, then substring, with degree
|
|
77634
|
-
* breaking ties so the `logger.ts` everything imports outranks a test fixture
|
|
77635
|
-
* that merely shares the word.
|
|
77636
|
-
*/
|
|
77637
|
-
function searchNodes(graph, rawQuery, limit = 40) {
|
|
77638
|
-
const query = rawQuery.trim().toLowerCase();
|
|
77639
|
-
if (query === "") return {
|
|
77640
|
-
nodes: [],
|
|
77641
|
-
truncated: false
|
|
77642
|
-
};
|
|
77643
|
-
const scored = [];
|
|
77644
|
-
for (const node of graph.nodes.values()) {
|
|
77645
|
-
const score = matchScore(node, query);
|
|
77646
|
-
if (score < 0) continue;
|
|
77647
|
-
scored.push({
|
|
77648
|
-
node,
|
|
77649
|
-
score
|
|
77650
|
-
});
|
|
77651
|
-
}
|
|
77652
|
-
const ranked = scored.toSorted((a, b) => a.score - b.score || (graph.degree.get(b.node.id) ?? 0) - (graph.degree.get(a.node.id) ?? 0) || (a.node.label ?? a.node.id).localeCompare(b.node.label ?? b.node.id));
|
|
77653
|
-
const capped = ranked.slice(0, limit);
|
|
77654
|
-
return {
|
|
77655
|
-
nodes: capped.map((entry) => summariseNode(graph, entry.node)),
|
|
77656
|
-
truncated: ranked.length > capped.length
|
|
77657
|
-
};
|
|
77658
|
-
}
|
|
77659
|
-
//#endregion
|
|
77660
|
-
//#region src/codeGraph/graphArtifact.ts
|
|
77661
|
-
/**
|
|
77662
|
-
* Reading `graphify-out/graph.json` off disk, once.
|
|
77663
|
-
*
|
|
77664
|
-
* The artifact is 26 MB here and 40 MB for CMMD's server tree, and parsing it
|
|
77665
|
-
* costs roughly a second. Every panel open would pay that again without a cache,
|
|
77666
|
-
* so one indexed graph is held per project and reused until the file changes.
|
|
77667
|
-
*
|
|
77668
|
-
* Kept free of Effect on purpose: the failure modes worth distinguishing are all
|
|
77669
|
-
* filesystem-shaped, and a plain promise keeps this unit-testable against real
|
|
77670
|
-
* fixtures without constructing a runtime. `ws.ts` wraps it at the boundary.
|
|
77671
|
-
*/
|
|
77672
|
-
const cache = /* @__PURE__ */ new Map();
|
|
77673
|
-
/** Git LFS writes a pointer file that is valid text and useless as a graph. */
|
|
77674
|
-
const LFS_POINTER_PREFIX = "version https://git-lfs.github.com/spec/v1";
|
|
77675
|
-
function codeGraphArtifactPath(cwd) {
|
|
77676
|
-
return path.join(cwd, CODE_GRAPH_ARTIFACT_PATH);
|
|
77677
|
-
}
|
|
77678
|
-
function isRawGraph(value) {
|
|
77679
|
-
if (typeof value !== "object" || value === null) return false;
|
|
77680
|
-
const candidate = value;
|
|
77681
|
-
return Array.isArray(candidate.nodes) && Array.isArray(candidate.links);
|
|
77682
|
-
}
|
|
77683
|
-
/**
|
|
77684
|
-
* Load and index the graph for one project checkout.
|
|
77685
|
-
*
|
|
77686
|
-
* The LFS-pointer case is called out separately rather than folded into
|
|
77687
|
-
* "malformed" because it is the single most likely failure on a fresh clone —
|
|
77688
|
-
* the file is present, tracked, and 133 bytes of metadata. Telling someone their
|
|
77689
|
-
* graph is corrupt when they simply have not run `git lfs pull` sends them to
|
|
77690
|
-
* rebuild something that is fine.
|
|
77691
|
-
*/
|
|
77692
|
-
async function loadIndexedGraph(cwd) {
|
|
77693
|
-
const artifactPath = codeGraphArtifactPath(cwd);
|
|
77694
|
-
let stats;
|
|
77695
|
-
try {
|
|
77696
|
-
stats = await stat(artifactPath);
|
|
77697
|
-
} catch {
|
|
77698
|
-
return {
|
|
77699
|
-
ok: false,
|
|
77700
|
-
failure: {
|
|
77701
|
-
kind: "missing",
|
|
77702
|
-
artifactPath
|
|
77703
|
-
}
|
|
77704
|
-
};
|
|
77705
|
-
}
|
|
77706
|
-
if (!stats.isFile()) return {
|
|
77707
|
-
ok: false,
|
|
77708
|
-
failure: {
|
|
77709
|
-
kind: "missing",
|
|
77710
|
-
artifactPath
|
|
77711
|
-
}
|
|
77712
|
-
};
|
|
77713
|
-
const cached = cache.get(artifactPath);
|
|
77714
|
-
if (cached !== void 0 && cached.mtimeMs === stats.mtimeMs && cached.size === stats.size) return {
|
|
77715
|
-
ok: true,
|
|
77716
|
-
graph: cached.graph
|
|
77717
|
-
};
|
|
77718
|
-
let contents;
|
|
77719
|
-
try {
|
|
77720
|
-
contents = await readFile$1(artifactPath, "utf8");
|
|
77721
|
-
} catch (error) {
|
|
77722
|
-
return {
|
|
77723
|
-
ok: false,
|
|
77724
|
-
failure: {
|
|
77725
|
-
kind: "unreadable",
|
|
77726
|
-
artifactPath,
|
|
77727
|
-
detail: error instanceof Error ? error.message : String(error)
|
|
77728
|
-
}
|
|
77729
|
-
};
|
|
77730
|
-
}
|
|
77731
|
-
if (contents.startsWith(LFS_POINTER_PREFIX)) return {
|
|
77732
|
-
ok: false,
|
|
77733
|
-
failure: {
|
|
77734
|
-
kind: "lfs-pointer",
|
|
77735
|
-
artifactPath
|
|
77736
|
-
}
|
|
77737
|
-
};
|
|
77738
|
-
let parsed;
|
|
77739
|
-
try {
|
|
77740
|
-
parsed = JSON.parse(contents);
|
|
77741
|
-
} catch (error) {
|
|
77742
|
-
return {
|
|
77743
|
-
ok: false,
|
|
77744
|
-
failure: {
|
|
77745
|
-
kind: "malformed",
|
|
77746
|
-
artifactPath,
|
|
77747
|
-
detail: error instanceof Error ? error.message : String(error)
|
|
77748
|
-
}
|
|
77749
|
-
};
|
|
77750
|
-
}
|
|
77751
|
-
if (!isRawGraph(parsed)) return {
|
|
77752
|
-
ok: false,
|
|
77753
|
-
failure: {
|
|
77754
|
-
kind: "malformed",
|
|
77755
|
-
artifactPath,
|
|
77756
|
-
detail: "Expected an object with `nodes` and `links` arrays."
|
|
77757
|
-
}
|
|
77758
|
-
};
|
|
77759
|
-
const graph = indexGraph(parsed, path.basename(cwd));
|
|
77760
|
-
cache.set(artifactPath, {
|
|
77761
|
-
mtimeMs: stats.mtimeMs,
|
|
77762
|
-
size: stats.size,
|
|
77763
|
-
graph
|
|
77764
|
-
});
|
|
77765
|
-
return {
|
|
77766
|
-
ok: true,
|
|
77767
|
-
graph
|
|
77768
|
-
};
|
|
77769
|
-
}
|
|
77770
|
-
//#endregion
|
|
77771
|
-
//#region src/codeGraph/service.ts
|
|
77772
|
-
/**
|
|
77773
|
-
* The code-graph RPC surface, as Effects.
|
|
77774
|
-
*
|
|
77775
|
-
* A thin seam between `ws.ts` and the pure aggregator: load the artifact, turn
|
|
77776
|
-
* a filesystem failure into the tagged error the client can act on, and slice.
|
|
77777
|
-
*
|
|
77778
|
-
* The failure mapping is the substance here. Each reason produces different
|
|
77779
|
-
* advice — pull LFS, run the extractor, report a corrupt file — so collapsing
|
|
77780
|
-
* them into one "graph unavailable" would send people to fix the wrong thing.
|
|
77781
|
-
*/
|
|
77782
|
-
function toUnavailable(failure) {
|
|
77783
|
-
switch (failure.kind) {
|
|
77784
|
-
case "missing": return new CodeGraphUnavailableError({
|
|
77785
|
-
reason: "missing",
|
|
77786
|
-
message: `No code graph in this checkout. Run \`graphify update .\` to build ${failure.artifactPath}.`
|
|
77787
|
-
});
|
|
77788
|
-
case "lfs-pointer": return new CodeGraphUnavailableError({
|
|
77789
|
-
reason: "lfs-pointer",
|
|
77790
|
-
message: `The graph is a Git LFS pointer, not the graph itself. Run \`git lfs pull\` to fetch it.`
|
|
77791
|
-
});
|
|
77792
|
-
case "malformed": return new CodeGraphUnavailableError({
|
|
77793
|
-
reason: "malformed",
|
|
77794
|
-
message: `The graph file could not be parsed: ${failure.detail}`
|
|
77795
|
-
});
|
|
77796
|
-
case "unreadable": return new CodeGraphUnavailableError({
|
|
77797
|
-
reason: "unreadable",
|
|
77798
|
-
message: `The graph file could not be read: ${failure.detail}`
|
|
77799
|
-
});
|
|
77800
|
-
}
|
|
77801
|
-
}
|
|
77802
|
-
function withGraph(cwd, use) {
|
|
77803
|
-
return flatMap(promise(() => loadIndexedGraph(cwd)), (result) => result.ok ? succeed(use(result.graph)) : fail(toUnavailable(result.failure)));
|
|
77804
|
-
}
|
|
77805
|
-
function readCodeGraphSummary(input) {
|
|
77806
|
-
return withGraph(input.cwd, buildSummary);
|
|
77807
|
-
}
|
|
77808
|
-
function readCodeGraphNeighborhood(input) {
|
|
77809
|
-
return flatMap(withGraph(input.cwd, (graph) => buildNeighborhood(graph, input.nodeId, input.depth ?? 1)), (neighborhood) => neighborhood === null ? fail(new CodeGraphNodeNotFoundError({ nodeId: input.nodeId })) : succeed(neighborhood));
|
|
77810
|
-
}
|
|
77811
|
-
function readCodeGraphSearch(input) {
|
|
77812
|
-
return withGraph(input.cwd, (graph) => searchNodes(graph, input.query, input.limit ?? 40));
|
|
77813
|
-
}
|
|
77814
|
-
//#endregion
|
|
77815
77134
|
//#region src/checkpointing/Services/CheckpointDiffQuery.ts
|
|
77816
77135
|
/**
|
|
77817
77136
|
* CheckpointDiffQuery - Service tag for checkpoint diff queries.
|
|
@@ -96683,6 +96002,7 @@ const registerCloudRuntimeForReplicaHydration = gen(function* () {
|
|
|
96683
96002
|
credentialEpoch,
|
|
96684
96003
|
activeTurnCount: 0,
|
|
96685
96004
|
activeSessionCount: 0,
|
|
96005
|
+
acceptingTurns: false,
|
|
96686
96006
|
...forgeGitCommit !== void 0 ? { forgeGitCommit } : {},
|
|
96687
96007
|
forgeServerVersion: installedForgeServerVersion
|
|
96688
96008
|
}),
|
|
@@ -96719,6 +96039,128 @@ const hydrateCloudRuntimeReplica = gen(function* () {
|
|
|
96719
96039
|
return yield* hydrateRuntimeReplica({ expectedRuntimeId: grant.runtimeId }, dependencies);
|
|
96720
96040
|
});
|
|
96721
96041
|
//#endregion
|
|
96042
|
+
//#region src/runtimeDrain/RuntimeDrainState.ts
|
|
96043
|
+
/**
|
|
96044
|
+
* The positive facts this process must observe before it can claim a turn.
|
|
96045
|
+
*
|
|
96046
|
+
* Every entry is required, so adding one here is the whole change: the
|
|
96047
|
+
* derivation below reads this list rather than naming fields, and the record
|
|
96048
|
+
* it indexes cannot be built with a member missing.
|
|
96049
|
+
*/
|
|
96050
|
+
const RUNTIME_EXECUTION_PRECONDITIONS = ["orchestrationEngine", "providerLayer"];
|
|
96051
|
+
/**
|
|
96052
|
+
* The single definition of the accepting-turns fact.
|
|
96053
|
+
*
|
|
96054
|
+
* Exported so test stubs of this service derive it exactly as the live state
|
|
96055
|
+
* does. A stub that recomputed it by hand could disagree with production and
|
|
96056
|
+
* still pass.
|
|
96057
|
+
*/
|
|
96058
|
+
function deriveAcceptingTurns(input) {
|
|
96059
|
+
return RUNTIME_EXECUTION_PRECONDITIONS.every((precondition) => input.preconditions[precondition]) && !input.draining && !input.shutdownRequested;
|
|
96060
|
+
}
|
|
96061
|
+
const initialState = {
|
|
96062
|
+
activeTurns: /* @__PURE__ */ new Set(),
|
|
96063
|
+
activeTurnCount: 0,
|
|
96064
|
+
activeSessionCount: 0,
|
|
96065
|
+
draining: false,
|
|
96066
|
+
drainReason: null,
|
|
96067
|
+
drainTargetImageRef: null,
|
|
96068
|
+
drainTargetImageVersion: null,
|
|
96069
|
+
drainForceRequired: false,
|
|
96070
|
+
preconditions: {
|
|
96071
|
+
orchestrationEngine: false,
|
|
96072
|
+
providerLayer: false
|
|
96073
|
+
},
|
|
96074
|
+
shutdownRequested: false
|
|
96075
|
+
};
|
|
96076
|
+
function snapshotFromState(state) {
|
|
96077
|
+
return {
|
|
96078
|
+
activeTurnCount: state.activeTurnCount,
|
|
96079
|
+
activeSessionCount: state.activeSessionCount,
|
|
96080
|
+
draining: state.draining,
|
|
96081
|
+
drainReason: state.drainReason,
|
|
96082
|
+
drainTargetImageRef: state.drainTargetImageRef,
|
|
96083
|
+
drainTargetImageVersion: state.drainTargetImageVersion,
|
|
96084
|
+
drainForceRequired: state.drainForceRequired,
|
|
96085
|
+
acceptingTurns: deriveAcceptingTurns(state)
|
|
96086
|
+
};
|
|
96087
|
+
}
|
|
96088
|
+
function turnKey(input) {
|
|
96089
|
+
return `${input.threadId}:${input.turnId ?? "unknown"}`;
|
|
96090
|
+
}
|
|
96091
|
+
function normalizeCount(count) {
|
|
96092
|
+
return Number.isFinite(count) ? Math.max(0, Math.floor(count)) : 0;
|
|
96093
|
+
}
|
|
96094
|
+
const makeRuntimeDrainState = gen(function* () {
|
|
96095
|
+
const stateRef = yield* make$50(initialState);
|
|
96096
|
+
const update = (f) => updateAndGet(stateRef, f).pipe(map$3(snapshotFromState));
|
|
96097
|
+
return {
|
|
96098
|
+
beginTurn: (input) => update((state) => {
|
|
96099
|
+
const activeTurns = new Set(state.activeTurns);
|
|
96100
|
+
activeTurns.add(turnKey(input));
|
|
96101
|
+
return {
|
|
96102
|
+
...state,
|
|
96103
|
+
activeTurns,
|
|
96104
|
+
activeTurnCount: activeTurns.size
|
|
96105
|
+
};
|
|
96106
|
+
}),
|
|
96107
|
+
completeTurn: (input) => update((state) => {
|
|
96108
|
+
const activeTurns = new Set(state.activeTurns);
|
|
96109
|
+
activeTurns.delete(turnKey(input));
|
|
96110
|
+
return {
|
|
96111
|
+
...state,
|
|
96112
|
+
activeTurns,
|
|
96113
|
+
activeTurnCount: activeTurns.size
|
|
96114
|
+
};
|
|
96115
|
+
}),
|
|
96116
|
+
clearActiveTurns: update((state) => ({
|
|
96117
|
+
...state,
|
|
96118
|
+
activeTurns: /* @__PURE__ */ new Set(),
|
|
96119
|
+
activeTurnCount: 0
|
|
96120
|
+
})),
|
|
96121
|
+
setActiveSessionCount: (count) => update((state) => ({
|
|
96122
|
+
...state,
|
|
96123
|
+
activeSessionCount: normalizeCount(count)
|
|
96124
|
+
})),
|
|
96125
|
+
reconcileProviderSessions: (sessions) => update((state) => {
|
|
96126
|
+
const activeSessions = sessions.filter((session) => session.status !== "closed");
|
|
96127
|
+
const activeTurns = new Set(activeSessions.flatMap((session) => session.activeTurnId === void 0 ? [] : [turnKey({
|
|
96128
|
+
threadId: session.threadId,
|
|
96129
|
+
turnId: session.activeTurnId
|
|
96130
|
+
})]));
|
|
96131
|
+
return {
|
|
96132
|
+
...state,
|
|
96133
|
+
activeTurns,
|
|
96134
|
+
activeTurnCount: activeTurns.size,
|
|
96135
|
+
activeSessionCount: activeSessions.length
|
|
96136
|
+
};
|
|
96137
|
+
}),
|
|
96138
|
+
applyControlPlaneState: (input) => update((state) => ({
|
|
96139
|
+
...state,
|
|
96140
|
+
draining: input.draining ?? state.draining,
|
|
96141
|
+
drainReason: input.drainReason ?? state.drainReason,
|
|
96142
|
+
drainTargetImageRef: input.drainTargetImageRef ?? state.drainTargetImageRef,
|
|
96143
|
+
drainTargetImageVersion: input.drainTargetImageVersion ?? state.drainTargetImageVersion,
|
|
96144
|
+
drainForceRequired: input.drainForceRequired ?? state.drainForceRequired
|
|
96145
|
+
})),
|
|
96146
|
+
markExecutionPrecondition: (precondition) => update((state) => ({
|
|
96147
|
+
...state,
|
|
96148
|
+
preconditions: {
|
|
96149
|
+
...state.preconditions,
|
|
96150
|
+
[precondition]: true
|
|
96151
|
+
}
|
|
96152
|
+
})),
|
|
96153
|
+
requestShutdown: update((state) => ({
|
|
96154
|
+
...state,
|
|
96155
|
+
shutdownRequested: true
|
|
96156
|
+
})),
|
|
96157
|
+
snapshot: get$6(stateRef).pipe(map$3(snapshotFromState)),
|
|
96158
|
+
isDraining: get$6(stateRef).pipe(map$3((state) => state.draining))
|
|
96159
|
+
};
|
|
96160
|
+
});
|
|
96161
|
+
var RuntimeDrainState = class extends Service$1()("forge/runtimeDrain/RuntimeDrainState") {};
|
|
96162
|
+
const RuntimeDrainStateLive = effect(RuntimeDrainState, makeRuntimeDrainState);
|
|
96163
|
+
//#endregion
|
|
96722
96164
|
//#region src/persistence/Services/LocalAutomations.ts
|
|
96723
96165
|
const LocalAutomationStatus = Literals([
|
|
96724
96166
|
"active",
|
|
@@ -100352,6 +99794,30 @@ const makeCommandGate = gen(function* () {
|
|
|
100352
99794
|
})
|
|
100353
99795
|
};
|
|
100354
99796
|
});
|
|
99797
|
+
/**
|
|
99798
|
+
* Settle the command gate for a finished startup, and report whether commands
|
|
99799
|
+
* are now accepted.
|
|
99800
|
+
*
|
|
99801
|
+
* The success branch is the moment the orchestration engine can take work, so
|
|
99802
|
+
* it is where the engine half of the accepting-turns fact is marked. A failed
|
|
99803
|
+
* startup accepts nothing and must leave the fact untouched: absent must not
|
|
99804
|
+
* read as healthy.
|
|
99805
|
+
*/
|
|
99806
|
+
const settleCommandReadiness = (input) => gen(function* () {
|
|
99807
|
+
if (isFailure(input.startupExit)) {
|
|
99808
|
+
const error = new ServerRuntimeStartupError({
|
|
99809
|
+
message: startupFailureMessage(input.startupExit.cause),
|
|
99810
|
+
cause: input.startupExit.cause
|
|
99811
|
+
});
|
|
99812
|
+
yield* logError("server runtime startup failed", { cause: describeStartupFailure(input.startupExit.cause) });
|
|
99813
|
+
yield* input.commandGate.failCommandReady(error);
|
|
99814
|
+
return false;
|
|
99815
|
+
}
|
|
99816
|
+
yield* logDebug("Accepting commands");
|
|
99817
|
+
yield* input.commandGate.signalCommandReady;
|
|
99818
|
+
yield* input.drainState.markExecutionPrecondition("orchestrationEngine");
|
|
99819
|
+
return true;
|
|
99820
|
+
});
|
|
100355
99821
|
const launchStartupHeartbeat = gen(function* () {
|
|
100356
99822
|
const analytics = yield* AnalyticsService;
|
|
100357
99823
|
const { threadCount, projectCount } = yield* (yield* ProjectionSnapshotQuery).getCounts().pipe(catch_((cause) => logWarning$1("failed to gather startup projection counts for telemetry", { cause }).pipe(as$3({
|
|
@@ -100532,6 +99998,7 @@ const ServerRuntimeStartupLive = effect(ServerRuntimeStartup, gen(function* () {
|
|
|
100532
99998
|
const serverSettings = yield* ServerSettingsService;
|
|
100533
99999
|
const serverEnvironment = yield* ServerEnvironment;
|
|
100534
100000
|
const usage = yield* UsageService;
|
|
100001
|
+
const drainState = yield* RuntimeDrainState;
|
|
100535
100002
|
const commandGate = yield* makeCommandGate;
|
|
100536
100003
|
const httpListening = yield* make$39();
|
|
100537
100004
|
const reactorScope = yield* make$37("sequential");
|
|
@@ -100614,18 +100081,11 @@ const ServerRuntimeStartupLive = effect(ServerRuntimeStartup, gen(function* () {
|
|
|
100614
100081
|
root: true
|
|
100615
100082
|
}));
|
|
100616
100083
|
yield* forkScoped(gen(function* () {
|
|
100617
|
-
|
|
100618
|
-
|
|
100619
|
-
|
|
100620
|
-
|
|
100621
|
-
|
|
100622
|
-
});
|
|
100623
|
-
yield* logError("server runtime startup failed", { cause: describeStartupFailure(startupExit.cause) });
|
|
100624
|
-
yield* commandGate.failCommandReady(error);
|
|
100625
|
-
return;
|
|
100626
|
-
}
|
|
100627
|
-
yield* logDebug("Accepting commands");
|
|
100628
|
-
yield* commandGate.signalCommandReady;
|
|
100084
|
+
if (!(yield* settleCommandReadiness({
|
|
100085
|
+
startupExit: yield* exit(startup),
|
|
100086
|
+
commandGate,
|
|
100087
|
+
drainState
|
|
100088
|
+
}))) return;
|
|
100629
100089
|
yield* logDebug("startup phase: starting the usage scan warm-up");
|
|
100630
100090
|
yield* forkScoped(runUsageScanWarmup({ readSummary: usage.readSummary }));
|
|
100631
100091
|
yield* logDebug("startup phase: waiting for http listener");
|
|
@@ -107173,9 +106633,6 @@ const makeWsRpcLayer = (currentSessionId, currentUserId) => WsRpcGroup.toLayer(g
|
|
|
107173
106633
|
}))), { "rpc.aggregate": "workspace" }),
|
|
107174
106634
|
[WS_METHODS.serverDiscoverSourceControl]: () => observeRpcEffect(WS_METHODS.serverDiscoverSourceControl, discoverSourceControl, { "rpc.aggregate": "server" }),
|
|
107175
106635
|
[WS_METHODS.serverReportClientActivity]: () => observeRpcEffect(WS_METHODS.serverReportClientActivity, void_$1, { "rpc.aggregate": "server" }),
|
|
107176
|
-
[WS_METHODS.codeGraphSummary]: (input) => observeRpcEffect(WS_METHODS.codeGraphSummary, readCodeGraphSummary(input), { "rpc.aggregate": "codeGraph" }),
|
|
107177
|
-
[WS_METHODS.codeGraphNeighborhood]: (input) => observeRpcEffect(WS_METHODS.codeGraphNeighborhood, readCodeGraphNeighborhood(input), { "rpc.aggregate": "codeGraph" }),
|
|
107178
|
-
[WS_METHODS.codeGraphSearch]: (input) => observeRpcEffect(WS_METHODS.codeGraphSearch, readCodeGraphSearch(input), { "rpc.aggregate": "codeGraph" }),
|
|
107179
106636
|
[WS_METHODS.projectsWriteFile]: (input) => observeRpcEffect(WS_METHODS.projectsWriteFile, workspaceFileSystem.writeFile(input).pipe(mapError((cause) => {
|
|
107180
106637
|
return new ProjectWriteFileError({
|
|
107181
106638
|
message: is$1(WorkspacePathOutsideRootError)(cause) ? "Workspace file path must stay within the project root." : "Failed to write workspace file",
|
|
@@ -153208,7 +152665,9 @@ var CodexAppServerManager = class extends EventEmitter$1 {
|
|
|
153208
152665
|
scheduleProviderEgressTokenRefresh(context, delayMs) {
|
|
153209
152666
|
if (context.tokenRefreshTimer) clearTimeout(context.tokenRefreshTimer);
|
|
153210
152667
|
const tokenRefreshTimer = setTimeout(() => {
|
|
153211
|
-
this.handleProviderEgressTokenRefresh(context.session.threadId).catch(() =>
|
|
152668
|
+
this.handleProviderEgressTokenRefresh(context.session.threadId).catch((error) => {
|
|
152669
|
+
this.emitErrorEvent(context, "session/tokenRefreshFailed", error instanceof Error ? error.message : String(error));
|
|
152670
|
+
});
|
|
153212
152671
|
}, delayMs);
|
|
153213
152672
|
tokenRefreshTimer.unref?.();
|
|
153214
152673
|
context.tokenRefreshTimer = tokenRefreshTimer;
|
|
@@ -290471,93 +289930,6 @@ async function maybeRefreshRuntimeProvisioningGrant(input) {
|
|
|
290471
289930
|
return "refreshed";
|
|
290472
289931
|
}
|
|
290473
289932
|
//#endregion
|
|
290474
|
-
//#region src/runtimeDrain/RuntimeDrainState.ts
|
|
290475
|
-
const initialState = {
|
|
290476
|
-
activeTurns: /* @__PURE__ */ new Set(),
|
|
290477
|
-
activeTurnCount: 0,
|
|
290478
|
-
activeSessionCount: 0,
|
|
290479
|
-
draining: false,
|
|
290480
|
-
drainReason: null,
|
|
290481
|
-
drainTargetImageRef: null,
|
|
290482
|
-
drainTargetImageVersion: null,
|
|
290483
|
-
drainForceRequired: false
|
|
290484
|
-
};
|
|
290485
|
-
function snapshotFromState(state) {
|
|
290486
|
-
return {
|
|
290487
|
-
activeTurnCount: state.activeTurnCount,
|
|
290488
|
-
activeSessionCount: state.activeSessionCount,
|
|
290489
|
-
draining: state.draining,
|
|
290490
|
-
drainReason: state.drainReason,
|
|
290491
|
-
drainTargetImageRef: state.drainTargetImageRef,
|
|
290492
|
-
drainTargetImageVersion: state.drainTargetImageVersion,
|
|
290493
|
-
drainForceRequired: state.drainForceRequired
|
|
290494
|
-
};
|
|
290495
|
-
}
|
|
290496
|
-
function turnKey(input) {
|
|
290497
|
-
return `${input.threadId}:${input.turnId ?? "unknown"}`;
|
|
290498
|
-
}
|
|
290499
|
-
function normalizeCount(count) {
|
|
290500
|
-
return Number.isFinite(count) ? Math.max(0, Math.floor(count)) : 0;
|
|
290501
|
-
}
|
|
290502
|
-
const makeRuntimeDrainState = gen(function* () {
|
|
290503
|
-
const stateRef = yield* make$50(initialState);
|
|
290504
|
-
const update = (f) => updateAndGet(stateRef, f).pipe(map$3(snapshotFromState));
|
|
290505
|
-
return {
|
|
290506
|
-
beginTurn: (input) => update((state) => {
|
|
290507
|
-
const activeTurns = new Set(state.activeTurns);
|
|
290508
|
-
activeTurns.add(turnKey(input));
|
|
290509
|
-
return {
|
|
290510
|
-
...state,
|
|
290511
|
-
activeTurns,
|
|
290512
|
-
activeTurnCount: activeTurns.size
|
|
290513
|
-
};
|
|
290514
|
-
}),
|
|
290515
|
-
completeTurn: (input) => update((state) => {
|
|
290516
|
-
const activeTurns = new Set(state.activeTurns);
|
|
290517
|
-
activeTurns.delete(turnKey(input));
|
|
290518
|
-
return {
|
|
290519
|
-
...state,
|
|
290520
|
-
activeTurns,
|
|
290521
|
-
activeTurnCount: activeTurns.size
|
|
290522
|
-
};
|
|
290523
|
-
}),
|
|
290524
|
-
clearActiveTurns: update((state) => ({
|
|
290525
|
-
...state,
|
|
290526
|
-
activeTurns: /* @__PURE__ */ new Set(),
|
|
290527
|
-
activeTurnCount: 0
|
|
290528
|
-
})),
|
|
290529
|
-
setActiveSessionCount: (count) => update((state) => ({
|
|
290530
|
-
...state,
|
|
290531
|
-
activeSessionCount: normalizeCount(count)
|
|
290532
|
-
})),
|
|
290533
|
-
reconcileProviderSessions: (sessions) => update((state) => {
|
|
290534
|
-
const activeSessions = sessions.filter((session) => session.status !== "closed");
|
|
290535
|
-
const activeTurns = new Set(activeSessions.flatMap((session) => session.activeTurnId === void 0 ? [] : [turnKey({
|
|
290536
|
-
threadId: session.threadId,
|
|
290537
|
-
turnId: session.activeTurnId
|
|
290538
|
-
})]));
|
|
290539
|
-
return {
|
|
290540
|
-
...state,
|
|
290541
|
-
activeTurns,
|
|
290542
|
-
activeTurnCount: activeTurns.size,
|
|
290543
|
-
activeSessionCount: activeSessions.length
|
|
290544
|
-
};
|
|
290545
|
-
}),
|
|
290546
|
-
applyControlPlaneState: (input) => update((state) => ({
|
|
290547
|
-
...state,
|
|
290548
|
-
draining: input.draining ?? state.draining,
|
|
290549
|
-
drainReason: input.drainReason ?? state.drainReason,
|
|
290550
|
-
drainTargetImageRef: input.drainTargetImageRef ?? state.drainTargetImageRef,
|
|
290551
|
-
drainTargetImageVersion: input.drainTargetImageVersion ?? state.drainTargetImageVersion,
|
|
290552
|
-
drainForceRequired: input.drainForceRequired ?? state.drainForceRequired
|
|
290553
|
-
})),
|
|
290554
|
-
snapshot: get$6(stateRef).pipe(map$3(snapshotFromState)),
|
|
290555
|
-
isDraining: get$6(stateRef).pipe(map$3((state) => state.draining))
|
|
290556
|
-
};
|
|
290557
|
-
});
|
|
290558
|
-
var RuntimeDrainState = class extends Service$1()("forge/runtimeDrain/RuntimeDrainState") {};
|
|
290559
|
-
const RuntimeDrainStateLive = effect(RuntimeDrainState, makeRuntimeDrainState);
|
|
290560
|
-
//#endregion
|
|
290561
289933
|
//#region src/runtimeDrain/RuntimeDrainReporter.ts
|
|
290562
289934
|
const HEARTBEAT_INTERVAL = seconds(30);
|
|
290563
289935
|
const HEARTBEAT_TICK_TIMEOUT = seconds(60);
|
|
@@ -290615,6 +289987,7 @@ const postRuntimeHeartbeat = (config, snapshot) => promise(async () => {
|
|
|
290615
289987
|
...config,
|
|
290616
289988
|
activeTurnCount: snapshot.activeTurnCount,
|
|
290617
289989
|
activeSessionCount: snapshot.activeSessionCount,
|
|
289990
|
+
acceptingTurns: snapshot.acceptingTurns,
|
|
290618
289991
|
...forgeGitCommit !== void 0 ? { forgeGitCommit } : {},
|
|
290619
289992
|
forgeServerVersion: installedForgeServerVersion
|
|
290620
289993
|
});
|
|
@@ -290723,6 +290096,7 @@ const makeRuntimeDrainReporter = gen(function* () {
|
|
|
290723
290096
|
work: reportOnce,
|
|
290724
290097
|
interval: HEARTBEAT_INTERVAL
|
|
290725
290098
|
}));
|
|
290099
|
+
yield* addFinalizer$2(() => drainState.requestShutdown);
|
|
290726
290100
|
})
|
|
290727
290101
|
};
|
|
290728
290102
|
});
|
|
@@ -290933,6 +290307,7 @@ function decodeCodexRateLimitWindows(raw) {
|
|
|
290933
290307
|
function publicProviderRuntimeError(message) {
|
|
290934
290308
|
return sanitizePublicProviderText(message, { fallback: DEFAULT_PUBLIC_PROVIDER_ERROR });
|
|
290935
290309
|
}
|
|
290310
|
+
const processDomainEvent = (_event) => void_$1;
|
|
290936
290311
|
function isAssistantTextDeltaEvent(event) {
|
|
290937
290312
|
return event.type === "content.delta" && event.payload.streamKind === "assistant_text";
|
|
290938
290313
|
}
|
|
@@ -291726,7 +291101,6 @@ const ProviderRuntimeIngestionLive = effect(ProviderRuntimeIngestionService, fn$
|
|
|
291726
291101
|
yield* runtimeDrainReporter.reportOnce;
|
|
291727
291102
|
}
|
|
291728
291103
|
});
|
|
291729
|
-
const processDomainEvent = (_event) => void_$1;
|
|
291730
291104
|
const processInput = (input) => input.source === "runtime" ? processRuntimeEvent(input.event) : processDomainEvent(input.event);
|
|
291731
291105
|
const processInputSafely = (input) => processInput(input).pipe(catchCause((cause) => {
|
|
291732
291106
|
if (hasInterruptsOnly(cause)) return failCause$1(cause);
|
|
@@ -291777,6 +291151,7 @@ const ProviderRuntimeIngestionLive = effect(ProviderRuntimeIngestionService, fn$
|
|
|
291777
291151
|
return {
|
|
291778
291152
|
start: fn$1("start")(function* () {
|
|
291779
291153
|
yield* reconcileOrphanedRunningSessions();
|
|
291154
|
+
yield* runtimeDrainState.markExecutionPrecondition("providerLayer");
|
|
291780
291155
|
yield* runtimeDrainReporter.start;
|
|
291781
291156
|
yield* forkScoped(runForEach(providerService.streamEvents, (event) => enqueueInput({
|
|
291782
291157
|
source: "runtime",
|
|
@@ -292015,6 +291390,8 @@ const HANDLED_TURN_START_KEY_MAX = 1e4;
|
|
|
292015
291390
|
const HANDLED_TURN_START_KEY_TTL = minutes(30);
|
|
292016
291391
|
const DEFAULT_RUNTIME_MODE = "full-access";
|
|
292017
291392
|
const DEFAULT_THREAD_TITLE = "New thread";
|
|
291393
|
+
const isProviderValidationError = is$1(ProviderValidationError);
|
|
291394
|
+
const isProviderKind = is$1(ProviderKind);
|
|
292018
291395
|
function isPathInsideRoot(candidatePath, rootPath) {
|
|
292019
291396
|
let resolvedCandidate;
|
|
292020
291397
|
let resolvedRoot;
|
|
@@ -292051,6 +291428,38 @@ function resolveExistingWorkspaceCwd(input) {
|
|
|
292051
291428
|
function publicProviderFailureDetail(detail) {
|
|
292052
291429
|
return sanitizePublicProviderText(detail, { fallback: "CMMD is temporarily unavailable. Check the workspace AI connection and retry." }) ?? "CMMD is temporarily unavailable. Check the workspace AI connection and retry.";
|
|
292053
291430
|
}
|
|
291431
|
+
/**
|
|
291432
|
+
* The failure detail a transcript shows, judged on the text and not the envelope.
|
|
291433
|
+
*
|
|
291434
|
+
* Forge writes its own validation copy, so `ProviderValidationError.issue` is
|
|
291435
|
+
* not raw provider output. Every envelope around it hides it, each in its own
|
|
291436
|
+
* way: `Cause.pretty` prints the error tag, and the sanitizer counts
|
|
291437
|
+
* "ProviderValidationError" as a provider leak, so a validation failure
|
|
291438
|
+
* rendered through `Cause.pretty` tripped the guard on its own wrapper. The
|
|
291439
|
+
* `message` getter spells the same tag out in prose. On 2026-09-16 the first of
|
|
291440
|
+
* those replaced "Reconnect the account and try again" with "CMMD is
|
|
291441
|
+
* temporarily unavailable" (#3337).
|
|
291442
|
+
*
|
|
291443
|
+
* The issue still goes through the sanitizer. `ProviderService` builds some
|
|
291444
|
+
* issues from a schema formatter, which echoes the decoded payload, so this is a
|
|
291445
|
+
* narrower input to the same guard rather than a way around it.
|
|
291446
|
+
*/
|
|
291447
|
+
function publicProviderFailureDetailFromError(error) {
|
|
291448
|
+
if (isProviderValidationError(error)) return publicProviderFailureDetail(error.issue);
|
|
291449
|
+
return publicProviderFailureDetail(error instanceof Error ? error.message : String(error));
|
|
291450
|
+
}
|
|
291451
|
+
/**
|
|
291452
|
+
* The same judgement for a failure that arrives as a cause.
|
|
291453
|
+
*
|
|
291454
|
+
* Only the validation branch delegates. A cause carries what a bare error does
|
|
291455
|
+
* not: defects, interrupts, and more than one failure, all of which
|
|
291456
|
+
* `Cause.pretty` renders and `.message` would drop. Squashing every failure into
|
|
291457
|
+
* its message to reach one shared line would lose that.
|
|
291458
|
+
*/
|
|
291459
|
+
function publicProviderFailureDetailFromCause(cause) {
|
|
291460
|
+
const error = squash(cause);
|
|
291461
|
+
return isProviderValidationError(error) ? publicProviderFailureDetailFromError(error) : publicProviderFailureDetail(pretty(cause));
|
|
291462
|
+
}
|
|
292054
291463
|
function canReplaceThreadTitle(currentTitle, titleSeed) {
|
|
292055
291464
|
const trimmedCurrentTitle = currentTitle.trim();
|
|
292056
291465
|
if (trimmedCurrentTitle === DEFAULT_THREAD_TITLE) return true;
|
|
@@ -292206,7 +291615,7 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292206
291615
|
const thread = readModel.threads.find((entry) => entry.id === threadId);
|
|
292207
291616
|
if (!thread) return yield* die$1(/* @__PURE__ */ new Error(`Thread '${threadId}' was not found in read model.`));
|
|
292208
291617
|
const desiredRuntimeMode = thread.runtimeMode;
|
|
292209
|
-
const currentProvider = thread.session?.status !== "stopped" &&
|
|
291618
|
+
const currentProvider = thread.session?.status !== "stopped" && isProviderKind(thread.session?.providerName) ? thread.session.providerName : void 0;
|
|
292210
291619
|
const rawRequestedModelSelection = options?.modelSelection;
|
|
292211
291620
|
const threadProvider = currentProvider ?? thread.modelSelection.provider;
|
|
292212
291621
|
const isStaleRequestedProvider = rawRequestedModelSelection !== void 0 && rawRequestedModelSelection.provider !== threadProvider;
|
|
@@ -292584,7 +291993,7 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292584
291993
|
threadId: event.payload.threadId,
|
|
292585
291994
|
kind: "provider.turn.start.failed",
|
|
292586
291995
|
summary: "Provider turn start failed",
|
|
292587
|
-
detail:
|
|
291996
|
+
detail: publicProviderFailureDetailFromCause(cause),
|
|
292588
291997
|
turnId: null,
|
|
292589
291998
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
292590
291999
|
})));
|
|
@@ -292600,7 +292009,14 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292600
292009
|
turnId: event.payload.turnId ?? null,
|
|
292601
292010
|
createdAt: event.payload.createdAt
|
|
292602
292011
|
});
|
|
292603
|
-
yield* providerService.interruptTurn({ threadId: event.payload.threadId })
|
|
292012
|
+
yield* providerService.interruptTurn({ threadId: event.payload.threadId }).pipe(catchCause((cause) => appendProviderFailureActivity({
|
|
292013
|
+
threadId: event.payload.threadId,
|
|
292014
|
+
kind: "provider.turn.interrupt.failed",
|
|
292015
|
+
summary: "Provider turn interrupt failed",
|
|
292016
|
+
detail: publicProviderFailureDetail(pretty(cause)),
|
|
292017
|
+
turnId: event.payload.turnId ?? null,
|
|
292018
|
+
createdAt: event.payload.createdAt
|
|
292019
|
+
})));
|
|
292604
292020
|
});
|
|
292605
292021
|
const processApprovalResponseRequested = fn$1("processApprovalResponseRequested")(function* (event) {
|
|
292606
292022
|
const staged = peekThreadContinuationSession(event.commandId);
|
|
@@ -292637,7 +292053,7 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292637
292053
|
threadId: event.payload.threadId,
|
|
292638
292054
|
kind: "provider.approval.respond.failed",
|
|
292639
292055
|
summary: "Provider approval response failed",
|
|
292640
|
-
detail: isUnknownPendingApprovalRequestError(cause) ? stalePendingRequestDetail("approval", event.payload.requestId) :
|
|
292056
|
+
detail: isUnknownPendingApprovalRequestError(cause) ? stalePendingRequestDetail("approval", event.payload.requestId) : publicProviderFailureDetailFromCause(cause),
|
|
292641
292057
|
turnId: null,
|
|
292642
292058
|
createdAt: event.payload.createdAt,
|
|
292643
292059
|
requestId: event.payload.requestId
|
|
@@ -292680,7 +292096,7 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292680
292096
|
threadId: event.payload.threadId,
|
|
292681
292097
|
kind: "provider.user-input.respond.failed",
|
|
292682
292098
|
summary: "Provider user input response failed",
|
|
292683
|
-
detail: isUnknownPendingUserInputRequestError(cause) ? stalePendingRequestDetail("user-input", event.payload.requestId) :
|
|
292099
|
+
detail: isUnknownPendingUserInputRequestError(cause) ? stalePendingRequestDetail("user-input", event.payload.requestId) : publicProviderFailureDetailFromCause(cause),
|
|
292684
292100
|
turnId: null,
|
|
292685
292101
|
createdAt: event.payload.createdAt,
|
|
292686
292102
|
requestId: event.payload.requestId
|
|
@@ -292693,8 +292109,7 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292693
292109
|
yield* providerService.stopSession({
|
|
292694
292110
|
threadId: thread.id,
|
|
292695
292111
|
...event.payload.preserveResumeState === true ? { preserveResumeState: true } : {}
|
|
292696
|
-
})
|
|
292697
|
-
yield* setThreadSession({
|
|
292112
|
+
}).pipe(tap(() => setThreadSession({
|
|
292698
292113
|
threadId: thread.id,
|
|
292699
292114
|
session: {
|
|
292700
292115
|
threadId: thread.id,
|
|
@@ -292706,7 +292121,14 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292706
292121
|
updatedAt: now
|
|
292707
292122
|
},
|
|
292708
292123
|
createdAt: now
|
|
292709
|
-
})
|
|
292124
|
+
})), catchCause((cause) => appendProviderFailureActivity({
|
|
292125
|
+
threadId: event.payload.threadId,
|
|
292126
|
+
kind: "provider.session.stop.failed",
|
|
292127
|
+
summary: "Provider session stop failed",
|
|
292128
|
+
detail: publicProviderFailureDetail(pretty(cause)),
|
|
292129
|
+
turnId: null,
|
|
292130
|
+
createdAt: now
|
|
292131
|
+
})));
|
|
292710
292132
|
});
|
|
292711
292133
|
const processDomainEvent = fn$1("processDomainEvent")(function* (event) {
|
|
292712
292134
|
yield* annotateCurrentSpan({
|
|
@@ -292801,7 +292223,7 @@ const ProviderCommandReactorLive = effect(ProviderCommandReactor, gen(function*
|
|
|
292801
292223
|
threadId: event.payload.threadId,
|
|
292802
292224
|
kind: "provider.turn.start.failed",
|
|
292803
292225
|
summary: "Provider turn start cleanup failed",
|
|
292804
|
-
detail:
|
|
292226
|
+
detail: publicProviderFailureDetailFromError(cause),
|
|
292805
292227
|
turnId: null,
|
|
292806
292228
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
292807
292229
|
})
|
|
@@ -298221,7 +297643,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
298221
297643
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
298222
297644
|
*/
|
|
298223
297645
|
function readBakedBuildCommit() {
|
|
298224
|
-
return "
|
|
297646
|
+
return "60c000d9c894e2ef04f90b602ddc8eb49c84980a";
|
|
298225
297647
|
}
|
|
298226
297648
|
async function resolveServerBuildCommit(input) {
|
|
298227
297649
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -321588,7 +321010,7 @@ const PlatformServicesLive = unwrap(gen(function* () {
|
|
|
321588
321010
|
}));
|
|
321589
321011
|
const RuntimeReplicationLayerLive = RuntimeReplicationLive.pipe(provideMerge(RuntimeReplicationClientLive), provideMerge(RuntimeReplicationOutboxLive), provideMerge(ActiveHourMeterLive.pipe(provide$1(RuntimeReplicationOutboxLive))));
|
|
321590
321012
|
const RuntimeDrainLayerLive = RuntimeDrainReporterLive.pipe(provideMerge(RuntimeDrainStateLive));
|
|
321591
|
-
const RuntimeAwareProviderReactorsLive = mergeAll(ProviderRuntimeIngestionLive, ProviderCommandReactorLive).pipe(provide$1(RuntimeDrainLayerLive), provide$1(ClaudeUsageTelemetryLive));
|
|
321013
|
+
const RuntimeAwareProviderReactorsLive = mergeAll(ProviderRuntimeIngestionLive, ProviderCommandReactorLive).pipe(provide$1(RuntimeDrainLayerLive), provideMerge(RuntimeDrainStateLive), provide$1(ClaudeUsageTelemetryLive));
|
|
321592
321014
|
const PipelineWorkerCoordinatorLayerLive = PipelineWorkerCoordinatorLive.pipe(provideMerge(PipelineRunClientLive));
|
|
321593
321015
|
const AgentProtocolReactorLayerLive = AgentProtocolReactorLive.pipe(provideMerge(PipelineRunStoreLive));
|
|
321594
321016
|
const PipelineRunCoordinatorLayerLive = PipelineRunCoordinatorLive.pipe(provideMerge(PipelineProviderAuthorityInstallerLive), provideMerge(PipelineChangeInspectorLive), provideMerge(PipelineContextArtifactStoreLive), provideMerge(PipelineModelPolicyLive), provideMerge(PipelineRunClientLive), provideMerge(PipelineRunStoreLive), provideMerge(PipelineRunWorkspaceAllocatorLive), provideMerge(PipelineStagePolicyLive), provideMerge(PipelineWorkerCoordinatorLayerLive));
|