@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.
Files changed (136) hide show
  1. package/dist/bin.js +523 -212
  2. package/dist/child-process-worker.js +323 -99
  3. package/dist/client/.vite/manifest.json +249 -249
  4. package/dist/client/assets/{AgentDetailView-swTdiyeE.js → AgentDetailView-ltOG8f0-.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-Dq-KuDaA.js → AgentPermissionPolicyEditor-CC_rrbbG.js} +1 -1
  6. package/dist/client/assets/{AgentsView-D1GEHyH0.js → AgentsView-DWUdi27N.js} +3 -3
  7. package/dist/client/assets/{ChatView-D1czGvvT.js → ChatView-mFKfoegS.js} +1 -1
  8. package/dist/client/assets/{CommandCenter-DWZ7OTOB.js → CommandCenter-C2wvDq_N.js} +1 -1
  9. package/dist/client/assets/{DevServerView-CAcUKOXd.js → DevServerView-0MWEJM7o.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-DVUl5jOk.js → DirectoryPicker-BjMPhCdh.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-CnexOxtr.js → DocumentsView-ckH3rjmd.js} +1 -1
  12. package/dist/client/assets/{EvalsView-rTupzcDf.js → EvalsView-NyA644VF.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-CXE6Bj3V.js → ExperimentalAgentOnboardingModal-D0ZfbBRN.js} +1 -1
  14. package/dist/client/assets/{GoalsView-CjHwnnIi.js → GoalsView-Ctt5P_yo.js} +1 -1
  15. package/dist/client/assets/{InsightsView-C3XocYP-.js → InsightsView-NDp0bdNB.js} +1 -1
  16. package/dist/client/assets/{MemoryView-CsNHcx_d.js → MemoryView-BKbA4Bm4.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-BPTPoZBI.js → PiExtensionsManager-V3AFWMHm.js} +1 -1
  18. package/dist/client/assets/{PluginManager-CXadn8JE.js → PluginManager-D88G_TZh.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-CC03CtZJ.js → PullRequestView-DQQmFFYC.js} +1 -1
  20. package/dist/client/assets/{ReportModal-Ci0na1eI.js → ReportModal-Clh1S8RF.js} +1 -1
  21. package/dist/client/assets/{ResearchView-DGWyAo8p.js → ResearchView-kxvq4zp5.js} +1 -1
  22. package/dist/client/assets/SecretsView-Dm0Vk8SA.js +1 -0
  23. package/dist/client/assets/{SessionTerminal-B22RlQeo.js → SessionTerminal-DJO4JTEX.js} +1 -1
  24. package/dist/client/assets/{SettingsModal-BkgBQZ19.js → SettingsModal-BN5mL_ym.js} +1 -1
  25. package/dist/client/assets/SettingsModal-CTf5voEW.js +21 -0
  26. package/dist/client/assets/{SettingsTextareaRow-0LXwMUQR.js → SettingsTextareaRow-CvKszqO-.js} +1 -1
  27. package/dist/client/assets/{SetupWizardModal-CyW3AlRO.js → SetupWizardModal-D5hVZh1G.js} +2 -2
  28. package/dist/client/assets/{SkillsView-3oqB1ubq.js → SkillsView-DQVz21w2.js} +1 -1
  29. package/dist/client/assets/{WorkflowNodeEditor-CfUK_xs1.js → WorkflowNodeEditor-CpKIi6Tb.js} +3 -3
  30. package/dist/client/assets/{agent-import-generation-C7-Cmo3M.js → agent-import-generation-DGUNF3nd.js} +1 -1
  31. package/dist/client/assets/{architectureDiagram-3BPJPVTR-BQ7ZN1r_.js → architectureDiagram-3BPJPVTR-CV83wubP.js} +1 -1
  32. package/dist/client/assets/{blockDiagram-GPEHLZMM-Debw1Xka.js → blockDiagram-GPEHLZMM-CNQsA3dD.js} +1 -1
  33. package/dist/client/assets/{c4Diagram-AAUBKEIU-CiU212s3.js → c4Diagram-AAUBKEIU-CXe7ii5H.js} +1 -1
  34. package/dist/client/assets/channel-DoX862zl.js +1 -0
  35. package/dist/client/assets/{chunk-2J33WTMH-BUJQ86zb.js → chunk-2J33WTMH-BS6W9bWv.js} +1 -1
  36. package/dist/client/assets/{chunk-4BX2VUAB-C6GdEm1z.js → chunk-4BX2VUAB-DbehRhdW.js} +1 -1
  37. package/dist/client/assets/{chunk-55IACEB6-CImvrxQL.js → chunk-55IACEB6-DMI5SR42.js} +1 -1
  38. package/dist/client/assets/{chunk-727SXJPM-Dt-A3pkM.js → chunk-727SXJPM-D1d-GBVj.js} +1 -1
  39. package/dist/client/assets/{chunk-AQP2D5EJ-DDj4oXTx.js → chunk-AQP2D5EJ-BzO6K3Uf.js} +1 -1
  40. package/dist/client/assets/{chunk-FMBD7UC4-BD4r1ukC.js → chunk-FMBD7UC4-BVRLV3lK.js} +1 -1
  41. package/dist/client/assets/{chunk-ND2GUHAM-DFSteefi.js → chunk-ND2GUHAM-DdWByQfn.js} +1 -1
  42. package/dist/client/assets/{chunk-QZHKN3VN-t2zF8tjB.js → chunk-QZHKN3VN-1ia12cRV.js} +1 -1
  43. package/dist/client/assets/classDiagram-4FO5ZUOK-mb2IeAGN.js +1 -0
  44. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-mb2IeAGN.js +1 -0
  45. package/dist/client/assets/{cose-bilkent-S5V4N54A-tkvDkXQA.js → cose-bilkent-S5V4N54A-BPDT41HR.js} +1 -1
  46. package/dist/client/assets/{dagre-BM42HDAG-DD2rW7wo.js → dagre-BM42HDAG-Cktn26EH.js} +1 -1
  47. package/dist/client/assets/{dashboard-view-B1vduc8x.js → dashboard-view-8o0EUcRX.js} +1 -1
  48. package/dist/client/assets/{dashboard-view-CciuDS5A.js → dashboard-view-CkCerlVJ.js} +1 -1
  49. package/dist/client/assets/{dashboard-view-DruCruAc.js → dashboard-view-D_HC4lnr.js} +1 -1
  50. package/dist/client/assets/{dashboard-view-C7jJ1lA4.js → dashboard-view-zd8GxC49.js} +1 -1
  51. package/dist/client/assets/{diagram-2AECGRRQ-DASuxGNc.js → diagram-2AECGRRQ-But4Lvf-.js} +1 -1
  52. package/dist/client/assets/{diagram-5GNKFQAL-f9WtiIUk.js → diagram-5GNKFQAL-2bpQAGFc.js} +1 -1
  53. package/dist/client/assets/{diagram-KO2AKTUF-QivICYCd.js → diagram-KO2AKTUF-Ckn9Qd1u.js} +1 -1
  54. package/dist/client/assets/{diagram-LMA3HP47-CMwcDFHR.js → diagram-LMA3HP47-Bjn8h84N.js} +1 -1
  55. package/dist/client/assets/{diagram-OG6HWLK6-C-vPMeHZ.js → diagram-OG6HWLK6-BI6541hx.js} +1 -1
  56. package/dist/client/assets/{erDiagram-TEJ5UH35-CxGtk9vj.js → erDiagram-TEJ5UH35-BqMiwHiM.js} +1 -1
  57. package/dist/client/assets/{flowDiagram-I6XJVG4X-qBZRZoV1.js → flowDiagram-I6XJVG4X-Q_SAB10M.js} +1 -1
  58. package/dist/client/assets/{folder-open-Dysi9Zzg.js → folder-open-CHiAJbTN.js} +1 -1
  59. package/dist/client/assets/{ganttDiagram-6RSMTGT7-DAaXroiu.js → ganttDiagram-6RSMTGT7-CqWFSfPF.js} +1 -1
  60. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DNUNQot_.js → gitGraphDiagram-PVQCEYII-B1o4uEjO.js} +1 -1
  61. package/dist/client/assets/index-Bdw5eNKV.css +1 -0
  62. package/dist/client/assets/index-kwRywd9M.js +2767 -0
  63. package/dist/client/assets/{infoDiagram-5YYISTIA-BSJmWLwh.js → infoDiagram-5YYISTIA-BzaMa0c2.js} +1 -1
  64. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-AyVKvoDq.js → ishikawaDiagram-YF4QCWOH-I38yge00.js} +1 -1
  65. package/dist/client/assets/{journeyDiagram-JHISSGLW-972txzzd.js → journeyDiagram-JHISSGLW-WVQSgx4P.js} +1 -1
  66. package/dist/client/assets/{kanban-definition-UN3LZRKU-1xiNvIqK.js → kanban-definition-UN3LZRKU-BWtPQ3AH.js} +1 -1
  67. package/dist/client/assets/{mermaid.core-oeDA8jOm.js → mermaid.core-D1hnBtbi.js} +4 -4
  68. package/dist/client/assets/{mindmap-definition-RKZ34NQL-DcktmI8s.js → mindmap-definition-RKZ34NQL-DqiSLkW7.js} +1 -1
  69. package/dist/client/assets/{pieDiagram-4H26LBE5-ekBwLt-O.js → pieDiagram-4H26LBE5-CcgwbdIN.js} +1 -1
  70. package/dist/client/assets/{puzzle-I6pr6ZrW.js → puzzle-BhXUaTQl.js} +1 -1
  71. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-D_wjTsvn.js → quadrantDiagram-W4KKPZXB-MsqQQfDN.js} +1 -1
  72. package/dist/client/assets/{requirementDiagram-4Y6WPE33-CKGHyiJ1.js → requirementDiagram-4Y6WPE33-CILGjMMA.js} +1 -1
  73. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CtiZFNk5.js → sankeyDiagram-5OEKKPKP-c14fWbtR.js} +1 -1
  74. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B6OMrfGk.js → sequenceDiagram-3UESZ5HK-BD5bxMom.js} +1 -1
  75. package/dist/client/assets/{shield-alert-CVMmviMG.js → shield-alert-C9W2WywS.js} +1 -1
  76. package/dist/client/assets/{standing-instructions-template-Cg1a3tjW.js → standing-instructions-template-CJdbDSyg.js} +1 -1
  77. package/dist/client/assets/{stateDiagram-AJRCARHV-CyTY2M_7.js → stateDiagram-AJRCARHV-CZ5YqeOn.js} +1 -1
  78. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-NWPCCiqC.js → stateDiagram-v2-BHNVJYJU-mdMN-PNX.js} +1 -1
  79. package/dist/client/assets/{timeline-definition-PNZ67QCA-DU4TVYpw.js → timeline-definition-PNZ67QCA-DHKay9uj.js} +1 -1
  80. package/dist/client/assets/{upload-VCzeCiFH.js → upload-DxEwowRU.js} +1 -1
  81. package/dist/client/assets/{users-DB3knZtm.js → users-mNFgW_Zd.js} +1 -1
  82. package/dist/client/assets/{vennDiagram-CIIHVFJN-DX0Ppll6.js → vennDiagram-CIIHVFJN-X29K9hWM.js} +1 -1
  83. package/dist/client/assets/{wardley-L42UT6IY-CBoWxpDv.js → wardley-L42UT6IY-yEoTrfmN.js} +1 -1
  84. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-B_eVqdhC.js → wardleyDiagram-YWT4CUSO-ny4k3kG0.js} +1 -1
  85. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DeZzEX0f.js → xychartDiagram-2RQKCTM6-DC8ODtRJ.js} +1 -1
  86. package/dist/client/index.html +2 -2
  87. package/dist/client/version.json +1 -1
  88. package/dist/droid-cli/package.json +1 -1
  89. package/dist/extension.js +411 -155
  90. package/dist/pi-claude-cli/package.json +1 -1
  91. package/dist/plugin-sdk/index.d.ts +159 -141
  92. package/dist/plugin-sdk/index.js +19 -0
  93. package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +19 -0
  94. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  95. package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +19 -0
  96. package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
  97. package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +19 -0
  98. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  99. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +19 -0
  100. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  101. package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +19 -0
  102. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  103. package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +19 -0
  104. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  105. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +19 -0
  106. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  107. package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +19 -0
  108. package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
  109. package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +19 -0
  110. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  111. package/dist/plugins/fusion-plugin-linear-import/bundled.js +19 -0
  112. package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
  113. package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +19 -0
  114. package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
  115. package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +19 -0
  116. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  117. package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +19 -0
  118. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  119. package/dist/plugins/fusion-plugin-quality/bundled.js +19 -0
  120. package/dist/plugins/fusion-plugin-quality/package.json +1 -1
  121. package/dist/plugins/fusion-plugin-reports/bundled.js +19 -0
  122. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  123. package/dist/plugins/fusion-plugin-roadmap/bundled.js +19 -0
  124. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  125. package/dist/plugins/fusion-plugin-todos/bundled.js +19 -0
  126. package/dist/plugins/fusion-plugin-todos/package.json +1 -1
  127. package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +19 -0
  128. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  129. package/package.json +1 -1
  130. package/dist/client/assets/SecretsView-Cv2IuqFO.js +0 -1
  131. package/dist/client/assets/SettingsModal-CPRpRK71.js +0 -21
  132. package/dist/client/assets/channel-D-O4mRXx.js +0 -1
  133. package/dist/client/assets/classDiagram-4FO5ZUOK-BhHdSetA.js +0 -1
  134. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BhHdSetA.js +0 -1
  135. package/dist/client/assets/index-D0QgE5F5.js +0 -2767
  136. 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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/openclaw-runtime",
3
- "version": "0.2.84-beta.0",
3
+ "version": "0.2.84-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/paperclip-runtime",
3
- "version": "0.2.84-beta.0",
3
+ "version": "0.2.84-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/quality",
3
- "version": "0.1.9-beta.0",
3
+ "version": "0.1.9-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/reports",
3
- "version": "0.1.53-beta.0",
3
+ "version": "0.1.53-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/roadmap",
3
- "version": "0.1.53-beta.0",
3
+ "version": "0.1.53-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/todos",
3
- "version": "0.1.2-beta.0",
3
+ "version": "0.1.2-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/whatsapp-chat",
3
- "version": "0.1.53-beta.0",
3
+ "version": "0.1.53-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.75.1-beta.0",
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};