@runfusion/fusion 0.38.1 → 0.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/bin.mjs +20 -0
  2. package/dist/automation-store-EKXXEE2S.js +10 -0
  3. package/dist/automation-store-PLNG3X72.js +10 -0
  4. package/dist/automation-store-RDDYZFUJ.js +10 -0
  5. package/dist/bin.js +72539 -40364
  6. package/dist/chunk-2JI3F6MG.js +948 -0
  7. package/dist/chunk-4L6CLWJC.js +8345 -0
  8. package/dist/chunk-4VNS5WPM.js +42 -0
  9. package/dist/chunk-5RGECGQL.js +1139 -0
  10. package/dist/chunk-6JDLN7IL.js +409 -0
  11. package/dist/chunk-AICJATVW.js +948 -0
  12. package/dist/chunk-AWKNRUOR.js +1148 -0
  13. package/dist/chunk-BHM3UYWS.js +4651 -0
  14. package/dist/chunk-BMUXDSBF.js +4647 -0
  15. package/dist/chunk-GETECT6V.js +353 -0
  16. package/dist/chunk-GUV4QQT3.js +1143 -0
  17. package/dist/chunk-JKQO7YYZ.js +8369 -0
  18. package/dist/chunk-LYZVU6UV.js +409 -0
  19. package/dist/chunk-MAN4WYHO.js +353 -0
  20. package/dist/chunk-MCUG2Z7M.js +4651 -0
  21. package/dist/chunk-PSDYB45U.js +948 -0
  22. package/dist/chunk-RR2HM46R.js +8345 -0
  23. package/dist/chunk-RXMQ5OMY.js +9226 -0
  24. package/dist/chunk-S2EVJUY3.js +353 -0
  25. package/dist/chunk-UXR5XZFZ.js +409 -0
  26. package/dist/client/.vite/manifest.json +457 -155
  27. package/dist/client/assets/AgentDetailView-BrETpTDj.js +18 -0
  28. package/dist/client/assets/AgentPermissionPolicyEditor-BP6d1LFG.js +6 -0
  29. package/dist/client/assets/AgentsView-COx3draV.js +29 -0
  30. package/dist/client/assets/{AgentsView-BI_CESkd.css → AgentsView-DfznJDek.css} +1 -1
  31. package/dist/client/assets/ChatView-CrVSqQK_.js +6 -0
  32. package/dist/client/assets/DevServerView-DXQ1LX4H.js +1 -0
  33. package/dist/client/assets/DirectoryPicker-B_8ICSPl.js +1 -0
  34. package/dist/client/assets/{DirectoryPicker-DzKVmxOf.css → DirectoryPicker-DTKtd8L2.css} +1 -1
  35. package/dist/client/assets/DocumentsView-DmNB9rJZ.js +1 -0
  36. package/dist/client/assets/DocumentsView-WfVoTZt8.css +1 -0
  37. package/dist/client/assets/EvalsView-72w3_AO6.js +1 -0
  38. package/dist/client/assets/{ExperimentalAgentOnboardingModal-lXM--LV-.js → ExperimentalAgentOnboardingModal-Be4oaohM.js} +41 -41
  39. package/dist/client/assets/GoalsView-DI66UsjT.css +1 -0
  40. package/dist/client/assets/GoalsView-DkEXO_mx.js +2 -0
  41. package/dist/client/assets/InsightsView-_-wd4BOJ.js +11 -0
  42. package/dist/client/assets/MemoryView-BOCIc8HT.js +2 -0
  43. package/dist/client/assets/NodesView-7VInxyf_.css +1 -0
  44. package/dist/client/assets/NodesView-DTQP1j4H.js +14 -0
  45. package/dist/client/assets/PiExtensionsManager-BqaI9GKX.js +11 -0
  46. package/dist/client/assets/PluginManager-DYaVwsXd.js +1 -0
  47. package/dist/client/assets/{PluginManager-BJQXdUmV.css → PluginManager-UHVLvWWl.css} +1 -1
  48. package/dist/client/assets/PullRequestView-Dk9a7jRZ.js +6 -0
  49. package/dist/client/assets/PullRequestView-WQIS0zUC.css +1 -0
  50. package/dist/client/assets/ReliabilityView-B-i5SOoD.js +1 -0
  51. package/dist/client/assets/ReliabilityView-eoKBhBc4.css +1 -0
  52. package/dist/client/assets/ResearchView-C2Gx8jC9.js +1 -0
  53. package/dist/client/assets/SecretsView-Db2HAGi2.js +1 -0
  54. package/dist/client/assets/SessionTerminal-BiigPP2l.css +1 -0
  55. package/dist/client/assets/SessionTerminal-DwlNZLlr.js +2 -0
  56. package/dist/client/assets/{SettingsModal-Cy42vswI.js → SettingsModal-B-d30TVy.js} +1 -1
  57. package/dist/client/assets/SettingsModal-Dje7N0hv.js +31 -0
  58. package/dist/client/assets/SettingsModal-bJvc9aHl.css +1 -0
  59. package/dist/client/assets/SettingsModal-nF_GaeeK.css +1 -0
  60. package/dist/client/assets/SetupWizardModal-CIqFbkrD.css +1 -0
  61. package/dist/client/assets/SetupWizardModal-Cw3RdN83.js +1 -0
  62. package/dist/client/assets/SkillsView-3bhGyWs1.css +1 -0
  63. package/dist/client/assets/SkillsView-BGyynaI4.js +1 -0
  64. package/dist/client/assets/StashRecoveryView-CFaU-hym.js +1 -0
  65. package/dist/client/assets/{TodoView-Cx9cVhq7.css → TodoView-7xIh-Fmi.css} +1 -1
  66. package/dist/client/assets/TodoView-Djjwcb49.js +6 -0
  67. package/dist/client/assets/WorkflowNodeEditor-Po5uv_dN.css +1 -0
  68. package/dist/client/assets/WorkflowNodeEditor-vnXnKvAr.js +8 -0
  69. package/dist/client/assets/{addon-fit-C7jRorKK.js → addon-fit-B4jkcKk4.js} +1 -1
  70. package/dist/client/assets/addon-unicode11-Cdne2Sj4.js +1 -0
  71. package/dist/client/assets/{addon-web-links-CkJwd4cQ.js → addon-web-links-CRNLzj7m.js} +1 -1
  72. package/dist/client/assets/{addon-webgl-BjvOw43o.js → addon-webgl-CeCSULF1.js} +1 -1
  73. package/dist/client/assets/app-CTRT_hQh.js +13 -0
  74. package/dist/client/assets/app-CVg6W-HU.js +13 -0
  75. package/dist/client/assets/app-CY3pQXOr.js +13 -0
  76. package/dist/client/assets/app-DNh04p5I.js +13 -0
  77. package/dist/client/assets/app-DhHgtB9j.js +13 -0
  78. package/dist/client/assets/app-NL_hPGDS.js +13 -0
  79. package/dist/client/assets/common-BRyX4VxB.js +1 -0
  80. package/dist/client/assets/common-CN9QPI2d.js +1 -0
  81. package/dist/client/assets/common-CNbjPELi.js +1 -0
  82. package/dist/client/assets/common-DFDqu_n0.js +1 -0
  83. package/dist/client/assets/common-DgWWKG8Z.js +1 -0
  84. package/dist/client/assets/common-X6PzBnVA.js +1 -0
  85. package/dist/client/assets/{createLucideIcon-BazL2hk5.js → createLucideIcon-BYvOGRiO.js} +2 -2
  86. package/dist/client/assets/dashboard-view-BgiLoG1G.css +1 -0
  87. package/dist/client/assets/{dashboard-view-DqWnXEbq.css → dashboard-view-CuUPQZzi.css} +1 -1
  88. package/dist/client/assets/dashboard-view-DOEa6gWS.js +1 -0
  89. package/dist/client/assets/dashboard-view-DlKsVySD.js +3 -0
  90. package/dist/client/assets/dashboard-view-O5j3PSGY.js +8101 -0
  91. package/dist/client/assets/errors-07IrmOYM.js +1 -0
  92. package/dist/client/assets/errors-BPsCufin.js +1 -0
  93. package/dist/client/assets/errors-CcVDgqlA.js +1 -0
  94. package/dist/client/assets/errors-D-i_Bxc6.js +1 -0
  95. package/dist/client/assets/errors-DDdWAK-U.js +1 -0
  96. package/dist/client/assets/errors-DOF5Td3F.js +1 -0
  97. package/dist/client/assets/{folder-open-Doam5g-y.js → folder-open-BtEAEp7E.js} +1 -1
  98. package/dist/client/assets/index-BHGM5W8a.css +1 -0
  99. package/dist/client/assets/index-CW4OzecJ.js +793 -0
  100. package/dist/client/assets/{upload-BUfrZl69.js → upload-Y9NiLQ9o.js} +1 -1
  101. package/dist/client/assets/{users-XNGnYBJb.js → users-B13HD4Tp.js} +1 -1
  102. package/dist/client/assets/vendor-i18n-CV0mwX_-.js +9 -0
  103. package/dist/client/assets/{vendor-react-K0fH_qHe.js → vendor-react-D37HfzIf.js} +1 -1
  104. package/dist/client/assets/vendor-reactflow-C5ap-Sga.css +1 -0
  105. package/dist/client/assets/vendor-reactflow-CRZcPCXF.js +15 -0
  106. package/dist/client/assets/{vendor-xterm-DzcZoU0P.js → vendor-xterm-tcedd2Jt.js} +1 -1
  107. package/dist/client/assets/x-CqNX_9E2.js +61 -0
  108. package/dist/client/assets/zoom-out-CSTHbJgD.js +21 -0
  109. package/dist/client/index.html +7 -4
  110. package/dist/client/sw.js +36 -1
  111. package/dist/client/version.json +1 -1
  112. package/dist/droid-cli/package.json +2 -2
  113. package/dist/extension.js +67616 -44149
  114. package/dist/extract-zip-WL55Z3AU.js +2497 -0
  115. package/dist/index.min-CHQ3ABYJ.js +2926 -0
  116. package/dist/memory-dreams-7USISKVE.js +32 -0
  117. package/dist/memory-dreams-PBPISUDD.js +32 -0
  118. package/dist/memory-dreams-XNO2B2QF.js +32 -0
  119. package/dist/migration-EH2YOCYQ.js +15 -0
  120. package/dist/migration-PLGTTKL5.js +15 -0
  121. package/dist/migration-WZEZK22R.js +15 -0
  122. package/dist/pi-claude-cli/package.json +2 -2
  123. package/dist/plugin-sdk/index.d.ts +97 -0
  124. package/dist/plugin-sdk/index.js +55 -0
  125. package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +17286 -0
  126. package/dist/plugins/fusion-plugin-acp-runtime/manifest.json +13 -0
  127. package/dist/plugins/fusion-plugin-acp-runtime/package.json +11 -0
  128. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +2 -3
  129. package/dist/plugins/fusion-plugin-cli-printing-press/src/dashboard-interop.d.ts +19 -0
  130. package/dist/plugins/fusion-plugin-cli-printing-press/src/index.ts +0 -3
  131. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +1984 -0
  132. package/dist/plugins/fusion-plugin-compound-engineering/manifest.json +56 -0
  133. package/dist/plugins/fusion-plugin-compound-engineering/package.json +11 -0
  134. package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +5 -0
  135. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  136. package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +5 -0
  137. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  138. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +43 -4
  139. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  140. package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +5 -0
  141. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  142. package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +5 -0
  143. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  144. package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +5 -0
  145. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  146. package/dist/plugins/fusion-plugin-reports/package.json +2 -2
  147. package/dist/plugins/fusion-plugin-reports/src/__tests__/review-panel.test.ts +3 -3
  148. package/dist/plugins/fusion-plugin-reports/src/index.ts +0 -1
  149. package/dist/plugins/fusion-plugin-roadmap/bundled.js +5 -0
  150. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  151. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +2 -2
  152. package/dist/routine-store-GIJ6MXWY.js +10 -0
  153. package/dist/routine-store-HTVC2PUQ.js +10 -0
  154. package/dist/routine-store-KGHZBPDF.js +10 -0
  155. package/package.json +24 -10
  156. package/skill/fusion/SKILL.md +1 -1
  157. package/skill/fusion/references/engine-tools.md +79 -3
  158. package/skill/fusion/references/extension-tools.md +79 -4
  159. package/skill/fusion/references/fusion-capabilities.md +12 -4
  160. package/dist/client/assets/AgentDetailView-DuRYmHK3.js +0 -18
  161. package/dist/client/assets/AgentPermissionPolicyEditor-ClY32kYN.js +0 -6
  162. package/dist/client/assets/AgentsView-UbCAHs_i.js +0 -29
  163. package/dist/client/assets/ChatView-DDDjYRKc.js +0 -6
  164. package/dist/client/assets/DevServerView-DY5GlJcD.js +0 -1
  165. package/dist/client/assets/DirectoryPicker-B4VRL2BH.js +0 -1
  166. package/dist/client/assets/DocumentsView-gv4zG3aT.css +0 -1
  167. package/dist/client/assets/DocumentsView-tqpIZ9t9.js +0 -1
  168. package/dist/client/assets/EvalsView-C_Br3ry8.js +0 -1
  169. package/dist/client/assets/GoalsView-B65urz9k.css +0 -1
  170. package/dist/client/assets/GoalsView-CI3Bzs1b.js +0 -1
  171. package/dist/client/assets/InsightsView-BYfsVobi.js +0 -11
  172. package/dist/client/assets/MemoryView-DT4vIhaW.js +0 -2
  173. package/dist/client/assets/NodesView-DT4pXowv.css +0 -1
  174. package/dist/client/assets/NodesView-Dx6HFqjI.js +0 -14
  175. package/dist/client/assets/PiExtensionsManager-BcGBnNiC.js +0 -6
  176. package/dist/client/assets/PluginManager-T_XZ7iNI.js +0 -1
  177. package/dist/client/assets/ReliabilityView-C1C1j1SD.js +0 -1
  178. package/dist/client/assets/ReliabilityView-D9AsVv5l.css +0 -1
  179. package/dist/client/assets/ResearchView-Bv4igpnv.js +0 -1
  180. package/dist/client/assets/SecretsView-C4VX2ZTa.js +0 -1
  181. package/dist/client/assets/SettingsModal-CLEkhLK_.js +0 -31
  182. package/dist/client/assets/SettingsModal-DZrJ5PFH.css +0 -1
  183. package/dist/client/assets/SettingsModal-D_uIvf6n.css +0 -1
  184. package/dist/client/assets/SetupWizardModal-CGYGKurR.css +0 -1
  185. package/dist/client/assets/SetupWizardModal-LqloAL4J.js +0 -1
  186. package/dist/client/assets/SkillsView-CUbSBeZ2.css +0 -1
  187. package/dist/client/assets/SkillsView-I1SDKaRz.js +0 -1
  188. package/dist/client/assets/StashRecoveryView-DMUUR3cy.js +0 -1
  189. package/dist/client/assets/TodoView-PKvJKjtV.js +0 -6
  190. package/dist/client/assets/dashboard-view-BWGH_fAq.js +0 -63
  191. package/dist/client/assets/dashboard-view-D4XVI1XP.js +0 -21
  192. package/dist/client/assets/index-BS-jSWPW.js +0 -742
  193. package/dist/client/assets/index-ktpD_W3I.css +0 -1
