@runfusion/fusion 0.77.0-beta.12 → 0.77.0-beta.14
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 +1648 -909
- package/dist/child-process-worker.js +1072 -471
- package/dist/client/.vite/manifest.json +260 -260
- package/dist/client/assets/{AgentDetailView-BZfDgV8f.js → AgentDetailView-C-fxrRM5.js} +1 -1
- package/dist/client/assets/AgentDetailView-DPoh46Ym.css +1 -0
- package/dist/client/assets/{AgentPermissionPolicyEditor-8yBqnwbx.js → AgentPermissionPolicyEditor-BvEdHYdU.js} +1 -1
- package/dist/client/assets/{AgentsView-BjMOtIMq.js → AgentsView-nLidYV1p.js} +3 -3
- package/dist/client/assets/CommandCenter-BshTzOtB.css +1 -0
- package/dist/client/assets/{CommandCenter-CDuO3HPd.js → CommandCenter-BxFBD-rU.js} +22 -22
- package/dist/client/assets/{DevServerView-C96RV0QJ.js → DevServerView-KLdA68W-.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-iRielXf7.js → DirectoryPicker-BiclyrJo.js} +1 -1
- package/dist/client/assets/{DocumentsView-DhAUnUD_.js → DocumentsView-BU24Dd5I.js} +1 -1
- package/dist/client/assets/{EvalsView--n1p2Bt0.js → EvalsView-BMSTg0vH.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-DraglCCV.js → ExperimentalAgentOnboardingModal-BtYOAtE2.js} +1 -1
- package/dist/client/assets/{GoalsView-BOWOua5t.js → GoalsView-Dlb12ETy.js} +1 -1
- package/dist/client/assets/{InsightsView-C5YcJZSc.js → InsightsView-NJuA0vFY.js} +1 -1
- package/dist/client/assets/{MemoryView-DsCuGVGx.js → MemoryView-te2vPbGq.js} +1 -1
- package/dist/client/assets/{PatchnodeView-CzgChkJV.js → PatchnodeView-F-TmysVw.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-qYbmaigE.js → PiExtensionsManager-CClfNfAm.js} +1 -1
- package/dist/client/assets/{PluginManager-Cklj4Smo.js → PluginManager-BdNdqcjr.js} +1 -1
- package/dist/client/assets/{PullRequestView-C6vozTTI.js → PullRequestView-Du4FqTkG.js} +1 -1
- package/dist/client/assets/{ReportModal-B0LU4E4L.js → ReportModal-BCUOLOBM.js} +1 -1
- package/dist/client/assets/{ResearchView-CpESx46e.js → ResearchView-DukV-C42.js} +1 -1
- package/dist/client/assets/{SecretsView-8ZdH9Yzs.js → SecretsView-B3ApHMyx.js} +1 -1
- package/dist/client/assets/SettingsModal-BEULP2a7.css +1 -0
- package/dist/client/assets/{SettingsModal-BJXu-dhz.js → SettingsModal-D-_HKpi5.js} +1 -1
- package/dist/client/assets/SettingsModal-JPt8VHZy.js +21 -0
- package/dist/client/assets/{SettingsTextareaRow-th-q0_2k.js → SettingsTextareaRow-CpTYQz1W.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-CBElxrRA.js → SetupWizardModal-DcD2ERVR.js} +2 -2
- package/dist/client/assets/{SkillsView-BuoicLbJ.js → SkillsView-DCqRw00z.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-BDw0LpWM.js → WorkflowNodeEditor-CxpjK-k_.js} +1 -1
- package/dist/client/assets/{agent-import-generation-CNridJHO.js → agent-import-generation-COouuGNI.js} +1 -1
- package/dist/client/assets/{agentsOrgChartLayout-BopFGp0r.js → agentsOrgChartLayout-BkXeACZM.js} +1 -1
- package/dist/client/assets/{app-DKzqBaeH.js → app-BUPxz3_I.js} +1 -1
- package/dist/client/assets/{app-y8x9KYqa.js → app-Bsb-vSJ2.js} +3 -3
- package/dist/client/assets/{app-DkJZhePX.js → app-CDMzhkVk.js} +1 -1
- package/dist/client/assets/{app-BtBMuy2Z.js → app-Ca3_7roP.js} +3 -3
- package/dist/client/assets/{app-JnrgtY9I.js → app-CaiQxtA9.js} +3 -3
- package/dist/client/assets/{app-LrO9EOLE.js → app-D7N3gRgK.js} +3 -3
- package/dist/client/assets/{app-Cv-4fcPl.js → app-Du0s0Xs8.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-2_yoUOD5.js → architectureDiagram-3BPJPVTR-CGeVlxee.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-ueBSwDJh.js → blockDiagram-GPEHLZMM-D3J6Tg96.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-D0cUU3pE.js → c4Diagram-AAUBKEIU-Ckh64Ujd.js} +1 -1
- package/dist/client/assets/channel-HtwB1uv6.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-DKJnGdD6.js → chunk-2J33WTMH-D2nEfwjq.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-BUrgUtvt.js → chunk-4BX2VUAB-C_LbWHxf.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DHy2hCYz.js → chunk-55IACEB6-DCe4vUlx.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-Dgbhllem.js → chunk-727SXJPM-iwy0O4kD.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-tPbicvl-.js → chunk-AQP2D5EJ-3FRhkbWy.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BpHFGFmo.js → chunk-FMBD7UC4-DKwvI3J1.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-DUTQ63ld.js → chunk-ND2GUHAM-BLCbQ396.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-ChCf_usL.js → chunk-QZHKN3VN-B8_SVfXK.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DY01_o5q.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DY01_o5q.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DgWzHtF9.js → cose-bilkent-S5V4N54A-BI3P2QH1.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-gQ1C1xHJ.js → dagre-BM42HDAG-Cw7T4fR4.js} +1 -1
- package/dist/client/assets/{dashboard-view-BXtoQ9a4.js → dashboard-view-Bahw8YdV.js} +1 -1
- package/dist/client/assets/{dashboard-view-BLenRoXu.js → dashboard-view-GzD2Iawz.js} +1 -1
- package/dist/client/assets/{dashboard-view-AQmzkBNb.js → dashboard-view-_8Rh_v2d.js} +1 -1
- package/dist/client/assets/{dashboard-view-BtFepPos.js → dashboard-view-nmh7Oq3W.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-Dv96I1MI.js → diagram-2AECGRRQ-D-HeBfdu.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BRyhjYes.js → diagram-5GNKFQAL-DdqdGn6R.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-Bmj3ihjc.js → diagram-KO2AKTUF-BiqjUeas.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-BYHVCFK2.js → diagram-LMA3HP47-XAqAjX_Q.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-0WZBLayt.js → diagram-OG6HWLK6-DFA7xW7A.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Cu-yj8hA.js → erDiagram-TEJ5UH35-ChXB-xPr.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-BSetu6oh.js → flowDiagram-I6XJVG4X-7EGMaA4S.js} +1 -1
- package/dist/client/assets/{folder-open-CkswT0lE.js → folder-open-CRG4IIvN.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-B5qn0KFQ.js → ganttDiagram-6RSMTGT7-CFu_eMTW.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-BVB3wm46.js → gitGraphDiagram-PVQCEYII-B6D4IPay.js} +1 -1
- package/dist/client/assets/index-bjswUBcF.js +2937 -0
- package/dist/client/assets/index-lxhrCjd_.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-ZBNKOBSK.js → infoDiagram-5YYISTIA-WjP49ki8.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CbNKgenI.js → ishikawaDiagram-YF4QCWOH-D9dfXlEr.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BLc2FHIF.js → journeyDiagram-JHISSGLW-B1qmhVqE.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-B08tij8f.js → kanban-definition-UN3LZRKU-DKJ9zHQh.js} +1 -1
- package/dist/client/assets/{mermaid.core-QX5z7w8Z.js → mermaid.core-L96x9i-s.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-C1md8M3c.js → mindmap-definition-RKZ34NQL-Cd6f8xCu.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BoQbn3Xp.js → pieDiagram-4H26LBE5-DxV4qYtG.js} +1 -1
- package/dist/client/assets/{puzzle-DCqPnWPE.js → puzzle-B-xyPV3x.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-DPvNcVK-.js → quadrantDiagram-W4KKPZXB-CSfHWa-s.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-KfdYf15t.js → requirementDiagram-4Y6WPE33-BVyQ-8E1.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-D1Eyoanf.js → sankeyDiagram-5OEKKPKP-bz2Lc_rV.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CmODsbCf.js → sequenceDiagram-3UESZ5HK-ZvToVBro.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-D_mPaGcG.js → standing-instructions-template-DVKRWk6d.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-Blbw_21G.js → stateDiagram-AJRCARHV-CSCy0VcB.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-DwMgvYO8.js → stateDiagram-v2-BHNVJYJU-ChRwUFh1.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DDtndgLc.js → timeline-definition-PNZ67QCA-9MuQjnnW.js} +1 -1
- package/dist/client/assets/{upload-DGCjJkMH.js → upload-B1HSIk-m.js} +1 -1
- package/dist/client/assets/{users-CbWZvFZP.js → users-CHrRYBSi.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-B6Sx0OqW.js → vennDiagram-CIIHVFJN-D3XO2rfJ.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-_SQFYU4g.js → wardley-L42UT6IY-Dug4bLhv.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Ce5igv6s.js → wardleyDiagram-YWT4CUSO-CtGA4P2g.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-zI0zyvDP.js → xychartDiagram-2RQKCTM6-D0EMf4Z7.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 +1487 -803
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.d.ts +1 -1
- package/dist/plugin-sdk/index.js +25 -14
- package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +25 -14
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/AgentDetailView-jzgy1BAS.css +0 -1
- package/dist/client/assets/CommandCenter-ilm-DbtI.css +0 -1
- package/dist/client/assets/SettingsModal-B1UCDc_h.js +0 -21
- package/dist/client/assets/SettingsModal-C5ic1ls7.css +0 -1
- package/dist/client/assets/channel-DfvbdnTK.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CkMyClXV.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CkMyClXV.js +0 -1
- package/dist/client/assets/index-BgE915SE.js +0 -2937
- package/dist/client/assets/index-e2yEk7y4.css +0 -1
package/dist/extension.js
CHANGED
|
@@ -1513,6 +1513,199 @@ Be specific: cite the plan section or file path for every finding and explain th
|
|
|
1513
1513
|
}
|
|
1514
1514
|
});
|
|
1515
1515
|
|
|
1516
|
+
// ../core/src/workflows/workflow-merge-region.ts
|
|
1517
|
+
function isMergeRegionNode(node) {
|
|
1518
|
+
return MERGE_REGION_ENTRY_NODE_KINDS.has(node.kind) || node.config?.seam === "merge";
|
|
1519
|
+
}
|
|
1520
|
+
function classifyWorkflowNodeMergeRegion(ir2, nodeId) {
|
|
1521
|
+
if (ir2.version !== "v2" || !Array.isArray(ir2.nodes)) return "unknown";
|
|
1522
|
+
const node = ir2.nodes.find((candidate) => candidate.id === nodeId);
|
|
1523
|
+
if (!node) return "unknown";
|
|
1524
|
+
return isMergeRegionNode(node) ? "merge-region" : "outside-merge-region";
|
|
1525
|
+
}
|
|
1526
|
+
var MERGE_REGION_ENTRY_NODE_KINDS;
|
|
1527
|
+
var init_workflow_merge_region = __esm({
|
|
1528
|
+
"../core/src/workflows/workflow-merge-region.ts"() {
|
|
1529
|
+
"use strict";
|
|
1530
|
+
MERGE_REGION_ENTRY_NODE_KINDS = /* @__PURE__ */ new Set([
|
|
1531
|
+
"merge-gate",
|
|
1532
|
+
"merge-attempt",
|
|
1533
|
+
"manual-merge-hold",
|
|
1534
|
+
"retry-backoff",
|
|
1535
|
+
"recovery-router",
|
|
1536
|
+
"branch-group-member-integration",
|
|
1537
|
+
"branch-group-promotion",
|
|
1538
|
+
"pr-create",
|
|
1539
|
+
"pr-respond",
|
|
1540
|
+
"pr-merge"
|
|
1541
|
+
]);
|
|
1542
|
+
}
|
|
1543
|
+
});
|
|
1544
|
+
|
|
1545
|
+
// ../core/src/workflows/workflow-optional-steps.ts
|
|
1546
|
+
function isWorkflowOptionalGroupEnabled(enabledWorkflowSteps, groupId, defaultOn = false) {
|
|
1547
|
+
return Array.isArray(enabledWorkflowSteps) ? enabledWorkflowSteps.includes(groupId) : defaultOn;
|
|
1548
|
+
}
|
|
1549
|
+
function isOptionalGroupNode(node) {
|
|
1550
|
+
return node.kind === "optional-group";
|
|
1551
|
+
}
|
|
1552
|
+
function computeNodeExecutionRanks(ir2) {
|
|
1553
|
+
const ranks = /* @__PURE__ */ new Map();
|
|
1554
|
+
if (ir2.version !== "v2" || !Array.isArray(ir2.nodes) || !Array.isArray(ir2.edges)) {
|
|
1555
|
+
return ranks;
|
|
1556
|
+
}
|
|
1557
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
1558
|
+
for (const edge of ir2.edges) {
|
|
1559
|
+
if (!outgoing.has(edge.from)) outgoing.set(edge.from, []);
|
|
1560
|
+
outgoing.get(edge.from)?.push(edge.to);
|
|
1561
|
+
}
|
|
1562
|
+
const queue = [];
|
|
1563
|
+
for (const node of ir2.nodes) {
|
|
1564
|
+
if (node.kind === "start" || node.id === "start") {
|
|
1565
|
+
queue.push({ id: node.id, rank: 0 });
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
while (queue.length > 0) {
|
|
1569
|
+
const next = queue.shift();
|
|
1570
|
+
if (!next) continue;
|
|
1571
|
+
const current = ranks.get(next.id);
|
|
1572
|
+
if (current !== void 0 && current <= next.rank) continue;
|
|
1573
|
+
ranks.set(next.id, next.rank);
|
|
1574
|
+
for (const target of outgoing.get(next.id) ?? []) {
|
|
1575
|
+
queue.push({ id: target, rank: next.rank + 1 });
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
return ranks;
|
|
1579
|
+
}
|
|
1580
|
+
function resolveWorkflowOptionalSteps(ir2, _pluginTemplates = []) {
|
|
1581
|
+
if (ir2.version !== "v2" || !Array.isArray(ir2.nodes)) return [];
|
|
1582
|
+
const ranks = computeNodeExecutionRanks(ir2);
|
|
1583
|
+
const resolved = [];
|
|
1584
|
+
for (const [nodeIndex, node] of ir2.nodes.entries()) {
|
|
1585
|
+
if (!isOptionalGroupNode(node)) continue;
|
|
1586
|
+
const config3 = node.config ?? {};
|
|
1587
|
+
resolved.push({
|
|
1588
|
+
// Keyed by the group node id (documented above); field name preserved.
|
|
1589
|
+
templateId: node.id,
|
|
1590
|
+
name: typeof config3.name === "string" && config3.name.trim() ? config3.name : node.id,
|
|
1591
|
+
description: "",
|
|
1592
|
+
/*
|
|
1593
|
+
FNXC:WorkflowOptionalSteps 2026-06-29-12:47:
|
|
1594
|
+
Post-merge verification is now a graph-native optional group. Task creation and detail surfaces need the resolver to preserve `config.phase` so post-merge toggles do not look like pre-merge gates.
|
|
1595
|
+
*/
|
|
1596
|
+
phase: config3.phase === "post-merge" ? "post-merge" : "pre-merge",
|
|
1597
|
+
defaultOn: config3.defaultOn === true,
|
|
1598
|
+
reportingOnly: config3.reportingOnly === true,
|
|
1599
|
+
/*
|
|
1600
|
+
FNXC:WorkflowDefinitionSteps 2026-06-29-00:41:
|
|
1601
|
+
Definition/task creation surfaces must order optional groups by graph execution position, not raw node-array order. Derived built-ins can insert Plan Review between planning and parse while appending its node object, and operators still need the step list to show Plan Review before execution.
|
|
1602
|
+
*/
|
|
1603
|
+
rank: ranks.get(node.id) ?? Number.MAX_SAFE_INTEGER,
|
|
1604
|
+
nodeIndex
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
return resolved.sort((a, b3) => a.rank - b3.rank || a.nodeIndex - b3.nodeIndex).map(({ rank: _rank, nodeIndex: _nodeIndex, ...step }) => step);
|
|
1608
|
+
}
|
|
1609
|
+
function resolveDefaultOnOptionalGroupIds(ir2) {
|
|
1610
|
+
return resolveWorkflowOptionalSteps(ir2).filter((step) => step.defaultOn).map((step) => step.templateId);
|
|
1611
|
+
}
|
|
1612
|
+
function resolveAllOptionalGroupIds(ir2) {
|
|
1613
|
+
return resolveWorkflowOptionalSteps(ir2).map((step) => step.templateId);
|
|
1614
|
+
}
|
|
1615
|
+
function isReportingOnlyOptionalGroup(ir2, nodeId) {
|
|
1616
|
+
if (!nodeId) return false;
|
|
1617
|
+
return resolveWorkflowOptionalSteps(ir2).some((step) => step.templateId === nodeId && step.reportingOnly);
|
|
1618
|
+
}
|
|
1619
|
+
var init_workflow_optional_steps = __esm({
|
|
1620
|
+
"../core/src/workflows/workflow-optional-steps.ts"() {
|
|
1621
|
+
"use strict";
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
// ../core/src/workflows/workflow-fast-lane.ts
|
|
1626
|
+
function isFastExecutionMode(task) {
|
|
1627
|
+
return task.executionMode === "fast";
|
|
1628
|
+
}
|
|
1629
|
+
function configString(node, key) {
|
|
1630
|
+
const value = node.config?.[key];
|
|
1631
|
+
return typeof value === "string" ? value : void 0;
|
|
1632
|
+
}
|
|
1633
|
+
function isTaskStepsForeach(node) {
|
|
1634
|
+
return node.kind === "foreach" && node.config?.source === "task-steps";
|
|
1635
|
+
}
|
|
1636
|
+
function isFastLaneSkippableCustomNode(node, opts = {}) {
|
|
1637
|
+
if (node.config?.summaryTarget === "task" || node.id === "completion-summary") return false;
|
|
1638
|
+
if (opts.optionalGroupId) return false;
|
|
1639
|
+
if (node.config?.seam) return false;
|
|
1640
|
+
return node.kind === "prompt" || node.kind === "script" || node.kind === "gate";
|
|
1641
|
+
}
|
|
1642
|
+
function isFastLaneBypassedTemplateNode(node) {
|
|
1643
|
+
return node.kind === "step-review";
|
|
1644
|
+
}
|
|
1645
|
+
function inactiveRoute() {
|
|
1646
|
+
return {
|
|
1647
|
+
active: false,
|
|
1648
|
+
bypassedNodeIds: /* @__PURE__ */ new Set(),
|
|
1649
|
+
bypassedPreMergeGroups: [],
|
|
1650
|
+
parseStepsNodeIds: /* @__PURE__ */ new Set()
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
function resolveFastLaneRoute(ir2, task) {
|
|
1654
|
+
if (!isFastExecutionMode(task)) return inactiveRoute();
|
|
1655
|
+
const foreachNode = ir2.nodes.find(isTaskStepsForeach);
|
|
1656
|
+
const executeNode = ir2.nodes.find((node) => configString(node, "seam") === "execute");
|
|
1657
|
+
const implementationNode = foreachNode ?? executeNode;
|
|
1658
|
+
if (!implementationNode) {
|
|
1659
|
+
return { ...inactiveRoute(), unsupportedReason: "no-implementation-node" };
|
|
1660
|
+
}
|
|
1661
|
+
const implementationKind = foreachNode ? "foreach-steps" : "execute-seam";
|
|
1662
|
+
const bypassedPreMergeGroups = resolveWorkflowOptionalSteps(ir2).filter((step) => step.phase === "pre-merge").map((step) => ({ nodeId: step.templateId, name: step.name }));
|
|
1663
|
+
const bypassedGroupIds = new Set(bypassedPreMergeGroups.map((group) => group.nodeId));
|
|
1664
|
+
const bypassedNodeIds = /* @__PURE__ */ new Set();
|
|
1665
|
+
for (const node of ir2.nodes) {
|
|
1666
|
+
if (isMergeRegionNode(node) || node.id === "completion-summary" || node.config?.summaryTarget === "task") continue;
|
|
1667
|
+
if (configString(node, "seam") === "planning") {
|
|
1668
|
+
bypassedNodeIds.add(node.id);
|
|
1669
|
+
continue;
|
|
1670
|
+
}
|
|
1671
|
+
if (bypassedGroupIds.has(node.id)) {
|
|
1672
|
+
bypassedNodeIds.add(node.id);
|
|
1673
|
+
continue;
|
|
1674
|
+
}
|
|
1675
|
+
const workflowAction = configString(node, "workflowAction");
|
|
1676
|
+
const groupId = configString(node, "forWorkflowStepId");
|
|
1677
|
+
if (workflowAction === "plan-replan" || workflowAction === "plan-review-no-op" || workflowAction === "pre-merge-remediation" || workflowAction === "review-remediation-steps" || groupId !== void 0 && bypassedGroupIds.has(groupId)) {
|
|
1678
|
+
bypassedNodeIds.add(node.id);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
const parseStepsNodeIds = new Set(ir2.nodes.filter((node) => node.kind === "parse-steps").map((node) => node.id));
|
|
1682
|
+
for (const parseNodeId of parseStepsNodeIds) {
|
|
1683
|
+
if (bypassedNodeIds.has(parseNodeId)) {
|
|
1684
|
+
throw new Error(`Fast lane cannot bypass parse-steps node '${parseNodeId}'`);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
return {
|
|
1688
|
+
active: true,
|
|
1689
|
+
bypassedNodeIds,
|
|
1690
|
+
bypassedPreMergeGroups,
|
|
1691
|
+
parseStepsNodeIds,
|
|
1692
|
+
implementationNodeId: implementationNode.id,
|
|
1693
|
+
implementationKind
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
var FAST_LANE_STEP_NAME, FAST_LANE_SKIP_VALUE, FAST_MODE_BYPASS_ACTOR, FAST_LANE_STEP_REVIEW_ROUTE_VALUE;
|
|
1697
|
+
var init_workflow_fast_lane = __esm({
|
|
1698
|
+
"../core/src/workflows/workflow-fast-lane.ts"() {
|
|
1699
|
+
"use strict";
|
|
1700
|
+
init_workflow_merge_region();
|
|
1701
|
+
init_workflow_optional_steps();
|
|
1702
|
+
FAST_LANE_STEP_NAME = "Fast implementation";
|
|
1703
|
+
FAST_LANE_SKIP_VALUE = "fast-lane-skip";
|
|
1704
|
+
FAST_MODE_BYPASS_ACTOR = "fast-mode";
|
|
1705
|
+
FAST_LANE_STEP_REVIEW_ROUTE_VALUE = "approve";
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
|
|
1516
1709
|
// ../core/src/workflows/workflow-step-results.ts
|
|
1517
1710
|
function isWorkflowStepNotRun(result2) {
|
|
1518
1711
|
return result2.status === "skipped" && typeof result2.notRunReason === "string" && WORKFLOW_STEP_NOT_RUN_REASONS.includes(result2.notRunReason);
|
|
@@ -1813,6 +2006,31 @@ var init_workflow_step_results = __esm({
|
|
|
1813
2006
|
});
|
|
1814
2007
|
|
|
1815
2008
|
// ../core/src/merge/pre-merge-approval.ts
|
|
2009
|
+
function requiresContentReviewProof(workflowStepId, result2) {
|
|
2010
|
+
return workflowStepId === "code-review" || result2.reviewKind === "code";
|
|
2011
|
+
}
|
|
2012
|
+
function isAuditedOperatorBypass(result2) {
|
|
2013
|
+
if (result2.status !== "skipped") return false;
|
|
2014
|
+
const actor = result2.bypassedBy?.trim();
|
|
2015
|
+
return Boolean(
|
|
2016
|
+
actor && !AUTOMATED_BYPASS_ACTORS.has(actor) && result2.bypassedAt?.trim() && result2.bypassReason?.trim()
|
|
2017
|
+
);
|
|
2018
|
+
}
|
|
2019
|
+
function resolveUnprovenReviewApproval(result2, options) {
|
|
2020
|
+
if ((result2.phase ?? "pre-merge") !== "pre-merge" || !requiresContentReviewProof(result2.workflowStepId, result2) || options.workspace || result2.status !== "passed" || result2.verdict !== "APPROVE" && result2.verdict !== "APPROVE_WITH_NOTES" || result2.reviewInputFingerprint !== void 0 || result2.bypassedBy !== void 0 || result2.remediationArchivedAt != null) {
|
|
2021
|
+
return void 0;
|
|
2022
|
+
}
|
|
2023
|
+
const { verdict: _verdict, ...withoutVerdict } = result2;
|
|
2024
|
+
return {
|
|
2025
|
+
downgraded: {
|
|
2026
|
+
...withoutVerdict,
|
|
2027
|
+
status: "failed",
|
|
2028
|
+
output: UNPROVEN_REVIEW_APPROVAL_DIAGNOSTIC,
|
|
2029
|
+
notes: UNPROVEN_REVIEW_APPROVAL_DIAGNOSTIC
|
|
2030
|
+
},
|
|
2031
|
+
reason: UNPROVEN_REVIEW_APPROVAL_DIAGNOSTIC
|
|
2032
|
+
};
|
|
2033
|
+
}
|
|
1816
2034
|
function evaluatePreMergeApprovals(task, options = {}) {
|
|
1817
2035
|
const required2 = options.requiredPreMergeStepIds;
|
|
1818
2036
|
if (!required2?.size) return [];
|
|
@@ -1823,13 +2041,16 @@ function evaluateStep(workflowStepId, results, task, descriptor) {
|
|
|
1823
2041
|
const result2 = results.filter((candidate) => candidate.workflowStepId === workflowStepId).at(-1);
|
|
1824
2042
|
if (!result2 && descriptor?.kind !== "workspace") return { workflowStepId, state: "missing" };
|
|
1825
2043
|
if (result2) {
|
|
1826
|
-
const requiresExplicitVerdict = workflowStepId
|
|
2044
|
+
const requiresExplicitVerdict = requiresContentReviewProof(workflowStepId, result2);
|
|
1827
2045
|
const approvedVerdict = result2.verdict === "APPROVE" || result2.verdict === "APPROVE_WITH_NOTES";
|
|
1828
2046
|
const isPlanDomain = workflowStepId === PLAN_REVIEW_GROUP_ID || result2.reviewKind === "plan";
|
|
1829
2047
|
const notRunApproves = isWorkflowStepNotRun(result2) && !requiresExplicitVerdict && !isPlanDomain;
|
|
1830
2048
|
const approved = result2.status === "passed" && (requiresExplicitVerdict ? approvedVerdict : result2.verdict === void 0 || approvedVerdict) || result2.status === "skipped" && !!result2.bypassedBy || notRunApproves;
|
|
1831
2049
|
if (!approved || !!result2.remediationArchivedAt) return { workflowStepId, state: "not-approved" };
|
|
1832
2050
|
if (result2.reviewKind === "plan") return { workflowStepId, state: "approved" };
|
|
2051
|
+
if (isAuditedOperatorBypass(result2) && descriptor?.kind !== "workspace") {
|
|
2052
|
+
return { workflowStepId, state: "approved" };
|
|
2053
|
+
}
|
|
1833
2054
|
const bindsContent = requiresExplicitVerdict || result2.reviewInputFingerprint !== void 0;
|
|
1834
2055
|
if (!bindsContent) return { workflowStepId, state: "approved" };
|
|
1835
2056
|
}
|
|
@@ -1860,11 +2081,15 @@ function evaluateStep(workflowStepId, results, task, descriptor) {
|
|
|
1860
2081
|
if (stale2.length) return { workflowStepId, state: "stale-content", repositories: stale2 };
|
|
1861
2082
|
return { workflowStepId, state: "approved" };
|
|
1862
2083
|
}
|
|
2084
|
+
var AUTOMATED_BYPASS_ACTORS, UNPROVEN_REVIEW_APPROVAL_DIAGNOSTIC;
|
|
1863
2085
|
var init_pre_merge_approval = __esm({
|
|
1864
2086
|
"../core/src/merge/pre-merge-approval.ts"() {
|
|
1865
2087
|
"use strict";
|
|
1866
2088
|
init_builtin_plan_review_group();
|
|
2089
|
+
init_workflow_fast_lane();
|
|
1867
2090
|
init_workflow_step_results();
|
|
2091
|
+
AUTOMATED_BYPASS_ACTORS = /* @__PURE__ */ new Set([FAST_MODE_BYPASS_ACTOR]);
|
|
2092
|
+
UNPROVEN_REVIEW_APPROVAL_DIAGNOSTIC = "Content-binding review approval recorded without reviewInputFingerprint; approval invalidated so the gate can run again.";
|
|
1868
2093
|
}
|
|
1869
2094
|
});
|
|
1870
2095
|
|
|
@@ -6426,7 +6651,7 @@ function scoreLatinLocale(text3) {
|
|
|
6426
6651
|
return { locale: "en", confidence: "low" };
|
|
6427
6652
|
}
|
|
6428
6653
|
const ratio = secondScore === 0 ? Infinity : bestScore / secondScore;
|
|
6429
|
-
const confidence = bestScore >= 4 && ratio >= 1.6 ? "high" : bestScore >=
|
|
6654
|
+
const confidence = bestScore >= 4 && ratio >= 1.6 ? "high" : bestScore >= 3 && ratio >= 1.5 ? "medium" : "low";
|
|
6430
6655
|
return { locale: best[0] === "cs" ? "unknown" : best[0], confidence };
|
|
6431
6656
|
}
|
|
6432
6657
|
function detectContentLanguage(text3) {
|
|
@@ -6568,11 +6793,16 @@ var init_detect_content_language = __esm({
|
|
|
6568
6793
|
"there",
|
|
6569
6794
|
"should"
|
|
6570
6795
|
],
|
|
6796
|
+
/*
|
|
6797
|
+
FNXC:TitleSummaryInputLanguage 2026-09-01-21:25:
|
|
6798
|
+
FN-9241 found that English and technical chat prose can contain `plus`, `par`, and `est`.
|
|
6799
|
+
Omit these collision-prone French tokens so a short English message cannot steer title generation
|
|
6800
|
+
toward French; stronger medium confidence keeps the import translation high-confidence behavior unchanged.
|
|
6801
|
+
*/
|
|
6571
6802
|
fr: [
|
|
6572
6803
|
"les",
|
|
6573
6804
|
"des",
|
|
6574
6805
|
"une",
|
|
6575
|
-
"est",
|
|
6576
6806
|
"dans",
|
|
6577
6807
|
"pour",
|
|
6578
6808
|
"que",
|
|
@@ -6580,8 +6810,6 @@ var init_detect_content_language = __esm({
|
|
|
6580
6810
|
"sur",
|
|
6581
6811
|
"avec",
|
|
6582
6812
|
"pas",
|
|
6583
|
-
"plus",
|
|
6584
|
-
"par",
|
|
6585
6813
|
"sont",
|
|
6586
6814
|
"cette",
|
|
6587
6815
|
"aussi",
|
|
@@ -11374,35 +11602,6 @@ var init_workflow_ir_types = __esm({
|
|
|
11374
11602
|
}
|
|
11375
11603
|
});
|
|
11376
11604
|
|
|
11377
|
-
// ../core/src/workflows/workflow-merge-region.ts
|
|
11378
|
-
function isMergeRegionNode(node) {
|
|
11379
|
-
return MERGE_REGION_ENTRY_NODE_KINDS.has(node.kind) || node.config?.seam === "merge";
|
|
11380
|
-
}
|
|
11381
|
-
function classifyWorkflowNodeMergeRegion(ir2, nodeId) {
|
|
11382
|
-
if (ir2.version !== "v2" || !Array.isArray(ir2.nodes)) return "unknown";
|
|
11383
|
-
const node = ir2.nodes.find((candidate) => candidate.id === nodeId);
|
|
11384
|
-
if (!node) return "unknown";
|
|
11385
|
-
return isMergeRegionNode(node) ? "merge-region" : "outside-merge-region";
|
|
11386
|
-
}
|
|
11387
|
-
var MERGE_REGION_ENTRY_NODE_KINDS;
|
|
11388
|
-
var init_workflow_merge_region = __esm({
|
|
11389
|
-
"../core/src/workflows/workflow-merge-region.ts"() {
|
|
11390
|
-
"use strict";
|
|
11391
|
-
MERGE_REGION_ENTRY_NODE_KINDS = /* @__PURE__ */ new Set([
|
|
11392
|
-
"merge-gate",
|
|
11393
|
-
"merge-attempt",
|
|
11394
|
-
"manual-merge-hold",
|
|
11395
|
-
"retry-backoff",
|
|
11396
|
-
"recovery-router",
|
|
11397
|
-
"branch-group-member-integration",
|
|
11398
|
-
"branch-group-promotion",
|
|
11399
|
-
"pr-create",
|
|
11400
|
-
"pr-respond",
|
|
11401
|
-
"pr-merge"
|
|
11402
|
-
]);
|
|
11403
|
-
}
|
|
11404
|
-
});
|
|
11405
|
-
|
|
11406
11605
|
// ../core/src/workflows/workflow-extension-types.ts
|
|
11407
11606
|
function workflowExtensionRegistryId(pluginId, extensionId) {
|
|
11408
11607
|
return `plugin:${pluginId}:${extensionId}`;
|
|
@@ -12398,6 +12597,16 @@ function validateReviewerAgentOverrides(nodes2) {
|
|
|
12398
12597
|
if (Array.isArray(templateNodes)) validateReviewerAgentOverrides(templateNodes);
|
|
12399
12598
|
}
|
|
12400
12599
|
}
|
|
12600
|
+
function validateReadonlyMcpServersConfig(nodes2) {
|
|
12601
|
+
for (const node of nodes2) {
|
|
12602
|
+
const value = node.config?.readonlyMcpServers;
|
|
12603
|
+
if (value !== void 0 && (!Array.isArray(value) || value.some((name2) => typeof name2 !== "string" || !name2.trim()))) {
|
|
12604
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' readonlyMcpServers must be an array of non-empty strings when present`);
|
|
12605
|
+
}
|
|
12606
|
+
const templateNodes = node.config?.template?.nodes;
|
|
12607
|
+
if (Array.isArray(templateNodes)) validateReadonlyMcpServersConfig(templateNodes);
|
|
12608
|
+
}
|
|
12609
|
+
}
|
|
12401
12610
|
function validateThinkingLevelConfig(nodes2) {
|
|
12402
12611
|
for (const node of nodes2) {
|
|
12403
12612
|
const value = node.config?.thinkingLevel;
|
|
@@ -13012,6 +13221,7 @@ function validateV2(ir2) {
|
|
|
13012
13221
|
const topLevelIds = new Set(ir2.nodes.map((n) => n.id));
|
|
13013
13222
|
validateStepExecutePlacement(ir2.nodes);
|
|
13014
13223
|
validateThinkingLevelConfig(ir2.nodes);
|
|
13224
|
+
validateReadonlyMcpServersConfig(ir2.nodes);
|
|
13015
13225
|
validateCredentialInstanceIdConfig(ir2.nodes);
|
|
13016
13226
|
validateReviewerAgentOverrides(ir2.nodes);
|
|
13017
13227
|
for (const node of ir2.nodes) {
|
|
@@ -29082,169 +29292,6 @@ var init_explicit_duplicate_marker = __esm({
|
|
|
29082
29292
|
}
|
|
29083
29293
|
});
|
|
29084
29294
|
|
|
29085
|
-
// ../core/src/workflows/workflow-optional-steps.ts
|
|
29086
|
-
function isWorkflowOptionalGroupEnabled(enabledWorkflowSteps, groupId, defaultOn = false) {
|
|
29087
|
-
return Array.isArray(enabledWorkflowSteps) ? enabledWorkflowSteps.includes(groupId) : defaultOn;
|
|
29088
|
-
}
|
|
29089
|
-
function isOptionalGroupNode(node) {
|
|
29090
|
-
return node.kind === "optional-group";
|
|
29091
|
-
}
|
|
29092
|
-
function computeNodeExecutionRanks(ir2) {
|
|
29093
|
-
const ranks = /* @__PURE__ */ new Map();
|
|
29094
|
-
if (ir2.version !== "v2" || !Array.isArray(ir2.nodes) || !Array.isArray(ir2.edges)) {
|
|
29095
|
-
return ranks;
|
|
29096
|
-
}
|
|
29097
|
-
const outgoing = /* @__PURE__ */ new Map();
|
|
29098
|
-
for (const edge of ir2.edges) {
|
|
29099
|
-
if (!outgoing.has(edge.from)) outgoing.set(edge.from, []);
|
|
29100
|
-
outgoing.get(edge.from)?.push(edge.to);
|
|
29101
|
-
}
|
|
29102
|
-
const queue = [];
|
|
29103
|
-
for (const node of ir2.nodes) {
|
|
29104
|
-
if (node.kind === "start" || node.id === "start") {
|
|
29105
|
-
queue.push({ id: node.id, rank: 0 });
|
|
29106
|
-
}
|
|
29107
|
-
}
|
|
29108
|
-
while (queue.length > 0) {
|
|
29109
|
-
const next = queue.shift();
|
|
29110
|
-
if (!next) continue;
|
|
29111
|
-
const current = ranks.get(next.id);
|
|
29112
|
-
if (current !== void 0 && current <= next.rank) continue;
|
|
29113
|
-
ranks.set(next.id, next.rank);
|
|
29114
|
-
for (const target of outgoing.get(next.id) ?? []) {
|
|
29115
|
-
queue.push({ id: target, rank: next.rank + 1 });
|
|
29116
|
-
}
|
|
29117
|
-
}
|
|
29118
|
-
return ranks;
|
|
29119
|
-
}
|
|
29120
|
-
function resolveWorkflowOptionalSteps(ir2, _pluginTemplates = []) {
|
|
29121
|
-
if (ir2.version !== "v2" || !Array.isArray(ir2.nodes)) return [];
|
|
29122
|
-
const ranks = computeNodeExecutionRanks(ir2);
|
|
29123
|
-
const resolved = [];
|
|
29124
|
-
for (const [nodeIndex, node] of ir2.nodes.entries()) {
|
|
29125
|
-
if (!isOptionalGroupNode(node)) continue;
|
|
29126
|
-
const config3 = node.config ?? {};
|
|
29127
|
-
resolved.push({
|
|
29128
|
-
// Keyed by the group node id (documented above); field name preserved.
|
|
29129
|
-
templateId: node.id,
|
|
29130
|
-
name: typeof config3.name === "string" && config3.name.trim() ? config3.name : node.id,
|
|
29131
|
-
description: "",
|
|
29132
|
-
/*
|
|
29133
|
-
FNXC:WorkflowOptionalSteps 2026-06-29-12:47:
|
|
29134
|
-
Post-merge verification is now a graph-native optional group. Task creation and detail surfaces need the resolver to preserve `config.phase` so post-merge toggles do not look like pre-merge gates.
|
|
29135
|
-
*/
|
|
29136
|
-
phase: config3.phase === "post-merge" ? "post-merge" : "pre-merge",
|
|
29137
|
-
defaultOn: config3.defaultOn === true,
|
|
29138
|
-
reportingOnly: config3.reportingOnly === true,
|
|
29139
|
-
/*
|
|
29140
|
-
FNXC:WorkflowDefinitionSteps 2026-06-29-00:41:
|
|
29141
|
-
Definition/task creation surfaces must order optional groups by graph execution position, not raw node-array order. Derived built-ins can insert Plan Review between planning and parse while appending its node object, and operators still need the step list to show Plan Review before execution.
|
|
29142
|
-
*/
|
|
29143
|
-
rank: ranks.get(node.id) ?? Number.MAX_SAFE_INTEGER,
|
|
29144
|
-
nodeIndex
|
|
29145
|
-
});
|
|
29146
|
-
}
|
|
29147
|
-
return resolved.sort((a, b3) => a.rank - b3.rank || a.nodeIndex - b3.nodeIndex).map(({ rank: _rank, nodeIndex: _nodeIndex, ...step }) => step);
|
|
29148
|
-
}
|
|
29149
|
-
function resolveDefaultOnOptionalGroupIds(ir2) {
|
|
29150
|
-
return resolveWorkflowOptionalSteps(ir2).filter((step) => step.defaultOn).map((step) => step.templateId);
|
|
29151
|
-
}
|
|
29152
|
-
function resolveAllOptionalGroupIds(ir2) {
|
|
29153
|
-
return resolveWorkflowOptionalSteps(ir2).map((step) => step.templateId);
|
|
29154
|
-
}
|
|
29155
|
-
function isReportingOnlyOptionalGroup(ir2, nodeId) {
|
|
29156
|
-
if (!nodeId) return false;
|
|
29157
|
-
return resolveWorkflowOptionalSteps(ir2).some((step) => step.templateId === nodeId && step.reportingOnly);
|
|
29158
|
-
}
|
|
29159
|
-
var init_workflow_optional_steps = __esm({
|
|
29160
|
-
"../core/src/workflows/workflow-optional-steps.ts"() {
|
|
29161
|
-
"use strict";
|
|
29162
|
-
}
|
|
29163
|
-
});
|
|
29164
|
-
|
|
29165
|
-
// ../core/src/workflows/workflow-fast-lane.ts
|
|
29166
|
-
function isFastExecutionMode(task) {
|
|
29167
|
-
return task.executionMode === "fast";
|
|
29168
|
-
}
|
|
29169
|
-
function configString(node, key) {
|
|
29170
|
-
const value = node.config?.[key];
|
|
29171
|
-
return typeof value === "string" ? value : void 0;
|
|
29172
|
-
}
|
|
29173
|
-
function isTaskStepsForeach(node) {
|
|
29174
|
-
return node.kind === "foreach" && node.config?.source === "task-steps";
|
|
29175
|
-
}
|
|
29176
|
-
function isFastLaneSkippableCustomNode(node, opts = {}) {
|
|
29177
|
-
if (node.config?.summaryTarget === "task" || node.id === "completion-summary") return false;
|
|
29178
|
-
if (opts.optionalGroupId) return false;
|
|
29179
|
-
if (node.config?.seam) return false;
|
|
29180
|
-
return node.kind === "prompt" || node.kind === "script" || node.kind === "gate";
|
|
29181
|
-
}
|
|
29182
|
-
function isFastLaneBypassedTemplateNode(node) {
|
|
29183
|
-
return node.kind === "step-review";
|
|
29184
|
-
}
|
|
29185
|
-
function inactiveRoute() {
|
|
29186
|
-
return {
|
|
29187
|
-
active: false,
|
|
29188
|
-
bypassedNodeIds: /* @__PURE__ */ new Set(),
|
|
29189
|
-
bypassedPreMergeGroups: [],
|
|
29190
|
-
parseStepsNodeIds: /* @__PURE__ */ new Set()
|
|
29191
|
-
};
|
|
29192
|
-
}
|
|
29193
|
-
function resolveFastLaneRoute(ir2, task) {
|
|
29194
|
-
if (!isFastExecutionMode(task)) return inactiveRoute();
|
|
29195
|
-
const foreachNode = ir2.nodes.find(isTaskStepsForeach);
|
|
29196
|
-
const executeNode = ir2.nodes.find((node) => configString(node, "seam") === "execute");
|
|
29197
|
-
const implementationNode = foreachNode ?? executeNode;
|
|
29198
|
-
if (!implementationNode) {
|
|
29199
|
-
return { ...inactiveRoute(), unsupportedReason: "no-implementation-node" };
|
|
29200
|
-
}
|
|
29201
|
-
const implementationKind = foreachNode ? "foreach-steps" : "execute-seam";
|
|
29202
|
-
const bypassedPreMergeGroups = resolveWorkflowOptionalSteps(ir2).filter((step) => step.phase === "pre-merge").map((step) => ({ nodeId: step.templateId, name: step.name }));
|
|
29203
|
-
const bypassedGroupIds = new Set(bypassedPreMergeGroups.map((group) => group.nodeId));
|
|
29204
|
-
const bypassedNodeIds = /* @__PURE__ */ new Set();
|
|
29205
|
-
for (const node of ir2.nodes) {
|
|
29206
|
-
if (isMergeRegionNode(node) || node.id === "completion-summary" || node.config?.summaryTarget === "task") continue;
|
|
29207
|
-
if (configString(node, "seam") === "planning") {
|
|
29208
|
-
bypassedNodeIds.add(node.id);
|
|
29209
|
-
continue;
|
|
29210
|
-
}
|
|
29211
|
-
if (bypassedGroupIds.has(node.id)) {
|
|
29212
|
-
bypassedNodeIds.add(node.id);
|
|
29213
|
-
continue;
|
|
29214
|
-
}
|
|
29215
|
-
const workflowAction = configString(node, "workflowAction");
|
|
29216
|
-
const groupId = configString(node, "forWorkflowStepId");
|
|
29217
|
-
if (workflowAction === "plan-replan" || workflowAction === "plan-review-no-op" || workflowAction === "pre-merge-remediation" || workflowAction === "review-remediation-steps" || groupId !== void 0 && bypassedGroupIds.has(groupId)) {
|
|
29218
|
-
bypassedNodeIds.add(node.id);
|
|
29219
|
-
}
|
|
29220
|
-
}
|
|
29221
|
-
const parseStepsNodeIds = new Set(ir2.nodes.filter((node) => node.kind === "parse-steps").map((node) => node.id));
|
|
29222
|
-
for (const parseNodeId of parseStepsNodeIds) {
|
|
29223
|
-
if (bypassedNodeIds.has(parseNodeId)) {
|
|
29224
|
-
throw new Error(`Fast lane cannot bypass parse-steps node '${parseNodeId}'`);
|
|
29225
|
-
}
|
|
29226
|
-
}
|
|
29227
|
-
return {
|
|
29228
|
-
active: true,
|
|
29229
|
-
bypassedNodeIds,
|
|
29230
|
-
bypassedPreMergeGroups,
|
|
29231
|
-
parseStepsNodeIds,
|
|
29232
|
-
implementationNodeId: implementationNode.id,
|
|
29233
|
-
implementationKind
|
|
29234
|
-
};
|
|
29235
|
-
}
|
|
29236
|
-
var FAST_LANE_STEP_NAME, FAST_LANE_SKIP_VALUE, FAST_LANE_STEP_REVIEW_ROUTE_VALUE;
|
|
29237
|
-
var init_workflow_fast_lane = __esm({
|
|
29238
|
-
"../core/src/workflows/workflow-fast-lane.ts"() {
|
|
29239
|
-
"use strict";
|
|
29240
|
-
init_workflow_merge_region();
|
|
29241
|
-
init_workflow_optional_steps();
|
|
29242
|
-
FAST_LANE_STEP_NAME = "Fast implementation";
|
|
29243
|
-
FAST_LANE_SKIP_VALUE = "fast-lane-skip";
|
|
29244
|
-
FAST_LANE_STEP_REVIEW_ROUTE_VALUE = "approve";
|
|
29245
|
-
}
|
|
29246
|
-
});
|
|
29247
|
-
|
|
29248
29295
|
// ../core/src/mesh/mesh-task-replication.ts
|
|
29249
29296
|
function buildBootstrapPrompt(taskId, title, description) {
|
|
29250
29297
|
const heading = title ? `${taskId}: ${title}` : taskId;
|
|
@@ -66445,10 +66492,10 @@ var init_migration = __esm({
|
|
|
66445
66492
|
return basename6(projectPath);
|
|
66446
66493
|
}
|
|
66447
66494
|
try {
|
|
66448
|
-
const { execFile:
|
|
66449
|
-
const { promisify:
|
|
66450
|
-
const
|
|
66451
|
-
const { stdout } = await
|
|
66495
|
+
const { execFile: execFile47 } = await import("node:child_process");
|
|
66496
|
+
const { promisify: promisify102 } = await import("node:util");
|
|
66497
|
+
const execFileAsync41 = promisify102(execFile47);
|
|
66498
|
+
const { stdout } = await execFileAsync41(
|
|
66452
66499
|
"git",
|
|
66453
66500
|
["remote", "get-url", "origin"],
|
|
66454
66501
|
{ cwd: projectPath, timeout: 1e3 }
|
|
@@ -68643,10 +68690,10 @@ var init_central_core = __esm({
|
|
|
68643
68690
|
*/
|
|
68644
68691
|
async generateProjectName(projectPath) {
|
|
68645
68692
|
try {
|
|
68646
|
-
const { execFile:
|
|
68647
|
-
const { promisify:
|
|
68648
|
-
const
|
|
68649
|
-
const { stdout } = await
|
|
68693
|
+
const { execFile: execFile47 } = await import("node:child_process");
|
|
68694
|
+
const { promisify: promisify102 } = await import("node:util");
|
|
68695
|
+
const execFileAsync41 = promisify102(execFile47);
|
|
68696
|
+
const { stdout } = await execFileAsync41(
|
|
68650
68697
|
"git",
|
|
68651
68698
|
["remote", "get-url", "origin"],
|
|
68652
68699
|
{ cwd: projectPath, timeout: 5e3 }
|
|
@@ -85448,14 +85495,12 @@ async function listWorkflowDefinitionsImpl(store, options) {
|
|
|
85448
85495
|
return pluginFiltered;
|
|
85449
85496
|
}
|
|
85450
85497
|
async function readAllWorkflowDefinitionsImpl(store) {
|
|
85451
|
-
if (store.workflowDefinitionsCache) return store.workflowDefinitionsCache;
|
|
85452
85498
|
const layer = store.getAsyncLayer();
|
|
85453
85499
|
if (!layer) {
|
|
85454
85500
|
throw new Error("workflow definitions: AsyncDataLayer not initialized in backend mode");
|
|
85455
85501
|
}
|
|
85456
85502
|
const rows = await listWorkflowRows(layer);
|
|
85457
|
-
|
|
85458
|
-
return store.workflowDefinitionsCache;
|
|
85503
|
+
return [...BUILTIN_WORKFLOWS, ...rows.map((row) => store.toWorkflowDefinition(row))];
|
|
85459
85504
|
}
|
|
85460
85505
|
async function getWorkflowDefinitionImpl(store, id) {
|
|
85461
85506
|
const builtin = getBuiltinWorkflow(id);
|
|
@@ -85524,7 +85569,6 @@ function insertWorkflowDefinitionSyncImpl(store, input) {
|
|
|
85524
85569
|
if (!isWorkflowDefinitionIdPrimaryKeyCollision(error3)) throw error3;
|
|
85525
85570
|
continue;
|
|
85526
85571
|
}
|
|
85527
|
-
store.workflowDefinitionsCache = null;
|
|
85528
85572
|
return definition;
|
|
85529
85573
|
}
|
|
85530
85574
|
throw new Error("Unable to allocate a free workflow definition id after repeated id collisions");
|
|
@@ -85914,11 +85958,6 @@ function getPluginStoreImpl(store) {
|
|
|
85914
85958
|
...pluginLayer ? { asyncLayer: pluginLayer } : {}
|
|
85915
85959
|
}
|
|
85916
85960
|
);
|
|
85917
|
-
const clearWorkflowDefinitionCache = () => {
|
|
85918
|
-
store.workflowDefinitionsCache = null;
|
|
85919
|
-
};
|
|
85920
|
-
store.pluginStore.on("plugin:registered", clearWorkflowDefinitionCache);
|
|
85921
|
-
store.pluginStore.on("plugin:unregistered", clearWorkflowDefinitionCache);
|
|
85922
85961
|
}
|
|
85923
85962
|
return store.pluginStore;
|
|
85924
85963
|
}
|
|
@@ -90290,11 +90329,11 @@ async function searchWithQmd(rootDir, options) {
|
|
|
90290
90329
|
const command = "qmd";
|
|
90291
90330
|
const limit = Math.max(1, Math.min(options.limit ?? 5, 20));
|
|
90292
90331
|
try {
|
|
90293
|
-
const
|
|
90294
|
-
await ensureQmdProjectMemoryCollection(rootDir,
|
|
90332
|
+
const execFileAsync41 = await getDefaultExecFileAsync();
|
|
90333
|
+
await ensureQmdProjectMemoryCollection(rootDir, execFileAsync41);
|
|
90295
90334
|
scheduleQmdProjectMemoryRefresh(rootDir);
|
|
90296
90335
|
const args = buildQmdSearchArgs(rootDir, options);
|
|
90297
|
-
const { stdout } = await
|
|
90336
|
+
const { stdout } = await execFileAsync41(command, args, {
|
|
90298
90337
|
cwd: rootDir,
|
|
90299
90338
|
timeout: 4e3,
|
|
90300
90339
|
maxBuffer: 1024 * 1024
|
|
@@ -90319,12 +90358,12 @@ async function searchWithQmd(rootDir, options) {
|
|
|
90319
90358
|
return [];
|
|
90320
90359
|
}
|
|
90321
90360
|
}
|
|
90322
|
-
async function ensureQmdProjectMemoryCollection(rootDir,
|
|
90361
|
+
async function ensureQmdProjectMemoryCollection(rootDir, execFileAsync41) {
|
|
90323
90362
|
const collectionName = qmdMemoryCollectionName(rootDir);
|
|
90324
90363
|
const memoryDir = memoryWorkspacePath(rootDir);
|
|
90325
90364
|
await mkdir10(memoryDir, { recursive: true });
|
|
90326
90365
|
try {
|
|
90327
|
-
await
|
|
90366
|
+
await execFileAsync41("qmd", buildQmdCollectionAddArgs(rootDir), {
|
|
90328
90367
|
cwd: rootDir,
|
|
90329
90368
|
timeout: 4e3,
|
|
90330
90369
|
maxBuffer: 512 * 1024
|
|
@@ -90422,14 +90461,14 @@ async function refreshQmdProjectMemoryIndex(rootDir, options) {
|
|
|
90422
90461
|
}
|
|
90423
90462
|
}
|
|
90424
90463
|
const promise = (async () => {
|
|
90425
|
-
const
|
|
90426
|
-
await ensureQmdProjectMemoryCollection(rootDir,
|
|
90427
|
-
await
|
|
90464
|
+
const execFileAsync41 = options?.execFileAsync ?? await getDefaultExecFileAsync();
|
|
90465
|
+
await ensureQmdProjectMemoryCollection(rootDir, execFileAsync41);
|
|
90466
|
+
await execFileAsync41("qmd", ["update"], {
|
|
90428
90467
|
cwd: rootDir,
|
|
90429
90468
|
timeout: 3e4,
|
|
90430
90469
|
maxBuffer: 1024 * 1024
|
|
90431
90470
|
});
|
|
90432
|
-
await
|
|
90471
|
+
await execFileAsync41("qmd", ["embed"], {
|
|
90433
90472
|
cwd: rootDir,
|
|
90434
90473
|
timeout: 12e4,
|
|
90435
90474
|
maxBuffer: 1024 * 1024
|
|
@@ -90465,12 +90504,12 @@ async function refreshQmdAgentMemoryIndex(rootDir, agentId, options) {
|
|
|
90465
90504
|
}
|
|
90466
90505
|
}
|
|
90467
90506
|
const promise = (async () => {
|
|
90468
|
-
const
|
|
90507
|
+
const execFileAsync41 = options?.execFileAsync ?? await getDefaultExecFileAsync();
|
|
90469
90508
|
const { agentMemoryWorkspacePath: agentMemoryWorkspacePath2 } = await Promise.resolve().then(() => (init_memory_dreams(), memory_dreams_exports));
|
|
90470
90509
|
const workspacePath = agentMemoryWorkspacePath2(rootDir, agentId);
|
|
90471
90510
|
await mkdir10(workspacePath, { recursive: true });
|
|
90472
90511
|
try {
|
|
90473
|
-
await
|
|
90512
|
+
await execFileAsync41("qmd", ["collection", "add", workspacePath, "--name", qmdAgentMemoryCollectionName(rootDir, agentId), "--mask", "**/*.md"], {
|
|
90474
90513
|
cwd: rootDir,
|
|
90475
90514
|
timeout: 4e3,
|
|
90476
90515
|
maxBuffer: 512 * 1024
|
|
@@ -90483,8 +90522,8 @@ ${stderr}`)) {
|
|
|
90483
90522
|
throw err;
|
|
90484
90523
|
}
|
|
90485
90524
|
}
|
|
90486
|
-
await
|
|
90487
|
-
await
|
|
90525
|
+
await execFileAsync41("qmd", ["update"], { cwd: rootDir, timeout: 3e4, maxBuffer: 1024 * 1024 });
|
|
90526
|
+
await execFileAsync41("qmd", ["embed"], { cwd: rootDir, timeout: 12e4, maxBuffer: 1024 * 1024 });
|
|
90488
90527
|
})();
|
|
90489
90528
|
qmdAgentRefreshState.set(key, { lastStartedAt: now, inFlight: promise });
|
|
90490
90529
|
try {
|
|
@@ -90505,8 +90544,8 @@ function scheduleQmdAgentMemoryRefresh(rootDir, agentId) {
|
|
|
90505
90544
|
}
|
|
90506
90545
|
async function isQmdAvailable() {
|
|
90507
90546
|
try {
|
|
90508
|
-
const
|
|
90509
|
-
await
|
|
90547
|
+
const execFileAsync41 = await getDefaultExecFileAsync();
|
|
90548
|
+
await execFileAsync41("qmd", ["--help"], {
|
|
90510
90549
|
timeout: 3e3,
|
|
90511
90550
|
maxBuffer: 128 * 1024,
|
|
90512
90551
|
keepAlive: true
|
|
@@ -90517,12 +90556,12 @@ async function isQmdAvailable() {
|
|
|
90517
90556
|
}
|
|
90518
90557
|
}
|
|
90519
90558
|
async function installQmd(options) {
|
|
90520
|
-
const
|
|
90559
|
+
const execFileAsync41 = options?.execFileAsync ?? await getDefaultExecFileAsync();
|
|
90521
90560
|
const [command, ...args] = QMD_INSTALL_COMMAND.split(" ");
|
|
90522
90561
|
if (!command || args.length === 0) {
|
|
90523
90562
|
throw new MemoryBackendError("BACKEND_UNAVAILABLE", "qmd install command is not configured", "qmd");
|
|
90524
90563
|
}
|
|
90525
|
-
await
|
|
90564
|
+
await execFileAsync41(command, args, {
|
|
90526
90565
|
timeout: 12e4,
|
|
90527
90566
|
maxBuffer: 1024 * 1024
|
|
90528
90567
|
});
|
|
@@ -94899,7 +94938,7 @@ Your ONLY job is to create a concise title (max 60 characters) that summarizes t
|
|
|
94899
94938
|
|
|
94900
94939
|
## Style
|
|
94901
94940
|
- Clear, descriptive, actionable, professional
|
|
94902
|
-
- Write the title in the SAME language as the task description content.
|
|
94941
|
+
- Write the title in the SAME language as the task description content.
|
|
94903
94942
|
- Maximum 60 characters
|
|
94904
94943
|
- Focus on the main goal or deliverable of the task`;
|
|
94905
94944
|
MAX_DESCRIPTION_LENGTH = 2e3;
|
|
@@ -100037,7 +100076,6 @@ async function createWorkflowDefinitionImpl(store, input) {
|
|
|
100037
100076
|
if (!isWorkflowDefinitionIdPrimaryKeyCollision(error3)) throw error3;
|
|
100038
100077
|
continue;
|
|
100039
100078
|
}
|
|
100040
|
-
store.workflowDefinitionsCache = null;
|
|
100041
100079
|
return definition;
|
|
100042
100080
|
}
|
|
100043
100081
|
throw new Error("Unable to allocate a free workflow definition id after repeated id collisions");
|
|
@@ -103621,7 +103659,6 @@ async function updateWorkflowDefinitionImpl(store, id, updates) {
|
|
|
103621
103659
|
eq(project_exports.workflows.id, id),
|
|
103622
103660
|
projectScopeFor(project_exports.workflows.projectId, layer.projectId)
|
|
103623
103661
|
));
|
|
103624
|
-
store.workflowDefinitionsCache = null;
|
|
103625
103662
|
return next;
|
|
103626
103663
|
});
|
|
103627
103664
|
if (pendingRehome) {
|
|
@@ -103656,7 +103693,6 @@ async function deleteWorkflowDefinitionImpl(store, id) {
|
|
|
103656
103693
|
projectScopeFor(project_exports.workflows.projectId, layer.projectId)
|
|
103657
103694
|
)).returning();
|
|
103658
103695
|
if (deleted.length === 0) throw new Error(`Workflow '${id}' not found`);
|
|
103659
|
-
store.workflowDefinitionsCache = null;
|
|
103660
103696
|
await layer.db.delete(project_exports.workflowSettings).where(and(
|
|
103661
103697
|
eq(project_exports.workflowSettings.workflowId, id),
|
|
103662
103698
|
projectScopeFor(project_exports.workflowSettings.projectId, layer.projectId)
|
|
@@ -108250,7 +108286,6 @@ var init_store = __esm({
|
|
|
108250
108286
|
taskIdIntegrityReport = { status: "ok", checkedAt: (/* @__PURE__ */ new Date()).toISOString(), anomalies: [] };
|
|
108251
108287
|
lastTaskIdIntegrityLogSignature = null;
|
|
108252
108288
|
workflowStepsCache = null;
|
|
108253
|
-
workflowDefinitionsCache = null;
|
|
108254
108289
|
_pluginWorkflowStepTemplates = [];
|
|
108255
108290
|
globalSettingsStore;
|
|
108256
108291
|
donePauseBackfillDone = false;
|
|
@@ -115880,7 +115915,7 @@ function getPostMergeFinalizeBlocker(task) {
|
|
|
115880
115915
|
}
|
|
115881
115916
|
function planConfirmedMergeChecklistReconciliation(task) {
|
|
115882
115917
|
return {
|
|
115883
|
-
skippedStepIndexes: task.steps.map((step, index2) => step.status === "pending" || step.status === "in-progress" ? index2 : -1).filter((index2) => index2 >= 0),
|
|
115918
|
+
skippedStepIndexes: (task.steps ?? []).map((step, index2) => step.status === "pending" || step.status === "in-progress" ? index2 : -1).filter((index2) => index2 >= 0),
|
|
115884
115919
|
reconciledWorkflowStepIds: (task.workflowStepResults ?? []).filter((result2) => result2.status === "pending").map((result2) => result2.workflowStepId)
|
|
115885
115920
|
};
|
|
115886
115921
|
}
|
|
@@ -135930,11 +135965,11 @@ var require_extract_zip = __commonJS({
|
|
|
135930
135965
|
var { createWriteStream, promises: fs10 } = __require("fs");
|
|
135931
135966
|
var getStream = require_get_stream();
|
|
135932
135967
|
var path13 = __require("path");
|
|
135933
|
-
var { promisify:
|
|
135968
|
+
var { promisify: promisify102 } = __require("util");
|
|
135934
135969
|
var stream = __require("stream");
|
|
135935
135970
|
var yauzl = require_yauzl();
|
|
135936
|
-
var openZip =
|
|
135937
|
-
var pipeline =
|
|
135971
|
+
var openZip = promisify102(yauzl.open);
|
|
135972
|
+
var pipeline = promisify102(stream.pipeline);
|
|
135938
135973
|
var Extractor = class {
|
|
135939
135974
|
constructor(zipPath, opts) {
|
|
135940
135975
|
this.zipPath = zipPath;
|
|
@@ -136016,7 +136051,7 @@ var require_extract_zip = __commonJS({
|
|
|
136016
136051
|
await fs10.mkdir(destDir, mkdirOptions);
|
|
136017
136052
|
if (isDir) return;
|
|
136018
136053
|
debug("opening read stream", dest);
|
|
136019
|
-
const readStream = await
|
|
136054
|
+
const readStream = await promisify102(this.zipfile.openReadStream.bind(this.zipfile))(entry);
|
|
136020
136055
|
if (symlink) {
|
|
136021
136056
|
const link = await getStream(readStream);
|
|
136022
136057
|
debug("creating symlink", link, dest);
|
|
@@ -137455,6 +137490,7 @@ async function updateChatSession(handle2, id, input) {
|
|
|
137455
137490
|
if (input.status !== void 0) setValues.status = input.status;
|
|
137456
137491
|
if (input.modelProvider !== void 0) setValues.modelProvider = input.modelProvider;
|
|
137457
137492
|
if (input.modelId !== void 0) setValues.modelId = input.modelId;
|
|
137493
|
+
if (input.agentId !== void 0) setValues.agentId = input.agentId;
|
|
137458
137494
|
if (input.thinkingLevel !== void 0) setValues.thinkingLevel = input.thinkingLevel;
|
|
137459
137495
|
if (input.memoryFocus !== void 0) setValues.memoryFocus = input.memoryFocus;
|
|
137460
137496
|
if (input.pinnedAt !== void 0) setValues.pinnedAt = input.pinnedAt;
|
|
@@ -138508,6 +138544,7 @@ var init_cli_session_store = __esm({
|
|
|
138508
138544
|
});
|
|
138509
138545
|
|
|
138510
138546
|
// ../core/src/secrets/oauth-credential-interop.ts
|
|
138547
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
138511
138548
|
import { existsSync as existsSync40, readFileSync as readFileSync11 } from "node:fs";
|
|
138512
138549
|
import { homedir as homedir7 } from "node:os";
|
|
138513
138550
|
import { join as join55 } from "node:path";
|
|
@@ -138567,6 +138604,22 @@ function getLastRefreshFallbackExpiryMs(lastRefresh) {
|
|
|
138567
138604
|
}
|
|
138568
138605
|
return parsed + CODEX_REFRESH_FALLBACK_WINDOW_MS;
|
|
138569
138606
|
}
|
|
138607
|
+
function isSameStoredCredentialMaterial(left, right) {
|
|
138608
|
+
if (!left || !right || left.type !== right.type) {
|
|
138609
|
+
return false;
|
|
138610
|
+
}
|
|
138611
|
+
return left.key === right.key && left.access === right.access && left.refresh === right.refresh;
|
|
138612
|
+
}
|
|
138613
|
+
function computeStoredCredentialAccountFingerprint(credential) {
|
|
138614
|
+
if (!credential) {
|
|
138615
|
+
return void 0;
|
|
138616
|
+
}
|
|
138617
|
+
const material = typeof credential.refresh === "string" && credential.refresh.length > 0 ? credential.refresh : typeof credential.access === "string" && credential.access.length > 0 ? credential.access : typeof credential.key === "string" && credential.key.length > 0 ? credential.key : void 0;
|
|
138618
|
+
if (!material) {
|
|
138619
|
+
return void 0;
|
|
138620
|
+
}
|
|
138621
|
+
return createHash22("sha256").update(`${credential.type ?? ""}\0${material}`).digest("hex").slice(0, 16);
|
|
138622
|
+
}
|
|
138570
138623
|
function isStoredAuthCredential(value) {
|
|
138571
138624
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
138572
138625
|
return false;
|
|
@@ -139537,7 +139590,7 @@ var init_task_timing = __esm({
|
|
|
139537
139590
|
});
|
|
139538
139591
|
|
|
139539
139592
|
// ../core/src/task-recommendation-notice.ts
|
|
139540
|
-
import { createHash as
|
|
139593
|
+
import { createHash as createHash23 } from "node:crypto";
|
|
139541
139594
|
function registerTaskRecommendationNoticeMailbox(store, mailbox) {
|
|
139542
139595
|
mailboxes2.set(store, mailbox);
|
|
139543
139596
|
return () => {
|
|
@@ -139562,7 +139615,7 @@ function buildTaskRecommendationNoticeContent(task, recommendations) {
|
|
|
139562
139615
|
}
|
|
139563
139616
|
function buildTaskRecommendationNoticeIdempotencyKey(taskId, recommendations) {
|
|
139564
139617
|
const ids = recommendations.map(({ id }) => id).sort().join("\n");
|
|
139565
|
-
const digest =
|
|
139618
|
+
const digest = createHash23("sha256").update(ids, "utf8").digest("hex").slice(0, 16);
|
|
139566
139619
|
return `task-recommendation-notice:${taskId}:${digest}`;
|
|
139567
139620
|
}
|
|
139568
139621
|
async function notifyOperatorOfTaskRecommendations(store, task, recommendations, settings) {
|
|
@@ -140008,6 +140061,7 @@ __export(src_exports, {
|
|
|
140008
140061
|
APPROVAL_REQUEST_STATUSES: () => APPROVAL_REQUEST_STATUSES,
|
|
140009
140062
|
ARCHIVED_TASK_DOCUMENT_ADDITION_BOUNDARY: () => ARCHIVED_TASK_DOCUMENT_ADDITION_BOUNDARY,
|
|
140010
140063
|
ARCHIVED_TASK_DOCUMENT_PUBLICATION_REJECTED: () => ARCHIVED_TASK_DOCUMENT_PUBLICATION_REJECTED,
|
|
140064
|
+
AUTOMATED_BYPASS_ACTORS: () => AUTOMATED_BYPASS_ACTORS,
|
|
140011
140065
|
AUTOMATION_PRESETS: () => AUTOMATION_PRESETS,
|
|
140012
140066
|
AUTOMATION_SELECTABLE_TOOLS: () => AUTOMATION_SELECTABLE_TOOLS,
|
|
140013
140067
|
AUTOPILOT_STATES: () => AUTOPILOT_STATES,
|
|
@@ -140203,6 +140257,7 @@ __export(src_exports, {
|
|
|
140203
140257
|
FAST_LANE_SKIP_VALUE: () => FAST_LANE_SKIP_VALUE,
|
|
140204
140258
|
FAST_LANE_STEP_NAME: () => FAST_LANE_STEP_NAME,
|
|
140205
140259
|
FAST_LANE_STEP_REVIEW_ROUTE_VALUE: () => FAST_LANE_STEP_REVIEW_ROUTE_VALUE,
|
|
140260
|
+
FAST_MODE_BYPASS_ACTOR: () => FAST_MODE_BYPASS_ACTOR,
|
|
140206
140261
|
FEATURE_LOOP_REPAIR_TRANSITIONS: () => FEATURE_LOOP_REPAIR_TRANSITIONS,
|
|
140207
140262
|
FEATURE_LOOP_STATES: () => FEATURE_LOOP_STATES,
|
|
140208
140263
|
FEATURE_STATUSES: () => FEATURE_STATUSES,
|
|
@@ -140767,6 +140822,7 @@ __export(src_exports, {
|
|
|
140767
140822
|
computeRetrySummary: () => computeRetrySummary,
|
|
140768
140823
|
computeSkillId: () => computeSkillId,
|
|
140769
140824
|
computeSnapshotChecksum: () => computeSnapshotChecksum,
|
|
140825
|
+
computeStoredCredentialAccountFingerprint: () => computeStoredCredentialAccountFingerprint,
|
|
140770
140826
|
computeWorkflowIrPin: () => computeWorkflowIrPin,
|
|
140771
140827
|
configurationTargetKey: () => configurationTargetKey,
|
|
140772
140828
|
configureApprovalRequestTtls: () => configureApprovalRequestTtls,
|
|
@@ -141089,6 +141145,7 @@ __export(src_exports, {
|
|
|
141089
141145
|
isApprovalRequestExpired: () => isApprovalRequestExpired,
|
|
141090
141146
|
isArchivedColumnRole: () => isArchivedColumnRole,
|
|
141091
141147
|
isArchivedRemediationCarrier: () => isArchivedRemediationCarrier,
|
|
141148
|
+
isAuditedOperatorBypass: () => isAuditedOperatorBypass,
|
|
141092
141149
|
isBlockingFinding: () => isBlockingFinding,
|
|
141093
141150
|
isBranchGroupComplete: () => isBranchGroupComplete,
|
|
141094
141151
|
isBranchGroupMemberLanded: () => isBranchGroupMemberLanded,
|
|
@@ -141176,6 +141233,7 @@ __export(src_exports, {
|
|
|
141176
141233
|
isReviewColumnRole: () => isReviewColumnRole,
|
|
141177
141234
|
isRunRecord: () => isRunRecord,
|
|
141178
141235
|
isRunningAgentTask: () => isRunningAgentTask,
|
|
141236
|
+
isSameStoredCredentialMaterial: () => isSameStoredCredentialMaterial,
|
|
141179
141237
|
isSanctionedEngineBackwardMove: () => isSanctionedEngineBackwardMove,
|
|
141180
141238
|
isSandboxExperimentalEnabled: () => isSandboxExperimentalEnabled,
|
|
141181
141239
|
isSecretAccessPolicy: () => isSecretAccessPolicy,
|
|
@@ -141454,6 +141512,7 @@ __export(src_exports, {
|
|
|
141454
141512
|
renderTriagePolicyPlaceholders: () => renderTriagePolicyPlaceholders,
|
|
141455
141513
|
renderValidationCause: () => renderValidationCause,
|
|
141456
141514
|
renderValidationFailureDescription: () => renderValidationFailureDescription,
|
|
141515
|
+
requiresContentReviewProof: () => requiresContentReviewProof,
|
|
141457
141516
|
requiresPlannerConfirmation: () => requiresPlannerConfirmation,
|
|
141458
141517
|
requiresWorktrunkInstallVerification: () => requiresWorktrunkInstallVerification,
|
|
141459
141518
|
resetGhAvailabilityCache: () => resetGhAvailabilityCache,
|
|
@@ -141617,6 +141676,7 @@ __export(src_exports, {
|
|
|
141617
141676
|
resolveTitleSummarizerSettingsModel: () => resolveTitleSummarizerSettingsModel,
|
|
141618
141677
|
resolveToolOutputBudget: () => resolveToolOutputBudget,
|
|
141619
141678
|
resolveTrailingVerificationStepIndex: () => resolveTrailingVerificationStepIndex,
|
|
141679
|
+
resolveUnprovenReviewApproval: () => resolveUnprovenReviewApproval,
|
|
141620
141680
|
resolveUpdateAutomationSettings: () => resolveUpdateAutomationSettings,
|
|
141621
141681
|
resolveUpdateTargetVersion: () => resolveUpdateTargetVersion,
|
|
141622
141682
|
resolveUpdatesExternallyManaged: () => resolveUpdatesExternallyManaged,
|
|
@@ -142251,7 +142311,7 @@ var init_logger3 = __esm({
|
|
|
142251
142311
|
});
|
|
142252
142312
|
|
|
142253
142313
|
// ../engine/src/agents/agent-logger.ts
|
|
142254
|
-
import { createHash as
|
|
142314
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
142255
142315
|
function truncateToolResultDetail(value) {
|
|
142256
142316
|
if (value.length <= TOOL_RESULT_DETAIL_LIMIT) return value;
|
|
142257
142317
|
return `${value.slice(0, TOOL_RESULT_DETAIL_LIMIT)}${TOOL_RESULT_DETAIL_TRUNCATION_NOTICE}`;
|
|
@@ -142359,7 +142419,7 @@ function summarizeToolArgs(name2, args) {
|
|
|
142359
142419
|
return `${key}=${clipToolArgValue(compactToolArgValue(args[key]), maximum)}`;
|
|
142360
142420
|
}).join(", ");
|
|
142361
142421
|
if (rendered.length <= TOOL_ARG_SUMMARY_MAX) return rendered;
|
|
142362
|
-
const hash3 =
|
|
142422
|
+
const hash3 = createHash24("sha256").update(fullArgsJson).digest("hex").slice(0, STRUCTURED_ARG_HASH_HEX_LEN);
|
|
142363
142423
|
const suffix = `\u2026#${hash3}`;
|
|
142364
142424
|
const keep = Math.max(0, TOOL_ARG_SUMMARY_MAX - suffix.length);
|
|
142365
142425
|
return `${rendered.slice(0, keep)}${suffix}`;
|
|
@@ -144126,6 +144186,14 @@ function resolveAiMergeRootPath(rootDir, settings) {
|
|
|
144126
144186
|
function resolveLegacyAiMergeRootPath(rootDir) {
|
|
144127
144187
|
return join58(rootDir, ".fusion", "ai-merge");
|
|
144128
144188
|
}
|
|
144189
|
+
function resolveAiMergeSearchRoots(rootDir, settings) {
|
|
144190
|
+
const roots = [
|
|
144191
|
+
resolveAiMergeRootPath(rootDir, settings),
|
|
144192
|
+
resolveLegacyAiMergeRootPath(rootDir),
|
|
144193
|
+
...settings?.worktreesDir ? [] : [join58(resolveLegacyWorktreesDirLayout(rootDir), AI_MERGE_DIRNAME)]
|
|
144194
|
+
];
|
|
144195
|
+
return [...new Set(roots)];
|
|
144196
|
+
}
|
|
144129
144197
|
function resolveWorktreesDir(rootDir, settings, workspaceContext) {
|
|
144130
144198
|
return resolveWorktreesDirLayout(rootDir, settings, workspaceContext);
|
|
144131
144199
|
}
|
|
@@ -145884,18 +145952,25 @@ function parseWorktreesFromPorcelain(porcelain) {
|
|
|
145884
145952
|
if (current.path) rows.push({ path: current.path, branch: current.branch });
|
|
145885
145953
|
return rows;
|
|
145886
145954
|
}
|
|
145955
|
+
function isRegenerableIgnoredPorcelainEntry(entry) {
|
|
145956
|
+
const path13 = entry.slice(3).replace(/\/$/, "");
|
|
145957
|
+
if (!path13 || path13.startsWith('"')) return false;
|
|
145958
|
+
const lastSegment = path13.split("/").at(-1);
|
|
145959
|
+
return lastSegment !== void 0 && REGENERABLE_IGNORED_DIR_NAMES.has(lastSegment);
|
|
145960
|
+
}
|
|
145887
145961
|
function classifyWorktreeRemovalContent(porcelain) {
|
|
145888
145962
|
const entries = porcelain.split(/\r?\n/).filter((line2) => line2.trim().length > 0);
|
|
145889
145963
|
if (entries.length === 0) return "clean";
|
|
145890
|
-
|
|
145964
|
+
if (entries.some((line2) => !line2.startsWith("!! "))) return "deliverable";
|
|
145965
|
+
return entries.every(isRegenerableIgnoredPorcelainEntry) ? "regenerable-ignored" : "ignored-only";
|
|
145891
145966
|
}
|
|
145892
145967
|
async function assertCleanForDefensiveRemoval(worktreePath) {
|
|
145893
145968
|
if (!existsSync44(worktreePath)) {
|
|
145894
|
-
return "clean";
|
|
145969
|
+
return { classification: "clean", entryCount: 0 };
|
|
145895
145970
|
}
|
|
145896
145971
|
let stdout;
|
|
145897
145972
|
try {
|
|
145898
|
-
({ stdout } = await execFileAsync6("git", ["status", "--porcelain=v1", "--ignored", "--untracked-files=normal"], {
|
|
145973
|
+
({ stdout } = await execFileAsync6("git", ["status", "--porcelain=v1", "--ignored=matching", "--untracked-files=normal"], {
|
|
145899
145974
|
cwd: worktreePath,
|
|
145900
145975
|
encoding: "utf-8",
|
|
145901
145976
|
timeout: 15e3,
|
|
@@ -145908,7 +145983,10 @@ async function assertCleanForDefensiveRemoval(worktreePath) {
|
|
|
145908
145983
|
if (classification === "deliverable") {
|
|
145909
145984
|
throw new Error(`preserving ${worktreePath}: uncommitted or ignored content present`);
|
|
145910
145985
|
}
|
|
145911
|
-
return
|
|
145986
|
+
return {
|
|
145987
|
+
classification,
|
|
145988
|
+
entryCount: stdout.split(/\r?\n/).filter((line2) => line2.trim().length > 0).length
|
|
145989
|
+
};
|
|
145912
145990
|
}
|
|
145913
145991
|
async function removeWorktree(input) {
|
|
145914
145992
|
const logger3 = {
|
|
@@ -145925,9 +146003,12 @@ async function removeWorktree(input) {
|
|
|
145925
146003
|
}
|
|
145926
146004
|
const requiresCleanWorktree = DEFENSIVE_REMOVAL_REASONS.has(input.reason);
|
|
145927
146005
|
let contentClassification;
|
|
146006
|
+
let contentEntryCount = 0;
|
|
145928
146007
|
if (requiresCleanWorktree) {
|
|
145929
146008
|
try {
|
|
145930
|
-
|
|
146009
|
+
const contentProbe = await assertCleanForDefensiveRemoval(input.worktreePath);
|
|
146010
|
+
contentClassification = contentProbe.classification;
|
|
146011
|
+
contentEntryCount = contentProbe.entryCount;
|
|
145931
146012
|
} catch (error3) {
|
|
145932
146013
|
const classification = error3 instanceof Error && error3.message.includes(": status probe failed (") ? "unverifiable" : "deliverable";
|
|
145933
146014
|
await input.audit?.git({
|
|
@@ -145944,6 +146025,17 @@ async function removeWorktree(input) {
|
|
|
145944
146025
|
throw error3;
|
|
145945
146026
|
}
|
|
145946
146027
|
if (contentClassification === "ignored-only" && !input.postLandingProof) {
|
|
146028
|
+
await input.audit?.git({
|
|
146029
|
+
type: "worktree:removal-preserved",
|
|
146030
|
+
target: input.worktreePath,
|
|
146031
|
+
metadata: {
|
|
146032
|
+
taskId: input.taskId,
|
|
146033
|
+
reason: input.reason,
|
|
146034
|
+
source: void 0,
|
|
146035
|
+
classification: "ignored-only",
|
|
146036
|
+
hasPostLandingProof: false
|
|
146037
|
+
}
|
|
146038
|
+
}).catch(() => void 0);
|
|
145947
146039
|
throw new Error(`preserving ${input.worktreePath}: uncommitted or ignored content present`);
|
|
145948
146040
|
}
|
|
145949
146041
|
}
|
|
@@ -145963,6 +146055,17 @@ async function removeWorktree(input) {
|
|
|
145963
146055
|
} catch {
|
|
145964
146056
|
}
|
|
145965
146057
|
};
|
|
146058
|
+
const recordRegenerableDiscard = async () => {
|
|
146059
|
+
if (contentClassification !== "regenerable-ignored") return;
|
|
146060
|
+
try {
|
|
146061
|
+
await input.audit?.git({
|
|
146062
|
+
type: "worktree:removal-discarded-regenerable-content",
|
|
146063
|
+
target: input.worktreePath,
|
|
146064
|
+
metadata: { taskId: input.taskId, reason: input.reason, entryCount: contentEntryCount }
|
|
146065
|
+
});
|
|
146066
|
+
} catch {
|
|
146067
|
+
}
|
|
146068
|
+
};
|
|
145966
146069
|
if (input.expectedOwnerTaskId && input.liveOwnerProbe) {
|
|
145967
146070
|
const reconciled = reconcileSelfOwnedActiveSessionForRemoval(
|
|
145968
146071
|
activeSessionRegistry,
|
|
@@ -146016,6 +146119,7 @@ async function removeWorktree(input) {
|
|
|
146016
146119
|
try {
|
|
146017
146120
|
await backend.remove(removeInput);
|
|
146018
146121
|
await recordIgnoredOnlyDiscard();
|
|
146122
|
+
await recordRegenerableDiscard();
|
|
146019
146123
|
if (input.audit) {
|
|
146020
146124
|
await input.audit.git({
|
|
146021
146125
|
type: backend.kind === "worktrunk" ? "worktree:worktrunk-remove" : "worktree:remove",
|
|
@@ -146043,6 +146147,7 @@ async function removeWorktree(input) {
|
|
|
146043
146147
|
try {
|
|
146044
146148
|
await native.remove(removeInput);
|
|
146045
146149
|
await recordIgnoredOnlyDiscard();
|
|
146150
|
+
await recordRegenerableDiscard();
|
|
146046
146151
|
await input.audit?.git({ type: "worktree:remove", target: input.worktreePath });
|
|
146047
146152
|
return { removed: true, classification: "removed" };
|
|
146048
146153
|
} catch (nativeError) {
|
|
@@ -146064,7 +146169,7 @@ function resolveWorktreeBackend(settings, deps = {}) {
|
|
|
146064
146169
|
}
|
|
146065
146170
|
return new NativeWorktreeBackend({ logger: deps.logger, settings, audit: deps.audit });
|
|
146066
146171
|
}
|
|
146067
|
-
var execAsync9, execFileAsync6, NATIVE_TIMEOUT_MS, REMOVE_TIMEOUT_MS, MAX_BUFFER3, HARMLESS_MERGE_REMOVE_ERROR_PATTERNS, WORKTRUNK_TIMEOUTS_MS, WORKTREE_BACKEND_MARKER, WorktrunkOperationError, NativeWorktreeBackend, WorktrunkWorktreeBackend, RemovalReason, ALLOWED_FORCE_REASONS, DEFENSIVE_REMOVAL_REASONS, POST_LANDING_PROOF_REASONS, InvalidForceUsageError, InvalidPostLandingProofUsageError, ActiveSessionWorktreeRemovalError;
|
|
146172
|
+
var execAsync9, execFileAsync6, NATIVE_TIMEOUT_MS, REMOVE_TIMEOUT_MS, MAX_BUFFER3, HARMLESS_MERGE_REMOVE_ERROR_PATTERNS, WORKTRUNK_TIMEOUTS_MS, WORKTREE_BACKEND_MARKER, WorktrunkOperationError, NativeWorktreeBackend, WorktrunkWorktreeBackend, RemovalReason, ALLOWED_FORCE_REASONS, DEFENSIVE_REMOVAL_REASONS, POST_LANDING_PROOF_REASONS, InvalidForceUsageError, InvalidPostLandingProofUsageError, ActiveSessionWorktreeRemovalError, REGENERABLE_IGNORED_DIR_NAMES;
|
|
146068
146173
|
var init_worktree_backend = __esm({
|
|
146069
146174
|
"../engine/src/worktree/worktree-backend.ts"() {
|
|
146070
146175
|
"use strict";
|
|
@@ -146804,6 +146909,27 @@ ${getErrorStderr(error3) ?? ""}`;
|
|
|
146804
146909
|
this.name = "ActiveSessionWorktreeRemovalError";
|
|
146805
146910
|
}
|
|
146806
146911
|
};
|
|
146912
|
+
REGENERABLE_IGNORED_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
146913
|
+
"node_modules",
|
|
146914
|
+
"dist",
|
|
146915
|
+
"build",
|
|
146916
|
+
"out",
|
|
146917
|
+
"target",
|
|
146918
|
+
"bin",
|
|
146919
|
+
"obj",
|
|
146920
|
+
"coverage",
|
|
146921
|
+
".next",
|
|
146922
|
+
".nuxt",
|
|
146923
|
+
".turbo",
|
|
146924
|
+
".svelte-kit",
|
|
146925
|
+
".parcel-cache",
|
|
146926
|
+
".pytest_cache",
|
|
146927
|
+
".mypy_cache",
|
|
146928
|
+
"__pycache__",
|
|
146929
|
+
".gradle",
|
|
146930
|
+
".venv",
|
|
146931
|
+
"venv"
|
|
146932
|
+
]);
|
|
146807
146933
|
}
|
|
146808
146934
|
});
|
|
146809
146935
|
|
|
@@ -147423,7 +147549,7 @@ var init_gating_classifications = __esm({
|
|
|
147423
147549
|
});
|
|
147424
147550
|
|
|
147425
147551
|
// ../engine/src/agents/agent-action-gate.ts
|
|
147426
|
-
import { createHash as
|
|
147552
|
+
import { createHash as createHash25 } from "node:crypto";
|
|
147427
147553
|
function getExemptTools() {
|
|
147428
147554
|
if (!_exemptTools) {
|
|
147429
147555
|
_exemptTools = new Set(DEFAULT_EXEMPT_TOOLS);
|
|
@@ -147475,7 +147601,7 @@ function evaluateAgentActionGate(params) {
|
|
|
147475
147601
|
if (params.toolName === "bash") {
|
|
147476
147602
|
const command = extractShellCommand(args);
|
|
147477
147603
|
const git11 = classifyGitCommand(command);
|
|
147478
|
-
resourceId = command ? `cmd:${
|
|
147604
|
+
resourceId = command ? `cmd:${createHash25("sha256").update(command).digest("hex").slice(0, 16)}` : void 0;
|
|
147479
147605
|
if (git11?.write) {
|
|
147480
147606
|
category = "git_write";
|
|
147481
147607
|
operation = git11.operation;
|
|
@@ -149241,6 +149367,15 @@ async function withOAuthRefreshLock(authPath, providerId, refresh) {
|
|
|
149241
149367
|
await release3();
|
|
149242
149368
|
}
|
|
149243
149369
|
}
|
|
149370
|
+
async function withOAuthInstanceLoginLock(authPath, providerId, operation) {
|
|
149371
|
+
const safeProviderId = providerId.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
149372
|
+
const release3 = await import_proper_lockfile.default.lock(`${authPath}.${safeProviderId}.instance-login`, AUTH_LOCK_OPTIONS);
|
|
149373
|
+
try {
|
|
149374
|
+
return await operation();
|
|
149375
|
+
} finally {
|
|
149376
|
+
await release3();
|
|
149377
|
+
}
|
|
149378
|
+
}
|
|
149244
149379
|
function readDefaultInstanceMap(data) {
|
|
149245
149380
|
const candidate = data.__fusionDefaultInstances;
|
|
149246
149381
|
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return {};
|
|
@@ -149530,7 +149665,7 @@ function createFusionAuthStorage() {
|
|
|
149530
149665
|
primary.reload();
|
|
149531
149666
|
const selectPersistedRefreshCredential = () => {
|
|
149532
149667
|
const storedCredential = primary.get(storageProvider);
|
|
149533
|
-
if (refreshLockProvider !== ANTHROPIC_PROVIDER_ID2) {
|
|
149668
|
+
if (storedCredential?.type === "oauth" || refreshLockProvider !== ANTHROPIC_PROVIDER_ID2) {
|
|
149534
149669
|
return storedCredential;
|
|
149535
149670
|
}
|
|
149536
149671
|
const legacyCredential = primary.get(ANTHROPIC_PROVIDER_ID2);
|
|
@@ -149660,18 +149795,16 @@ function createFusionAuthStorage() {
|
|
|
149660
149795
|
if (rawKey) return rawKey;
|
|
149661
149796
|
}
|
|
149662
149797
|
const subscriptionLoggedOut = loggedOutProviders.has(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
|
|
149663
|
-
const
|
|
149798
|
+
const subscriptionCredential = subscriptionLoggedOut ? void 0 : selectStoredCredential(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
|
|
149799
|
+
if (subscriptionCredential?.type === "oauth") {
|
|
149800
|
+
const subscriptionKey = await resolveRefreshableCredentialApiKey(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID, subscriptionCredential);
|
|
149801
|
+
if (subscriptionKey) return subscriptionKey;
|
|
149802
|
+
}
|
|
149803
|
+
const legacyAnthropicOAuthCredential = rawProviderLoggedOut || subscriptionCredential ? void 0 : selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "oauth");
|
|
149664
149804
|
if (!subscriptionLoggedOut && legacyAnthropicOAuthCredential) {
|
|
149665
149805
|
const legacyKey = await resolveRefreshableCredentialApiKey(ANTHROPIC_PROVIDER_ID2, legacyAnthropicOAuthCredential);
|
|
149666
149806
|
if (legacyKey) return legacyKey;
|
|
149667
149807
|
}
|
|
149668
|
-
if (!subscriptionLoggedOut) {
|
|
149669
|
-
const subscriptionCredential = selectStoredCredential(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
|
|
149670
|
-
if (subscriptionCredential?.type === "oauth") {
|
|
149671
|
-
const subscriptionKey = await resolveRefreshableCredentialApiKey(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID, subscriptionCredential);
|
|
149672
|
-
if (subscriptionKey) return subscriptionKey;
|
|
149673
|
-
}
|
|
149674
|
-
}
|
|
149675
149808
|
if (preferSubscription) {
|
|
149676
149809
|
const rawKey = resolveRawApiKey();
|
|
149677
149810
|
if (rawKey) return rawKey;
|
|
@@ -149848,8 +149981,15 @@ function createFusionAuthStorage() {
|
|
|
149848
149981
|
return void 0;
|
|
149849
149982
|
}
|
|
149850
149983
|
if (sourceProvider !== ANTHROPIC_SUBSCRIPTION_PROVIDER_ID) {
|
|
149851
|
-
await
|
|
149852
|
-
|
|
149984
|
+
const legacyKey = await resolveRefreshableCredentialApiKey(ANTHROPIC_PROVIDER_ID2, subscriptionCredential);
|
|
149985
|
+
primary.reload();
|
|
149986
|
+
const storedSubscription = primary.get(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
|
|
149987
|
+
const refreshedLegacyCredential = primary.get(ANTHROPIC_PROVIDER_ID2);
|
|
149988
|
+
if (!storedSubscription && refreshedLegacyCredential?.type === "oauth") {
|
|
149989
|
+
await primary.set(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID, refreshedLegacyCredential);
|
|
149990
|
+
loggedOutProviders.delete(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
|
|
149991
|
+
}
|
|
149992
|
+
return legacyKey;
|
|
149853
149993
|
}
|
|
149854
149994
|
return resolveRefreshableCredentialApiKey(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID, subscriptionCredential);
|
|
149855
149995
|
}
|
|
@@ -149894,6 +150034,9 @@ var init_auth_storage = __esm({
|
|
|
149894
150034
|
}
|
|
149895
150035
|
data = {};
|
|
149896
150036
|
modelRuntime;
|
|
150037
|
+
async withProviderInstanceLoginLock(providerId, operation) {
|
|
150038
|
+
return withOAuthInstanceLoginLock(this.authPath, providerId, operation);
|
|
150039
|
+
}
|
|
149897
150040
|
ensureFile() {
|
|
149898
150041
|
const parent = dirname26(this.authPath);
|
|
149899
150042
|
if (!existsSync45(parent)) mkdirSync7(parent, { recursive: true, mode: 448 });
|
|
@@ -150236,6 +150379,35 @@ var init_model_registry_refresh = __esm({
|
|
|
150236
150379
|
});
|
|
150237
150380
|
|
|
150238
150381
|
// ../engine/src/auth/provider-auth.ts
|
|
150382
|
+
async function withProviderInstanceLoginLock(authStorage, providerId, operation) {
|
|
150383
|
+
let locks = instanceLoginLocks.get(authStorage);
|
|
150384
|
+
if (!locks) {
|
|
150385
|
+
locks = /* @__PURE__ */ new Map();
|
|
150386
|
+
instanceLoginLocks.set(authStorage, locks);
|
|
150387
|
+
}
|
|
150388
|
+
const previous = locks.get(providerId);
|
|
150389
|
+
let release3;
|
|
150390
|
+
const gate = new Promise((resolve65) => {
|
|
150391
|
+
release3 = resolve65;
|
|
150392
|
+
});
|
|
150393
|
+
const queued = (previous ?? Promise.resolve()).catch(() => void 0).then(() => gate);
|
|
150394
|
+
locks.set(providerId, queued);
|
|
150395
|
+
await (previous ?? Promise.resolve()).catch(() => void 0);
|
|
150396
|
+
try {
|
|
150397
|
+
if (!authStorage.withProviderInstanceLoginLock) {
|
|
150398
|
+
return await operation();
|
|
150399
|
+
}
|
|
150400
|
+
return await authStorage.withProviderInstanceLoginLock(providerId, async () => {
|
|
150401
|
+
authStorage.reload();
|
|
150402
|
+
return await operation();
|
|
150403
|
+
});
|
|
150404
|
+
} finally {
|
|
150405
|
+
release3();
|
|
150406
|
+
if (locks.get(providerId) === queued) {
|
|
150407
|
+
locks.delete(providerId);
|
|
150408
|
+
}
|
|
150409
|
+
}
|
|
150410
|
+
}
|
|
150239
150411
|
function toApiKeyStorageProviderId(providerId) {
|
|
150240
150412
|
return providerId === ANTHROPIC_API_KEY_PROVIDER_ID2 ? ANTHROPIC_STORAGE_PROVIDER_ID : providerId;
|
|
150241
150413
|
}
|
|
@@ -150273,7 +150445,18 @@ function wrapAuthStorageWithApiKeyProviders(authStorage, modelRegistry, readFall
|
|
|
150273
150445
|
providerId,
|
|
150274
150446
|
callbacks
|
|
150275
150447
|
);
|
|
150276
|
-
|
|
150448
|
+
const credential = authStorage.get(providerId);
|
|
150449
|
+
if (credential?.type !== "oauth") {
|
|
150450
|
+
return credential;
|
|
150451
|
+
}
|
|
150452
|
+
const stampedCredential = {
|
|
150453
|
+
...credential,
|
|
150454
|
+
...computeStoredCredentialAccountFingerprint(credential) ? {
|
|
150455
|
+
accountFingerprint: computeStoredCredentialAccountFingerprint(credential)
|
|
150456
|
+
} : {}
|
|
150457
|
+
};
|
|
150458
|
+
await authStorage.set(providerId, stampedCredential);
|
|
150459
|
+
return stampedCredential;
|
|
150277
150460
|
}
|
|
150278
150461
|
const existingApiKey = mergedAuthStorage.get(ANTHROPIC_STORAGE_PROVIDER_ID);
|
|
150279
150462
|
await mergedAuthStorage.login(
|
|
@@ -150282,19 +150465,29 @@ function wrapAuthStorageWithApiKeyProviders(authStorage, modelRegistry, readFall
|
|
|
150282
150465
|
);
|
|
150283
150466
|
const oauthCredential = authStorage.get(ANTHROPIC_STORAGE_PROVIDER_ID);
|
|
150284
150467
|
if (oauthCredential?.type === "oauth") {
|
|
150285
|
-
|
|
150468
|
+
const stampedCredential = {
|
|
150469
|
+
...oauthCredential,
|
|
150470
|
+
...computeStoredCredentialAccountFingerprint(oauthCredential) ? {
|
|
150471
|
+
accountFingerprint: computeStoredCredentialAccountFingerprint(oauthCredential)
|
|
150472
|
+
} : {}
|
|
150473
|
+
};
|
|
150474
|
+
await mergedAuthStorage.set(ANTHROPIC_SUBSCRIPTION_STORAGE_PROVIDER_ID, stampedCredential);
|
|
150286
150475
|
if (existingApiKey?.type === "api_key") {
|
|
150287
150476
|
await mergedAuthStorage.set(ANTHROPIC_STORAGE_PROVIDER_ID, existingApiKey);
|
|
150288
150477
|
} else {
|
|
150289
150478
|
await authStorage.remove(ANTHROPIC_STORAGE_PROVIDER_ID);
|
|
150290
150479
|
}
|
|
150480
|
+
return stampedCredential;
|
|
150291
150481
|
}
|
|
150482
|
+
return void 0;
|
|
150292
150483
|
};
|
|
150293
150484
|
return {
|
|
150294
150485
|
reload: () => mergedAuthStorage.reload(),
|
|
150295
150486
|
getOAuthProviders: () => mergedAuthStorage.getOAuthProviders().map((provider) => provider.id === ANTHROPIC_STORAGE_PROVIDER_ID ? { id: ANTHROPIC_STORAGE_PROVIDER_ID, name: "Anthropic Subscription" } : { id: provider.id, name: provider.name }),
|
|
150296
150487
|
hasAuth: (provider) => provider === ANTHROPIC_STORAGE_PROVIDER_ID || provider === ANTHROPIC_SUBSCRIPTION_STORAGE_PROVIDER_ID ? Boolean(getAnthropicSubscriptionCredential()) : mergedAuthStorage.hasAuth(provider),
|
|
150297
|
-
login,
|
|
150488
|
+
login: async (providerId, callbacks) => {
|
|
150489
|
+
await login(providerId, callbacks);
|
|
150490
|
+
},
|
|
150298
150491
|
logout: async (provider) => {
|
|
150299
150492
|
if (provider !== ANTHROPIC_STORAGE_PROVIDER_ID && provider !== ANTHROPIC_SUBSCRIPTION_STORAGE_PROVIDER_ID) {
|
|
150300
150493
|
await mergedAuthStorage.logout(provider);
|
|
@@ -150378,19 +150571,33 @@ function wrapAuthStorageWithApiKeyProviders(authStorage, modelRegistry, readFall
|
|
|
150378
150571
|
},
|
|
150379
150572
|
loginInstance: async (ref, callbacks, label) => {
|
|
150380
150573
|
const providerId = ref.providerId === ANTHROPIC_STORAGE_PROVIDER_ID ? ANTHROPIC_SUBSCRIPTION_STORAGE_PROVIDER_ID : ref.providerId;
|
|
150381
|
-
|
|
150382
|
-
|
|
150383
|
-
|
|
150384
|
-
|
|
150385
|
-
|
|
150386
|
-
|
|
150387
|
-
|
|
150388
|
-
|
|
150389
|
-
|
|
150390
|
-
|
|
150391
|
-
|
|
150392
|
-
|
|
150393
|
-
|
|
150574
|
+
return withProviderInstanceLoginLock(authStorage, providerId, async () => {
|
|
150575
|
+
const target = { providerId, instanceId: ref.instanceId };
|
|
150576
|
+
const previousDefault = mergedAuthStorage.getDefaultInstance(providerId);
|
|
150577
|
+
const previousCredential = previousDefault && mergedAuthStorage.getInstance(previousDefault);
|
|
150578
|
+
const preLoginInstances = mergedAuthStorage.listInstances(providerId).map((instanceRef) => ({ ref: instanceRef, credential: mergedAuthStorage.getInstance(instanceRef) })).filter((entry) => Boolean(entry.credential));
|
|
150579
|
+
const credential = await login(providerId, callbacks);
|
|
150580
|
+
if (!credential) return;
|
|
150581
|
+
const duplicate = preLoginInstances.find(
|
|
150582
|
+
(entry) => entry.ref.instanceId !== target.instanceId && isSameStoredCredentialMaterial(credential, entry.credential)
|
|
150583
|
+
);
|
|
150584
|
+
if (duplicate) {
|
|
150585
|
+
if (previousDefault && previousCredential) {
|
|
150586
|
+
await mergedAuthStorage.setInstance(previousDefault, previousCredential);
|
|
150587
|
+
}
|
|
150588
|
+
const conflictingAccount = duplicate.credential.label || duplicate.ref.instanceId;
|
|
150589
|
+
throw new Error(
|
|
150590
|
+
`This login authorized the account already stored as ${conflictingAccount}. Sign out of the provider in your browser and retry.`
|
|
150591
|
+
);
|
|
150592
|
+
}
|
|
150593
|
+
await mergedAuthStorage.setInstance(target, { ...credential, ...label ? { label } : {} });
|
|
150594
|
+
if (previousDefault && previousCredential && previousDefault.instanceId !== target.instanceId) {
|
|
150595
|
+
await mergedAuthStorage.setInstance(previousDefault, previousCredential);
|
|
150596
|
+
} else if (!previousDefault && target.instanceId !== DEFAULT_PROVIDER_INSTANCE_ID) {
|
|
150597
|
+
await mergedAuthStorage.removeInstance({ providerId, instanceId: DEFAULT_PROVIDER_INSTANCE_ID });
|
|
150598
|
+
await mergedAuthStorage.setDefaultInstance(target);
|
|
150599
|
+
}
|
|
150600
|
+
});
|
|
150394
150601
|
},
|
|
150395
150602
|
logoutInstance: async (ref) => {
|
|
150396
150603
|
await mergedAuthStorage.removeInstance({
|
|
@@ -150634,7 +150841,7 @@ function createReadOnlyAuthFileStorage(authPaths) {
|
|
|
150634
150841
|
}
|
|
150635
150842
|
};
|
|
150636
150843
|
}
|
|
150637
|
-
var ANTHROPIC_API_KEY_PROVIDER_ID2, ANTHROPIC_STORAGE_PROVIDER_ID, ANTHROPIC_SUBSCRIPTION_STORAGE_PROVIDER_ID, BUILT_IN_API_KEY_PROVIDERS, CLI_PROVIDER_IDS;
|
|
150844
|
+
var ANTHROPIC_API_KEY_PROVIDER_ID2, ANTHROPIC_STORAGE_PROVIDER_ID, ANTHROPIC_SUBSCRIPTION_STORAGE_PROVIDER_ID, BUILT_IN_API_KEY_PROVIDERS, CLI_PROVIDER_IDS, instanceLoginLocks;
|
|
150638
150845
|
var init_provider_auth = __esm({
|
|
150639
150846
|
"../engine/src/auth/provider-auth.ts"() {
|
|
150640
150847
|
"use strict";
|
|
@@ -150654,6 +150861,7 @@ var init_provider_auth = __esm({
|
|
|
150654
150861
|
{ id: "zai", name: "Zai" }
|
|
150655
150862
|
];
|
|
150656
150863
|
CLI_PROVIDER_IDS = /* @__PURE__ */ new Set(["pi-claude-cli", "droid-cli"]);
|
|
150864
|
+
instanceLoginLocks = /* @__PURE__ */ new WeakMap();
|
|
150657
150865
|
}
|
|
150658
150866
|
});
|
|
150659
150867
|
|
|
@@ -151039,7 +151247,7 @@ var init_plan_review_continuation = __esm({
|
|
|
151039
151247
|
});
|
|
151040
151248
|
|
|
151041
151249
|
// ../engine/src/execution/hold-release.ts
|
|
151042
|
-
import { createHash as
|
|
151250
|
+
import { createHash as createHash26 } from "node:crypto";
|
|
151043
151251
|
import { readFile as readFile36 } from "node:fs/promises";
|
|
151044
151252
|
function findColumn2(ir2, columnId) {
|
|
151045
151253
|
if (ir2.version !== "v2") return void 0;
|
|
@@ -151077,9 +151285,9 @@ async function checkAndRecordUnplannedExecutionBlock(store, task, ir2) {
|
|
|
151077
151285
|
promptContent = "";
|
|
151078
151286
|
}
|
|
151079
151287
|
}
|
|
151080
|
-
const promptMarker = promptContent.length > 0 ?
|
|
151288
|
+
const promptMarker = promptContent.length > 0 ? createHash26("sha256").update(promptContent).digest("hex") : "missing";
|
|
151081
151289
|
const dependencies = [...task.dependencies ?? []].sort();
|
|
151082
|
-
const episode =
|
|
151290
|
+
const episode = createHash26("sha256").update(JSON.stringify({
|
|
151083
151291
|
planReviewNode,
|
|
151084
151292
|
promptMarker,
|
|
151085
151293
|
dependencies,
|
|
@@ -175048,6 +175256,7 @@ async function connectMcpSessionTools(servers, opts = {}) {
|
|
|
175048
175256
|
const clients = [];
|
|
175049
175257
|
const closedClients = /* @__PURE__ */ new WeakSet();
|
|
175050
175258
|
const usedToolNames = /* @__PURE__ */ new Set();
|
|
175259
|
+
const serverByToolName = /* @__PURE__ */ new Map();
|
|
175051
175260
|
let disposed = false;
|
|
175052
175261
|
const closeOnce = async (client) => {
|
|
175053
175262
|
if (closedClients.has(client)) return;
|
|
@@ -175097,7 +175306,9 @@ async function connectMcpSessionTools(servers, opts = {}) {
|
|
|
175097
175306
|
opts.logger?.log?.(connectMsg);
|
|
175098
175307
|
}
|
|
175099
175308
|
for (const tool of listedTools) {
|
|
175100
|
-
|
|
175309
|
+
const wrappedTool = wrapMcpTool(server.name, tool, client, usedToolNames);
|
|
175310
|
+
tools.push(wrappedTool);
|
|
175311
|
+
serverByToolName.set(wrappedTool.name, server.name);
|
|
175101
175312
|
}
|
|
175102
175313
|
break;
|
|
175103
175314
|
} catch (error3) {
|
|
@@ -175124,7 +175335,7 @@ async function connectMcpSessionTools(servers, opts = {}) {
|
|
|
175124
175335
|
await closeAll();
|
|
175125
175336
|
}
|
|
175126
175337
|
}
|
|
175127
|
-
return { tools, connected, skipped, dispose: closeAll };
|
|
175338
|
+
return { tools, connected, skipped, serverByToolName, dispose: closeAll };
|
|
175128
175339
|
}
|
|
175129
175340
|
function normalizeMaxAttempts(value) {
|
|
175130
175341
|
if (value === void 0 || !Number.isFinite(value)) return DEFAULT_MAX_ATTEMPTS;
|
|
@@ -178264,8 +178475,10 @@ async function createPiAgentSessionRaw(options) {
|
|
|
178264
178475
|
const createSessionWithModel = async (modelOverride) => {
|
|
178265
178476
|
let mcpToolset;
|
|
178266
178477
|
const allowReadonlyMcpTools = options.allowMcpToolsInReadonly === true;
|
|
178267
|
-
|
|
178268
|
-
|
|
178478
|
+
const readonlyMcpServerAllowlist = options.readonlyMcpServerAllowlist === void 0 ? void 0 : new Set(options.readonlyMcpServerAllowlist.map((name2) => name2.trim()).filter(Boolean));
|
|
178479
|
+
const mcpServersToConnect = isReadonly && allowReadonlyMcpTools && readonlyMcpServerAllowlist !== void 0 ? forwardedMcpServers.filter((server) => readonlyMcpServerAllowlist.has(server.name)) : forwardedMcpServers;
|
|
178480
|
+
if (mcpServersToConnect.length > 0 && (!isReadonly || allowReadonlyMcpTools)) {
|
|
178481
|
+
mcpToolset = await connectMcpSessionTools(mcpServersToConnect, {
|
|
178269
178482
|
cwd: options.cwd,
|
|
178270
178483
|
clientFactory: options.mcpClientFactory,
|
|
178271
178484
|
logger: piLog,
|
|
@@ -178276,7 +178489,8 @@ async function createPiAgentSessionRaw(options) {
|
|
|
178276
178489
|
piLog.warn(`MCP session continuing with unavailable servers: count=${bootstrapFailures.length}`);
|
|
178277
178490
|
}
|
|
178278
178491
|
} else if (forwardedMcpServers.length > 0 && isReadonly) {
|
|
178279
|
-
|
|
178492
|
+
const reason = !allowReadonlyMcpTools ? "no-readonly-opt-in" : "readonly-allowlist-no-match";
|
|
178493
|
+
piLog.log(`readonly session \u2014 MCP servers (${forwardedMcpServers.length}) skipped: reason=${reason}`);
|
|
178280
178494
|
}
|
|
178281
178495
|
const mcpReadonlyTools = new Set(mcpToolset?.tools ?? []);
|
|
178282
178496
|
const candidateCustomTools = [
|
|
@@ -178285,7 +178499,9 @@ async function createPiAgentSessionRaw(options) {
|
|
|
178285
178499
|
];
|
|
178286
178500
|
const readonlyFilteredCustomTools = isReadonly ? filterCustomToolsForReadonly(
|
|
178287
178501
|
candidateCustomTools,
|
|
178288
|
-
allowReadonlyMcpTools ? {
|
|
178502
|
+
allowReadonlyMcpTools ? {
|
|
178503
|
+
allowTool: (tool) => readonlyMcpServerAllowlist === void 0 ? mcpReadonlyTools.has(tool) : readonlyMcpServerAllowlist.has(mcpToolset?.serverByToolName?.get(tool.name) ?? "")
|
|
178504
|
+
} : {}
|
|
178289
178505
|
) : { allowed: candidateCustomTools, denied: [] };
|
|
178290
178506
|
const allowlistFilteredCustomTools = {
|
|
178291
178507
|
...readonlyFilteredCustomTools,
|
|
@@ -180297,7 +180513,7 @@ var init_retry_burned_logger = __esm({
|
|
|
180297
180513
|
|
|
180298
180514
|
// ../engine/src/merge/merge-dependency-sync.ts
|
|
180299
180515
|
import { exec as exec18 } from "node:child_process";
|
|
180300
|
-
import { createHash as
|
|
180516
|
+
import { createHash as createHash27 } from "node:crypto";
|
|
180301
180517
|
import { existsSync as existsSync49, readFileSync as readFileSync19, writeFileSync as writeFileSync6 } from "node:fs";
|
|
180302
180518
|
import { join as join67 } from "node:path";
|
|
180303
180519
|
import { promisify as promisify23 } from "node:util";
|
|
@@ -180330,7 +180546,7 @@ function computeLockfileHash(rootDir) {
|
|
|
180330
180546
|
const p2 = join67(rootDir, name2);
|
|
180331
180547
|
if (existsSync49(p2)) {
|
|
180332
180548
|
try {
|
|
180333
|
-
return
|
|
180549
|
+
return createHash27("sha256").update(readFileSync19(p2)).digest("hex");
|
|
180334
180550
|
} catch {
|
|
180335
180551
|
return null;
|
|
180336
180552
|
}
|
|
@@ -180460,7 +180676,7 @@ var init_merge_dependency_sync = __esm({
|
|
|
180460
180676
|
});
|
|
180461
180677
|
|
|
180462
180678
|
// ../engine/src/worktree/worktree-dependency-install.ts
|
|
180463
|
-
import { createHash as
|
|
180679
|
+
import { createHash as createHash28 } from "node:crypto";
|
|
180464
180680
|
import { existsSync as existsSync50, readFileSync as readFileSync20, readdirSync as readdirSync8, statSync as statSync11, writeFileSync as writeFileSync7 } from "node:fs";
|
|
180465
180681
|
import { delimiter as delimiter2, join as join68 } from "node:path";
|
|
180466
180682
|
function rootEntries(rootDir) {
|
|
@@ -180558,7 +180774,7 @@ function isCommandAvailable(binary, env = process.env) {
|
|
|
180558
180774
|
);
|
|
180559
180775
|
}
|
|
180560
180776
|
function hashParts(parts) {
|
|
180561
|
-
const hash3 =
|
|
180777
|
+
const hash3 = createHash28("sha256");
|
|
180562
180778
|
for (const [name2, value] of [...parts].sort(([left], [right]) => left.localeCompare(right))) {
|
|
180563
180779
|
hash3.update(name2).update("\0").update(value).update("\0");
|
|
180564
180780
|
}
|
|
@@ -186546,7 +186762,7 @@ var init_mission_feature_sync = __esm({
|
|
|
186546
186762
|
// ../engine/src/agent-tools.ts
|
|
186547
186763
|
import { appendFile as appendFile3, mkdir as mkdir27, readFile as readFile40, readdir as readdir11, realpath, stat as stat11, writeFile as writeFile23 } from "node:fs/promises";
|
|
186548
186764
|
import { existsSync as existsSync53 } from "node:fs";
|
|
186549
|
-
import { createHash as
|
|
186765
|
+
import { createHash as createHash29, randomUUID as randomUUID48 } from "node:crypto";
|
|
186550
186766
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
186551
186767
|
import { extname as extname4, isAbsolute as isAbsolute14, join as join71, relative as relative13, resolve as resolve40, sep as sep11 } from "node:path";
|
|
186552
186768
|
import { Type as Type2 } from "@earendil-works/pi-ai";
|
|
@@ -186590,7 +186806,7 @@ async function readAgentMemoryWorkspaceLongTerm(rootDir, agentId) {
|
|
|
186590
186806
|
}
|
|
186591
186807
|
}
|
|
186592
186808
|
function qmdAgentMemoryCollectionName2(rootDir, agentId) {
|
|
186593
|
-
const hash3 =
|
|
186809
|
+
const hash3 = createHash29("sha1").update(`${rootDir}:${agentId}`).digest("hex").slice(0, 12);
|
|
186594
186810
|
return `fusion-agent-memory-${sanitizeAgentMemoryId(agentId).toLowerCase()}-${hash3}`;
|
|
186595
186811
|
}
|
|
186596
186812
|
function buildQmdAgentMemoryCollectionAddArgs(rootDir, agentId) {
|
|
@@ -186719,11 +186935,11 @@ async function refreshAgentMemoryQmdIndex(rootDir, agentMemory) {
|
|
|
186719
186935
|
return;
|
|
186720
186936
|
}
|
|
186721
186937
|
const promise = (async () => {
|
|
186722
|
-
const { execFile:
|
|
186723
|
-
const { promisify:
|
|
186724
|
-
const
|
|
186938
|
+
const { execFile: execFile47 } = await import("node:child_process");
|
|
186939
|
+
const { promisify: promisify102 } = await import("node:util");
|
|
186940
|
+
const execFileAsync41 = promisify102(execFile47);
|
|
186725
186941
|
try {
|
|
186726
|
-
await
|
|
186942
|
+
await execFileAsync41("qmd", buildQmdAgentMemoryCollectionAddArgs(rootDir, agentMemory.agentId), {
|
|
186727
186943
|
cwd: rootDir,
|
|
186728
186944
|
timeout: 4e3,
|
|
186729
186945
|
maxBuffer: 512 * 1024
|
|
@@ -186736,8 +186952,8 @@ ${stderr}`)) {
|
|
|
186736
186952
|
throw error3;
|
|
186737
186953
|
}
|
|
186738
186954
|
}
|
|
186739
|
-
await
|
|
186740
|
-
await
|
|
186955
|
+
await execFileAsync41("qmd", ["update"], { cwd: rootDir, timeout: 3e4, maxBuffer: 1024 * 1024 });
|
|
186956
|
+
await execFileAsync41("qmd", ["embed"], { cwd: rootDir, timeout: 12e4, maxBuffer: 1024 * 1024 });
|
|
186741
186957
|
})();
|
|
186742
186958
|
agentQmdRefreshState.set(key, { lastStartedAt: now, inFlight: promise });
|
|
186743
186959
|
try {
|
|
@@ -186792,10 +187008,10 @@ async function searchAgentMemoryWithQmd(rootDir, agentMemory, query, limit) {
|
|
|
186792
187008
|
}
|
|
186793
187009
|
try {
|
|
186794
187010
|
await refreshAgentMemoryQmdIndex(rootDir, agentMemory);
|
|
186795
|
-
const { execFile:
|
|
186796
|
-
const { promisify:
|
|
186797
|
-
const
|
|
186798
|
-
const { stdout } = await
|
|
187011
|
+
const { execFile: execFile47 } = await import("node:child_process");
|
|
187012
|
+
const { promisify: promisify102 } = await import("node:util");
|
|
187013
|
+
const execFileAsync41 = promisify102(execFile47);
|
|
187014
|
+
const { stdout } = await execFileAsync41("qmd", buildQmdAgentMemorySearchArgs(rootDir, agentMemory.agentId, query, limit), {
|
|
186799
187015
|
cwd: rootDir,
|
|
186800
187016
|
timeout: 4e3,
|
|
186801
187017
|
maxBuffer: 1024 * 1024
|
|
@@ -198085,7 +198301,7 @@ var init_workspace_review_remediation = __esm({
|
|
|
198085
198301
|
});
|
|
198086
198302
|
|
|
198087
198303
|
// ../engine/src/worktree/secrets-env-writer.ts
|
|
198088
|
-
import { createHash as
|
|
198304
|
+
import { createHash as createHash30 } from "node:crypto";
|
|
198089
198305
|
import { execFile as execFile14 } from "node:child_process";
|
|
198090
198306
|
import { promises as fs6 } from "node:fs";
|
|
198091
198307
|
import path3 from "node:path";
|
|
@@ -198094,7 +198310,7 @@ function isValidFilename(filename) {
|
|
|
198094
198310
|
return !!filename && !filename.includes("/") && !filename.includes("\\") && !filename.includes("..") && !filename.includes("\0") && filename !== FINGERPRINT_FILE;
|
|
198095
198311
|
}
|
|
198096
198312
|
function sha2562(content) {
|
|
198097
|
-
return
|
|
198313
|
+
return createHash30("sha256").update(Buffer.from(content, "utf8")).digest("hex");
|
|
198098
198314
|
}
|
|
198099
198315
|
function quote(value) {
|
|
198100
198316
|
return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"').replaceAll("\n", "\\n").replaceAll("\r", "\\r").replaceAll(" ", "\\t")}"`;
|
|
@@ -200653,7 +200869,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
200653
200869
|
phase: "pre-merge",
|
|
200654
200870
|
source: "optional-group",
|
|
200655
200871
|
status: "skipped",
|
|
200656
|
-
bypassedBy:
|
|
200872
|
+
bypassedBy: FAST_MODE_BYPASS_ACTOR,
|
|
200657
200873
|
bypassedAt,
|
|
200658
200874
|
bypassReason: "Fast mode bypasses pre-merge workflow gates",
|
|
200659
200875
|
bypassedFromStatus: "absent",
|
|
@@ -200857,7 +201073,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
200857
201073
|
const stepFindings = this.workflowReviewKind(node) && Array.isArray(exitContextPatch?.findings) ? exitContextPatch.findings : void 0;
|
|
200858
201074
|
const repositoryReviewOutcomes = this.workflowReviewKind(node) && Array.isArray(exitContextPatch?.repositoryReviewOutcomes) ? exitContextPatch.repositoryReviewOutcomes : void 0;
|
|
200859
201075
|
const repositoryScopeRevision = this.workflowReviewKind(node) && typeof exitContextPatch?.repositoryScopeRevision === "number" ? exitContextPatch.repositoryScopeRevision : void 0;
|
|
200860
|
-
const reviewInputFingerprint = this.workflowReviewKind(node) && typeof exitContextPatch?.reviewInputFingerprint === "string" ? exitContextPatch.reviewInputFingerprint : void 0;
|
|
201076
|
+
const reviewInputFingerprint = requiresContentReviewProof(node.id, { reviewKind: this.workflowReviewKind(node) }) && typeof exitContextPatch?.reviewInputFingerprint === "string" ? exitContextPatch.reviewInputFingerprint : void 0;
|
|
200861
201077
|
const reviewedCommitSha = this.workflowReviewKind(node) && typeof exitContextPatch?.reviewedCommitSha === "string" ? exitContextPatch.reviewedCommitSha : void 0;
|
|
200862
201078
|
const supersededFindingSourceWorkflowStepId = this.workflowReviewKind(node) && typeof exitContextPatch?.supersededFindingSourceWorkflowStepId === "string" ? exitContextPatch.supersededFindingSourceWorkflowStepId : void 0;
|
|
200863
201079
|
const supersededFindingIds = supersededFindingSourceWorkflowStepId && this.workflowReviewKind(node) && Array.isArray(exitContextPatch?.supersededFindingIds) ? exitContextPatch.supersededFindingIds.filter((id) => typeof id === "string") : void 0;
|
|
@@ -201596,7 +201812,7 @@ ${stepOutput}` : ""}`);
|
|
|
201596
201812
|
const findings = this.workflowReviewKind(node) && Array.isArray(contextPatch.findings) ? contextPatch.findings : void 0;
|
|
201597
201813
|
const repositoryReviewOutcomes = this.workflowReviewKind(node) && Array.isArray(contextPatch.repositoryReviewOutcomes) ? contextPatch.repositoryReviewOutcomes : void 0;
|
|
201598
201814
|
const repositoryScopeRevision = this.workflowReviewKind(node) && typeof contextPatch.repositoryScopeRevision === "number" ? contextPatch.repositoryScopeRevision : void 0;
|
|
201599
|
-
const reviewInputFingerprint = this.workflowReviewKind(node) && typeof contextPatch.reviewInputFingerprint === "string" ? contextPatch.reviewInputFingerprint : void 0;
|
|
201815
|
+
const reviewInputFingerprint = requiresContentReviewProof(node.id, { reviewKind: this.workflowReviewKind(node) }) && typeof contextPatch.reviewInputFingerprint === "string" ? contextPatch.reviewInputFingerprint : void 0;
|
|
201600
201816
|
const reviewedCommitSha = this.workflowReviewKind(node) && typeof contextPatch.reviewedCommitSha === "string" ? contextPatch.reviewedCommitSha : void 0;
|
|
201601
201817
|
const supersededFindingSourceWorkflowStepId = this.workflowReviewKind(node) && typeof contextPatch.supersededFindingSourceWorkflowStepId === "string" ? contextPatch.supersededFindingSourceWorkflowStepId : void 0;
|
|
201602
201818
|
const supersededFindingIds = supersededFindingSourceWorkflowStepId && this.workflowReviewKind(node) && Array.isArray(contextPatch.supersededFindingIds) ? contextPatch.supersededFindingIds.filter((id) => typeof id === "string") : void 0;
|
|
@@ -202977,17 +203193,141 @@ var init_agent_binding_pure = __esm({
|
|
|
202977
203193
|
}
|
|
202978
203194
|
});
|
|
202979
203195
|
|
|
202980
|
-
// ../engine/src/worktree
|
|
202981
|
-
import {
|
|
202982
|
-
import { execFile as execFile15 } from "node:child_process";
|
|
203196
|
+
// ../engine/src/executor/worktree-git-refs.ts
|
|
203197
|
+
import { exec as exec25, execFile as execFile15, execSync as execSync3 } from "node:child_process";
|
|
202983
203198
|
import { promisify as promisify32 } from "node:util";
|
|
203199
|
+
async function preExecutionWorktreeHasWork(worktreePath) {
|
|
203200
|
+
try {
|
|
203201
|
+
const { stdout: dirty } = await execFileAsync9("git", ["status", "--porcelain"], { cwd: worktreePath, timeout: 3e4 });
|
|
203202
|
+
if (dirty.trim()) return true;
|
|
203203
|
+
const { stdout: ahead } = await execFileAsync9("git", ["log", "--oneline", "@{upstream}..HEAD"], { cwd: worktreePath, timeout: 3e4 }).catch(async () => await execFileAsync9("git", ["log", "--oneline", "-1", "HEAD", "--not", "--remotes", "--branches=main", "--branches=master"], { cwd: worktreePath, timeout: 3e4 }));
|
|
203204
|
+
return Boolean(ahead.trim());
|
|
203205
|
+
} catch {
|
|
203206
|
+
return true;
|
|
203207
|
+
}
|
|
203208
|
+
}
|
|
203209
|
+
async function resolveContaminationBaseRef(worktreePath) {
|
|
203210
|
+
try {
|
|
203211
|
+
const { stdout } = await execAsync22(
|
|
203212
|
+
"git merge-base HEAD main 2>/dev/null || git merge-base HEAD origin/main",
|
|
203213
|
+
{ cwd: worktreePath, encoding: "utf-8" }
|
|
203214
|
+
);
|
|
203215
|
+
const ref = stdout.trim();
|
|
203216
|
+
return ref || void 0;
|
|
203217
|
+
} catch (err) {
|
|
203218
|
+
const errorMessage2 = err instanceof Error ? err.message : String(err);
|
|
203219
|
+
executorLog.warn(`Failed merge-base lookup for contamination check in ${worktreePath}: ${errorMessage2}`);
|
|
203220
|
+
return void 0;
|
|
203221
|
+
}
|
|
203222
|
+
}
|
|
203223
|
+
async function resolveDiffBaseRef(worktreePath, baseCommitSha) {
|
|
203224
|
+
if (baseCommitSha) return baseCommitSha;
|
|
203225
|
+
try {
|
|
203226
|
+
const { stdout } = await execAsync22(
|
|
203227
|
+
"git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main",
|
|
203228
|
+
{ cwd: worktreePath, encoding: "utf-8" }
|
|
203229
|
+
);
|
|
203230
|
+
const ref = stdout.trim();
|
|
203231
|
+
if (ref) return ref;
|
|
203232
|
+
} catch (mergeBaseErr) {
|
|
203233
|
+
const mergeBaseMsg = mergeBaseErr instanceof Error ? mergeBaseErr.message : String(mergeBaseErr);
|
|
203234
|
+
executorLog.warn(`Failed merge-base lookup for diff base in ${worktreePath}, trying HEAD~1 fallback: ${mergeBaseMsg}`);
|
|
203235
|
+
}
|
|
203236
|
+
try {
|
|
203237
|
+
const { stdout } = await execAsync22("git rev-parse HEAD~1", {
|
|
203238
|
+
cwd: worktreePath,
|
|
203239
|
+
encoding: "utf-8"
|
|
203240
|
+
});
|
|
203241
|
+
return stdout.trim() || void 0;
|
|
203242
|
+
} catch {
|
|
203243
|
+
executorLog.debug(`Could not determine base commit for diff in ${worktreePath}`);
|
|
203244
|
+
return void 0;
|
|
203245
|
+
}
|
|
203246
|
+
}
|
|
203247
|
+
async function captureBaseCommitSha(store, task, worktreePath, audit, options = { isResume: false }) {
|
|
203248
|
+
try {
|
|
203249
|
+
if (options.isResume && task.baseCommitSha) {
|
|
203250
|
+
try {
|
|
203251
|
+
execSync3(`git merge-base --is-ancestor ${task.baseCommitSha} HEAD`, {
|
|
203252
|
+
cwd: worktreePath,
|
|
203253
|
+
stdio: "pipe"
|
|
203254
|
+
});
|
|
203255
|
+
executorLog.log(`${task.id}: preserved baseCommitSha ${task.baseCommitSha.slice(0, 7)} (resume)`);
|
|
203256
|
+
await audit.git({
|
|
203257
|
+
type: "commit:create",
|
|
203258
|
+
target: task.baseCommitSha,
|
|
203259
|
+
metadata: { purpose: "base", preserved: true }
|
|
203260
|
+
});
|
|
203261
|
+
return;
|
|
203262
|
+
} catch {
|
|
203263
|
+
}
|
|
203264
|
+
}
|
|
203265
|
+
const baseCommitSha = await resolveCapturedBaseCommitSha(worktreePath, {
|
|
203266
|
+
warn: (msg) => executorLog.warn(`${task.id}: ${msg}`)
|
|
203267
|
+
});
|
|
203268
|
+
if (!baseCommitSha) {
|
|
203269
|
+
throw new Error("could not resolve base commit SHA");
|
|
203270
|
+
}
|
|
203271
|
+
await store.updateTask(task.id, { baseCommitSha });
|
|
203272
|
+
executorLog.debug(`${task.id}: captured baseCommitSha ${baseCommitSha.slice(0, 7)}`);
|
|
203273
|
+
await audit.git({ type: "commit:create", target: baseCommitSha, metadata: { purpose: "base", preserved: false } });
|
|
203274
|
+
} catch (err) {
|
|
203275
|
+
const errorMessage2 = err instanceof Error ? err.message : String(err);
|
|
203276
|
+
executorLog.debug(`Failed to capture baseCommitSha for ${task.id}: ${errorMessage2}`);
|
|
203277
|
+
}
|
|
203278
|
+
}
|
|
203279
|
+
var execAsync22, execFileAsync9;
|
|
203280
|
+
var init_worktree_git_refs = __esm({
|
|
203281
|
+
"../engine/src/executor/worktree-git-refs.ts"() {
|
|
203282
|
+
"use strict";
|
|
203283
|
+
init_base_commit_capture();
|
|
203284
|
+
init_logger3();
|
|
203285
|
+
execAsync22 = promisify32(exec25);
|
|
203286
|
+
execFileAsync9 = promisify32(execFile15);
|
|
203287
|
+
}
|
|
203288
|
+
});
|
|
203289
|
+
|
|
203290
|
+
// ../engine/src/worktree/review-diff-fingerprint.ts
|
|
203291
|
+
import { createHash as createHash31 } from "node:crypto";
|
|
203292
|
+
import { execFile as execFile16 } from "node:child_process";
|
|
203293
|
+
import { promisify as promisify33 } from "node:util";
|
|
203294
|
+
function gitCaptureOptions(cwd) {
|
|
203295
|
+
return {
|
|
203296
|
+
cwd,
|
|
203297
|
+
encoding: "utf8",
|
|
203298
|
+
maxBuffer: REVIEW_DIFF_GIT_MAX_BUFFER_BYTES,
|
|
203299
|
+
timeout: REVIEW_DIFF_GIT_TIMEOUT_MS
|
|
203300
|
+
};
|
|
203301
|
+
}
|
|
203302
|
+
function isGitDiffBufferOverflow(error3) {
|
|
203303
|
+
if (typeof error3 !== "object" || error3 === null) return false;
|
|
203304
|
+
const candidate = error3;
|
|
203305
|
+
return candidate.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" || typeof candidate.message === "string" && candidate.message.includes("maxBuffer");
|
|
203306
|
+
}
|
|
203307
|
+
async function resolveContentReviewInputProof(worktreePath, diffBaseCommitSha) {
|
|
203308
|
+
let baseRef;
|
|
203309
|
+
try {
|
|
203310
|
+
baseRef = await resolveDiffBaseRef(worktreePath, diffBaseCommitSha);
|
|
203311
|
+
} catch {
|
|
203312
|
+
return { kind: "unprovable", reason: "no-diff-base" };
|
|
203313
|
+
}
|
|
203314
|
+
if (!baseRef) return { kind: "unprovable", reason: "no-diff-base" };
|
|
203315
|
+
const probe = await probeReviewDiffFingerprint(worktreePath, baseRef);
|
|
203316
|
+
if (probe.state === "empty") {
|
|
203317
|
+
return { kind: "fingerprint", fingerprint: EMPTY_REVIEW_DIFF_FINGERPRINT };
|
|
203318
|
+
}
|
|
203319
|
+
return probe.state === "fingerprint" ? { kind: "fingerprint", fingerprint: probe.fingerprint } : { kind: "unprovable", reason: probe.reason };
|
|
203320
|
+
}
|
|
202984
203321
|
async function probeReviewDiffFingerprint(worktreePath, baseRef, targetRef = "HEAD") {
|
|
202985
203322
|
if (!worktreePath || !baseRef) return { state: "unavailable", reason: "missing-worktree-or-base" };
|
|
202986
203323
|
try {
|
|
202987
|
-
const { stdout } = await
|
|
202988
|
-
return stdout ? { state: "fingerprint", fingerprint:
|
|
202989
|
-
} catch {
|
|
202990
|
-
return {
|
|
203324
|
+
const { stdout } = await execFileAsync10("git", ["diff", "--binary", `${baseRef}..${targetRef}`], gitCaptureOptions(worktreePath));
|
|
203325
|
+
return stdout ? { state: "fingerprint", fingerprint: createHash31("sha256").update(stdout).digest("hex") } : { state: "empty" };
|
|
203326
|
+
} catch (error3) {
|
|
203327
|
+
return {
|
|
203328
|
+
state: "unavailable",
|
|
203329
|
+
reason: isGitDiffBufferOverflow(error3) ? "git-diff-too-large" : "git-diff-failed"
|
|
203330
|
+
};
|
|
202991
203331
|
}
|
|
202992
203332
|
}
|
|
202993
203333
|
async function probeReviewChangesSinceCommit(worktreePath, reviewedCommitSha) {
|
|
@@ -202995,14 +203335,11 @@ async function probeReviewChangesSinceCommit(worktreePath, reviewedCommitSha) {
|
|
|
202995
203335
|
return { state: "unavailable", reason: "missing-worktree-or-reviewed-commit" };
|
|
202996
203336
|
}
|
|
202997
203337
|
try {
|
|
202998
|
-
await
|
|
202999
|
-
cwd: worktreePath,
|
|
203000
|
-
encoding: "utf8"
|
|
203001
|
-
});
|
|
203338
|
+
await execFileAsync10("git", ["cat-file", "-e", `${reviewedCommitSha}^{commit}`], gitCaptureOptions(worktreePath));
|
|
203002
203339
|
const [{ stdout: countOutput }, { stdout: filesOutput }, { stdout: shortstatOutput }] = await Promise.all([
|
|
203003
|
-
|
|
203004
|
-
|
|
203005
|
-
|
|
203340
|
+
execFileAsync10("git", ["rev-list", "--count", `${reviewedCommitSha}..HEAD`], gitCaptureOptions(worktreePath)),
|
|
203341
|
+
execFileAsync10("git", ["diff", "--name-only", "-z", `${reviewedCommitSha}..HEAD`], gitCaptureOptions(worktreePath)),
|
|
203342
|
+
execFileAsync10("git", ["diff", "--shortstat", `${reviewedCommitSha}..HEAD`], gitCaptureOptions(worktreePath))
|
|
203006
203343
|
]);
|
|
203007
203344
|
const commitCount = Number.parseInt(countOutput.trim(), 10);
|
|
203008
203345
|
if (!Number.isSafeInteger(commitCount) || commitCount < 0) {
|
|
@@ -203031,22 +203368,30 @@ async function computeCodeReviewInputFingerprint(worktreePath, baseRef, targetRe
|
|
|
203031
203368
|
if (result2.state === "empty") return EMPTY_REVIEW_DIFF_FINGERPRINT;
|
|
203032
203369
|
return result2.state === "fingerprint" ? result2.fingerprint : void 0;
|
|
203033
203370
|
}
|
|
203034
|
-
var
|
|
203371
|
+
var execFileAsync10, REVIEW_DIFF_GIT_MAX_BUFFER_BYTES, REVIEW_DIFF_GIT_TIMEOUT_MS, MAX_REVIEW_CHANGED_FILES, EMPTY_REVIEW_DIFF_FINGERPRINT;
|
|
203035
203372
|
var init_review_diff_fingerprint = __esm({
|
|
203036
203373
|
"../engine/src/worktree/review-diff-fingerprint.ts"() {
|
|
203037
203374
|
"use strict";
|
|
203038
|
-
|
|
203375
|
+
init_worktree_git_refs();
|
|
203376
|
+
execFileAsync10 = promisify33(execFile16);
|
|
203377
|
+
REVIEW_DIFF_GIT_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
203378
|
+
REVIEW_DIFF_GIT_TIMEOUT_MS = 12e4;
|
|
203039
203379
|
MAX_REVIEW_CHANGED_FILES = 100;
|
|
203040
203380
|
EMPTY_REVIEW_DIFF_FINGERPRINT = "empty-review-input:v1";
|
|
203041
203381
|
}
|
|
203042
203382
|
});
|
|
203043
203383
|
|
|
203044
203384
|
// ../engine/src/worktree/workspace-review-evidence.ts
|
|
203045
|
-
import { execFile as
|
|
203046
|
-
import { promisify as
|
|
203385
|
+
import { execFile as execFile17 } from "node:child_process";
|
|
203386
|
+
import { promisify as promisify34 } from "node:util";
|
|
203047
203387
|
import { join as join76 } from "node:path";
|
|
203048
203388
|
async function git3(args, cwd) {
|
|
203049
|
-
const { stdout } = await
|
|
203389
|
+
const { stdout } = await execFileAsync11("git", args, {
|
|
203390
|
+
cwd,
|
|
203391
|
+
encoding: "utf8",
|
|
203392
|
+
maxBuffer: REVIEW_DIFF_GIT_MAX_BUFFER_BYTES,
|
|
203393
|
+
timeout: REVIEW_DIFF_GIT_TIMEOUT_MS
|
|
203394
|
+
});
|
|
203050
203395
|
return stdout.trim();
|
|
203051
203396
|
}
|
|
203052
203397
|
async function captureWorkspaceReviewEvidence(options) {
|
|
@@ -203099,13 +203444,60 @@ async function captureWorkspaceReviewEvidence(options) {
|
|
|
203099
203444
|
outOfScopeRepositories
|
|
203100
203445
|
};
|
|
203101
203446
|
}
|
|
203102
|
-
var
|
|
203447
|
+
var execFileAsync11;
|
|
203103
203448
|
var init_workspace_review_evidence = __esm({
|
|
203104
203449
|
"../engine/src/worktree/workspace-review-evidence.ts"() {
|
|
203105
203450
|
"use strict";
|
|
203106
203451
|
init_workspace_base_branch();
|
|
203107
203452
|
init_review_diff_fingerprint();
|
|
203108
|
-
|
|
203453
|
+
execFileAsync11 = promisify34(execFile17);
|
|
203454
|
+
}
|
|
203455
|
+
});
|
|
203456
|
+
|
|
203457
|
+
// ../engine/src/worktree/review-inline-fix-recapture.ts
|
|
203458
|
+
import { execFile as execFile18 } from "node:child_process";
|
|
203459
|
+
import { promisify as promisify35 } from "node:util";
|
|
203460
|
+
function classifyReviewInlineFixRecapture(input) {
|
|
203461
|
+
if (input.reviewKind === "plan") return { recapture: false, reason: "plan-domain" };
|
|
203462
|
+
if (input.verdict !== "APPROVE" && input.verdict !== "APPROVE_WITH_NOTES") {
|
|
203463
|
+
return { recapture: false, reason: "not-approval-verdict" };
|
|
203464
|
+
}
|
|
203465
|
+
if (!input.reviewedCommitSha || !input.currentHeadSha || !input.baseRef) {
|
|
203466
|
+
return { recapture: false, reason: "missing-anchor" };
|
|
203467
|
+
}
|
|
203468
|
+
if (input.reviewedCommitSha === input.currentHeadSha) return { recapture: false, reason: "head-unchanged" };
|
|
203469
|
+
if (input.fastForwardAdvance === void 0 || input.baseIsAncestor === void 0) {
|
|
203470
|
+
return { recapture: false, reason: "probe-unavailable" };
|
|
203471
|
+
}
|
|
203472
|
+
if (!input.fastForwardAdvance) return { recapture: false, reason: "history-rewritten" };
|
|
203473
|
+
if (!input.baseIsAncestor) return { recapture: false, reason: "base-not-ancestor" };
|
|
203474
|
+
if (!input.fingerprintProbeAvailable) return { recapture: false, reason: "probe-unavailable" };
|
|
203475
|
+
return { recapture: true, reason: "recaptured" };
|
|
203476
|
+
}
|
|
203477
|
+
async function readHeadSha(worktreePath) {
|
|
203478
|
+
if (!worktreePath) return void 0;
|
|
203479
|
+
try {
|
|
203480
|
+
const { stdout } = await execFileAsync12("git", ["rev-parse", "HEAD"], { cwd: worktreePath, encoding: "utf8" });
|
|
203481
|
+
return stdout.trim() || void 0;
|
|
203482
|
+
} catch {
|
|
203483
|
+
return void 0;
|
|
203484
|
+
}
|
|
203485
|
+
}
|
|
203486
|
+
async function isFastForwardAdvance(worktreePath, fromSha, toSha) {
|
|
203487
|
+
if (!worktreePath || !fromSha || !toSha) return void 0;
|
|
203488
|
+
try {
|
|
203489
|
+
await execFileAsync12("git", ["merge-base", "--is-ancestor", fromSha, toSha], { cwd: worktreePath, encoding: "utf8" });
|
|
203490
|
+
return true;
|
|
203491
|
+
} catch (error3) {
|
|
203492
|
+
const code = error3?.code;
|
|
203493
|
+
return code === 1 ? false : void 0;
|
|
203494
|
+
}
|
|
203495
|
+
}
|
|
203496
|
+
var execFileAsync12;
|
|
203497
|
+
var init_review_inline_fix_recapture = __esm({
|
|
203498
|
+
"../engine/src/worktree/review-inline-fix-recapture.ts"() {
|
|
203499
|
+
"use strict";
|
|
203500
|
+
execFileAsync12 = promisify35(execFile18);
|
|
203109
203501
|
}
|
|
203110
203502
|
});
|
|
203111
203503
|
|
|
@@ -203295,8 +203687,8 @@ var init_workspace_zero_acquire = __esm({
|
|
|
203295
203687
|
});
|
|
203296
203688
|
|
|
203297
203689
|
// ../engine/src/execution/branch-attribution.ts
|
|
203298
|
-
import { exec as
|
|
203299
|
-
import { promisify as
|
|
203690
|
+
import { exec as exec26 } from "node:child_process";
|
|
203691
|
+
import { promisify as promisify36 } from "node:util";
|
|
203300
203692
|
function quoteShellArg6(value) {
|
|
203301
203693
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
203302
203694
|
}
|
|
@@ -203334,7 +203726,7 @@ function taskIdsMatch(a, b3) {
|
|
|
203334
203726
|
return a.toUpperCase() === b3.toUpperCase();
|
|
203335
203727
|
}
|
|
203336
203728
|
async function collectOwnTaskCommitsForRange(opts) {
|
|
203337
|
-
const execImpl = opts.execAsyncImpl ??
|
|
203729
|
+
const execImpl = opts.execAsyncImpl ?? execAsync23;
|
|
203338
203730
|
let logOutput;
|
|
203339
203731
|
try {
|
|
203340
203732
|
const result2 = await execImpl(
|
|
@@ -203375,7 +203767,7 @@ async function collectOwnTaskCommitsForRange(opts) {
|
|
|
203375
203767
|
return { ownCommitCount: ownCommitShas.length, ownCommitShas };
|
|
203376
203768
|
}
|
|
203377
203769
|
async function filterFilesToOwnTaskCommits(opts) {
|
|
203378
|
-
const execImpl = opts.execAsyncImpl ??
|
|
203770
|
+
const execImpl = opts.execAsyncImpl ?? execAsync23;
|
|
203379
203771
|
const runGit10 = async (command) => {
|
|
203380
203772
|
try {
|
|
203381
203773
|
const { stdout } = await execImpl(command, {
|
|
@@ -203441,11 +203833,11 @@ async function filterFilesToOwnTaskCommits(opts) {
|
|
|
203441
203833
|
commitAttributions
|
|
203442
203834
|
};
|
|
203443
203835
|
}
|
|
203444
|
-
var
|
|
203836
|
+
var execAsync23, GIT_TIMEOUT_MS5, GIT_MAX_BUFFER2, BranchAttributionError, SilentNoOpAttributionMismatchError;
|
|
203445
203837
|
var init_branch_attribution = __esm({
|
|
203446
203838
|
"../engine/src/execution/branch-attribution.ts"() {
|
|
203447
203839
|
"use strict";
|
|
203448
|
-
|
|
203840
|
+
execAsync23 = promisify36(exec26);
|
|
203449
203841
|
GIT_TIMEOUT_MS5 = 3e4;
|
|
203450
203842
|
GIT_MAX_BUFFER2 = 10 * 1024 * 1024;
|
|
203451
203843
|
BranchAttributionError = class extends Error {
|
|
@@ -203479,103 +203871,9 @@ var init_branch_attribution = __esm({
|
|
|
203479
203871
|
}
|
|
203480
203872
|
});
|
|
203481
203873
|
|
|
203482
|
-
// ../engine/src/executor/worktree-git-refs.ts
|
|
203483
|
-
import { exec as exec26, execFile as execFile17, execSync as execSync3 } from "node:child_process";
|
|
203484
|
-
import { promisify as promisify35 } from "node:util";
|
|
203485
|
-
async function preExecutionWorktreeHasWork(worktreePath) {
|
|
203486
|
-
try {
|
|
203487
|
-
const { stdout: dirty } = await execFileAsync11("git", ["status", "--porcelain"], { cwd: worktreePath, timeout: 3e4 });
|
|
203488
|
-
if (dirty.trim()) return true;
|
|
203489
|
-
const { stdout: ahead } = await execFileAsync11("git", ["log", "--oneline", "@{upstream}..HEAD"], { cwd: worktreePath, timeout: 3e4 }).catch(async () => await execFileAsync11("git", ["log", "--oneline", "-1", "HEAD", "--not", "--remotes", "--branches=main", "--branches=master"], { cwd: worktreePath, timeout: 3e4 }));
|
|
203490
|
-
return Boolean(ahead.trim());
|
|
203491
|
-
} catch {
|
|
203492
|
-
return true;
|
|
203493
|
-
}
|
|
203494
|
-
}
|
|
203495
|
-
async function resolveContaminationBaseRef(worktreePath) {
|
|
203496
|
-
try {
|
|
203497
|
-
const { stdout } = await execAsync23(
|
|
203498
|
-
"git merge-base HEAD main 2>/dev/null || git merge-base HEAD origin/main",
|
|
203499
|
-
{ cwd: worktreePath, encoding: "utf-8" }
|
|
203500
|
-
);
|
|
203501
|
-
const ref = stdout.trim();
|
|
203502
|
-
return ref || void 0;
|
|
203503
|
-
} catch (err) {
|
|
203504
|
-
const errorMessage2 = err instanceof Error ? err.message : String(err);
|
|
203505
|
-
executorLog.warn(`Failed merge-base lookup for contamination check in ${worktreePath}: ${errorMessage2}`);
|
|
203506
|
-
return void 0;
|
|
203507
|
-
}
|
|
203508
|
-
}
|
|
203509
|
-
async function resolveDiffBaseRef(worktreePath, baseCommitSha) {
|
|
203510
|
-
if (baseCommitSha) return baseCommitSha;
|
|
203511
|
-
try {
|
|
203512
|
-
const { stdout } = await execAsync23(
|
|
203513
|
-
"git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main",
|
|
203514
|
-
{ cwd: worktreePath, encoding: "utf-8" }
|
|
203515
|
-
);
|
|
203516
|
-
const ref = stdout.trim();
|
|
203517
|
-
if (ref) return ref;
|
|
203518
|
-
} catch (mergeBaseErr) {
|
|
203519
|
-
const mergeBaseMsg = mergeBaseErr instanceof Error ? mergeBaseErr.message : String(mergeBaseErr);
|
|
203520
|
-
executorLog.warn(`Failed merge-base lookup for diff base in ${worktreePath}, trying HEAD~1 fallback: ${mergeBaseMsg}`);
|
|
203521
|
-
}
|
|
203522
|
-
try {
|
|
203523
|
-
const { stdout } = await execAsync23("git rev-parse HEAD~1", {
|
|
203524
|
-
cwd: worktreePath,
|
|
203525
|
-
encoding: "utf-8"
|
|
203526
|
-
});
|
|
203527
|
-
return stdout.trim() || void 0;
|
|
203528
|
-
} catch {
|
|
203529
|
-
executorLog.debug(`Could not determine base commit for diff in ${worktreePath}`);
|
|
203530
|
-
return void 0;
|
|
203531
|
-
}
|
|
203532
|
-
}
|
|
203533
|
-
async function captureBaseCommitSha(store, task, worktreePath, audit, options = { isResume: false }) {
|
|
203534
|
-
try {
|
|
203535
|
-
if (options.isResume && task.baseCommitSha) {
|
|
203536
|
-
try {
|
|
203537
|
-
execSync3(`git merge-base --is-ancestor ${task.baseCommitSha} HEAD`, {
|
|
203538
|
-
cwd: worktreePath,
|
|
203539
|
-
stdio: "pipe"
|
|
203540
|
-
});
|
|
203541
|
-
executorLog.log(`${task.id}: preserved baseCommitSha ${task.baseCommitSha.slice(0, 7)} (resume)`);
|
|
203542
|
-
await audit.git({
|
|
203543
|
-
type: "commit:create",
|
|
203544
|
-
target: task.baseCommitSha,
|
|
203545
|
-
metadata: { purpose: "base", preserved: true }
|
|
203546
|
-
});
|
|
203547
|
-
return;
|
|
203548
|
-
} catch {
|
|
203549
|
-
}
|
|
203550
|
-
}
|
|
203551
|
-
const baseCommitSha = await resolveCapturedBaseCommitSha(worktreePath, {
|
|
203552
|
-
warn: (msg) => executorLog.warn(`${task.id}: ${msg}`)
|
|
203553
|
-
});
|
|
203554
|
-
if (!baseCommitSha) {
|
|
203555
|
-
throw new Error("could not resolve base commit SHA");
|
|
203556
|
-
}
|
|
203557
|
-
await store.updateTask(task.id, { baseCommitSha });
|
|
203558
|
-
executorLog.debug(`${task.id}: captured baseCommitSha ${baseCommitSha.slice(0, 7)}`);
|
|
203559
|
-
await audit.git({ type: "commit:create", target: baseCommitSha, metadata: { purpose: "base", preserved: false } });
|
|
203560
|
-
} catch (err) {
|
|
203561
|
-
const errorMessage2 = err instanceof Error ? err.message : String(err);
|
|
203562
|
-
executorLog.debug(`Failed to capture baseCommitSha for ${task.id}: ${errorMessage2}`);
|
|
203563
|
-
}
|
|
203564
|
-
}
|
|
203565
|
-
var execAsync23, execFileAsync11;
|
|
203566
|
-
var init_worktree_git_refs = __esm({
|
|
203567
|
-
"../engine/src/executor/worktree-git-refs.ts"() {
|
|
203568
|
-
"use strict";
|
|
203569
|
-
init_base_commit_capture();
|
|
203570
|
-
init_logger3();
|
|
203571
|
-
execAsync23 = promisify35(exec26);
|
|
203572
|
-
execFileAsync11 = promisify35(execFile17);
|
|
203573
|
-
}
|
|
203574
|
-
});
|
|
203575
|
-
|
|
203576
203874
|
// ../engine/src/executor/worktree-capture-modified-files.ts
|
|
203577
203875
|
import { exec as exec27 } from "node:child_process";
|
|
203578
|
-
import { promisify as
|
|
203876
|
+
import { promisify as promisify37 } from "node:util";
|
|
203579
203877
|
async function captureModifiedFiles(worktreePath, baseCommitSha, taskId, audit, source = "unspecified") {
|
|
203580
203878
|
try {
|
|
203581
203879
|
const baseRef = await resolveDiffBaseRef(worktreePath, baseCommitSha);
|
|
@@ -203661,7 +203959,7 @@ var init_worktree_capture_modified_files = __esm({
|
|
|
203661
203959
|
init_branch_attribution();
|
|
203662
203960
|
init_logger3();
|
|
203663
203961
|
init_worktree_git_refs();
|
|
203664
|
-
execAsync24 =
|
|
203962
|
+
execAsync24 = promisify37(exec27);
|
|
203665
203963
|
}
|
|
203666
203964
|
});
|
|
203667
203965
|
|
|
@@ -203826,6 +204124,27 @@ ${result2.review}`);
|
|
|
203826
204124
|
summarySections.push(`[${repoRel}] ${result2.verdict}: ${result2.summary}`);
|
|
203827
204125
|
}
|
|
203828
204126
|
const aggregateVerdict = reviewedResults.some(({ result: result2 }) => result2.verdict === "RETHINK") ? "RETHINK" : reviewedResults.some(({ result: result2 }) => result2.verdict === "REVISE") ? "REVISE" : reviewedResults.some(({ result: result2 }) => !isApprovalFamilyVerdict(result2.verdict)) ? "UNAVAILABLE" : "APPROVE";
|
|
204127
|
+
let publishedModifiedFiles = modifiedFiles;
|
|
204128
|
+
if (isApprovalFamilyVerdict(aggregateVerdict) && evidence && options.workspaceRootDir) {
|
|
204129
|
+
try {
|
|
204130
|
+
const refreshed = await captureWorkspaceReviewEvidence({ task, workspaceRootDir: options.workspaceRootDir, settings: options.settings ?? {} });
|
|
204131
|
+
if (refreshed.outOfScopeRepositories.size > 0) {
|
|
204132
|
+
return { verdict: "UNAVAILABLE", retryable: false, review: "Workspace Code Review cannot approve changes outside confirmed scope after review.", summary: "Unavailable: changes outside confirmed scope after review", repositoryScopeRevision };
|
|
204133
|
+
}
|
|
204134
|
+
for (const updated of refreshed.repositories) {
|
|
204135
|
+
const original = evidence.repositories.find((candidate) => candidate.repository === updated.repository);
|
|
204136
|
+
const worktreePath = workspaceWorktrees[updated.repository]?.worktreePath;
|
|
204137
|
+
const outcome = repositoryReviewOutcomes.find((candidate) => candidate.repository === updated.repository && candidate.status === "REVIEWED");
|
|
204138
|
+
if (!original || !worktreePath || !updated.fingerprint || !outcome || !repositoryScope.has(updated.repository)) continue;
|
|
204139
|
+
if (await isFastForwardAdvance(worktreePath, original.branch, updated.branch)) {
|
|
204140
|
+
repositoryDiffFingerprints[updated.repository] = updated.fingerprint;
|
|
204141
|
+
outcome.fingerprint = updated.fingerprint;
|
|
204142
|
+
}
|
|
204143
|
+
}
|
|
204144
|
+
publishedModifiedFiles = refreshed.modifiedFiles;
|
|
204145
|
+
} catch {
|
|
204146
|
+
}
|
|
204147
|
+
}
|
|
203829
204148
|
const blockingRepositories = reviewedResults.filter(({ result: result2 }) => !isApprovalFamilyVerdict(result2.verdict)).map(({ repository }) => repository);
|
|
203830
204149
|
const blockingSummary = blockingRepositories.length > 0 ? `blocking repositories: ${blockingRepositories.join(", ")}` : `all ${repoKeys.length} modified in-scope repositories approved`;
|
|
203831
204150
|
const coverageNotice = noVerdictRepositories.length > 0 ? `
|
|
@@ -203837,7 +204156,7 @@ Not covered by a verdict: ${noVerdictRepositories.join(", ")}.` : "";
|
|
|
203837
204156
|
${reviewSections.join("\n\n")}`,
|
|
203838
204157
|
summary: `${aggregateVerdict} \u2014 ${blockingSummary} \u2014 ${summarySections.join(" | ")}`,
|
|
203839
204158
|
repositoryDiffFingerprints,
|
|
203840
|
-
repositoryModifiedFiles:
|
|
204159
|
+
repositoryModifiedFiles: publishedModifiedFiles,
|
|
203841
204160
|
repositoryReviewOutcomes,
|
|
203842
204161
|
...findings.length > 0 ? { findings } : {},
|
|
203843
204162
|
repositoryScopeRevision
|
|
@@ -203848,6 +204167,7 @@ var init_workspace_review_per_repo = __esm({
|
|
|
203848
204167
|
"../engine/src/executor/workspace-review-per-repo.ts"() {
|
|
203849
204168
|
"use strict";
|
|
203850
204169
|
init_workspace_review_evidence();
|
|
204170
|
+
init_review_inline_fix_recapture();
|
|
203851
204171
|
init_workspace_zero_acquire();
|
|
203852
204172
|
init_worktree_capture_modified_files();
|
|
203853
204173
|
hasRepositoryPrefix = (value, repoRel, separator) => value === repoRel || value?.startsWith(`${repoRel}${separator}`) === true;
|
|
@@ -205212,6 +205532,8 @@ async function runGraphCustomNode(deps, node, nodeTask, settings, columnBinding,
|
|
|
205212
205532
|
}
|
|
205213
205533
|
const optionalGroupId = typeof graphContext?.[WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY] === "string" ? graphContext[WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY] : void 0;
|
|
205214
205534
|
const declaredReviewKind = cfg.reviewKind === "plan" || cfg.reviewKind === "code" ? cfg.reviewKind : graphContext?.[WORKFLOW_REVIEW_KIND_CONTEXT_KEY] === "plan" || graphContext?.[WORKFLOW_REVIEW_KIND_CONTEXT_KEY] === "code" ? graphContext[WORKFLOW_REVIEW_KIND_CONTEXT_KEY] : void 0;
|
|
205535
|
+
const effectiveStepId = optionalGroupId ?? node.id;
|
|
205536
|
+
const isContentBindingStep = requiresContentReviewProof(effectiveStepId, { reviewKind: declaredReviewKind });
|
|
205215
205537
|
if (isFastExecutionMode(live) && graphContext?.["workflow:fast-lane-active"] === true && isFastLaneSkippableCustomNode(node, { optionalGroupId })) {
|
|
205216
205538
|
executorLog.debug(`${live.id}: fast mode \u2014 skipping custom graph node '${node.id}'`);
|
|
205217
205539
|
await deps.store.logEntry(
|
|
@@ -205406,6 +205728,7 @@ ${prompt}`;
|
|
|
205406
205728
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
205407
205729
|
const stepSkillName = executorKind === "skill" && typeof cfg.skillName === "string" && cfg.skillName.trim() ? cfg.skillName.trim() : void 0;
|
|
205408
205730
|
const stepThinkingLevel = typeof cfg.thinkingLevel === "string" && WORKFLOW_THINKING_LEVEL_SET2.has(cfg.thinkingLevel) ? cfg.thinkingLevel : void 0;
|
|
205731
|
+
const readonlyMcpServers = Array.isArray(cfg.readonlyMcpServers) ? [...new Set(cfg.readonlyMcpServers.filter((name2) => typeof name2 === "string").map((name2) => name2.trim()).filter(Boolean))] : [];
|
|
205409
205732
|
const step = {
|
|
205410
205733
|
id: `graph:${node.id}`,
|
|
205411
205734
|
name: typeof cfg.name === "string" && cfg.name.trim() ? cfg.name : node.id,
|
|
@@ -205422,7 +205745,8 @@ ${prompt}`;
|
|
|
205422
205745
|
...stepSkillName ? { skillName: stepSkillName } : {},
|
|
205423
205746
|
...cfg.requiresBrowser === true ? { requiresBrowser: true } : {},
|
|
205424
205747
|
...modelProvider && modelId ? { modelProvider, modelId } : {},
|
|
205425
|
-
...stepThinkingLevel ? { thinkingLevel: stepThinkingLevel } : {}
|
|
205748
|
+
...stepThinkingLevel ? { thinkingLevel: stepThinkingLevel } : {},
|
|
205749
|
+
...readonlyMcpServers.length > 0 ? { readonlyMcpServers } : {}
|
|
205426
205750
|
};
|
|
205427
205751
|
if (cfg.summaryTarget === "task") {
|
|
205428
205752
|
step.summaryTarget = "task";
|
|
@@ -205536,12 +205860,36 @@ ${prompt}`;
|
|
|
205536
205860
|
outcome = buildWorkspaceReviewOutcome(aggregate, { superseded: reviewSuperseded });
|
|
205537
205861
|
}
|
|
205538
205862
|
} else {
|
|
205539
|
-
|
|
205540
|
-
|
|
205541
|
-
|
|
205542
|
-
|
|
205543
|
-
|
|
205544
|
-
|
|
205863
|
+
const dispatchSingularStep = async (reviewInputFingerprint) => {
|
|
205864
|
+
if (mode === "script") {
|
|
205865
|
+
const scriptOutcome = await deps.executeScriptWorkflowStep(live, step, worktreePath, settings, nodeEnv);
|
|
205866
|
+
return reviewInputFingerprint === void 0 ? scriptOutcome : { ...scriptOutcome, reviewInputFingerprint };
|
|
205867
|
+
}
|
|
205868
|
+
return deps.executeWorkflowStep(live, step, worktreePath, settings, nodeEnv, {
|
|
205869
|
+
unattended,
|
|
205870
|
+
principalAgentId,
|
|
205871
|
+
outputLanguage,
|
|
205872
|
+
...nodeSessionBoundary ? { sessionBoundary: nodeSessionBoundary } : {},
|
|
205873
|
+
...reviewInputFingerprint !== void 0 ? { reviewInputFingerprint } : {}
|
|
205874
|
+
});
|
|
205875
|
+
};
|
|
205876
|
+
if (isContentBindingStep && !workspaceConfig) {
|
|
205877
|
+
const proof = await resolveContentReviewInputProof(worktreePath, executionTarget.baseCommitSha);
|
|
205878
|
+
if (proof.kind === "unprovable") {
|
|
205879
|
+
const diagnostic = `${step.name} review input is unprovable (${proof.reason}); reviewer dispatch refused.`;
|
|
205880
|
+
await deps.store.logEntry(
|
|
205881
|
+
live.id,
|
|
205882
|
+
`[pre-merge] ${diagnostic}`,
|
|
205883
|
+
void 0,
|
|
205884
|
+
deps.getRunContextFor(live.id)
|
|
205885
|
+
);
|
|
205886
|
+
outcome = { success: false, error: diagnostic, failureValue: "review-input-unprovable" };
|
|
205887
|
+
} else {
|
|
205888
|
+
outcome = await dispatchSingularStep(proof.fingerprint);
|
|
205889
|
+
}
|
|
205890
|
+
} else {
|
|
205891
|
+
outcome = await dispatchSingularStep();
|
|
205892
|
+
}
|
|
205545
205893
|
}
|
|
205546
205894
|
if (declaredReviewKind && typeof outcome.output === "string") {
|
|
205547
205895
|
const rawReviewOutput = outcome.output;
|
|
@@ -205628,6 +205976,7 @@ var init_run_graph_custom_node = __esm({
|
|
|
205628
205976
|
init_create_authoritative_workflow_seams();
|
|
205629
205977
|
init_verification_gate();
|
|
205630
205978
|
init_worktree_dependency_install();
|
|
205979
|
+
init_review_diff_fingerprint();
|
|
205631
205980
|
WORKFLOW_THINKING_LEVEL_SET2 = new Set(THINKING_LEVELS);
|
|
205632
205981
|
WORKFLOW_STEP_NOT_RUN_REASON_SET2 = new Set(WORKFLOW_STEP_NOT_RUN_REASONS);
|
|
205633
205982
|
WORKSPACE_REPO_REVIEW_NO_NOTES_NOTICE = "The repository reviewer recorded no notes for this verdict.";
|
|
@@ -207687,7 +208036,7 @@ var init_agent_heartbeat_error_recovery = __esm({
|
|
|
207687
208036
|
|
|
207688
208037
|
// ../engine/src/agent-heartbeat.ts
|
|
207689
208038
|
import { Type as Type3 } from "@earendil-works/pi-ai";
|
|
207690
|
-
import { createHash as
|
|
208039
|
+
import { createHash as createHash32 } from "node:crypto";
|
|
207691
208040
|
async function resolveHeartbeatReboundColumn(taskStore, taskId) {
|
|
207692
208041
|
try {
|
|
207693
208042
|
return resolveReboundTarget(await resolveWorkflowIrForTask(taskStore, taskId)) ?? "todo";
|
|
@@ -207842,7 +208191,7 @@ function truncatePrompt(text3, maxChars) {
|
|
|
207842
208191
|
... (truncated, ${text3.length} chars)`;
|
|
207843
208192
|
}
|
|
207844
208193
|
function shortContentHash(value) {
|
|
207845
|
-
return
|
|
208194
|
+
return createHash32("sha256").update(value).digest("hex").slice(0, 8);
|
|
207846
208195
|
}
|
|
207847
208196
|
function buildIdentitySnapshot(args) {
|
|
207848
208197
|
const { agent, resolvedInstructions, workspaceMemory } = args;
|
|
@@ -212275,6 +212624,91 @@ var init_auto_merge_finalization = __esm({
|
|
|
212275
212624
|
}
|
|
212276
212625
|
});
|
|
212277
212626
|
|
|
212627
|
+
// ../engine/src/merge/merge-content-capture.ts
|
|
212628
|
+
async function captureMergeContentDescriptor(task, deps) {
|
|
212629
|
+
if (describeMergeContentShape(task) === "workspace") {
|
|
212630
|
+
try {
|
|
212631
|
+
const evidence = await captureWorkspaceReviewEvidence({
|
|
212632
|
+
task,
|
|
212633
|
+
workspaceRootDir: deps.workspaceRootDir,
|
|
212634
|
+
settings: deps.settings
|
|
212635
|
+
});
|
|
212636
|
+
return {
|
|
212637
|
+
kind: "workspace",
|
|
212638
|
+
repositories: {
|
|
212639
|
+
state: "captured",
|
|
212640
|
+
fingerprints: Object.fromEntries(evidence.repositories.filter((repository) => repository.fingerprint).map((repository) => [repository.repository, repository.fingerprint])),
|
|
212641
|
+
inScopeModified: [...evidence.modifiedRepositories].sort()
|
|
212642
|
+
}
|
|
212643
|
+
};
|
|
212644
|
+
} catch {
|
|
212645
|
+
return { kind: "workspace", repositories: { state: "unavailable", reason: "workspace-evidence-capture-failed" } };
|
|
212646
|
+
}
|
|
212647
|
+
}
|
|
212648
|
+
const baseRef = task.worktree ? await resolveDiffBaseRef(task.worktree, task.baseCommitSha) : void 0;
|
|
212649
|
+
const probe = await probeReviewDiffFingerprint(task.worktree, baseRef);
|
|
212650
|
+
return { kind: "singular", diff: probe };
|
|
212651
|
+
}
|
|
212652
|
+
var init_merge_content_capture = __esm({
|
|
212653
|
+
"../engine/src/merge/merge-content-capture.ts"() {
|
|
212654
|
+
"use strict";
|
|
212655
|
+
init_src2();
|
|
212656
|
+
init_worktree_git_refs();
|
|
212657
|
+
init_review_diff_fingerprint();
|
|
212658
|
+
init_workspace_review_evidence();
|
|
212659
|
+
}
|
|
212660
|
+
});
|
|
212661
|
+
|
|
212662
|
+
// ../engine/src/merge/stale-content-review-reroute.ts
|
|
212663
|
+
function isContentReviewNode(node) {
|
|
212664
|
+
if (node.kind !== "optional-group" && node.kind !== "step-review") return false;
|
|
212665
|
+
const name2 = typeof node.config?.name === "string" ? node.config.name : "";
|
|
212666
|
+
return node.id === "code-review" || node.config?.reviewKind === "code" || /code review/i.test(name2);
|
|
212667
|
+
}
|
|
212668
|
+
async function rerouteSingularStaleContentToReview(store, task, options) {
|
|
212669
|
+
const mergeContent = options.mergeContent;
|
|
212670
|
+
if (mergeContent.kind !== "singular" || task.workspaceWorktrees !== void 0) {
|
|
212671
|
+
return { rerouted: false, reason: "not-singular" };
|
|
212672
|
+
}
|
|
212673
|
+
if (task.paused || task.userPaused || task.deletedAt || task.autoMerge === false) {
|
|
212674
|
+
return { rerouted: false, reason: "operator-held" };
|
|
212675
|
+
}
|
|
212676
|
+
if (mergeContent.diff.state !== "fingerprint") return { rerouted: false, reason: "no-progress" };
|
|
212677
|
+
const currentFingerprint = mergeContent.diff.fingerprint;
|
|
212678
|
+
const ir2 = await resolveWorkflowIrForTask(store, task.id);
|
|
212679
|
+
const selection = store.getTaskWorkflowSelectionAsync ? await store.getTaskWorkflowSelectionAsync(task.id) : store.getTaskWorkflowSelection(task.id);
|
|
212680
|
+
const selected = selection?.stepIds ?? [];
|
|
212681
|
+
const nodes2 = ir2.nodes.filter((node2) => {
|
|
212682
|
+
if (!isContentReviewNode(node2) || !options.requiredPreMergeStepIds.has(node2.id)) return false;
|
|
212683
|
+
return node2.config?.defaultOn === true || selected.includes(node2.id);
|
|
212684
|
+
});
|
|
212685
|
+
const node = nodes2.find((candidate) => {
|
|
212686
|
+
const latest = task.workflowStepResults?.filter((result3) => result3.workflowStepId === candidate.id).at(-1);
|
|
212687
|
+
return latest?.reviewInputFingerprint !== currentFingerprint;
|
|
212688
|
+
});
|
|
212689
|
+
if (!node) return { rerouted: false, reason: nodes2.length ? "no-progress" : "no-review-route" };
|
|
212690
|
+
const items = await store.listWorkflowWorkItemsForTask(task.id);
|
|
212691
|
+
const result2 = await store.seedWorkspaceCodeReviewContinuationIfIdle({
|
|
212692
|
+
taskId: task.id,
|
|
212693
|
+
nodeId: node.id,
|
|
212694
|
+
kind: "task",
|
|
212695
|
+
state: "runnable",
|
|
212696
|
+
runId: `${task.id}:stale-content-review-reroute:${node.id}:${items.length}`,
|
|
212697
|
+
stableWorkflowRunId: `${task.id}:${ir2.name}`,
|
|
212698
|
+
continuationSequence: items.length,
|
|
212699
|
+
sourceColumn: task.column,
|
|
212700
|
+
targetColumn: node.column ?? task.column,
|
|
212701
|
+
irHash: computeWorkflowIrPin(ir2, node.id).irHash
|
|
212702
|
+
});
|
|
212703
|
+
return result2.seeded ? { rerouted: true, reason: "seeded", nodeId: node.id, workflowStepId: node.id } : { rerouted: false, reason: "active-continuation", nodeId: node.id, workflowStepId: node.id };
|
|
212704
|
+
}
|
|
212705
|
+
var init_stale_content_review_reroute = __esm({
|
|
212706
|
+
"../engine/src/merge/stale-content-review-reroute.ts"() {
|
|
212707
|
+
"use strict";
|
|
212708
|
+
init_src2();
|
|
212709
|
+
}
|
|
212710
|
+
});
|
|
212711
|
+
|
|
212278
212712
|
// ../engine/src/healing/auto-recovery.ts
|
|
212279
212713
|
function actionForMode(mode, failureClass) {
|
|
212280
212714
|
if (mode === "off") return "pause";
|
|
@@ -212431,10 +212865,10 @@ var init_stranded_continuation_reclaim = __esm({
|
|
|
212431
212865
|
});
|
|
212432
212866
|
|
|
212433
212867
|
// ../engine/src/merge/workspace-land-predicate.ts
|
|
212434
|
-
import { execFile as
|
|
212435
|
-
import { promisify as
|
|
212868
|
+
import { execFile as execFile19 } from "node:child_process";
|
|
212869
|
+
import { promisify as promisify38 } from "node:util";
|
|
212436
212870
|
async function git4(args, cwd, opts = {}) {
|
|
212437
|
-
const { stdout } = await
|
|
212871
|
+
const { stdout } = await execFileAsync13("git", args, {
|
|
212438
212872
|
cwd,
|
|
212439
212873
|
encoding: "utf-8",
|
|
212440
212874
|
timeout: opts.timeout ?? 12e4,
|
|
@@ -212513,11 +212947,11 @@ async function isRepoLanded(repoRootDir, integrationBranch, landedSha, taskId, b
|
|
|
212513
212947
|
await findProvenLandedCommit(repoRootDir, integrationBranch, landedSha, taskId, branch, revertBoundarySha, taskCreatedAt)
|
|
212514
212948
|
);
|
|
212515
212949
|
}
|
|
212516
|
-
var
|
|
212950
|
+
var execFileAsync13, FUSION_TASK_ID_TRAILER_KEY2, TRAILER_SCAN_CLOCK_SKEW_MS, UNBOUNDED_TRAILER_SCAN_WINDOW_MS, UNBOUNDED_TRAILER_SCAN_MAX_COMMITS;
|
|
212517
212951
|
var init_workspace_land_predicate = __esm({
|
|
212518
212952
|
"../engine/src/merge/workspace-land-predicate.ts"() {
|
|
212519
212953
|
"use strict";
|
|
212520
|
-
|
|
212954
|
+
execFileAsync13 = promisify38(execFile19);
|
|
212521
212955
|
FUSION_TASK_ID_TRAILER_KEY2 = "Fusion-Task-Id";
|
|
212522
212956
|
TRAILER_SCAN_CLOCK_SKEW_MS = 24 * 60 * 60 * 1e3;
|
|
212523
212957
|
UNBOUNDED_TRAILER_SCAN_WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
@@ -212542,7 +212976,7 @@ var init_workspace_land_failure = __esm({
|
|
|
212542
212976
|
|
|
212543
212977
|
// ../engine/src/merge/already-merged-detector.ts
|
|
212544
212978
|
import { exec as exec28, execSync as execSync4 } from "node:child_process";
|
|
212545
|
-
import { promisify as
|
|
212979
|
+
import { promisify as promisify39 } from "node:util";
|
|
212546
212980
|
function shellQuote(value) {
|
|
212547
212981
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
212548
212982
|
}
|
|
@@ -212818,7 +213252,7 @@ var init_already_merged_detector = __esm({
|
|
|
212818
213252
|
"../engine/src/merge/already-merged-detector.ts"() {
|
|
212819
213253
|
"use strict";
|
|
212820
213254
|
init_worktree_names();
|
|
212821
|
-
execAsync25 =
|
|
213255
|
+
execAsync25 = promisify39(exec28);
|
|
212822
213256
|
}
|
|
212823
213257
|
});
|
|
212824
213258
|
|
|
@@ -212950,10 +213384,10 @@ var init_review_empty_content_close = __esm({
|
|
|
212950
213384
|
});
|
|
212951
213385
|
|
|
212952
213386
|
// ../engine/src/merge/merger-ref-update-advance.ts
|
|
212953
|
-
import { execFile as
|
|
212954
|
-
import { promisify as
|
|
213387
|
+
import { execFile as execFile20 } from "node:child_process";
|
|
213388
|
+
import { promisify as promisify40 } from "node:util";
|
|
212955
213389
|
async function runGit3(args, cwd) {
|
|
212956
|
-
return await
|
|
213390
|
+
return await execFileAsync14("git", args, {
|
|
212957
213391
|
cwd,
|
|
212958
213392
|
encoding: "utf-8",
|
|
212959
213393
|
timeout: 3e4
|
|
@@ -213100,11 +213534,11 @@ async function advanceIntegrationBranchRef(args) {
|
|
|
213100
213534
|
};
|
|
213101
213535
|
}
|
|
213102
213536
|
}
|
|
213103
|
-
var
|
|
213537
|
+
var execFileAsync14, testHooks, IntegrationBranchConcurrentAdvanceError;
|
|
213104
213538
|
var init_merger_ref_update_advance = __esm({
|
|
213105
213539
|
"../engine/src/merge/merger-ref-update-advance.ts"() {
|
|
213106
213540
|
"use strict";
|
|
213107
|
-
|
|
213541
|
+
execFileAsync14 = promisify40(execFile20);
|
|
213108
213542
|
testHooks = {
|
|
213109
213543
|
runGit: runGit3
|
|
213110
213544
|
};
|
|
@@ -213132,7 +213566,7 @@ var init_merger_ref_update_advance = __esm({
|
|
|
213132
213566
|
|
|
213133
213567
|
// ../engine/src/merge/group-merge-coordinator.ts
|
|
213134
213568
|
import * as childProcess2 from "node:child_process";
|
|
213135
|
-
import { promisify as
|
|
213569
|
+
import { promisify as promisify41 } from "node:util";
|
|
213136
213570
|
function evaluateBranchGroupCompletion(input) {
|
|
213137
213571
|
const landedMemberIds = [];
|
|
213138
213572
|
const pendingMemberIds = [];
|
|
@@ -213172,10 +213606,10 @@ function evaluateBranchGroupPromotion(input) {
|
|
|
213172
213606
|
}
|
|
213173
213607
|
async function ensureGroupBranchExists(rootDir, branchName, startPoint) {
|
|
213174
213608
|
try {
|
|
213175
|
-
await
|
|
213609
|
+
await execFileAsync15("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], { cwd: rootDir });
|
|
213176
213610
|
return;
|
|
213177
213611
|
} catch {
|
|
213178
|
-
await
|
|
213612
|
+
await execFileAsync15("git", ["branch", branchName, startPoint], { cwd: rootDir });
|
|
213179
213613
|
}
|
|
213180
213614
|
}
|
|
213181
213615
|
function throwIfPromotionAborted(signal) {
|
|
@@ -213280,14 +213714,14 @@ async function promoteBranchGroupInner(input) {
|
|
|
213280
213714
|
if (!needsPrRepair && !isPrMode) {
|
|
213281
213715
|
throwIfPromotionAborted(input.signal);
|
|
213282
213716
|
await ensureGroupBranchExists(input.rootDir, group.branchName, integrationBranch);
|
|
213283
|
-
const currentBranch2 = (await
|
|
213717
|
+
const currentBranch2 = (await execFileAsync15("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: input.rootDir })).stdout.trim();
|
|
213284
213718
|
try {
|
|
213285
213719
|
throwIfPromotionAborted(input.signal);
|
|
213286
|
-
await
|
|
213720
|
+
await execFileAsync15("git", ["checkout", integrationBranch], { cwd: input.rootDir, signal: input.signal });
|
|
213287
213721
|
throwIfPromotionAborted(input.signal);
|
|
213288
|
-
await
|
|
213722
|
+
await execFileAsync15("git", ["merge", "--no-ff", "--no-edit", group.branchName], { cwd: input.rootDir, signal: input.signal });
|
|
213289
213723
|
} finally {
|
|
213290
|
-
await
|
|
213724
|
+
await execFileAsync15("git", ["checkout", currentBranch2], { cwd: input.rootDir });
|
|
213291
213725
|
}
|
|
213292
213726
|
}
|
|
213293
213727
|
let prNumber = group.prNumber;
|
|
@@ -213411,20 +213845,20 @@ async function resolveBranchGroupMergeRouting(input) {
|
|
|
213411
213845
|
)
|
|
213412
213846
|
};
|
|
213413
213847
|
}
|
|
213414
|
-
var
|
|
213848
|
+
var execFileAsync15, promotionLocks;
|
|
213415
213849
|
var init_group_merge_coordinator = __esm({
|
|
213416
213850
|
"../engine/src/merge/group-merge-coordinator.ts"() {
|
|
213417
213851
|
"use strict";
|
|
213418
213852
|
init_src2();
|
|
213419
213853
|
init_integration_branch();
|
|
213420
|
-
|
|
213854
|
+
execFileAsync15 = (file, args, opts) => promisify41(childProcess2.execFile)(file, args, opts);
|
|
213421
213855
|
promotionLocks = /* @__PURE__ */ new Map();
|
|
213422
213856
|
}
|
|
213423
213857
|
});
|
|
213424
213858
|
|
|
213425
213859
|
// ../engine/src/merge/merger-bare-subject.ts
|
|
213426
213860
|
import { exec as exec29 } from "node:child_process";
|
|
213427
|
-
import { promisify as
|
|
213861
|
+
import { promisify as promisify42 } from "node:util";
|
|
213428
213862
|
function quoteArg(value) {
|
|
213429
213863
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
213430
213864
|
}
|
|
@@ -213464,7 +213898,7 @@ var init_merger_bare_subject = __esm({
|
|
|
213464
213898
|
"use strict";
|
|
213465
213899
|
init_src2();
|
|
213466
213900
|
init_logger3();
|
|
213467
|
-
execAsync26 =
|
|
213901
|
+
execAsync26 = promisify42(exec29);
|
|
213468
213902
|
BARE_MERGE_SUBJECT_RE = /^[a-z]+(?:\([^)]+\))?!?:\s*merge\s+\S+\s*$/i;
|
|
213469
213903
|
}
|
|
213470
213904
|
});
|
|
@@ -213472,7 +213906,7 @@ var init_merger_bare_subject = __esm({
|
|
|
213472
213906
|
// ../engine/src/recovery/foreign-only-contamination.ts
|
|
213473
213907
|
import { exec as exec30 } from "node:child_process";
|
|
213474
213908
|
import { existsSync as existsSync62 } from "node:fs";
|
|
213475
|
-
import { promisify as
|
|
213909
|
+
import { promisify as promisify43 } from "node:util";
|
|
213476
213910
|
function quote3(value) {
|
|
213477
213911
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
213478
213912
|
}
|
|
@@ -213580,7 +214014,7 @@ var init_foreign_only_contamination = __esm({
|
|
|
213580
214014
|
init_lifecycle_move();
|
|
213581
214015
|
init_branch_conflicts();
|
|
213582
214016
|
init_worktree_pool();
|
|
213583
|
-
execAsync27 =
|
|
214017
|
+
execAsync27 = promisify43(exec30);
|
|
213584
214018
|
GIT_TIMEOUT_MS6 = 3e4;
|
|
213585
214019
|
GIT_MAX_BUFFER3 = 10 * 1024 * 1024;
|
|
213586
214020
|
}
|
|
@@ -213677,7 +214111,7 @@ var init_surfacing_sweeps = __esm({
|
|
|
213677
214111
|
});
|
|
213678
214112
|
|
|
213679
214113
|
// ../engine/src/self-healing-git-evidence.ts
|
|
213680
|
-
import { promisify as
|
|
214114
|
+
import { promisify as promisify44 } from "node:util";
|
|
213681
214115
|
import { exec as exec31 } from "node:child_process";
|
|
213682
214116
|
function classifyBranchProbeError(error3) {
|
|
213683
214117
|
if (typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === 1 && !error3.killed && (error3.signal === null || error3.signal === void 0)) {
|
|
@@ -213721,7 +214155,7 @@ var init_self_healing_git_evidence = __esm({
|
|
|
213721
214155
|
init_already_merged_detector();
|
|
213722
214156
|
init_logger3();
|
|
213723
214157
|
log32 = createLogger2("self-healing");
|
|
213724
|
-
execAsync28 =
|
|
214158
|
+
execAsync28 = promisify44(exec31);
|
|
213725
214159
|
SelfHealingGitEvidence = class {
|
|
213726
214160
|
async findLandedTaskCommit(task, options) {
|
|
213727
214161
|
const rebaseBaseSha = task.mergeDetails?.rebaseBaseSha;
|
|
@@ -214083,12 +214517,12 @@ var init_self_healing_constants = __esm({
|
|
|
214083
214517
|
});
|
|
214084
214518
|
|
|
214085
214519
|
// ../engine/src/healing/self-healing-branch.ts
|
|
214086
|
-
import { promisify as
|
|
214087
|
-
import { execFile as
|
|
214520
|
+
import { promisify as promisify45 } from "node:util";
|
|
214521
|
+
import { execFile as execFile22 } from "node:child_process";
|
|
214088
214522
|
async function isBranchAheadOfBase(task, rootDir, preferredBaseRef) {
|
|
214089
214523
|
const branchName = resolveTaskWorkingBranch(task);
|
|
214090
214524
|
try {
|
|
214091
|
-
await
|
|
214525
|
+
await execFileAsync16("git", ["rev-parse", "--verify", branchName], {
|
|
214092
214526
|
cwd: rootDir,
|
|
214093
214527
|
timeout: 3e4
|
|
214094
214528
|
});
|
|
@@ -214098,14 +214532,14 @@ async function isBranchAheadOfBase(task, rootDir, preferredBaseRef) {
|
|
|
214098
214532
|
const requestedBaseRef = preferredBaseRef || task.mergeDetails?.mergeTargetBranch || await resolveIntegrationBranch(rootDir, void 0);
|
|
214099
214533
|
let resolvedBaseRef = requestedBaseRef;
|
|
214100
214534
|
try {
|
|
214101
|
-
await
|
|
214535
|
+
await execFileAsync16("git", ["rev-parse", "--verify", requestedBaseRef], {
|
|
214102
214536
|
cwd: rootDir,
|
|
214103
214537
|
timeout: 3e4
|
|
214104
214538
|
});
|
|
214105
214539
|
} catch {
|
|
214106
214540
|
const remoteRef = `origin/${requestedBaseRef}`;
|
|
214107
214541
|
try {
|
|
214108
|
-
await
|
|
214542
|
+
await execFileAsync16("git", ["rev-parse", "--verify", remoteRef], {
|
|
214109
214543
|
cwd: rootDir,
|
|
214110
214544
|
timeout: 3e4
|
|
214111
214545
|
});
|
|
@@ -214115,7 +214549,7 @@ async function isBranchAheadOfBase(task, rootDir, preferredBaseRef) {
|
|
|
214115
214549
|
}
|
|
214116
214550
|
}
|
|
214117
214551
|
try {
|
|
214118
|
-
const { stdout } = await
|
|
214552
|
+
const { stdout } = await execFileAsync16(
|
|
214119
214553
|
"git",
|
|
214120
214554
|
["rev-list", "--count", `${resolvedBaseRef}..${branchName}`],
|
|
214121
214555
|
{ cwd: rootDir, timeout: 3e4 }
|
|
@@ -214133,7 +214567,7 @@ async function isBranchAheadOfBase(task, rootDir, preferredBaseRef) {
|
|
|
214133
214567
|
return null;
|
|
214134
214568
|
}
|
|
214135
214569
|
}
|
|
214136
|
-
var log33,
|
|
214570
|
+
var log33, execFileAsync16;
|
|
214137
214571
|
var init_self_healing_branch = __esm({
|
|
214138
214572
|
"../engine/src/healing/self-healing-branch.ts"() {
|
|
214139
214573
|
"use strict";
|
|
@@ -214141,7 +214575,7 @@ var init_self_healing_branch = __esm({
|
|
|
214141
214575
|
init_integration_branch();
|
|
214142
214576
|
init_logger3();
|
|
214143
214577
|
log33 = createLogger2("self-healing");
|
|
214144
|
-
|
|
214578
|
+
execFileAsync16 = promisify45(execFile22);
|
|
214145
214579
|
}
|
|
214146
214580
|
});
|
|
214147
214581
|
|
|
@@ -214978,7 +215412,7 @@ var init_merger_workspace_test_commands = __esm({
|
|
|
214978
215412
|
});
|
|
214979
215413
|
|
|
214980
215414
|
// ../engine/src/merge/merger-file-scope.ts
|
|
214981
|
-
import { promisify as
|
|
215415
|
+
import { promisify as promisify46 } from "node:util";
|
|
214982
215416
|
import { exec as exec32 } from "node:child_process";
|
|
214983
215417
|
function parseDiffStat(diffStat) {
|
|
214984
215418
|
const entries = [];
|
|
@@ -215190,7 +215624,7 @@ var init_merger_file_scope = __esm({
|
|
|
215190
215624
|
init_merger_glob();
|
|
215191
215625
|
init_logger3();
|
|
215192
215626
|
init_merge_trait();
|
|
215193
|
-
execAsync29 =
|
|
215627
|
+
execAsync29 = promisify46(exec32);
|
|
215194
215628
|
FileScopeViolationError = class extends Error {
|
|
215195
215629
|
taskId;
|
|
215196
215630
|
stagedFiles;
|
|
@@ -215250,7 +215684,7 @@ var init_merger_errors = __esm({
|
|
|
215250
215684
|
});
|
|
215251
215685
|
|
|
215252
215686
|
// ../engine/src/merge/merger-owned-landed.ts
|
|
215253
|
-
import { promisify as
|
|
215687
|
+
import { promisify as promisify47 } from "node:util";
|
|
215254
215688
|
import * as childProcess3 from "node:child_process";
|
|
215255
215689
|
function escapeRegexForOwnership(value) {
|
|
215256
215690
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -215267,8 +215701,8 @@ function commitOwnedByTask2(taskId, subject, body) {
|
|
|
215267
215701
|
async function findOwnedLandedCommitForTask(rootDir, task) {
|
|
215268
215702
|
const tryHydrate = async (sha) => {
|
|
215269
215703
|
try {
|
|
215270
|
-
await
|
|
215271
|
-
const { stdout } = await
|
|
215704
|
+
await execFileAsync17("git", ["merge-base", "--is-ancestor", sha, "HEAD"], { cwd: rootDir });
|
|
215705
|
+
const { stdout } = await execFileAsync17("git", ["log", "-1", "--format=%H%x1f%s%x1f%b", sha], {
|
|
215272
215706
|
cwd: rootDir,
|
|
215273
215707
|
encoding: "utf-8"
|
|
215274
215708
|
});
|
|
@@ -215276,7 +215710,7 @@ async function findOwnedLandedCommitForTask(rootDir, task) {
|
|
|
215276
215710
|
if (!resolvedSha || !commitOwnedByTask2(task.id, subject, body)) return null;
|
|
215277
215711
|
const owned = { sha: resolvedSha, subject };
|
|
215278
215712
|
try {
|
|
215279
|
-
const { stdout: statsOut } = await
|
|
215713
|
+
const { stdout: statsOut } = await execFileAsync17("git", ["show", "--shortstat", "--format=", resolvedSha], {
|
|
215280
215714
|
cwd: rootDir,
|
|
215281
215715
|
encoding: "utf-8"
|
|
215282
215716
|
});
|
|
@@ -215299,7 +215733,7 @@ async function findOwnedLandedCommitForTask(rootDir, task) {
|
|
|
215299
215733
|
];
|
|
215300
215734
|
for (const args of searches) {
|
|
215301
215735
|
try {
|
|
215302
|
-
const { stdout } = await
|
|
215736
|
+
const { stdout } = await execFileAsync17("git", args, { cwd: rootDir, encoding: "utf-8" });
|
|
215303
215737
|
const first = stdout.trim().split("\n").find(Boolean);
|
|
215304
215738
|
if (!first) continue;
|
|
215305
215739
|
const [sha] = first.split("");
|
|
@@ -215320,14 +215754,14 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215320
215754
|
const ownedCommit = await findOwnedLandedCommitForTask(rootDir, task);
|
|
215321
215755
|
if (ownedCommit) {
|
|
215322
215756
|
try {
|
|
215323
|
-
await
|
|
215757
|
+
await execFileAsync17("git", ["merge-base", "--is-ancestor", ownedCommit.sha, mergeTargetBranch], { cwd: rootDir });
|
|
215324
215758
|
return { kind: "owned-commit", commit: ownedCommit };
|
|
215325
215759
|
} catch {
|
|
215326
215760
|
}
|
|
215327
215761
|
}
|
|
215328
215762
|
let aheadCount = null;
|
|
215329
215763
|
try {
|
|
215330
|
-
const { stdout } = await
|
|
215764
|
+
const { stdout } = await execFileAsync17("git", ["rev-list", "--count", `${mergeTargetBranch}..${branch}`], {
|
|
215331
215765
|
cwd: rootDir,
|
|
215332
215766
|
encoding: "utf-8"
|
|
215333
215767
|
});
|
|
@@ -215339,7 +215773,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215339
215773
|
let baseReachableFromTarget = false;
|
|
215340
215774
|
if (task.baseCommitSha) {
|
|
215341
215775
|
try {
|
|
215342
|
-
await
|
|
215776
|
+
await execFileAsync17("git", ["merge-base", "--is-ancestor", task.baseCommitSha, mergeTargetBranch], { cwd: rootDir });
|
|
215343
215777
|
baseReachableFromTarget = true;
|
|
215344
215778
|
} catch {
|
|
215345
215779
|
baseReachableFromTarget = false;
|
|
@@ -215350,7 +215784,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215350
215784
|
}
|
|
215351
215785
|
if (aheadCount !== null && aheadCount > 0) {
|
|
215352
215786
|
try {
|
|
215353
|
-
const { stdout: mergeBaseOut } = await
|
|
215787
|
+
const { stdout: mergeBaseOut } = await execFileAsync17(
|
|
215354
215788
|
"git",
|
|
215355
215789
|
["merge-base", mergeTargetBranch, branch],
|
|
215356
215790
|
{ cwd: rootDir, encoding: "utf-8" }
|
|
@@ -215359,7 +215793,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215359
215793
|
if (mergeBase) {
|
|
215360
215794
|
let ownDiffEmpty = false;
|
|
215361
215795
|
try {
|
|
215362
|
-
await
|
|
215796
|
+
await execFileAsync17(
|
|
215363
215797
|
"git",
|
|
215364
215798
|
["diff", "--quiet", `${mergeBase}..${branch}`],
|
|
215365
215799
|
{ cwd: rootDir }
|
|
@@ -215372,7 +215806,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215372
215806
|
let mergeBaseReachable = baseReachableFromTarget;
|
|
215373
215807
|
if (!mergeBaseReachable) {
|
|
215374
215808
|
try {
|
|
215375
|
-
await
|
|
215809
|
+
await execFileAsync17(
|
|
215376
215810
|
"git",
|
|
215377
215811
|
["merge-base", "--is-ancestor", mergeBase, mergeTargetBranch],
|
|
215378
215812
|
{ cwd: rootDir }
|
|
@@ -215392,7 +215826,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215392
215826
|
}
|
|
215393
215827
|
let branchExists = false;
|
|
215394
215828
|
try {
|
|
215395
|
-
await
|
|
215829
|
+
await execFileAsync17("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], { cwd: rootDir });
|
|
215396
215830
|
branchExists = true;
|
|
215397
215831
|
} catch {
|
|
215398
215832
|
branchExists = false;
|
|
@@ -215410,7 +215844,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215410
215844
|
}
|
|
215411
215845
|
if (task.baseCommitSha && !baseReachableFromTarget) {
|
|
215412
215846
|
try {
|
|
215413
|
-
const { stdout } = await
|
|
215847
|
+
const { stdout } = await execFileAsync17("git", ["for-each-ref", "--format=%(refname:short)", "refs/heads/fusion"], {
|
|
215414
215848
|
cwd: rootDir,
|
|
215415
215849
|
encoding: "utf-8"
|
|
215416
215850
|
});
|
|
@@ -215418,7 +215852,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215418
215852
|
for (const ref of refs) {
|
|
215419
215853
|
if (ref === branch) continue;
|
|
215420
215854
|
try {
|
|
215421
|
-
await
|
|
215855
|
+
await execFileAsync17("git", ["merge-base", "--is-ancestor", task.baseCommitSha, ref], { cwd: rootDir });
|
|
215422
215856
|
return {
|
|
215423
215857
|
kind: "unproven",
|
|
215424
215858
|
reason: "foreign-start-point",
|
|
@@ -215432,7 +215866,7 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215432
215866
|
}
|
|
215433
215867
|
if (aheadCount !== null && aheadCount > 0) {
|
|
215434
215868
|
try {
|
|
215435
|
-
const { stdout } = await
|
|
215869
|
+
const { stdout } = await execFileAsync17("git", ["log", "--format=%s%x1f%b", `${mergeTargetBranch}..${branch}`], {
|
|
215436
215870
|
cwd: rootDir,
|
|
215437
215871
|
encoding: "utf-8"
|
|
215438
215872
|
});
|
|
@@ -215473,20 +215907,20 @@ async function classifyOwnedLandedEvidence(rootDir, task, opts) {
|
|
|
215473
215907
|
}
|
|
215474
215908
|
};
|
|
215475
215909
|
}
|
|
215476
|
-
var
|
|
215910
|
+
var execFileAsync17, FUSION_TASK_ID_TRAILER_KEY3;
|
|
215477
215911
|
var init_merger_owned_landed = __esm({
|
|
215478
215912
|
"../engine/src/merge/merger-owned-landed.ts"() {
|
|
215479
215913
|
"use strict";
|
|
215480
215914
|
init_merger_file_scope();
|
|
215481
215915
|
init_worktree_names();
|
|
215482
|
-
|
|
215916
|
+
execFileAsync17 = (file, args, opts) => promisify47(childProcess3.execFile)(file, args, opts);
|
|
215483
215917
|
FUSION_TASK_ID_TRAILER_KEY3 = "Fusion-Task-Id";
|
|
215484
215918
|
}
|
|
215485
215919
|
});
|
|
215486
215920
|
|
|
215487
215921
|
// ../engine/src/merge/merger-conflict-resolution.ts
|
|
215488
|
-
import { promisify as
|
|
215489
|
-
import { exec as exec33, execFile as
|
|
215922
|
+
import { promisify as promisify48 } from "node:util";
|
|
215923
|
+
import { exec as exec33, execFile as execFile24 } from "node:child_process";
|
|
215490
215924
|
async function getConflictedFiles(cwd) {
|
|
215491
215925
|
try {
|
|
215492
215926
|
const { stdout } = await execAsync30("git diff --name-only --diff-filter=U", {
|
|
@@ -215502,7 +215936,7 @@ async function getConflictedFiles(cwd) {
|
|
|
215502
215936
|
}
|
|
215503
215937
|
async function isTrivialWhitespaceConflict(filePath, cwd) {
|
|
215504
215938
|
try {
|
|
215505
|
-
const { stdout } = await
|
|
215939
|
+
const { stdout } = await execFileAsync18(
|
|
215506
215940
|
"git",
|
|
215507
215941
|
["diff", "-p", "-w", `:2:${filePath}`, `:3:${filePath}`],
|
|
215508
215942
|
{ cwd, encoding: "utf-8" }
|
|
@@ -215538,8 +215972,8 @@ async function classifyConflict(filePath, cwd) {
|
|
|
215538
215972
|
}
|
|
215539
215973
|
async function resolveWithOurs(filePath, cwd) {
|
|
215540
215974
|
try {
|
|
215541
|
-
await
|
|
215542
|
-
await
|
|
215975
|
+
await execFileAsync18("git", ["checkout", "--ours", "--", filePath], { cwd });
|
|
215976
|
+
await execFileAsync18("git", ["add", "--", filePath], { cwd });
|
|
215543
215977
|
mergerLog.debug(`Auto-resolved ${filePath} using --ours`);
|
|
215544
215978
|
} catch (error3) {
|
|
215545
215979
|
throw new Error(`Failed to auto-resolve ${filePath} with ours: ${error3}`);
|
|
@@ -215547,8 +215981,8 @@ async function resolveWithOurs(filePath, cwd) {
|
|
|
215547
215981
|
}
|
|
215548
215982
|
async function resolveWithTheirs(filePath, cwd) {
|
|
215549
215983
|
try {
|
|
215550
|
-
await
|
|
215551
|
-
await
|
|
215984
|
+
await execFileAsync18("git", ["checkout", "--theirs", "--", filePath], { cwd });
|
|
215985
|
+
await execFileAsync18("git", ["add", "--", filePath], { cwd });
|
|
215552
215986
|
mergerLog.debug(`Auto-resolved ${filePath} using --theirs`);
|
|
215553
215987
|
} catch (error3) {
|
|
215554
215988
|
throw new Error(`Failed to auto-resolve ${filePath} with theirs: ${error3}`);
|
|
@@ -215556,8 +215990,8 @@ async function resolveWithTheirs(filePath, cwd) {
|
|
|
215556
215990
|
}
|
|
215557
215991
|
async function resolveTrivialWhitespace(filePath, cwd) {
|
|
215558
215992
|
try {
|
|
215559
|
-
await
|
|
215560
|
-
await
|
|
215993
|
+
await execFileAsync18("git", ["checkout", "--ours", "--", filePath], { cwd });
|
|
215994
|
+
await execFileAsync18("git", ["add", "--", filePath], { cwd });
|
|
215561
215995
|
mergerLog.debug(`Auto-resolved ${filePath} (trivial whitespace)`);
|
|
215562
215996
|
} catch (error3) {
|
|
215563
215997
|
throw new Error(`Failed to auto-resolve ${filePath} trivial conflict: ${error3}`);
|
|
@@ -215603,14 +216037,14 @@ async function resolveConflicts(categories2, rootDir) {
|
|
|
215603
216037
|
}
|
|
215604
216038
|
return remainingComplex;
|
|
215605
216039
|
}
|
|
215606
|
-
var execAsync30,
|
|
216040
|
+
var execAsync30, execFileAsync18;
|
|
215607
216041
|
var init_merger_conflict_resolution = __esm({
|
|
215608
216042
|
"../engine/src/merge/merger-conflict-resolution.ts"() {
|
|
215609
216043
|
"use strict";
|
|
215610
216044
|
init_merger_glob();
|
|
215611
216045
|
init_logger3();
|
|
215612
|
-
execAsync30 =
|
|
215613
|
-
|
|
216046
|
+
execAsync30 = promisify48(exec33);
|
|
216047
|
+
execFileAsync18 = (file, args, opts) => promisify48(execFile24)(file, args, opts);
|
|
215614
216048
|
}
|
|
215615
216049
|
});
|
|
215616
216050
|
|
|
@@ -215734,8 +216168,8 @@ var init_merger_autostash_labels = __esm({
|
|
|
215734
216168
|
});
|
|
215735
216169
|
|
|
215736
216170
|
// ../engine/src/merge/merger-squash-audit.ts
|
|
215737
|
-
import { execFile as
|
|
215738
|
-
import { promisify as
|
|
216171
|
+
import { execFile as execFile25 } from "node:child_process";
|
|
216172
|
+
import { promisify as promisify49 } from "node:util";
|
|
215739
216173
|
async function auditSquashMerge(input) {
|
|
215740
216174
|
const normalizedLookback = normalizeMergeOverlapLookback(input.lookback);
|
|
215741
216175
|
if (input.strategy === "rebase") {
|
|
@@ -215853,7 +216287,7 @@ async function collectTouchedFileOverlaps(rootDir, touchedFiles, recentMainCommi
|
|
|
215853
216287
|
return touchedFileOverlaps;
|
|
215854
216288
|
}
|
|
215855
216289
|
async function git5(rootDir, args) {
|
|
215856
|
-
const { stdout } = await
|
|
216290
|
+
const { stdout } = await execFileAsync19("git", args, {
|
|
215857
216291
|
cwd: rootDir,
|
|
215858
216292
|
encoding: "utf-8",
|
|
215859
216293
|
maxBuffer: GIT_OUTPUT_MAX_BUFFER
|
|
@@ -215886,19 +216320,19 @@ function normalizeMergeOverlapLookback(value) {
|
|
|
215886
216320
|
}
|
|
215887
216321
|
return Math.trunc(value);
|
|
215888
216322
|
}
|
|
215889
|
-
var
|
|
216323
|
+
var execFileAsync19, MERGER_MAIN_OVERLAP_LOOKBACK_COMMITS, GIT_OUTPUT_MAX_BUFFER;
|
|
215890
216324
|
var init_merger_squash_audit = __esm({
|
|
215891
216325
|
"../engine/src/merge/merger-squash-audit.ts"() {
|
|
215892
216326
|
"use strict";
|
|
215893
|
-
|
|
216327
|
+
execFileAsync19 = promisify49(execFile25);
|
|
215894
216328
|
MERGER_MAIN_OVERLAP_LOOKBACK_COMMITS = 30;
|
|
215895
216329
|
GIT_OUTPUT_MAX_BUFFER = 10 * 1024 * 1024;
|
|
215896
216330
|
}
|
|
215897
216331
|
});
|
|
215898
216332
|
|
|
215899
216333
|
// ../engine/src/merge/merger-overlap-guard.ts
|
|
215900
|
-
import { execFile as
|
|
215901
|
-
import { promisify as
|
|
216334
|
+
import { execFile as execFile26 } from "node:child_process";
|
|
216335
|
+
import { promisify as promisify50 } from "node:util";
|
|
215902
216336
|
async function getBranchTouchedFiles({
|
|
215903
216337
|
rootDir,
|
|
215904
216338
|
branch,
|
|
@@ -215974,7 +216408,7 @@ async function restoreBranchWinsFiles({
|
|
|
215974
216408
|
}
|
|
215975
216409
|
async function gitLines(rootDir, args, context2) {
|
|
215976
216410
|
try {
|
|
215977
|
-
const { stdout } = await
|
|
216411
|
+
const { stdout } = await execFileAsync20("git", args, {
|
|
215978
216412
|
cwd: rootDir,
|
|
215979
216413
|
encoding: "utf-8",
|
|
215980
216414
|
maxBuffer: GIT_OUTPUT_MAX_BUFFER2
|
|
@@ -215992,7 +216426,7 @@ function normalizeLines3(value) {
|
|
|
215992
216426
|
}
|
|
215993
216427
|
async function gitRun(rootDir, args, context2) {
|
|
215994
216428
|
try {
|
|
215995
|
-
await
|
|
216429
|
+
await execFileAsync20("git", args, {
|
|
215996
216430
|
cwd: rootDir,
|
|
215997
216431
|
encoding: "utf-8",
|
|
215998
216432
|
maxBuffer: GIT_OUTPUT_MAX_BUFFER2
|
|
@@ -216004,7 +216438,7 @@ async function gitRun(rootDir, args, context2) {
|
|
|
216004
216438
|
}
|
|
216005
216439
|
async function gitExitCode2(rootDir, args) {
|
|
216006
216440
|
try {
|
|
216007
|
-
await
|
|
216441
|
+
await execFileAsync20("git", args, {
|
|
216008
216442
|
cwd: rootDir,
|
|
216009
216443
|
encoding: "utf-8",
|
|
216010
216444
|
maxBuffer: GIT_OUTPUT_MAX_BUFFER2
|
|
@@ -216017,20 +216451,20 @@ async function gitExitCode2(rootDir, args) {
|
|
|
216017
216451
|
function formatErrorMessage(error3) {
|
|
216018
216452
|
return error3 instanceof Error ? error3.message : String(error3);
|
|
216019
216453
|
}
|
|
216020
|
-
var
|
|
216454
|
+
var execFileAsync20, GIT_OUTPUT_MAX_BUFFER2;
|
|
216021
216455
|
var init_merger_overlap_guard = __esm({
|
|
216022
216456
|
"../engine/src/merge/merger-overlap-guard.ts"() {
|
|
216023
216457
|
"use strict";
|
|
216024
216458
|
init_logger3();
|
|
216025
216459
|
init_merger_squash_audit();
|
|
216026
|
-
|
|
216460
|
+
execFileAsync20 = promisify50(execFile26);
|
|
216027
216461
|
GIT_OUTPUT_MAX_BUFFER2 = 10 * 1024 * 1024;
|
|
216028
216462
|
}
|
|
216029
216463
|
});
|
|
216030
216464
|
|
|
216031
216465
|
// ../engine/src/merge/merger-auto-prerebase.ts
|
|
216032
216466
|
import { exec as exec34 } from "node:child_process";
|
|
216033
|
-
import { promisify as
|
|
216467
|
+
import { promisify as promisify51 } from "node:util";
|
|
216034
216468
|
async function probeDivergence(opts) {
|
|
216035
216469
|
const mainRef = opts.mainRef ?? "HEAD";
|
|
216036
216470
|
const range = `${opts.baseCommitSha}..${mainRef}`;
|
|
@@ -216117,13 +216551,13 @@ var execAsync31;
|
|
|
216117
216551
|
var init_merger_auto_prerebase = __esm({
|
|
216118
216552
|
"../engine/src/merge/merger-auto-prerebase.ts"() {
|
|
216119
216553
|
"use strict";
|
|
216120
|
-
execAsync31 =
|
|
216554
|
+
execAsync31 = promisify51(exec34);
|
|
216121
216555
|
}
|
|
216122
216556
|
});
|
|
216123
216557
|
|
|
216124
216558
|
// ../engine/src/execution/branch-autocorrect.ts
|
|
216125
216559
|
import { exec as exec35 } from "node:child_process";
|
|
216126
|
-
import { promisify as
|
|
216560
|
+
import { promisify as promisify52 } from "node:util";
|
|
216127
216561
|
function quoteShellArg7(value) {
|
|
216128
216562
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
216129
216563
|
}
|
|
@@ -216192,7 +216626,7 @@ var execAsync32, GIT_TIMEOUT_MS7, GIT_MAX_BUFFER4;
|
|
|
216192
216626
|
var init_branch_autocorrect = __esm({
|
|
216193
216627
|
"../engine/src/execution/branch-autocorrect.ts"() {
|
|
216194
216628
|
"use strict";
|
|
216195
|
-
execAsync32 =
|
|
216629
|
+
execAsync32 = promisify52(exec35);
|
|
216196
216630
|
GIT_TIMEOUT_MS7 = 1e4;
|
|
216197
216631
|
GIT_MAX_BUFFER4 = 1024 * 1024;
|
|
216198
216632
|
}
|
|
@@ -216656,9 +217090,9 @@ var init_mesh_lease_manager = __esm({
|
|
|
216656
217090
|
});
|
|
216657
217091
|
|
|
216658
217092
|
// ../engine/src/merge/merger-integration-worktree.ts
|
|
216659
|
-
import { createHash as
|
|
216660
|
-
import { exec as exec36, execFile as
|
|
216661
|
-
import { promisify as
|
|
217093
|
+
import { createHash as createHash33 } from "node:crypto";
|
|
217094
|
+
import { exec as exec36, execFile as execFile27 } from "node:child_process";
|
|
217095
|
+
import { promisify as promisify53 } from "node:util";
|
|
216662
217096
|
function quoteAutostashArg(value) {
|
|
216663
217097
|
return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
|
|
216664
217098
|
}
|
|
@@ -216735,15 +217169,15 @@ async function snapshotDirtyFilesLocal(rootDir) {
|
|
|
216735
217169
|
const paths3 = /* @__PURE__ */ new Set();
|
|
216736
217170
|
try {
|
|
216737
217171
|
const [unstagedOut, stagedOut, porcelainOut] = await Promise.all([
|
|
216738
|
-
|
|
217172
|
+
execFileAsync21("git", ["diff", "-z", "--name-only"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
216739
217173
|
(r) => r.stdout,
|
|
216740
217174
|
() => ""
|
|
216741
217175
|
),
|
|
216742
|
-
|
|
217176
|
+
execFileAsync21("git", ["diff", "-z", "--cached", "--name-only"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
216743
217177
|
(r) => r.stdout,
|
|
216744
217178
|
() => ""
|
|
216745
217179
|
),
|
|
216746
|
-
|
|
217180
|
+
execFileAsync21("git", ["status", "-z", "--porcelain"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
216747
217181
|
(r) => r.stdout,
|
|
216748
217182
|
() => ""
|
|
216749
217183
|
)
|
|
@@ -216768,18 +217202,18 @@ async function snapshotDirtyFilesLocal(rootDir) {
|
|
|
216768
217202
|
async function gitDirtyFingerprintLocal(rootDir) {
|
|
216769
217203
|
try {
|
|
216770
217204
|
const [diffOut, statusOut] = await Promise.all([
|
|
216771
|
-
|
|
217205
|
+
execFileAsync21("git", ["diff", "HEAD"], {
|
|
216772
217206
|
cwd: rootDir,
|
|
216773
217207
|
encoding: "utf-8",
|
|
216774
217208
|
maxBuffer: 64 * 1024 * 1024
|
|
216775
217209
|
}).then((r) => r.stdout, () => ""),
|
|
216776
|
-
|
|
217210
|
+
execFileAsync21("git", ["status", "-z", "--porcelain"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
216777
217211
|
(r) => r.stdout,
|
|
216778
217212
|
() => ""
|
|
216779
217213
|
)
|
|
216780
217214
|
]);
|
|
216781
217215
|
if (!diffOut && !statusOut) return "";
|
|
216782
|
-
return
|
|
217216
|
+
return createHash33("sha256").update(diffOut).update("\0").update(statusOut).digest("hex");
|
|
216783
217217
|
} catch {
|
|
216784
217218
|
return "";
|
|
216785
217219
|
}
|
|
@@ -216796,7 +217230,7 @@ async function probeIntegrationWorktreeState(input) {
|
|
|
216796
217230
|
const dirtyFingerprint = await gitDirtyFingerprintLocal(registeredPath);
|
|
216797
217231
|
let untrackedCount = 0;
|
|
216798
217232
|
try {
|
|
216799
|
-
const { stdout } = await
|
|
217233
|
+
const { stdout } = await execFileAsync21("git", ["status", "-z", "--porcelain"], {
|
|
216800
217234
|
cwd: registeredPath,
|
|
216801
217235
|
encoding: "utf-8"
|
|
216802
217236
|
});
|
|
@@ -217157,7 +217591,7 @@ async function releaseReuseHandoff(input) {
|
|
|
217157
217591
|
}
|
|
217158
217592
|
});
|
|
217159
217593
|
}
|
|
217160
|
-
var execAsync33,
|
|
217594
|
+
var execAsync33, execFileAsync21, MERGE_HANDOFF_WORKER_ID, MergeHandoffRefusedError;
|
|
217161
217595
|
var init_merger_integration_worktree = __esm({
|
|
217162
217596
|
"../engine/src/merge/merger-integration-worktree.ts"() {
|
|
217163
217597
|
"use strict";
|
|
@@ -217168,8 +217602,8 @@ var init_merger_integration_worktree = __esm({
|
|
|
217168
217602
|
init_mesh_lease_manager();
|
|
217169
217603
|
init_worktree_pool();
|
|
217170
217604
|
init_worktree_names();
|
|
217171
|
-
execAsync33 =
|
|
217172
|
-
|
|
217605
|
+
execAsync33 = promisify53(exec36);
|
|
217606
|
+
execFileAsync21 = promisify53(execFile27);
|
|
217173
217607
|
MERGE_HANDOFF_WORKER_ID = "merger-reuse-handoff";
|
|
217174
217608
|
MergeHandoffRefusedError = class extends Error {
|
|
217175
217609
|
reason;
|
|
@@ -217198,13 +217632,13 @@ var init_push_after_merge_policy = __esm({
|
|
|
217198
217632
|
});
|
|
217199
217633
|
|
|
217200
217634
|
// ../engine/src/worktree/worktree-ref-sync.ts
|
|
217201
|
-
import { execFile as
|
|
217202
|
-
import { promisify as
|
|
217635
|
+
import { execFile as execFile28, spawn as spawn7 } from "node:child_process";
|
|
217636
|
+
import { promisify as promisify54 } from "node:util";
|
|
217203
217637
|
import { copyFileSync, existsSync as existsSync64, mkdirSync as mkdirSync8, mkdtempSync as mkdtempSync2, readFileSync as readFileSync22, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
|
|
217204
217638
|
import { dirname as dirname39, join as join80 } from "node:path";
|
|
217205
217639
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
217206
217640
|
async function runGit5(args, cwd, timeoutMs) {
|
|
217207
|
-
const result2 = await
|
|
217641
|
+
const result2 = await execFileAsync22("git", ["-c", "core.quotePath=false", ...args], {
|
|
217208
217642
|
cwd,
|
|
217209
217643
|
timeout: timeoutMs,
|
|
217210
217644
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -217438,11 +217872,11 @@ async function syncWorktreeToHead(input) {
|
|
|
217438
217872
|
}
|
|
217439
217873
|
}
|
|
217440
217874
|
}
|
|
217441
|
-
var
|
|
217875
|
+
var execFileAsync22;
|
|
217442
217876
|
var init_worktree_ref_sync = __esm({
|
|
217443
217877
|
"../engine/src/worktree/worktree-ref-sync.ts"() {
|
|
217444
217878
|
"use strict";
|
|
217445
|
-
|
|
217879
|
+
execFileAsync22 = promisify54(execFile28);
|
|
217446
217880
|
}
|
|
217447
217881
|
});
|
|
217448
217882
|
|
|
@@ -217450,7 +217884,7 @@ var init_worktree_ref_sync = __esm({
|
|
|
217450
217884
|
import { exec as exec37 } from "node:child_process";
|
|
217451
217885
|
import { readFile as readFile44, writeFile as writeFile26 } from "node:fs/promises";
|
|
217452
217886
|
import { join as join81 } from "node:path";
|
|
217453
|
-
import { promisify as
|
|
217887
|
+
import { promisify as promisify55 } from "node:util";
|
|
217454
217888
|
function quoteArg4(value) {
|
|
217455
217889
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
217456
217890
|
}
|
|
@@ -217626,7 +218060,7 @@ var init_merger_scope_auto_widen = __esm({
|
|
|
217626
218060
|
"use strict";
|
|
217627
218061
|
init_src2();
|
|
217628
218062
|
init_merger();
|
|
217629
|
-
execAsync34 =
|
|
218063
|
+
execAsync34 = promisify55(exec37);
|
|
217630
218064
|
GIT_MAX_BUFFER5 = 10 * 1024 * 1024;
|
|
217631
218065
|
ScopeAutoWidenPersistError = class extends Error {
|
|
217632
218066
|
constructor(message) {
|
|
@@ -217760,9 +218194,9 @@ __export(merger_exports, {
|
|
|
217760
218194
|
});
|
|
217761
218195
|
import { execSync as execSync6, exec as exec38 } from "node:child_process";
|
|
217762
218196
|
import * as childProcess4 from "node:child_process";
|
|
217763
|
-
import { promisify as
|
|
218197
|
+
import { promisify as promisify56 } from "node:util";
|
|
217764
218198
|
import { existsSync as existsSync65, readFileSync as readFileSync23, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
217765
|
-
import { createHash as
|
|
218199
|
+
import { createHash as createHash34 } from "node:crypto";
|
|
217766
218200
|
import { join as join82, resolve as resolve48 } from "node:path";
|
|
217767
218201
|
import { hostname as hostname3 } from "node:os";
|
|
217768
218202
|
import { Type as Type4 } from "typebox";
|
|
@@ -217973,15 +218407,15 @@ async function snapshotDirtyFiles(rootDir) {
|
|
|
217973
218407
|
const paths3 = /* @__PURE__ */ new Set();
|
|
217974
218408
|
try {
|
|
217975
218409
|
const [unstagedOut, stagedOut, porcelainOut] = await Promise.all([
|
|
217976
|
-
|
|
218410
|
+
execFileAsync23("git", ["diff", "-z", "--name-only"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
217977
218411
|
(r) => r.stdout,
|
|
217978
218412
|
() => ""
|
|
217979
218413
|
),
|
|
217980
|
-
|
|
218414
|
+
execFileAsync23("git", ["diff", "-z", "--cached", "--name-only"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
217981
218415
|
(r) => r.stdout,
|
|
217982
218416
|
() => ""
|
|
217983
218417
|
),
|
|
217984
|
-
|
|
218418
|
+
execFileAsync23("git", ["status", "-z", "--porcelain"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
217985
218419
|
(r) => r.stdout,
|
|
217986
218420
|
() => ""
|
|
217987
218421
|
)
|
|
@@ -218006,18 +218440,18 @@ async function snapshotDirtyFiles(rootDir) {
|
|
|
218006
218440
|
async function gitDirtyFingerprint(rootDir) {
|
|
218007
218441
|
try {
|
|
218008
218442
|
const [diffOut, statusOut] = await Promise.all([
|
|
218009
|
-
|
|
218443
|
+
execFileAsync23("git", ["diff", "HEAD"], {
|
|
218010
218444
|
cwd: rootDir,
|
|
218011
218445
|
encoding: "utf-8",
|
|
218012
218446
|
maxBuffer: 64 * 1024 * 1024
|
|
218013
218447
|
}).then((r) => r.stdout, () => ""),
|
|
218014
|
-
|
|
218448
|
+
execFileAsync23("git", ["status", "-z", "--porcelain"], { cwd: rootDir, encoding: "utf-8" }).then(
|
|
218015
218449
|
(r) => r.stdout,
|
|
218016
218450
|
() => ""
|
|
218017
218451
|
)
|
|
218018
218452
|
]);
|
|
218019
218453
|
if (!diffOut && !statusOut) return "";
|
|
218020
|
-
return
|
|
218454
|
+
return createHash34("sha256").update(diffOut).update("\0").update(statusOut).digest("hex");
|
|
218021
218455
|
} catch {
|
|
218022
218456
|
return "";
|
|
218023
218457
|
}
|
|
@@ -219979,7 +220413,7 @@ function splitNulDelimited(output2) {
|
|
|
219979
220413
|
return text3.split(NUL).filter((entry) => entry.length > 0);
|
|
219980
220414
|
}
|
|
219981
220415
|
async function countStagedPaths(rootDir) {
|
|
219982
|
-
const { stdout } = await
|
|
220416
|
+
const { stdout } = await execFileAsync23("git", ["diff", "--cached", "--name-only", "-z"], {
|
|
219983
220417
|
cwd: rootDir,
|
|
219984
220418
|
encoding: "buffer",
|
|
219985
220419
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -219988,7 +220422,7 @@ async function countStagedPaths(rootDir) {
|
|
|
219988
220422
|
}
|
|
219989
220423
|
async function filterStagedGitignoredPaths(rootDir, taskId) {
|
|
219990
220424
|
try {
|
|
219991
|
-
const { stdout: stagedOut } = await
|
|
220425
|
+
const { stdout: stagedOut } = await execFileAsync23("git", ["diff", "--cached", "--name-only", "-z"], {
|
|
219992
220426
|
cwd: rootDir,
|
|
219993
220427
|
encoding: "buffer",
|
|
219994
220428
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -220002,7 +220436,7 @@ async function filterStagedGitignoredPaths(rootDir, taskId) {
|
|
|
220002
220436
|
for (let i = 0; i < stagedPaths.length; i += batchSize) {
|
|
220003
220437
|
const batch = stagedPaths.slice(i, i + batchSize);
|
|
220004
220438
|
try {
|
|
220005
|
-
const { stdout } = await
|
|
220439
|
+
const { stdout } = await execFileAsync23("git", ["check-ignore", "--no-index", "--", ...batch], {
|
|
220006
220440
|
cwd: rootDir,
|
|
220007
220441
|
encoding: "utf-8",
|
|
220008
220442
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -220025,7 +220459,7 @@ async function filterStagedGitignoredPaths(rootDir, taskId) {
|
|
|
220025
220459
|
`${taskId}: refusing to stage gitignored path "${path13}" \u2014 unstaging (agents must not bypass .gitignore via \`git add -f\`)`
|
|
220026
220460
|
);
|
|
220027
220461
|
try {
|
|
220028
|
-
await
|
|
220462
|
+
await execFileAsync23("git", ["reset", "HEAD", "--", path13], {
|
|
220029
220463
|
cwd: rootDir,
|
|
220030
220464
|
encoding: "utf-8",
|
|
220031
220465
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -220057,7 +220491,7 @@ async function commitOrAmendMergeWithFixes(rootDir, taskId, branch, commitLog, i
|
|
|
220057
220491
|
encoding: "utf-8"
|
|
220058
220492
|
});
|
|
220059
220493
|
const unstaged = new Set(unstagedOut.split("\n").map((l) => l.trim()).filter(Boolean));
|
|
220060
|
-
const { stdout: porcelainOut } = await
|
|
220494
|
+
const { stdout: porcelainOut } = await execFileAsync23("git", ["status", "-z", "--porcelain"], {
|
|
220061
220495
|
cwd: rootDir,
|
|
220062
220496
|
encoding: "utf-8"
|
|
220063
220497
|
});
|
|
@@ -220078,7 +220512,7 @@ async function commitOrAmendMergeWithFixes(rootDir, taskId, branch, commitLog, i
|
|
|
220078
220512
|
}
|
|
220079
220513
|
}
|
|
220080
220514
|
if (unstagedToStage.length > 0) {
|
|
220081
|
-
await
|
|
220515
|
+
await execFileAsync23("git", ["add", "--", ...unstagedToStage], { cwd: rootDir });
|
|
220082
220516
|
}
|
|
220083
220517
|
const untrackedToStage = [];
|
|
220084
220518
|
for (const p2 of untracked) {
|
|
@@ -220091,7 +220525,7 @@ async function commitOrAmendMergeWithFixes(rootDir, taskId, branch, commitLog, i
|
|
|
220091
220525
|
}
|
|
220092
220526
|
}
|
|
220093
220527
|
if (untrackedToStage.length > 0) {
|
|
220094
|
-
await
|
|
220528
|
+
await execFileAsync23("git", ["add", "--", ...untrackedToStage], { cwd: rootDir });
|
|
220095
220529
|
}
|
|
220096
220530
|
const cap = (arr, n = 20) => arr.length <= n ? arr.join(", ") : `${arr.slice(0, n).join(", ")} ... (+${arr.length - n} more)`;
|
|
220097
220531
|
mergerLog.debug(
|
|
@@ -221562,7 +221996,7 @@ function isNonFastForwardPushError(message) {
|
|
|
221562
221996
|
}
|
|
221563
221997
|
async function probeRebaseInProgress(rootDir) {
|
|
221564
221998
|
const gitPath = async (name2) => {
|
|
221565
|
-
const { stdout } = await
|
|
221999
|
+
const { stdout } = await execFileAsync23("git", ["rev-parse", "--git-path", name2], {
|
|
221566
222000
|
cwd: rootDir,
|
|
221567
222001
|
encoding: "utf-8",
|
|
221568
222002
|
timeout: PUSH_TIMEOUT_MS
|
|
@@ -225747,7 +226181,7 @@ async function completeTask(store, taskId, result2) {
|
|
|
225747
226181
|
}
|
|
225748
226182
|
store.emit("task:merged", result2);
|
|
225749
226183
|
}
|
|
225750
|
-
var execAsync35,
|
|
226184
|
+
var execAsync35, execFileAsync23, LEGACY_COMPLETE_LANES2, DEPENDENCY_SYNC_TRIGGER_PATTERNS, PULL_REBASE_TIMEOUT_MS, PUSH_TIMEOUT_MS, PUSH_NON_FF_MAX_RETRIES, PUSH_NON_FF_RETRY_BACKOFF_MS, PUSH_TRANSIENT_RETRY_BACKOFF_MS, TRANSIENT_GIT_PUSH_PATTERNS, MERGE_COMMIT_LOG_MAX_CHARS, MERGE_DIFF_STAT_MAX_CHARS, MERGE_USER_COMMENTS_MAX_CHARS, summarizeVerificationOutputLocal, VERIFICATION_EXTRA_ENV, ACTIVE_MERGER_STATUS_FILENAME, __test__, AutostashCreationFailedError, NUL, SquashAuditError;
|
|
225751
226185
|
var init_merger = __esm({
|
|
225752
226186
|
"../engine/src/merger.ts"() {
|
|
225753
226187
|
"use strict";
|
|
@@ -225819,8 +226253,8 @@ var init_merger = __esm({
|
|
|
225819
226253
|
init_merger_scope_auto_widen();
|
|
225820
226254
|
init_lifecycle_move();
|
|
225821
226255
|
init_merger_ref_update_advance();
|
|
225822
|
-
execAsync35 =
|
|
225823
|
-
|
|
226256
|
+
execAsync35 = promisify56(exec38);
|
|
226257
|
+
execFileAsync23 = (file, args, opts) => promisify56(childProcess4.execFile)(file, args, opts);
|
|
225824
226258
|
LEGACY_COMPLETE_LANES2 = ["done"];
|
|
225825
226259
|
DEPENDENCY_SYNC_TRIGGER_PATTERNS = [
|
|
225826
226260
|
"package.json",
|
|
@@ -225924,9 +226358,6 @@ function isDependencySatisfiedWithoutWorkflowMetadata(column) {
|
|
|
225924
226358
|
function isLegacyCompleteColumnForWorkspaceTeardown(column) {
|
|
225925
226359
|
return column === "done";
|
|
225926
226360
|
}
|
|
225927
|
-
function resolveRepoLocalAiMergeRoot(rootDir, settings) {
|
|
225928
|
-
return resolveAiMergeRootPath(rootDir, settings);
|
|
225929
|
-
}
|
|
225930
226361
|
async function classifyOwnedLandedEvidenceForSelfHealing(rootDir, task, mergeTargetBranch) {
|
|
225931
226362
|
const { classifyOwnedLandedEvidence: classifyOwnedLandedEvidence2 } = await Promise.resolve().then(() => (init_merger(), merger_exports));
|
|
225932
226363
|
return classifyOwnedLandedEvidence2(rootDir, task, { mergeTargetBranch });
|
|
@@ -226013,6 +226444,8 @@ var init_self_healing = __esm({
|
|
|
226013
226444
|
init_branch_conflicts();
|
|
226014
226445
|
init_run_audit();
|
|
226015
226446
|
init_auto_merge_finalization();
|
|
226447
|
+
init_merge_content_capture();
|
|
226448
|
+
init_stale_content_review_reroute();
|
|
226016
226449
|
init_post_landing_worktree_cleanup();
|
|
226017
226450
|
init_auto_recovery();
|
|
226018
226451
|
init_active_session_registry();
|
|
@@ -226181,6 +226614,7 @@ var init_self_healing = __esm({
|
|
|
226181
226614
|
symbolLockNoActionAudited = false;
|
|
226182
226615
|
maintenanceTickCounter = 0;
|
|
226183
226616
|
taskLifecycleRetentionLastPrunedAt = /* @__PURE__ */ new Map();
|
|
226617
|
+
staleContentRerouteAuditKeys = /* @__PURE__ */ new Set();
|
|
226184
226618
|
githubCheckStateRetentionLastPrunedAt = /* @__PURE__ */ new Map();
|
|
226185
226619
|
processBootStartedAt = Date.now();
|
|
226186
226620
|
lastDbCorruptionNotifiedAt = null;
|
|
@@ -226896,6 +227330,7 @@ var init_self_healing = __esm({
|
|
|
226896
227330
|
// flight" to all of them (the merge gate included), which is the two-hour
|
|
226897
227331
|
// stall-deadlock ride this sweep exists to prevent.
|
|
226898
227332
|
{ name: "reconcile-orphaned-pending-step-results", fn: () => this.reconcileOrphanedPendingStepResults().then(() => void 0) },
|
|
227333
|
+
{ name: "reconcile-unproven-review-approvals", fn: () => this.reconcileUnprovenReviewApprovals().then(() => void 0) },
|
|
226899
227334
|
/*
|
|
226900
227335
|
FNXC:WorkspaceContention 2026-08-23-08:00:
|
|
226901
227336
|
`contention-hold` is owned by an in-memory retry timer. After a process restart that
|
|
@@ -227776,6 +228211,7 @@ var init_self_healing = __esm({
|
|
|
227776
228211
|
Keep them adjacent and in this order.
|
|
227777
228212
|
*/
|
|
227778
228213
|
{ name: "reconcile-orphaned-pending-step-results", fn: () => this.reconcileOrphanedPendingStepResults() },
|
|
228214
|
+
{ name: "reconcile-unproven-review-approvals", fn: () => this.reconcileUnprovenReviewApprovals() },
|
|
227779
228215
|
{ name: "recover-failed-pre-merge-steps", fn: () => this.recoverReviewTasksWithFailedPreMergeSteps() },
|
|
227780
228216
|
{ name: "recover-missing-worktree-review-failures", fn: () => this.recoverMissingWorktreeReviewFailures() },
|
|
227781
228217
|
{ name: "recover-interrupted-merging", fn: () => this.recoverInterruptedMergingTasks() },
|
|
@@ -232222,6 +232658,95 @@ var init_self_healing = __esm({
|
|
|
232222
232658
|
return 0;
|
|
232223
232659
|
}
|
|
232224
232660
|
}
|
|
232661
|
+
/*
|
|
232662
|
+
FNXC:ReviewInputProof 2026-09-01-11:28:
|
|
232663
|
+
Prevention cannot release cards that already persisted a proofless `passed` content review. Repair
|
|
232664
|
+
only the invalid result in place, including when auto-merge is off, so automatic recovery can re-run
|
|
232665
|
+
eligible gates and a human-held card gains the failed result its audited bypass needs. The
|
|
232666
|
+
`needsOperatorBypass` label is therefore truthful rather than aspirational; no lifecycle state moves.
|
|
232667
|
+
|
|
232668
|
+
FNXC:ReviewInputProof 2026-09-01-11:57:
|
|
232669
|
+
Reconciliation must recompute from the lock-held task inside `updateTaskAtomic`; a graph writer can
|
|
232670
|
+
publish a proof-bound approval or another gate after the preliminary read, and a stale array write
|
|
232671
|
+
would discard that valid result. Re-check lane, user pause, workspace ownership, and session liveness
|
|
232672
|
+
in the callback, then log and audit only a repair whose atomic mutation actually applied.
|
|
232673
|
+
*/
|
|
232674
|
+
async reconcileUnprovenReviewApprovals() {
|
|
232675
|
+
try {
|
|
232676
|
+
const reviewColumns = await resolveProjectColumnsForRoles(this.store, REVIEW_ROLES);
|
|
232677
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
232678
|
+
for (const column of reviewColumns) {
|
|
232679
|
+
for (const task of await this.store.listTasks({ column, slim: true })) candidates.set(task.id, task);
|
|
232680
|
+
}
|
|
232681
|
+
const settings = await this.store.getSettings().catch(() => void 0);
|
|
232682
|
+
let repairedTasks = 0;
|
|
232683
|
+
const isSessionLive = (taskId) => {
|
|
232684
|
+
const livePaths = activeSessionRegistry.pathsForTask(taskId);
|
|
232685
|
+
return livePaths.some((path13) => activeSessionRegistry.isPathActive(path13)) || executingTaskLock.has(taskId) || this.options.isTaskActive?.(taskId) === true;
|
|
232686
|
+
};
|
|
232687
|
+
for (const candidate of candidates.values()) {
|
|
232688
|
+
if (candidate.userPaused === true || candidate.workspaceWorktrees !== void 0 || isSessionLive(candidate.id)) continue;
|
|
232689
|
+
if (!candidate.workflowStepResults?.some((result2) => resolveUnprovenReviewApproval(result2, { workspace: false }))) continue;
|
|
232690
|
+
const fresh = await this.store.getTask(candidate.id);
|
|
232691
|
+
if (!fresh || !reviewColumns.has(fresh.column) || fresh.userPaused === true || fresh.workspaceWorktrees !== void 0 || isSessionLive(fresh.id)) continue;
|
|
232692
|
+
let repair;
|
|
232693
|
+
try {
|
|
232694
|
+
await this.store.updateTaskAtomic(fresh.id, (live) => {
|
|
232695
|
+
repair = void 0;
|
|
232696
|
+
if (!reviewColumns.has(live.column) || live.userPaused === true || live.workspaceWorktrees !== void 0 || isSessionLive(live.id)) return null;
|
|
232697
|
+
const repairedStepIds = [];
|
|
232698
|
+
let repairReason;
|
|
232699
|
+
const results = (live.workflowStepResults ?? []).map((result2) => {
|
|
232700
|
+
const resolution = resolveUnprovenReviewApproval(result2, { workspace: false });
|
|
232701
|
+
if (!resolution) return result2;
|
|
232702
|
+
repairedStepIds.push(result2.workflowStepId);
|
|
232703
|
+
repairReason ??= resolution.reason;
|
|
232704
|
+
return resolution.downgraded;
|
|
232705
|
+
});
|
|
232706
|
+
if (repairedStepIds.length === 0 || !repairReason) return null;
|
|
232707
|
+
repair = {
|
|
232708
|
+
stepIds: repairedStepIds,
|
|
232709
|
+
reason: repairReason,
|
|
232710
|
+
column: live.column,
|
|
232711
|
+
resultCount: results.length,
|
|
232712
|
+
needsOperatorBypass: settings ? !allowsAutoMergeProcessing(live, settings) : void 0
|
|
232713
|
+
};
|
|
232714
|
+
return { workflowStepResults: results };
|
|
232715
|
+
});
|
|
232716
|
+
if (!repair) continue;
|
|
232717
|
+
repairedTasks += 1;
|
|
232718
|
+
} catch (error3) {
|
|
232719
|
+
log34.warn(`reconcileUnprovenReviewApprovals: failed for ${fresh.id}: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
232720
|
+
continue;
|
|
232721
|
+
}
|
|
232722
|
+
await this.store.logEntry(
|
|
232723
|
+
fresh.id,
|
|
232724
|
+
`[pre-merge] Invalid proofless approval repaired for ${repair.stepIds.join(", ")}: ${repair.reason}`
|
|
232725
|
+
).catch(() => void 0);
|
|
232726
|
+
await emitBoundedRunAudit2(this.store, {
|
|
232727
|
+
taskId: fresh.id,
|
|
232728
|
+
agentId: "self-healing",
|
|
232729
|
+
runId: generateSyntheticRunId("reconcile-unproven-review-approval", fresh.id),
|
|
232730
|
+
domain: "database",
|
|
232731
|
+
mutationType: "task:reconcile-unproven-review-approval",
|
|
232732
|
+
target: fresh.id,
|
|
232733
|
+
metadata: {
|
|
232734
|
+
taskId: fresh.id,
|
|
232735
|
+
column: repair.column,
|
|
232736
|
+
workflowStepId: repair.stepIds[0],
|
|
232737
|
+
repairedCount: repair.stepIds.length,
|
|
232738
|
+
resultCount: repair.resultCount,
|
|
232739
|
+
needsOperatorBypass: repair.needsOperatorBypass
|
|
232740
|
+
}
|
|
232741
|
+
}, { log: log34 });
|
|
232742
|
+
}
|
|
232743
|
+
if (repairedTasks > 0) log34.log(`Repaired unproven review approvals on ${repairedTasks} task(s)`);
|
|
232744
|
+
return repairedTasks;
|
|
232745
|
+
} catch (error3) {
|
|
232746
|
+
log34.error(`reconcileUnprovenReviewApprovals failed: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
232747
|
+
return 0;
|
|
232748
|
+
}
|
|
232749
|
+
}
|
|
232225
232750
|
/**
|
|
232226
232751
|
* Backward lifecycle move gated on triple proof (FN-5335).
|
|
232227
232752
|
* When the unproven fallback predicate fails, emits `task:finalize-no-op-review-no-action` and skips lifecycle mutation.
|
|
@@ -232575,6 +233100,66 @@ var init_self_healing = __esm({
|
|
|
232575
233100
|
}
|
|
232576
233101
|
return allowsAutoMergeProcessing(task, settings) && resolveEffectiveAutoMerge(task, settings) !== false;
|
|
232577
233102
|
}
|
|
233103
|
+
/*
|
|
233104
|
+
FNXC:PreMergeApproval 2026-09-01-14:05:
|
|
233105
|
+
Self-healing must not treat a stale content-bound approval as mergeable just because the cheap
|
|
233106
|
+
blocker check lacks a fresh Git descriptor. Capture the same merge content the merge queue uses and
|
|
233107
|
+
seed the graph back at Code Review, so cards like FN-9234 stop looping through doomed merge retries.
|
|
233108
|
+
*/
|
|
233109
|
+
async routeStaleSingularApprovalBackToReview(task, reviewColumns, settings) {
|
|
233110
|
+
let mergeGate;
|
|
233111
|
+
try {
|
|
233112
|
+
mergeGate = await resolvePreMergeGateForTask(this.store, task.id, task.enabledWorkflowSteps, task);
|
|
233113
|
+
} catch {
|
|
233114
|
+
return false;
|
|
233115
|
+
}
|
|
233116
|
+
if (mergeGate.provenance === "default" && !mergeGate.selectionAbsent) return false;
|
|
233117
|
+
const mergeContent = await captureMergeContentDescriptor(task, {
|
|
233118
|
+
workspaceRootDir: this.options.rootDir,
|
|
233119
|
+
settings
|
|
233120
|
+
});
|
|
233121
|
+
const blocker = getTaskMergeBlocker(task, {
|
|
233122
|
+
reviewColumns,
|
|
233123
|
+
requiredPreMergeStepIds: mergeGate.requiredPreMergeStepIds,
|
|
233124
|
+
mergeContent
|
|
233125
|
+
});
|
|
233126
|
+
if (blocker !== "task has a pre-merge approval recorded against different content" || mergeContent.kind !== "singular") {
|
|
233127
|
+
return false;
|
|
233128
|
+
}
|
|
233129
|
+
const reroute = await rerouteSingularStaleContentToReview(this.store, task, {
|
|
233130
|
+
requiredPreMergeStepIds: mergeGate.requiredPreMergeStepIds,
|
|
233131
|
+
mergeContent
|
|
233132
|
+
}).catch(() => ({
|
|
233133
|
+
rerouted: false,
|
|
233134
|
+
reason: "no-progress",
|
|
233135
|
+
nodeId: void 0,
|
|
233136
|
+
workflowStepId: void 0
|
|
233137
|
+
}));
|
|
233138
|
+
if (reroute.rerouted) {
|
|
233139
|
+
await this.store.logEntry(task.id, "[pre-merge] Self-healing re-seeded Code Review after stale content evidence blocked merge.");
|
|
233140
|
+
log34.warn(`Stale content approval for ${task.id} re-seeded at ${reroute.nodeId ?? "code-review"}`);
|
|
233141
|
+
}
|
|
233142
|
+
const auditKey = `${task.id}:${reroute.reason}:${reroute.nodeId ?? ""}`;
|
|
233143
|
+
if (!this.staleContentRerouteAuditKeys.has(auditKey)) {
|
|
233144
|
+
this.staleContentRerouteAuditKeys.add(auditKey);
|
|
233145
|
+
await emitBoundedRunAudit2(this.store, {
|
|
233146
|
+
taskId: task.id,
|
|
233147
|
+
agentId: "self-healing",
|
|
233148
|
+
runId: generateSyntheticRunId("self-healing", task.id),
|
|
233149
|
+
domain: "database",
|
|
233150
|
+
mutationType: "task:merge-stale-content-review-rerouted",
|
|
233151
|
+
target: task.id,
|
|
233152
|
+
metadata: {
|
|
233153
|
+
taskId: task.id,
|
|
233154
|
+
nodeId: reroute.nodeId,
|
|
233155
|
+
workflowStepId: reroute.workflowStepId,
|
|
233156
|
+
reason: reroute.reason,
|
|
233157
|
+
source: "self-healing"
|
|
233158
|
+
}
|
|
233159
|
+
});
|
|
233160
|
+
}
|
|
233161
|
+
return true;
|
|
233162
|
+
}
|
|
232578
233163
|
/**
|
|
232579
233164
|
* Recover `in-review` tasks that are fully mergeable but never had
|
|
232580
233165
|
* `mergeTask()` invoked.
|
|
@@ -232628,6 +233213,7 @@ var init_self_healing = __esm({
|
|
|
232628
233213
|
for (const task of mergeable) {
|
|
232629
233214
|
const reviewColumns = await ownReviewLanesFor(task);
|
|
232630
233215
|
if (!reviewColumns.has(task.column)) continue;
|
|
233216
|
+
if (await this.routeStaleSingularApprovalBackToReview(task, reviewColumns, settings)) continue;
|
|
232631
233217
|
if (getTaskMergeBlocker(task, { reviewColumns }) !== void 0) continue;
|
|
232632
233218
|
laneQualifiedMergeable.push(task);
|
|
232633
233219
|
}
|
|
@@ -235194,8 +235780,7 @@ This review is not retried until its findings change. Re-run the review after ad
|
|
|
235194
235780
|
}
|
|
235195
235781
|
async listAiMergeWorktreeCandidates(taskId, settings) {
|
|
235196
235782
|
const roots = Array.from(/* @__PURE__ */ new Set([
|
|
235197
|
-
|
|
235198
|
-
resolveLegacyAiMergeRootPath(this.options.rootDir),
|
|
235783
|
+
...resolveAiMergeSearchRoots(this.options.rootDir, settings),
|
|
235199
235784
|
tmpdir8()
|
|
235200
235785
|
]));
|
|
235201
235786
|
const testWorkerRoot = process.env.FUSION_TEST_WORKER_ROOT;
|
|
@@ -237729,9 +238314,7 @@ This review is not retried until its findings change. Re-run the review after ad
|
|
|
237729
238314
|
log34.debug("[self-healing] temp-dir sweep: worktrunk enabled \u2014 AI merge clean-room worktrees use Fusion's dedicated clean-room root, proceeding with native sweep");
|
|
237730
238315
|
}
|
|
237731
238316
|
const roots = Array.from(/* @__PURE__ */ new Set([
|
|
237732
|
-
|
|
237733
|
-
resolveLegacyAiMergeRootPath(this.options.rootDir),
|
|
237734
|
-
...settings.worktreesDir ? [] : [join83(resolveLegacyWorktreesDirLayout(this.options.rootDir), ".ai-merge")],
|
|
238317
|
+
...resolveAiMergeSearchRoots(this.options.rootDir, settings),
|
|
237735
238318
|
tmpdir8()
|
|
237736
238319
|
]));
|
|
237737
238320
|
const auditor = createRunAuditor(this.store, {
|
|
@@ -238284,7 +238867,7 @@ import { exec as exec39 } from "node:child_process";
|
|
|
238284
238867
|
import { existsSync as existsSync67 } from "node:fs";
|
|
238285
238868
|
import { readFile as readFile46, writeFile as writeFile27, rm as rm11 } from "node:fs/promises";
|
|
238286
238869
|
import { join as join84 } from "node:path";
|
|
238287
|
-
import { promisify as
|
|
238870
|
+
import { promisify as promisify57 } from "node:util";
|
|
238288
238871
|
function getPlanningLifecycleLockTransportFailure(task) {
|
|
238289
238872
|
const candidate = task.customFields?.[PLANNING_LIFECYCLE_LOCK_TRANSPORT_FAILURE_KEY];
|
|
238290
238873
|
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return null;
|
|
@@ -241681,7 +242264,7 @@ ${lines.join("\n")}` }],
|
|
|
241681
242264
|
written,
|
|
241682
242265
|
{
|
|
241683
242266
|
cwd: this.rootDir,
|
|
241684
|
-
exec:
|
|
242267
|
+
exec: promisify57(exec39)
|
|
241685
242268
|
}
|
|
241686
242269
|
),
|
|
241687
242270
|
new Promise((resolve65) => setTimeout(() => resolve65(null), 15e3))
|
|
@@ -241935,7 +242518,7 @@ var init_workflow_gate_activity = __esm({
|
|
|
241935
242518
|
|
|
241936
242519
|
// ../engine/src/executor/browser-probe.ts
|
|
241937
242520
|
import { exec as exec40 } from "node:child_process";
|
|
241938
|
-
import { promisify as
|
|
242521
|
+
import { promisify as promisify58 } from "node:util";
|
|
241939
242522
|
function isAgentBrowserNotFoundError(error3) {
|
|
241940
242523
|
const err = error3;
|
|
241941
242524
|
const code = typeof err?.code === "string" || typeof err?.code === "number" ? String(err.code) : void 0;
|
|
@@ -241991,7 +242574,7 @@ var execAsync36, AGENT_BROWSER_NAVIGATION_SKILL_ID;
|
|
|
241991
242574
|
var init_browser_probe = __esm({
|
|
241992
242575
|
"../engine/src/executor/browser-probe.ts"() {
|
|
241993
242576
|
"use strict";
|
|
241994
|
-
execAsync36 =
|
|
242577
|
+
execAsync36 = promisify58(exec40);
|
|
241995
242578
|
AGENT_BROWSER_NAVIGATION_SKILL_ID = "agent-browser-navigation";
|
|
241996
242579
|
}
|
|
241997
242580
|
});
|
|
@@ -242510,7 +243093,7 @@ var init_workflow_failure_scope_guard = __esm({
|
|
|
242510
243093
|
// ../engine/src/executor/worktree-registry-helpers.ts
|
|
242511
243094
|
import { isAbsolute as isAbsolute21, relative as relative20, resolve as resolvePath3 } from "node:path";
|
|
242512
243095
|
import { exec as exec41 } from "node:child_process";
|
|
242513
|
-
import { promisify as
|
|
243096
|
+
import { promisify as promisify59 } from "node:util";
|
|
242514
243097
|
async function isRegisteredWorktree(rootDir, path13) {
|
|
242515
243098
|
return isRegisteredGitWorktree(rootDir, path13);
|
|
242516
243099
|
}
|
|
@@ -242554,7 +243137,7 @@ var init_worktree_registry_helpers = __esm({
|
|
|
242554
243137
|
"../engine/src/executor/worktree-registry-helpers.ts"() {
|
|
242555
243138
|
"use strict";
|
|
242556
243139
|
init_worktree_pool();
|
|
242557
|
-
execAsync37 =
|
|
243140
|
+
execAsync37 = promisify59(exec41);
|
|
242558
243141
|
NonRetryableWorktreeError = class extends Error {
|
|
242559
243142
|
};
|
|
242560
243143
|
}
|
|
@@ -242783,7 +243366,7 @@ var init_worktree_ownership = __esm({
|
|
|
242783
243366
|
|
|
242784
243367
|
// ../engine/src/executor/worktree-stale-branch.ts
|
|
242785
243368
|
import { exec as exec42 } from "node:child_process";
|
|
242786
|
-
import { promisify as
|
|
243369
|
+
import { promisify as promisify60 } from "node:util";
|
|
242787
243370
|
async function cleanupStaleBranch(rootDir, store, branch, taskId) {
|
|
242788
243371
|
const task = await store.getTask?.(taskId);
|
|
242789
243372
|
if (!task || !isFusionDeletableBranch(task, branch)) {
|
|
@@ -242839,13 +243422,13 @@ var init_worktree_stale_branch = __esm({
|
|
|
242839
243422
|
"../engine/src/executor/worktree-stale-branch.ts"() {
|
|
242840
243423
|
"use strict";
|
|
242841
243424
|
init_src2();
|
|
242842
|
-
execAsync38 =
|
|
243425
|
+
execAsync38 = promisify60(exec42);
|
|
242843
243426
|
}
|
|
242844
243427
|
});
|
|
242845
243428
|
|
|
242846
243429
|
// ../engine/src/executor/worktree-squash-import-plan.ts
|
|
242847
243430
|
import { exec as exec43 } from "node:child_process";
|
|
242848
|
-
import { promisify as
|
|
243431
|
+
import { promisify as promisify61 } from "node:util";
|
|
242849
243432
|
async function planSquashImportFromDep(rootDir, store, _taskId, depTip, originalStartPoint) {
|
|
242850
243433
|
let settings;
|
|
242851
243434
|
try {
|
|
@@ -242919,7 +243502,7 @@ var init_worktree_squash_import_plan = __esm({
|
|
|
242919
243502
|
"../engine/src/executor/worktree-squash-import-plan.ts"() {
|
|
242920
243503
|
"use strict";
|
|
242921
243504
|
init_shell_quote();
|
|
242922
|
-
execAsync39 =
|
|
243505
|
+
execAsync39 = promisify61(exec43);
|
|
242923
243506
|
}
|
|
242924
243507
|
});
|
|
242925
243508
|
|
|
@@ -243670,7 +244253,7 @@ var init_optional_step_revision = __esm({
|
|
|
243670
244253
|
|
|
243671
244254
|
// ../engine/src/executor/execute-workflow-step.ts
|
|
243672
244255
|
import { exec as exec44 } from "node:child_process";
|
|
243673
|
-
import { promisify as
|
|
244256
|
+
import { promisify as promisify62 } from "node:util";
|
|
243674
244257
|
function findReusableReviewResult(task, workflowStepId, reviewInputFingerprint, repositoryScopeRevision) {
|
|
243675
244258
|
if (!reviewInputFingerprint) return void 0;
|
|
243676
244259
|
return (task.workflowStepResults ?? []).find(
|
|
@@ -243708,6 +244291,8 @@ async function executeWorkflowStep(deps, task, workflowStep, worktreePath, setti
|
|
|
243708
244291
|
const unattended = stepOptions?.unattended === true;
|
|
243709
244292
|
const workflowStepMetadata = workflowStep;
|
|
243710
244293
|
const optionalGroupId = workflowStepMetadata.optionalGroupId;
|
|
244294
|
+
const effectiveWorkflowStepId = optionalGroupId ?? workflowStep.id.replace(/^graph:/, "");
|
|
244295
|
+
const isContentBindingStep = requiresContentReviewProof(effectiveWorkflowStepId, workflowStepMetadata);
|
|
243711
244296
|
const isPlanReviewStep = workflowStep.id === "graph:plan-review-step" || workflowStep.name === "Plan Review" || optionalGroupId === PLAN_REVIEW_GROUP_ID;
|
|
243712
244297
|
const planReviewRevisionKey = optionalStepRevisionKey2(optionalGroupId, workflowStep.name);
|
|
243713
244298
|
const isReviewTypeWorkflowStep = isPlanReviewStep || workflowStepMetadata.reviewCanFixInline === true || /(?:^|\b)(?:review|verification)(?:\b|$)/i.test(workflowStep.name) || optionalGroupId === "plan-review" || optionalGroupId === "code-review" || optionalGroupId === "browser-verification";
|
|
@@ -243718,6 +244303,8 @@ async function executeWorkflowStep(deps, task, workflowStep, worktreePath, setti
|
|
|
243718
244303
|
toolMode = "coding";
|
|
243719
244304
|
}
|
|
243720
244305
|
const requireExternalIntegrationEvidence = workflowStepMetadata.requireExternalIntegrationEvidence === true;
|
|
244306
|
+
const readonlyMcpServerAllowlist = toolMode === "readonly" ? [...new Set((workflowStepMetadata.readonlyMcpServers ?? []).map((name2) => name2.trim()).filter(Boolean))] : [];
|
|
244307
|
+
const allowReadonlyMcpTools = toolMode === "readonly" && readonlyMcpServerAllowlist.length > 0;
|
|
243721
244308
|
let workflowReviewSpecArtifact;
|
|
243722
244309
|
if (isReviewTypeWorkflowStep) {
|
|
243723
244310
|
try {
|
|
@@ -243736,7 +244323,7 @@ async function executeWorkflowStep(deps, task, workflowStep, worktreePath, setti
|
|
|
243736
244323
|
const workflowReviewSpecText = typeof workflowReviewSpecArtifact === "string" ? workflowReviewSpecArtifact : "";
|
|
243737
244324
|
const planReviewSpecText = isPlanReviewStep ? workflowReviewSpecText : "";
|
|
243738
244325
|
const latestTaskForUserComments = await deps.store.getTask(task.id).catch(() => task);
|
|
243739
|
-
const sameGateStepId =
|
|
244326
|
+
const sameGateStepId = effectiveWorkflowStepId;
|
|
243740
244327
|
const planReviewConvergenceContext = isPlanReviewStep ? buildGraphPlanReviewConvergenceContext(latestTaskForUserComments, planReviewRevisionKey) : "";
|
|
243741
244328
|
const planReviewEnvironmentCapabilities = isPlanReviewStep ? await probeEnvironmentCapabilities({
|
|
243742
244329
|
extraCommands: [
|
|
@@ -243784,21 +244371,44 @@ async function executeWorkflowStep(deps, task, workflowStep, worktreePath, setti
|
|
|
243784
244371
|
let diffShortstat;
|
|
243785
244372
|
let reviewInputFingerprint;
|
|
243786
244373
|
let reviewedCommitSha;
|
|
244374
|
+
let baseRef;
|
|
243787
244375
|
try {
|
|
243788
|
-
|
|
243789
|
-
|
|
243790
|
-
|
|
243791
|
-
|
|
243792
|
-
|
|
243793
|
-
|
|
243794
|
-
|
|
244376
|
+
baseRef = await resolveDiffBaseRef(worktreePath, diffBaseCommitSha);
|
|
244377
|
+
} catch {
|
|
244378
|
+
}
|
|
244379
|
+
if (isContentBindingStep && task.workspaceWorktrees === void 0) {
|
|
244380
|
+
const suppliedFingerprint = stepOptions?.reviewInputFingerprint?.trim();
|
|
244381
|
+
const proof = suppliedFingerprint ? { kind: "fingerprint", fingerprint: suppliedFingerprint } : await resolveContentReviewInputProof(worktreePath, diffBaseCommitSha);
|
|
244382
|
+
if (proof.kind === "unprovable") {
|
|
244383
|
+
const diagnostic = `${workflowStep.name} review input is unprovable (${proof.reason}); reviewer dispatch refused.`;
|
|
244384
|
+
await deps.store.logEntry(
|
|
244385
|
+
task.id,
|
|
244386
|
+
`[pre-merge] ${diagnostic}`,
|
|
244387
|
+
void 0,
|
|
244388
|
+
deps.getRunContextFor(task.id)
|
|
244389
|
+
);
|
|
244390
|
+
return { success: false, error: diagnostic, failureValue: "review-input-unprovable" };
|
|
244391
|
+
}
|
|
244392
|
+
reviewInputFingerprint = proof.fingerprint;
|
|
244393
|
+
} else if (baseRef) {
|
|
244394
|
+
try {
|
|
243795
244395
|
if (workflowStepMetadata.reviewKind === "code") {
|
|
243796
244396
|
reviewInputFingerprint = await computeCodeReviewInputFingerprint(worktreePath, baseRef);
|
|
243797
244397
|
} else if (isReviewTypeWorkflowStep) {
|
|
243798
244398
|
reviewInputFingerprint = await computeReviewDiffFingerprint(worktreePath, baseRef);
|
|
243799
244399
|
}
|
|
244400
|
+
} catch {
|
|
244401
|
+
}
|
|
244402
|
+
}
|
|
244403
|
+
if (baseRef) {
|
|
244404
|
+
try {
|
|
244405
|
+
const { stdout } = await execAsync40(`git diff --shortstat ${baseRef}..HEAD`, {
|
|
244406
|
+
cwd: worktreePath,
|
|
244407
|
+
encoding: "utf-8"
|
|
244408
|
+
});
|
|
244409
|
+
diffShortstat = stdout.trim() || void 0;
|
|
244410
|
+
} catch {
|
|
243800
244411
|
}
|
|
243801
|
-
} catch {
|
|
243802
244412
|
}
|
|
243803
244413
|
if (isReviewTypeWorkflowStep) {
|
|
243804
244414
|
try {
|
|
@@ -244108,6 +244718,12 @@ ${workflowStepUserCommentSection}` : ""}${priorFindingsBlock}
|
|
|
244108
244718
|
const workflowStepThinkingSource = workflowStep.thinkingLevel ?? (isReviewTypeWorkflowStep ? task.validatorThinkingLevel ?? task.thinkingLevel : task.thinkingLevel);
|
|
244109
244719
|
const workflowStepThinkingLevel = attemptLabel === "fallback" ? isReviewTypeWorkflowStep ? resolveValidatorFallbackThinkingLevel(workflowStepThinkingSource, settings) : resolveExecutorFallbackThinkingLevel(workflowStepThinkingSource, settings) : isReviewTypeWorkflowStep ? resolveValidatorThinkingLevel(workflowStepThinkingSource, settings) : resolveExecutorThinkingLevel(workflowStepThinkingSource, settings);
|
|
244110
244720
|
const workflowStepFallbackThinkingLevel = isReviewTypeWorkflowStep ? resolveValidatorFallbackThinkingLevel(workflowStepThinkingSource, settings) : resolveExecutorFallbackThinkingLevel(workflowStepThinkingSource, settings);
|
|
244721
|
+
if (allowReadonlyMcpTools) {
|
|
244722
|
+
await deps.store.logEntry(
|
|
244723
|
+
task.id,
|
|
244724
|
+
`Workflow step '${workflowStep.name}' enabled read-only MCP servers: ${readonlyMcpServerAllowlist.join(", ")}`
|
|
244725
|
+
);
|
|
244726
|
+
}
|
|
244111
244727
|
const { session } = await createResolvedAgentSession({
|
|
244112
244728
|
sessionPurpose: "executor",
|
|
244113
244729
|
taskExecutionSession: true,
|
|
@@ -244128,6 +244744,10 @@ ${workflowStepUserCommentSection}` : ""}${priorFindingsBlock}
|
|
|
244128
244744
|
settings,
|
|
244129
244745
|
taskEnv: stepEnv,
|
|
244130
244746
|
mcpServers: await deps.resolveMcpServers(void 0),
|
|
244747
|
+
...allowReadonlyMcpTools ? {
|
|
244748
|
+
allowMcpToolsInReadonly: true,
|
|
244749
|
+
readonlyMcpServerAllowlist
|
|
244750
|
+
} : {},
|
|
244131
244751
|
// FNXC:SessionRouting 2026-06-24-11:20:
|
|
244132
244752
|
// #1675: propagate task id so workflow-step requests carry the same
|
|
244133
244753
|
// X-Session-Id/X-Session-Affinity as the primary session.
|
|
@@ -244343,6 +244963,60 @@ ${detectedQuestion}
|
|
|
244343
244963
|
});
|
|
244344
244964
|
}
|
|
244345
244965
|
const revisionRequested = effectiveVerdict === "REVISE";
|
|
244966
|
+
if (isReviewTypeWorkflowStep && !isPlanReviewStep && !revisionRequested) {
|
|
244967
|
+
const priorReviewedCommitSha = reviewedCommitSha;
|
|
244968
|
+
const currentHeadSha = await readHeadSha(worktreePath);
|
|
244969
|
+
const fastForwardAdvance = await isFastForwardAdvance(worktreePath, priorReviewedCommitSha, currentHeadSha);
|
|
244970
|
+
const baseIsAncestor = await isFastForwardAdvance(worktreePath, baseRef, currentHeadSha);
|
|
244971
|
+
const decision = classifyReviewInlineFixRecapture({
|
|
244972
|
+
verdict: effectiveVerdict,
|
|
244973
|
+
reviewKind: workflowStepMetadata.reviewKind,
|
|
244974
|
+
reviewedCommitSha: priorReviewedCommitSha,
|
|
244975
|
+
currentHeadSha,
|
|
244976
|
+
baseRef,
|
|
244977
|
+
fastForwardAdvance,
|
|
244978
|
+
baseIsAncestor,
|
|
244979
|
+
fingerprintProbeAvailable: true
|
|
244980
|
+
});
|
|
244981
|
+
if (decision.recapture) {
|
|
244982
|
+
try {
|
|
244983
|
+
const recapturedFingerprint = workflowStepMetadata.reviewKind === "code" ? await computeCodeReviewInputFingerprint(worktreePath, baseRef) : await computeReviewDiffFingerprint(worktreePath, baseRef);
|
|
244984
|
+
const finalDecision = classifyReviewInlineFixRecapture({
|
|
244985
|
+
verdict: effectiveVerdict,
|
|
244986
|
+
reviewKind: workflowStepMetadata.reviewKind,
|
|
244987
|
+
reviewedCommitSha: priorReviewedCommitSha,
|
|
244988
|
+
currentHeadSha,
|
|
244989
|
+
baseRef,
|
|
244990
|
+
fastForwardAdvance,
|
|
244991
|
+
baseIsAncestor,
|
|
244992
|
+
fingerprintProbeAvailable: recapturedFingerprint !== void 0
|
|
244993
|
+
});
|
|
244994
|
+
if (finalDecision.recapture && currentHeadSha) {
|
|
244995
|
+
reviewInputFingerprint = recapturedFingerprint;
|
|
244996
|
+
reviewedCommitSha = currentHeadSha;
|
|
244997
|
+
const resolvedInReviewFindingCount = parsed.findings?.filter((finding) => finding.resolution === "resolved-in-review").length ?? 0;
|
|
244998
|
+
await deps.store.logEntry(task.id, `[pre-merge] ${workflowStep.name} re-captured its own review identity after fast-forward ${priorReviewedCommitSha?.slice(0, 7)} \u2192 ${currentHeadSha.slice(0, 7)} (${finalDecision.reason})`);
|
|
244999
|
+
const runContext = deps.getRunContextFor(task.id);
|
|
245000
|
+
if (runContext) await emitBoundedRunAudit2(deps.store, {
|
|
245001
|
+
taskId: task.id,
|
|
245002
|
+
agentId: runContext.agentId,
|
|
245003
|
+
runId: runContext.runId,
|
|
245004
|
+
domain: "git",
|
|
245005
|
+
mutationType: "task:review-input-recaptured",
|
|
245006
|
+
target: task.id,
|
|
245007
|
+
metadata: {
|
|
245008
|
+
taskId: task.id,
|
|
245009
|
+
workflowStepId: workflowStep.id,
|
|
245010
|
+
verdict: effectiveVerdict,
|
|
245011
|
+
resolvedInReviewFindingCount,
|
|
245012
|
+
reason: finalDecision.reason
|
|
245013
|
+
}
|
|
245014
|
+
});
|
|
245015
|
+
}
|
|
245016
|
+
} catch {
|
|
245017
|
+
}
|
|
245018
|
+
}
|
|
245019
|
+
}
|
|
244346
245020
|
if (workflowStep.requiresBrowser === true) {
|
|
244347
245021
|
await logBrowserVerificationActivity(`[browser-verification] finished browser verification for task ${task.id}: verdict ${effectiveVerdict}`);
|
|
244348
245022
|
}
|
|
@@ -244487,9 +245161,10 @@ var init_execute_workflow_step = __esm({
|
|
|
244487
245161
|
init_workflow_step_verdict();
|
|
244488
245162
|
init_worktree_git_refs();
|
|
244489
245163
|
init_review_diff_fingerprint();
|
|
245164
|
+
init_review_inline_fix_recapture();
|
|
244490
245165
|
init_optional_step_revision();
|
|
244491
245166
|
init_agent_usage_telemetry();
|
|
244492
|
-
execAsync40 =
|
|
245167
|
+
execAsync40 = promisify62(exec44);
|
|
244493
245168
|
WORKFLOW_STEP_NOTES_REPAIR_TIMEOUT_MS = 12e4;
|
|
244494
245169
|
}
|
|
244495
245170
|
});
|
|
@@ -245123,7 +245798,7 @@ var init_public_reexports = __esm({
|
|
|
245123
245798
|
|
|
245124
245799
|
// ../engine/src/executor/worktree-create-conflict.ts
|
|
245125
245800
|
import { exec as exec45 } from "node:child_process";
|
|
245126
|
-
import { promisify as
|
|
245801
|
+
import { promisify as promisify63 } from "node:util";
|
|
245127
245802
|
import { existsSync as existsSync69 } from "node:fs";
|
|
245128
245803
|
import { rm as rm12 } from "node:fs/promises";
|
|
245129
245804
|
async function tryCreateWorktree(deps, branch, path13, taskId, startPoint, attemptNumber = 0, recoveryDepth = 0, allowSiblingBranchRename = false, settings = {}) {
|
|
@@ -245418,13 +246093,13 @@ var init_worktree_create_conflict = __esm({
|
|
|
245418
246093
|
init_logger3();
|
|
245419
246094
|
init_worktree_conflict_info();
|
|
245420
246095
|
init_worktree_registry_helpers();
|
|
245421
|
-
execAsync41 =
|
|
246096
|
+
execAsync41 = promisify63(exec45);
|
|
245422
246097
|
}
|
|
245423
246098
|
});
|
|
245424
246099
|
|
|
245425
246100
|
// ../engine/src/executor/worktree-cleanup-conflicting.ts
|
|
245426
246101
|
import { exec as exec46 } from "node:child_process";
|
|
245427
|
-
import { promisify as
|
|
246102
|
+
import { promisify as promisify64 } from "node:util";
|
|
245428
246103
|
import { existsSync as existsSync70, lstatSync as lstatSync3, realpathSync as realpathSync11 } from "node:fs";
|
|
245429
246104
|
import { rm as rm13 } from "node:fs/promises";
|
|
245430
246105
|
async function cleanupConflictingWorktree(deps, worktreePath, branch, taskId) {
|
|
@@ -245543,13 +246218,13 @@ var init_worktree_cleanup_conflicting = __esm({
|
|
|
245543
246218
|
init_src2();
|
|
245544
246219
|
init_worktree_pool();
|
|
245545
246220
|
init_logger3();
|
|
245546
|
-
execAsync42 =
|
|
246221
|
+
execAsync42 = promisify64(exec46);
|
|
245547
246222
|
}
|
|
245548
246223
|
});
|
|
245549
246224
|
|
|
245550
246225
|
// ../engine/src/executor/worktree-create-outer.ts
|
|
245551
246226
|
import { exec as exec47 } from "node:child_process";
|
|
245552
|
-
import { promisify as
|
|
246227
|
+
import { promisify as promisify65 } from "node:util";
|
|
245553
246228
|
import { existsSync as existsSync71 } from "node:fs";
|
|
245554
246229
|
import { isAbsolute as isAbsolute22 } from "node:path";
|
|
245555
246230
|
async function resolveWorktreeStartPoint(rootDir, store, startPoint, taskId) {
|
|
@@ -245754,13 +246429,13 @@ var init_worktree_create_outer = __esm({
|
|
|
245754
246429
|
init_logger3();
|
|
245755
246430
|
init_shell_quote();
|
|
245756
246431
|
init_worktree_registry_helpers();
|
|
245757
|
-
execAsync43 =
|
|
246432
|
+
execAsync43 = promisify65(exec47);
|
|
245758
246433
|
}
|
|
245759
246434
|
});
|
|
245760
246435
|
|
|
245761
246436
|
// ../engine/src/executor/worktree-branch-conflict-handle.ts
|
|
245762
246437
|
import { exec as exec48 } from "node:child_process";
|
|
245763
|
-
import { promisify as
|
|
246438
|
+
import { promisify as promisify66 } from "node:util";
|
|
245764
246439
|
async function reclaimExistingWorktree(deps, task, livePath, branch, tipSha, count2, settings) {
|
|
245765
246440
|
const targetPath = preservedWorktreeTargetPathForTask(task.id, livePath, settings, deps.rootDir);
|
|
245766
246441
|
const normalizedPath = await deps.normalizeReclaimableWorktreePath(livePath, targetPath, task.id, settings);
|
|
@@ -245909,7 +246584,7 @@ var init_worktree_branch_conflict_handle = __esm({
|
|
|
245909
246584
|
init_worktree_git_refs();
|
|
245910
246585
|
init_worktree_registry_helpers();
|
|
245911
246586
|
init_branch_conflict_format();
|
|
245912
|
-
execAsync44 =
|
|
246587
|
+
execAsync44 = promisify66(exec48);
|
|
245913
246588
|
}
|
|
245914
246589
|
});
|
|
245915
246590
|
|
|
@@ -246064,10 +246739,10 @@ var init_session_worktree_paths = __esm({
|
|
|
246064
246739
|
});
|
|
246065
246740
|
|
|
246066
246741
|
// ../engine/src/execution/external-execution-checkout.ts
|
|
246067
|
-
import { execFile as
|
|
246742
|
+
import { execFile as execFile30 } from "node:child_process";
|
|
246068
246743
|
import { existsSync as existsSync72, realpathSync as realpathSync13, statSync as statSync14 } from "node:fs";
|
|
246069
246744
|
import { isAbsolute as isAbsolute23 } from "node:path";
|
|
246070
|
-
import { promisify as
|
|
246745
|
+
import { promisify as promisify67 } from "node:util";
|
|
246071
246746
|
function readSourceMetadata(task) {
|
|
246072
246747
|
if (!task || typeof task !== "object") return void 0;
|
|
246073
246748
|
const sourceMetadata = task.sourceMetadata;
|
|
@@ -246086,7 +246761,7 @@ async function inspectExternalGitCheckout(candidate, options = {}) {
|
|
|
246086
246761
|
return { valid: false, reason: `checkoutPath is not a directory: ${checkoutPath}` };
|
|
246087
246762
|
}
|
|
246088
246763
|
const canonicalCheckout = realpathSync13(checkoutPath);
|
|
246089
|
-
const { stdout: topLevelOutput } = await
|
|
246764
|
+
const { stdout: topLevelOutput } = await execFileAsync24("git", ["rev-parse", "--show-toplevel"], {
|
|
246090
246765
|
cwd: canonicalCheckout,
|
|
246091
246766
|
encoding: "utf-8",
|
|
246092
246767
|
timeout: 1e4
|
|
@@ -246099,7 +246774,7 @@ async function inspectExternalGitCheckout(candidate, options = {}) {
|
|
|
246099
246774
|
reason: `checkoutPath must be the Git top-level (observed ${canonicalTopLevel})`
|
|
246100
246775
|
};
|
|
246101
246776
|
}
|
|
246102
|
-
const { stdout: branchOutput } = await
|
|
246777
|
+
const { stdout: branchOutput } = await execFileAsync24("git", ["symbolic-ref", "--quiet", "--short", "HEAD"], {
|
|
246103
246778
|
cwd: canonicalCheckout,
|
|
246104
246779
|
encoding: "utf-8",
|
|
246105
246780
|
timeout: 1e4
|
|
@@ -246109,7 +246784,7 @@ async function inspectExternalGitCheckout(candidate, options = {}) {
|
|
|
246109
246784
|
return { valid: false, reason: "checkoutPath must have a checked-out branch" };
|
|
246110
246785
|
}
|
|
246111
246786
|
if (options.requireClean) {
|
|
246112
|
-
const { stdout: statusOutput } = await
|
|
246787
|
+
const { stdout: statusOutput } = await execFileAsync24("git", ["status", "--porcelain=v1"], {
|
|
246113
246788
|
cwd: canonicalCheckout,
|
|
246114
246789
|
encoding: "utf-8",
|
|
246115
246790
|
timeout: 1e4
|
|
@@ -246157,11 +246832,11 @@ async function resolveExternalExecutionCheckoutRoute(task) {
|
|
|
246157
246832
|
}
|
|
246158
246833
|
return { configured: true, ...inspection };
|
|
246159
246834
|
}
|
|
246160
|
-
var
|
|
246835
|
+
var execFileAsync24;
|
|
246161
246836
|
var init_external_execution_checkout = __esm({
|
|
246162
246837
|
"../engine/src/execution/external-execution-checkout.ts"() {
|
|
246163
246838
|
"use strict";
|
|
246164
|
-
|
|
246839
|
+
execFileAsync24 = promisify67(execFile30);
|
|
246165
246840
|
}
|
|
246166
246841
|
});
|
|
246167
246842
|
|
|
@@ -246185,7 +246860,7 @@ var init_resolve_authoritative_external_execution_route = __esm({
|
|
|
246185
246860
|
import { exec as exec49 } from "node:child_process";
|
|
246186
246861
|
import { existsSync as existsSync73, promises as fs7 } from "node:fs";
|
|
246187
246862
|
import path4 from "node:path";
|
|
246188
|
-
import { promisify as
|
|
246863
|
+
import { promisify as promisify68 } from "node:util";
|
|
246189
246864
|
function workspaceExecutionAnchor(task) {
|
|
246190
246865
|
const executionValues = [task.firstExecutionAt, task.executionStartedAt].map((value) => typeof value === "string" ? Date.parse(value) : Number.NaN).filter(Number.isFinite);
|
|
246191
246866
|
const values2 = executionValues.length ? executionValues : [typeof task.createdAt === "string" ? Date.parse(task.createdAt) : Number.NaN].filter(Number.isFinite);
|
|
@@ -246309,14 +246984,14 @@ var init_workspace_main_checkout_guard = __esm({
|
|
|
246309
246984
|
init_workspace_paths();
|
|
246310
246985
|
init_worktree_paths();
|
|
246311
246986
|
init_workflow_feedback_paths();
|
|
246312
|
-
execAsync45 =
|
|
246987
|
+
execAsync45 = promisify68(exec49);
|
|
246313
246988
|
probeOptions = { encoding: "utf-8", timeout: 1e4, maxBuffer: 1024 * 1024 };
|
|
246314
246989
|
}
|
|
246315
246990
|
});
|
|
246316
246991
|
|
|
246317
246992
|
// ../engine/src/executor/worktree-verify-invariants.ts
|
|
246318
246993
|
import { exec as exec50 } from "node:child_process";
|
|
246319
|
-
import { promisify as
|
|
246994
|
+
import { promisify as promisify69 } from "node:util";
|
|
246320
246995
|
import { existsSync as existsSync74 } from "node:fs";
|
|
246321
246996
|
async function verifyWorktreeInvariants(deps, task, worktreePathOverride, allowReanchor = true, options) {
|
|
246322
246997
|
const workspaceConfig = deps.ensureWorkspaceConfig ? await deps.ensureWorkspaceConfig() : deps.workspaceConfig;
|
|
@@ -246737,17 +247412,17 @@ var init_worktree_verify_invariants = __esm({
|
|
|
246737
247412
|
init_no_commit_eligibility();
|
|
246738
247413
|
init_resolve_authoritative_external_execution_route();
|
|
246739
247414
|
init_workspace_main_checkout_guard();
|
|
246740
|
-
execAsync46 =
|
|
247415
|
+
execAsync46 = promisify69(exec50);
|
|
246741
247416
|
}
|
|
246742
247417
|
});
|
|
246743
247418
|
|
|
246744
247419
|
// ../engine/src/executor/worktree-task-done-scope-leak.ts
|
|
246745
|
-
import { execFile as
|
|
247420
|
+
import { execFile as execFile31 } from "node:child_process";
|
|
246746
247421
|
import { access as access10 } from "node:fs/promises";
|
|
246747
|
-
import { promisify as
|
|
247422
|
+
import { promisify as promisify70 } from "node:util";
|
|
246748
247423
|
async function verifyRepositoryCaptureEvidence(worktreePath) {
|
|
246749
247424
|
await access10(worktreePath);
|
|
246750
|
-
const { stdout } = await
|
|
247425
|
+
const { stdout } = await execFileAsync25("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
246751
247426
|
cwd: worktreePath,
|
|
246752
247427
|
encoding: "utf8"
|
|
246753
247428
|
});
|
|
@@ -246764,7 +247439,7 @@ async function captureRepositoryChangeEvidence(worktreePath, baseCommitSha) {
|
|
|
246764
247439
|
} else {
|
|
246765
247440
|
commands.push(["rev-parse", "--verify", "HEAD"]);
|
|
246766
247441
|
}
|
|
246767
|
-
const results = await Promise.all(commands.map((args) =>
|
|
247442
|
+
const results = await Promise.all(commands.map((args) => execFileAsync25("git", args, {
|
|
246768
247443
|
cwd: worktreePath,
|
|
246769
247444
|
encoding: "utf8"
|
|
246770
247445
|
})));
|
|
@@ -246893,7 +247568,7 @@ async function evaluateTaskDoneScopeLeak(deps, task, worktreePath, promptContent
|
|
|
246893
247568
|
}
|
|
246894
247569
|
return { blocked: false };
|
|
246895
247570
|
}
|
|
246896
|
-
var
|
|
247571
|
+
var execFileAsync25;
|
|
246897
247572
|
var init_worktree_task_done_scope_leak = __esm({
|
|
246898
247573
|
"../engine/src/executor/worktree-task-done-scope-leak.ts"() {
|
|
246899
247574
|
"use strict";
|
|
@@ -246901,7 +247576,7 @@ var init_worktree_task_done_scope_leak = __esm({
|
|
|
246901
247576
|
init_logger3();
|
|
246902
247577
|
init_prompt_derived_eligibility();
|
|
246903
247578
|
init_workflow_feedback_paths();
|
|
246904
|
-
|
|
247579
|
+
execFileAsync25 = promisify70(execFile31);
|
|
246905
247580
|
}
|
|
246906
247581
|
});
|
|
246907
247582
|
|
|
@@ -247311,7 +247986,7 @@ var init_task_done_refusal_handler = __esm({
|
|
|
247311
247986
|
|
|
247312
247987
|
// ../engine/src/executor/dep-abort-cleanup.ts
|
|
247313
247988
|
import { exec as exec51 } from "node:child_process";
|
|
247314
|
-
import { promisify as
|
|
247989
|
+
import { promisify as promisify71 } from "node:util";
|
|
247315
247990
|
async function handleDepAbortCleanup(deps, taskId, worktreePath) {
|
|
247316
247991
|
executorLog.log(`${taskId} dependency added \u2014 work discarded, moved to triage for re-planning`);
|
|
247317
247992
|
const task = await deps.store.getTask(taskId);
|
|
@@ -247362,7 +248037,7 @@ var init_dep_abort_cleanup = __esm({
|
|
|
247362
248037
|
init_logger3();
|
|
247363
248038
|
init_external_execution_checkout();
|
|
247364
248039
|
init_lifecycle_columns();
|
|
247365
|
-
execAsync47 =
|
|
248040
|
+
execAsync47 = promisify71(exec51);
|
|
247366
248041
|
}
|
|
247367
248042
|
});
|
|
247368
248043
|
|
|
@@ -247886,7 +248561,7 @@ var init_no_merge_complete_column = __esm({
|
|
|
247886
248561
|
// ../engine/src/execution/step-runner.ts
|
|
247887
248562
|
import { exec as exec52 } from "node:child_process";
|
|
247888
248563
|
import { existsSync as existsSync75, statSync as statSync15 } from "node:fs";
|
|
247889
|
-
import { promisify as
|
|
248564
|
+
import { promisify as promisify72 } from "node:util";
|
|
247890
248565
|
async function runTaskStep(deps, task, stepIndex, opts = {}) {
|
|
247891
248566
|
const { store, worktreePath } = deps;
|
|
247892
248567
|
const gitRevParse = deps.gitRevParse ?? defaultGitRevParse;
|
|
@@ -248070,7 +248745,7 @@ var init_step_runner = __esm({
|
|
|
248070
248745
|
"../engine/src/execution/step-runner.ts"() {
|
|
248071
248746
|
"use strict";
|
|
248072
248747
|
init_logger3();
|
|
248073
|
-
execAsync48 =
|
|
248748
|
+
execAsync48 = promisify72(exec52);
|
|
248074
248749
|
}
|
|
248075
248750
|
});
|
|
248076
248751
|
|
|
@@ -250029,7 +250704,7 @@ var init_recover_failed_pre_merge_step = __esm({
|
|
|
250029
250704
|
|
|
250030
250705
|
// ../engine/src/executor/reconcile-steps-from-git-history.ts
|
|
250031
250706
|
import { exec as exec53 } from "node:child_process";
|
|
250032
|
-
import { promisify as
|
|
250707
|
+
import { promisify as promisify73 } from "node:util";
|
|
250033
250708
|
async function reconcileStepsFromGitHistory(deps, taskId, detail, worktreePath) {
|
|
250034
250709
|
const baseCommitSha = detail.baseCommitSha;
|
|
250035
250710
|
if (!baseCommitSha) return;
|
|
@@ -250117,7 +250792,7 @@ var init_reconcile_steps_from_git_history = __esm({
|
|
|
250117
250792
|
"use strict";
|
|
250118
250793
|
init_src2();
|
|
250119
250794
|
init_logger3();
|
|
250120
|
-
execAsync49 =
|
|
250795
|
+
execAsync49 = promisify73(exec53);
|
|
250121
250796
|
}
|
|
250122
250797
|
});
|
|
250123
250798
|
|
|
@@ -252401,7 +253076,14 @@ async function persistWorkflowStepResultWithOutcome(deps, taskId, result2, fence
|
|
|
252401
253076
|
scopeSuperseded = true;
|
|
252402
253077
|
return null;
|
|
252403
253078
|
}
|
|
252404
|
-
const
|
|
253079
|
+
const unprovenApproval = resolveUnprovenReviewApproval(result2, {
|
|
253080
|
+
workspace: current.workspaceWorktrees !== void 0
|
|
253081
|
+
});
|
|
253082
|
+
const built = buildWorkflowStepResultPatch(
|
|
253083
|
+
current,
|
|
253084
|
+
unprovenApproval?.downgraded ?? result2,
|
|
253085
|
+
isPlanReviewResult
|
|
253086
|
+
);
|
|
252405
253087
|
activityResult = built.resultToPersist;
|
|
252406
253088
|
activityResults = built.results;
|
|
252407
253089
|
return built.patch;
|
|
@@ -252438,21 +253120,30 @@ async function persistWorkflowStepResultWithOutcome(deps, taskId, result2, fence
|
|
|
252438
253120
|
if (scopeSuperseded) return { scopeCurrent: false, persisted: false };
|
|
252439
253121
|
if (fenceRefused) return { scopeCurrent: true, persisted: false };
|
|
252440
253122
|
const persistedResult = activityResults?.find((entry) => entry.workflowStepId === result2.workflowStepId) ?? activityResult;
|
|
252441
|
-
|
|
252442
|
-
|
|
253123
|
+
const approvalDowngraded = result2.status === "passed" && persistedResult.status === "failed" && result2.reviewInputFingerprint === void 0 && persistedResult.verdict === void 0;
|
|
253124
|
+
if (approvalDowngraded) {
|
|
253125
|
+
await deps.store.logEntry(
|
|
253126
|
+
taskId,
|
|
253127
|
+
`[pre-merge] ${result2.workflowStepName} approval invalidated: ${persistedResult.notes ?? persistedResult.output ?? "review input proof missing"}`,
|
|
253128
|
+
void 0,
|
|
253129
|
+
deps.getRunContextFor(taskId)
|
|
253130
|
+
).catch(() => void 0);
|
|
253131
|
+
}
|
|
253132
|
+
if (isTerminalStepResult(persistedResult)) {
|
|
253133
|
+
const passed = persistedResult.status === "passed" || persistedResult.status === "skipped" || persistedResult.verdict === "APPROVE" || persistedResult.verdict === "APPROVE_WITH_NOTES" || persistedResult.verdict === "CLOSE_NO_OP";
|
|
252443
253134
|
try {
|
|
252444
253135
|
await deps.store.recordAgentActivity({
|
|
252445
253136
|
type: passed ? "workflow:gate-passed" : "workflow:gate-failed",
|
|
252446
253137
|
attributionClaim: resolveWorkflowGateActivityClaim(
|
|
252447
|
-
deps.workflowGateActivityPrincipals?.get(`${taskId}\0${
|
|
253138
|
+
deps.workflowGateActivityPrincipals?.get(`${taskId}\0${persistedResult.workflowStepId}`) ?? deps.activeWorkflowPrincipals?.get(taskId)?.agentId,
|
|
252448
253139
|
live?.assignedAgentId
|
|
252449
253140
|
),
|
|
252450
253141
|
taskId,
|
|
252451
|
-
occurredAt:
|
|
252452
|
-
discriminator: `${
|
|
252453
|
-
metadata: buildWorkflowGateActivityMetadata(
|
|
253142
|
+
occurredAt: persistedResult.completedAt ?? persistedResult.startedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
253143
|
+
discriminator: `${persistedResult.workflowStepId}:${persistedResult.startedAt ?? persistedResult.completedAt ?? persistedResult.status}`,
|
|
253144
|
+
metadata: buildWorkflowGateActivityMetadata(persistedResult, persistedResult)
|
|
252454
253145
|
});
|
|
252455
|
-
deps.workflowGateActivityPrincipals?.delete(`${taskId}\0${
|
|
253146
|
+
deps.workflowGateActivityPrincipals?.delete(`${taskId}\0${persistedResult.workflowStepId}`);
|
|
252456
253147
|
} catch (error3) {
|
|
252457
253148
|
executorLog.warn(`[agent-activity] ${taskId}: failed to record workflow gate activity: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
252458
253149
|
}
|
|
@@ -254463,7 +255154,7 @@ var init_run_spawned_child = __esm({
|
|
|
254463
255154
|
|
|
254464
255155
|
// ../engine/src/auto-recovery-handlers/file-scope.ts
|
|
254465
255156
|
import { exec as exec54 } from "node:child_process";
|
|
254466
|
-
import { promisify as
|
|
255157
|
+
import { promisify as promisify74 } from "node:util";
|
|
254467
255158
|
function createFileScopeAutoRecoveryHandler(deps) {
|
|
254468
255159
|
return new FileScopeAutoRecoveryHandler({
|
|
254469
255160
|
...deps,
|
|
@@ -254474,7 +255165,7 @@ var execAsync50, FileScopeAutoRecoveryHandler;
|
|
|
254474
255165
|
var init_file_scope2 = __esm({
|
|
254475
255166
|
"../engine/src/auto-recovery-handlers/file-scope.ts"() {
|
|
254476
255167
|
"use strict";
|
|
254477
|
-
execAsync50 =
|
|
255168
|
+
execAsync50 = promisify74(exec54);
|
|
254478
255169
|
FileScopeAutoRecoveryHandler = class {
|
|
254479
255170
|
constructor(deps) {
|
|
254480
255171
|
this.deps = deps;
|
|
@@ -254490,7 +255181,7 @@ var init_file_scope2 = __esm({
|
|
|
254490
255181
|
// ../engine/src/auto-recovery-handlers/branch-worktree.ts
|
|
254491
255182
|
import { exec as exec55 } from "node:child_process";
|
|
254492
255183
|
import { existsSync as existsSync78 } from "node:fs";
|
|
254493
|
-
import { promisify as
|
|
255184
|
+
import { promisify as promisify75 } from "node:util";
|
|
254494
255185
|
var execAsync51, baseLog2, GIT_TIMEOUT_MS8, GIT_MAX_BUFFER6, BranchWorktreeAutoRecoveryHandler;
|
|
254495
255186
|
var init_branch_worktree = __esm({
|
|
254496
255187
|
"../engine/src/auto-recovery-handlers/branch-worktree.ts"() {
|
|
@@ -254500,7 +255191,7 @@ var init_branch_worktree = __esm({
|
|
|
254500
255191
|
init_active_session_registry();
|
|
254501
255192
|
init_integration_branch();
|
|
254502
255193
|
init_logger3();
|
|
254503
|
-
execAsync51 =
|
|
255194
|
+
execAsync51 = promisify75(exec55);
|
|
254504
255195
|
baseLog2 = createLogger2("auto-recovery:branch-worktree");
|
|
254505
255196
|
GIT_TIMEOUT_MS8 = 3e4;
|
|
254506
255197
|
GIT_MAX_BUFFER6 = 10 * 1024 * 1024;
|
|
@@ -255567,7 +256258,7 @@ var init_run_raw_cli_command = __esm({
|
|
|
255567
256258
|
|
|
255568
256259
|
// ../engine/src/executor/reset-steps-if-work-lost.ts
|
|
255569
256260
|
import { exec as exec56 } from "node:child_process";
|
|
255570
|
-
import { promisify as
|
|
256261
|
+
import { promisify as promisify76 } from "node:util";
|
|
255571
256262
|
async function resetStepsIfWorkLost(deps, task) {
|
|
255572
256263
|
const completedSteps = task.steps.filter(
|
|
255573
256264
|
(s3) => s3.status === "done" || s3.status === "in-progress"
|
|
@@ -255608,7 +256299,7 @@ var init_reset_steps_if_work_lost = __esm({
|
|
|
255608
256299
|
init_src2();
|
|
255609
256300
|
init_worktree_names();
|
|
255610
256301
|
init_logger3();
|
|
255611
|
-
execAsync52 =
|
|
256302
|
+
execAsync52 = promisify76(exec56);
|
|
255612
256303
|
}
|
|
255613
256304
|
});
|
|
255614
256305
|
|
|
@@ -255655,7 +256346,7 @@ var init_route_retryable_remediation = __esm({
|
|
|
255655
256346
|
|
|
255656
256347
|
// ../engine/src/executor/build-foreach-worktree-deps.ts
|
|
255657
256348
|
import { exec as exec57 } from "node:child_process";
|
|
255658
|
-
import { promisify as
|
|
256349
|
+
import { promisify as promisify77 } from "node:util";
|
|
255659
256350
|
function buildForeachWorktreeDeps(deps, task, runId) {
|
|
255660
256351
|
const taskId = task.id;
|
|
255661
256352
|
const instancePaths = /* @__PURE__ */ new Map();
|
|
@@ -255849,20 +256540,20 @@ var init_build_foreach_worktree_deps = __esm({
|
|
|
255849
256540
|
init_worktree_names();
|
|
255850
256541
|
init_worktree_paths();
|
|
255851
256542
|
init_logger3();
|
|
255852
|
-
execAsync53 =
|
|
256543
|
+
execAsync53 = promisify77(exec57);
|
|
255853
256544
|
WORKSPACE_ISOLATION_UNSUPPORTED_MESSAGE = "per-instance worktree isolation is not supported for workspace projects";
|
|
255854
256545
|
}
|
|
255855
256546
|
});
|
|
255856
256547
|
|
|
255857
256548
|
// ../engine/src/executor/derive-remediation-steps.ts
|
|
255858
|
-
import { createHash as
|
|
256549
|
+
import { createHash as createHash35 } from "node:crypto";
|
|
255859
256550
|
function normalizeVerificationEvidence(output2) {
|
|
255860
256551
|
if (!output2?.trim()) return "";
|
|
255861
256552
|
return output2.replace(ansiEscapeSequence, "").replace(/\r\n?/g, "\n").split("\n").map((line2) => line2.trim().replace(isoTimestamp, "<timestamp>").replace(bareTimestamp, "<timestamp>").replace(elapsedDuration, "<duration>").replace(/\s+/g, " ")).filter(Boolean).join("\n");
|
|
255862
256553
|
}
|
|
255863
256554
|
function verificationEvidenceDigest(output2) {
|
|
255864
256555
|
const evidence = normalizeVerificationEvidence(output2);
|
|
255865
|
-
return evidence ?
|
|
256556
|
+
return evidence ? createHash35("sha256").update(evidence).digest("hex").slice(0, 16) : void 0;
|
|
255866
256557
|
}
|
|
255867
256558
|
function verificationCandidates(input) {
|
|
255868
256559
|
const detail = input.verificationCommandLabel ?? "verification command";
|
|
@@ -260565,10 +261256,10 @@ var init_pending_review_block = __esm({
|
|
|
260565
261256
|
});
|
|
260566
261257
|
|
|
260567
261258
|
// ../engine/src/merge/merger-orphan-rehome.ts
|
|
260568
|
-
import { execFile as
|
|
260569
|
-
import { promisify as
|
|
261259
|
+
import { execFile as execFile32 } from "node:child_process";
|
|
261260
|
+
import { promisify as promisify78 } from "node:util";
|
|
260570
261261
|
async function runGit6(args, cwd) {
|
|
260571
|
-
const { stdout } = await
|
|
261262
|
+
const { stdout } = await execFileAsync26("git", args, {
|
|
260572
261263
|
cwd,
|
|
260573
261264
|
encoding: "utf-8",
|
|
260574
261265
|
timeout: 3e4
|
|
@@ -260577,7 +261268,7 @@ async function runGit6(args, cwd) {
|
|
|
260577
261268
|
}
|
|
260578
261269
|
async function isAncestor3(repoDir, ancestor, descendant) {
|
|
260579
261270
|
try {
|
|
260580
|
-
await
|
|
261271
|
+
await execFileAsync26(
|
|
260581
261272
|
"git",
|
|
260582
261273
|
["merge-base", "--is-ancestor", ancestor, descendant],
|
|
260583
261274
|
{ cwd: repoDir, encoding: "utf-8", timeout: 3e4 }
|
|
@@ -260672,13 +261363,13 @@ async function rehomeOrphanOntoIntegration(input) {
|
|
|
260672
261363
|
newTipSha: advanceResult.newSha
|
|
260673
261364
|
};
|
|
260674
261365
|
}
|
|
260675
|
-
var
|
|
261366
|
+
var execFileAsync26;
|
|
260676
261367
|
var init_merger_orphan_rehome = __esm({
|
|
260677
261368
|
"../engine/src/merge/merger-orphan-rehome.ts"() {
|
|
260678
261369
|
"use strict";
|
|
260679
261370
|
init_src2();
|
|
260680
261371
|
init_merger_ref_update_advance();
|
|
260681
|
-
|
|
261372
|
+
execFileAsync26 = promisify78(execFile32);
|
|
260682
261373
|
}
|
|
260683
261374
|
});
|
|
260684
261375
|
|
|
@@ -260705,7 +261396,7 @@ var init_merge_execution_exclusion = __esm({
|
|
|
260705
261396
|
|
|
260706
261397
|
// ../engine/src/executor/run-implementation.ts
|
|
260707
261398
|
import { exec as exec58 } from "node:child_process";
|
|
260708
|
-
import { promisify as
|
|
261399
|
+
import { promisify as promisify79 } from "node:util";
|
|
260709
261400
|
import { existsSync as existsSync81 } from "node:fs";
|
|
260710
261401
|
import { join as join93 } from "node:path";
|
|
260711
261402
|
import { SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
|
|
@@ -263541,7 +264232,7 @@ var init_run_implementation = __esm({
|
|
|
263541
264232
|
init_worktree_acquisition();
|
|
263542
264233
|
init_worktree_paths();
|
|
263543
264234
|
init_worktree_pool();
|
|
263544
|
-
execAsync54 =
|
|
264235
|
+
execAsync54 = promisify79(exec58);
|
|
263545
264236
|
MAX_TASK_DONE_SESSION_RETRIES = 3;
|
|
263546
264237
|
}
|
|
263547
264238
|
});
|
|
@@ -267267,8 +267958,8 @@ var init_worktree_create_binders = __esm({
|
|
|
267267
267958
|
});
|
|
267268
267959
|
|
|
267269
267960
|
// ../engine/src/executor/wire-executor-lifecycle.ts
|
|
267270
|
-
import { execFile as
|
|
267271
|
-
import { promisify as
|
|
267961
|
+
import { execFile as execFile33 } from "node:child_process";
|
|
267962
|
+
import { promisify as promisify80 } from "node:util";
|
|
267272
267963
|
async function releaseWorkspaceAcquireClaims(store, taskId) {
|
|
267273
267964
|
for (const entry of activeSessionRegistry.entriesByKind("workspace-repo-acquire")) {
|
|
267274
267965
|
if (entry.taskId === taskId) activeSessionRegistry.unregisterPath(entry.path);
|
|
@@ -267316,7 +268007,7 @@ function wireExecutorLifecycle(deps) {
|
|
|
267316
268007
|
if (await canonicalizeWorktreePath(entry.worktreePath) === await canonicalizeWorktreePath(entry.repoRootDir)) throw new Error("Refusing to remove workspace repository root");
|
|
267317
268008
|
activeSessionRegistry.unregisterPath(entry.worktreePath);
|
|
267318
268009
|
await removeWorktree({ worktreePath: entry.worktreePath, rootDir: entry.repoRootDir, settings: await deps.store.getSettings(), taskId: task.id, reason: RemovalReason.ExecutorDispose, force: true });
|
|
267319
|
-
await
|
|
268010
|
+
await execFileAsync27("git", ["branch", "-D", entry.branch], { cwd: entry.repoRootDir, timeout: 12e4, maxBuffer: 10 * 1024 * 1024 });
|
|
267320
268011
|
if (task.workspaceWorktrees) for (const repoRel of [entry.repoRel, ...entry.aliasRepoRels]) delete task.workspaceWorktrees[repoRel];
|
|
267321
268012
|
removed.push(entry.repoRel);
|
|
267322
268013
|
} catch (error3) {
|
|
@@ -267744,7 +268435,7 @@ function wireTaskExecutorLifecycle(host) {
|
|
|
267744
268435
|
h.workflowAgentCapacity = new WorkflowAgentCapacity(h.options?.agentStore ?? void 0);
|
|
267745
268436
|
applyWireExecutorLifecycleDisposers(host, wireExecutorLifecycle(buildWireExecutorLifecycleDeps(host)));
|
|
267746
268437
|
}
|
|
267747
|
-
var
|
|
268438
|
+
var execFileAsync27, WIRE_LIFECYCLE_FIELDS, WIRE_LIFECYCLE_METHODS;
|
|
267748
268439
|
var init_wire_executor_lifecycle = __esm({
|
|
267749
268440
|
"../engine/src/executor/wire-executor-lifecycle.ts"() {
|
|
267750
268441
|
"use strict";
|
|
@@ -267761,7 +268452,7 @@ var init_wire_executor_lifecycle = __esm({
|
|
|
267761
268452
|
init_task_predicates();
|
|
267762
268453
|
init_facade_methods();
|
|
267763
268454
|
init_workflow_agent_capacity();
|
|
267764
|
-
|
|
268455
|
+
execFileAsync27 = promisify80(execFile33);
|
|
267765
268456
|
WIRE_LIFECYCLE_FIELDS = [
|
|
267766
268457
|
"activeConfiguredCommandControllers",
|
|
267767
268458
|
"activeSessions",
|
|
@@ -270658,7 +271349,7 @@ import { promises as fs9 } from "node:fs";
|
|
|
270658
271349
|
import os7 from "node:os";
|
|
270659
271350
|
import path5 from "node:path";
|
|
270660
271351
|
import { exec as exec59 } from "node:child_process";
|
|
270661
|
-
import { promisify as
|
|
271352
|
+
import { promisify as promisify81 } from "node:util";
|
|
270662
271353
|
var execAsync55, verifyLog, GitCheckoutMaterializer;
|
|
270663
271354
|
var init_mission_verification = __esm({
|
|
270664
271355
|
"../engine/src/missions/mission-verification.ts"() {
|
|
@@ -270668,7 +271359,7 @@ var init_mission_verification = __esm({
|
|
|
270668
271359
|
init_sandbox_exec_detect();
|
|
270669
271360
|
init_verification_utils();
|
|
270670
271361
|
init_logger3();
|
|
270671
|
-
execAsync55 =
|
|
271362
|
+
execAsync55 = promisify81(exec59);
|
|
270672
271363
|
verifyLog = createLogger2("mission-verify");
|
|
270673
271364
|
GitCheckoutMaterializer = class {
|
|
270674
271365
|
async materialize(rootDir, revision) {
|
|
@@ -270711,14 +271402,14 @@ ${stdout.trim()}`);
|
|
|
270711
271402
|
|
|
270712
271403
|
// ../engine/src/missions/mission-execution-loop.ts
|
|
270713
271404
|
import { EventEmitter as EventEmitter25 } from "node:events";
|
|
270714
|
-
import { createHash as
|
|
271405
|
+
import { createHash as createHash36 } from "node:crypto";
|
|
270715
271406
|
import { exec as exec60 } from "node:child_process";
|
|
270716
|
-
import { promisify as
|
|
271407
|
+
import { promisify as promisify82 } from "node:util";
|
|
270717
271408
|
function quoteShellArg8(value) {
|
|
270718
271409
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
270719
271410
|
}
|
|
270720
271411
|
function fingerprintMissionValidationInput(landedSha, provider, modelId, systemPrompt, userPrompt) {
|
|
270721
|
-
return
|
|
271412
|
+
return createHash36("sha256").update(Buffer.from(JSON.stringify(["mission-validation-input-v1", landedSha, provider, modelId, systemPrompt, userPrompt]), "utf8")).digest("hex");
|
|
270722
271413
|
}
|
|
270723
271414
|
var execAsync56, loopLog, VALIDATION_TIMEOUT_MS, MAX_VALIDATION_RESPONSE_BYTES, MAX_VALIDATION_JSON_CANDIDATES, VALIDATION_FAILURE_BUDGET_PER_FINGERPRINT, MissionExecutionLoop;
|
|
270724
271415
|
var init_mission_execution_loop = __esm({
|
|
@@ -270734,7 +271425,7 @@ var init_mission_execution_loop = __esm({
|
|
|
270734
271425
|
init_fallback_model_observer();
|
|
270735
271426
|
init_mcp_resolution();
|
|
270736
271427
|
init_run_audit();
|
|
270737
|
-
execAsync56 =
|
|
271428
|
+
execAsync56 = promisify82(exec60);
|
|
270738
271429
|
loopLog = createLogger2("mission-loop");
|
|
270739
271430
|
VALIDATION_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
270740
271431
|
MAX_VALIDATION_RESPONSE_BYTES = 256 * 1024;
|
|
@@ -272248,44 +272939,9 @@ ${taskContext}` : ""}`;
|
|
|
272248
272939
|
}
|
|
272249
272940
|
});
|
|
272250
272941
|
|
|
272251
|
-
// ../engine/src/merge/merge-content-capture.ts
|
|
272252
|
-
async function captureMergeContentDescriptor(task, deps) {
|
|
272253
|
-
if (describeMergeContentShape(task) === "workspace") {
|
|
272254
|
-
try {
|
|
272255
|
-
const evidence = await captureWorkspaceReviewEvidence({
|
|
272256
|
-
task,
|
|
272257
|
-
workspaceRootDir: deps.workspaceRootDir,
|
|
272258
|
-
settings: deps.settings
|
|
272259
|
-
});
|
|
272260
|
-
return {
|
|
272261
|
-
kind: "workspace",
|
|
272262
|
-
repositories: {
|
|
272263
|
-
state: "captured",
|
|
272264
|
-
fingerprints: Object.fromEntries(evidence.repositories.filter((repository) => repository.fingerprint).map((repository) => [repository.repository, repository.fingerprint])),
|
|
272265
|
-
inScopeModified: [...evidence.modifiedRepositories].sort()
|
|
272266
|
-
}
|
|
272267
|
-
};
|
|
272268
|
-
} catch {
|
|
272269
|
-
return { kind: "workspace", repositories: { state: "unavailable", reason: "workspace-evidence-capture-failed" } };
|
|
272270
|
-
}
|
|
272271
|
-
}
|
|
272272
|
-
const baseRef = task.worktree ? await resolveDiffBaseRef(task.worktree, task.baseCommitSha) : void 0;
|
|
272273
|
-
const probe = await probeReviewDiffFingerprint(task.worktree, baseRef);
|
|
272274
|
-
return { kind: "singular", diff: probe };
|
|
272275
|
-
}
|
|
272276
|
-
var init_merge_content_capture = __esm({
|
|
272277
|
-
"../engine/src/merge/merge-content-capture.ts"() {
|
|
272278
|
-
"use strict";
|
|
272279
|
-
init_src2();
|
|
272280
|
-
init_worktree_git_refs();
|
|
272281
|
-
init_review_diff_fingerprint();
|
|
272282
|
-
init_workspace_review_evidence();
|
|
272283
|
-
}
|
|
272284
|
-
});
|
|
272285
|
-
|
|
272286
272942
|
// ../engine/src/merge/merger-ai-squash-gates.ts
|
|
272287
|
-
import { execFile as
|
|
272288
|
-
import { promisify as
|
|
272943
|
+
import { execFile as execFile34 } from "node:child_process";
|
|
272944
|
+
import { promisify as promisify83 } from "node:util";
|
|
272289
272945
|
function resolveRepoDeclaredScopeTransform({ repoRel, repoKeys }) {
|
|
272290
272946
|
return {
|
|
272291
272947
|
transform(scope) {
|
|
@@ -272316,8 +272972,8 @@ async function enforceAiMergeSquashGates(params) {
|
|
|
272316
272972
|
});
|
|
272317
272973
|
} catch (error3) {
|
|
272318
272974
|
if (!(error3 instanceof FileScopeViolationError)) throw error3;
|
|
272319
|
-
await
|
|
272320
|
-
await
|
|
272975
|
+
await execFileAsync28("git", ["reset", "--hard", params.tipSha], { cwd: params.mergeRoot });
|
|
272976
|
+
await execFileAsync28("git", ["clean", "-fd"], { cwd: params.mergeRoot });
|
|
272321
272977
|
try {
|
|
272322
272978
|
await params.store.updateTask(params.taskId, { aiMergeReviewReconciliation: null });
|
|
272323
272979
|
} catch {
|
|
@@ -272325,13 +272981,13 @@ async function enforceAiMergeSquashGates(params) {
|
|
|
272325
272981
|
throw error3;
|
|
272326
272982
|
}
|
|
272327
272983
|
}
|
|
272328
|
-
var
|
|
272984
|
+
var execFileAsync28;
|
|
272329
272985
|
var init_merger_ai_squash_gates = __esm({
|
|
272330
272986
|
"../engine/src/merge/merger-ai-squash-gates.ts"() {
|
|
272331
272987
|
"use strict";
|
|
272332
272988
|
init_workspace_paths();
|
|
272333
272989
|
init_merger_file_scope();
|
|
272334
|
-
|
|
272990
|
+
execFileAsync28 = promisify83(execFile34);
|
|
272335
272991
|
}
|
|
272336
272992
|
});
|
|
272337
272993
|
|
|
@@ -272831,11 +273487,11 @@ var init_workspace_merge_readiness = __esm({
|
|
|
272831
273487
|
});
|
|
272832
273488
|
|
|
272833
273489
|
// ../engine/src/merge/workspace-fence-ref.ts
|
|
272834
|
-
import { execFile as
|
|
272835
|
-
import { createHash as
|
|
272836
|
-
import { promisify as
|
|
273490
|
+
import { execFile as execFile35 } from "node:child_process";
|
|
273491
|
+
import { createHash as createHash37 } from "node:crypto";
|
|
273492
|
+
import { promisify as promisify84 } from "node:util";
|
|
272837
273493
|
async function git6(args, cwd) {
|
|
272838
|
-
const { stdout } = await
|
|
273494
|
+
const { stdout } = await execFileAsync29("git", args, {
|
|
272839
273495
|
cwd,
|
|
272840
273496
|
encoding: "utf8",
|
|
272841
273497
|
maxBuffer: 1024 * 1024
|
|
@@ -272848,7 +273504,7 @@ async function remoteRefSha(remote, ref, cwd) {
|
|
|
272848
273504
|
return /^[0-9a-f]{40,64}$/i.test(sha ?? "") ? sha : void 0;
|
|
272849
273505
|
}
|
|
272850
273506
|
function workspaceLandFenceRef(repoRelPath) {
|
|
272851
|
-
const slug2 =
|
|
273507
|
+
const slug2 = createHash37("sha256").update(repoRelPath).digest("hex").slice(0, 24);
|
|
272852
273508
|
return `refs/fusion/workspace-lease/${slug2}`;
|
|
272853
273509
|
}
|
|
272854
273510
|
function mergeDispatchFenceRef(taskId) {
|
|
@@ -272857,7 +273513,7 @@ function mergeDispatchFenceRef(taskId) {
|
|
|
272857
273513
|
async function createFenceObject(cwd, handle2) {
|
|
272858
273514
|
const tree = await git6(["hash-object", "-w", "-t", "tree", "/dev/null"], cwd);
|
|
272859
273515
|
const message = `workspace lease ${handle2.leaseKey} ${handle2.owner.taskId} ${handle2.owner.nodeId} ${handle2.owner.incarnationId} ${handle2.fenceToken}`;
|
|
272860
|
-
const { stdout } = await
|
|
273516
|
+
const { stdout } = await execFileAsync29("git", [
|
|
272861
273517
|
"-c",
|
|
272862
273518
|
"user.name=Fusion",
|
|
272863
273519
|
"-c",
|
|
@@ -272987,11 +273643,11 @@ async function publishWorkspaceIntegrationRef(input) {
|
|
|
272987
273643
|
await pushWithWorkspaceFence({ ...input, expectedTargetSha: observedTargetSha });
|
|
272988
273644
|
return { republishedFromObservedTip: true, observedTargetSha };
|
|
272989
273645
|
}
|
|
272990
|
-
var
|
|
273646
|
+
var execFileAsync29, WorkspaceFenceRefError;
|
|
272991
273647
|
var init_workspace_fence_ref = __esm({
|
|
272992
273648
|
"../engine/src/merge/workspace-fence-ref.ts"() {
|
|
272993
273649
|
"use strict";
|
|
272994
|
-
|
|
273650
|
+
execFileAsync29 = promisify84(execFile35);
|
|
272995
273651
|
WorkspaceFenceRefError = class extends Error {
|
|
272996
273652
|
constructor(message, kind) {
|
|
272997
273653
|
super(message);
|
|
@@ -273003,10 +273659,10 @@ var init_workspace_fence_ref = __esm({
|
|
|
273003
273659
|
});
|
|
273004
273660
|
|
|
273005
273661
|
// ../engine/src/merge/workspace-integration-target.ts
|
|
273006
|
-
import { execFile as
|
|
273007
|
-
import { promisify as
|
|
273662
|
+
import { execFile as execFile36 } from "node:child_process";
|
|
273663
|
+
import { promisify as promisify85 } from "node:util";
|
|
273008
273664
|
async function git7(args, cwd) {
|
|
273009
|
-
const { stdout } = await
|
|
273665
|
+
const { stdout } = await execFileAsync30("git", args, { cwd, encoding: "utf8" });
|
|
273010
273666
|
return stdout.trim();
|
|
273011
273667
|
}
|
|
273012
273668
|
async function resolveWorkspaceIntegrationTarget(input) {
|
|
@@ -273046,11 +273702,11 @@ async function resolveWorkspaceIntegrationTarget(input) {
|
|
|
273046
273702
|
`Workspace repository ${input.repository} has ambiguous integration remotes: ${remotes.join(", ")}`
|
|
273047
273703
|
);
|
|
273048
273704
|
}
|
|
273049
|
-
var
|
|
273705
|
+
var execFileAsync30, WorkspaceEnvironmentError, WorkspaceIntegrationTargetError;
|
|
273050
273706
|
var init_workspace_integration_target = __esm({
|
|
273051
273707
|
"../engine/src/merge/workspace-integration-target.ts"() {
|
|
273052
273708
|
"use strict";
|
|
273053
|
-
|
|
273709
|
+
execFileAsync30 = promisify85(execFile36);
|
|
273054
273710
|
WorkspaceEnvironmentError = class extends Error {
|
|
273055
273711
|
constructor(repository, resource, action, message) {
|
|
273056
273712
|
super(message);
|
|
@@ -273073,14 +273729,14 @@ var init_workspace_integration_target = __esm({
|
|
|
273073
273729
|
});
|
|
273074
273730
|
|
|
273075
273731
|
// ../engine/src/merge/merger-ai-worktree.ts
|
|
273076
|
-
import { execFile as
|
|
273732
|
+
import { execFile as execFile37 } from "node:child_process";
|
|
273077
273733
|
import { appendFileSync as appendFileSync2, existsSync as existsSync84, mkdirSync as mkdirSync10, readdirSync as readdirSync12, readFileSync as readFileSync26, realpathSync as realpathSync14, rmSync as rmSync7, statSync as statSync16 } from "node:fs";
|
|
273078
273734
|
import { rm as rm17 } from "node:fs/promises";
|
|
273079
273735
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
273080
273736
|
import { isAbsolute as isAbsolute25, join as join95, relative as relative22 } from "node:path";
|
|
273081
|
-
import { promisify as
|
|
273737
|
+
import { promisify as promisify86 } from "node:util";
|
|
273082
273738
|
async function git8(args, cwd, opts = {}) {
|
|
273083
|
-
const { stdout } = await
|
|
273739
|
+
const { stdout } = await execFileAsync31("git", args, {
|
|
273084
273740
|
cwd,
|
|
273085
273741
|
encoding: "utf-8",
|
|
273086
273742
|
timeout: opts.timeout ?? 12e4,
|
|
@@ -273109,14 +273765,7 @@ function ensureAiMergeRootIgnored(projectRootDir, settings) {
|
|
|
273109
273765
|
if (!existsSync84(excludePath)) return;
|
|
273110
273766
|
try {
|
|
273111
273767
|
const current = readFileSync26(excludePath, "utf-8");
|
|
273112
|
-
const
|
|
273113
|
-
const legacyRelativeAiMergeRoot = relative22(projectRootDir, legacyAiMergeRoot);
|
|
273114
|
-
const entries = [`${legacyRelativeAiMergeRoot.replaceAll("\\", "/")}/`];
|
|
273115
|
-
const aiMergeRoot = resolveAiMergeRootPath(projectRootDir, settings);
|
|
273116
|
-
const relativeAiMergeRoot = relative22(projectRootDir, aiMergeRoot);
|
|
273117
|
-
if (relativeAiMergeRoot && !relativeAiMergeRoot.startsWith("..") && !isAbsolute25(relativeAiMergeRoot)) {
|
|
273118
|
-
entries.push(`${relativeAiMergeRoot.replaceAll("\\", "/")}/`);
|
|
273119
|
-
}
|
|
273768
|
+
const entries = resolveAiMergeSearchRoots(projectRootDir, settings).map((root) => relative22(projectRootDir, root)).filter((root) => root && !root.startsWith("..") && !isAbsolute25(root)).map((root) => `${root.replaceAll("\\", "/")}/`);
|
|
273120
273769
|
const missing = entries.filter((entry) => !current.split(/\r?\n/).includes(entry));
|
|
273121
273770
|
if (missing.length > 0) {
|
|
273122
273771
|
appendFileSync2(excludePath, `${current.endsWith("\n") ? "" : "\n"}${missing.join("\n")}
|
|
@@ -273132,7 +273781,7 @@ function resolveAiMergeRoot(projectRootDir, settings) {
|
|
|
273132
273781
|
return root;
|
|
273133
273782
|
}
|
|
273134
273783
|
function getAiMergeTempSearchRoots(projectRootDir, settings) {
|
|
273135
|
-
const roots = [resolveAiMergeRoot(projectRootDir, settings),
|
|
273784
|
+
const roots = [resolveAiMergeRoot(projectRootDir, settings), ...resolveAiMergeSearchRoots(projectRootDir, settings), tmpdir11()];
|
|
273136
273785
|
const testWorkerRoot = process.env.FUSION_TEST_WORKER_ROOT;
|
|
273137
273786
|
if (testWorkerRoot) {
|
|
273138
273787
|
try {
|
|
@@ -273185,7 +273834,7 @@ async function pruneExistingAiMergeWorktrees(taskId, projectRootDir, audit, log4
|
|
|
273185
273834
|
let alreadyAbsent = false;
|
|
273186
273835
|
try {
|
|
273187
273836
|
cleanupAttempted = true;
|
|
273188
|
-
await
|
|
273837
|
+
await execFileAsync31("git", ["worktree", "remove", "--force", canonicalPath], {
|
|
273189
273838
|
cwd: projectRootDir,
|
|
273190
273839
|
timeout: 3e4
|
|
273191
273840
|
});
|
|
@@ -273216,7 +273865,7 @@ async function pruneExistingAiMergeWorktrees(taskId, projectRootDir, audit, log4
|
|
|
273216
273865
|
}
|
|
273217
273866
|
if (cleanupAttempted) {
|
|
273218
273867
|
try {
|
|
273219
|
-
await
|
|
273868
|
+
await execFileAsync31("git", ["worktree", "prune"], { cwd: projectRootDir, timeout: 3e4 });
|
|
273220
273869
|
} catch (err) {
|
|
273221
273870
|
await log42(`AI merge pre-merge prune: git worktree prune failed: ${describeCleanupError(err)}`);
|
|
273222
273871
|
}
|
|
@@ -273282,7 +273931,7 @@ async function cleanupAiMergeWorktree(input) {
|
|
|
273282
273931
|
await audit.git({ type: "merge:ai-worktree-cleanup", target: canonicalRoot, metadata: { ...cleanupMetadata, phase: "git-prune", success: false, error: error3, ...code ? { code } : {} } });
|
|
273283
273932
|
}
|
|
273284
273933
|
}
|
|
273285
|
-
var
|
|
273934
|
+
var execFileAsync31;
|
|
273286
273935
|
var init_merger_ai_worktree = __esm({
|
|
273287
273936
|
"../engine/src/merge/merger-ai-worktree.ts"() {
|
|
273288
273937
|
"use strict";
|
|
@@ -273290,7 +273939,7 @@ var init_merger_ai_worktree = __esm({
|
|
|
273290
273939
|
init_self_healing();
|
|
273291
273940
|
init_worktree_paths();
|
|
273292
273941
|
init_worktree_removal_retry();
|
|
273293
|
-
|
|
273942
|
+
execFileAsync31 = promisify86(execFile37);
|
|
273294
273943
|
}
|
|
273295
273944
|
});
|
|
273296
273945
|
|
|
@@ -273642,8 +274291,8 @@ var init_merger_ai_prompts = __esm({
|
|
|
273642
274291
|
});
|
|
273643
274292
|
|
|
273644
274293
|
// ../engine/src/merge/merger-ai.ts
|
|
273645
|
-
import { execFile as
|
|
273646
|
-
import { promisify as
|
|
274294
|
+
import { execFile as execFile38 } from "node:child_process";
|
|
274295
|
+
import { promisify as promisify87 } from "node:util";
|
|
273647
274296
|
import { realpathSync as realpathSync15, readdirSync as readdirSync13 } from "node:fs";
|
|
273648
274297
|
import { mkdtemp as mkdtemp5 } from "node:fs/promises";
|
|
273649
274298
|
import { tmpdir as tmpdir12 } from "node:os";
|
|
@@ -273671,7 +274320,7 @@ function writeTransientMergeStatus(store, taskId, signal, status) {
|
|
|
273671
274320
|
return fence.write("lifecycle", () => store.updateTask(taskId, { status }).catch(() => void 0));
|
|
273672
274321
|
}
|
|
273673
274322
|
async function git9(args, cwd, opts = {}) {
|
|
273674
|
-
const { stdout } = await
|
|
274323
|
+
const { stdout } = await execFileAsync32("git", args, {
|
|
273675
274324
|
cwd,
|
|
273676
274325
|
encoding: "utf-8",
|
|
273677
274326
|
timeout: opts.timeout ?? 12e4,
|
|
@@ -273711,7 +274360,7 @@ function boundBlockingReviewReasons(reasons) {
|
|
|
273711
274360
|
}
|
|
273712
274361
|
function listAiMergeWorktreeCandidates(taskId, projectRootDir, settings) {
|
|
273713
274362
|
const prefix = `fusion-ai-merge-${taskId.toLowerCase()}-`;
|
|
273714
|
-
const roots = Array.from(/* @__PURE__ */ new Set([resolveAiMergeRoot(projectRootDir, settings),
|
|
274363
|
+
const roots = Array.from(/* @__PURE__ */ new Set([resolveAiMergeRoot(projectRootDir, settings), ...resolveAiMergeSearchRoots(projectRootDir, settings), tmpdir12()]));
|
|
273715
274364
|
const testWorkerRoot = process.env.FUSION_TEST_WORKER_ROOT;
|
|
273716
274365
|
if (testWorkerRoot) {
|
|
273717
274366
|
try {
|
|
@@ -276060,7 +276709,7 @@ async function finalizeTask(store, taskId, result2, audit, log42, rootDir, fence
|
|
|
276060
276709
|
function throwIfAborted3(signal, taskId) {
|
|
276061
276710
|
assertMergeGenerationOwned(signal, taskId);
|
|
276062
276711
|
}
|
|
276063
|
-
var
|
|
276712
|
+
var execFileAsync32, aiMergeLog, MAX_CONCURRENT_ADVANCE_RETRIES, MAX_BLOCKING_REVIEW_REASONS, AiMergeBlockedError, AiMergeReviewReconciliationInvalidatedError, LEGACY_COMPLETE_COLUMN, LEGACY_ARCHIVED_COLUMN, LEGACY_TERMINAL_COLUMNS3, LEGACY_REBOUND_COLUMN2, STRONG_LANDED_STRATEGIES, RecordedMergeBranchTipChangedError, WORKSPACE_REPO_LAND_OWNER_KEY, WorkspaceRepoLandBusyError, WorkspaceMergeTechnicalError, WorkspacePartialLandError, WorkspaceFinalizeBlockedError, WorkspaceReviewRequiredError, WorkspaceMergeDispatchSupersededError;
|
|
276064
276713
|
var init_merger_ai = __esm({
|
|
276065
276714
|
"../engine/src/merge/merger-ai.ts"() {
|
|
276066
276715
|
"use strict";
|
|
@@ -276110,7 +276759,7 @@ var init_merger_ai = __esm({
|
|
|
276110
276759
|
init_merger_ai_prompts();
|
|
276111
276760
|
init_merger_ai_worktree();
|
|
276112
276761
|
init_merger_ai_prompts();
|
|
276113
|
-
|
|
276762
|
+
execFileAsync32 = promisify87(execFile38);
|
|
276114
276763
|
aiMergeLog = createLogger2("merger-ai");
|
|
276115
276764
|
MAX_CONCURRENT_ADVANCE_RETRIES = 3;
|
|
276116
276765
|
MAX_BLOCKING_REVIEW_REASONS = 8;
|
|
@@ -276262,7 +276911,7 @@ var init_workspace_merge_dispatch_lease = __esm({
|
|
|
276262
276911
|
// ../engine/src/execution/task-revert.ts
|
|
276263
276912
|
import { exec as exec61 } from "node:child_process";
|
|
276264
276913
|
import { join as join97 } from "node:path";
|
|
276265
|
-
import { promisify as
|
|
276914
|
+
import { promisify as promisify88 } from "node:util";
|
|
276266
276915
|
function quoteShellArg9(value) {
|
|
276267
276916
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
276268
276917
|
}
|
|
@@ -277131,7 +277780,7 @@ var init_task_revert = __esm({
|
|
|
277131
277780
|
init_branch_attribution();
|
|
277132
277781
|
init_workspace_base_branch();
|
|
277133
277782
|
init_run_audit();
|
|
277134
|
-
defaultExecAsync2 =
|
|
277783
|
+
defaultExecAsync2 = promisify88(exec61);
|
|
277135
277784
|
GIT_TIMEOUT_MS9 = 3e4;
|
|
277136
277785
|
GIT_MAX_BUFFER7 = 10 * 1024 * 1024;
|
|
277137
277786
|
TaskRevertError = class extends Error {
|
|
@@ -277150,10 +277799,10 @@ var init_task_revert = __esm({
|
|
|
277150
277799
|
});
|
|
277151
277800
|
|
|
277152
277801
|
// ../engine/src/merge/smart-pull.ts
|
|
277153
|
-
import { execFile as
|
|
277154
|
-
import { promisify as
|
|
277802
|
+
import { execFile as execFile39 } from "node:child_process";
|
|
277803
|
+
import { promisify as promisify89 } from "node:util";
|
|
277155
277804
|
async function runGit8(args, cwd, timeoutMs) {
|
|
277156
|
-
const result2 = await
|
|
277805
|
+
const result2 = await execFileAsync33("git", args, {
|
|
277157
277806
|
cwd,
|
|
277158
277807
|
timeout: timeoutMs,
|
|
277159
277808
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -277304,11 +277953,11 @@ async function smartPull(input) {
|
|
|
277304
277953
|
return { kind: "stash-pop-conflict", fromSha, toSha, stashSha, stashLabel, conflictedFiles };
|
|
277305
277954
|
}
|
|
277306
277955
|
}
|
|
277307
|
-
var
|
|
277956
|
+
var execFileAsync33;
|
|
277308
277957
|
var init_smart_pull = __esm({
|
|
277309
277958
|
"../engine/src/merge/smart-pull.ts"() {
|
|
277310
277959
|
"use strict";
|
|
277311
|
-
|
|
277960
|
+
execFileAsync33 = promisify89(execFile39);
|
|
277312
277961
|
}
|
|
277313
277962
|
});
|
|
277314
277963
|
|
|
@@ -278954,7 +279603,7 @@ var init_finalize_types = __esm({
|
|
|
278954
279603
|
|
|
278955
279604
|
// ../engine/src/experiment/git-ops.ts
|
|
278956
279605
|
import { exec as exec62 } from "node:child_process";
|
|
278957
|
-
import { promisify as
|
|
279606
|
+
import { promisify as promisify90 } from "node:util";
|
|
278958
279607
|
async function runGit9(cwd, args) {
|
|
278959
279608
|
const command = `git ${args.join(" ")}`;
|
|
278960
279609
|
try {
|
|
@@ -279061,7 +279710,7 @@ var init_git_ops = __esm({
|
|
|
279061
279710
|
"use strict";
|
|
279062
279711
|
init_git_identity();
|
|
279063
279712
|
init_finalize_types();
|
|
279064
|
-
execAsync57 =
|
|
279713
|
+
execAsync57 = promisify90(exec62);
|
|
279065
279714
|
GIT_TIMEOUT_MS10 = 3e4;
|
|
279066
279715
|
GIT_MAX_BUFFER8 = 10 * 1024 * 1024;
|
|
279067
279716
|
}
|
|
@@ -283685,9 +284334,9 @@ var init_routine_scheduler = __esm({
|
|
|
283685
284334
|
});
|
|
283686
284335
|
|
|
283687
284336
|
// ../engine/src/healing/stuck-task-detector.ts
|
|
283688
|
-
import { createHash as
|
|
284337
|
+
import { createHash as createHash38 } from "node:crypto";
|
|
283689
284338
|
function hashToolDetail(detail) {
|
|
283690
|
-
return
|
|
284339
|
+
return createHash38("sha256").update(detail).digest("hex").slice(0, TOOL_DETAIL_HASH_HEX_LEN);
|
|
283691
284340
|
}
|
|
283692
284341
|
function buildToolFingerprint(toolName, toolDetail) {
|
|
283693
284342
|
const name2 = toolName.trim().toLowerCase() || "tool";
|
|
@@ -286963,11 +287612,11 @@ var init_adapters = __esm({
|
|
|
286963
287612
|
|
|
286964
287613
|
// ../engine/src/cli-agent/resume-coordinator.ts
|
|
286965
287614
|
import { existsSync as existsSync87 } from "node:fs";
|
|
286966
|
-
import { execFile as
|
|
286967
|
-
import { promisify as
|
|
287615
|
+
import { execFile as execFile40 } from "node:child_process";
|
|
287616
|
+
import { promisify as promisify91 } from "node:util";
|
|
286968
287617
|
async function defaultIsWorktreeDirty(worktreePath) {
|
|
286969
287618
|
try {
|
|
286970
|
-
const { stdout } = await
|
|
287619
|
+
const { stdout } = await execFileAsync34("git", ["status", "--porcelain"], {
|
|
286971
287620
|
cwd: worktreePath
|
|
286972
287621
|
});
|
|
286973
287622
|
return stdout.trim().length > 0;
|
|
@@ -286975,13 +287624,13 @@ async function defaultIsWorktreeDirty(worktreePath) {
|
|
|
286975
287624
|
return false;
|
|
286976
287625
|
}
|
|
286977
287626
|
}
|
|
286978
|
-
var
|
|
287627
|
+
var execFileAsync34, ORPHANED_LIVE_STATES, DEFAULT_MAX_RESUME_ATTEMPTS, DEFAULT_RESUME_BACKOFF_BASE_MS, CliResumeCoordinator;
|
|
286979
287628
|
var init_resume_coordinator = __esm({
|
|
286980
287629
|
"../engine/src/cli-agent/resume-coordinator.ts"() {
|
|
286981
287630
|
"use strict";
|
|
286982
287631
|
init_session_manager();
|
|
286983
287632
|
init_state_machine();
|
|
286984
|
-
|
|
287633
|
+
execFileAsync34 = promisify91(execFile40);
|
|
286985
287634
|
ORPHANED_LIVE_STATES = /* @__PURE__ */ new Set([
|
|
286986
287635
|
"starting",
|
|
286987
287636
|
"ready",
|
|
@@ -287268,7 +287917,7 @@ var init_node_dispatch_validation = __esm({
|
|
|
287268
287917
|
});
|
|
287269
287918
|
|
|
287270
287919
|
// ../engine/src/runtimes/in-process-runtime.ts
|
|
287271
|
-
import { createHash as
|
|
287920
|
+
import { createHash as createHash39 } from "node:crypto";
|
|
287272
287921
|
import { EventEmitter as EventEmitter26 } from "node:events";
|
|
287273
287922
|
import { setImmediate as setImmediateCb4 } from "node:timers";
|
|
287274
287923
|
function createDiscoveryPluginLoaderOptions(scopedStore) {
|
|
@@ -287533,7 +288182,7 @@ function stableNotificationJson(value) {
|
|
|
287533
288182
|
return `{${fields.join(",")}}`;
|
|
287534
288183
|
}
|
|
287535
288184
|
function buildCliAgentNotificationDedupeKey(input) {
|
|
287536
|
-
const notificationFingerprint =
|
|
288185
|
+
const notificationFingerprint = createHash39("sha256").update(stableNotificationJson(input.info.notification ?? null)).digest("hex").slice(0, 16);
|
|
287537
288186
|
const waitingEpoch = input.session?.updatedAt ?? "unknown-waiting-epoch";
|
|
287538
288187
|
return [
|
|
287539
288188
|
"cli-agent",
|
|
@@ -291614,8 +292263,8 @@ var init_provider_adapters = __esm({
|
|
|
291614
292263
|
|
|
291615
292264
|
// ../engine/src/remote-access/tunnel-process-manager.ts
|
|
291616
292265
|
import { EventEmitter as EventEmitter31 } from "node:events";
|
|
291617
|
-
import { exec as exec64, execFile as
|
|
291618
|
-
import { promisify as
|
|
292266
|
+
import { exec as exec64, execFile as execFile41, spawn as spawn9 } from "node:child_process";
|
|
292267
|
+
import { promisify as promisify92 } from "node:util";
|
|
291619
292268
|
function serveConfigScopes(config3) {
|
|
291620
292269
|
const foreground = Object.values(config3.Foreground ?? {}).filter(
|
|
291621
292270
|
(scope) => Boolean(scope)
|
|
@@ -291661,7 +292310,7 @@ function toStateError(code, err) {
|
|
|
291661
292310
|
at: nowIso2()
|
|
291662
292311
|
};
|
|
291663
292312
|
}
|
|
291664
|
-
var DEFAULT_MAX_LOG_ENTRIES, DEFAULT_STOP_TIMEOUT_MS2, DEFAULT_RESTART_BASE_DELAY_MS, DEFAULT_RESTART_MAX_DELAY_MS,
|
|
292313
|
+
var DEFAULT_MAX_LOG_ENTRIES, DEFAULT_STOP_TIMEOUT_MS2, DEFAULT_RESTART_BASE_DELAY_MS, DEFAULT_RESTART_MAX_DELAY_MS, execFileAsync35, execAsync58, LineBuffer, TunnelProcessManager;
|
|
291665
292314
|
var init_tunnel_process_manager = __esm({
|
|
291666
292315
|
"../engine/src/remote-access/tunnel-process-manager.ts"() {
|
|
291667
292316
|
"use strict";
|
|
@@ -291672,8 +292321,8 @@ var init_tunnel_process_manager = __esm({
|
|
|
291672
292321
|
DEFAULT_STOP_TIMEOUT_MS2 = 5e3;
|
|
291673
292322
|
DEFAULT_RESTART_BASE_DELAY_MS = 1e3;
|
|
291674
292323
|
DEFAULT_RESTART_MAX_DELAY_MS = 3e4;
|
|
291675
|
-
|
|
291676
|
-
execAsync58 =
|
|
292324
|
+
execFileAsync35 = promisify92(execFile41);
|
|
292325
|
+
execAsync58 = promisify92(exec64);
|
|
291677
292326
|
LineBuffer = class {
|
|
291678
292327
|
pending = "";
|
|
291679
292328
|
push(chunk) {
|
|
@@ -291778,7 +292427,7 @@ var init_tunnel_process_manager = __esm({
|
|
|
291778
292427
|
return null;
|
|
291779
292428
|
}
|
|
291780
292429
|
try {
|
|
291781
|
-
const { stdout } = await
|
|
292430
|
+
const { stdout } = await execFileAsync35("tailscale", ["status", "--json"], { timeout: 3e3 });
|
|
291782
292431
|
const data = JSON.parse(String(stdout));
|
|
291783
292432
|
const dnsName = data.Self?.DNSName?.replace(/\.$/, "");
|
|
291784
292433
|
if (!dnsName) {
|
|
@@ -291801,7 +292450,7 @@ var init_tunnel_process_manager = __esm({
|
|
|
291801
292450
|
];
|
|
291802
292451
|
for (const resetCommand of resetCommands) {
|
|
291803
292452
|
try {
|
|
291804
|
-
await
|
|
292453
|
+
await execFileAsync35(resetCommand.command, resetCommand.args, { timeout: 5e3 });
|
|
291805
292454
|
return;
|
|
291806
292455
|
} catch {
|
|
291807
292456
|
}
|
|
@@ -291907,7 +292556,7 @@ var init_tunnel_process_manager = __esm({
|
|
|
291907
292556
|
async detectActiveFunnel() {
|
|
291908
292557
|
let stdout = "";
|
|
291909
292558
|
try {
|
|
291910
|
-
const result2 = await
|
|
292559
|
+
const result2 = await execFileAsync35("tailscale", ["serve", "status", "--json"], { timeout: 5e3 });
|
|
291911
292560
|
stdout = String(result2.stdout ?? "");
|
|
291912
292561
|
} catch (error3) {
|
|
291913
292562
|
const failure = error3;
|
|
@@ -292325,8 +292974,8 @@ var init_tunnel_process_manager = __esm({
|
|
|
292325
292974
|
});
|
|
292326
292975
|
|
|
292327
292976
|
// ../engine/src/remote-access/remote-tunnel-service.ts
|
|
292328
|
-
import { execFile as
|
|
292329
|
-
import { promisify as
|
|
292977
|
+
import { execFile as execFile42 } from "node:child_process";
|
|
292978
|
+
import { promisify as promisify93 } from "node:util";
|
|
292330
292979
|
function remoteTunnelScopeKey(input) {
|
|
292331
292980
|
const projectId2 = input.projectId?.trim();
|
|
292332
292981
|
if (projectId2) return `project:${projectId2}`;
|
|
@@ -292369,14 +293018,14 @@ async function shutdownAllRemoteTunnels() {
|
|
|
292369
293018
|
function __resetRemoteTunnelServicesForTests() {
|
|
292370
293019
|
remoteTunnelServices.clear();
|
|
292371
293020
|
}
|
|
292372
|
-
var
|
|
293021
|
+
var execFileAsync36, isRemoteActive, RemoteTunnelService, remoteTunnelServices;
|
|
292373
293022
|
var init_remote_tunnel_service = __esm({
|
|
292374
293023
|
"../engine/src/remote-access/remote-tunnel-service.ts"() {
|
|
292375
293024
|
"use strict";
|
|
292376
293025
|
init_logger3();
|
|
292377
293026
|
init_local_dashboard_port();
|
|
292378
293027
|
init_tunnel_process_manager();
|
|
292379
|
-
|
|
293028
|
+
execFileAsync36 = promisify93(execFile42);
|
|
292380
293029
|
isRemoteActive = (ra) => ra?.activeProvider != null && (ra.providers[ra.activeProvider]?.enabled ?? false);
|
|
292381
293030
|
RemoteTunnelService = class {
|
|
292382
293031
|
manager = new TunnelProcessManager();
|
|
@@ -292725,7 +293374,7 @@ var init_remote_tunnel_service = __esm({
|
|
|
292725
293374
|
async checkTailscaleDaemonReady() {
|
|
292726
293375
|
let stdout = "";
|
|
292727
293376
|
try {
|
|
292728
|
-
const result2 = await
|
|
293377
|
+
const result2 = await execFileAsync36("tailscale", ["status", "--json"], {
|
|
292729
293378
|
timeout: 5e3,
|
|
292730
293379
|
maxBuffer: 8 * 1024 * 1024
|
|
292731
293380
|
});
|
|
@@ -292773,7 +293422,7 @@ var init_remote_tunnel_service = __esm({
|
|
|
292773
293422
|
async checkExecutableAvailable(command) {
|
|
292774
293423
|
const checker = process.platform === "win32" ? "where" : "which";
|
|
292775
293424
|
try {
|
|
292776
|
-
await
|
|
293425
|
+
await execFileAsync36(checker, [command]);
|
|
292777
293426
|
return { available: true };
|
|
292778
293427
|
} catch {
|
|
292779
293428
|
return {
|
|
@@ -292788,8 +293437,8 @@ var init_remote_tunnel_service = __esm({
|
|
|
292788
293437
|
});
|
|
292789
293438
|
|
|
292790
293439
|
// ../engine/src/project-engine.ts
|
|
292791
|
-
import { execFile as
|
|
292792
|
-
import { promisify as
|
|
293440
|
+
import { execFile as execFile43 } from "node:child_process";
|
|
293441
|
+
import { promisify as promisify94 } from "node:util";
|
|
292793
293442
|
function emitMergeRequestShadowDequeueParityAudit(store, legacyTaskId, shadowTaskId) {
|
|
292794
293443
|
const agree = shadowTaskId === legacyTaskId;
|
|
292795
293444
|
void emitBoundedRunAudit2(store, {
|
|
@@ -292844,7 +293493,7 @@ async function verifyMergeConfirmedReachability(args) {
|
|
|
292844
293493
|
return { reachable: true, skipped: "no-integration-branch" };
|
|
292845
293494
|
}
|
|
292846
293495
|
try {
|
|
292847
|
-
await
|
|
293496
|
+
await execFileAsync37("git", ["cat-file", "-e", `${commitSha}^{commit}`], {
|
|
292848
293497
|
cwd,
|
|
292849
293498
|
timeout: 1e4
|
|
292850
293499
|
});
|
|
@@ -292853,7 +293502,7 @@ async function verifyMergeConfirmedReachability(args) {
|
|
|
292853
293502
|
return { reachable: false, reason: "commit-missing", diagnostic };
|
|
292854
293503
|
}
|
|
292855
293504
|
try {
|
|
292856
|
-
await
|
|
293505
|
+
await execFileAsync37(
|
|
292857
293506
|
"git",
|
|
292858
293507
|
["merge-base", "--is-ancestor", commitSha, `refs/heads/${integrationBranch}`],
|
|
292859
293508
|
{ cwd, timeout: 1e4 }
|
|
@@ -292869,7 +293518,7 @@ async function verifyMergeConfirmedReachability(args) {
|
|
|
292869
293518
|
return { reachable: false, reason: "git-error", diagnostic };
|
|
292870
293519
|
}
|
|
292871
293520
|
}
|
|
292872
|
-
var WorkspaceMergeDispatchBusyError2,
|
|
293521
|
+
var WorkspaceMergeDispatchBusyError2, execFileAsync37, MERGE_HANDOFF_GRACE_MS, PR_MERGE_RETRY_BACKOFF_BASE_MS, deterministicMergerModeDeprecationWarnedProjects, ProjectEngine;
|
|
292873
293522
|
var init_project_engine = __esm({
|
|
292874
293523
|
"../engine/src/project-engine.ts"() {
|
|
292875
293524
|
"use strict";
|
|
@@ -292902,6 +293551,7 @@ var init_project_engine = __esm({
|
|
|
292902
293551
|
init_merger_ai();
|
|
292903
293552
|
init_group_merge_coordinator();
|
|
292904
293553
|
init_workspace_review_reroute();
|
|
293554
|
+
init_stale_content_review_reroute();
|
|
292905
293555
|
init_workspace_integration_target();
|
|
292906
293556
|
init_concurrency();
|
|
292907
293557
|
init_merge_reclaim_policy();
|
|
@@ -292928,7 +293578,7 @@ var init_project_engine = __esm({
|
|
|
292928
293578
|
}
|
|
292929
293579
|
retryable = true;
|
|
292930
293580
|
};
|
|
292931
|
-
|
|
293581
|
+
execFileAsync37 = promisify94(execFile43);
|
|
292932
293582
|
MERGE_HANDOFF_GRACE_MS = 300;
|
|
292933
293583
|
PR_MERGE_RETRY_BACKOFF_BASE_MS = 5e3;
|
|
292934
293584
|
deterministicMergerModeDeprecationWarnedProjects = /* @__PURE__ */ new Set();
|
|
@@ -292992,6 +293642,7 @@ var init_project_engine = __esm({
|
|
|
292992
293642
|
}
|
|
292993
293643
|
});
|
|
292994
293644
|
}
|
|
293645
|
+
staleContentRerouteAuditKeys = /* @__PURE__ */ new Set();
|
|
292995
293646
|
runtime;
|
|
292996
293647
|
started = false;
|
|
292997
293648
|
specDriftReconciler;
|
|
@@ -294788,11 +295439,44 @@ ${detail}`);
|
|
|
294788
295439
|
workspaceRootDir: this.config.workingDirectory,
|
|
294789
295440
|
settings
|
|
294790
295441
|
});
|
|
294791
|
-
|
|
295442
|
+
const blocker = getTaskMergeBlocker(task, {
|
|
294792
295443
|
reviewColumns: mergeGate.reviewColumns.size > 0 ? mergeGate.reviewColumns : /* @__PURE__ */ new Set(["in-review"]),
|
|
294793
295444
|
requiredPreMergeStepIds: mergeGate.requiredPreMergeStepIds,
|
|
294794
295445
|
mergeContent
|
|
294795
295446
|
});
|
|
295447
|
+
if (blocker === "task has a pre-merge approval recorded against different content" && mergeContent.kind === "singular") {
|
|
295448
|
+
const reroute = await rerouteSingularStaleContentToReview(store, task, {
|
|
295449
|
+
requiredPreMergeStepIds: mergeGate.requiredPreMergeStepIds,
|
|
295450
|
+
mergeContent
|
|
295451
|
+
}).catch(() => ({
|
|
295452
|
+
rerouted: false,
|
|
295453
|
+
reason: "no-progress",
|
|
295454
|
+
nodeId: void 0,
|
|
295455
|
+
workflowStepId: void 0
|
|
295456
|
+
}));
|
|
295457
|
+
if (reroute.rerouted) {
|
|
295458
|
+
await store.logEntry(task.id, `[pre-merge] Code Review re-entry is owned by the workflow graph after stale content evidence was refused.`);
|
|
295459
|
+
}
|
|
295460
|
+
const auditKey = `${task.id}:${reroute.reason}`;
|
|
295461
|
+
if (!this.staleContentRerouteAuditKeys.has(auditKey)) {
|
|
295462
|
+
this.staleContentRerouteAuditKeys.add(auditKey);
|
|
295463
|
+
await emitBoundedRunAudit2(store, {
|
|
295464
|
+
taskId: task.id,
|
|
295465
|
+
agentId: "merge-gate",
|
|
295466
|
+
runId: `${task.id}:merge-gate`,
|
|
295467
|
+
domain: "database",
|
|
295468
|
+
mutationType: "task:merge-stale-content-review-rerouted",
|
|
295469
|
+
target: task.id,
|
|
295470
|
+
metadata: {
|
|
295471
|
+
taskId: task.id,
|
|
295472
|
+
nodeId: reroute.nodeId,
|
|
295473
|
+
workflowStepId: reroute.workflowStepId,
|
|
295474
|
+
reason: reroute.reason
|
|
295475
|
+
}
|
|
295476
|
+
});
|
|
295477
|
+
}
|
|
295478
|
+
}
|
|
295479
|
+
return blocker;
|
|
294796
295480
|
}
|
|
294797
295481
|
/**
|
|
294798
295482
|
* Remove and return the highest-priority taskId from the merge queue.
|
|
@@ -295638,7 +296322,7 @@ ${detail}`);
|
|
|
295638
296322
|
}
|
|
295639
296323
|
const checklist = planConfirmedMergeChecklistReconciliation(task);
|
|
295640
296324
|
if (checklist.skippedStepIndexes.length > 0 || checklist.reconciledWorkflowStepIds.length > 0) {
|
|
295641
|
-
const steps = task.steps.map((step, index2) => checklist.skippedStepIndexes.includes(index2) ? { ...step, status: "skipped" } : step);
|
|
296325
|
+
const steps = (task.steps ?? []).map((step, index2) => checklist.skippedStepIndexes.includes(index2) ? { ...step, status: "skipped" } : step);
|
|
295642
296326
|
const workflowStepResults = (task.workflowStepResults ?? []).map((result2) => checklist.reconciledWorkflowStepIds.includes(result2.workflowStepId) ? { ...result2, status: "skipped" } : result2);
|
|
295643
296327
|
await store.updateTask(taskId, { steps, workflowStepResults });
|
|
295644
296328
|
task.steps = steps;
|
|
@@ -297384,9 +298068,9 @@ import { access as access12, unlink as unlink12, writeFile as writeFile31 } from
|
|
|
297384
298068
|
import net2 from "node:net";
|
|
297385
298069
|
import { platform as platform3, tmpdir as tmpdir13 } from "node:os";
|
|
297386
298070
|
import { join as join100 } from "node:path";
|
|
297387
|
-
import { createHash as
|
|
298071
|
+
import { createHash as createHash40 } from "node:crypto";
|
|
297388
298072
|
function projectHash(projectId2) {
|
|
297389
|
-
return
|
|
298073
|
+
return createHash40("sha1").update(projectId2).digest("hex").slice(0, 16);
|
|
297390
298074
|
}
|
|
297391
298075
|
function computeEngineSocketPath(projectId2) {
|
|
297392
298076
|
const hash3 = projectHash(projectId2);
|
|
@@ -299004,8 +299688,8 @@ var init_remote_access = __esm({
|
|
|
299004
299688
|
});
|
|
299005
299689
|
|
|
299006
299690
|
// ../engine/src/healing/archive-worktree-disposer-install.ts
|
|
299007
|
-
import { execFile as
|
|
299008
|
-
import { promisify as
|
|
299691
|
+
import { execFile as execFile44 } from "node:child_process";
|
|
299692
|
+
import { promisify as promisify95 } from "node:util";
|
|
299009
299693
|
function installBaselineArchiveWorktreeDisposer(store, input) {
|
|
299010
299694
|
const allowLiveRemoval = input.allowLiveRemoval ?? (() => false);
|
|
299011
299695
|
const unregisterSingle = getArchiveWorktreeDisposer(store) ? () => {
|
|
@@ -299027,7 +299711,7 @@ function installBaselineArchiveWorktreeDisposer(store, input) {
|
|
|
299027
299711
|
try {
|
|
299028
299712
|
if (await canonicalizeWorktreePath(entry.worktreePath) === await canonicalizeWorktreePath(entry.repoRootDir)) throw new Error("Refusing to remove workspace repository root");
|
|
299029
299713
|
await removeWorktree({ worktreePath: entry.worktreePath, rootDir: entry.repoRootDir, settings: await input.getSettings(), taskId: task.id, reason: RemovalReason.ExecutorDispose, force: true });
|
|
299030
|
-
await
|
|
299714
|
+
await execFileAsync38("git", ["branch", "-D", entry.branch], { cwd: entry.repoRootDir, timeout: 12e4, maxBuffer: 10 * 1024 * 1024 });
|
|
299031
299715
|
if (task.workspaceWorktrees) for (const repoRel of [entry.repoRel, ...entry.aliasRepoRels]) delete task.workspaceWorktrees[repoRel];
|
|
299032
299716
|
removed.push(entry.repoRel);
|
|
299033
299717
|
} catch (error3) {
|
|
@@ -299041,13 +299725,13 @@ function installBaselineArchiveWorktreeDisposer(store, input) {
|
|
|
299041
299725
|
unregisterSingle();
|
|
299042
299726
|
};
|
|
299043
299727
|
}
|
|
299044
|
-
var
|
|
299728
|
+
var execFileAsync38;
|
|
299045
299729
|
var init_archive_worktree_disposer_install = __esm({
|
|
299046
299730
|
"../engine/src/healing/archive-worktree-disposer-install.ts"() {
|
|
299047
299731
|
"use strict";
|
|
299048
299732
|
init_src2();
|
|
299049
299733
|
init_worktree_backend();
|
|
299050
|
-
|
|
299734
|
+
execFileAsync38 = promisify95(execFile44);
|
|
299051
299735
|
}
|
|
299052
299736
|
});
|
|
299053
299737
|
|
|
@@ -300900,7 +301584,7 @@ import { exec as exec65 } from "node:child_process";
|
|
|
300900
301584
|
import { mkdtemp as mkdtemp7, rm as rm18 } from "node:fs/promises";
|
|
300901
301585
|
import { tmpdir as tmpdir14 } from "node:os";
|
|
300902
301586
|
import { join as join101 } from "node:path";
|
|
300903
|
-
import { promisify as
|
|
301587
|
+
import { promisify as promisify96 } from "node:util";
|
|
300904
301588
|
function resolveCommentAuthor(input) {
|
|
300905
301589
|
const login = input.login || "unknown";
|
|
300906
301590
|
const authorIsBot = Boolean(
|
|
@@ -301369,7 +302053,7 @@ var init_github = __esm({
|
|
|
301369
302053
|
"use strict";
|
|
301370
302054
|
init_src2();
|
|
301371
302055
|
init_issue_image_attachments();
|
|
301372
|
-
execAsync59 =
|
|
302056
|
+
execAsync59 = promisify96(exec65);
|
|
301373
302057
|
DiscussionsDisabledError = class extends Error {
|
|
301374
302058
|
name = "DiscussionsDisabledError";
|
|
301375
302059
|
constructor(owner, repo, cause) {
|
|
@@ -308726,7 +309410,7 @@ var init_knowledge_index_refresh = __esm({
|
|
|
308726
309410
|
});
|
|
308727
309411
|
|
|
308728
309412
|
// ../dashboard/src/pr-metadata-generator.ts
|
|
308729
|
-
import { promisify as
|
|
309413
|
+
import { promisify as promisify97 } from "node:util";
|
|
308730
309414
|
import { exec as execCb } from "node:child_process";
|
|
308731
309415
|
import { access as access13, readFile as readFile52 } from "node:fs/promises";
|
|
308732
309416
|
import { join as join102 } from "node:path";
|
|
@@ -309018,7 +309702,7 @@ var init_pr_metadata_generator = __esm({
|
|
|
309018
309702
|
"use strict";
|
|
309019
309703
|
init_src2();
|
|
309020
309704
|
init_src5();
|
|
309021
|
-
execAsync60 =
|
|
309705
|
+
execAsync60 = promisify97(execCb);
|
|
309022
309706
|
PR_METADATA_TIMEOUT_MS = 6e4;
|
|
309023
309707
|
PR_METADATA_SYSTEM_PROMPT = [
|
|
309024
309708
|
"You generate GitHub pull request metadata for Fusion tasks.",
|
|
@@ -309035,13 +309719,13 @@ var init_pr_metadata_generator = __esm({
|
|
|
309035
309719
|
});
|
|
309036
309720
|
|
|
309037
309721
|
// ../dashboard/src/routes/resolve-diff-base.ts
|
|
309038
|
-
import { execFile as
|
|
309039
|
-
import { promisify as
|
|
309040
|
-
var
|
|
309722
|
+
import { execFile as execFile45 } from "node:child_process";
|
|
309723
|
+
import { promisify as promisify98 } from "node:util";
|
|
309724
|
+
var execFileAsync39;
|
|
309041
309725
|
var init_resolve_diff_base = __esm({
|
|
309042
309726
|
"../dashboard/src/routes/resolve-diff-base.ts"() {
|
|
309043
309727
|
"use strict";
|
|
309044
|
-
|
|
309728
|
+
execFileAsync39 = promisify98(execFile45);
|
|
309045
309729
|
}
|
|
309046
309730
|
});
|
|
309047
309731
|
|
|
@@ -309082,7 +309766,7 @@ var init_git_worktree_safety = __esm({
|
|
|
309082
309766
|
|
|
309083
309767
|
// ../dashboard/src/routes/register-git-github.ts
|
|
309084
309768
|
import { exec as execCb2, spawn as spawn10 } from "node:child_process";
|
|
309085
|
-
import { promisify as
|
|
309769
|
+
import { promisify as promisify99 } from "node:util";
|
|
309086
309770
|
var severityAuditLog30, execAsync61, PR_ROUTE_MAX_BUFFER_BYTES, GITHUB_TRACKING_RECONCILE_INTERVAL_MS;
|
|
309087
309771
|
var init_register_git_github = __esm({
|
|
309088
309772
|
"../dashboard/src/routes/register-git-github.ts"() {
|
|
@@ -309114,7 +309798,7 @@ var init_register_git_github = __esm({
|
|
|
309114
309798
|
init_resolve_diff_base();
|
|
309115
309799
|
init_git_worktree_safety();
|
|
309116
309800
|
severityAuditLog30 = createLogger("dashboard-register-git-github");
|
|
309117
|
-
execAsync61 =
|
|
309801
|
+
execAsync61 = promisify99(execCb2);
|
|
309118
309802
|
PR_ROUTE_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
309119
309803
|
GITHUB_TRACKING_RECONCILE_INTERVAL_MS = 15 * 60 * 1e3;
|
|
309120
309804
|
}
|
|
@@ -316051,13 +316735,13 @@ var init_register_agents_projects_nodes = __esm({
|
|
|
316051
316735
|
});
|
|
316052
316736
|
|
|
316053
316737
|
// ../dashboard/src/exec-file.ts
|
|
316054
|
-
import { execFile as
|
|
316055
|
-
import { promisify as
|
|
316056
|
-
var
|
|
316738
|
+
import { execFile as execFile46 } from "node:child_process";
|
|
316739
|
+
import { promisify as promisify100 } from "node:util";
|
|
316740
|
+
var execFileAsync40;
|
|
316057
316741
|
var init_exec_file = __esm({
|
|
316058
316742
|
"../dashboard/src/exec-file.ts"() {
|
|
316059
316743
|
"use strict";
|
|
316060
|
-
|
|
316744
|
+
execFileAsync40 = promisify100(execFile46);
|
|
316061
316745
|
}
|
|
316062
316746
|
});
|
|
316063
316747
|
|
|
@@ -327335,7 +328019,7 @@ var init_register_fn_binary_routes = __esm({
|
|
|
327335
328019
|
|
|
327336
328020
|
// ../dashboard/src/update-check.ts
|
|
327337
328021
|
import { exec as exec66 } from "node:child_process";
|
|
327338
|
-
import { promisify as
|
|
328022
|
+
import { promisify as promisify101 } from "node:util";
|
|
327339
328023
|
var INSTALL_MAX_BUFFER, DAY_MS, execAsync62;
|
|
327340
328024
|
var init_update_check = __esm({
|
|
327341
328025
|
"../dashboard/src/update-check.ts"() {
|
|
@@ -327343,7 +328027,7 @@ var init_update_check = __esm({
|
|
|
327343
328027
|
init_src2();
|
|
327344
328028
|
INSTALL_MAX_BUFFER = 10 * 1024 * 1024;
|
|
327345
328029
|
DAY_MS = 24 * 60 * 60 * 1e3;
|
|
327346
|
-
execAsync62 =
|
|
328030
|
+
execAsync62 = promisify101(exec66);
|
|
327347
328031
|
}
|
|
327348
328032
|
});
|
|
327349
328033
|
|
|
@@ -327434,7 +328118,7 @@ var init_types5 = __esm({
|
|
|
327434
328118
|
});
|
|
327435
328119
|
|
|
327436
328120
|
// ../dashboard/src/stt/model-manager.ts
|
|
327437
|
-
import { createHash as
|
|
328121
|
+
import { createHash as createHash41, randomUUID as randomUUID63 } from "node:crypto";
|
|
327438
328122
|
import { mkdir as mkdir34, open as open5, readFile as readFile56, readdir as readdir14, rename as rename13, rm as rm21, stat as stat15, writeFile as writeFile33 } from "node:fs/promises";
|
|
327439
328123
|
import { join as join121, relative as relative25, resolve as resolve62, sep as sep20 } from "node:path";
|
|
327440
328124
|
function parseSafeTarListing(listing) {
|
|
@@ -327523,7 +328207,7 @@ function createVoiceModelManager(options = {}) {
|
|
|
327523
328207
|
if (!response.ok || !response.body) throw Object.assign(new Error("download failed"), { voiceReason: "network" });
|
|
327524
328208
|
if (!current(g2, signal)) return state;
|
|
327525
328209
|
const total = Number(response.headers.get("content-length")) || void 0;
|
|
327526
|
-
const hash3 =
|
|
328210
|
+
const hash3 = createHash41("sha256");
|
|
327527
328211
|
let bytes = 0;
|
|
327528
328212
|
for await (const chunk of response.body) {
|
|
327529
328213
|
if (!current(g2, signal)) return state;
|