@runfusion/fusion 0.75.1-beta.0 → 0.75.1-beta.1
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 +259 -76
- package/dist/child-process-worker.js +185 -61
- package/dist/client/.vite/manifest.json +248 -248
- package/dist/client/assets/{AgentDetailView-swTdiyeE.js → AgentDetailView-CE_7nvDT.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-Dq-KuDaA.js → AgentPermissionPolicyEditor-DYr3dk5X.js} +1 -1
- package/dist/client/assets/{AgentsView-D1GEHyH0.js → AgentsView-DZoYoiaD.js} +3 -3
- package/dist/client/assets/{ChatView-D1czGvvT.js → ChatView-BE9zMzYZ.js} +1 -1
- package/dist/client/assets/{CommandCenter-DWZ7OTOB.js → CommandCenter-DnLsp4_S.js} +1 -1
- package/dist/client/assets/{DevServerView-CAcUKOXd.js → DevServerView-CI-3j-lH.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DVUl5jOk.js → DirectoryPicker-D1ADu0Av.js} +1 -1
- package/dist/client/assets/{DocumentsView-CnexOxtr.js → DocumentsView-CF8y1gob.js} +1 -1
- package/dist/client/assets/{EvalsView-rTupzcDf.js → EvalsView-C9vLiM2_.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CXE6Bj3V.js → ExperimentalAgentOnboardingModal-CX_2Hjh0.js} +1 -1
- package/dist/client/assets/{GoalsView-CjHwnnIi.js → GoalsView-DJIA3k8q.js} +1 -1
- package/dist/client/assets/{InsightsView-C3XocYP-.js → InsightsView--TCeutLO.js} +1 -1
- package/dist/client/assets/{MemoryView-CsNHcx_d.js → MemoryView-Btp4m7pK.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-BPTPoZBI.js → PiExtensionsManager-DXdfh-Uf.js} +1 -1
- package/dist/client/assets/{PluginManager-CXadn8JE.js → PluginManager-BDFelFY6.js} +1 -1
- package/dist/client/assets/{PullRequestView-CC03CtZJ.js → PullRequestView-TSNKGSAg.js} +1 -1
- package/dist/client/assets/{ReportModal-Ci0na1eI.js → ReportModal-DhXMNHDL.js} +1 -1
- package/dist/client/assets/{ResearchView-DGWyAo8p.js → ResearchView-0w30HikQ.js} +1 -1
- package/dist/client/assets/{SecretsView-Cv2IuqFO.js → SecretsView-DgMu7279.js} +1 -1
- package/dist/client/assets/{SessionTerminal-B22RlQeo.js → SessionTerminal-CF6_uy2u.js} +1 -1
- package/dist/client/assets/{SettingsModal-BkgBQZ19.js → SettingsModal-BMAPX_7v.js} +1 -1
- package/dist/client/assets/{SettingsModal-CPRpRK71.js → SettingsModal-Dckls6LL.js} +3 -3
- package/dist/client/assets/{SettingsTextareaRow-0LXwMUQR.js → SettingsTextareaRow-LqXxpJl5.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-CyW3AlRO.js → SetupWizardModal-D1ZvGOcK.js} +2 -2
- package/dist/client/assets/{SkillsView-3oqB1ubq.js → SkillsView-CfO5B7SO.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-CfUK_xs1.js → WorkflowNodeEditor-CjdK9fFS.js} +3 -3
- package/dist/client/assets/{agent-import-generation-C7-Cmo3M.js → agent-import-generation-DqTzyLOZ.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BQ7ZN1r_.js → architectureDiagram-3BPJPVTR-CHkolL_b.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-Debw1Xka.js → blockDiagram-GPEHLZMM-BFRYQi8H.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CiU212s3.js → c4Diagram-AAUBKEIU-D9mMEYbR.js} +1 -1
- package/dist/client/assets/channel-CLdamWm5.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-BUJQ86zb.js → chunk-2J33WTMH-CCv6QaQn.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-C6GdEm1z.js → chunk-4BX2VUAB-Bfe22y5T.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CImvrxQL.js → chunk-55IACEB6-CwicrA9V.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-Dt-A3pkM.js → chunk-727SXJPM-DlIpTC03.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DDj4oXTx.js → chunk-AQP2D5EJ-CRX4mFVq.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BD4r1ukC.js → chunk-FMBD7UC4-DzG-bovU.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-DFSteefi.js → chunk-ND2GUHAM-D5F2jtpM.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-t2zF8tjB.js → chunk-QZHKN3VN-BmSaCwG6.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BYWknNX0.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BYWknNX0.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-tkvDkXQA.js → cose-bilkent-S5V4N54A-BbKTljui.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-DD2rW7wo.js → dagre-BM42HDAG-u0hwXb_T.js} +1 -1
- package/dist/client/assets/{dashboard-view-B1vduc8x.js → dashboard-view-BfYZZ9Ms.js} +1 -1
- package/dist/client/assets/{dashboard-view-DruCruAc.js → dashboard-view-BjPZG2Fv.js} +1 -1
- package/dist/client/assets/{dashboard-view-CciuDS5A.js → dashboard-view-faKSXA4_.js} +1 -1
- package/dist/client/assets/{dashboard-view-C7jJ1lA4.js → dashboard-view-oCjWDGbW.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-DASuxGNc.js → diagram-2AECGRRQ-Q7towbBl.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-f9WtiIUk.js → diagram-5GNKFQAL-UAwBmAxb.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-QivICYCd.js → diagram-KO2AKTUF-BL1n0pkf.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CMwcDFHR.js → diagram-LMA3HP47-O-v_IZUJ.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-C-vPMeHZ.js → diagram-OG6HWLK6-CAYSE2Mz.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CxGtk9vj.js → erDiagram-TEJ5UH35-Cr_DgCyp.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-qBZRZoV1.js → flowDiagram-I6XJVG4X-TdLzHKPW.js} +1 -1
- package/dist/client/assets/{folder-open-Dysi9Zzg.js → folder-open-BoddkTkv.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DAaXroiu.js → ganttDiagram-6RSMTGT7-CO1ErtJY.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DNUNQot_.js → gitGraphDiagram-PVQCEYII-C8_Kx0Yh.js} +1 -1
- package/dist/client/assets/index-C7KY0q8Q.js +2767 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-BSJmWLwh.js → infoDiagram-5YYISTIA-Dd6Zo7Dh.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-AyVKvoDq.js → ishikawaDiagram-YF4QCWOH-BE9JCLb5.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-972txzzd.js → journeyDiagram-JHISSGLW-B6RIZGDq.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-1xiNvIqK.js → kanban-definition-UN3LZRKU-CPXff-h-.js} +1 -1
- package/dist/client/assets/{mermaid.core-oeDA8jOm.js → mermaid.core-CbGj7iEw.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DcktmI8s.js → mindmap-definition-RKZ34NQL-DF5LZmsH.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-ekBwLt-O.js → pieDiagram-4H26LBE5-Dpy0Xm9T.js} +1 -1
- package/dist/client/assets/{puzzle-I6pr6ZrW.js → puzzle-BZa4U8-N.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-D_wjTsvn.js → quadrantDiagram-W4KKPZXB-BTLAQFpz.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CKGHyiJ1.js → requirementDiagram-4Y6WPE33-DSUV9ySs.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CtiZFNk5.js → sankeyDiagram-5OEKKPKP-Fmfn0XDL.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B6OMrfGk.js → sequenceDiagram-3UESZ5HK-_343I_b4.js} +1 -1
- package/dist/client/assets/{shield-alert-CVMmviMG.js → shield-alert-CdJ55UvI.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-Cg1a3tjW.js → standing-instructions-template-r03dZ5Z0.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-CyTY2M_7.js → stateDiagram-AJRCARHV-C9EbWegm.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-NWPCCiqC.js → stateDiagram-v2-BHNVJYJU-Bmh2GRh6.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DU4TVYpw.js → timeline-definition-PNZ67QCA-q86S9wyl.js} +1 -1
- package/dist/client/assets/{upload-VCzeCiFH.js → upload-DS9-qtCF.js} +1 -1
- package/dist/client/assets/{users-DB3knZtm.js → users-DP5Sngeg.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DX0Ppll6.js → vennDiagram-CIIHVFJN-BFq8uIt3.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-CBoWxpDv.js → wardley-L42UT6IY-BL_sLGYI.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-B_eVqdhC.js → wardleyDiagram-YWT4CUSO-BEKJJ9Vi.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DeZzEX0f.js → xychartDiagram-2RQKCTM6-DsvFnlxK.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +186 -62
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.d.ts +157 -140
- package/dist/plugin-sdk/index.js +19 -0
- package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +19 -0
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-D-O4mRXx.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BhHdSetA.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BhHdSetA.js +0 -1
- package/dist/client/assets/index-D0QgE5F5.js +0 -2767
package/dist/extension.js
CHANGED
|
@@ -9968,6 +9968,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
9968
9968
|
);
|
|
9969
9969
|
}
|
|
9970
9970
|
for (const inner of templateNodes) {
|
|
9971
|
+
validateReviewKind(inner, "nested");
|
|
9971
9972
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
9972
9973
|
throw new WorkflowIrError(
|
|
9973
9974
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10086,6 +10087,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10086
10087
|
);
|
|
10087
10088
|
}
|
|
10088
10089
|
for (const inner of templateNodes) {
|
|
10090
|
+
validateReviewKind(inner, "nested");
|
|
10089
10091
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10090
10092
|
throw new WorkflowIrError(
|
|
10091
10093
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10179,6 +10181,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10179
10181
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10180
10182
|
}
|
|
10181
10183
|
for (const inner of templateNodes) {
|
|
10184
|
+
validateReviewKind(inner, "nested");
|
|
10182
10185
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10183
10186
|
throw new WorkflowIrError(
|
|
10184
10187
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -10850,6 +10853,19 @@ function validateColumnRecovery(column) {
|
|
|
10850
10853
|
);
|
|
10851
10854
|
}
|
|
10852
10855
|
}
|
|
10856
|
+
function validateReviewKind(node, placement) {
|
|
10857
|
+
const value = node.config?.reviewKind;
|
|
10858
|
+
if (value === void 0) return;
|
|
10859
|
+
if (value !== "plan" && value !== "code") {
|
|
10860
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
10861
|
+
}
|
|
10862
|
+
if (placement === "nested") {
|
|
10863
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
10864
|
+
}
|
|
10865
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
10866
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
10867
|
+
}
|
|
10868
|
+
}
|
|
10853
10869
|
function validateV2(ir2) {
|
|
10854
10870
|
validateColumns(ir2);
|
|
10855
10871
|
for (const [index2, column] of ir2.columns.entries()) {
|
|
@@ -10872,6 +10888,7 @@ function validateV2(ir2) {
|
|
|
10872
10888
|
}
|
|
10873
10889
|
const nodesById = new Map(ir2.nodes.map((n) => [n.id, n]));
|
|
10874
10890
|
for (const node of ir2.nodes) {
|
|
10891
|
+
validateReviewKind(node, "top-level");
|
|
10875
10892
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
10876
10893
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
10877
10894
|
throw new WorkflowIrError(
|
|
@@ -13335,6 +13352,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13335
13352
|
column,
|
|
13336
13353
|
config: {
|
|
13337
13354
|
name: CODE_REVIEW_NAME,
|
|
13355
|
+
reviewKind: "code",
|
|
13338
13356
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13339
13357
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13340
13358
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13480,6 +13498,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13480
13498
|
...column ? { column } : {},
|
|
13481
13499
|
config: {
|
|
13482
13500
|
name: PLAN_REVIEW_NAME,
|
|
13501
|
+
reviewKind: "plan",
|
|
13483
13502
|
defaultOn: options.defaultOn ?? true,
|
|
13484
13503
|
/*
|
|
13485
13504
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -127080,6 +127099,36 @@ var init_async_knowledge = __esm({
|
|
|
127080
127099
|
});
|
|
127081
127100
|
|
|
127082
127101
|
// ../core/src/workflows/workflow-step-results.ts
|
|
127102
|
+
function normalizeWorkflowReviewFindings(raw) {
|
|
127103
|
+
if (!Array.isArray(raw)) return void 0;
|
|
127104
|
+
const normalized = [];
|
|
127105
|
+
const usedIds = /* @__PURE__ */ new Set();
|
|
127106
|
+
for (const candidate of raw) {
|
|
127107
|
+
if (normalized.length >= MAX_WORKFLOW_REVIEW_FINDINGS || !candidate || typeof candidate !== "object") continue;
|
|
127108
|
+
const value = candidate;
|
|
127109
|
+
const title = boundedTrimmedString(value.title, MAX_FINDING_TITLE_LENGTH);
|
|
127110
|
+
const body = boundedTrimmedString(value.body, MAX_FINDING_BODY_LENGTH);
|
|
127111
|
+
if (!title || !body) continue;
|
|
127112
|
+
const baseId = boundedTrimmedString(value.id, MAX_FINDING_ID_LENGTH) || `finding-${normalized.length + 1}`;
|
|
127113
|
+
let id = baseId;
|
|
127114
|
+
let suffix = 2;
|
|
127115
|
+
while (usedIds.has(id)) id = `${baseId.slice(0, Math.max(1, MAX_FINDING_ID_LENGTH - String(suffix).length - 1))}-${suffix++}`;
|
|
127116
|
+
usedIds.add(id);
|
|
127117
|
+
const filePath = boundedTrimmedString(value.filePath, MAX_FINDING_PATH_LENGTH);
|
|
127118
|
+
const line2 = typeof value.line === "number" && Number.isFinite(value.line) && value.line > 0 ? Math.floor(value.line) : void 0;
|
|
127119
|
+
const severity = isWorkflowReviewFindingSeverity(value.severity) ? value.severity : void 0;
|
|
127120
|
+
normalized.push({ id, title, body, ...filePath ? { filePath } : {}, ...line2 ? { line: line2 } : {}, ...severity ? { severity } : {} });
|
|
127121
|
+
}
|
|
127122
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
127123
|
+
}
|
|
127124
|
+
function boundedTrimmedString(value, maxLength) {
|
|
127125
|
+
if (typeof value !== "string") return void 0;
|
|
127126
|
+
const trimmed = value.trim();
|
|
127127
|
+
return trimmed && trimmed.length <= maxLength ? trimmed : void 0;
|
|
127128
|
+
}
|
|
127129
|
+
function isWorkflowReviewFindingSeverity(value) {
|
|
127130
|
+
return typeof value === "string" && WORKFLOW_REVIEW_FINDING_SEVERITIES.includes(value);
|
|
127131
|
+
}
|
|
127083
127132
|
function isTerminalFailure(result2) {
|
|
127084
127133
|
return TERMINAL_FAILURE_STATUSES.has(result2.status);
|
|
127085
127134
|
}
|
|
@@ -127145,10 +127194,16 @@ function makeReviewLeaseRecord(args) {
|
|
|
127145
127194
|
leaseOwner: args.owner
|
|
127146
127195
|
};
|
|
127147
127196
|
}
|
|
127148
|
-
var MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS, TERMINAL_FAILURE_STATUSES, PLAN_REVIEW_LEASE_STALENESS_MS, TERMINAL_STEP_STATUSES;
|
|
127197
|
+
var WORKFLOW_REVIEW_FINDING_SEVERITIES, MAX_WORKFLOW_REVIEW_FINDINGS, MAX_FINDING_ID_LENGTH, MAX_FINDING_TITLE_LENGTH, MAX_FINDING_BODY_LENGTH, MAX_FINDING_PATH_LENGTH, MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS, TERMINAL_FAILURE_STATUSES, PLAN_REVIEW_LEASE_STALENESS_MS, TERMINAL_STEP_STATUSES;
|
|
127149
127198
|
var init_workflow_step_results = __esm({
|
|
127150
127199
|
"../core/src/workflows/workflow-step-results.ts"() {
|
|
127151
127200
|
"use strict";
|
|
127201
|
+
WORKFLOW_REVIEW_FINDING_SEVERITIES = ["low", "medium", "high", "critical"];
|
|
127202
|
+
MAX_WORKFLOW_REVIEW_FINDINGS = 20;
|
|
127203
|
+
MAX_FINDING_ID_LENGTH = 128;
|
|
127204
|
+
MAX_FINDING_TITLE_LENGTH = 240;
|
|
127205
|
+
MAX_FINDING_BODY_LENGTH = 4e3;
|
|
127206
|
+
MAX_FINDING_PATH_LENGTH = 1e3;
|
|
127152
127207
|
MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS = 5;
|
|
127153
127208
|
TERMINAL_FAILURE_STATUSES = /* @__PURE__ */ new Set([
|
|
127154
127209
|
"failed",
|
|
@@ -127635,6 +127690,7 @@ __export(src_exports, {
|
|
|
127635
127690
|
MAX_TITLE_LENGTH: () => MAX_TITLE_LENGTH,
|
|
127636
127691
|
MAX_TITLE_SUMMARIZE_INPUT_LENGTH: () => MAX_TITLE_SUMMARIZE_INPUT_LENGTH,
|
|
127637
127692
|
MAX_WORKFLOW_ICON_LENGTH: () => MAX_WORKFLOW_ICON_LENGTH,
|
|
127693
|
+
MAX_WORKFLOW_REVIEW_FINDINGS: () => MAX_WORKFLOW_REVIEW_FINDINGS,
|
|
127638
127694
|
MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS: () => MAX_WORKFLOW_STEP_PRIOR_ATTEMPTS,
|
|
127639
127695
|
MEMORY_AUDIT_PATH: () => MEMORY_AUDIT_PATH,
|
|
127640
127696
|
MEMORY_BACKEND_SETTINGS_KEYS: () => MEMORY_BACKEND_SETTINGS_KEYS,
|
|
@@ -127836,6 +127892,7 @@ __export(src_exports, {
|
|
|
127836
127892
|
WAKE_DELTA_ASSIGNED_TASKS_CAP: () => WAKE_DELTA_ASSIGNED_TASKS_CAP,
|
|
127837
127893
|
WEDGE_RENOTIFY_COOLDOWN_MS: () => WEDGE_RENOTIFY_COOLDOWN_MS,
|
|
127838
127894
|
WORKFLOW_EXTENSION_SCHEMA_VERSION: () => WORKFLOW_EXTENSION_SCHEMA_VERSION,
|
|
127895
|
+
WORKFLOW_REVIEW_FINDING_SEVERITIES: () => WORKFLOW_REVIEW_FINDING_SEVERITIES,
|
|
127839
127896
|
WORKFLOW_SETTING_REJECTION_CODES: () => WORKFLOW_SETTING_REJECTION_CODES,
|
|
127840
127897
|
WORKFLOW_SETTING_TYPES: () => WORKFLOW_SETTING_TYPES,
|
|
127841
127898
|
WORKFLOW_WORK_ITEM_KINDS: () => WORKFLOW_WORK_ITEM_KINDS,
|
|
@@ -128363,6 +128420,7 @@ __export(src_exports, {
|
|
|
128363
128420
|
isWipColumn: () => isWipColumn,
|
|
128364
128421
|
isWipColumnRole: () => isWipColumnRole,
|
|
128365
128422
|
isWorkflowOptionalGroupEnabled: () => isWorkflowOptionalGroupEnabled,
|
|
128423
|
+
isWorkflowReviewFindingSeverity: () => isWorkflowReviewFindingSeverity,
|
|
128366
128424
|
isWorkspaceTask: () => isWorkspaceTask,
|
|
128367
128425
|
layoutForIr: () => layoutForIr,
|
|
128368
128426
|
listActiveAiSessions: () => listActiveAiSessions,
|
|
@@ -128436,6 +128494,7 @@ __export(src_exports, {
|
|
|
128436
128494
|
normalizeValidationDiagnostics: () => normalizeValidationDiagnostics,
|
|
128437
128495
|
normalizeWorkflowIcon: () => normalizeWorkflowIcon,
|
|
128438
128496
|
normalizeWorkflowPromptOverrides: () => normalizeWorkflowPromptOverrides,
|
|
128497
|
+
normalizeWorkflowReviewFindings: () => normalizeWorkflowReviewFindings,
|
|
128439
128498
|
notifyOperatorOfNonOperatorDelete: () => notifyOperatorOfNonOperatorDelete,
|
|
128440
128499
|
overseerAdviceSeverityRank: () => overseerAdviceSeverityRank,
|
|
128441
128500
|
parseAgentManifest: () => parseAgentManifest,
|
|
@@ -173094,37 +173153,6 @@ var init_effective_settings = __esm({
|
|
|
173094
173153
|
}
|
|
173095
173154
|
});
|
|
173096
173155
|
|
|
173097
|
-
// ../engine/src/errors/transient-merge-error-classifier.ts
|
|
173098
|
-
function classifyTransientMergeError(error3) {
|
|
173099
|
-
if (!error3) return null;
|
|
173100
|
-
if (/lease-handoff-failed[^a-z]+target-not-queued/i.test(error3)) {
|
|
173101
|
-
return "lease-handoff-target-not-queued";
|
|
173102
|
-
}
|
|
173103
|
-
if (/\bACP turn failed\b/i.test(error3) || /\bacp rpc code -32(?:603|00[0-3])\b/i.test(error3)) {
|
|
173104
|
-
return "ai-provider-turn-failure";
|
|
173105
|
-
}
|
|
173106
|
-
if (/\bspawn(?:\s+\S+)?\s+ENO(?:TDIR|ENT)\b/i.test(error3)) {
|
|
173107
|
-
return "process-spawn-failure";
|
|
173108
|
-
}
|
|
173109
|
-
if (/\bis not a working tree\b/i.test(error3)) {
|
|
173110
|
-
return "process-spawn-failure";
|
|
173111
|
-
}
|
|
173112
|
-
const sameSha = error3.match(/advanced concurrently \(expected ([0-9a-f]{7,40}),\s+observed ([0-9a-f]{7,40})\)/i);
|
|
173113
|
-
if (sameSha && sameSha[1].toLowerCase() === sameSha[2].toLowerCase()) {
|
|
173114
|
-
return "spurious-concurrent-advance-same-sha";
|
|
173115
|
-
}
|
|
173116
|
-
if (isTransientError(error3)) {
|
|
173117
|
-
return "network-transport-failure";
|
|
173118
|
-
}
|
|
173119
|
-
return null;
|
|
173120
|
-
}
|
|
173121
|
-
var init_transient_merge_error_classifier = __esm({
|
|
173122
|
-
"../engine/src/errors/transient-merge-error-classifier.ts"() {
|
|
173123
|
-
"use strict";
|
|
173124
|
-
init_transient_error_patterns();
|
|
173125
|
-
}
|
|
173126
|
-
});
|
|
173127
|
-
|
|
173128
173156
|
// ../engine/src/notification/ntfy-provider.ts
|
|
173129
173157
|
function resolveParticipantLabel(metadata, kind) {
|
|
173130
173158
|
const nameKey = kind === "from" ? "fromName" : "toName";
|
|
@@ -173598,7 +173626,50 @@ var init_webhook_provider = __esm({
|
|
|
173598
173626
|
}
|
|
173599
173627
|
});
|
|
173600
173628
|
|
|
173629
|
+
// ../engine/src/errors/transient-merge-error-classifier.ts
|
|
173630
|
+
function classifyTransientMergeError(error3) {
|
|
173631
|
+
if (!error3) return null;
|
|
173632
|
+
if (/lease-handoff-failed[^a-z]+target-not-queued/i.test(error3)) {
|
|
173633
|
+
return "lease-handoff-target-not-queued";
|
|
173634
|
+
}
|
|
173635
|
+
if (/\bACP turn failed\b/i.test(error3) || /\bacp rpc code -32(?:603|00[0-3])\b/i.test(error3)) {
|
|
173636
|
+
return "ai-provider-turn-failure";
|
|
173637
|
+
}
|
|
173638
|
+
if (/\bspawn(?:\s+\S+)?\s+ENO(?:TDIR|ENT)\b/i.test(error3)) {
|
|
173639
|
+
return "process-spawn-failure";
|
|
173640
|
+
}
|
|
173641
|
+
if (/\bis not a working tree\b/i.test(error3)) {
|
|
173642
|
+
return "process-spawn-failure";
|
|
173643
|
+
}
|
|
173644
|
+
const sameSha = error3.match(/advanced concurrently \(expected ([0-9a-f]{7,40}),\s+observed ([0-9a-f]{7,40})\)/i);
|
|
173645
|
+
if (sameSha && sameSha[1].toLowerCase() === sameSha[2].toLowerCase()) {
|
|
173646
|
+
return "spurious-concurrent-advance-same-sha";
|
|
173647
|
+
}
|
|
173648
|
+
if (isTransientError(error3)) {
|
|
173649
|
+
return "network-transport-failure";
|
|
173650
|
+
}
|
|
173651
|
+
return null;
|
|
173652
|
+
}
|
|
173653
|
+
function hasTransientMergeRecoveryOwner(task) {
|
|
173654
|
+
return classifyTransientMergeError(task.error) !== null && typeof task.mergeTransientRetryCount === "number" && Number.isInteger(task.mergeTransientRetryCount) && task.mergeTransientRetryCount >= 0 && task.mergeTransientRetryCount < MAX_AUTO_MERGE_TRANSIENT_RETRIES;
|
|
173655
|
+
}
|
|
173656
|
+
var MAX_AUTO_MERGE_TRANSIENT_RETRIES;
|
|
173657
|
+
var init_transient_merge_error_classifier = __esm({
|
|
173658
|
+
"../engine/src/errors/transient-merge-error-classifier.ts"() {
|
|
173659
|
+
"use strict";
|
|
173660
|
+
init_transient_error_patterns();
|
|
173661
|
+
MAX_AUTO_MERGE_TRANSIENT_RETRIES = 5;
|
|
173662
|
+
}
|
|
173663
|
+
});
|
|
173664
|
+
|
|
173601
173665
|
// ../engine/src/notification/task-wedge-notification.ts
|
|
173666
|
+
function describeTaskRecoveryOwner(task) {
|
|
173667
|
+
if (hasTransientMergeRecoveryOwner(task)) return { kind: "transient-merge-retry" };
|
|
173668
|
+
if (typeof task.recoveryRetryCount === "number" && Number.isInteger(task.recoveryRetryCount) && task.recoveryRetryCount >= 0 && typeof task.nextRecoveryAt === "string" && Number.isFinite(Date.parse(task.nextRecoveryAt))) {
|
|
173669
|
+
return { kind: "scheduled-recovery" };
|
|
173670
|
+
}
|
|
173671
|
+
return null;
|
|
173672
|
+
}
|
|
173602
173673
|
function describeSelfHealingNoActionWedge(task, stage, metadata) {
|
|
173603
173674
|
const description = SELF_HEALING_NO_ACTIONS[stage];
|
|
173604
173675
|
if (!description || task.userPaused || task.paused || task.autoMerge === false) return null;
|
|
@@ -173656,6 +173727,7 @@ function describeTaskWedge(task) {
|
|
|
173656
173727
|
if (/merge.*(?:blocked|verification|gate)|(?:verification|gate).*(?:failed|exhaust)/i.test(error3)) {
|
|
173657
173728
|
return { reasonKey: "merge-blocked", reason: "Merge verification cannot progress without operator action.", action: "Fix the failing verification, then retry the task." };
|
|
173658
173729
|
}
|
|
173730
|
+
if (describeTaskRecoveryOwner(task)) return null;
|
|
173659
173731
|
if (!error3 && (task.mergeRetries ?? 0) < 3) return null;
|
|
173660
173732
|
return {
|
|
173661
173733
|
reasonKey: "terminal-failed",
|
|
@@ -173667,6 +173739,7 @@ var SELF_HEALING_NO_ACTIONS;
|
|
|
173667
173739
|
var init_task_wedge_notification = __esm({
|
|
173668
173740
|
"../engine/src/notification/task-wedge-notification.ts"() {
|
|
173669
173741
|
"use strict";
|
|
173742
|
+
init_transient_merge_error_classifier();
|
|
173670
173743
|
SELF_HEALING_NO_ACTIONS = {
|
|
173671
173744
|
"reclaim-pr-conflict": {
|
|
173672
173745
|
reason: "Self-healing could not reclaim a stalled pull-request conflict.",
|
|
@@ -173732,7 +173805,6 @@ var init_notification_service = __esm({
|
|
|
173732
173805
|
init_src2();
|
|
173733
173806
|
init_notifier();
|
|
173734
173807
|
init_logger3();
|
|
173735
|
-
init_transient_merge_error_classifier();
|
|
173736
173808
|
init_ntfy_provider();
|
|
173737
173809
|
init_webhook_provider();
|
|
173738
173810
|
init_task_wedge_notification();
|
|
@@ -173958,10 +174030,10 @@ var init_notification_service = __esm({
|
|
|
173958
174030
|
}
|
|
173959
174031
|
}
|
|
173960
174032
|
handleTaskUpdated = (task, meta2) => {
|
|
173961
|
-
const
|
|
173962
|
-
const wedge =
|
|
174033
|
+
const recoveryOwner = task.status === "failed" ? describeTaskRecoveryOwner(task) : null;
|
|
174034
|
+
const wedge = describeTaskWedge(task);
|
|
173963
174035
|
if (wedge) this.cancelPendingFailureNotification(task.id, "classified-terminal-wedge");
|
|
173964
|
-
|
|
174036
|
+
void this.enqueueWedgeHandling(task.id, () => this.maybeNotifyTaskWedge(task, wedge));
|
|
173965
174037
|
void this.maybeSuppressTransientFailedNotification(task, `status=${task.status ?? "undefined"}`);
|
|
173966
174038
|
if (task.status === "awaiting-approval") {
|
|
173967
174039
|
void this.writeAwaitingApprovalMailboxMessage(task);
|
|
@@ -173972,17 +174044,12 @@ var init_notification_service = __esm({
|
|
|
173972
174044
|
if (!this.notificationsEnabled) {
|
|
173973
174045
|
return;
|
|
173974
174046
|
}
|
|
173975
|
-
if (task.status === "failed" &&
|
|
173976
|
-
|
|
173977
|
-
|
|
173978
|
-
|
|
173979
|
-
schedulerLog.debug(
|
|
173980
|
-
`[notify] ${task.id} transient merge failure (${transientClass}) \u2014 suppressed notification (self-heal in flight)`
|
|
173981
|
-
);
|
|
173982
|
-
return;
|
|
173983
|
-
}
|
|
174047
|
+
if (task.status === "failed" && recoveryOwner) {
|
|
174048
|
+
this.failureNotificationSuppressedCount += 1;
|
|
174049
|
+
schedulerLog.debug(`[notify] ${task.id} recovery-owned failure \u2014 suppressed notification`);
|
|
174050
|
+
} else if (task.status === "failed" && !wedge) {
|
|
173984
174051
|
if (this.failureNotificationMode === "all") {
|
|
173985
|
-
|
|
174052
|
+
void this.maybeNotifyImmediateFailure(task);
|
|
173986
174053
|
} else {
|
|
173987
174054
|
this.scheduleFailureNotification(task);
|
|
173988
174055
|
}
|
|
@@ -174069,7 +174136,17 @@ var init_notification_service = __esm({
|
|
|
174069
174136
|
await this.enqueueWedgeHandling(task.id, () => this.maybeNotifyTaskWedge(task, descriptor));
|
|
174070
174137
|
}
|
|
174071
174138
|
async maybeNotifyTaskWedge(task, suppliedDescriptor) {
|
|
174072
|
-
const
|
|
174139
|
+
const liveTask = this.store.getTask ? await this.store.getTask(task.id) ?? task : task;
|
|
174140
|
+
const recoveryOwner = describeTaskRecoveryOwner(liveTask);
|
|
174141
|
+
if (recoveryOwner) {
|
|
174142
|
+
if (this.activeWedgeReasons.has(task.id) || liveTask.wedgeNotification?.status === "active") {
|
|
174143
|
+
this.activeWedgeReasons.delete(task.id);
|
|
174144
|
+
await this.store.claimTaskWedgeNotificationEpisode?.(task.id, null);
|
|
174145
|
+
}
|
|
174146
|
+
return;
|
|
174147
|
+
}
|
|
174148
|
+
const descriptor = suppliedDescriptor ?? describeTaskWedge(liveTask);
|
|
174149
|
+
task = liveTask;
|
|
174073
174150
|
let episode;
|
|
174074
174151
|
if (!descriptor) {
|
|
174075
174152
|
const isActiveSelfHealingNoAction = task.wedgeNotification?.status === "active" && task.wedgeNotification.reasonKey.startsWith("self-healing-no-action:");
|
|
@@ -174436,6 +174513,14 @@ var init_notification_service = __esm({
|
|
|
174436
174513
|
this.failureNotificationDelayMs = typeof settings.failureNotificationDelayMs === "number" && settings.failureNotificationDelayMs >= 0 ? settings.failureNotificationDelayMs : this.failedNotificationGraceMs;
|
|
174437
174514
|
this.failureNotificationMode = settings.failureNotificationMode ?? "sticky-only";
|
|
174438
174515
|
}
|
|
174516
|
+
async maybeNotifyImmediateFailure(task) {
|
|
174517
|
+
const liveTask = this.store.getTask ? await this.store.getTask(task.id) ?? task : task;
|
|
174518
|
+
if (liveTask.status !== "failed" || describeTaskRecoveryOwner(liveTask) || describeTaskWedge(liveTask)) {
|
|
174519
|
+
this.failureNotificationSuppressedCount += 1;
|
|
174520
|
+
return;
|
|
174521
|
+
}
|
|
174522
|
+
this.maybeNotify(liveTask.id, "failed", this.createTaskPayload(liveTask, "failed"));
|
|
174523
|
+
}
|
|
174439
174524
|
scheduleFailureNotification(task) {
|
|
174440
174525
|
if (this.pendingFailureNotifications.has(task.id)) {
|
|
174441
174526
|
return;
|
|
@@ -174492,12 +174577,9 @@ var init_notification_service = __esm({
|
|
|
174492
174577
|
schedulerLog.debug(`[notify] ${taskId} no longer failed at dispatch time \u2014 suppressed notification`);
|
|
174493
174578
|
return;
|
|
174494
174579
|
}
|
|
174495
|
-
|
|
174496
|
-
if (transientClassAtDispatch) {
|
|
174580
|
+
if (describeTaskRecoveryOwner(task)) {
|
|
174497
174581
|
this.failureNotificationSuppressedCount += 1;
|
|
174498
|
-
schedulerLog.debug(
|
|
174499
|
-
`[notify] ${taskId} transient merge failure (${transientClassAtDispatch}) at dispatch time \u2014 suppressed notification (self-heal in flight)`
|
|
174500
|
-
);
|
|
174582
|
+
schedulerLog.debug(`[notify] ${taskId} recovery-owned failure at dispatch time \u2014 suppressed notification`);
|
|
174501
174583
|
return;
|
|
174502
174584
|
}
|
|
174503
174585
|
if (describeTaskWedge(task)) {
|
|
@@ -186152,10 +186234,21 @@ var init_scheduler = __esm({
|
|
|
186152
186234
|
const unmetDeps = getUnmetSchedulingDependencies(task, tasks2, schedulingDependencyOptions);
|
|
186153
186235
|
if (unmetDeps.length > 0) {
|
|
186154
186236
|
const normalizedUnmetDeps = [...new Set(unmetDeps)].sort();
|
|
186237
|
+
let activeOverlapBlockedBy = null;
|
|
186238
|
+
if (activeScopes.size > 0) {
|
|
186239
|
+
try {
|
|
186240
|
+
const taskScope = await getFilteredFileScope(task.id);
|
|
186241
|
+
if (taskScope.length > 0 && !isCoordinationOnlyTask(task, taskScope)) {
|
|
186242
|
+
activeOverlapBlockedBy = Array.from(activeScopes.entries()).sort(([aId], [bId]) => aId.localeCompare(bId)).find(([, activeScope]) => this.pathsOverlap(taskScope, activeScope))?.[0] ?? null;
|
|
186243
|
+
}
|
|
186244
|
+
} catch (error3) {
|
|
186245
|
+
schedulerLog.warn(`Failed to refresh file-scope overlap blocker for dependency-blocked task ${task.id}`, error3);
|
|
186246
|
+
}
|
|
186247
|
+
}
|
|
186155
186248
|
await this.transitionQueuedEpisode(task, {
|
|
186156
186249
|
signature: `dependency:${normalizedUnmetDeps.join(",")}`,
|
|
186157
186250
|
blockedBy: unmetDeps[0] ?? null,
|
|
186158
|
-
overlapBlockedBy:
|
|
186251
|
+
overlapBlockedBy: activeOverlapBlockedBy,
|
|
186159
186252
|
action: `queued \u2014 unmet dependencies: ${unmetDeps.join(", ")}`
|
|
186160
186253
|
});
|
|
186161
186254
|
this.options.onBlocked?.(task, unmetDeps);
|
|
@@ -217957,7 +218050,7 @@ function recoverPassedPlanReviewFromLatestLog(task) {
|
|
|
217957
218050
|
completedAt: latest.timestamp
|
|
217958
218051
|
};
|
|
217959
218052
|
}
|
|
217960
|
-
var PLAN_REVIEW_PROVIDER_FAILURE_HOLD_VALUE, PLAN_REVIEW_LEASE_HELD_VALUE, SESSION_CONTENTION_HOLD_VALUE, WORKFLOW_INTERRUPTED_NODE_ID_CONTEXT_KEY, WORKFLOW_INTERRUPTED_NODE_ABORT_KIND_CONTEXT_KEY, WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY, WORKFLOW_NODE_ENGINE_PAUSE_ABORT_KIND, WORKFLOW_DRIFT_PARK_CONTEXT_KEY, WorkflowGraphSuspended, MERGE_REGION_KINDS, WorkflowGraphExecutor;
|
|
218053
|
+
var PLAN_REVIEW_PROVIDER_FAILURE_HOLD_VALUE, PLAN_REVIEW_LEASE_HELD_VALUE, SESSION_CONTENTION_HOLD_VALUE, WORKFLOW_INTERRUPTED_NODE_ID_CONTEXT_KEY, WORKFLOW_INTERRUPTED_NODE_ABORT_KIND_CONTEXT_KEY, WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY, WORKFLOW_REVIEW_KIND_CONTEXT_KEY, WORKFLOW_NODE_ENGINE_PAUSE_ABORT_KIND, WORKFLOW_DRIFT_PARK_CONTEXT_KEY, WorkflowGraphSuspended, MERGE_REGION_KINDS, WorkflowGraphExecutor;
|
|
217961
218054
|
var init_workflow_graph_executor = __esm({
|
|
217962
218055
|
"../engine/src/workflows/workflow-graph-executor.ts"() {
|
|
217963
218056
|
"use strict";
|
|
@@ -217977,6 +218070,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
217977
218070
|
WORKFLOW_INTERRUPTED_NODE_ID_CONTEXT_KEY = "workflow:interruptedNodeId";
|
|
217978
218071
|
WORKFLOW_INTERRUPTED_NODE_ABORT_KIND_CONTEXT_KEY = "workflow:interruptedNodeAbortKind";
|
|
217979
218072
|
WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY = "workflow:optionalGroupActive";
|
|
218073
|
+
WORKFLOW_REVIEW_KIND_CONTEXT_KEY = "workflow:reviewKind";
|
|
217980
218074
|
WORKFLOW_NODE_ENGINE_PAUSE_ABORT_KIND = "engine-pause";
|
|
217981
218075
|
WORKFLOW_DRIFT_PARK_CONTEXT_KEY = "workflow:driftPark";
|
|
217982
218076
|
WorkflowGraphSuspended = class extends Error {
|
|
@@ -218225,6 +218319,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
218225
218319
|
phase: stepPhase,
|
|
218226
218320
|
status: "pending",
|
|
218227
218321
|
source: "optional-group",
|
|
218322
|
+
...this.workflowReviewKind(node) ? { reviewKind: this.workflowReviewKind(node) } : {},
|
|
218228
218323
|
startedAt: stepStartedAt,
|
|
218229
218324
|
// U3/KTD-4: stamp the lease owner so a concurrent/crashed re-entry
|
|
218230
218325
|
// adopts this pending gate instead of dispatching a second reviewer.
|
|
@@ -218244,7 +218339,8 @@ var init_workflow_graph_executor = __esm({
|
|
|
218244
218339
|
runTemplateNode: (tNode, sig, contextOverride) => {
|
|
218245
218340
|
const optionalGroupContext = {
|
|
218246
218341
|
...contextOverride ?? context,
|
|
218247
|
-
[WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY]: node.id
|
|
218342
|
+
[WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY]: node.id,
|
|
218343
|
+
...this.workflowReviewKind(node) ? { [WORKFLOW_REVIEW_KIND_CONTEXT_KEY]: this.workflowReviewKind(node) } : {}
|
|
218248
218344
|
};
|
|
218249
218345
|
return this.executeNodeWithRetries(tNode, task, settings, optionalGroupContext, ir2, sig, false);
|
|
218250
218346
|
},
|
|
@@ -218262,6 +218358,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
218262
218358
|
const exitContextPatch = exitResult?.contextPatch;
|
|
218263
218359
|
let stepOutput = typeof exitContextPatch?.output === "string" ? exitContextPatch.output : void 0;
|
|
218264
218360
|
const stepNotes = typeof exitContextPatch?.notes === "string" ? exitContextPatch.notes : void 0;
|
|
218361
|
+
const stepFindings = this.workflowReviewKind(node) && Array.isArray(exitContextPatch?.findings) ? exitContextPatch.findings : void 0;
|
|
218265
218362
|
if (stepStatus === "failed" && !verdict && stepOutput === void 0 && stepNotes === void 0) {
|
|
218266
218363
|
const lastVisited = groupResult.visitedNodeIds[groupResult.visitedNodeIds.length - 1];
|
|
218267
218364
|
const templateNodeId = lastVisited?.includes("::") ? lastVisited.slice(lastVisited.indexOf("::") + 2) : void 0;
|
|
@@ -218279,9 +218376,11 @@ var init_workflow_graph_executor = __esm({
|
|
|
218279
218376
|
phase: stepPhase,
|
|
218280
218377
|
source: "optional-group",
|
|
218281
218378
|
status: stepStatus,
|
|
218379
|
+
...this.workflowReviewKind(node) ? { reviewKind: this.workflowReviewKind(node) } : {},
|
|
218282
218380
|
...verdict ? { verdict } : {},
|
|
218283
218381
|
...stepOutput !== void 0 ? { output: stepOutput } : {},
|
|
218284
218382
|
...stepNotes !== void 0 ? { notes: stepNotes } : {},
|
|
218383
|
+
...stepFindings?.length ? { findings: stepFindings } : {},
|
|
218285
218384
|
startedAt: stepStartedAt,
|
|
218286
218385
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
218287
218386
|
});
|
|
@@ -218741,9 +218840,15 @@ var init_workflow_graph_executor = __esm({
|
|
|
218741
218840
|
}
|
|
218742
218841
|
return failureResult;
|
|
218743
218842
|
}
|
|
218843
|
+
/** FNXC:WorkflowReviewKind 2026-08-05-02:31: Persist only the declared closed
|
|
218844
|
+
* marker; execution never derives review semantics from a label, verdict, or gate mode. */
|
|
218845
|
+
workflowReviewKind(node) {
|
|
218846
|
+
return node.config?.reviewKind === "plan" || node.config?.reviewKind === "code" ? node.config.reviewKind : void 0;
|
|
218847
|
+
}
|
|
218744
218848
|
shouldRecordNodeProgress(node) {
|
|
218745
218849
|
const skillName = typeof node.config?.skillName === "string" ? node.config.skillName.trim() : "";
|
|
218746
|
-
|
|
218850
|
+
const markedReview = this.workflowReviewKind(node) !== void 0;
|
|
218851
|
+
return markedReview && (node.kind === "prompt" || node.kind === "gate" || node.kind === "script") || skillName.length > 0 && (node.kind === "prompt" || node.kind === "gate");
|
|
218747
218852
|
}
|
|
218748
218853
|
workflowNodeProgressName(node) {
|
|
218749
218854
|
const configuredName = typeof node.config?.name === "string" ? node.config.name.trim() : "";
|
|
@@ -218757,6 +218862,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
218757
218862
|
phase: node.config?.phase === "post-merge" ? "post-merge" : "pre-merge",
|
|
218758
218863
|
source: "node",
|
|
218759
218864
|
status: "pending",
|
|
218865
|
+
...this.workflowReviewKind(node) ? { reviewKind: this.workflowReviewKind(node) } : {},
|
|
218760
218866
|
startedAt
|
|
218761
218867
|
};
|
|
218762
218868
|
await this.recordOptionalGroupStepResult(taskId, result2);
|
|
@@ -218767,6 +218873,7 @@ var init_workflow_graph_executor = __esm({
|
|
|
218767
218873
|
const contextPatch = nodeResult.contextPatch ?? {};
|
|
218768
218874
|
let output = typeof contextPatch.output === "string" ? contextPatch.output : void 0;
|
|
218769
218875
|
const notes = typeof contextPatch.notes === "string" ? contextPatch.notes : void 0;
|
|
218876
|
+
const findings = this.workflowReviewKind(node) && Array.isArray(contextPatch.findings) ? contextPatch.findings : void 0;
|
|
218770
218877
|
if (status === "failed" && output === void 0 && notes === void 0) {
|
|
218771
218878
|
output = this.synthesizeNonVerdictFailureOutput({
|
|
218772
218879
|
stepLabel: this.workflowNodeProgressName(node),
|
|
@@ -218781,8 +218888,10 @@ var init_workflow_graph_executor = __esm({
|
|
|
218781
218888
|
phase: started?.phase ?? (node.config?.phase === "post-merge" ? "post-merge" : "pre-merge"),
|
|
218782
218889
|
source: "node",
|
|
218783
218890
|
status,
|
|
218891
|
+
...this.workflowReviewKind(node) ? { reviewKind: this.workflowReviewKind(node) } : {},
|
|
218784
218892
|
...output !== void 0 ? { output } : {},
|
|
218785
218893
|
...notes !== void 0 ? { notes } : {},
|
|
218894
|
+
...findings?.length ? { findings } : {},
|
|
218786
218895
|
startedAt: started?.startedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
218787
218896
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
218788
218897
|
});
|
|
@@ -224063,9 +224172,11 @@ function parseWorkflowStepVerdict(rawOutput) {
|
|
|
224063
224172
|
verdict = "REVISE";
|
|
224064
224173
|
}
|
|
224065
224174
|
if (!verdict) continue;
|
|
224175
|
+
const findings = normalizeWorkflowReviewFindings(parsed.findings);
|
|
224066
224176
|
return {
|
|
224067
224177
|
verdict,
|
|
224068
|
-
notes: typeof parsed.notes === "string" ? parsed.notes : ""
|
|
224178
|
+
notes: typeof parsed.notes === "string" ? parsed.notes : "",
|
|
224179
|
+
...findings ? { findings } : {}
|
|
224069
224180
|
};
|
|
224070
224181
|
} catch {
|
|
224071
224182
|
}
|
|
@@ -224097,7 +224208,8 @@ function parseWorkflowStepOutput(rawOutput, options = {}) {
|
|
|
224097
224208
|
return {
|
|
224098
224209
|
output: parsed.notes || "",
|
|
224099
224210
|
verdict: parsed.verdict,
|
|
224100
|
-
notes: parsed.notes
|
|
224211
|
+
notes: parsed.notes,
|
|
224212
|
+
...parsed.findings ? { findings: parsed.findings } : {}
|
|
224101
224213
|
};
|
|
224102
224214
|
}
|
|
224103
224215
|
const inferred = inferWorkflowStepVerdictFromProse(trimmed);
|
|
@@ -230358,6 +230470,7 @@ ${info.feedback}`, revisionKey),
|
|
|
230358
230470
|
return this.runCliAgentNode(node, await this.store.getTask(live.id), cfg);
|
|
230359
230471
|
}
|
|
230360
230472
|
const optionalGroupId = typeof graphContext?.[WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY] === "string" ? graphContext[WORKFLOW_OPTIONAL_GROUP_CONTEXT_KEY] : void 0;
|
|
230473
|
+
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;
|
|
230361
230474
|
const isCompletionSummaryNode2 = cfg.summaryTarget === "task" || node.id === "completion-summary";
|
|
230362
230475
|
if (live.executionMode === "fast" && !isCompletionSummaryNode2 && !optionalGroupId && !cfg.seam && (node.kind === "prompt" || node.kind === "script" || node.kind === "gate")) {
|
|
230363
230476
|
executorLog.debug(`${live.id}: fast mode \u2014 skipping custom graph node '${node.id}'`);
|
|
@@ -230506,6 +230619,9 @@ ${prompt}`;
|
|
|
230506
230619
|
if (optionalGroupId) {
|
|
230507
230620
|
step.optionalGroupId = optionalGroupId;
|
|
230508
230621
|
}
|
|
230622
|
+
if (declaredReviewKind) {
|
|
230623
|
+
step.reviewKind = declaredReviewKind;
|
|
230624
|
+
}
|
|
230509
230625
|
if (cfg.reviewCanFixInline === true) {
|
|
230510
230626
|
step.reviewCanFixInline = true;
|
|
230511
230627
|
}
|
|
@@ -230518,7 +230634,11 @@ ${prompt}`;
|
|
|
230518
230634
|
executorLog.debug(`${live.id}: graph node '${node.id}' runtime env injected (${injected.pathEntryCount} PATH entries, ${injected.injectedKeyCount} env keys)`);
|
|
230519
230635
|
}
|
|
230520
230636
|
const unattended = this.graphUnattendedRuns.has(live.id);
|
|
230521
|
-
|
|
230637
|
+
let outcome = mode === "script" ? await this.executeScriptWorkflowStep(live, step, worktreePath, settings, nodeEnv) : await this.executeWorkflowStep(live, step, worktreePath, settings, nodeEnv, { unattended });
|
|
230638
|
+
if (declaredReviewKind && typeof outcome.output === "string") {
|
|
230639
|
+
const parsedReviewOutput = parseWorkflowStepOutput(outcome.output, { requireVerdict: false });
|
|
230640
|
+
if (parsedReviewOutput.findings?.length) outcome = { ...outcome, findings: parsedReviewOutput.findings };
|
|
230641
|
+
}
|
|
230522
230642
|
const awaitQuestion = parseAwaitInputSentinel(outcome.output);
|
|
230523
230643
|
if (awaitQuestion) {
|
|
230524
230644
|
await this.store.logEntry(
|
|
@@ -230541,6 +230661,8 @@ ${prompt}`;
|
|
|
230541
230661
|
const contextPatch = {};
|
|
230542
230662
|
if (typeof stepOutput === "string") contextPatch.output = stepOutput;
|
|
230543
230663
|
if (typeof stepNotes === "string" && stepNotes) contextPatch.notes = stepNotes;
|
|
230664
|
+
const stepFindings = outcome.findings;
|
|
230665
|
+
if (stepFindings?.length) contextPatch.findings = stepFindings;
|
|
230544
230666
|
if (cfg.summaryTarget === "task" && typeof stepOutput === "string" && stepOutput.trim()) {
|
|
230545
230667
|
contextPatch.summary = stepOutput.trim();
|
|
230546
230668
|
}
|
|
@@ -237043,13 +237165,14 @@ CRITICAL SCOPING RULES \u2014 read before doing anything else:
|
|
|
237043
237165
|
const isSkillStep = typeof workflowStep.skillName === "string" && workflowStep.skillName.trim().length > 0;
|
|
237044
237166
|
const isSummaryProjectionStep = workflowStep.summaryTarget === "task";
|
|
237045
237167
|
const requireVerdict = !isSummaryProjectionStep && (workflowStep.gateMode === "gate" || !isSkillStep);
|
|
237168
|
+
const reviewFindingsContract = workflowStepMetadata.reviewKind === "plan" || workflowStepMetadata.reviewKind === "code";
|
|
237046
237169
|
const verdictBlock = requireVerdict ? `
|
|
237047
237170
|
|
|
237048
237171
|
## Feedback Format
|
|
237049
237172
|
|
|
237050
237173
|
When your review is complete, your final line MUST be a single JSON object (no markdown fences):
|
|
237051
237174
|
|
|
237052
|
-
{"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}
|
|
237175
|
+
${reviewFindingsContract ? '{"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"...","findings":[{"id":"stable-id","title":"concise issue","body":"actionable detail","filePath":"optional/path","line":1,"severity":"low|medium|high|critical"}]}' : '{"verdict":"APPROVE|APPROVE_WITH_NOTES|REVISE","notes":"..."}'}
|
|
237053
237176
|
|
|
237054
237177
|
Rules:
|
|
237055
237178
|
- Output exactly one trailing JSON object and stop.
|
|
@@ -237359,7 +237482,8 @@ ${detectedQuestion}
|
|
|
237359
237482
|
revisionRequested,
|
|
237360
237483
|
output: parsed.output,
|
|
237361
237484
|
verdict: parsed.verdict,
|
|
237362
|
-
notes: parsed.notes
|
|
237485
|
+
notes: parsed.notes,
|
|
237486
|
+
...parsed.findings ? { findings: parsed.findings } : {}
|
|
237363
237487
|
};
|
|
237364
237488
|
}
|
|
237365
237489
|
if (parsed.malformed) {
|
|
@@ -261461,7 +261585,7 @@ var init_project_engine = __esm({
|
|
|
261461
261585
|
*
|
|
261462
261586
|
* Readable (not private) so tests derive the cap from this single source of truth rather
|
|
261463
261587
|
* than hardcoding it — the FN-8004 bump broke two suites that had baked in the old `3`. */
|
|
261464
|
-
static MAX_AUTO_MERGE_TRANSIENT_RETRIES =
|
|
261588
|
+
static MAX_AUTO_MERGE_TRANSIENT_RETRIES = MAX_AUTO_MERGE_TRANSIENT_RETRIES;
|
|
261465
261589
|
static MERGE_REQUEST_RETRY_EXHAUSTED_AGE_MS = 30 * 60 * 1e3;
|
|
261466
261590
|
/** Cap on outer in-review→in-progress bounces caused by deterministic
|
|
261467
261591
|
* verification failures during auto-merge. After this many failed merges
|