@runfusion/fusion 0.53.1 → 0.54.0

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 (186) hide show
  1. package/dist/bin.js +457 -168
  2. package/dist/client/.vite/manifest.json +233 -233
  3. package/dist/client/assets/{AgentDetailView-DYiAlisV.js → AgentDetailView-BJditQat.js} +1 -1
  4. package/dist/{desktop/client/assets/AgentPermissionPolicyEditor-KMUDm0nu.js → client/assets/AgentPermissionPolicyEditor-D2AQ6swg.js} +1 -1
  5. package/dist/client/assets/{AgentsView-YfJlxZoN.js → AgentsView-DwEFPKuN.js} +3 -3
  6. package/dist/{desktop/client/assets/ChatView-EeFLKmZB.js → client/assets/ChatView-B4bjPXFN.js} +1 -1
  7. package/dist/client/assets/{CommandCenter-CIwFDUKg.js → CommandCenter-BABqoSkg.js} +1 -1
  8. package/dist/client/assets/{DevServerView-DDRHfATy.js → DevServerView-DlgOzRdC.js} +1 -1
  9. package/dist/client/assets/{DirectoryPicker-C6HRGnSQ.js → DirectoryPicker-BwMSmxYS.js} +1 -1
  10. package/dist/{desktop/client/assets/DocumentsView-DCS-N7cU.js → client/assets/DocumentsView-BfaRXFg5.js} +1 -1
  11. package/dist/client/assets/{EvalsView-B9DCS8sV.js → EvalsView-CQBNrO5n.js} +1 -1
  12. package/dist/client/assets/{ExperimentalAgentOnboardingModal-DGmpwghz.js → ExperimentalAgentOnboardingModal-2SDqP2lc.js} +1 -1
  13. package/dist/client/assets/{GoalsView-B2hr3p6f.js → GoalsView-BgkX-_SB.js} +1 -1
  14. package/dist/client/assets/{InsightsView-DM3eYN2S.js → InsightsView-CJY4eZcO.js} +1 -1
  15. package/dist/{desktop/client/assets/MemoryView-D2OAkbGv.js → client/assets/MemoryView-5Crtfanz.js} +1 -1
  16. package/dist/{desktop/client/assets/PiExtensionsManager-DLrKJDwr.js → client/assets/PiExtensionsManager-COmzskVa.js} +1 -1
  17. package/dist/client/assets/{PluginManager-C1YuxOWu.js → PluginManager-CGWXqZMa.js} +1 -1
  18. package/dist/{desktop/client/assets/PullRequestView-DhTrKHeu.js → client/assets/PullRequestView-DAHh0FVM.js} +1 -1
  19. package/dist/{desktop/client/assets/ResearchView-BQwV9L4h.js → client/assets/ResearchView-cSUka3sd.js} +1 -1
  20. package/dist/{desktop/client/assets/SecretsView-Boby9tkU.js → client/assets/SecretsView-ChFAfFRY.js} +1 -1
  21. package/dist/client/assets/{SessionTerminal-BSeQ5i5F.js → SessionTerminal-CtQKDaqI.js} +1 -1
  22. package/dist/client/assets/{SettingsModal-CQuHnNXu.js → SettingsModal-BYaotQ2o.js} +3 -3
  23. package/dist/client/assets/{SettingsModal-_04cEhgW.js → SettingsModal-pAz_hOoN.js} +1 -1
  24. package/dist/client/assets/{SetupWizardModal-Dk9VO68p.js → SetupWizardModal-eHZHi8VP.js} +2 -2
  25. package/dist/{desktop/client/assets/ShadcnColorPicker-0ZZqsOqD.js → client/assets/ShadcnColorPicker-CsfgWpf6.js} +1 -1
  26. package/dist/{desktop/client/assets/SkillsView-Pzo5lSju.js → client/assets/SkillsView-BSUplEYb.js} +1 -1
  27. package/dist/client/assets/{TodoView-DaXGwdTQ.js → TodoView-DhBseLvM.js} +1 -1
  28. package/dist/client/assets/{WorkflowNodeEditor-DmJI-3Qp.js → WorkflowNodeEditor-Bi12CNif.js} +1 -1
  29. package/dist/client/assets/{agentSkills-B_n4hPLc.js → agentSkills-qVb0x_G3.js} +1 -1
  30. package/dist/{desktop/client/assets/architectureDiagram-3BPJPVTR-CrjMDhPI.js → client/assets/architectureDiagram-3BPJPVTR-DEt4eIEQ.js} +1 -1
  31. package/dist/client/assets/{blockDiagram-GPEHLZMM-DpwJlK7i.js → blockDiagram-GPEHLZMM-CJuX0UM_.js} +1 -1
  32. package/dist/client/assets/{c4Diagram-AAUBKEIU-DV115Z4B.js → c4Diagram-AAUBKEIU-a46Lm113.js} +1 -1
  33. package/dist/client/assets/channel-BGI9APMr.js +1 -0
  34. package/dist/client/assets/{chunk-2J33WTMH-B5BtZWCx.js → chunk-2J33WTMH-iBhwyS0c.js} +1 -1
  35. package/dist/client/assets/{chunk-4BX2VUAB-CJvgQM9e.js → chunk-4BX2VUAB-C7lS5wER.js} +1 -1
  36. package/dist/client/assets/{chunk-55IACEB6-ClrKLhVZ.js → chunk-55IACEB6-CQ6YOncn.js} +1 -1
  37. package/dist/client/assets/{chunk-727SXJPM-DhfUMdP5.js → chunk-727SXJPM-CveMaMKK.js} +1 -1
  38. package/dist/{desktop/client/assets/chunk-AQP2D5EJ-DegV3EMW.js → client/assets/chunk-AQP2D5EJ-DErjGUEk.js} +1 -1
  39. package/dist/client/assets/{chunk-FMBD7UC4-sLs4-jLA.js → chunk-FMBD7UC4-DXUvEFfJ.js} +1 -1
  40. package/dist/client/assets/{chunk-ND2GUHAM-BaptHWZM.js → chunk-ND2GUHAM-w5RqSj1J.js} +1 -1
  41. package/dist/client/assets/{chunk-QZHKN3VN-CArEOzHE.js → chunk-QZHKN3VN-CAi0lJ7V.js} +1 -1
  42. package/dist/client/assets/classDiagram-4FO5ZUOK-g6hCcufy.js +1 -0
  43. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-g6hCcufy.js +1 -0
  44. package/dist/{desktop/client/assets/cose-bilkent-S5V4N54A-DWz6vuMa.js → client/assets/cose-bilkent-S5V4N54A-Ck2h4uV5.js} +1 -1
  45. package/dist/{desktop/client/assets/dagre-BM42HDAG-GgO-3j8E.js → client/assets/dagre-BM42HDAG-BCRTXNj6.js} +1 -1
  46. package/dist/{desktop/client/assets/dashboard-view-CosTtyxo.js → client/assets/dashboard-view-BfLJ60Kd.js} +1 -1
  47. package/dist/client/assets/{dashboard-view-Bc5cz2DG.js → dashboard-view-D9rF_PCq.js} +1 -1
  48. package/dist/{desktop/client/assets/diagram-2AECGRRQ-BZQIXBBG.js → client/assets/diagram-2AECGRRQ-DTTk-DYO.js} +1 -1
  49. package/dist/client/assets/{diagram-5GNKFQAL-fRigQDqm.js → diagram-5GNKFQAL-jDc9kMi2.js} +1 -1
  50. package/dist/{desktop/client/assets/diagram-KO2AKTUF-B2lApC5l.js → client/assets/diagram-KO2AKTUF-CcLmzlGr.js} +1 -1
  51. package/dist/client/assets/{diagram-LMA3HP47-BVRY5C4e.js → diagram-LMA3HP47-DCW8XKQj.js} +1 -1
  52. package/dist/client/assets/{diagram-OG6HWLK6-DdP1xMRM.js → diagram-OG6HWLK6-wbbKquPs.js} +1 -1
  53. package/dist/client/assets/{erDiagram-TEJ5UH35-BU5DG9IX.js → erDiagram-TEJ5UH35-Fo933Mo7.js} +1 -1
  54. package/dist/{desktop/client/assets/flowDiagram-I6XJVG4X-Zk7IzQc2.js → client/assets/flowDiagram-I6XJVG4X-Dfum7HZP.js} +1 -1
  55. package/dist/client/assets/{folder-open-CV5ek-IV.js → folder-open-B8vOwFeP.js} +1 -1
  56. package/dist/client/assets/{ganttDiagram-6RSMTGT7-BFVLXtHC.js → ganttDiagram-6RSMTGT7-BzEBCn01.js} +1 -1
  57. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-TiwSURa4.js → gitGraphDiagram-PVQCEYII-CgovghHs.js} +1 -1
  58. package/dist/client/assets/{index-CEUULqTR.js → index-BjELA24x.js} +210 -210
  59. package/dist/client/assets/index-DwGW7OJh.css +1 -0
  60. package/dist/client/assets/{infoDiagram-5YYISTIA-Drkf3o26.js → infoDiagram-5YYISTIA-BzpU4Wys.js} +1 -1
  61. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-a9ZSlbx2.js → ishikawaDiagram-YF4QCWOH-cpp5pozu.js} +1 -1
  62. package/dist/client/assets/{journeyDiagram-JHISSGLW-DF_3fPPW.js → journeyDiagram-JHISSGLW-BVjcw6oo.js} +1 -1
  63. package/dist/client/assets/{kanban-definition-UN3LZRKU-B6dXVyXh.js → kanban-definition-UN3LZRKU-4unAhBzo.js} +1 -1
  64. package/dist/client/assets/{mermaid.core-BGFpwAba.js → mermaid.core-DzIyUj9t.js} +4 -4
  65. package/dist/client/assets/{mindmap-definition-RKZ34NQL-D5bZ0zCy.js → mindmap-definition-RKZ34NQL-Be_yfVir.js} +1 -1
  66. package/dist/client/assets/{pieDiagram-4H26LBE5-Dh6rUd7R.js → pieDiagram-4H26LBE5-Cfnw2aji.js} +1 -1
  67. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-D9Fy6Nl1.js → quadrantDiagram-W4KKPZXB-BFlC-_Uo.js} +1 -1
  68. package/dist/{desktop/client/assets/requirementDiagram-4Y6WPE33-C8S5lJeA.js → client/assets/requirementDiagram-4Y6WPE33-DpVPzCOx.js} +1 -1
  69. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-Cs9Bx7N3.js → sankeyDiagram-5OEKKPKP-DM-gKKP0.js} +1 -1
  70. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BV7DAI0_.js → sequenceDiagram-3UESZ5HK-DjhZCZhd.js} +1 -1
  71. package/dist/{desktop/client/assets/shield-alert-BHWZI_om.js → client/assets/shield-alert-DCfkjjYc.js} +1 -1
  72. package/dist/client/assets/{stateDiagram-AJRCARHV-CTvWoU00.js → stateDiagram-AJRCARHV-BCA96rdI.js} +1 -1
  73. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-ZSZ46LWU.js → stateDiagram-v2-BHNVJYJU-DHds08RS.js} +1 -1
  74. package/dist/{desktop/client/assets/timeline-definition-PNZ67QCA-BrtDAg8s.js → client/assets/timeline-definition-PNZ67QCA-CHW2OQRw.js} +1 -1
  75. package/dist/client/assets/{upload-CNW5goS6.js → upload-EJc5PJPz.js} +1 -1
  76. package/dist/{desktop/client/assets/users-2kEJQeOu.js → client/assets/users-C-e-99Vp.js} +1 -1
  77. package/dist/{desktop/client/assets/vennDiagram-CIIHVFJN-CVjr2RxJ.js → client/assets/vennDiagram-CIIHVFJN-shGh4eBY.js} +1 -1
  78. package/dist/client/assets/{wardley-L42UT6IY-Bt1vdMb3.js → wardley-L42UT6IY-l0RGrVhn.js} +1 -1
  79. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-B_Dlx683.js → wardleyDiagram-YWT4CUSO-C-USmO8A.js} +1 -1
  80. package/dist/{desktop/client/assets/xychartDiagram-2RQKCTM6-B0o0ggVt.js → client/assets/xychartDiagram-2RQKCTM6-CHX9Umta.js} +1 -1
  81. package/dist/client/index.html +2 -2
  82. package/dist/client/version.json +1 -1
  83. package/dist/desktop/client/.vite/manifest.json +236 -236
  84. package/dist/desktop/client/assets/{AgentDetailView-SJpg9JA5.js → AgentDetailView-CmKvdHMb.js} +1 -1
  85. package/dist/{client/assets/AgentPermissionPolicyEditor-CMtzKP_x.js → desktop/client/assets/AgentPermissionPolicyEditor-C-A5YsOB.js} +1 -1
  86. package/dist/desktop/client/assets/{AgentsView-CITigHGD.js → AgentsView-Ci8aGe-d.js} +3 -3
  87. package/dist/{client/assets/ChatView-Diuc5LOe.js → desktop/client/assets/ChatView-_ZTSW2bn.js} +1 -1
  88. package/dist/desktop/client/assets/{CommandCenter-DmqJyMvs.js → CommandCenter-B7_gwqKx.js} +1 -1
  89. package/dist/desktop/client/assets/{DevServerView-Ckhpio_x.js → DevServerView-BFF8C0F8.js} +1 -1
  90. package/dist/desktop/client/assets/{DirectoryPicker-j-rxo0kC.js → DirectoryPicker-CfhD5v7D.js} +1 -1
  91. package/dist/{client/assets/DocumentsView-C5RTxVSE.js → desktop/client/assets/DocumentsView-DpeUtihC.js} +1 -1
  92. package/dist/desktop/client/assets/{EvalsView-Dd26ipFU.js → EvalsView-BcBDpBZQ.js} +1 -1
  93. package/dist/desktop/client/assets/{ExperimentalAgentOnboardingModal-BqgWIa9n.js → ExperimentalAgentOnboardingModal-CGeNiEm7.js} +1 -1
  94. package/dist/desktop/client/assets/{GoalsView-C5gWzKqI.js → GoalsView-t-86-sWc.js} +1 -1
  95. package/dist/desktop/client/assets/{InsightsView-2SPZDH3m.js → InsightsView-BKdG05Yh.js} +1 -1
  96. package/dist/{client/assets/MemoryView-8Yg8r9qS.js → desktop/client/assets/MemoryView-BhT-vG17.js} +1 -1
  97. package/dist/{client/assets/PiExtensionsManager-DbZ5qtAF.js → desktop/client/assets/PiExtensionsManager-C5kqG7zt.js} +1 -1
  98. package/dist/desktop/client/assets/{PluginManager-B0CMG4RR.js → PluginManager-4nZ3Dccd.js} +1 -1
  99. package/dist/{client/assets/PullRequestView-CMVvVGaP.js → desktop/client/assets/PullRequestView-m0-ygvgV.js} +1 -1
  100. package/dist/{client/assets/ResearchView-BjvgxMjL.js → desktop/client/assets/ResearchView-Be0JmVPT.js} +1 -1
  101. package/dist/{client/assets/SecretsView-gChNSW57.js → desktop/client/assets/SecretsView-BpjSNOmd.js} +1 -1
  102. package/dist/desktop/client/assets/{SessionTerminal-CT_DUO7z.js → SessionTerminal-B2tZ8AY1.js} +1 -1
  103. package/dist/desktop/client/assets/{SettingsModal-Dijfj3cb.js → SettingsModal-COlmbl7p.js} +3 -3
  104. package/dist/desktop/client/assets/{SettingsModal-CvsRQchW.js → SettingsModal-pY1WnN3a.js} +1 -1
  105. package/dist/desktop/client/assets/{SetupWizardModal-BIiJIXkh.js → SetupWizardModal-BFzU4EUM.js} +2 -2
  106. package/dist/{client/assets/ShadcnColorPicker-DyPMec2U.js → desktop/client/assets/ShadcnColorPicker-DnTw9J9K.js} +1 -1
  107. package/dist/{client/assets/SkillsView-BAMinq2_.js → desktop/client/assets/SkillsView-BeOeeV_9.js} +1 -1
  108. package/dist/desktop/client/assets/{TodoView-ClCgLTmi.js → TodoView-Yb7RPsSG.js} +1 -1
  109. package/dist/desktop/client/assets/{WorkflowNodeEditor-8XHmq-V2.js → WorkflowNodeEditor-ygM9IC7d.js} +1 -1
  110. package/dist/desktop/client/assets/{agentSkills-D5osLOR5.js → agentSkills-hS-ir3dK.js} +1 -1
  111. package/dist/{client/assets/architectureDiagram-3BPJPVTR-DysoZtiI.js → desktop/client/assets/architectureDiagram-3BPJPVTR-WcTzF6ME.js} +1 -1
  112. package/dist/desktop/client/assets/{blockDiagram-GPEHLZMM-CTQo88ZR.js → blockDiagram-GPEHLZMM-BYmICOh-.js} +1 -1
  113. package/dist/desktop/client/assets/{c4Diagram-AAUBKEIU-YjMRExC0.js → c4Diagram-AAUBKEIU-3ags6jHx.js} +1 -1
  114. package/dist/desktop/client/assets/channel-CxoQ1L5k.js +1 -0
  115. package/dist/desktop/client/assets/{chunk-2J33WTMH-O2741OpT.js → chunk-2J33WTMH-C2YTcAIE.js} +1 -1
  116. package/dist/desktop/client/assets/{chunk-4BX2VUAB-E8A3umbR.js → chunk-4BX2VUAB-CM-ULeCo.js} +1 -1
  117. package/dist/desktop/client/assets/{chunk-55IACEB6-B052cwdC.js → chunk-55IACEB6-puic6XS6.js} +1 -1
  118. package/dist/desktop/client/assets/{chunk-727SXJPM-BKI0HQTP.js → chunk-727SXJPM-D19Luj8o.js} +1 -1
  119. package/dist/{client/assets/chunk-AQP2D5EJ-CGKqiWfs.js → desktop/client/assets/chunk-AQP2D5EJ-CMrfBV_j.js} +1 -1
  120. package/dist/desktop/client/assets/{chunk-FMBD7UC4-B7tLsOki.js → chunk-FMBD7UC4-C_7tmt8f.js} +1 -1
  121. package/dist/desktop/client/assets/{chunk-ND2GUHAM-2xF-Tg95.js → chunk-ND2GUHAM-CS1wETTI.js} +1 -1
  122. package/dist/desktop/client/assets/{chunk-QZHKN3VN-DUl8dvkQ.js → chunk-QZHKN3VN-BUFmz9j9.js} +1 -1
  123. package/dist/desktop/client/assets/classDiagram-4FO5ZUOK-CkwAKz6i.js +1 -0
  124. package/dist/desktop/client/assets/classDiagram-v2-Q7XG4LA2-CkwAKz6i.js +1 -0
  125. package/dist/{client/assets/cose-bilkent-S5V4N54A-DZ4jAfQc.js → desktop/client/assets/cose-bilkent-S5V4N54A-CKNwQVxq.js} +1 -1
  126. package/dist/{client/assets/dagre-BM42HDAG-CMhtRslH.js → desktop/client/assets/dagre-BM42HDAG-CUUNF5LG.js} +1 -1
  127. package/dist/{client/assets/dashboard-view-Buq7raMZ.js → desktop/client/assets/dashboard-view-DTUxDN-H.js} +1 -1
  128. package/dist/desktop/client/assets/{dashboard-view-Cw1KM3Az.js → dashboard-view-DqJev4PV.js} +1 -1
  129. package/dist/{client/assets/diagram-2AECGRRQ-6uVCJGM-.js → desktop/client/assets/diagram-2AECGRRQ-D2jVjZrI.js} +1 -1
  130. package/dist/desktop/client/assets/{diagram-5GNKFQAL-B1pdxoln.js → diagram-5GNKFQAL-DfwBCAme.js} +1 -1
  131. package/dist/{client/assets/diagram-KO2AKTUF-DeLeKk1C.js → desktop/client/assets/diagram-KO2AKTUF-CBWuxzRU.js} +1 -1
  132. package/dist/desktop/client/assets/{diagram-LMA3HP47-BRqKMh4D.js → diagram-LMA3HP47-DIdjbaEx.js} +1 -1
  133. package/dist/desktop/client/assets/{diagram-OG6HWLK6-Dl7BJ0tE.js → diagram-OG6HWLK6-DU6aJ_ab.js} +1 -1
  134. package/dist/desktop/client/assets/{erDiagram-TEJ5UH35-DS6QZa9s.js → erDiagram-TEJ5UH35-CB7jraE9.js} +1 -1
  135. package/dist/{client/assets/flowDiagram-I6XJVG4X-CFSihB_T.js → desktop/client/assets/flowDiagram-I6XJVG4X-DAuaVo8C.js} +1 -1
  136. package/dist/desktop/client/assets/{folder-open-BhDX2lOd.js → folder-open-B3OWnACS.js} +1 -1
  137. package/dist/desktop/client/assets/{ganttDiagram-6RSMTGT7-CJuYCcjE.js → ganttDiagram-6RSMTGT7-BF3vyyoq.js} +1 -1
  138. package/dist/desktop/client/assets/{gitGraphDiagram-PVQCEYII-BmCm6tvH.js → gitGraphDiagram-PVQCEYII-kfNrpgK7.js} +1 -1
  139. package/dist/desktop/client/assets/{index-CoS-MsCg.js → index-lGrAUOVY.js} +240 -240
  140. package/dist/desktop/client/assets/{infoDiagram-5YYISTIA-Ds6lrlTh.js → infoDiagram-5YYISTIA-CuKJEoCg.js} +1 -1
  141. package/dist/desktop/client/assets/{ishikawaDiagram-YF4QCWOH-D3deq-vb.js → ishikawaDiagram-YF4QCWOH-CE_2WBE3.js} +1 -1
  142. package/dist/desktop/client/assets/{journeyDiagram-JHISSGLW-BuHVkT2m.js → journeyDiagram-JHISSGLW-BYQgXH_-.js} +1 -1
  143. package/dist/desktop/client/assets/{kanban-definition-UN3LZRKU-DdoE5oU5.js → kanban-definition-UN3LZRKU-sr34WcdB.js} +1 -1
  144. package/dist/desktop/client/assets/{mermaid.core-_nbzHc5D.js → mermaid.core-CY1aILvw.js} +4 -4
  145. package/dist/desktop/client/assets/{mindmap-definition-RKZ34NQL-Bq-XuCz_.js → mindmap-definition-RKZ34NQL-BAxyJwWa.js} +1 -1
  146. package/dist/desktop/client/assets/{pieDiagram-4H26LBE5-BgcfpW6J.js → pieDiagram-4H26LBE5-DV4jRFhI.js} +1 -1
  147. package/dist/desktop/client/assets/{quadrantDiagram-W4KKPZXB-Xys80jUW.js → quadrantDiagram-W4KKPZXB-CRtFlWS-.js} +1 -1
  148. package/dist/{client/assets/requirementDiagram-4Y6WPE33-Bky271Dr.js → desktop/client/assets/requirementDiagram-4Y6WPE33-C3kGj3sc.js} +1 -1
  149. package/dist/desktop/client/assets/{sankeyDiagram-5OEKKPKP-B_3GGQyd.js → sankeyDiagram-5OEKKPKP-rH_2R8B6.js} +1 -1
  150. package/dist/desktop/client/assets/{sequenceDiagram-3UESZ5HK-DIu6iwmX.js → sequenceDiagram-3UESZ5HK-BUlBU-AX.js} +1 -1
  151. package/dist/{client/assets/shield-alert-BEwCrI8k.js → desktop/client/assets/shield-alert-CXSmWFIA.js} +1 -1
  152. package/dist/desktop/client/assets/{stateDiagram-AJRCARHV-CnaR2a9t.js → stateDiagram-AJRCARHV-CZloQCqS.js} +1 -1
  153. package/dist/desktop/client/assets/{stateDiagram-v2-BHNVJYJU-VHc1xbe0.js → stateDiagram-v2-BHNVJYJU-CMUjVDVd.js} +1 -1
  154. package/dist/{client/assets/timeline-definition-PNZ67QCA-DSJscSa7.js → desktop/client/assets/timeline-definition-PNZ67QCA-ChiOOBC-.js} +1 -1
  155. package/dist/desktop/client/assets/{upload-DOLP3Bv3.js → upload-BHs6kHbo.js} +1 -1
  156. package/dist/{client/assets/users-BhzdPkLN.js → desktop/client/assets/users-PPo03TKl.js} +1 -1
  157. package/dist/{client/assets/vennDiagram-CIIHVFJN-CziD-NoU.js → desktop/client/assets/vennDiagram-CIIHVFJN-Dq4yiSea.js} +1 -1
  158. package/dist/desktop/client/assets/{wardley-L42UT6IY-CVstgB5f.js → wardley-L42UT6IY-Ctho3NZr.js} +1 -1
  159. package/dist/desktop/client/assets/{wardleyDiagram-YWT4CUSO-Da3szr-D.js → wardleyDiagram-YWT4CUSO-CXcLpQ87.js} +1 -1
  160. package/dist/{client/assets/xychartDiagram-2RQKCTM6-cYDRrhyM.js → desktop/client/assets/xychartDiagram-2RQKCTM6-B4tWIB07.js} +1 -1
  161. package/dist/desktop/client/index.html +1 -1
  162. package/dist/desktop/client/version.json +1 -1
  163. package/dist/droid-cli/package.json +1 -1
  164. package/dist/extension.js +371 -118
  165. package/dist/pi-claude-cli/package.json +1 -1
  166. package/dist/plugin-sdk/index.d.ts +2 -0
  167. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  168. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  169. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  170. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  171. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  172. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  173. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  174. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  175. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  176. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  177. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  178. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +2 -1
  179. package/package.json +1 -1
  180. package/dist/client/assets/channel-BgnsK1mp.js +0 -1
  181. package/dist/client/assets/classDiagram-4FO5ZUOK-ZkHxi9su.js +0 -1
  182. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-ZkHxi9su.js +0 -1
  183. package/dist/client/assets/index-D1IHwGhg.css +0 -1
  184. package/dist/desktop/client/assets/channel-ByWi0lfq.js +0 -1
  185. package/dist/desktop/client/assets/classDiagram-4FO5ZUOK-C6nL18EV.js +0 -1
  186. package/dist/desktop/client/assets/classDiagram-v2-Q7XG4LA2-C6nL18EV.js +0 -1
