@runfusion/fusion 0.75.1-beta.1 → 0.75.1-beta.2
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.js +264 -136
- package/dist/child-process-worker.js +138 -38
- package/dist/client/.vite/manifest.json +253 -253
- package/dist/client/assets/{AgentDetailView-CE_7nvDT.js → AgentDetailView-ltOG8f0-.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-DYr3dk5X.js → AgentPermissionPolicyEditor-CC_rrbbG.js} +1 -1
- package/dist/client/assets/{AgentsView-DZoYoiaD.js → AgentsView-DWUdi27N.js} +3 -3
- package/dist/client/assets/{ChatView-BE9zMzYZ.js → ChatView-mFKfoegS.js} +1 -1
- package/dist/client/assets/{CommandCenter-DnLsp4_S.js → CommandCenter-C2wvDq_N.js} +1 -1
- package/dist/client/assets/{DevServerView-CI-3j-lH.js → DevServerView-0MWEJM7o.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-D1ADu0Av.js → DirectoryPicker-BjMPhCdh.js} +1 -1
- package/dist/client/assets/{DocumentsView-CF8y1gob.js → DocumentsView-ckH3rjmd.js} +1 -1
- package/dist/client/assets/{EvalsView-C9vLiM2_.js → EvalsView-NyA644VF.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CX_2Hjh0.js → ExperimentalAgentOnboardingModal-D0ZfbBRN.js} +1 -1
- package/dist/client/assets/{GoalsView-DJIA3k8q.js → GoalsView-Ctt5P_yo.js} +1 -1
- package/dist/client/assets/{InsightsView--TCeutLO.js → InsightsView-NDp0bdNB.js} +1 -1
- package/dist/client/assets/{MemoryView-Btp4m7pK.js → MemoryView-BKbA4Bm4.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-DXdfh-Uf.js → PiExtensionsManager-V3AFWMHm.js} +1 -1
- package/dist/client/assets/{PluginManager-BDFelFY6.js → PluginManager-D88G_TZh.js} +1 -1
- package/dist/client/assets/{PullRequestView-TSNKGSAg.js → PullRequestView-DQQmFFYC.js} +1 -1
- package/dist/client/assets/{ReportModal-DhXMNHDL.js → ReportModal-Clh1S8RF.js} +1 -1
- package/dist/client/assets/{ResearchView-0w30HikQ.js → ResearchView-kxvq4zp5.js} +1 -1
- package/dist/client/assets/SecretsView-Dm0Vk8SA.js +1 -0
- package/dist/client/assets/{SessionTerminal-CF6_uy2u.js → SessionTerminal-DJO4JTEX.js} +1 -1
- package/dist/client/assets/{SettingsModal-BMAPX_7v.js → SettingsModal-BN5mL_ym.js} +1 -1
- package/dist/client/assets/SettingsModal-CTf5voEW.js +21 -0
- package/dist/client/assets/{SettingsTextareaRow-LqXxpJl5.js → SettingsTextareaRow-CvKszqO-.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-D1ZvGOcK.js → SetupWizardModal-D5hVZh1G.js} +2 -2
- package/dist/client/assets/{SkillsView-CfO5B7SO.js → SkillsView-DQVz21w2.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-CjdK9fFS.js → WorkflowNodeEditor-CpKIi6Tb.js} +1 -1
- package/dist/client/assets/{agent-import-generation-DqTzyLOZ.js → agent-import-generation-DGUNF3nd.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-CHkolL_b.js → architectureDiagram-3BPJPVTR-CV83wubP.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-BFRYQi8H.js → blockDiagram-GPEHLZMM-CNQsA3dD.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-D9mMEYbR.js → c4Diagram-AAUBKEIU-CXe7ii5H.js} +1 -1
- package/dist/client/assets/channel-DoX862zl.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-CCv6QaQn.js → chunk-2J33WTMH-BS6W9bWv.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-Bfe22y5T.js → chunk-4BX2VUAB-DbehRhdW.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CwicrA9V.js → chunk-55IACEB6-DMI5SR42.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DlIpTC03.js → chunk-727SXJPM-D1d-GBVj.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CRX4mFVq.js → chunk-AQP2D5EJ-BzO6K3Uf.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DzG-bovU.js → chunk-FMBD7UC4-BVRLV3lK.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-D5F2jtpM.js → chunk-ND2GUHAM-DdWByQfn.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BmSaCwG6.js → chunk-QZHKN3VN-1ia12cRV.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-mb2IeAGN.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-mb2IeAGN.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-BbKTljui.js → cose-bilkent-S5V4N54A-BPDT41HR.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-u0hwXb_T.js → dagre-BM42HDAG-Cktn26EH.js} +1 -1
- package/dist/client/assets/{dashboard-view-BfYZZ9Ms.js → dashboard-view-8o0EUcRX.js} +1 -1
- package/dist/client/assets/{dashboard-view-faKSXA4_.js → dashboard-view-CkCerlVJ.js} +1 -1
- package/dist/client/assets/{dashboard-view-BjPZG2Fv.js → dashboard-view-D_HC4lnr.js} +1 -1
- package/dist/client/assets/{dashboard-view-oCjWDGbW.js → dashboard-view-zd8GxC49.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-Q7towbBl.js → diagram-2AECGRRQ-But4Lvf-.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-UAwBmAxb.js → diagram-5GNKFQAL-2bpQAGFc.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BL1n0pkf.js → diagram-KO2AKTUF-Ckn9Qd1u.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-O-v_IZUJ.js → diagram-LMA3HP47-Bjn8h84N.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-CAYSE2Mz.js → diagram-OG6HWLK6-BI6541hx.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Cr_DgCyp.js → erDiagram-TEJ5UH35-BqMiwHiM.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-TdLzHKPW.js → flowDiagram-I6XJVG4X-Q_SAB10M.js} +1 -1
- package/dist/client/assets/{folder-open-BoddkTkv.js → folder-open-CHiAJbTN.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-CO1ErtJY.js → ganttDiagram-6RSMTGT7-CqWFSfPF.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-C8_Kx0Yh.js → gitGraphDiagram-PVQCEYII-B1o4uEjO.js} +1 -1
- package/dist/client/assets/index-Bdw5eNKV.css +1 -0
- package/dist/client/assets/index-kwRywd9M.js +2767 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-Dd6Zo7Dh.js → infoDiagram-5YYISTIA-BzaMa0c2.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BE9JCLb5.js → ishikawaDiagram-YF4QCWOH-I38yge00.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-B6RIZGDq.js → journeyDiagram-JHISSGLW-WVQSgx4P.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-CPXff-h-.js → kanban-definition-UN3LZRKU-BWtPQ3AH.js} +1 -1
- package/dist/client/assets/{mermaid.core-CbGj7iEw.js → mermaid.core-D1hnBtbi.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DF5LZmsH.js → mindmap-definition-RKZ34NQL-DqiSLkW7.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-Dpy0Xm9T.js → pieDiagram-4H26LBE5-CcgwbdIN.js} +1 -1
- package/dist/client/assets/{puzzle-BZa4U8-N.js → puzzle-BhXUaTQl.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-BTLAQFpz.js → quadrantDiagram-W4KKPZXB-MsqQQfDN.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-DSUV9ySs.js → requirementDiagram-4Y6WPE33-CILGjMMA.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-Fmfn0XDL.js → sankeyDiagram-5OEKKPKP-c14fWbtR.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-_343I_b4.js → sequenceDiagram-3UESZ5HK-BD5bxMom.js} +1 -1
- package/dist/client/assets/{shield-alert-CdJ55UvI.js → shield-alert-C9W2WywS.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-r03dZ5Z0.js → standing-instructions-template-CJdbDSyg.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-C9EbWegm.js → stateDiagram-AJRCARHV-CZ5YqeOn.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-Bmh2GRh6.js → stateDiagram-v2-BHNVJYJU-mdMN-PNX.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-q86S9wyl.js → timeline-definition-PNZ67QCA-DHKay9uj.js} +1 -1
- package/dist/client/assets/{upload-DS9-qtCF.js → upload-DxEwowRU.js} +1 -1
- package/dist/client/assets/{users-DP5Sngeg.js → users-mNFgW_Zd.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-BFq8uIt3.js → vennDiagram-CIIHVFJN-X29K9hWM.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-BL_sLGYI.js → wardley-L42UT6IY-yEoTrfmN.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BEKJJ9Vi.js → wardleyDiagram-YWT4CUSO-ny4k3kG0.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DsvFnlxK.js → xychartDiagram-2RQKCTM6-DC8ODtRJ.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +225 -93
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.d.ts +2 -1
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/SecretsView-DgMu7279.js +0 -1
- package/dist/client/assets/SettingsModal-Dckls6LL.js +0 -21
- package/dist/client/assets/channel-CLdamWm5.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BYWknNX0.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BYWknNX0.js +0 -1
- package/dist/client/assets/index-C7KY0q8Q.js +0 -2767
- package/dist/client/assets/index-DHk_s6rA.css +0 -1
|
@@ -1181,6 +1181,9 @@ function isFusionSiblingBranch(branch) {
|
|
|
1181
1181
|
function resolveEffectiveAutoMerge(task, settings) {
|
|
1182
1182
|
return task.autoMerge ?? settings.autoMerge;
|
|
1183
1183
|
}
|
|
1184
|
+
function hasUserAutoMergeHold(task) {
|
|
1185
|
+
return task.autoMerge === false && task.autoMergeProvenance === "user";
|
|
1186
|
+
}
|
|
1184
1187
|
function allowsAutoMergeProcessing(task, settings) {
|
|
1185
1188
|
return (settings.autoMerge !== false || task.autoMerge === true) && !taskHasManualOpenPullRequest(task);
|
|
1186
1189
|
}
|
|
@@ -63421,7 +63424,7 @@ function rowToTask(row) {
|
|
|
63421
63424
|
executionStartBranch: row.executionStartBranch || void 0,
|
|
63422
63425
|
branch: row.branch || void 0,
|
|
63423
63426
|
autoMerge: row.autoMerge === null ? void 0 : row.autoMerge === 1,
|
|
63424
|
-
autoMergeProvenance: row.autoMergeProvenance === "user" || row.autoMergeProvenance === "legacy-stamp" ? row.autoMergeProvenance : void 0,
|
|
63427
|
+
autoMergeProvenance: row.autoMergeProvenance === "user" || row.autoMergeProvenance === "mission" || row.autoMergeProvenance === "legacy-stamp" ? row.autoMergeProvenance : void 0,
|
|
63425
63428
|
baseCommitSha: row.baseCommitSha || void 0,
|
|
63426
63429
|
scopeOverride: row.scopeOverride ? true : void 0,
|
|
63427
63430
|
scopeOverrideReason: row.scopeOverrideReason || void 0,
|
|
@@ -72937,10 +72940,10 @@ ${feature.acceptanceCriteria}`);
|
|
|
72937
72940
|
Apply the selected Missions header workflow atomically during TaskStore.createTask so newly triaged features land in the intended workflow lane. Duplicate-guard reuses skip this create path, preserving existing duplicate tasks without workflow mutation.
|
|
72938
72941
|
*/
|
|
72939
72942
|
/*
|
|
72940
|
-
FNXC:MissionAutoMerge 2026-
|
|
72941
|
-
An autoMerge:false mission stamps each newly triaged task so its shared branch produces one PR instead of per-task auto-merges. Duplicate reuse intentionally bypasses this create-only override.
|
|
72943
|
+
FNXC:MissionAutoMerge 2026-08-05-22:50:
|
|
72944
|
+
An autoMerge:false mission stamps each newly triaged task as mission policy so its shared branch produces one PR instead of per-task auto-merges. Duplicate reuse intentionally bypasses this create-only override; policy must not impersonate an operator manual-hold choice.
|
|
72942
72945
|
*/
|
|
72943
|
-
...mission?.autoMerge === false ? { autoMerge: false } : {},
|
|
72946
|
+
...mission?.autoMerge === false ? { autoMerge: false, autoMergeProvenance: "mission" } : {},
|
|
72944
72947
|
// FNXC:MissionTaskPrefix 2026-07-26-12:00: thread the mission's optional taskPrefix into TaskCreateInput for distributed id minting.
|
|
72945
72948
|
...mission?.taskPrefix ? { taskPrefix: mission.taskPrefix } : {},
|
|
72946
72949
|
...branchOptions?.workflowId !== void 0 ? { workflowId: branchOptions.workflowId } : {}
|
|
@@ -76118,10 +76121,10 @@ ${feature.acceptanceCriteria}`);
|
|
|
76118
76121
|
}
|
|
76119
76122
|
} : {},
|
|
76120
76123
|
/*
|
|
76121
|
-
FNXC:MissionAutoMerge 2026-
|
|
76122
|
-
An autoMerge:false mission stamps each newly triaged task so its shared branch produces one PR instead of per-task auto-merges. Duplicate reuse intentionally bypasses this create-only override.
|
|
76124
|
+
FNXC:MissionAutoMerge 2026-08-05-22:50:
|
|
76125
|
+
An autoMerge:false mission stamps each newly triaged task as mission policy so its shared branch produces one PR instead of per-task auto-merges. Duplicate reuse intentionally bypasses this create-only override; policy must not impersonate an operator manual-hold choice.
|
|
76123
76126
|
*/
|
|
76124
|
-
...mission?.autoMerge === false ? { autoMerge: false } : {},
|
|
76127
|
+
...mission?.autoMerge === false ? { autoMerge: false, autoMergeProvenance: "mission" } : {},
|
|
76125
76128
|
// FNXC:MissionTaskPrefix 2026-07-26-12:00: thread the mission's optional taskPrefix into TaskCreateInput so the distributed allocator mints ERR-N (etc.) instead of the project prefix.
|
|
76126
76129
|
...mission?.taskPrefix ? { taskPrefix: mission.taskPrefix } : {},
|
|
76127
76130
|
...branchOptions?.workflowId !== void 0 ? { workflowId: branchOptions.workflowId } : {}
|
|
@@ -86472,7 +86475,9 @@ async function _createTaskInternalBackendImpl(store, input, title, resolvedWorkf
|
|
|
86472
86475
|
sourceMetadata: withTaskBranchContextInSourceMetadata(input.source?.sourceMetadata, input.branchContext),
|
|
86473
86476
|
branchContext: input.branchContext,
|
|
86474
86477
|
autoMerge: input.autoMerge,
|
|
86475
|
-
|
|
86478
|
+
// FNXC:SharedBranchMemberHold 2026-08-05-22:50: trusted mission creation
|
|
86479
|
+
// preserves policy provenance; operator/API create requests retain user provenance.
|
|
86480
|
+
autoMergeProvenance: input.autoMerge === void 0 ? void 0 : input.autoMergeProvenance ?? "user",
|
|
86476
86481
|
// FNXC:CodingIdeasWorkflow 2026-07-05-19:45: land the task in its
|
|
86477
86482
|
// workflow's manual intake column (e.g. Coding (Ideas) → "ideas") when
|
|
86478
86483
|
// no explicit column is given (main FN-7591 parity).
|
|
@@ -127350,6 +127355,7 @@ var init_task_timing = __esm({
|
|
|
127350
127355
|
});
|
|
127351
127356
|
|
|
127352
127357
|
// ../core/src/session-identity-registry.ts
|
|
127358
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
127353
127359
|
import { resolve as resolve21 } from "node:path";
|
|
127354
127360
|
import { realpathSync as realpathSync5 } from "node:fs";
|
|
127355
127361
|
function getRegistry() {
|
|
@@ -127361,6 +127367,16 @@ function getRegistry() {
|
|
|
127361
127367
|
}
|
|
127362
127368
|
return registry3;
|
|
127363
127369
|
}
|
|
127370
|
+
function getActiveInvocationStorage() {
|
|
127371
|
+
const holder = globalThis;
|
|
127372
|
+
const existing = holder[ACTIVE_INVOCATION_KEY];
|
|
127373
|
+
if (existing instanceof AsyncLocalStorage) {
|
|
127374
|
+
return existing;
|
|
127375
|
+
}
|
|
127376
|
+
const storage = new AsyncLocalStorage();
|
|
127377
|
+
holder[ACTIVE_INVOCATION_KEY] = storage;
|
|
127378
|
+
return storage;
|
|
127379
|
+
}
|
|
127364
127380
|
function canonicalizeCwd(cwd) {
|
|
127365
127381
|
const resolved = resolve21(cwd);
|
|
127366
127382
|
try {
|
|
@@ -127388,8 +127404,13 @@ function registerFusionSessionIdentity(cwd, identity) {
|
|
|
127388
127404
|
};
|
|
127389
127405
|
}
|
|
127390
127406
|
function resolveFusionSessionPrincipal(cwd) {
|
|
127407
|
+
const canonicalCwd = canonicalizeCwd(cwd);
|
|
127408
|
+
const activeInvocation = getActiveInvocationStorage().getStore();
|
|
127409
|
+
if (activeInvocation?.cwdKeys.has(canonicalCwd)) {
|
|
127410
|
+
return { kind: "agent", identity: activeInvocation.identity };
|
|
127411
|
+
}
|
|
127391
127412
|
const registry3 = getRegistry();
|
|
127392
|
-
const list = registry3.get(
|
|
127413
|
+
const list = registry3.get(canonicalCwd);
|
|
127393
127414
|
if (!list || list.length === 0) {
|
|
127394
127415
|
return { kind: "operator" };
|
|
127395
127416
|
}
|
|
@@ -127398,14 +127419,24 @@ function resolveFusionSessionPrincipal(cwd) {
|
|
|
127398
127419
|
}
|
|
127399
127420
|
return { kind: "ambiguous", identities: [...list] };
|
|
127400
127421
|
}
|
|
127422
|
+
function runWithFusionSessionIdentity(cwdKeys, identity, callback) {
|
|
127423
|
+
const invocation = {
|
|
127424
|
+
identity: { ...identity, registeredAt: Date.now() },
|
|
127425
|
+
cwdKeys: new Set(cwdKeys.map(canonicalizeCwd))
|
|
127426
|
+
};
|
|
127427
|
+
return getActiveInvocationStorage().run(invocation, callback);
|
|
127428
|
+
}
|
|
127401
127429
|
function __clearFusionSessionIdentityRegistryForTests() {
|
|
127402
|
-
|
|
127430
|
+
const holder = globalThis;
|
|
127431
|
+
holder[REGISTRY_KEY] = /* @__PURE__ */ new Map();
|
|
127432
|
+
holder[ACTIVE_INVOCATION_KEY] = new AsyncLocalStorage();
|
|
127403
127433
|
}
|
|
127404
|
-
var REGISTRY_KEY;
|
|
127434
|
+
var REGISTRY_KEY, ACTIVE_INVOCATION_KEY;
|
|
127405
127435
|
var init_session_identity_registry = __esm({
|
|
127406
127436
|
"../core/src/session-identity-registry.ts"() {
|
|
127407
127437
|
"use strict";
|
|
127408
127438
|
REGISTRY_KEY = "__FUSION_SESSION_IDENTITY_REGISTRY_V1__";
|
|
127439
|
+
ACTIVE_INVOCATION_KEY = "__FUSION_SESSION_IDENTITY_ACTIVE_INVOCATION_V1__";
|
|
127409
127440
|
}
|
|
127410
127441
|
});
|
|
127411
127442
|
|
|
@@ -128376,6 +128407,7 @@ __export(src_exports, {
|
|
|
128376
128407
|
hasRoleOverrides: () => hasRoleOverrides,
|
|
128377
128408
|
hasSyncPassphraseConfigured: () => hasSyncPassphraseConfigured,
|
|
128378
128409
|
hasTitleIdDrift: () => hasTitleIdDrift,
|
|
128410
|
+
hasUserAutoMergeHold: () => hasUserAutoMergeHold,
|
|
128379
128411
|
hashWorkflowIr: () => hashWorkflowIr,
|
|
128380
128412
|
healSchemaDrift: () => healSchemaDrift,
|
|
128381
128413
|
importMcpServersJson: () => importMcpServersJson,
|
|
@@ -128836,6 +128868,7 @@ __export(src_exports, {
|
|
|
128836
128868
|
runMemoryBackupCommand: () => runMemoryBackupCommand,
|
|
128837
128869
|
runReconciliationAbort: () => runReconciliationAbort,
|
|
128838
128870
|
runScheduledEvalBatch: () => runScheduledEvalBatch,
|
|
128871
|
+
runWithFusionSessionIdentity: () => runWithFusionSessionIdentity,
|
|
128839
128872
|
sanitizeBranchSegment: () => sanitizeBranchSegment,
|
|
128840
128873
|
sanitizeCliAgentSettings: () => sanitizeCliAgentSettings,
|
|
128841
128874
|
sanitizeCliAgentsSettings: () => sanitizeCliAgentsSettings,
|
|
@@ -158234,6 +158267,7 @@ import { existsSync as existsSync49, readFileSync as readFileSync16, realpathSyn
|
|
|
158234
158267
|
import { exec as exec11, execFile as execFile9 } from "node:child_process";
|
|
158235
158268
|
import { promisify as promisify15 } from "node:util";
|
|
158236
158269
|
import { createRequire as createRequire5 } from "node:module";
|
|
158270
|
+
import { randomUUID as randomUUID42 } from "node:crypto";
|
|
158237
158271
|
import { basename as basename16, dirname as dirname24, join as join59, relative as relative8, isAbsolute as isAbsolute10, resolve as resolve30 } from "node:path";
|
|
158238
158272
|
import {
|
|
158239
158273
|
createAgentSession,
|
|
@@ -159938,7 +159972,8 @@ async function createFnAgent2(options) {
|
|
|
159938
159972
|
});
|
|
159939
159973
|
};
|
|
159940
159974
|
const sessionIdentity = (() => {
|
|
159941
|
-
const
|
|
159975
|
+
const namedAgentId = options.actionGateContext?.agentId ?? options.permanentAgentGating?.requester?.actorId;
|
|
159976
|
+
const principalAgentId = namedAgentId ?? `engine-session-${randomUUID42()}`;
|
|
159942
159977
|
const principalAgentName = options.actionGateContext?.agentName ?? options.permanentAgentGating?.requester?.actorName;
|
|
159943
159978
|
return {
|
|
159944
159979
|
agentId: principalAgentId,
|
|
@@ -159950,6 +159985,14 @@ async function createFnAgent2(options) {
|
|
|
159950
159985
|
const sessionIdentityKeys = [...new Set([options.cwd, resolvedProjectRoot].filter((key) => Boolean(key)))];
|
|
159951
159986
|
const attachSessionIdentity = (session) => {
|
|
159952
159987
|
const identityDisposers = sessionIdentityKeys.map((key) => registerFusionSessionIdentity(key, sessionIdentity));
|
|
159988
|
+
const sessionInvocations = session;
|
|
159989
|
+
const wrapInvocation = (methodName) => {
|
|
159990
|
+
const original = sessionInvocations[methodName];
|
|
159991
|
+
if (typeof original !== "function") return;
|
|
159992
|
+
sessionInvocations[methodName] = (...args) => runWithFusionSessionIdentity(sessionIdentityKeys, sessionIdentity, () => original.apply(session, args));
|
|
159993
|
+
};
|
|
159994
|
+
wrapInvocation("prompt");
|
|
159995
|
+
wrapInvocation("promptWithFallback");
|
|
159953
159996
|
const disposeBeforeIdentity = typeof session.dispose === "function" ? session.dispose.bind(session) : () => void 0;
|
|
159954
159997
|
session.dispose = async () => {
|
|
159955
159998
|
for (const disposeIdentity of identityDisposers) {
|
|
@@ -162745,10 +162788,11 @@ function createMergeAttemptHandler(deps) {
|
|
|
162745
162788
|
);
|
|
162746
162789
|
};
|
|
162747
162790
|
}
|
|
162748
|
-
function createMergeGateHandler() {
|
|
162791
|
+
function createMergeGateHandler(deps = {}) {
|
|
162749
162792
|
return async (_node, ctx) => {
|
|
162750
162793
|
const settingsAutoMerge = ctx.settings?.autoMerge;
|
|
162751
|
-
const
|
|
162794
|
+
const settings = { autoMerge: settingsAutoMerge ?? true };
|
|
162795
|
+
const autoMerge = !hasUserAutoMergeHold(ctx.task) && (await deps.isLiveSharedBranchMember?.(ctx.task, settings) === true || ctx.task.autoMerge !== false && settings.autoMerge !== false);
|
|
162752
162796
|
return {
|
|
162753
162797
|
outcome: "success",
|
|
162754
162798
|
value: autoMerge ? "auto-on" : "auto-off"
|
|
@@ -162758,6 +162802,7 @@ function createMergeGateHandler() {
|
|
|
162758
162802
|
var init_merge_runner = __esm({
|
|
162759
162803
|
"../engine/src/workflow-node-runners/merge-runner.ts"() {
|
|
162760
162804
|
"use strict";
|
|
162805
|
+
init_src2();
|
|
162761
162806
|
init_workflow_merge_nodes();
|
|
162762
162807
|
}
|
|
162763
162808
|
});
|
|
@@ -163101,7 +163146,7 @@ function createDefaultNodeHandlers(seams, runCustomNode, deps) {
|
|
|
163101
163146
|
"parse-steps": parseSteps,
|
|
163102
163147
|
code: createCodeNodeHandler(deps?.runCode),
|
|
163103
163148
|
notify: createNotifyHandler(deps?.notifyDispatch),
|
|
163104
|
-
"merge-gate": createMergeGateHandler(),
|
|
163149
|
+
"merge-gate": createMergeGateHandler({ isLiveSharedBranchMember: deps?.isLiveSharedBranchMember }),
|
|
163105
163150
|
"merge-attempt": createMergeAttemptHandler({
|
|
163106
163151
|
primitives: deps?.primitives,
|
|
163107
163152
|
seams,
|
|
@@ -169712,7 +169757,7 @@ var init_goal_anchoring_audit = __esm({
|
|
|
169712
169757
|
// ../engine/src/agent-tools.ts
|
|
169713
169758
|
import { appendFile as appendFile3, mkdir as mkdir26, readFile as readFile34, readdir as readdir9, realpath, stat as stat9, writeFile as writeFile24 } from "node:fs/promises";
|
|
169714
169759
|
import { existsSync as existsSync52 } from "node:fs";
|
|
169715
|
-
import { createHash as createHash19, randomUUID as
|
|
169760
|
+
import { createHash as createHash19, randomUUID as randomUUID43 } from "node:crypto";
|
|
169716
169761
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
169717
169762
|
import { extname as extname3, isAbsolute as isAbsolute13, join as join64, relative as relative11, resolve as resolve33, sep as sep9 } from "node:path";
|
|
169718
169763
|
import { Type as Type2 } from "@earendil-works/pi-ai";
|
|
@@ -170358,7 +170403,7 @@ function createTaskCreateTool(store, provenance, options) {
|
|
|
170358
170403
|
toType: "user",
|
|
170359
170404
|
type: "agent-to-user",
|
|
170360
170405
|
content: `Task proposal awaiting validation: ${title}`,
|
|
170361
|
-
metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey:
|
|
170406
|
+
metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey: randomUUID43(), taskId: options.sourceTaskId, proposedTask: { title, description: params.description, priority: params.priority, workflowId: params.workflow_id, dependencies: params.dependencies } }
|
|
170362
170407
|
});
|
|
170363
170408
|
return { content: [{ type: "text", text: "Task proposal submitted to the operator for validation; no task was created." }], details: { proposed: true } };
|
|
170364
170409
|
}
|
|
@@ -194766,7 +194811,8 @@ var WorkflowGraphExecutor = class {
|
|
|
194766
194811
|
parseSteps: deps.parseStepsDeps,
|
|
194767
194812
|
runCode: deps.runCode,
|
|
194768
194813
|
notifyDispatch: deps.notifyDispatch,
|
|
194769
|
-
prNodes: deps.prNodes
|
|
194814
|
+
prNodes: deps.prNodes,
|
|
194815
|
+
isLiveSharedBranchMember: deps.isLiveSharedBranchMember
|
|
194770
194816
|
}),
|
|
194771
194817
|
...deps.runnerRegistry?.toHandlers() ?? {},
|
|
194772
194818
|
...deps.handlers ?? {}
|
|
@@ -196009,6 +196055,10 @@ var WorkflowGraphTaskRunner = class {
|
|
|
196009
196055
|
runCode: this.deps.runCode,
|
|
196010
196056
|
notifyDispatch: this.deps.notifyDispatch,
|
|
196011
196057
|
prNodes: this.deps.prNodes,
|
|
196058
|
+
// FNXC:SharedBranchMemberHold 2026-08-06-00:24: carry the executor's
|
|
196059
|
+
// live group resolver into the graph merge gate; omitting it turns
|
|
196060
|
+
// mission-policy members into manual holds before integration.
|
|
196061
|
+
isLiveSharedBranchMember: this.deps.isLiveSharedBranchMember,
|
|
196012
196062
|
/*
|
|
196013
196063
|
FNXC:WorkflowResume 2026-06-29-08:49:
|
|
196014
196064
|
Production graph runs must fetch live task steps during foreach replay. The runner is the workflow boundary that has store access, so it supplies the fresh projection seam instead of making executor self-healing guess after a stale step node fails.
|
|
@@ -207415,16 +207465,29 @@ var SelfHealingManager = class _SelfHealingManager extends SelfHealingGitEvidenc
|
|
|
207415
207465
|
activeWork: await this.resolveActiveWorkColumnsFor(taskId, cache)
|
|
207416
207466
|
};
|
|
207417
207467
|
}
|
|
207418
|
-
|
|
207468
|
+
/*
|
|
207469
|
+
FNXC:SharedBranchMemberHold 2026-08-05-23:35:
|
|
207470
|
+
Pause-abort recovery must resolve the same live intermediate-group predicate as
|
|
207471
|
+
merge admission. Shared metadata alone is stale after group closure or a
|
|
207472
|
+
default-branch collision, so it cannot suppress that task's standalone hold.
|
|
207473
|
+
*/
|
|
207474
|
+
async isLiveSharedMemberIntegration(task, settings) {
|
|
207475
|
+
const groupId = task.branchContext?.groupId?.trim();
|
|
207476
|
+
const group = groupId ? await this.store.getBranchGroup?.(groupId) : null;
|
|
207477
|
+
const defaultBranch = await resolveIntegrationBranch(this.options.rootDir, settings);
|
|
207478
|
+
return isLiveSharedBranchGroupMemberIntegration(task, group, defaultBranch);
|
|
207479
|
+
}
|
|
207480
|
+
async classifyPausedAbortWorkflowRecovery(task, settings, isExecuting, columns) {
|
|
207419
207481
|
const isPausedAbortPark = task.status === "failed" && typeof task.error === "string" && task.error.includes(PAUSE_ABORT_PARK_OPERATOR_MARKER) && task.error.includes(PAUSE_ABORT_PARK_ERROR_MARKER);
|
|
207420
207482
|
if (!isPausedAbortPark) return { kind: "no-action", reason: "not-pause-abort" };
|
|
207421
207483
|
if (task.paused || task.userPaused || isExecuting) return { kind: "no-action", reason: "unsafe-or-not-routable" };
|
|
207422
207484
|
const errorText = typeof task.error === "string" ? task.error.toLowerCase() : "";
|
|
207423
207485
|
const isTerminalMergePark = errorText.includes("conflict") || errorText.includes("contamination") || errorText.includes("foreign") || errorText.includes("retry-exhausted") || errorText.includes("retries exhausted") || errorText.includes("max retries");
|
|
207424
207486
|
const completedSteps = task.steps.length > 0 && task.steps.every((step) => step.status === "done" || step.status === "skipped");
|
|
207425
|
-
const
|
|
207426
|
-
const
|
|
207427
|
-
const
|
|
207487
|
+
const liveSharedBranchMember = await this.isLiveSharedMemberIntegration(task, settings);
|
|
207488
|
+
const autoMergeProcessing = allowsAutoMergeProcessing(task, settings) || liveSharedBranchMember;
|
|
207489
|
+
const hasReviewProgress = columns.review.has(task.column) && autoMergeProcessing && task.mergeDetails?.mergeConfirmed !== true && !isTerminalMergePark && completedSteps;
|
|
207490
|
+
const hasManualMergeHoldProgress = columns.review.has(task.column) && (hasUserAutoMergeHold(task) || !allowsAutoMergeProcessing(task, settings) || resolveEffectiveAutoMerge(task, settings) === false) && (!liveSharedBranchMember || hasUserAutoMergeHold(task)) && task.mergeDetails?.mergeConfirmed !== true && !isTerminalMergePark && completedSteps;
|
|
207428
207491
|
if (hasManualMergeHoldProgress) {
|
|
207429
207492
|
return { kind: "work-item-resume", reason: "pause-abort-manual-merge-hold" };
|
|
207430
207493
|
}
|
|
@@ -213092,8 +213155,23 @@ var SelfHealingManager = class _SelfHealingManager extends SelfHealingGitEvidenc
|
|
|
213092
213155
|
return own.length > 0 ? new Set(own) : /* @__PURE__ */ new Set(["in-review"]);
|
|
213093
213156
|
};
|
|
213094
213157
|
const executingIds = this.options.getExecutingTaskIds?.() ?? /* @__PURE__ */ new Set();
|
|
213158
|
+
const canRecoverMergeableReviewTask = async (task) => {
|
|
213159
|
+
if (hasUserAutoMergeHold(task)) return false;
|
|
213160
|
+
const groupId = task.branchContext?.groupId?.trim();
|
|
213161
|
+
const branchGroup = groupId ? await this.store.getBranchGroup(groupId) : null;
|
|
213162
|
+
const projectDefaultBranch = await resolveIntegrationBranch(this.options.rootDir, settings);
|
|
213163
|
+
if (isLiveSharedBranchGroupMemberIntegration(task, branchGroup, projectDefaultBranch)) {
|
|
213164
|
+
return true;
|
|
213165
|
+
}
|
|
213166
|
+
return allowsAutoMergeProcessing(task, settings) && resolveEffectiveAutoMerge(task, settings) !== false;
|
|
213167
|
+
};
|
|
213168
|
+
const mergeAdmission = await Promise.all(tasks2.map(async (task) => [
|
|
213169
|
+
task.id,
|
|
213170
|
+
await canRecoverMergeableReviewTask(task)
|
|
213171
|
+
]));
|
|
213172
|
+
const mergeAdmissionByTaskId = new Map(mergeAdmission);
|
|
213095
213173
|
const mergeable = tasks2.filter(
|
|
213096
|
-
(t) =>
|
|
213174
|
+
(t) => mergeAdmissionByTaskId.get(t.id) === true && !t.paused && !executingIds.has(t.id) && t.status !== "failed" && // Exclude transient merge statuses. Active merges should be left alone;
|
|
213097
213175
|
// stale ones are handled by recoverStaleMergingStatus().
|
|
213098
213176
|
t.status !== "merging" && t.status !== "merging-pr" && // FNXC:Workspace 2026-06-22-09:30 (Phase D U1, KTD1 — admit workspace tasks):
|
|
213099
213177
|
// A workspace task has task.worktree===null (its worktrees live per-repo in
|
|
@@ -216140,7 +216218,7 @@ var SelfHealingManager = class _SelfHealingManager extends SelfHealingGitEvidenc
|
|
|
216140
216218
|
for (const t of tasks2) {
|
|
216141
216219
|
if (!this.isPauseAbortParkCandidate(t)) continue;
|
|
216142
216220
|
const columns = await this.resolvePauseAbortColumnsFor(t.id, columnCache);
|
|
216143
|
-
if (this.classifyPausedAbortWorkflowRecovery(t, settings, executingIds.has(t.id), columns).kind !== "no-action") {
|
|
216221
|
+
if ((await this.classifyPausedAbortWorkflowRecovery(t, settings, executingIds.has(t.id), columns)).kind !== "no-action") {
|
|
216144
216222
|
parked.push(t);
|
|
216145
216223
|
}
|
|
216146
216224
|
}
|
|
@@ -216157,7 +216235,7 @@ var SelfHealingManager = class _SelfHealingManager extends SelfHealingGitEvidenc
|
|
|
216157
216235
|
continue;
|
|
216158
216236
|
}
|
|
216159
216237
|
const freshColumns = await this.resolvePauseAbortColumnsFor(fresh.id, columnCache);
|
|
216160
|
-
const route = this.classifyPausedAbortWorkflowRecovery(fresh, settings, latestExecutingIds.has(fresh.id), freshColumns);
|
|
216238
|
+
const route = await this.classifyPausedAbortWorkflowRecovery(fresh, settings, latestExecutingIds.has(fresh.id), freshColumns);
|
|
216161
216239
|
if (route.kind === "no-action") {
|
|
216162
216240
|
continue;
|
|
216163
216241
|
}
|
|
@@ -222882,6 +222960,7 @@ ${feedback}`,
|
|
|
222882
222960
|
if (info.phase !== "pre-merge") return false;
|
|
222883
222961
|
if (info.status !== "advisory_failure" && info.status !== "failed") return false;
|
|
222884
222962
|
const liveTask = await this.store.getTask(taskId).catch(() => fallbackTask);
|
|
222963
|
+
if (hasUserAutoMergeHold(liveTask)) return false;
|
|
222885
222964
|
const missingArtifactKeys = parseRequiredArtifactMissingValue(info.failureValue);
|
|
222886
222965
|
if (missingArtifactKeys) {
|
|
222887
222966
|
await this.recoverMissingRequiredArtifacts(liveTask, missingArtifactKeys, {
|
|
@@ -223138,6 +223217,7 @@ ${info.feedback}`, revisionKey),
|
|
|
223138
223217
|
*/
|
|
223139
223218
|
async recoverFailedPreMergeWorkflowStep(task) {
|
|
223140
223219
|
try {
|
|
223220
|
+
if (hasUserAutoMergeHold(task)) return false;
|
|
223141
223221
|
const failed = (task.workflowStepResults ?? []).filter((r) => (r.phase || "pre-merge") === "pre-merge" && r.status === "failed").sort((a, b3) => {
|
|
223142
223222
|
const aTs = Date.parse(a.completedAt || a.startedAt || "");
|
|
223143
223223
|
const bTs = Date.parse(b3.completedAt || b3.startedAt || "");
|
|
@@ -223664,6 +223744,7 @@ ${info.feedback}`, revisionKey),
|
|
|
223664
223744
|
getTask: (taskId) => this.store.getTask(taskId)
|
|
223665
223745
|
},
|
|
223666
223746
|
runId: resolvedRunId,
|
|
223747
|
+
isLiveSharedBranchMember: (nodeTask) => this.isLiveSharedBranchGroupMember(nodeTask),
|
|
223667
223748
|
primitives: this.createAuthoritativeWorkflowPrimitives(settings),
|
|
223668
223749
|
seams: this.createAuthoritativeWorkflowSeams(settings),
|
|
223669
223750
|
prepareNodeExecution: (node, nodeTask, requirement) => this.prepareGraphNodeExecution(node, nodeTask, settings, requirement),
|
|
@@ -226605,6 +226686,7 @@ Graph value: ${failureValue}` : ""}`, budget.key),
|
|
|
226605
226686
|
} catch {
|
|
226606
226687
|
return false;
|
|
226607
226688
|
}
|
|
226689
|
+
if (hasUserAutoMergeHold(live)) return false;
|
|
226608
226690
|
const sharedBranchMember = await this.isLiveSharedBranchGroupMember(live);
|
|
226609
226691
|
if (!sharedBranchMember && !allowsAutoMergeProcessing(live, settings)) return false;
|
|
226610
226692
|
if (!sharedBranchMember && resolveEffectiveAutoMerge(live, settings) === false) return false;
|
|
@@ -226666,8 +226748,8 @@ Graph value: ${failureValue}` : ""}`, budget.key),
|
|
|
226666
226748
|
} catch {
|
|
226667
226749
|
return false;
|
|
226668
226750
|
}
|
|
226669
|
-
if (await this.isLiveSharedBranchGroupMember(live)) return false;
|
|
226670
|
-
return !allowsAutoMergeProcessing(live, settings) || resolveEffectiveAutoMerge(live, settings) === false;
|
|
226751
|
+
if (await this.isLiveSharedBranchGroupMember(live) && !hasUserAutoMergeHold(live)) return false;
|
|
226752
|
+
return hasUserAutoMergeHold(live) || !allowsAutoMergeProcessing(live, settings) || resolveEffectiveAutoMerge(live, settings) === false;
|
|
226671
226753
|
}
|
|
226672
226754
|
async handleStaleInReviewPlanPauseAbortReplay(live, result, abortProvenance, pausedAborted, userCanceled, resumeLanesMemo) {
|
|
226673
226755
|
if (!pausedAborted) return false;
|
|
@@ -226831,9 +226913,9 @@ Graph value: ${failureValue}` : ""}`, budget.key),
|
|
|
226831
226913
|
if (settings.globalPause === true) return false;
|
|
226832
226914
|
}
|
|
226833
226915
|
if (live.column === resumeLanes.review) {
|
|
226834
|
-
if (live.autoMerge === false) return false;
|
|
226835
226916
|
if (!settings) return false;
|
|
226836
226917
|
const sharedBranchMember = await this.isLiveSharedBranchGroupMember(live);
|
|
226918
|
+
if (hasUserAutoMergeHold(live) || live.autoMerge === false && !sharedBranchMember) return false;
|
|
226837
226919
|
if (!sharedBranchMember && !allowsAutoMergeProcessing(live, settings)) return false;
|
|
226838
226920
|
if (live.mergeDetails?.mergeConfirmed === true) return false;
|
|
226839
226921
|
}
|
|
@@ -247890,6 +247972,7 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
247890
247972
|
}
|
|
247891
247973
|
}
|
|
247892
247974
|
const prNodeGithubOps = this.config.prNodeGithubOps;
|
|
247975
|
+
const secretsStore = await this.taskStore.getSecretsStore();
|
|
247893
247976
|
const executorOptions = {
|
|
247894
247977
|
/*
|
|
247895
247978
|
FNXC:PlanReviewLease 2026-07-26-21:12:
|
|
@@ -247905,6 +247988,7 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
247905
247988
|
cliAgentRuntime: this.cliAgentRuntime?.bundle,
|
|
247906
247989
|
pluginRunner: this.pluginRunner,
|
|
247907
247990
|
messageStore: this.messageStore,
|
|
247991
|
+
secretsStore,
|
|
247908
247992
|
missionStore,
|
|
247909
247993
|
reflectionService,
|
|
247910
247994
|
// PR-entity nodes (U3): assemble the handler deps from the CLI-injected
|
|
@@ -248006,6 +248090,7 @@ var InProcessRuntime = class extends EventEmitter27 {
|
|
|
248006
248090
|
reflectionService,
|
|
248007
248091
|
selfImproveService,
|
|
248008
248092
|
credentialRotator: this.credentialRotator,
|
|
248093
|
+
secretsStore,
|
|
248009
248094
|
snapshotManager: autoClaimSnapshotManager,
|
|
248010
248095
|
onMissed: (agentId, reason) => {
|
|
248011
248096
|
runtimeLog.warn(`Agent ${agentId} missed heartbeat: ${reason}`);
|
|
@@ -255045,7 +255130,21 @@ var ProjectEngine = class _ProjectEngine {
|
|
|
255045
255130
|
Cleared on the first non-busy outcome (success path resets it).
|
|
255046
255131
|
*/
|
|
255047
255132
|
workspaceBusyReenqueues = /* @__PURE__ */ new Map();
|
|
255133
|
+
workspaceBusyReenqueueTimers = /* @__PURE__ */ new Set();
|
|
255048
255134
|
static WORKSPACE_BUSY_MAX_REENQUEUES = 10;
|
|
255135
|
+
/*
|
|
255136
|
+
FNXC:WorkspaceMergeDispatch 2026-08-05-23:56:
|
|
255137
|
+
Workspace lease-contention retries are engine-owned lifecycle work, not detached callbacks.
|
|
255138
|
+
Track only these busy re-enqueue timers so stop() can cancel them and tests can measure the
|
|
255139
|
+
capped workspace ladder without confusing it with merge-body or maintenance timers.
|
|
255140
|
+
*/
|
|
255141
|
+
scheduleWorkspaceBusyReenqueue(taskId, delayMs) {
|
|
255142
|
+
const timer2 = setTimeout(() => {
|
|
255143
|
+
this.workspaceBusyReenqueueTimers.delete(timer2);
|
|
255144
|
+
if (!this.shuttingDown) this.internalEnqueueMerge(taskId);
|
|
255145
|
+
}, delayMs);
|
|
255146
|
+
this.workspaceBusyReenqueueTimers.add(timer2);
|
|
255147
|
+
}
|
|
255049
255148
|
/**
|
|
255050
255149
|
* Pending manual merge resolvers — keyed by taskId.
|
|
255051
255150
|
* When `onMerge` is called, the task is enqueued like auto-merge but a
|
|
@@ -255580,6 +255679,10 @@ ${detail}`);
|
|
|
255580
255679
|
clearInterval(this.mergeActiveReconcileTimer);
|
|
255581
255680
|
this.mergeActiveReconcileTimer = null;
|
|
255582
255681
|
}
|
|
255682
|
+
for (const timer2 of this.workspaceBusyReenqueueTimers) {
|
|
255683
|
+
clearTimeout(timer2);
|
|
255684
|
+
}
|
|
255685
|
+
this.workspaceBusyReenqueueTimers.clear();
|
|
255583
255686
|
for (const [taskId, deferred] of this.capacityDeferredMerges) {
|
|
255584
255687
|
clearTimeout(deferred.timer);
|
|
255585
255688
|
for (const resolver of deferred.resolvers) {
|
|
@@ -256879,16 +256982,15 @@ ${detail}`);
|
|
|
256879
256982
|
* older low-priority task would start before a later urgent one.
|
|
256880
256983
|
*/
|
|
256881
256984
|
async allowInReviewMergeProcessing(task, settings, store = this.runtime.getTaskStore()) {
|
|
256882
|
-
if (
|
|
256883
|
-
return true;
|
|
256884
|
-
}
|
|
256985
|
+
if (hasUserAutoMergeHold(task)) return false;
|
|
256885
256986
|
const groupId = task.branchContext?.groupId?.trim();
|
|
256886
256987
|
const branchGroup = groupId ? await store.getBranchGroup?.(groupId) : null;
|
|
256887
|
-
if (!branchGroup || branchGroup.status !== "open" || !branchGroup.branchName.trim()) {
|
|
256888
|
-
return false;
|
|
256889
|
-
}
|
|
256890
256988
|
const projectDefaultBranch = await resolveIntegrationBranch(this.config.workingDirectory, settings);
|
|
256891
|
-
|
|
256989
|
+
if (isLiveSharedBranchGroupMemberIntegration(task, branchGroup, projectDefaultBranch)) {
|
|
256990
|
+
return true;
|
|
256991
|
+
}
|
|
256992
|
+
if (task.autoMerge === false && groupId) return false;
|
|
256993
|
+
return allowsAutoMergeProcessing(task, settings);
|
|
256892
256994
|
}
|
|
256893
256995
|
async emitLegacyAutoMergeStampAdvisory(store) {
|
|
256894
256996
|
if (this.legacyAutoMergeStampAdvisoryEmitted) {
|
|
@@ -257841,9 +257943,7 @@ ${detail}`);
|
|
|
257841
257943
|
runtimeLog.log(
|
|
257842
257944
|
`Workspace land busy re-enqueue ${busyCount + 1}/${_ProjectEngine.WORKSPACE_BUSY_MAX_REENQUEUES} for ${taskId} in ${delayMs / 1e3}s (no mergeRetry consumed \u2014 pure lease contention)`
|
|
257843
257945
|
);
|
|
257844
|
-
|
|
257845
|
-
if (!this.shuttingDown) this.internalEnqueueMerge(taskId);
|
|
257846
|
-
}, delayMs);
|
|
257946
|
+
this.scheduleWorkspaceBusyReenqueue(taskId, delayMs);
|
|
257847
257947
|
} else {
|
|
257848
257948
|
this.workspaceBusyReenqueues.delete(taskId);
|
|
257849
257949
|
await store.updateTask(taskId, { status: "failed", error: errorMsg }).catch(() => void 0);
|