@@ -0,0 +1,56 @@
1
+ {
2
+ "id": "fusion-plugin-compound-engineering",
3
+ "name": "Compound Engineering",
4
+ "version": "0.1.0",
5
+ "description": "A dedicated dashboard surface for compound-engineering artifacts and interactive ce-* sessions.",
6
+ "author": "Fusion Team",
7
+ "fusionVersion": ">=0.1.0",
8
+ "dashboardViews": [
9
+ {
10
+ "viewId": "compound-engineering",
11
+ "label": "Compound Engineering",
12
+ "componentPath": "./dashboard-view",
13
+ "icon": "Sparkles",
14
+ "placement": "primary",
15
+ "order": 36
16
+ }
17
+ ],
18
+ "settingsSchema": {
19
+ "defaultProvider": {
20
+ "type": "string",
21
+ "label": "Default Session Provider",
22
+ "description": "Model provider used for CE interactive sessions (for example anthropic). Leave blank to use the host default.",
23
+ "group": "Sessions",
24
+ "defaultValue": ""
25
+ },
26
+ "defaultModelId": {
27
+ "type": "string",
28
+ "label": "Default Session Model",
29
+ "description": "Model ID within the provider used for CE interactive sessions. Leave blank to use the host default.",
30
+ "group": "Sessions",
31
+ "defaultValue": ""
32
+ },
33
+ "enabledStages": {
34
+ "type": "array",
35
+ "itemType": "string",
36
+ "label": "Enabled Stages",
37
+ "description": "Stage IDs that may be launched from the Compound Engineering view (for example strategy, ideate, brainstorm, plan, work).",
38
+ "group": "Sessions",
39
+ "defaultValue": ["strategy", "ideate", "brainstorm", "plan", "work"]
40
+ },
41
+ "reconcileOnHooks": {
42
+ "type": "boolean",
43
+ "label": "Reconcile on Board Changes",
44
+ "description": "Run the board→pipeline reconcile sweep automatically after task move/complete hooks. Disable to only reconcile on demand.",
45
+ "group": "Sync",
46
+ "defaultValue": true
47
+ },
48
+ "reconcileIntervalMinutes": {
49
+ "type": "number",
50
+ "label": "Reconcile Cadence (minutes)",
51
+ "description": "Cadence hint for how often an on-demand refresh surface sweeps the reconciler. Not a continuous poll loop.",
52
+ "group": "Sync",
53
+ "defaultValue": 15
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@fusion-plugin-examples/compound-engineering",
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./bundled.js"
8
+ }
9
+ },
10
+ "private": true
11
+ }
@@ -1,4 +1,9 @@
1
1
  // ../plugin-sdk/src/index.ts