package/dist/extension.js CHANGED
@@ -1370,6 +1370,11 @@ var init_settings_schema = __esm({
1370
1370
  // coverage. Falls back to package/explicit command when no tests resolve.
1371
1371
  scopeVerificationToChangedFiles: true,
1372
1372
  ephemeralAgentsEnabled: true,
1373
+ /*
1374
+ FNXC:EphemeralAgentTaskCreation 2026-07-01-00:00:
1375
+ Default-on so ephemeral task-worker agents keep the ability to open follow-up tasks via fn_task_create. Operators who want to confine task creation to humans/permanent agents flip this off.
1376
+ */
1377
+ ephemeralAgentsCanCreateTasks: true,
1373
1378
  agentProvisioning: {},
1374
1379
  sandboxProvisioning: {},
1375
1380
  defaultAgentPermissionPolicy: void 0,
@@ -51647,7 +51652,7 @@ function filterRepairOverlapIgnoredPaths(paths, ignorePaths) {
51647
51652
  if (ignorePaths.length === 0) return paths;
51648
51653
  return paths.filter((path6) => !ignorePaths.some((ignorePath) => repairIgnoredOverlapPath(path6, ignorePath)));
51649
51654
  }
51650
- var serializeTaskAutoMerge, serializeTaskAutoMergeProvenance, TASK_COLUMN_DESCRIPTORS, TASK_COLUMN_DESCRIPTOR_BY_COLUMN, TASK_PERSIST_SQL_COLUMNS, TASK_UPSERT_SQL_ASSIGNMENTS, TASK_BRANCH_CONTEXT_METADATA_KEY, DEFAULT_TASK_ACTIVITY_LOG_ENTRY_LIMIT, DEFAULT_TASK_ACTIVITY_LOG_OUTCOME_LIMIT, taskActivityLogEntryLimit, taskActivityLogOutcomeLimit, ARCHIVE_AGENT_LOG_SNAPSHOT_LIMIT, ARCHIVE_AGENT_LOG_SNIPPET_LIMIT, RECONCILE_ORPHAN_TASK_DIR_MAX_AGE_MS, storeLog, coreLog, TaskHasDependentsError, TaskDeletedError, TombstonedTaskResurrectionError, TaskHasLineageChildrenError, InvalidFileScopeError, SELF_DEFEATING_OPERATION_VERBS, SelfDefeatingDependencyError, DependencyCycleError, MergeQueueTaskNotFoundError, MergeQueueInvalidColumnError, MergeQueueLeaseOwnershipError, InvalidMergeQueueLeaseDurationError, HandoffInvariantViolationError, TransitionRejectionError, WORKFLOW_MOVE_POLICY_TIMEOUT_MS, LEGACY_AUTO_MERGE_STAMP_MARKER_KEY, LEGACY_AUTO_MERGE_STAMP_MARKER_VERSION, TaskStore;
51655
+ var serializeTaskAutoMerge, serializeTaskAutoMergeProvenance, TASK_COLUMN_DESCRIPTORS, TASK_COLUMN_DESCRIPTOR_BY_COLUMN, TASK_PERSIST_SQL_COLUMNS, TASK_UPSERT_SQL_ASSIGNMENTS, TASK_BRANCH_CONTEXT_METADATA_KEY, DEFAULT_TASK_ACTIVITY_LOG_ENTRY_LIMIT, DEFAULT_TASK_ACTIVITY_LOG_OUTCOME_LIMIT, taskActivityLogEntryLimit, taskActivityLogOutcomeLimit, ARCHIVE_AGENT_LOG_SNAPSHOT_LIMIT, ARCHIVE_AGENT_LOG_SNIPPET_LIMIT, RECONCILE_ORPHAN_TASK_DIR_MAX_AGE_MS, storeLog, coreLog, TaskHasDependentsError, TaskSelfDeleteError, TaskDeletedError, TombstonedTaskResurrectionError, TaskHasLineageChildrenError, InvalidFileScopeError, SELF_DEFEATING_OPERATION_VERBS, SelfDefeatingDependencyError, DependencyCycleError, MergeQueueTaskNotFoundError, MergeQueueInvalidColumnError, MergeQueueLeaseOwnershipError, InvalidMergeQueueLeaseDurationError, HandoffInvariantViolationError, TransitionRejectionError, WORKFLOW_MOVE_POLICY_TIMEOUT_MS, LEGACY_AUTO_MERGE_STAMP_MARKER_KEY, LEGACY_AUTO_MERGE_STAMP_MARKER_VERSION, TaskStore;
51651
51656
  var init_store = __esm({
51652
51657
  "../core/src/store.ts"() {
51653
51658
  "use strict";
@@ -51899,6 +51904,15 @@ var init_store = __esm({
51899
51904
  this.dependentIds = dependentIds;
51900
51905
  }
51901
51906
  };
51907
+ TaskSelfDeleteError = class extends Error {
51908
+ taskId;
51909
+ code = "TASK_SELF_DELETE";
51910
+ constructor(taskId) {
51911
+ super(`Task ${taskId} cannot delete itself`);
51912
+ this.name = "TaskSelfDeleteError";
51913
+ this.taskId = taskId;
51914
+ }
51915
+ };
51902
51916
  TaskDeletedError = class extends Error {
51903
51917
  constructor(taskId, deletedAt) {
51904
51918
  super(`Task ${taskId} is soft-deleted (deletedAt=${deletedAt}) and cannot be read or mutated`);
@@ -60173,6 +60187,9 @@ ${newTask.description}
60173
60187
  */
60174
60188
  async deleteTask(id, options) {
60175
60189
  const deletedTask = await this.withTaskLock(id, async () => {
60190
+ if (options?.auditContext?.taskId === id) {
60191
+ throw new TaskSelfDeleteError(id);
60192
+ }
60176
60193
  this.flushAgentLogBuffer();
60177
60194
  const task = this.readTaskFromDb(id, { includeDeleted: true });
60178
60195
  if (!task) {
@@ -127577,6 +127594,17 @@ function createTaskCreateTool(store, provenance, options) {
127577
127594
  parameters: taskCreateParams,
127578
127595
  execute: async (_id, params) => {
127579
127596
  try {
127597
+ if (options?.callerIsEphemeral) {
127598
+ const settings = typeof store.getSettings === "function" ? await store.getSettings().catch(() => ({})) : {};
127599
+ if (settings.ephemeralAgentsCanCreateTasks === false) {
127600
+ const message = "Ephemeral task-worker agents are not allowed to create tasks (ephemeralAgentsCanCreateTasks is disabled for this project).";
127601
+ return {
127602
+ content: [{ type: "text", text: `ERROR: ${message}` }],
127603
+ details: { error: message, rule: "ephemeral-agents-cannot-create-tasks" },
127604
+ isError: true
127605
+ };
127606
+ }
127607
+ }
127580
127608
  const workflowId = params.workflow_id?.trim() || void 0;
127581
127609
  const { task, wasDuplicate } = await createAgentTask(store, {
127582
127610
  description: params.description,
@@ -163461,25 +163489,91 @@ function buildReviewRequest(taskId, stepNumber, stepName, reviewType, promptCont
163461
163489
  );
163462
163490
  return parts.join("\n");
163463
163491
  }
163464
- function extractVerdict(review) {
163465
- const jsonMatch = review.match(
163466
- /\{\s*"verdict"\s*:\s*"(APPROVE|REVISE|RETHINK)"\s*\}/i
163492
+ function proseSignalsClearApproval(rawOutput) {
163493
+ const text = rawOutput.trim();
163494
+ if (text.length === 0) return false;
163495
+ const blockingSignal = new RegExp(
163496
+ [
163497
+ /\bREVIS(?:E|ED|ES|ING|ION|IONS)\b/,
163498
+ /\bRETHINK\b/,
163499
+ /\bREQUEST(?:ING|ED)?\s+(?:REVISION|CHANGES?)\b/,
163500
+ /\bNEEDS?\s+(?:REVISION|CHANGES?|WORK|FIXE?S?)\b/,
163501
+ /\bMUST\s+(?:BE\s+)?(?:FIX|CHANG|CORRECT|ADDRESS|RESOLV|UPDAT)\w*/,
163502
+ /\bSHOULD\s+(?:BE\s+)?(?:FIX|CHANG|CORRECT|ADDRESS|RESOLV|UPDAT|REVIS)\w*/,
163503
+ /\bPLEASE\s+(?:FIX|CHANG|CORRECT|ADDRESS|UPDAT|REVIS)\w*/,
163504
+ /\bWANTS?\s+(?:\w+\s+){0,3}?(?:CHANG|FIX|CORRECT|ADDRESS|REVIS)\w*/,
163505
+ /\bBEFORE\s+MERG\w*/,
163506
+ /\bREJECT(?:ED|ING|S)?\b/,
163507
+ /\bDISAPPROVE\b/
163508
+ ].map((r) => r.source).join("|"),
163509
+ "i"
163467
163510
  );
163468
- if (jsonMatch) {
163469
- reviewerLog.log(`Verdict extracted via JSON block: ${jsonMatch[1].toUpperCase()}`);
163470
- return jsonMatch[1].toUpperCase();
163511
+ const negatedApproval = /\b(?:not|no|never|cannot|can['’]?t|don['’]?t|doesn['’]?t|won['’]?t|without)\s+approv/i;
163512
+ if (blockingSignal.test(text) || negatedApproval.test(text)) return false;
163513
+ const approvalSignal = /\b(?:approv(?:e|ed|es|ing|al)|approve[_\s]with[_\s]notes|looks?\s+good|lgtm|ship\s+it|no\s+(?:blocking\s+)?(?:issues|concerns|problems|objections)|passes?\s+(?:the\s+)?review|all\s+good|acceptable|good\s+to\s+(?:go|merge)|out\s+of\s+scope)\b/i;
163514
+ return approvalSignal.test(text);
163515
+ }
163516
+ function extractJsonObjectCandidates(text) {
163517
+ const out = [];
163518
+ const starts = [];
163519
+ let inString = false;
163520
+ let escaped = false;
163521
+ for (let i = 0; i < text.length; i += 1) {
163522
+ const ch = text[i];
163523
+ if (inString) {
163524
+ if (escaped) escaped = false;
163525
+ else if (ch === "\\") escaped = true;
163526
+ else if (ch === '"') inString = false;
163527
+ continue;
163528
+ }
163529
+ if (ch === '"') inString = true;
163530
+ else if (ch === "{") starts.push(i);
163531
+ else if (ch === "}") {
163532
+ const start = starts.pop();
163533
+ if (start !== void 0 && starts.length === 0) out.push(text.slice(start, i + 1));
163534
+ }
163471
163535
  }
163536
+ return out;
163537
+ }
163538
+ function classifyReviewVerdictToken(raw) {
163539
+ const v2 = raw.trim().toUpperCase();
163540
+ if (v2.startsWith("APPROVE") || v2.startsWith("APPROVAL")) return "APPROVE";
163541
+ if (v2.startsWith("REVISE") || v2.startsWith("REQUEST_REVISION") || v2.startsWith("REJECT")) return "REVISE";
163542
+ if (v2.startsWith("RETHINK")) return "RETHINK";
163543
+ return null;
163544
+ }
163545
+ function extractVerdict(review) {
163472
163546
  const headingMatch = review.match(
163473
- /^[>\s]*(?:###?\s*|[*_]{1,2})Verdict[:\s]*[*_]{0,2}\s*(APPROVE|REVISE|RETHINK)\b/im
163547
+ /^[>\s]*(?:###?\s*|[*_]{1,2})Verdict[:\s]*[*_]{0,2}\s*([A-Za-z_]+)/im
163474
163548
  );
163475
163549
  if (headingMatch) {
163476
- return headingMatch[1].toUpperCase();
163550
+ const classified = classifyReviewVerdictToken(headingMatch[1]);
163551
+ if (classified) return classified;
163477
163552
  }
163478
163553
  const lineFallback = review.match(
163479
- /^[>\s]*(?:verdict|decision)\s*[-:]\s*(APPROVE|REVISE|RETHINK)\b/im
163554
+ /^[>\s]*(?:verdict|decision)\s*[-:]\s*([A-Za-z_]+)/im
163480
163555
  );
163481
163556
  if (lineFallback) {
163482
- return lineFallback[1].toUpperCase();
163557
+ const classified = classifyReviewVerdictToken(lineFallback[1]);
163558
+ if (classified) return classified;
163559
+ }
163560
+ const jsonCandidates = extractJsonObjectCandidates(review);
163561
+ for (let i = jsonCandidates.length - 1; i >= 0; i -= 1) {
163562
+ try {
163563
+ const parsed = JSON.parse(jsonCandidates[i]);
163564
+ if (typeof parsed?.verdict === "string") {
163565
+ const classified = classifyReviewVerdictToken(parsed.verdict);
163566
+ if (classified) {
163567
+ reviewerLog.log(`Verdict extracted via JSON payload: ${classified}`);
163568
+ return classified;
163569
+ }
163570
+ }
163571
+ } catch {
163572
+ }
163573
+ }
163574
+ if (proseSignalsClearApproval(review)) {
163575
+ reviewerLog.log(`Verdict extracted via lenient prose approval (${review.length} chars) \u2192 APPROVE`);
163576
+ return "APPROVE";
163483
163577
  }
163484
163578
  reviewerLog.warn(`Could not extract verdict from review (${review.length} chars). Returning UNAVAILABLE.`);
163485
163579
  return "UNAVAILABLE";
@@ -172652,18 +172746,21 @@ function parseWorkflowStepVerdict(rawOutput) {
172652
172746
  for (const match of fencedMatches) {
172653
172747
  candidates.push(match[1].trim());
172654
172748
  }
172655
- const jsonObjectMatches = trimmed.match(/\{[\s\S]*\}/g);
172656
- if (jsonObjectMatches) {
172657
- candidates.push(...jsonObjectMatches.map((value) => value.trim()));
172658
- }
172749
+ candidates.push(...extractJsonObjectCandidates(trimmed));
172659
172750
  for (let i = candidates.length - 1; i >= 0; i -= 1) {
172660
172751
  try {
172661
172752
  const parsed = JSON.parse(candidates[i]);
172662
- if (!parsed || typeof parsed.verdict !== "string" || !WORKFLOW_STEP_VERDICTS.has(parsed.verdict)) {
172663
- continue;
172664
- }
172753
+ if (!parsed || typeof parsed.verdict !== "string") continue;
172754
+ const token = parsed.verdict.trim().toUpperCase();
172755
+ let verdict = null;
172756
+ if (token.startsWith("APPROVE") || token.startsWith("APPROVAL")) {
172757
+ verdict = token.includes("NOTE") ? "APPROVE_WITH_NOTES" : "APPROVE";
172758
+ } else if (token.startsWith("REVISE") || token.startsWith("REQUEST_REVISION") || token.startsWith("REJECT")) {
172759
+ verdict = "REVISE";
172760
+ }
172761
+ if (!verdict) continue;
172665
172762
  return {
172666
- verdict: parsed.verdict,
172763
+ verdict,
172667
172764
  notes: typeof parsed.notes === "string" ? parsed.notes : ""
172668
172765
  };
172669
172766
  } catch {
@@ -172684,7 +172781,7 @@ function inferWorkflowStepVerdictFromProse(rawOutput) {
172684
172781
  notes: ""
172685
172782
  };
172686
172783
  }
172687
- if (/\b(approve|approved|looks good|no issues|out of scope)\b/i.test(trimmed)) {
172784
+ if (proseSignalsClearApproval(trimmed)) {
172688
172785
  return { verdict: "APPROVE", notes: "" };
172689
172786
  }
172690
172787
  return null;
@@ -172931,6 +173028,11 @@ Please adjust your approach based on this feedback.`;
172931
173028
  function hasNonTerminalWorkflowSteps(task) {
172932
173029
  return task.steps.length > 0 && task.steps.some((step) => step.status !== "done" && step.status !== "skipped");
172933
173030
  }
173031
+ function clearTerminalWorkflowStepFailures(results) {
173032
+ const current = results ?? [];
173033
+ const kept = current.filter((result) => result.status !== "failed" && result.status !== "advisory_failure");
173034
+ return kept.length === current.length ? current : kept;
173035
+ }
172934
173036
  function workflowStepResultPassed(task, workflowStepId) {
172935
173037
  const results = task?.workflowStepResults ?? [];
172936
173038
  return results.some(
@@ -173031,7 +173133,7 @@ function detectReviewHandoffIntent(commentText) {
173031
173133
  ];
173032
173134
  return handoffPhrases.some((phrase) => text.includes(phrase));
173033
173135
  }
173034
- var execAsync32, AGENT_BROWSER_NAVIGATION_SKILL_ID, yieldEventLoop3, tokenCacheMetricsLog, OPTIONAL_STEP_REVISION_KEY_MARKER2, STEP_STATUSES, MAX_WORKFLOW_STEP_RETRIES, MAX_TASK_DONE_SESSION_RETRIES, MAX_TASK_DONE_REQUEUE_RETRIES, MAX_TRANSIENT_GRAPH_RESUME_RETRIES, TRANSIENT_GRAPH_RESUME_RETRY_BACKOFF_MS, COMPLETED_TASK_WATCHDOG_MS, WORKFLOW_RERUN_WATCHDOG_MS, LOOP_COMPACTION_TIMEOUT_MS, TASK_DONE_REFUSAL_SUFFIX, TRANSIENT_WORKTREE_TASK_JSON_ENOENT_PATTERN, DISSENT_PATTERNS, WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS, NonRetryableWorktreeError, taskUpdateParams, taskAddDepParams, spawnAgentParams, FUSION_WORKFLOW_STEP_CONVENTIONS_PREAMBLE, WORKFLOW_STEP_VERDICTS, reviewStepParams, EXECUTOR_SYSTEM_PROMPT, TaskExecutor;
173136
+ var execAsync32, AGENT_BROWSER_NAVIGATION_SKILL_ID, yieldEventLoop3, tokenCacheMetricsLog, OPTIONAL_STEP_REVISION_KEY_MARKER2, STEP_STATUSES, MAX_WORKFLOW_STEP_RETRIES, MAX_TASK_DONE_SESSION_RETRIES, MAX_TASK_DONE_REQUEUE_RETRIES, MAX_TRANSIENT_GRAPH_RESUME_RETRIES, TRANSIENT_GRAPH_RESUME_RETRY_BACKOFF_MS, COMPLETED_TASK_WATCHDOG_MS, WORKFLOW_RERUN_WATCHDOG_MS, LOOP_COMPACTION_TIMEOUT_MS, TASK_DONE_REFUSAL_SUFFIX, TRANSIENT_WORKTREE_TASK_JSON_ENOENT_PATTERN, DISSENT_PATTERNS, WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS, NonRetryableWorktreeError, taskUpdateParams, taskAddDepParams, spawnAgentParams, FUSION_WORKFLOW_STEP_CONVENTIONS_PREAMBLE, reviewStepParams, EXECUTOR_SYSTEM_PROMPT, TaskExecutor;
173035
173137
  var init_executor = __esm({
173036
173138
  "../engine/src/executor.ts"() {
173037
173139
  "use strict";
@@ -173191,7 +173293,6 @@ You are running as a Fusion autonomous workflow step \u2014 NOT an interactive C
173191
173293
  3. Dispatching a \`ce-<persona>\` subagent: do NOT use a raw \`Task ce-*(...)\` call. Instead, read the persona definition from \`$FUSION_CE_AGENTS_DIR/<persona>.md\`, strip its YAML frontmatter, and pass the remaining body as the \`systemPromptOverride\` argument to the \`fn_spawn_agent\` tool. Resolve the path strictly inside \`$FUSION_CE_AGENTS_DIR\` \u2014 reject any \`<persona>\` containing \`/\` or \`..\` (path traversal), and skip a def whose body is empty or implausibly large. If \`fn_spawn_agent\` is not available (a readonly step), do the persona's work inline yourself instead of spawning.
173192
173294
 
173193
173295
  `;
173194
- WORKFLOW_STEP_VERDICTS = /* @__PURE__ */ new Set(["APPROVE", "APPROVE_WITH_NOTES", "REVISE"]);
173195
173296
  reviewStepParams = Type6.Object({
173196
173297
  step: Type6.Number({ description: "Step number to review (0-indexed; matches the `### Step N:` numbers in PROMPT.md \u2014 Step 0 is Preflight)." }),
173197
173298
  type: Type6.Union(
@@ -174904,6 +175005,18 @@ The tool prevents your session from being killed by the inactivity watchdog duri
174904
175005
  * this as a successful retry, since the original bounce may itself be
174905
175006
  * stuck.
174906
175007
  */
175008
+ /*
175009
+ FNXC:ReviewLeniency 2026-07-02-02:10:
175010
+ Clear prior terminal failure results (failed/advisory_failure — incl. optional gate nodes like code-review) so a retry starts clean. Call this ONLY once the task has left the mergeable in-review column (i.e. it is in `todo`): clearing while still in-review drops the merge blocker during the rerun-bounce window and could let a concurrent auto-merge sweep merge an empty-`steps` graph-native task with its gate failure unaddressed. `moveTask(in-review→todo)` already clears ALL results (applyReopenFieldClears), so this is chiefly for the in-progress→todo bounce path where the move does not. Passed/skipped/pending evidence is kept.
175011
+ */
175012
+ async clearTerminalStepFailuresForRetry(taskId) {
175013
+ const live = await this.store.getTask(taskId).catch(() => null);
175014
+ if (!live) return;
175015
+ const cleared = clearTerminalWorkflowStepFailures(live.workflowStepResults);
175016
+ if (cleared !== live.workflowStepResults) {
175017
+ await this.store.updateTask(taskId, { workflowStepResults: cleared }, this.getRunContextFor(taskId));
175018
+ }
175019
+ }
174907
175020
  async performWorkflowRerunBounce(taskId, worktreePath, preserveResumeState = true) {
174908
175021
  const pauseLabel = await this.getExecutionPauseLabel();
174909
175022
  if (pauseLabel) {
@@ -174943,6 +175056,7 @@ The tool prevents your session from being killed by the inactivity watchdog duri
174943
175056
  executorLog.log(`${taskId}: workflow rerun parked in todo \u2014 ${pauseLabelAfterTodo} became active during bounce`);
174944
175057
  return "deferred-paused";
174945
175058
  }
175059
+ await this.clearTerminalStepFailuresForRetry(taskId);
174946
175060
  await this.store.moveTask(taskId, "in-progress");
174947
175061
  return "bounced";
174948
175062
  }
@@ -174953,6 +175067,7 @@ The tool prevents your session from being killed by the inactivity watchdog duri
174953
175067
  executorLog.log(`${taskId}: workflow rerun parked in todo \u2014 ${pauseLabelBeforeResume} became active before resume`);
174954
175068
  return "deferred-paused";
174955
175069
  }
175070
+ await this.clearTerminalStepFailuresForRetry(taskId);
174956
175071
  await this.store.moveTask(taskId, "in-progress");
174957
175072
  return "bounced";
174958
175073
  }
@@ -177870,9 +177985,10 @@ ${prompt}`;
177870
177985
  if (cfg.summaryTarget === "task" && typeof stepOutput === "string" && stepOutput.trim()) {
177871
177986
  contextPatch.summary = stepOutput.trim();
177872
177987
  }
177873
- const advisoryFailureValue = outcome.malformed ? "advisory_failure" : "failed";
177988
+ const malformed = outcome.malformed === true;
177989
+ const advisoryFailureValue = malformed ? "advisory_failure" : "failed";
177874
177990
  return {
177875
- outcome: outcome.success || !blocking ? "success" : "failure",
177991
+ outcome: outcome.success || !blocking || malformed ? "success" : "failure",
177876
177992
  value: verdict ?? (outcome.success ? "passed" : advisoryFailureValue),
177877
177993
  ...Object.keys(contextPatch).length > 0 ? { contextPatch } : {}
177878
177994
  };
@@ -178037,6 +178153,29 @@ ${prompt}`;
178037
178153
  if (MERGE_REGION_KINDS.has(failedNode)) return true;
178038
178154
  return failedNode === "merge-manual-hold" || failedNode === "merge-retry";
178039
178155
  }
178156
+ /*
178157
+ FNXC:WorkflowRemediation 2026-07-01-23:40:
178158
+ A live agent session surface for a task proves the work is still executing, independent of the persisted column/pause/status row that handleGraphFailure re-fetches. This mirrors clearPhantomExecutorBinding's `hasLiveSessionSurface` (FN-6736) but deliberately EXCLUDES `this.executing` and graph-routing membership: those are still set for the graph run that is currently ending (graphRouting is cleared in maybeExecuteWorkflowGraph's finally, AFTER handleGraphFailure returns), so including them would report every ending run as "still executing" and suppress all failures. Only a registered coding/step/CLI session surface means a SEPARATE, live agent is working the task.
178159
+ */
178160
+ hasLiveTaskSessionSurface(taskId) {
178161
+ return this.activeSessions.has(taskId) || this.activeStepExecutors.has(taskId) || this.activeWorkflowStepSessions.has(taskId) || this.activeCliTaskSessions.has(taskId);
178162
+ }
178163
+ /*
178164
+ FNXC:WorkflowRemediation 2026-07-01-23:40:
178165
+ A `pre-merge-remediation` / `plan-replan` node (e.g. `code-review-remediation`) is a FIRE-AND-FORGET async scheduler, not a terminal work node: its job is to hand off an implementation fix (sendTaskBackForFix re-dispatches the coding session) and stop traversal. These nodes carry only a `success` rework edge back to their gate and NO `failure` out-edge, so when their schedule call cannot re-arm (missing rehydrated failureContext after a restart → `missing-remediation-context`, `remediation-not-scheduled`, or an exhausted rework budget) the failure bubbles out as the terminal graph outcome and handleGraphFailure would stamp `status:"failed"` — even while a previously-scheduled fix/reviewer session is still live. Classify these nodes so that terminal sink can preserve a still-executing task instead of flagging a spurious failure. Detection prefers the resolved IR `workflowAction` (covers custom workflows), with a node-id fallback for the built-in ids when the IR cannot be resolved.
178166
+ */
178167
+ async isRemediationGraphNode(taskId, failedNode) {
178168
+ if (!failedNode) return false;
178169
+ try {
178170
+ const ir2 = await resolveWorkflowIrForTask(this.store, taskId);
178171
+ const node = ir2?.nodes?.find((n) => n.id === failedNode);
178172
+ const action = node?.config?.workflowAction;
178173
+ if (action === "pre-merge-remediation" || action === "plan-replan") return true;
178174
+ if (node) return false;
178175
+ } catch {
178176
+ }
178177
+ return failedNode === "code-review-remediation" || failedNode === "browser-verification-remediation" || failedNode === "plan-replan";
178178
+ }
178040
178179
  isTerminalMergeGraphFailureValue(value) {
178041
178180
  if (!value) return false;
178042
178181
  const normalized = value.toLowerCase();
@@ -178546,6 +178685,13 @@ ${prompt}`;
178546
178685
  return;
178547
178686
  }
178548
178687
  }
178688
+ if (this.hasLiveTaskSessionSurface(task.id) && await this.isRemediationGraphNode(task.id, failedNode)) {
178689
+ const benignMessage = `Workflow graph ended at remediation node '${failedNode ?? "unknown"}' while a live agent session is still executing \u2014 not flagging as failed; live session preserved`;
178690
+ executorLog.warn(`${task.id}: ${benignMessage}`);
178691
+ await this.store.logEntry(task.id, benignMessage, void 0, this.getRunContextFor(task.id));
178692
+ await this.persistTokenUsage(task.id);
178693
+ return;
178694
+ }
178549
178695
  const message = `Workflow graph terminated with failure at node '${failedNode ?? "unknown"}'`;
178550
178696
  executorLog.warn(`${task.id}: ${message}`);
178551
178697
  await this.store.logEntry(task.id, message, void 0, this.getRunContextFor(task.id));
@@ -178579,6 +178725,7 @@ ${prompt}`;
178579
178725
  recoveryRehome: true
178580
178726
  });
178581
178727
  }
178728
+ await this.clearTerminalStepFailuresForRetry(live.id);
178582
178729
  await this.persistTokenUsage(live.id);
178583
178730
  return true;
178584
178731
  }
@@ -178755,6 +178902,41 @@ ${prompt}`;
178755
178902
  executorLog.log(`${liveTask.id}: executor dispatch blocked by unmet dependencies: ${unmetDeps.join(", ")}`);
178756
178903
  return true;
178757
178904
  }
178905
+ /*
178906
+ FNXC:EphemeralAgents 2026-07-01-00:00:
178907
+ `ephemeralAgentsEnabled: false` means "never spawn short-lived executor-FN-XXXX workers; only permanent agents run work" (see types.ts ephemeralAgentsEnabled). The legacy spawn refusal lives in EphemeralWorkerManager.onTaskStart (ephemeral-worker-manager.ts), but that runs as a fire-and-forget bookkeeping callback AFTER execution has already begun, so it cannot stop a run. The workflow-engine dispatch paths (maybeExecuteWorkflowGraph, workflowAuthoritativeDispatch, maybeDispatchWorkflowWorkEngine) execute tasks in-process without ever consulting the toggle. Any task that reaches execute() without a permanent assignment via a non-scheduler path (resume-after-restart, heartbeat re-entry, mission/autopilot, work-engine claim) therefore ran despite the operator disabling ephemeral agents.
178908
+
178909
+ This guard is the executor's last line of defense, mirroring the scheduler cutover gate (scheduler.ts:2464) and the spawn refusal (ephemeral-worker-manager.ts:132). It runs once at the top of the outer dispatch — before all three workflow paths — so a single check covers every workflow dispatch entry point. A task explicitly assigned to a permanent (non-ephemeral) agent is exactly how ephemeral-off mode is meant to run, so those are allowed through; everything else is re-queued for the scheduler to auto-assign a permanent agent or hold.
178910
+ */
178911
+ async blockOuterDispatchWhenEphemeralDisabled(task) {
178912
+ const settings = await this.store.getSettings();
178913
+ if (settings.ephemeralAgentsEnabled !== false) return false;
178914
+ const assignedId = task.assignedAgentId?.trim();
178915
+ if (assignedId) {
178916
+ if (!this.options.agentStore) return false;
178917
+ const agent = await this.options.agentStore.getAgent(assignedId).catch(() => null);
178918
+ if (agent && !isEphemeralAgent(agent)) return false;
178919
+ }
178920
+ const liveTask = await this.store.getTask(task.id).catch(() => null) ?? task;
178921
+ if (liveTask.column !== "todo") {
178922
+ await this.store.moveTask(liveTask.id, "todo", {
178923
+ preserveProgress: true,
178924
+ preserveWorktree: true,
178925
+ preserveResumeState: true,
178926
+ moveSource: "engine",
178927
+ recoveryRehome: true
178928
+ });
178929
+ }
178930
+ await this.store.updateTask(liveTask.id, { status: "queued" }, this.getRunContextFor(liveTask.id));
178931
+ await this.store.logEntry(
178932
+ liveTask.id,
178933
+ "queued \u2014 ephemeral agents disabled; no permanent executor assigned",
178934
+ "Executor pre-dispatch ephemeral gate blocked workflow/authoritative execution.",
178935
+ this.getRunContextFor(liveTask.id)
178936
+ );
178937
+ executorLog.log(`${liveTask.id}: executor dispatch blocked \u2014 ephemeralAgentsEnabled=false and no permanent agent assigned`);
178938
+ return true;
178939
+ }
178758
178940
  async execute(task) {
178759
178941
  this.completionFinalizedTaskIds.delete(task.id);
178760
178942
  await this.clearStalePauseAbortBeforeDispatch(task);
@@ -178764,6 +178946,7 @@ ${prompt}`;
178764
178946
  return;
178765
178947
  }
178766
178948
  if (await this.blockOuterDispatchWhenDependenciesUnmet(task)) return;
178949
+ if (await this.blockOuterDispatchWhenEphemeralDisabled(task)) return;
178767
178950
  const graphOwned = await this.maybeExecuteWorkflowGraph(task);
178768
178951
  if (graphOwned) return;
178769
178952
  const authoritativeOwned = await this.options.workflowAuthoritativeDispatch?.(task);
@@ -179629,7 +179812,7 @@ ${summary}`,
179629
179812
  const customTools = [
179630
179813
  this.createTaskUpdateTool(task.id, codeReviewVerdicts, sessionRef, stepCheckpoints, stuckDetector),
179631
179814
  this.createTaskLogTool(task.id),
179632
- this.createTaskCreateTool(),
179815
+ this.createTaskCreateTool(!identityAgent || isEphemeralAgent(identityAgent)),
179633
179816
  this.createTaskAddDepTool(task.id),
179634
179817
  this.createTaskDoneTool(task.id, worktreePath, detail.prompt ?? "", codeReviewVerdicts, () => {
179635
179818
  taskDone = true;
@@ -181193,8 +181376,12 @@ ${summary}`,
181193
181376
  createTaskLogTool(taskId) {
181194
181377
  return createTaskLogTool(this.store, taskId);
181195
181378
  }
181196
- createTaskCreateTool() {
181197
- return createTaskCreateTool(this.store, { sourceType: "api" }, { rootDir: this.rootDir });
181379
+ /*
181380
+ FNXC:EphemeralAgentTaskCreation 2026-07-01-00:00:
181381
+ A task-execution session is an ephemeral worker when no permanent identity agent governs it (default executor-FN-XXXX worker) or the governing agent is itself ephemeral. Pass that through so fn_task_create honors the project `ephemeralAgentsCanCreateTasks` toggle; permanent-agent sessions are never gated.
181382
+ */
181383
+ createTaskCreateTool(callerIsEphemeral) {
181384
+ return createTaskCreateTool(this.store, { sourceType: "api" }, { rootDir: this.rootDir, callerIsEphemeral });
181198
181385
  }
181199
181386
  createTaskDocumentWriteTool(taskId) {
181200
181387
  return createTaskDocumentWriteTool(this.store, taskId);
@@ -183332,7 +183519,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
183332
183519
  if (parsed.malformed) {
183333
183520
  await this.store.logEntry(
183334
183521
  task.id,
183335
- `[pre-merge] Workflow step '${workflowStep.name}' produced malformed output \u2014 blocking gate success`
183522
+ `[pre-merge] Workflow step '${workflowStep.name}' produced malformed output (no parseable verdict) \u2014 recorded as non-blocking advisory`
183336
183523
  );
183337
183524
  if (workflowStep.requiresBrowser === true) {
183338
183525
  await logBrowserVerificationActivity(`[browser-verification] finished browser verification for task ${task.id}: malformed output`);
@@ -183382,16 +183569,18 @@ Review the work done in this worktree and evaluate it against the criteria in yo
183382
183569
  }
183383
183570
  };
183384
183571
  const primaryOutcome = await runOnce(primaryProvider, primaryModelId, "primary");
183385
- if (!primaryOutcome.timedOut) return primaryOutcome;
183572
+ const primaryMalformed = primaryOutcome.malformed === true;
183573
+ if (!primaryOutcome.timedOut && !primaryMalformed) return primaryOutcome;
183386
183574
  if (!fallback) {
183387
- executorLog.warn(`${task.id}: workflow step '${workflowStep.name}' timed out and no fallback model is configured`);
183575
+ const reason = primaryOutcome.timedOut ? "timed out" : "produced malformed output";
183576
+ executorLog.warn(`${task.id}: workflow step '${workflowStep.name}' ${reason} and no fallback model is configured`);
183388
183577
  await this.store.logEntry(
183389
183578
  task.id,
183390
- `Workflow step '${workflowStep.name}' timed out \u2014 no fallback model configured (set settings.validatorFallbackProvider/Id or fallbackProvider/Id)`
183579
+ `Workflow step '${workflowStep.name}' ${reason} \u2014 no fallback model configured (set settings.validatorFallbackProvider/Id or fallbackProvider/Id)`
183391
183580
  );
183392
183581
  return primaryOutcome;
183393
183582
  }
183394
- executorLog.log(`${task.id}: retrying workflow step '${workflowStep.name}' with fallback ${fallback.provider}/${fallback.modelId} (label=${fallback.label})`);
183583
+ executorLog.log(`${task.id}: retrying workflow step '${workflowStep.name}' with fallback ${fallback.provider}/${fallback.modelId} (label=${fallback.label}) after primary ${primaryOutcome.timedOut ? "timeout" : "malformed output"}`);
183395
183584
  return runOnce(fallback.provider, fallback.modelId, "fallback");
183396
183585
  }
183397
183586
  MAX_WORKTREE_RETRIES = 3;
@@ -226037,7 +226226,7 @@ var init_src8 = __esm({
226037
226226
  }
226038
226227
  });
226039
226228
 
226040
- // ../../plugins/fusion-plugin-paperclip-runtime/dist/paperclip-client.js
226229
+ // ../../plugins/fusion-plugin-paperclip-runtime/src/paperclip-client.ts
226041
226230
  function normalizeApiUrl(url2) {
226042
226231
  return url2.replace(/\/+$/, "");
226043
226232
  }
@@ -226065,19 +226254,18 @@ async function parseJsonBody(response) {
226065
226254
  try {
226066
226255
  return { value: JSON.parse(raw), raw };
226067
226256
  } catch {
226068
- throw new Error(`Paperclip API ${response.status} ${response.statusText}: invalid JSON response body`);
226257
+ throw new Error(
226258
+ `Paperclip API ${response.status} ${response.statusText}: invalid JSON response body`
226259
+ );
226069
226260
  }
226070
226261
  }
226071
226262
  function toErrorMessage2(status, statusText, body, raw) {
226072
226263
  if (body && typeof body === "object") {
226073
226264
  const b2 = body;
226074
- if (typeof b2.error === "string")
226075
- return b2.error;
226076
- if (typeof b2.message === "string")
226077
- return b2.message;
226265
+ if (typeof b2.error === "string") return b2.error;
226266
+ if (typeof b2.message === "string") return b2.message;
226078
226267
  }
226079
- if (raw.trim() !== "")
226080
- return raw.slice(0, 200).trim();
226268
+ if (raw.trim() !== "") return raw.slice(0, 200).trim();
226081
226269
  return `${status} ${statusText}`.trim();
226082
226270
  }
226083
226271
  async function request(apiUrl, path6, options) {
@@ -226100,8 +226288,7 @@ async function request(apiUrl, path6, options) {
226100
226288
  if (!response.ok) {
226101
226289
  const msg = toErrorMessage2(response.status, response.statusText, value, raw);
226102
226290
  const full = `Paperclip API ${response.status} (${method} ${path6}): ${msg}`;
226103
- if (response.status === 409)
226104
- throw new ConflictError(full);
226291
+ if (response.status === 409) throw new ConflictError(full);
226105
226292
  throw new Error(full);
226106
226293
  }
226107
226294
  return value;
@@ -226111,7 +226298,9 @@ function getSettingString(settings, key) {
226111
226298
  return typeof v2 === "string" && v2.trim() !== "" ? v2.trim() : void 0;
226112
226299
  }
226113
226300
  function resolvePaperclipConfig(settings) {
226114
- const apiUrl = normalizeApiUrl(getSettingString(settings, "apiUrl") ?? process.env.PAPERCLIP_API_URL?.trim() ?? "http://localhost:3100");
226301
+ const apiUrl = normalizeApiUrl(
226302
+ getSettingString(settings, "apiUrl") ?? process.env.PAPERCLIP_API_URL?.trim() ?? "http://localhost:3100"
226303
+ );
226115
226304
  const apiKey = getSettingString(settings, "apiKey") ?? (process.env.PAPERCLIP_API_KEY?.trim() || void 0);
226116
226305
  const agentId = getSettingString(settings, "agentId") ?? process.env.PAPERCLIP_AGENT_ID?.trim() ?? void 0;
226117
226306
  const companyId = getSettingString(settings, "companyId") ?? process.env.PAPERCLIP_COMPANY_ID?.trim() ?? void 0;
@@ -226123,9 +226312,18 @@ function resolvePaperclipConfig(settings) {
226123
226312
  const parentIssueId = getSettingString(settings, "parentIssueId") ?? process.env.PAPERCLIP_PARENT_ISSUE_ID?.trim() ?? void 0;
226124
226313
  const projectId = getSettingString(settings, "projectId") ?? process.env.PAPERCLIP_PROJECT_ID?.trim() ?? void 0;
226125
226314
  const goalId = getSettingString(settings, "goalId") ?? process.env.PAPERCLIP_GOAL_ID?.trim() ?? void 0;
226126
- const runTimeoutMs = parseInt(getSettingString(settings, "runTimeoutMs") ?? process.env.PAPERCLIP_RUN_TIMEOUT_MS ?? "600000", 10);
226127
- const pollIntervalMs = parseInt(getSettingString(settings, "pollIntervalMs") ?? process.env.PAPERCLIP_POLL_INTERVAL_MS ?? "500", 10);
226128
- const pollIntervalMaxMs = parseInt(getSettingString(settings, "pollIntervalMaxMs") ?? process.env.PAPERCLIP_POLL_INTERVAL_MAX_MS ?? "2000", 10);
226315
+ const runTimeoutMs = parseInt(
226316
+ getSettingString(settings, "runTimeoutMs") ?? process.env.PAPERCLIP_RUN_TIMEOUT_MS ?? "600000",
226317
+ 10
226318
+ );
226319
+ const pollIntervalMs = parseInt(
226320
+ getSettingString(settings, "pollIntervalMs") ?? process.env.PAPERCLIP_POLL_INTERVAL_MS ?? "500",
226321
+ 10
226322
+ );
226323
+ const pollIntervalMaxMs = parseInt(
226324
+ getSettingString(settings, "pollIntervalMaxMs") ?? process.env.PAPERCLIP_POLL_INTERVAL_MAX_MS ?? "2000",
226325
+ 10
226326
+ );
226129
226327
  return {
226130
226328
  apiUrl,
226131
226329
  apiKey,
@@ -226218,11 +226416,9 @@ async function getRunEvents(apiUrl, apiKey, runId, afterSeq, limit = 100) {
226218
226416
  apiKey,
226219
226417
  query
226220
226418
  });
226221
- if (Array.isArray(result))
226222
- return result;
226419
+ if (Array.isArray(result)) return result;
226223
226420
  const r = result;
226224
- if (Array.isArray(r.events))
226225
- return r.events;
226421
+ if (Array.isArray(r.events)) return r.events;
226226
226422
  return [];
226227
226423
  }
226228
226424
  async function probePaperclipConnection(opts) {
@@ -226300,7 +226496,9 @@ function stripAnsi2(str) {
226300
226496
  function remapSpawnError(err, bin) {
226301
226497
  const code = err?.code;
226302
226498
  if (code === "ENOENT") {
226303
- return new Error(`paperclipai binary not found at ${bin}; install via \`npm i -g paperclipai\``);
226499
+ return new Error(
226500
+ `paperclipai binary not found at ${bin}; install via \`npm i -g paperclipai\``
226501
+ );
226304
226502
  }
226305
226503
  return err instanceof Error ? err : new Error(String(err));
226306
226504
  }
@@ -226336,8 +226534,7 @@ async function spawnPaperclipCliJson(args, opts) {
226336
226534
  const lines = chunk.toString("utf-8").split("\n");
226337
226535
  for (const line of lines) {
226338
226536
  const stripped = stripAnsi2(line).trim();
226339
- if (stripped)
226340
- stderrLines.push(stripped);
226537
+ if (stripped) stderrLines.push(stripped);
226341
226538
  }
226342
226539
  });
226343
226540
  child.on("error", (err) => {
@@ -226346,12 +226543,17 @@ async function spawnPaperclipCliJson(args, opts) {
226346
226543
  });
226347
226544
  child.on("close", (code) => {
226348
226545
  clearTimeout(timer);
226349
- if (killed)
226350
- return;
226351
- const cleaned = stripAnsi2(Buffer.concat(stdoutChunks).toString("utf-8")).trim();
226546
+ if (killed) return;
226547
+ const cleaned = stripAnsi2(
226548
+ Buffer.concat(stdoutChunks).toString("utf-8")
226549
+ ).trim();
226352
226550
  if (code !== 0) {
226353
226551
  const lastErr = stderrLines.filter(Boolean).pop() ?? "";
226354
- reject(new Error(lastErr ? `${label} exited ${code}: ${lastErr}` : `${label} exited ${code}`));
226552
+ reject(
226553
+ new Error(
226554
+ lastErr ? `${label} exited ${code}: ${lastErr}` : `${label} exited ${code}`
226555
+ )
226556
+ );
226355
226557
  return;
226356
226558
  }
226357
226559
  if (!cleaned) {
@@ -226361,7 +226563,9 @@ async function spawnPaperclipCliJson(args, opts) {
226361
226563
  try {
226362
226564
  resolve34(JSON.parse(cleaned));
226363
226565
  } catch {
226364
- reject(new Error(`${label} returned non-JSON output: ${cleaned.slice(0, 200)}`));
226566
+ reject(
226567
+ new Error(`${label} returned non-JSON output: ${cleaned.slice(0, 200)}`)
226568
+ );
226365
226569
  }
226366
226570
  });
226367
226571
  });
@@ -226369,40 +226573,49 @@ async function spawnPaperclipCliJson(args, opts) {
226369
226573
  async function createIssueViaCli(opts) {
226370
226574
  const args = ["issue", "create", "--company-id", opts.companyId];
226371
226575
  args.push("--title", opts.body.title);
226372
- if (opts.body.description)
226373
- args.push("--description", opts.body.description);
226374
- if (opts.body.status)
226375
- args.push("--status", opts.body.status);
226576
+ if (opts.body.description) args.push("--description", opts.body.description);
226577
+ if (opts.body.status) args.push("--status", opts.body.status);
226376
226578
  if (opts.body.assigneeAgentId)
226377
226579
  args.push("--assignee-agent-id", opts.body.assigneeAgentId);
226378
- if (opts.body.parentId)
226379
- args.push("--parent-id", opts.body.parentId);
226380
- if (opts.body.projectId)
226381
- args.push("--project-id", opts.body.projectId);
226382
- if (opts.body.goalId)
226383
- args.push("--goal-id", opts.body.goalId);
226580
+ if (opts.body.parentId) args.push("--parent-id", opts.body.parentId);
226581
+ if (opts.body.projectId) args.push("--project-id", opts.body.projectId);
226582
+ if (opts.body.goalId) args.push("--goal-id", opts.body.goalId);
226384
226583
  const raw = await spawnPaperclipCliJson(args, opts);
226385
226584
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
226386
- throw new Error(`paperclipai issue create returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`);
226585
+ throw new Error(
226586
+ `paperclipai issue create returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`
226587
+ );
226387
226588
  }
226388
226589
  return raw;
226389
226590
  }
226390
226591
  async function getIssueViaCli(opts) {
226391
- const raw = await spawnPaperclipCliJson(["issue", "get", opts.issueId], opts);
226592
+ const raw = await spawnPaperclipCliJson(
226593
+ ["issue", "get", opts.issueId],
226594
+ opts
226595
+ );
226392
226596
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
226393
- throw new Error(`paperclipai issue get returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`);
226597
+ throw new Error(
226598
+ `paperclipai issue get returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`
226599
+ );
226394
226600
  }
226395
226601
  return raw;
226396
226602
  }
226397
226603
  async function agentsMeViaCli(opts) {
226398
- const raw = await spawnPaperclipCliJson(["agent", "get", opts.agentId], opts);
226604
+ const raw = await spawnPaperclipCliJson(
226605
+ ["agent", "get", opts.agentId],
226606
+ opts
226607
+ );
226399
226608
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
226400
- throw new Error(`paperclipai agent get returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`);
226609
+ throw new Error(
226610
+ `paperclipai agent get returned unexpected payload: ${JSON.stringify(raw).slice(0, 200)}`
226611
+ );
226401
226612
  }
226402
226613
  const id = typeof raw.id === "string" ? raw.id : void 0;
226403
226614
  const cId = typeof raw.companyId === "string" ? raw.companyId : void 0;
226404
226615
  if (!id || !cId) {
226405
- throw new Error("paperclipai agent get returned a response missing `id` or `companyId`");
226616
+ throw new Error(
226617
+ "paperclipai agent get returned a response missing `id` or `companyId`"
226618
+ );
226406
226619
  }
226407
226620
  return {
226408
226621
  agentId: id,
@@ -226414,7 +226627,7 @@ async function agentsMeViaCli(opts) {
226414
226627
  }
226415
226628
  var ConflictError;
226416
226629
  var init_paperclip_client = __esm({
226417
- "../../plugins/fusion-plugin-paperclip-runtime/dist/paperclip-client.js"() {
226630
+ "../../plugins/fusion-plugin-paperclip-runtime/src/paperclip-client.ts"() {
226418
226631
  "use strict";
226419
226632
  ConflictError = class extends Error {
226420
226633
  status = 409;
@@ -226426,7 +226639,7 @@ var init_paperclip_client = __esm({
226426
226639
  }
226427
226640
  });
226428
226641
 
226429
- // ../../plugins/fusion-plugin-paperclip-runtime/dist/runtime-adapter.js
226642
+ // ../../plugins/fusion-plugin-paperclip-runtime/src/runtime-adapter.ts
226430
226643
  import { randomUUID as randomUUID27 } from "node:crypto";
226431
226644
  function sleep6(ms2) {
226432
226645
  return new Promise((resolve34) => setTimeout(resolve34, ms2));
@@ -226455,22 +226668,20 @@ function pickIssueId(issue2) {
226455
226668
  return issueId;
226456
226669
  }
226457
226670
  function normalizeMode3(mode) {
226458
- if (mode && VALID_MODES2.has(mode))
226459
- return mode;
226671
+ if (mode && VALID_MODES2.has(mode)) return mode;
226460
226672
  return "rolling-issue";
226461
226673
  }
226462
226674
  function pickLatestVisibleComment(comments) {
226463
226675
  for (let i = comments.length - 1; i >= 0; i--) {
226464
226676
  const c = comments[i];
226465
226677
  const body = asString3(c.body)?.trim();
226466
- if (body)
226467
- return body;
226678
+ if (body) return body;
226468
226679
  }
226469
226680
  return void 0;
226470
226681
  }
226471
226682
  var TERMINAL_RUN_STATUSES2, VALID_MODES2, PaperclipRuntimeAdapter;
226472
226683
  var init_runtime_adapter4 = __esm({
226473
- "../../plugins/fusion-plugin-paperclip-runtime/dist/runtime-adapter.js"() {
226684
+ "../../plugins/fusion-plugin-paperclip-runtime/src/runtime-adapter.ts"() {
226474
226685
  "use strict";
226475
226686
  init_paperclip_client();
226476
226687
  TERMINAL_RUN_STATUSES2 = /* @__PURE__ */ new Set([
@@ -226490,7 +226701,9 @@ var init_runtime_adapter4 = __esm({
226490
226701
  config;
226491
226702
  logger;
226492
226703
  constructor(config2, logger3) {
226493
- const resolved = resolvePaperclipConfig(config2);
226704
+ const resolved = resolvePaperclipConfig(
226705
+ config2
226706
+ );
226494
226707
  this.config = {
226495
226708
  ...resolved,
226496
226709
  mode: normalizeMode3(resolved.mode),
@@ -226506,13 +226719,17 @@ var init_runtime_adapter4 = __esm({
226506
226719
  configPath: this.config.cliConfigPath
226507
226720
  });
226508
226721
  if (!discovery.ok) {
226509
- throw new Error(`Paperclip CLI mode failed: ${discovery.reason} (Switch to API mode in settings if paperclipai isn't installed.)`);
226722
+ throw new Error(
226723
+ `Paperclip CLI mode failed: ${discovery.reason} (Switch to API mode in settings if paperclipai isn't installed.)`
226724
+ );
226510
226725
  }
226511
226726
  effectiveApiUrl = discovery.apiUrl;
226512
226727
  if (!effectiveApiKey) {
226513
226728
  effectiveApiKey = discovery.apiKey;
226514
226729
  }
226515
- this.logger.info(`Paperclip CLI mode resolved apiUrl=${effectiveApiUrl} (deploymentMode=${discovery.deploymentMode ?? "unknown"})`);
226730
+ this.logger.info(
226731
+ `Paperclip CLI mode resolved apiUrl=${effectiveApiUrl} (deploymentMode=${discovery.deploymentMode ?? "unknown"})`
226732
+ );
226516
226733
  }
226517
226734
  let agentId = this.config.agentId;
226518
226735
  let companyId = this.config.companyId;
@@ -226520,7 +226737,9 @@ var init_runtime_adapter4 = __esm({
226520
226737
  try {
226521
226738
  if (this.config.transport === "cli") {
226522
226739
  if (!agentId) {
226523
- throw new Error("agentId is required in Local CLI mode (paperclipai has no `agents/me` equivalent \u2014 pick an agent in settings)");
226740
+ throw new Error(
226741
+ "agentId is required in Local CLI mode (paperclipai has no `agents/me` equivalent \u2014 pick an agent in settings)"
226742
+ );
226524
226743
  }
226525
226744
  const me2 = await agentsMeViaCli({
226526
226745
  agentId,
@@ -226535,11 +226754,15 @@ var init_runtime_adapter4 = __esm({
226535
226754
  }
226536
226755
  } catch (error2) {
226537
226756
  const reason = error2 instanceof Error ? error2.message : String(error2);
226538
- throw new Error(`Paperclip runtime could not derive agentId/companyId. Configure them explicitly or check the API key / CLI auth. Underlying error: ${reason}`);
226757
+ throw new Error(
226758
+ `Paperclip runtime could not derive agentId/companyId. Configure them explicitly or check the API key / CLI auth. Underlying error: ${reason}`
226759
+ );
226539
226760
  }
226540
226761
  }
226541
226762
  if (!agentId || !companyId) {
226542
- throw new Error("Paperclip runtime is missing required config: agentId or companyId. Configure plugin settings (apiUrl, apiKey, agentId, companyId) or PAPERCLIP_* env vars.");
226763
+ throw new Error(
226764
+ "Paperclip runtime is missing required config: agentId or companyId. Configure plugin settings (apiUrl, apiKey, agentId, companyId) or PAPERCLIP_* env vars."
226765
+ );
226543
226766
  }
226544
226767
  const session = {
226545
226768
  apiUrl: effectiveApiUrl,
@@ -226636,18 +226859,15 @@ var init_runtime_adapter4 = __esm({
226636
226859
  if (!finalText) {
226637
226860
  const comments = await getIssueComments(session.apiUrl, session.apiKey, issueId);
226638
226861
  const latest = pickLatestVisibleComment(comments);
226639
- if (latest)
226640
- finalText = latest;
226862
+ if (latest) finalText = latest;
226641
226863
  }
226642
226864
  } catch (error2) {
226643
226865
  const reason = error2 instanceof Error ? error2.message : String(error2);
226644
226866
  this.logger.warn(`Paperclip post-run fetch failed: ${reason}`);
226645
226867
  }
226646
226868
  }
226647
- if (finalText)
226648
- session.onText?.(finalText);
226649
- if (stream.thinking)
226650
- session.onThinking?.(stream.thinking);
226869
+ if (finalText) session.onText?.(finalText);
226870
+ if (stream.thinking) session.onThinking?.(stream.thinking);
226651
226871
  const isError = stream.runStatus === "failed" || stream.runStatus === "timed_out";
226652
226872
  session.onToolEnd?.("paperclip.run", isError || stream.timedOutLocally, {
226653
226873
  runId,
@@ -226695,24 +226915,27 @@ var init_runtime_adapter4 = __esm({
226695
226915
  while (true) {
226696
226916
  let events = [];
226697
226917
  try {
226698
- events = await getRunEvents(session.apiUrl, session.apiKey, runId, afterSeq, 200);
226918
+ events = await getRunEvents(
226919
+ session.apiUrl,
226920
+ session.apiKey,
226921
+ runId,
226922
+ afterSeq,
226923
+ 200
226924
+ );
226699
226925
  } catch (error2) {
226700
226926
  const reason = error2 instanceof Error ? error2.message : String(error2);
226701
226927
  this.logger.warn(`Paperclip getRunEvents failed: ${reason}`);
226702
226928
  }
226703
226929
  for (const ev of events) {
226704
- if (typeof ev.seq === "number" && ev.seq > afterSeq)
226705
- afterSeq = ev.seq;
226930
+ if (typeof ev.seq === "number" && ev.seq > afterSeq) afterSeq = ev.seq;
226706
226931
  const type = ev.type ?? "";
226707
226932
  const payload = ev.payload ?? {};
226708
226933
  if (type === "heartbeat.run.status") {
226709
226934
  const next = asString3(payload.status);
226710
- if (next)
226711
- runStatus = next;
226935
+ if (next) runStatus = next;
226712
226936
  } else if (type === "heartbeat.run.log") {
226713
226937
  const chunk = asString3(payload.chunk) ?? "";
226714
- if (!chunk)
226715
- continue;
226938
+ if (!chunk) continue;
226716
226939
  if (payload.stream === "stdout") {
226717
226940
  textBuf += chunk;
226718
226941
  session.onText?.(chunk);
@@ -226724,11 +226947,12 @@ var init_runtime_adapter4 = __esm({
226724
226947
  }
226725
226948
  }
226726
226949
  }
226727
- if (TERMINAL_RUN_STATUSES2.has(runStatus))
226728
- break;
226950
+ if (TERMINAL_RUN_STATUSES2.has(runStatus)) break;
226729
226951
  if (Date.now() - startedAt > session.runTimeoutMs) {
226730
226952
  timedOutLocally = true;
226731
- this.logger.warn(`Paperclip run ${runId} exceeded local runTimeoutMs=${session.runTimeoutMs}; abandoning poll. Run continues server-side.`);
226953
+ this.logger.warn(
226954
+ `Paperclip run ${runId} exceeded local runTimeoutMs=${session.runTimeoutMs}; abandoning poll. Run continues server-side.`
226955
+ );
226732
226956
  break;
226733
226957
  }
226734
226958
  await sleep6(interval);
@@ -226740,17 +226964,20 @@ var init_runtime_adapter4 = __esm({
226740
226964
  }
226741
226965
  });
226742
226966
 
226743
- // ../../plugins/fusion-plugin-paperclip-runtime/dist/index.js
226967
+ // ../../plugins/fusion-plugin-paperclip-runtime/src/index.ts
226744
226968
  function getSettingsConfig(settings) {
226745
226969
  return resolvePaperclipConfig(settings ?? {});
226746
226970
  }
226747
226971
  async function paperclipRuntimeFactory(ctx) {
226748
226972
  const config2 = getSettingsConfig(ctx.settings);
226749
- return new PaperclipRuntimeAdapter(config2, ctx.logger);
226973
+ return new PaperclipRuntimeAdapter(
226974
+ config2,
226975
+ ctx.logger
226976
+ );
226750
226977
  }
226751
226978
  var paperclipRuntime, plugin4;
226752
- var init_dist = __esm({
226753
- "../../plugins/fusion-plugin-paperclip-runtime/dist/index.js"() {
226979
+ var init_src9 = __esm({
226980
+ "../../plugins/fusion-plugin-paperclip-runtime/src/index.ts"() {
226754
226981
  "use strict";
226755
226982
  init_src5();
226756
226983
  init_paperclip_client();
@@ -226795,7 +227022,9 @@ var init_dist = __esm({
226795
227022
  });
226796
227023
  if (status.available) {
226797
227024
  const ident = status.identity;
226798
- ctx.logger.info(ident ? `Paperclip reachable as ${ident.agentName} (${ident.role ?? "agent"}) at ${ident.companyName ?? ident.companyId}` : `Paperclip reachable at ${config2.apiUrl}`);
227025
+ ctx.logger.info(
227026
+ ident ? `Paperclip reachable as ${ident.agentName} (${ident.role ?? "agent"}) at ${ident.companyName ?? ident.companyId}` : `Paperclip reachable at ${config2.apiUrl}`
227027
+ );
226799
227028
  } else {
226800
227029
  ctx.logger.warn(`Paperclip probe failed: ${status.reason ?? "unknown"}`);
226801
227030
  }
@@ -226816,7 +227045,7 @@ var init_runtime_provider_probes = __esm({
226816
227045
  init_src6();
226817
227046
  init_src7();
226818
227047
  init_src8();
226819
- init_dist();
227048
+ init_src9();
226820
227049
  }
226821
227050
  });
226822
227051
 
@@ -228649,7 +228878,7 @@ var init_server = __esm({
228649
228878
 
228650
228879
  // ../../plugins/fusion-plugin-roadmap/src/index.ts
228651
228880
  var plugin5;
228652
- var init_src9 = __esm({
228881
+ var init_src10 = __esm({
228653
228882
  "../../plugins/fusion-plugin-roadmap/src/index.ts"() {
228654
228883
  "use strict";
228655
228884
  init_src5();
@@ -228686,7 +228915,7 @@ var init_roadmap_routes3 = __esm({
228686
228915
  "../dashboard/src/roadmap-routes.ts"() {
228687
228916
  "use strict";
228688
228917
  init_src();
228689
- init_src9();
228918
+ init_src10();
228690
228919
  init_project_store_resolver();
228691
228920
  }
228692
228921
  });
@@ -229227,7 +229456,7 @@ var init_plugins = __esm({
229227
229456
  });
229228
229457
 
229229
229458
  // ../dashboard/src/index.ts
229230
- var init_src10 = __esm({
229459
+ var init_src11 = __esm({
229231
229460
  "../dashboard/src/index.ts"() {
229232
229461
  "use strict";
229233
229462
  init_server2();
@@ -229570,7 +229799,7 @@ var init_pr = __esm({
229570
229799
  init_src();
229571
229800
  init_gh_cli();
229572
229801
  init_src4();
229573
- init_src10();
229802
+ init_src11();
229574
229803
  init_project_context();
229575
229804
  }
229576
229805
  });
@@ -231091,7 +231320,7 @@ var init_task = __esm({
231091
231320
  init_src();
231092
231321
  init_src4();
231093
231322
  init_planning();
231094
- init_src10();
231323
+ init_src11();
231095
231324
  init_gh_cli();
231096
231325
  init_project_context();
231097
231326
  init_node();
@@ -231246,7 +231475,7 @@ init_src();
231246
231475
  init_src();
231247
231476
  init_gh_cli();
231248
231477
  init_src4();
231249
- init_src10();
231478
+ init_src11();
231250
231479
  import { Type as Type9 } from "typebox";
231251
231480
  import { StringEnum } from "@earendil-works/pi-ai";
231252
231481
  import { resolve as resolve33, basename as basename19, extname as extname3, join as join66 } from "node:path";
@@ -231365,6 +231594,19 @@ async function validateAssignableAgentId(cwd, agentId, task, override = false) {
231365
231594
  }
231366
231595
  return null;
231367
231596
  }
231597
+ async function isEphemeralCallerAgent(cwd, callerAgentId) {
231598
+ if (!callerAgentId) return false;
231599
+ try {
231600
+ const { AgentStore: AgentStore2, isEphemeralAgent: isEphemeralAgent2 } = await Promise.resolve().then(() => (init_src(), src_exports));
231601
+ const agentStore = new AgentStore2({ rootDir: getFusionDir(cwd) });
231602
+ await agentStore.init();
231603
+ const agent = await agentStore.resolveAgent(callerAgentId);
231604
+ if (!agent) return false;
231605
+ return isEphemeralAgent2(agent);
231606
+ } catch {
231607
+ return false;
231608
+ }
231609
+ }
231368
231610
  function normalizeNullableStringInput(value) {
231369
231611
  if (value === void 0) {
231370
231612
  return void 0;
@@ -231732,6 +231974,16 @@ function kbExtension(pi2) {
231732
231974
  }),
231733
231975
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
231734
231976
  const store = await getStore2(ctx.cwd);
231977
+ const fnCtx = ctx;
231978
+ const projectSettingsForGate = await store.getSettings();
231979
+ if (projectSettingsForGate.ephemeralAgentsCanCreateTasks === false && await isEphemeralCallerAgent(ctx.cwd ?? process.cwd(), fnCtx.agentId)) {
231980
+ const error2 = "Ephemeral task-worker agents are not allowed to create tasks (ephemeralAgentsCanCreateTasks is disabled for this project).";
231981
+ return {
231982
+ content: [{ type: "text", text: `ERROR: ${error2}` }],
231983
+ isError: true,
231984
+ details: { error: error2, rule: "ephemeral-agents-cannot-create-tasks", callerAgentId: fnCtx.agentId }
231985
+ };
231986
+ }
231735
231987
  const normalizedAgentId = normalizeNullableStringInput(params.agentId);
231736
231988
  if (normalizedAgentId !== void 0 && normalizedAgentId !== null) {
231737
231989
  const candidateTask = { id: "<new>", column: "todo" };
@@ -231745,11 +231997,10 @@ function kbExtension(pi2) {
231745
231997
  }
231746
231998
  }
231747
231999
  try {
231748
- const projectSettings = await store.getSettings();
231749
232000
  const globalSettings = await store.getGlobalSettingsStore().getSettings();
231750
232001
  const resolvedTracking = resolveTaskGithubTracking(
231751
232002
  { githubTracking: void 0 },
231752
- projectSettings,
232003
+ projectSettingsForGate,
231753
232004
  globalSettings
231754
232005
  );
231755
232006
  const workflowId = params.workflow_id?.trim() || void 0;
@@ -232330,11 +232581,13 @@ Path: .fusion/tasks/${params.id}/attachments/${attachment.filename}`
232330
232581
  }),
232331
232582
  async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
232332
232583
  const store = await getStore2(ctx.cwd);
232584
+ const callerTaskId = ctx.taskId;
232333
232585
  const task = await store.deleteTask(params.id, {
232334
232586
  allowResurrection: params.allowResurrection === true,
232335
232587
  auditContext: {
232336
232588
  agentId: "pi-extension",
232337
- runId: `synthetic-pi-delete-${params.id}-${Date.now()}`
232589
+ runId: `synthetic-pi-delete-${params.id}-${Date.now()}`,
232590
+ taskId: callerTaskId
232338
232591
  }
232339
232592
  });
232340
232593
  return {