@runfusion/fusion 0.75.1-beta.0 → 0.75.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +523 -212
- package/dist/child-process-worker.js +323 -99
- package/dist/client/.vite/manifest.json +249 -249
- package/dist/client/assets/{AgentDetailView-swTdiyeE.js → AgentDetailView-ltOG8f0-.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-Dq-KuDaA.js → AgentPermissionPolicyEditor-CC_rrbbG.js} +1 -1
- package/dist/client/assets/{AgentsView-D1GEHyH0.js → AgentsView-DWUdi27N.js} +3 -3
- package/dist/client/assets/{ChatView-D1czGvvT.js → ChatView-mFKfoegS.js} +1 -1
- package/dist/client/assets/{CommandCenter-DWZ7OTOB.js → CommandCenter-C2wvDq_N.js} +1 -1
- package/dist/client/assets/{DevServerView-CAcUKOXd.js → DevServerView-0MWEJM7o.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DVUl5jOk.js → DirectoryPicker-BjMPhCdh.js} +1 -1
- package/dist/client/assets/{DocumentsView-CnexOxtr.js → DocumentsView-ckH3rjmd.js} +1 -1
- package/dist/client/assets/{EvalsView-rTupzcDf.js → EvalsView-NyA644VF.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CXE6Bj3V.js → ExperimentalAgentOnboardingModal-D0ZfbBRN.js} +1 -1
- package/dist/client/assets/{GoalsView-CjHwnnIi.js → GoalsView-Ctt5P_yo.js} +1 -1
- package/dist/client/assets/{InsightsView-C3XocYP-.js → InsightsView-NDp0bdNB.js} +1 -1
- package/dist/client/assets/{MemoryView-CsNHcx_d.js → MemoryView-BKbA4Bm4.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-BPTPoZBI.js → PiExtensionsManager-V3AFWMHm.js} +1 -1
- package/dist/client/assets/{PluginManager-CXadn8JE.js → PluginManager-D88G_TZh.js} +1 -1
- package/dist/client/assets/{PullRequestView-CC03CtZJ.js → PullRequestView-DQQmFFYC.js} +1 -1
- package/dist/client/assets/{ReportModal-Ci0na1eI.js → ReportModal-Clh1S8RF.js} +1 -1
- package/dist/client/assets/{ResearchView-DGWyAo8p.js → ResearchView-kxvq4zp5.js} +1 -1
- package/dist/client/assets/SecretsView-Dm0Vk8SA.js +1 -0
- package/dist/client/assets/{SessionTerminal-B22RlQeo.js → SessionTerminal-DJO4JTEX.js} +1 -1
- package/dist/client/assets/{SettingsModal-BkgBQZ19.js → SettingsModal-BN5mL_ym.js} +1 -1
- package/dist/client/assets/SettingsModal-CTf5voEW.js +21 -0
- package/dist/client/assets/{SettingsTextareaRow-0LXwMUQR.js → SettingsTextareaRow-CvKszqO-.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-CyW3AlRO.js → SetupWizardModal-D5hVZh1G.js} +2 -2
- package/dist/client/assets/{SkillsView-3oqB1ubq.js → SkillsView-DQVz21w2.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-CfUK_xs1.js → WorkflowNodeEditor-CpKIi6Tb.js} +3 -3
- package/dist/client/assets/{agent-import-generation-C7-Cmo3M.js → agent-import-generation-DGUNF3nd.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BQ7ZN1r_.js → architectureDiagram-3BPJPVTR-CV83wubP.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-Debw1Xka.js → blockDiagram-GPEHLZMM-CNQsA3dD.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CiU212s3.js → c4Diagram-AAUBKEIU-CXe7ii5H.js} +1 -1
- package/dist/client/assets/channel-DoX862zl.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-BUJQ86zb.js → chunk-2J33WTMH-BS6W9bWv.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-C6GdEm1z.js → chunk-4BX2VUAB-DbehRhdW.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CImvrxQL.js → chunk-55IACEB6-DMI5SR42.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-Dt-A3pkM.js → chunk-727SXJPM-D1d-GBVj.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DDj4oXTx.js → chunk-AQP2D5EJ-BzO6K3Uf.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BD4r1ukC.js → chunk-FMBD7UC4-BVRLV3lK.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-DFSteefi.js → chunk-ND2GUHAM-DdWByQfn.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-t2zF8tjB.js → chunk-QZHKN3VN-1ia12cRV.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-mb2IeAGN.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-mb2IeAGN.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-tkvDkXQA.js → cose-bilkent-S5V4N54A-BPDT41HR.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-DD2rW7wo.js → dagre-BM42HDAG-Cktn26EH.js} +1 -1
- package/dist/client/assets/{dashboard-view-B1vduc8x.js → dashboard-view-8o0EUcRX.js} +1 -1
- package/dist/client/assets/{dashboard-view-CciuDS5A.js → dashboard-view-CkCerlVJ.js} +1 -1
- package/dist/client/assets/{dashboard-view-DruCruAc.js → dashboard-view-D_HC4lnr.js} +1 -1
- package/dist/client/assets/{dashboard-view-C7jJ1lA4.js → dashboard-view-zd8GxC49.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-DASuxGNc.js → diagram-2AECGRRQ-But4Lvf-.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-f9WtiIUk.js → diagram-5GNKFQAL-2bpQAGFc.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-QivICYCd.js → diagram-KO2AKTUF-Ckn9Qd1u.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CMwcDFHR.js → diagram-LMA3HP47-Bjn8h84N.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-C-vPMeHZ.js → diagram-OG6HWLK6-BI6541hx.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CxGtk9vj.js → erDiagram-TEJ5UH35-BqMiwHiM.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-qBZRZoV1.js → flowDiagram-I6XJVG4X-Q_SAB10M.js} +1 -1
- package/dist/client/assets/{folder-open-Dysi9Zzg.js → folder-open-CHiAJbTN.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DAaXroiu.js → ganttDiagram-6RSMTGT7-CqWFSfPF.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DNUNQot_.js → gitGraphDiagram-PVQCEYII-B1o4uEjO.js} +1 -1
- package/dist/client/assets/index-Bdw5eNKV.css +1 -0
- package/dist/client/assets/index-kwRywd9M.js +2767 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-BSJmWLwh.js → infoDiagram-5YYISTIA-BzaMa0c2.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-AyVKvoDq.js → ishikawaDiagram-YF4QCWOH-I38yge00.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-972txzzd.js → journeyDiagram-JHISSGLW-WVQSgx4P.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-1xiNvIqK.js → kanban-definition-UN3LZRKU-BWtPQ3AH.js} +1 -1
- package/dist/client/assets/{mermaid.core-oeDA8jOm.js → mermaid.core-D1hnBtbi.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DcktmI8s.js → mindmap-definition-RKZ34NQL-DqiSLkW7.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-ekBwLt-O.js → pieDiagram-4H26LBE5-CcgwbdIN.js} +1 -1
- package/dist/client/assets/{puzzle-I6pr6ZrW.js → puzzle-BhXUaTQl.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-D_wjTsvn.js → quadrantDiagram-W4KKPZXB-MsqQQfDN.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CKGHyiJ1.js → requirementDiagram-4Y6WPE33-CILGjMMA.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CtiZFNk5.js → sankeyDiagram-5OEKKPKP-c14fWbtR.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B6OMrfGk.js → sequenceDiagram-3UESZ5HK-BD5bxMom.js} +1 -1
- package/dist/client/assets/{shield-alert-CVMmviMG.js → shield-alert-C9W2WywS.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-Cg1a3tjW.js → standing-instructions-template-CJdbDSyg.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-CyTY2M_7.js → stateDiagram-AJRCARHV-CZ5YqeOn.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-NWPCCiqC.js → stateDiagram-v2-BHNVJYJU-mdMN-PNX.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DU4TVYpw.js → timeline-definition-PNZ67QCA-DHKay9uj.js} +1 -1
- package/dist/client/assets/{upload-VCzeCiFH.js → upload-DxEwowRU.js} +1 -1
- package/dist/client/assets/{users-DB3knZtm.js → users-mNFgW_Zd.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DX0Ppll6.js → vennDiagram-CIIHVFJN-X29K9hWM.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-CBoWxpDv.js → wardley-L42UT6IY-yEoTrfmN.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-B_eVqdhC.js → wardleyDiagram-YWT4CUSO-ny4k3kG0.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DeZzEX0f.js → xychartDiagram-2RQKCTM6-DC8ODtRJ.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +411 -155
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.d.ts +159 -141
- 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/SecretsView-Cv2IuqFO.js +0 -1
- package/dist/client/assets/SettingsModal-CPRpRK71.js +0 -21
- 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/client/assets/index-DHk_s6rA.css +0 -1
|
@@ -10539,6 +10539,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
10539
10539
|
);
|
|
10540
10540
|
}
|
|
10541
10541
|
for (const inner of templateNodes) {
|
|
10542
|
+
validateReviewKind(inner, "nested");
|
|
10542
10543
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
10543
10544
|
throw new WorkflowIrError(
|
|
10544
10545
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10657,6 +10658,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10657
10658
|
);
|
|
10658
10659
|
}
|
|
10659
10660
|
for (const inner of templateNodes) {
|
|
10661
|
+
validateReviewKind(inner, "nested");
|
|
10660
10662
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10661
10663
|
throw new WorkflowIrError(
|
|
10662
10664
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10750,6 +10752,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10750
10752
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10751
10753
|
}
|
|
10752
10754
|
for (const inner of templateNodes) {
|
|
10755
|
+
validateReviewKind(inner, "nested");
|
|
10753
10756
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10754
10757
|
throw new WorkflowIrError(
|
|
10755
10758
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -11421,6 +11424,19 @@ function validateColumnRecovery(column) {
|
|
|
11421
11424
|
);
|
|
11422
11425
|
}
|
|
11423
11426
|
}
|
|
11427
|
+
function validateReviewKind(node, placement) {
|
|
11428
|
+
const value = node.config?.reviewKind;
|
|
11429
|
+
if (value === void 0) return;
|
|
11430
|
+
if (value !== "plan" && value !== "code") {
|
|
11431
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
11432
|
+
}
|
|
11433
|
+
if (placement === "nested") {
|
|
11434
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
11435
|
+
}
|
|
11436
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
11437
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
11424
11440
|
function validateV2(ir) {
|
|
11425
11441
|
validateColumns(ir);
|
|
11426
11442
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -11443,6 +11459,7 @@ function validateV2(ir) {
|
|
|
11443
11459
|
}
|
|
11444
11460
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
11445
11461
|
for (const node of ir.nodes) {
|
|
11462
|
+
validateReviewKind(node, "top-level");
|
|
11446
11463
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
11447
11464
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
11448
11465
|
throw new WorkflowIrError(
|
|
@@ -13613,6 +13630,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13613
13630
|
column,
|
|
13614
13631
|
config: {
|
|
13615
13632
|
name: CODE_REVIEW_NAME,
|
|
13633
|
+
reviewKind: "code",
|
|
13616
13634
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13617
13635
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13618
13636
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13743,6 +13761,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13743
13761
|
...column ? { column } : {},
|
|
13744
13762
|
config: {
|
|
13745
13763
|
name: PLAN_REVIEW_NAME,
|
|
13764
|
+
reviewKind: "plan",
|
|
13746
13765
|
defaultOn: options.defaultOn ?? true,
|
|
13747
13766
|
/*
|
|
13748
13767
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -10539,6 +10539,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
10539
10539
|
);
|
|
10540
10540
|
}
|
|
10541
10541
|
for (const inner of templateNodes) {
|
|
10542
|
+
validateReviewKind(inner, "nested");
|
|
10542
10543
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
10543
10544
|
throw new WorkflowIrError(
|
|
10544
10545
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10657,6 +10658,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10657
10658
|
);
|
|
10658
10659
|
}
|
|
10659
10660
|
for (const inner of templateNodes) {
|
|
10661
|
+
validateReviewKind(inner, "nested");
|
|
10660
10662
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10661
10663
|
throw new WorkflowIrError(
|
|
10662
10664
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10750,6 +10752,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10750
10752
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10751
10753
|
}
|
|
10752
10754
|
for (const inner of templateNodes) {
|
|
10755
|
+
validateReviewKind(inner, "nested");
|
|
10753
10756
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10754
10757
|
throw new WorkflowIrError(
|
|
10755
10758
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -11421,6 +11424,19 @@ function validateColumnRecovery(column) {
|
|
|
11421
11424
|
);
|
|
11422
11425
|
}
|
|
11423
11426
|
}
|
|
11427
|
+
function validateReviewKind(node, placement) {
|
|
11428
|
+
const value = node.config?.reviewKind;
|
|
11429
|
+
if (value === void 0) return;
|
|
11430
|
+
if (value !== "plan" && value !== "code") {
|
|
11431
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
11432
|
+
}
|
|
11433
|
+
if (placement === "nested") {
|
|
11434
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
11435
|
+
}
|
|
11436
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
11437
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
11424
11440
|
function validateV2(ir) {
|
|
11425
11441
|
validateColumns(ir);
|
|
11426
11442
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -11443,6 +11459,7 @@ function validateV2(ir) {
|
|
|
11443
11459
|
}
|
|
11444
11460
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
11445
11461
|
for (const node of ir.nodes) {
|
|
11462
|
+
validateReviewKind(node, "top-level");
|
|
11446
11463
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
11447
11464
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
11448
11465
|
throw new WorkflowIrError(
|
|
@@ -13613,6 +13630,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13613
13630
|
column,
|
|
13614
13631
|
config: {
|
|
13615
13632
|
name: CODE_REVIEW_NAME,
|
|
13633
|
+
reviewKind: "code",
|
|
13616
13634
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13617
13635
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13618
13636
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13743,6 +13761,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13743
13761
|
...column ? { column } : {},
|
|
13744
13762
|
config: {
|
|
13745
13763
|
name: PLAN_REVIEW_NAME,
|
|
13764
|
+
reviewKind: "plan",
|
|
13746
13765
|
defaultOn: options.defaultOn ?? true,
|
|
13747
13766
|
/*
|
|
13748
13767
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -10542,6 +10542,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
10542
10542
|
);
|
|
10543
10543
|
}
|
|
10544
10544
|
for (const inner of templateNodes) {
|
|
10545
|
+
validateReviewKind(inner, "nested");
|
|
10545
10546
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
10546
10547
|
throw new WorkflowIrError(
|
|
10547
10548
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10660,6 +10661,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10660
10661
|
);
|
|
10661
10662
|
}
|
|
10662
10663
|
for (const inner of templateNodes) {
|
|
10664
|
+
validateReviewKind(inner, "nested");
|
|
10663
10665
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10664
10666
|
throw new WorkflowIrError(
|
|
10665
10667
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10753,6 +10755,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10753
10755
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10754
10756
|
}
|
|
10755
10757
|
for (const inner of templateNodes) {
|
|
10758
|
+
validateReviewKind(inner, "nested");
|
|
10756
10759
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10757
10760
|
throw new WorkflowIrError(
|
|
10758
10761
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -11424,6 +11427,19 @@ function validateColumnRecovery(column) {
|
|
|
11424
11427
|
);
|
|
11425
11428
|
}
|
|
11426
11429
|
}
|
|
11430
|
+
function validateReviewKind(node, placement) {
|
|
11431
|
+
const value = node.config?.reviewKind;
|
|
11432
|
+
if (value === void 0) return;
|
|
11433
|
+
if (value !== "plan" && value !== "code") {
|
|
11434
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
11435
|
+
}
|
|
11436
|
+
if (placement === "nested") {
|
|
11437
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
11438
|
+
}
|
|
11439
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
11440
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
11441
|
+
}
|
|
11442
|
+
}
|
|
11427
11443
|
function validateV2(ir) {
|
|
11428
11444
|
validateColumns(ir);
|
|
11429
11445
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -11446,6 +11462,7 @@ function validateV2(ir) {
|
|
|
11446
11462
|
}
|
|
11447
11463
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
11448
11464
|
for (const node of ir.nodes) {
|
|
11465
|
+
validateReviewKind(node, "top-level");
|
|
11449
11466
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
11450
11467
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
11451
11468
|
throw new WorkflowIrError(
|
|
@@ -13616,6 +13633,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13616
13633
|
column,
|
|
13617
13634
|
config: {
|
|
13618
13635
|
name: CODE_REVIEW_NAME,
|
|
13636
|
+
reviewKind: "code",
|
|
13619
13637
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13620
13638
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13621
13639
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13746,6 +13764,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13746
13764
|
...column ? { column } : {},
|
|
13747
13765
|
config: {
|
|
13748
13766
|
name: PLAN_REVIEW_NAME,
|
|
13767
|
+
reviewKind: "plan",
|
|
13749
13768
|
defaultOn: options.defaultOn ?? true,
|
|
13750
13769
|
/*
|
|
13751
13770
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -10659,6 +10659,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
10659
10659
|
);
|
|
10660
10660
|
}
|
|
10661
10661
|
for (const inner of templateNodes) {
|
|
10662
|
+
validateReviewKind(inner, "nested");
|
|
10662
10663
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
10663
10664
|
throw new WorkflowIrError(
|
|
10664
10665
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10777,6 +10778,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10777
10778
|
);
|
|
10778
10779
|
}
|
|
10779
10780
|
for (const inner of templateNodes) {
|
|
10781
|
+
validateReviewKind(inner, "nested");
|
|
10780
10782
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10781
10783
|
throw new WorkflowIrError(
|
|
10782
10784
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10870,6 +10872,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10870
10872
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10871
10873
|
}
|
|
10872
10874
|
for (const inner of templateNodes) {
|
|
10875
|
+
validateReviewKind(inner, "nested");
|
|
10873
10876
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10874
10877
|
throw new WorkflowIrError(
|
|
10875
10878
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -11541,6 +11544,19 @@ function validateColumnRecovery(column) {
|
|
|
11541
11544
|
);
|
|
11542
11545
|
}
|
|
11543
11546
|
}
|
|
11547
|
+
function validateReviewKind(node, placement) {
|
|
11548
|
+
const value = node.config?.reviewKind;
|
|
11549
|
+
if (value === void 0) return;
|
|
11550
|
+
if (value !== "plan" && value !== "code") {
|
|
11551
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
11552
|
+
}
|
|
11553
|
+
if (placement === "nested") {
|
|
11554
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
11555
|
+
}
|
|
11556
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
11557
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
11558
|
+
}
|
|
11559
|
+
}
|
|
11544
11560
|
function validateV2(ir) {
|
|
11545
11561
|
validateColumns(ir);
|
|
11546
11562
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -11563,6 +11579,7 @@ function validateV2(ir) {
|
|
|
11563
11579
|
}
|
|
11564
11580
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
11565
11581
|
for (const node of ir.nodes) {
|
|
11582
|
+
validateReviewKind(node, "top-level");
|
|
11566
11583
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
11567
11584
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
11568
11585
|
throw new WorkflowIrError(
|
|
@@ -13733,6 +13750,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13733
13750
|
column,
|
|
13734
13751
|
config: {
|
|
13735
13752
|
name: CODE_REVIEW_NAME,
|
|
13753
|
+
reviewKind: "code",
|
|
13736
13754
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13737
13755
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13738
13756
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13863,6 +13881,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13863
13881
|
...column ? { column } : {},
|
|
13864
13882
|
config: {
|
|
13865
13883
|
name: PLAN_REVIEW_NAME,
|
|
13884
|
+
reviewKind: "plan",
|
|
13866
13885
|
defaultOn: options.defaultOn ?? true,
|
|
13867
13886
|
/*
|
|
13868
13887
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -10539,6 +10539,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
10539
10539
|
);
|
|
10540
10540
|
}
|
|
10541
10541
|
for (const inner of templateNodes) {
|
|
10542
|
+
validateReviewKind(inner, "nested");
|
|
10542
10543
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
10543
10544
|
throw new WorkflowIrError(
|
|
10544
10545
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10657,6 +10658,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10657
10658
|
);
|
|
10658
10659
|
}
|
|
10659
10660
|
for (const inner of templateNodes) {
|
|
10661
|
+
validateReviewKind(inner, "nested");
|
|
10660
10662
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10661
10663
|
throw new WorkflowIrError(
|
|
10662
10664
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10750,6 +10752,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10750
10752
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10751
10753
|
}
|
|
10752
10754
|
for (const inner of templateNodes) {
|
|
10755
|
+
validateReviewKind(inner, "nested");
|
|
10753
10756
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10754
10757
|
throw new WorkflowIrError(
|
|
10755
10758
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -11421,6 +11424,19 @@ function validateColumnRecovery(column) {
|
|
|
11421
11424
|
);
|
|
11422
11425
|
}
|
|
11423
11426
|
}
|
|
11427
|
+
function validateReviewKind(node, placement) {
|
|
11428
|
+
const value = node.config?.reviewKind;
|
|
11429
|
+
if (value === void 0) return;
|
|
11430
|
+
if (value !== "plan" && value !== "code") {
|
|
11431
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
11432
|
+
}
|
|
11433
|
+
if (placement === "nested") {
|
|
11434
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
11435
|
+
}
|
|
11436
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
11437
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
11424
11440
|
function validateV2(ir) {
|
|
11425
11441
|
validateColumns(ir);
|
|
11426
11442
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -11443,6 +11459,7 @@ function validateV2(ir) {
|
|
|
11443
11459
|
}
|
|
11444
11460
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
11445
11461
|
for (const node of ir.nodes) {
|
|
11462
|
+
validateReviewKind(node, "top-level");
|
|
11446
11463
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
11447
11464
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
11448
11465
|
throw new WorkflowIrError(
|
|
@@ -13613,6 +13630,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13613
13630
|
column,
|
|
13614
13631
|
config: {
|
|
13615
13632
|
name: CODE_REVIEW_NAME,
|
|
13633
|
+
reviewKind: "code",
|
|
13616
13634
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13617
13635
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13618
13636
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13743,6 +13761,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13743
13761
|
...column ? { column } : {},
|
|
13744
13762
|
config: {
|
|
13745
13763
|
name: PLAN_REVIEW_NAME,
|
|
13764
|
+
reviewKind: "plan",
|
|
13746
13765
|
defaultOn: options.defaultOn ?? true,
|
|
13747
13766
|
/*
|
|
13748
13767
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -10539,6 +10539,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
10539
10539
|
);
|
|
10540
10540
|
}
|
|
10541
10541
|
for (const inner of templateNodes) {
|
|
10542
|
+
validateReviewKind(inner, "nested");
|
|
10542
10543
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
10543
10544
|
throw new WorkflowIrError(
|
|
10544
10545
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10657,6 +10658,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
10657
10658
|
);
|
|
10658
10659
|
}
|
|
10659
10660
|
for (const inner of templateNodes) {
|
|
10661
|
+
validateReviewKind(inner, "nested");
|
|
10660
10662
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
10661
10663
|
throw new WorkflowIrError(
|
|
10662
10664
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -10750,6 +10752,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
10750
10752
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
10751
10753
|
}
|
|
10752
10754
|
for (const inner of templateNodes) {
|
|
10755
|
+
validateReviewKind(inner, "nested");
|
|
10753
10756
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
10754
10757
|
throw new WorkflowIrError(
|
|
10755
10758
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -11421,6 +11424,19 @@ function validateColumnRecovery(column) {
|
|
|
11421
11424
|
);
|
|
11422
11425
|
}
|
|
11423
11426
|
}
|
|
11427
|
+
function validateReviewKind(node, placement) {
|
|
11428
|
+
const value2 = node.config?.reviewKind;
|
|
11429
|
+
if (value2 === void 0) return;
|
|
11430
|
+
if (value2 !== "plan" && value2 !== "code") {
|
|
11431
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value2)}'; expected 'plan' or 'code'`);
|
|
11432
|
+
}
|
|
11433
|
+
if (placement === "nested") {
|
|
11434
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
11435
|
+
}
|
|
11436
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
11437
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
11424
11440
|
function validateV2(ir) {
|
|
11425
11441
|
validateColumns(ir);
|
|
11426
11442
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -11443,6 +11459,7 @@ function validateV2(ir) {
|
|
|
11443
11459
|
}
|
|
11444
11460
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
11445
11461
|
for (const node of ir.nodes) {
|
|
11462
|
+
validateReviewKind(node, "top-level");
|
|
11446
11463
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
11447
11464
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
11448
11465
|
throw new WorkflowIrError(
|
|
@@ -13613,6 +13630,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
13613
13630
|
column,
|
|
13614
13631
|
config: {
|
|
13615
13632
|
name: CODE_REVIEW_NAME,
|
|
13633
|
+
reviewKind: "code",
|
|
13616
13634
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
13617
13635
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
13618
13636
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -13743,6 +13761,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
13743
13761
|
...column ? { column } : {},
|
|
13744
13762
|
config: {
|
|
13745
13763
|
name: PLAN_REVIEW_NAME,
|
|
13764
|
+
reviewKind: "plan",
|
|
13746
13765
|
defaultOn: options.defaultOn ?? true,
|
|
13747
13766
|
/*
|
|
13748
13767
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
|
@@ -167840,6 +167840,7 @@ function validateForeach(node, topLevelNodeIds, columnIds) {
|
|
|
167840
167840
|
);
|
|
167841
167841
|
}
|
|
167842
167842
|
for (const inner of templateNodes) {
|
|
167843
|
+
validateReviewKind(inner, "nested");
|
|
167843
167844
|
if (inner.kind === "foreach" || inner.kind === "loop") {
|
|
167844
167845
|
throw new WorkflowIrError(
|
|
167845
167846
|
`foreach node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -167958,6 +167959,7 @@ function validateLoop(node, topLevelNodeIds, columnIds) {
|
|
|
167958
167959
|
);
|
|
167959
167960
|
}
|
|
167960
167961
|
for (const inner of templateNodes) {
|
|
167962
|
+
validateReviewKind(inner, "nested");
|
|
167961
167963
|
if (inner.kind === "loop" || inner.kind === "foreach") {
|
|
167962
167964
|
throw new WorkflowIrError(
|
|
167963
167965
|
`loop node '${node.id}' template may not contain nested loop/foreach ('${inner.id}')`
|
|
@@ -168051,6 +168053,7 @@ function validateOptionalGroup(node, topLevelNodeIds, columnIds) {
|
|
|
168051
168053
|
throw new WorkflowIrError(`optional-group node '${node.id}' template has duplicate node ids`);
|
|
168052
168054
|
}
|
|
168053
168055
|
for (const inner of templateNodes) {
|
|
168056
|
+
validateReviewKind(inner, "nested");
|
|
168054
168057
|
if (inner.kind === "loop" || inner.kind === "foreach" || inner.kind === "optional-group") {
|
|
168055
168058
|
throw new WorkflowIrError(
|
|
168056
168059
|
`optional-group node '${node.id}' template may not contain nested loop/foreach/optional-group ('${inner.id}')`
|
|
@@ -168722,6 +168725,19 @@ function validateColumnRecovery(column) {
|
|
|
168722
168725
|
);
|
|
168723
168726
|
}
|
|
168724
168727
|
}
|
|
168728
|
+
function validateReviewKind(node, placement) {
|
|
168729
|
+
const value = node.config?.reviewKind;
|
|
168730
|
+
if (value === void 0) return;
|
|
168731
|
+
if (value !== "plan" && value !== "code") {
|
|
168732
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has invalid reviewKind '${String(value)}'; expected 'plan' or 'code'`);
|
|
168733
|
+
}
|
|
168734
|
+
if (placement === "nested") {
|
|
168735
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind in an unsupported nested template placement`);
|
|
168736
|
+
}
|
|
168737
|
+
if (node.kind !== "prompt" && node.kind !== "gate" && node.kind !== "script" && node.kind !== "optional-group") {
|
|
168738
|
+
throw new WorkflowIrError(`Workflow node '${node.id}' has reviewKind on unsupported node kind '${node.kind}'`);
|
|
168739
|
+
}
|
|
168740
|
+
}
|
|
168725
168741
|
function validateV2(ir) {
|
|
168726
168742
|
validateColumns(ir);
|
|
168727
168743
|
for (const [index2, column] of ir.columns.entries()) {
|
|
@@ -168744,6 +168760,7 @@ function validateV2(ir) {
|
|
|
168744
168760
|
}
|
|
168745
168761
|
const nodesById = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
168746
168762
|
for (const node of ir.nodes) {
|
|
168763
|
+
validateReviewKind(node, "top-level");
|
|
168747
168764
|
validateExtensionMetadata(`Workflow node '${node.id}'`, node.extensions);
|
|
168748
168765
|
if (node.column !== void 0 && !columnIds.has(node.column)) {
|
|
168749
168766
|
throw new WorkflowIrError(
|
|
@@ -170914,6 +170931,7 @@ function codeReviewOptionalGroupNode(column, options = {}) {
|
|
|
170914
170931
|
column,
|
|
170915
170932
|
config: {
|
|
170916
170933
|
name: CODE_REVIEW_NAME,
|
|
170934
|
+
reviewKind: "code",
|
|
170917
170935
|
// Default-ON: runs for every coding task by default, but operators can toggle it
|
|
170918
170936
|
// off per task (remove `code-review` from enabledWorkflowSteps).
|
|
170919
170937
|
defaultOn: options.defaultOn ?? true,
|
|
@@ -171044,6 +171062,7 @@ function planReviewOptionalGroupNode(column, options = {}) {
|
|
|
171044
171062
|
...column ? { column } : {},
|
|
171045
171063
|
config: {
|
|
171046
171064
|
name: PLAN_REVIEW_NAME,
|
|
171065
|
+
reviewKind: "plan",
|
|
171047
171066
|
defaultOn: options.defaultOn ?? true,
|
|
171048
171067
|
/*
|
|
171049
171068
|
* FNXC:WorkflowRemediation 2026-06-29-12:14:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.75.1-beta.
|
|
3
|
+
"version": "0.75.1-beta.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as c,j as e}from"./vendor-react-SZ_qB27O.js";import{V as he,o as me,R as J,P as ye,E as Y,p as z,q as xe,u as ve,v as be,x as je,C as fe,g as Se,y as ge}from"./index-D0QgE5F5.js";import{u as Ne}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";const Ce="__sync_passphrase__",L={key:"",value:"",description:"",scope:"project",accessPolicy:"prompt",envExportable:!1,envExportKey:""},n={className:"secrets-action-icon","aria-hidden":!0,style:{width:"1em",height:"1em"}},Pe={...n,className:"secrets-action-icon spin"},Me=({addToast:i})=>{const{t:a}=Ne("app"),[R,G]=c.useState([]),[T,M]=c.useState(!0),[A,D]=c.useState(null),[K,b]=c.useState(null),[p,O]=c.useState(null),[U,x]=c.useState(!1),[Q,g]=c.useState(null),[t,l]=c.useState(L),[N,C]=c.useState(!1),[V,j]=c.useState({}),[W,F]=c.useState(null),[u,X]=c.useState(!1),[Z,_]=c.useState(!1),[f,B]=c.useState(""),[P,$]=c.useState(""),[ee,H]=c.useState(!1),[E,se]=c.useState(!1),h=c.useRef(new Map),w=c.useRef(new Map),o=c.useCallback(async(s,r)=>{const d=await fetch(s,{...r,headers:{"Content-Type":"application/json",...r?.headers??{}}});if(!d.ok){const m=await d.json().catch(()=>({error:"Request failed"}));throw new Error(String(m?.error??"Request failed"))}if(d.status!==204)return d.json()},[]),v=c.useCallback(async()=>{M(!0),D(null);try{const s=await o("/api/secrets");G(s.secrets)}catch(s){D(s instanceof Error?s.message:String(s))}finally{M(!1)}},[o]),S=c.useCallback(async()=>{try{const s=await o("/api/secrets/sync-passphrase");X(!!s.configured)}catch(s){i?.(a("secrets.errorLoadSyncStatus","Failed to load sync passphrase status: {{error}}",{error:s instanceof Error?s.message:String(s)}),"error")}},[i,o]);c.useEffect(()=>(v(),S(),()=>{h.current.forEach(s=>clearTimeout(s)),w.current.forEach(s=>clearTimeout(s))}),[v,S]);const k=()=>{_(!1),B(""),$("")},ae=async s=>{await o("/api/secrets/sync-passphrase",{method:"PUT",body:JSON.stringify({passphrase:s})})},re=async()=>{H(!0);try{await ae(f),i?.(u?a("secrets.syncPassphraseRotated","Sync passphrase rotated"):a("secrets.syncPassphraseSet","Sync passphrase set"),"success"),k(),await S()}catch(s){i?.(a("secrets.errorSaveSyncPassphrase","Failed to save sync passphrase: {{error}}",{error:s instanceof Error?s.message:String(s)}),"error")}finally{H(!1)}},te=async()=>{if(window.confirm(a("secrets.confirmClearSyncPassphrase","Clear the cross-node sync passphrase? Existing sync pairs will stop working until you set a new passphrase.")))try{await o("/api/secrets/sync-passphrase",{method:"DELETE"}),i?.(a("secrets.syncPassphraseCleared","Sync passphrase cleared"),"success"),await S()}catch(r){i?.(a("secrets.errorClearSyncPassphrase","Failed to clear sync passphrase: {{error}}",{error:r instanceof Error?r.message:String(r)}),"error")}},ce=()=>{O(null),l(L),x(!0),C(!1),b(null)},le=s=>{O(s),l({key:s.key,value:"",description:s.description??"",scope:s.scope,accessPolicy:s.accessPolicy,envExportable:s.envExportable,envExportKey:s.envExportKey??""}),x(!0),C(!1),b(null)},ne=async()=>{b(null);try{if(p){const s={key:t.key,description:t.description||null,accessPolicy:t.accessPolicy,envExportable:t.envExportable,envExportKey:t.envExportable&&t.envExportKey||null};t.value&&(s.value=t.value),await o(`/api/secrets/${p.scope}/${p.id}`,{method:"PATCH",body:JSON.stringify(s)})}else await o("/api/secrets",{method:"POST",body:JSON.stringify({scope:t.scope,key:t.key,value:t.value,description:t.description||null,accessPolicy:t.accessPolicy,envExportable:t.envExportable,envExportKey:t.envExportable&&t.envExportKey||null})});x(!1),l(L),await v()}catch(s){b(s instanceof Error?s.message:String(s))}},oe=s=>{const r=h.current.get(s.id);r&&(clearTimeout(r),h.current.delete(s.id)),j(d=>({...d,[s.id]:null}))},ie=async s=>{const r=await o(`/api/secrets/${s.scope}/${s.id}/reveal`,{method:"POST"});j(y=>({...y,[s.id]:r.value})),i?.(a("secrets.revealed","Revealed"),"success");const d=setTimeout(()=>{j(y=>({...y,[s.id]:null})),h.current.delete(s.id)},3e4),m=h.current.get(s.id);m&&clearTimeout(m),h.current.set(s.id,d)},de=async s=>{const r=V[s.id];if(!r)return;if(!await ge(r)){i?.(a("secrets.copyFailed","Failed to copy secret"),"error");return}F(s.id),i?.(a("secrets.copied","Copied"),"success");const m=setTimeout(()=>{F(null),j(ue=>({...ue,[s.id]:null}))},1500),y=w.current.get(s.id);y&&clearTimeout(y),w.current.set(s.id,m)},pe=async s=>{await o(`/api/secrets/${s.scope}/${s.id}`,{method:"DELETE"}),g(null),await v()},I=c.useMemo(()=>[...R].filter(s=>!(s.scope==="global"&&s.key===Ce)).sort((s,r)=>s.key.localeCompare(r.key)),[R]),q=f.length>0&&f===P;return e.jsxs("section",{className:"secrets-view",children:[e.jsx(he,{icon:me,title:a("secrets.title","Secrets"),actions:e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void v(),children:[e.jsx(J,{...n})," ",a("secrets.refresh","Refresh")]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:ce,children:[e.jsx(ye,{...n})," ",a("secrets.addSecret","Add Secret")]})]})}),A?e.jsx("div",{className:"form-error",children:A}):null,T?e.jsxs("div",{className:"secrets-loading",children:[e.jsx(J,{...Pe})," ",a("secrets.loading","Loading…")]}):null,!T&&I.length===0?e.jsx("div",{className:"secrets-empty",children:a("secrets.empty","No secrets found.")}):null,e.jsx("div",{className:"secrets-list",children:I.map(s=>{const r=V[s.id];return e.jsxs("article",{className:"card secrets-row",children:[e.jsxs("div",{className:"secrets-row-main",children:[e.jsx("div",{className:"secrets-row-key",children:s.key}),e.jsxs("div",{className:"secrets-row-meta",children:[e.jsx("span",{className:"secrets-chip",children:s.scope}),e.jsx("span",{className:"secrets-chip",children:s.accessPolicy}),s.envExportable?e.jsx("span",{className:"secrets-chip",children:a("secrets.envExportableChip","env exportable")}):null]}),r?e.jsx("pre",{className:"secrets-revealed",children:r}):null]}),e.jsxs("div",{className:"secrets-row-side",children:[e.jsx("span",{className:"secrets-row-read",children:s.lastReadAt?new Date(s.lastReadAt).toLocaleString():a("secrets.neverRead","Never read")}),e.jsxs("div",{className:"secrets-row-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>{if(r){oe(s);return}ie(s)},"aria-label":r?a("secrets.hideAriaLabel","Hide"):a("secrets.revealAriaLabel","Reveal"),children:r?e.jsx(Y,{...n}):e.jsx(z,{...n})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>void de(s),"aria-label":a("secrets.copyAriaLabel","Copy"),disabled:!r,children:W===s.id?e.jsx(xe,{...n}):e.jsx(ve,{...n})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>le(s),"aria-label":a("secrets.editAriaLabel","Edit"),children:e.jsx(be,{...n})}),e.jsx("button",{className:"btn btn-icon btn-danger",onClick:()=>g(s.id),"aria-label":a("secrets.deleteAriaLabel","Delete"),children:e.jsx(je,{...n})})]}),Q===s.id?e.jsxs("div",{className:"secrets-confirm",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void pe(s),children:a("secrets.confirmDelete","Confirm")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>g(null),children:a("secrets.cancelDelete","Cancel")})]}):null]})]},s.id)})}),e.jsxs("article",{className:"card secrets-sync-card secrets-sync-disclosure",children:[e.jsxs("button",{type:"button",className:"secrets-sync-disclosure-toggle","data-testid":"secrets-passphrase-disclosure","aria-expanded":E,"aria-controls":"secrets-sync-disclosure-panel",onClick:()=>se(s=>!s),children:[E?e.jsx(fe,{size:16,"aria-hidden":"true"}):e.jsx(Se,{size:16,"aria-hidden":"true"}),e.jsx("span",{children:a("secrets.syncPassphraseTitle","Cross-Node Sync Passphrase")})]}),E?e.jsxs("div",{id:"secrets-sync-disclosure-panel",className:"secrets-sync-disclosure-panel",children:[e.jsxs("div",{className:"secrets-sync-header",children:[e.jsxs("p",{className:"secrets-sync-status",children:[e.jsx("span",{className:`status-dot ${u?"status-dot--online":"status-dot--pending"}`,"aria-hidden":"true"})," ",u?a("secrets.syncConfigured","Configured"):a("secrets.syncNotConfigured","Not configured")]}),e.jsxs("div",{className:"secrets-sync-actions",children:[e.jsx("button",{className:"btn",onClick:()=>_(!0),children:u?a("secrets.rotateSyncPassphrase","Rotate"):a("secrets.setPassphrase","Set passphrase")}),u?e.jsx("button",{className:"btn btn-danger",onClick:()=>void te(),children:a("secrets.clearSyncPassphrase","Clear")}):null]})]}),e.jsx("p",{className:"secrets-sync-copy",children:a("secrets.syncPassphraseDescription","Shared passphrase used to wrap cross-node secret bundles. Both nodes in a sync pair must share the same value. Stored locally only; never transmitted.")})]}):null]}),Z?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":u?a("secrets.rotateSyncPassphraseModalTitle","Rotate sync passphrase"):a("secrets.setSyncPassphraseModalTitle","Set sync passphrase"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:u?a("secrets.rotateSyncPassphraseModalTitle","Rotate sync passphrase"):a("secrets.setSyncPassphraseModalTitle","Set sync passphrase")}),e.jsx("button",{className:"modal-close",onClick:k,"aria-label":a("secrets.closeAriaLabel","Close"),children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.passphraseLabel","Passphrase")}),e.jsx("input",{"aria-label":a("secrets.passphraseLabel","Passphrase"),className:"input",type:"password",autoComplete:"new-password",value:f,onChange:s=>B(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.confirmPassphraseLabel","Confirm passphrase")}),e.jsx("input",{"aria-label":a("secrets.confirmPassphraseLabel","Confirm passphrase"),className:"input",type:"password",autoComplete:"new-password",value:P,onChange:s=>$(s.target.value)})]}),!q&&P.length>0?e.jsx("div",{className:"form-error",children:a("secrets.passphraseMustMatch","Passphrases must match.")}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:k,children:a("secrets.cancelBtn","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void re(),disabled:!q||ee,children:u?a("secrets.rotateSyncPassphrase","Rotate"):a("secrets.setPassphrase","Set passphrase")})]})})]})}):null,U?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":p?a("secrets.editSecretModalTitle","Edit secret"):a("secrets.addSecretModalTitle","Add secret"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:p?a("secrets.editSecretModalTitle","Edit secret"):a("secrets.addSecretModalTitle","Add secret")}),e.jsx("button",{className:"modal-close",onClick:()=>x(!1),"aria-label":a("secrets.closeAriaLabel","Close"),children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.keyLabel","Key")}),e.jsx("input",{className:"input",value:t.key,onChange:s=>l(r=>({...r,key:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.valueLabel","Value")}),e.jsxs("div",{className:"secrets-value-row",children:[e.jsx("input",{className:"input",type:N?"text":"password",autoComplete:"off",spellCheck:!1,value:t.value,onChange:s=>l(r=>({...r,value:s.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>C(s=>!s),"aria-label":N?a("secrets.hideValueAriaLabel","Hide value"):a("secrets.showValueAriaLabel","Show value"),children:N?e.jsx(Y,{...n}):e.jsx(z,{...n})})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.descriptionLabel","Description")}),e.jsx("textarea",{className:"input",value:t.description,onChange:s=>l(r=>({...r,description:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.scopeLabel","Scope")}),e.jsxs("div",{className:"secrets-radio-row",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:t.scope==="project",onChange:()=>l(s=>({...s,scope:"project"})),disabled:!!p})," ",a("secrets.scopeProject","Project")]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:t.scope==="global",onChange:()=>l(s=>({...s,scope:"global"})),disabled:!!p})," ",a("secrets.scopeGlobal","Global")]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.accessPolicyLabel","Access policy")}),e.jsxs("select",{className:"select",value:t.accessPolicy,onChange:s=>l(r=>({...r,accessPolicy:s.target.value})),children:[e.jsx("option",{value:"auto",children:a("secrets.accessPolicyAuto","auto")}),e.jsx("option",{value:"prompt",children:a("secrets.accessPolicyPrompt","prompt")}),e.jsx("option",{value:"deny",children:a("secrets.accessPolicyDeny","deny")})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:t.envExportable,onChange:s=>l(r=>({...r,envExportable:s.target.checked}))})," ",a("secrets.exportToEnvLabel","Export to env")]})}),t.envExportable?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.envKeyLabel","Env key")}),e.jsx("input",{className:"input",value:t.envExportKey,onChange:s=>l(r=>({...r,envExportKey:s.target.value}))})]}):null,K?e.jsx("div",{className:"form-error",children:K}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:()=>x(!1),children:a("secrets.cancelBtn","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void ne(),children:p?a("secrets.saveBtn","Save"):a("secrets.createBtn","Create")})]})})]})}):null]})};export{Me as SecretsView};
|