2
+ import {
3
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
4
+ workflowExtensionRegistryId,
5
+ createBoardActionServices
6
+ } from "@fusion/core";
2
7
  function definePlugin(plugin2) {
3
8
  return plugin2;
4
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/cursor-runtime",
3
- "version": "0.1.18",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,4 +1,9 @@
1
1
  // ../plugin-sdk/src/index.ts
2
+ import {
3
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
4
+ workflowExtensionRegistryId,
5
+ createBoardActionServices
6
+ } from "@fusion/core";
2
7
  function definePlugin(plugin2) {
3
8
  return plugin2;
4
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/dependency-graph",
3
- "version": "0.1.30",
3
+ "version": "0.1.33",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -129072,6 +129072,11 @@ var init_openai_responses = __esm({
129072
129072
  });
129073
129073
 
129074
129074
  // ../plugin-sdk/src/index.ts
129075
+ import {
129076
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
129077
+ workflowExtensionRegistryId,
129078
+ createBoardActionServices
129079
+ } from "@fusion/core";
129075
129080
  function definePlugin(plugin2) {
129076
129081
  return plugin2;
129077
129082
  }
@@ -137081,6 +137086,20 @@ function mapStopReason5(reason) {
137081
137086
  return "stop";
137082
137087
  }
137083
137088
  }
137089
+ function normalizeStreamingDelta(previousText, nextDelta) {
137090
+ if (!previousText || !nextDelta) {
137091
+ return nextDelta;
137092
+ }
137093
+ const previousChar = previousText.slice(-1);
137094
+ const nextChar = nextDelta[0] ?? "";
137095
+ if (/\s/.test(previousChar) || /\s/.test(nextChar)) {
137096
+ return nextDelta;
137097
+ }
137098
+ if (/[.!?]/.test(previousChar) && /[A-Z0-9"'([]/.test(nextChar)) {
137099
+ return ` ${nextDelta}`;
137100
+ }
137101
+ return nextDelta;
137102
+ }
137084
137103
  function createEventBridge(stream2, model) {
137085
137104
  const blocks = [];
137086
137105
  const output = {
@@ -137101,6 +137120,18 @@ function createEventBridge(stream2, model) {
137101
137120
  timestamp: Date.now()
137102
137121
  };
137103
137122
  let started = false;
137123
+ function getPreviousContentText(contentIndex, type) {
137124
+ for (let i2 = contentIndex - 1; i2 >= 0; i2--) {
137125
+ const contentBlock = output.content[i2];
137126
+ if (type === "text" && contentBlock?.type === "text") {
137127
+ return contentBlock.text;
137128
+ }
137129
+ if (type === "thinking" && contentBlock?.type === "thinking") {
137130
+ return contentBlock.thinking;
137131
+ }
137132
+ }
137133
+ return "";
137134
+ }
137104
137135
  function handleEvent(event) {
137105
137136
  if (!started) {
137106
137137
  stream2.push({ type: "start", partial: output });
@@ -137207,13 +137238,17 @@ function createEventBridge(stream2, model) {
137207
137238
  if (idx === -1) return;
137208
137239
  const block = blocks[idx];
137209
137240
  if (block.type === "text") {
137210
- block.text += event.delta.text;
137241
+ const delta = normalizeStreamingDelta(
137242
+ block.text || getPreviousContentText(idx, "text"),
137243
+ event.delta.text
137244
+ );
137245
+ block.text += delta;
137211
137246
  const contentBlock = output.content[idx];
137212
137247
  contentBlock.text = block.text;
137213
137248
  stream2.push({
137214
137249
  type: "text_delta",
137215
137250
  contentIndex: idx,
137216
- delta: event.delta.text,
137251
+ delta,
137217
137252
  partial: output
137218
137253
  });
137219
137254
  }
@@ -137222,13 +137257,17 @@ function createEventBridge(stream2, model) {
137222
137257
  if (idx === -1) return;
137223
137258
  const block = blocks[idx];
137224
137259
  if (block.type === "thinking") {
137225
- block.text += event.delta.thinking;
137260
+ const delta = normalizeStreamingDelta(
137261
+ block.text || getPreviousContentText(idx, "thinking"),
137262
+ event.delta.thinking
137263
+ );
137264
+ block.text += delta;
137226
137265
  const contentBlock = output.content[idx];
137227
137266
  contentBlock.thinking = block.text;
137228
137267
  stream2.push({
137229
137268
  type: "thinking_delta",
137230
137269
  contentIndex: idx,
137231
- delta: event.delta.thinking,
137270
+ delta,
137232
137271
  partial: output
137233
137272
  });
137234
137273
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/droid-runtime",
3
- "version": "0.1.25",
3
+ "version": "0.1.28",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,4 +1,9 @@
1
1
  // ../plugin-sdk/src/index.ts
2
+ import {
3
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
4
+ workflowExtensionRegistryId,
5
+ createBoardActionServices
6
+ } from "@fusion/core";
2
7
  function definePlugin(plugin2) {
3
8
  return plugin2;
4
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/hermes-runtime",
3
- "version": "0.2.49",
3
+ "version": "0.2.52",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,4 +1,9 @@
1
1
  // ../plugin-sdk/src/index.ts
2
+ import {
3
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
4
+ workflowExtensionRegistryId,
5
+ createBoardActionServices
6
+ } from "@fusion/core";
2
7
  function definePlugin(plugin2) {
3
8
  return plugin2;
4
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/openclaw-runtime",
3
- "version": "0.2.49",
3
+ "version": "0.2.52",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,4 +1,9 @@
1
1
  // ../plugin-sdk/src/index.ts
2
+ import {
3
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
4
+ workflowExtensionRegistryId,
5
+ createBoardActionServices
6
+ } from "@fusion/core";
2
7
  function definePlugin(plugin2) {
3
8
  return plugin2;
4
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/paperclip-runtime",
3
- "version": "0.2.49",
3
+ "version": "0.2.52",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/reports",
3
- "version": "0.1.18",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "description": "Reports plugin for Fusion",
6
6
  "private": true,
@@ -37,6 +37,6 @@
37
37
  "@types/react": "^19.0.0",
38
38
  "@types/node": "^25.5.2",
39
39
  "typescript": "^5.7.0",
40
- "vitest": "^3.2.4"
40
+ "vitest": "^4.1.0"
41
41
  }
42
42
  }
@@ -83,9 +83,9 @@ describe("runReviewPanel", () => {
83
83
  if (systemPrompt.includes("Operations")) {
84
84
  return {
85
85
  session: {
86
- prompt: vi.fn(async () => new Promise(() => {})),
86
+ prompt: vi.fn(async () => new Promise<void>(() => {})),
87
87
  state: { messages: [] },
88
- dispose: vi.fn(),
88
+ dispose: vi.fn<() => void>(),
89
89
  },
90
90
  };
91
91
  }
@@ -93,7 +93,7 @@ describe("runReviewPanel", () => {
93
93
  session: {
94
94
  prompt: vi.fn(async () => {}),
95
95
  state: { messages: [{ role: "assistant", content: JSON.stringify({ verdict: "approve", summary: "ok", highlights: [], lowlights: [], suggestions: [] }) }] },
96
- dispose: vi.fn(),
96
+ dispose: vi.fn<() => void>(),
97
97
  },
98
98
  };
99
99
  });
@@ -16,7 +16,6 @@ import {
16
16
  } from "./settings.js";
17
17
  import type { ReportCadence, ReportCreateInput } from "./store/report-types.js";
18
18
  import { ReportStore } from "./store/report-store.js";
19
- export { ReportsDashboardView } from "./dashboard-view.js";
20
19
 
21
20
  const plugin = definePlugin({
22
21
  manifest: {
@@ -1,4 +1,9 @@
1
1
  // ../plugin-sdk/src/index.ts
2
+ import {
3
+ WORKFLOW_EXTENSION_SCHEMA_VERSION,
4
+ workflowExtensionRegistryId,
5
+ createBoardActionServices
6
+ } from "@fusion/core";
2
7
  function definePlugin(plugin2) {
3
8
  return plugin2;
4
9
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/roadmap",
3
- "version": "0.1.18",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/whatsapp-chat",
3
- "version": "0.1.18",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "description": "WhatsApp Web (Baileys) chat bridge for Fusion agents",
6
6
  "keywords": [
@@ -29,6 +29,6 @@
29
29
  "devDependencies": {
30
30
  "@types/node": "^25.5.2",
31
31
  "typescript": "^5.7.0",
32
- "vitest": "^3.2.4"
32
+ "vitest": "^4.1.0"
33
33
  }
34
34
  }
@@ -0,0 +1,10 @@
1
+ import {
2
+ RoutineStore
3
+ } from "./chunk-LYZVU6UV.js";
4
+ import "./chunk-RXMQ5OMY.js";
5
+ import "./chunk-BHM3UYWS.js";
6
+ import "./chunk-AWKNRUOR.js";
7
+ import "./chunk-4VNS5WPM.js";
8
+ export {
9
+ RoutineStore
10
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ RoutineStore
3
+ } from "./chunk-6JDLN7IL.js";
4
+ import "./chunk-RXMQ5OMY.js";
5
+ import "./chunk-MCUG2Z7M.js";
6
+ import "./chunk-GUV4QQT3.js";
7
+ import "./chunk-4VNS5WPM.js";
8
+ export {
9
+ RoutineStore
10
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ RoutineStore
3
+ } from "./chunk-UXR5XZFZ.js";
4
+ import "./chunk-RXMQ5OMY.js";
5
+ import "./chunk-BMUXDSBF.js";
6
+ import "./chunk-5RGECGQL.js";
7
+ import "./chunk-4VNS5WPM.js";
8
+ export {
9
+ RoutineStore
10
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.38.1",
3
+ "version": "0.40.1",
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",
@@ -12,8 +12,8 @@
12
12
  "pi-package"
13
13
  ],
14
14
  "bin": {
15
- "fn": "./dist/bin.js",
16
- "fusion": "./dist/bin.js"
15
+ "fn": "./bin.mjs",
16
+ "fusion": "./bin.mjs"
17
17
  },
18
18
  "pi": {
19
19
  "extensions": [
@@ -28,6 +28,7 @@
28
28
  "access": "public"
29
29
  },
30
30
  "files": [
31
+ "bin.mjs",
31
32
  "dist/**/*.js",
32
33
  "dist/**/*.d.ts",
33
34
  "dist/**/*.d.ts.map",
@@ -40,17 +41,20 @@
40
41
  "README.md"
41
42
  ],
42
43
  "dependencies": {
43
- "@earendil-works/pi-ai": "^0.77.0",
44
- "@earendil-works/pi-coding-agent": "^0.77.0",
44
+ "@earendil-works/pi-ai": "^0.78.0",
45
+ "@earendil-works/pi-coding-agent": "^0.78.0",
45
46
  "dockerode": "^4.0.12",
46
47
  "express": "^5.1.0",
47
- "ink": "^6.8.0",
48
+ "i18next": "^26.3.1",
49
+ "ink": "^7.0.5",
48
50
  "ink-spinner": "^5.0.0",
49
51
  "ink-text-input": "^6.0.0",
50
52
  "ioredis": "^5.6.0",
51
53
  "multer": "^2.1.1",
52
54
  "node-pty": "npm:@homebridge/node-pty-prebuilt-multiarch@^0.13.1",
53
- "react": "^19.0.0"
55
+ "react": "^19.2.0",
56
+ "react-i18next": "^17.0.8",
57
+ "ws": "^8.18.0"
54
58
  },
55
59
  "peerDependencies": {
56
60
  "@earendil-works/pi-ai": "*",
@@ -70,8 +74,9 @@
70
74
  },
71
75
  "devDependencies": {
72
76
  "@types/node": "^22.0.0",
73
- "@types/react": "^19.0.0",
74
- "@vitest/coverage-v8": "^3.1.0",
77
+ "@types/react": "^19.2.0",
78
+ "@types/ws": "^8.5.0",
79
+ "@vitest/coverage-v8": "^4.1.0",
75
80
  "cross-env": "^7.0.0",
76
81
  "esbuild": "^0.25.12",
77
82
  "ink-testing-library": "^4.0.0",
@@ -79,13 +84,21 @@
79
84
  "tsx": "^4.19.0",
80
85
  "typebox": "^1.0.0",
81
86
  "typescript": "^5.7.0",
82
- "vitest": "^3.1.0",
87
+ "vitest": "^4.1.0",
83
88
  "yaml": "^2.8.3"
84
89
  },
85
90
  "repository": {
86
91
  "type": "git",
87
92
  "url": "https://github.com/Runfusion/Fusion"
88
93
  },
94
+ "exports": {
95
+ "./plugin-sdk": {
96
+ "types": "./dist/plugin-sdk/index.d.ts",
97
+ "import": "./dist/plugin-sdk/index.js"
98
+ },
99
+ "./dist/*": "./dist/*",
100
+ "./package.json": "./package.json"
101
+ },
89
102
  "scripts": {
90
103
  "dev": "tsx src/bin.ts",
91
104
  "prebuild": "node ../../scripts/sync-fusion-skill-tools.mjs",
@@ -94,6 +107,7 @@
94
107
  "build:exe:all": "bun run build.ts --all",
95
108
  "typecheck": "tsc --noEmit",
96
109
  "test": "vitest run --silent=passed-only --reporter=dot",
110
+ "test:ci-shape": "vitest run src/__tests__/ci-workflow.test.ts --silent=passed-only --reporter=dot",
97
111
  "test:slow-cli": "cross-env FUSION_TEST_SLOW_CLI=1 vitest run src/commands/__tests__/agent-export.test.ts --silent=passed-only --reporter=dot",
98
112
  "test:extension-integration": "cross-env FUSION_TEST_EXTENSION_INTEGRATION=1 vitest run src/__tests__/extension-integration.test.ts --silent=passed-only --reporter=dot",
99
113
  "test:build-exe": "cross-env FUSION_TEST_BUILD_EXE=1 vitest run --config vitest.build-exe.config.ts --silent=passed-only --reporter=dot",
@@ -29,7 +29,7 @@ Mission → Milestone → Slice → Feature → Task
29
29
  <!-- BEGIN: tool-categories (auto-generated by scripts/sync-fusion-skill-tools.mjs — do not edit by hand) -->
30
30
  - **Task tools** — `fn_task_create`, `fn_task_update`, `fn_task_list`, `fn_task_show`, `fn_task_attach`, `fn_task_pause`, `fn_task_unpause`, `fn_task_retry`, `fn_task_duplicate`, `fn_task_refine`, `fn_task_archive`, `fn_task_unarchive`, `fn_task_delete`, `fn_task_plan`
31
31
  - **GitHub tools** — `fn_task_import_github`, `fn_task_import_github_issue`, `fn_task_browse_github_issues`
32
- - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_delete`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_slice_activate`, `fn_feature_link_task`, `fn_feature_update`, `fn_milestone_update`
32
+ - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_list_goals`, `fn_mission_link_goal`, `fn_mission_unlink_goal`, `fn_mission_backfill_assertions`, `fn_mission_delete`, `fn_mission_update`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_feature_delete`, `fn_slice_delete`, `fn_milestone_delete`, `fn_slice_activate`, `fn_feature_link_task`, `fn_feature_update`, `fn_milestone_update`
33
33
  - **Goal tools** — `fn_goal_list`, `fn_goal_create`, `fn_goal_archive`, `fn_goal_show`
34
34
  - **Agent tools** — `fn_agent_stop`, `fn_agent_start`, `fn_agent_create`, `fn_agent_delete`, `fn_list_agents`, `fn_delegate_task`, `fn_agent_show`, `fn_agent_org_chart`
35
35
  - **Skills tools** — `fn_skills_search`, `fn_skills_install`
@@ -11,10 +11,27 @@ These tools are **not** part of the user-invokable extension surface. They are i
11
11
 
12
12
  | Tool | Agent Types | Purpose | Parameters |
13
13
  |---|---|---|---|
14
- | `fn_task_create` | triage, executor, heartbeat | Create a follow-up task from within an agent run | `description` (string), `dependencies?` (string[]), `priority?` (`low` \| `normal` \| `high` \| `urgent`) |
14
+ | `fn_task_create` | triage, executor, heartbeat | Create a follow-up task from within an agent run | `description` (string), `dependencies?` (string[]), `priority?` (`low` \| `normal` \| `high` \| `urgent`), `workflow_id?` (string) |
15
15
  | `fn_task_log` | executor, heartbeat | Write significant task log entries | `message` (string), `outcome?` (string) |
16
16
  | `fn_task_document_write` | triage, executor, heartbeat | Save/update a named task document revision | `key` (string), `content` (string), `author?` (string) |
17
17
  | `fn_task_document_read` | triage, executor, heartbeat | Read one task document or list all | `key?` (string) |
18
+ | `fn_goal_list` | triage, executor, heartbeat | List goals with concise citation-ready snippets and active-goal warning details | `status?` (`active` \| `archived` \| `all`) |
19
+ | `fn_goal_show` | triage, executor, heartbeat | Show one goal's full detail on demand, including the full description body | `id` (string) |
20
+ | `fn_workflow_list` | executor | List the project's custom workflows (read-only built-ins plus user definitions) | none |
21
+ | `fn_workflow_get` | executor | Fetch one workflow definition by id — name, description, builtin flag, and the full IR (nodes/edges/columns/artifacts/fields/settings) as JSON | `workflow_id` (string) |
22
+ | `fn_workflow_select` | executor | Assign a custom workflow to a task (defaults to the current task) | `workflow_id` (string), `task_id?` (string) |
23
+ | `fn_workflow_create` | executor | Create a custom workflow definition from a graph IR (validated server-side). v2 IR supports step-inversion constructs: `parse-steps`, `foreach` (mode/isolation/concurrency/maxReworkCycles), `step-execute`, `step-review`, `code` nodes, `rework` edges, plus `artifacts`, custom `fields`, and typed `settings` declarations | `name` (string), `description?` (string), `ir` (object), `layout?` (object) |
24
+ | `fn_workflow_update` | executor | Update a custom workflow definition's name/description/ir/layout (built-ins cannot be edited; same step-inversion IR constructs as create; editing `fields` orphans rather than destroys existing task values; editing `settings` declarations drops orphaned setting values on resolution) | `workflow_id` (string), `name?` (string), `description?` (string), `ir?` (object), `layout?` (object), `rehome_to?` (string) |
25
+ | `fn_workflow_delete` | executor | Delete a custom workflow definition (built-ins cannot be deleted); selecting tasks are re-homed to the default workflow's entry column | `workflow_id` (string) |
26
+ | `fn_workflow_settings` | executor | Read/write a workflow's per-`(workflow, project)` setting **values** (`get` returns `{stored, effective, orphaned}`; `set` writes `values` and returns `{stored, effective, orphaned}`, with `null` clearing an override — including any stored value for an orphaned key). Validated against the named workflow's declared settings; built-in **values** are writable though built-in **declarations** are not; invalid values return a typed rejection list and persist nothing | `action` (`get` \| `set`), `workflow_id` (string), `values?` (object keyed by setting id) |
27
+ | `fn_workflow_list` | executor, chat, planning | List the project's custom workflows (read-only built-ins plus user definitions) | none |
28
+ | `fn_workflow_get` | executor, chat, planning | Fetch one workflow definition by id — name, description, builtin flag, and the full IR (nodes/edges/columns/artifacts/fields) as JSON | `workflow_id` (string) |
29
+ | `fn_workflow_select` | executor, chat, planning | Assign a custom workflow to a task (defaults to the current task) | `workflow_id` (string), `task_id?` (string) |
30
+ | `fn_workflow_create` | executor, chat, planning | Create a custom workflow definition from a graph IR (validated server-side). v2 IR supports step-inversion constructs: `parse-steps`, `foreach` (mode/isolation/concurrency/maxReworkCycles), `step-execute`, `step-review`, `code` nodes, `rework` edges, plus `artifacts` and custom `fields` declarations | `name` (string), `description?` (string), `ir` (object), `layout?` (object) |
31
+ | `fn_workflow_update` | executor, chat, planning | Update a custom workflow definition's name/description/ir/layout (built-ins cannot be edited; same step-inversion IR constructs as create; editing `fields` orphans rather than destroys existing task values) | `workflow_id` (string), `name?` (string), `description?` (string), `ir?` (object), `layout?` (object), `rehome_to?` (string) |
32
+ | `fn_workflow_delete` | executor, chat, planning | Delete a custom workflow definition (built-ins cannot be deleted); selecting tasks are re-homed to the default workflow's entry column | `workflow_id` (string) |
33
+ | `fn_task_promote` | executor | Promote a held task out of a manual-release hold column (defaults to the current task) | `task_id?` (string) |
34
+ | `fn_trait_list` | executor, chat, planning | List the registered column trait catalog (built-in and plugin traits) | none |
18
35
  | `fn_memory_search` | triage, executor, heartbeat | Search project memory plus per-agent layered memory snippets | `query` (string), `limit?` (number) |
19
36
  | `fn_memory_get` | triage, executor, heartbeat | Read a bounded memory file window (including bounded per-agent layered paths) | `path` (string), `startLine?` (number), `lineCount?` (number) |
20
37
  | `fn_memory_append` | executor, heartbeat (when writable backend enabled) | Append memory notes with explicit scope: `scope="agent"` for private operating context, `scope="project"` for workspace-wide durable knowledge | `scope?` (`project` \| `agent`), `layer` (`long-term` \| `daily`), `content` (string) |
@@ -27,7 +44,7 @@ These tools are **not** part of the user-invokable extension surface. They are i
27
44
  | `fn_update_identity` | heartbeat | Update the current agent's own `soul`, `instructionsText`, or `memory` fields | `soul?` (string), `instructionsText?` (string), `memory?` (string) |
28
45
  | `fn_reflect_on_performance` | executor, heartbeat (when reflection service enabled) | Generate reflection insights from prior runs | `focus_area?` (string) |
29
46
  | `fn_list_agents` | triage, executor, heartbeat | List agents (optionally filtered) | `role?` (string), `state?` (string), `includeEphemeral?` (boolean) |
30
- | `fn_delegate_task` | triage, executor, heartbeat | Create and assign a new task to a specific agent | `agent_id` (string), `description` (string), `dependencies?` (string[]), `override?` (boolean) |
47
+ | `fn_delegate_task` | triage, executor, heartbeat | Create and assign a new task to a specific agent | `agent_id` (string), `description` (string), `dependencies?` (string[]), `workflow_id?` (string), `override?` (boolean) |
31
48
  | `fn_get_agent_config` | executor, heartbeat | Read full config for a direct-report agent | `agent_id` (string) |
32
49
  | `fn_update_agent_config` | executor, heartbeat | Update config fields for a direct-report, non-ephemeral agent | `agent_id` (string), optional: `soul`, `instructions_text`, `instructions_path`, `heartbeat_procedure_path`, `heartbeat_interval_ms`, `heartbeat_timeout_ms`, `max_concurrent_runs`, `message_response_mode` |
33
50
  | `fn_agent_create` | executor, heartbeat | Create a non-ephemeral direct-report agent | `name` (string), `role` (string), optional: `soul`, `instructions_text`, `instructions_path`, `reportsTo`, `heartbeat_interval_ms`, `heartbeat_timeout_ms`, `max_concurrent_runs`, `message_response_mode` |
@@ -51,7 +68,7 @@ Note: step-session execution (`step-session-executor.ts`) reuses executor coordi
51
68
 
52
69
  | Tool | Purpose | Parameters |
53
70
  |---|---|---|
54
- | `fn_task_update` | Update a spec step status (`pending`/`in-progress`/`done`/`skipped`) | `step` (number), `status` (enum) |
71
+ | `fn_task_update` | Update a spec step status (`pending`/`in-progress`/`done`/`skipped`), task dependencies, and/or workflow-defined custom field values | `step?` (number, 1-indexed), `status?` (enum), `dependencies?` (string[]), `custom_fields?` (object keyed by field id; validated against the workflow field schema, `null` clears a field) |
55
72
  | `fn_task_add_dep` | Add a dependency to current task (confirmation-gated) | `task_id` (string), `confirm?` (boolean) |
56
73
  | `fn_task_done` | Mark task complete and optionally store summary | `summary?` (string) |
57
74
  | `fn_review_step` | Spawn step plan/code reviewer | `step` (number), `type` (`plan` \| `code`), `step_name` (string), `baseline?` (string) |
@@ -68,3 +85,62 @@ Note: step-session execution (`step-session-executor.ts`) reuses executor coordi
68
85
  | Tool | Purpose | Parameters |
69
86
  |---|---|---|
70
87
  | `fn_heartbeat_done` | Signal end of heartbeat run with optional summary | `summary?` (string) |
88
+
89
+ ## Workflow settings: declarations vs. values
90
+
91
+ Workflow settings split into two surfaces (the same split as custom task fields, one level up):
92
+
93
+ - **Declarations** (the typed schema) live in the workflow IR's `settings` array and are authored with `fn_workflow_create` / `fn_workflow_update`. Built-in workflow declarations cannot be edited (the store's built-in guard rejects the IR edit with a `WorkflowIrError`/built-in error surfaced through the tool result).
94
+ - **Values** (the per-`(workflow, project)` data) are read/written with `fn_workflow_settings`. Built-in workflow **values** are writable so each project can tune `builtin:coding` differently.
95
+
96
+ Declare a setting (custom workflow):
97
+
98
+ ```jsonc
99
+ // fn_workflow_create
100
+ {
101
+ "name": "QA",
102
+ "ir": {
103
+ "version": "v2",
104
+ "name": "QA",
105
+ "columns": [{ "id": "intake", "name": "Intake", "traits": [] }],
106
+ "nodes": [],
107
+ "edges": [],
108
+ "settings": [
109
+ { "id": "reviewHandoffPolicy", "name": "Review handoff", "type": "enum",
110
+ "default": "disabled",
111
+ "options": [
112
+ { "value": "disabled", "label": "Disabled" },
113
+ { "value": "always", "label": "Always" }
114
+ ] }
115
+ ]
116
+ }
117
+ }
118
+ ```
119
+
120
+ Write a value (built-in workflow VALUE — accepted even though built-in declarations are read-only):
121
+
122
+ ```jsonc
123
+ // fn_workflow_settings
124
+ { "action": "set", "workflow_id": "builtin:coding",
125
+ "values": { "workflowStepTimeoutMs": 600000, "reviewHandoffPolicy": "always" } }
126
+ ```
127
+
128
+ An invalid value (e.g. an enum violation) is rejected with a typed list and persists nothing:
129
+
130
+ ```jsonc
131
+ // returns isError:true with details.rejections:
132
+ // [{ "code": "enum-violation", "settingId": "reviewHandoffPolicy", "message": "..." }]
133
+ ```
134
+
135
+ Read values — `effective` is what the engine actually consumes (declaration defaults filled in, orphaned values dropped); `stored` is the raw override map; `orphaned` lists stored entries with no current declaration (or a value that no longer validates). `set` returns the same `{stored, effective, orphaned}` shape:
136
+
137
+ ```jsonc
138
+ // fn_workflow_settings
139
+ { "action": "get", "workflow_id": "builtin:coding" }
140
+ // → { "workflowId": "builtin:coding",
141
+ // "stored": { "workflowStepTimeoutMs": 600000 },
142
+ // "effective": { "workflowStepTimeoutMs": 600000, "reviewHandoffPolicy": "disabled", ... },
143
+ // "orphaned": [] }
144
+ ```
145
+
146
+ Patching a key to `null` clears any stored value for it — including a value left behind under an orphaned key — so `set` doubles as the way to drop orphans. To see the full declaration catalog (every setting id, type, and default) call `fn_workflow_get` on `builtin:coding`, whose IR `settings` array is the canonical catalog.