comisai 1.0.24 → 1.0.26

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 (192) hide show
  1. package/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +130 -10
  2. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.d.ts +1 -1
  3. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +9 -2
  4. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +8 -0
  5. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +2 -0
  6. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +29 -0
  7. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +242 -2
  8. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +210 -0
  9. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +566 -0
  10. package/node_modules/@comis/agent/dist/context-engine/context-engine.js +8 -6
  11. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +51 -30
  12. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +109 -36
  13. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +5 -1
  14. package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +22 -20
  15. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.d.ts +2 -0
  16. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +111 -15
  17. package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +20 -17
  18. package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +132 -52
  19. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +16 -3
  20. package/node_modules/@comis/agent/dist/executor/model-retry.d.ts +14 -0
  21. package/node_modules/@comis/agent/dist/executor/model-retry.js +72 -1
  22. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +3 -0
  23. package/node_modules/@comis/agent/dist/executor/pi-executor.js +68 -9
  24. package/node_modules/@comis/agent/dist/executor/post-batch-continuation.d.ts +82 -0
  25. package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +200 -0
  26. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -9
  27. package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +37 -2
  28. package/node_modules/@comis/agent/dist/executor/tool-deferral.js +45 -3
  29. package/node_modules/@comis/agent/dist/executor/tool-parallelism.js +0 -1
  30. package/node_modules/@comis/agent/dist/executor/types.d.ts +11 -2
  31. package/node_modules/@comis/agent/dist/index.d.ts +3 -1
  32. package/node_modules/@comis/agent/dist/index.js +2 -0
  33. package/node_modules/@comis/agent/dist/model/last-known-model.d.ts +36 -0
  34. package/node_modules/@comis/agent/dist/model/last-known-model.js +49 -0
  35. package/node_modules/@comis/agent/dist/model/model-registry-adapter.d.ts +16 -4
  36. package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +65 -21
  37. package/node_modules/@comis/agent/dist/planner/types.d.ts +0 -2
  38. package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +10 -0
  39. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +5 -0
  40. package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.js +7 -0
  41. package/node_modules/@comis/agent/package.json +1 -1
  42. package/node_modules/@comis/channels/package.json +1 -1
  43. package/node_modules/@comis/cli/dist/client/rpc-client.js +6 -1
  44. package/node_modules/@comis/cli/dist/commands/doctor.js +5 -3
  45. package/node_modules/@comis/cli/dist/commands/health.js +5 -2
  46. package/node_modules/@comis/cli/dist/wizard/json-output.js +7 -3
  47. package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +130 -0
  48. package/node_modules/@comis/cli/package.json +1 -1
  49. package/node_modules/@comis/core/dist/bootstrap.js +5 -0
  50. package/node_modules/@comis/core/dist/config/env-layer.d.ts +31 -0
  51. package/node_modules/@comis/core/dist/config/env-layer.js +41 -0
  52. package/node_modules/@comis/core/dist/config/immutable-keys.d.ts +2 -2
  53. package/node_modules/@comis/core/dist/config/immutable-keys.js +8 -3
  54. package/node_modules/@comis/core/dist/config/layered.d.ts +9 -0
  55. package/node_modules/@comis/core/dist/config/layered.js +11 -0
  56. package/node_modules/@comis/core/dist/config/managed-sections.d.ts +43 -4
  57. package/node_modules/@comis/core/dist/config/managed-sections.js +100 -6
  58. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +39 -0
  59. package/node_modules/@comis/core/dist/config/schema-agent.js +14 -0
  60. package/node_modules/@comis/core/dist/config/schema.d.ts +4 -0
  61. package/node_modules/@comis/core/dist/config/schema.js +14 -0
  62. package/node_modules/@comis/core/dist/domain/execution-graph.d.ts +1 -1
  63. package/node_modules/@comis/core/dist/event-bus/events-agent.d.ts +17 -2
  64. package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
  65. package/node_modules/@comis/core/dist/exports/config.js +1 -1
  66. package/node_modules/@comis/core/package.json +1 -1
  67. package/node_modules/@comis/daemon/dist/daemon.d.ts +22 -0
  68. package/node_modules/@comis/daemon/dist/daemon.js +45 -0
  69. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +5 -2
  70. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +80 -1
  71. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.d.ts +67 -0
  72. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +139 -0
  73. package/node_modules/@comis/daemon/dist/rpc/model-handlers.d.ts +3 -0
  74. package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +29 -5
  75. package/node_modules/@comis/daemon/dist/rpc/probe-provider-auth.d.ts +30 -0
  76. package/node_modules/@comis/daemon/dist/rpc/probe-provider-auth.js +59 -0
  77. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.d.ts +37 -0
  78. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +330 -0
  79. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +18 -1
  80. package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.d.ts +4 -0
  81. package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +30 -0
  82. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +3 -1
  83. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +28 -2
  84. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -0
  85. package/node_modules/@comis/daemon/dist/wiring/setup-tools.js +7 -4
  86. package/node_modules/@comis/daemon/package.json +1 -1
  87. package/node_modules/@comis/gateway/package.json +1 -1
  88. package/node_modules/@comis/infra/dist/index.d.ts +1 -0
  89. package/node_modules/@comis/infra/dist/index.js +2 -0
  90. package/node_modules/@comis/infra/dist/runtime/is-docker.d.ts +1 -0
  91. package/node_modules/@comis/infra/dist/runtime/is-docker.js +25 -0
  92. package/node_modules/@comis/infra/package.json +1 -1
  93. package/node_modules/@comis/memory/package.json +1 -1
  94. package/node_modules/@comis/scheduler/package.json +1 -1
  95. package/node_modules/@comis/shared/package.json +1 -1
  96. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +1 -3
  97. package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.js +24 -1
  98. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +53 -7
  99. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +218 -24
  100. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +4 -1
  101. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +16 -1
  102. package/node_modules/@comis/skills/dist/builtin/platform/index.d.ts +1 -1
  103. package/node_modules/@comis/skills/dist/builtin/platform/index.js +1 -1
  104. package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.d.ts +56 -0
  105. package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.js +203 -0
  106. package/node_modules/@comis/skills/dist/index.d.ts +1 -1
  107. package/node_modules/@comis/skills/dist/index.js +2 -2
  108. package/node_modules/@comis/skills/dist/policy/tool-policy.js +0 -1
  109. package/node_modules/@comis/skills/package.json +1 -1
  110. package/node_modules/@comis/web/dist/assets/{agent-detail-BG9MGWWj.js → agent-detail-DqL6Artv.js} +270 -270
  111. package/node_modules/@comis/web/dist/assets/agent-editor-CNM_h94Y.js +2173 -0
  112. package/node_modules/@comis/web/dist/assets/{agent-list-LHCJ4rw2.js → agent-list-Dbh-xD_F.js} +170 -170
  113. package/node_modules/@comis/web/dist/assets/{approvals-q9VH_IKr.js → approvals-C-K6hN2U.js} +13 -13
  114. package/node_modules/@comis/web/dist/assets/billing-view-C1DmtyzK.js +375 -0
  115. package/node_modules/@comis/web/dist/assets/{channel-detail-CaInesJM.js → channel-detail-CtCH22N1.js} +265 -265
  116. package/node_modules/@comis/web/dist/assets/channel-list-C7xXn-60.js +323 -0
  117. package/node_modules/@comis/web/dist/assets/{chat-console-CNmzl0JW.js → chat-console-C51pjFwk.js} +243 -246
  118. package/node_modules/@comis/web/dist/assets/{config-editor-DX4ITw6y.js → config-editor-BLArYRB7.js} +477 -477
  119. package/node_modules/@comis/web/dist/assets/{context-dag-browser-BwiaF5tf.js → context-dag-browser-fuyMinNI.js} +105 -105
  120. package/node_modules/@comis/web/dist/assets/{context-engine-BZ5Am6hA.js → context-engine-Bngf2bH0.js} +136 -136
  121. package/node_modules/@comis/web/dist/assets/decorate-BvWYovGE.js +38 -0
  122. package/node_modules/@comis/web/dist/assets/{delivery-view-OfBZof-m.js → delivery-view-C80hucxX.js} +134 -134
  123. package/node_modules/@comis/web/dist/assets/{diagnostics-view-YFwCxgr2.js → diagnostics-view-Cl4VbHZ6.js} +82 -82
  124. package/node_modules/@comis/web/dist/assets/directive-BOYXJ-K-.js +1 -0
  125. package/node_modules/@comis/web/dist/assets/{extract-variables-BM5qyK-s.js → extract-variables-B7-Doo7l.js} +39 -39
  126. package/node_modules/@comis/web/dist/assets/{ic-array-editor-B7m6x7-S.js → ic-array-editor-BLoEyeLS.js} +29 -29
  127. package/node_modules/@comis/web/dist/assets/{ic-breadcrumb-CUMpp3BL.js → ic-breadcrumb-DqN6G3gc.js} +16 -16
  128. package/node_modules/@comis/web/dist/assets/{ic-budget-segment-bar-BtJ6x5mN.js → ic-budget-segment-bar-zLsMzjDO.js} +20 -20
  129. package/node_modules/@comis/web/dist/assets/ic-chat-message-ByFUoMm6.js +352 -0
  130. package/node_modules/@comis/web/dist/assets/{ic-confirm-dialog-CCDbB04e.js → ic-confirm-dialog-DGlPbV1T.js} +26 -26
  131. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CnT1b8xr.js → ic-connection-dot-C4nDHgY2.js} +13 -13
  132. package/node_modules/@comis/web/dist/assets/ic-data-table-CKIvr-ag.js +277 -0
  133. package/node_modules/@comis/web/dist/assets/ic-delivery-row-B3YwjjuM.js +67 -0
  134. package/node_modules/@comis/web/dist/assets/{ic-detail-panel-BF83r-if.js → ic-detail-panel-DiCe4hLr.js} +27 -27
  135. package/node_modules/@comis/web/dist/assets/{ic-empty-state-60l2ePhd.js → ic-empty-state-CM3Wbj2f.js} +19 -19
  136. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-ByRjij68.js +359 -0
  137. package/node_modules/@comis/web/dist/assets/ic-icon-BGNCCPpZ.js +33 -0
  138. package/node_modules/@comis/web/dist/assets/{ic-layer-waterfall-COvEYMg5.js → ic-layer-waterfall-WkaFyu-l.js} +18 -18
  139. package/node_modules/@comis/web/dist/assets/ic-relative-time-B3UAnTqg.js +12 -0
  140. package/node_modules/@comis/web/dist/assets/{ic-search-input-CSOxY9g7.js → ic-search-input-B02AGw1i.js} +22 -22
  141. package/node_modules/@comis/web/dist/assets/{ic-select-Ce-Raudx.js → ic-select-BqfZISjw.js} +29 -29
  142. package/node_modules/@comis/web/dist/assets/ic-tabs-yBjkWKJH.js +95 -0
  143. package/node_modules/@comis/web/dist/assets/ic-tag-CvMVQFRR.js +33 -0
  144. package/node_modules/@comis/web/dist/assets/{ic-time-range-picker-CypCT68y.js → ic-time-range-picker-DXbYeBmY.js} +31 -31
  145. package/node_modules/@comis/web/dist/assets/{ic-tool-call-7MaXSsCW.js → ic-tool-call-Bh5kq-yY.js} +51 -51
  146. package/node_modules/@comis/web/dist/assets/index-BBkuC-EU.js +2792 -0
  147. package/node_modules/@comis/web/dist/assets/index-CVEaS9aY.css +2 -0
  148. package/node_modules/@comis/web/dist/assets/{mcp-management-BNZPnpDn.js → mcp-management-DB-phOo7.js} +209 -209
  149. package/node_modules/@comis/web/dist/assets/{media-config-BBvTYxOX.js → media-config-CRqZ1ZUH.js} +154 -154
  150. package/node_modules/@comis/web/dist/assets/{media-test-BkK3RCRK.js → media-test-C9vE20Oy.js} +259 -259
  151. package/node_modules/@comis/web/dist/assets/{memory-inspector-1hDGCGat.js → memory-inspector-CeqfnxMZ.js} +450 -450
  152. package/node_modules/@comis/web/dist/assets/{message-center-CXefwsUu.js → message-center-Daup7Mof.js} +290 -290
  153. package/node_modules/@comis/web/dist/assets/{models-C1qcU_j3.js → models-DLYnEU8E.js} +371 -371
  154. package/node_modules/@comis/web/dist/assets/observability-types-D0tkwElU.js +1 -0
  155. package/node_modules/@comis/web/dist/assets/{observe-view-C0VBhX4C.js → observe-view-BTSt_PO5.js} +399 -399
  156. package/node_modules/@comis/web/dist/assets/pipeline-builder-DknfzyLt.js +1495 -0
  157. package/node_modules/@comis/web/dist/assets/{pipeline-history-DkfOQ6SW.js → pipeline-history-JnHZdeU_.js} +124 -124
  158. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-hyHgD0ai.js → pipeline-history-detail-Dg4knsEb.js} +65 -65
  159. package/node_modules/@comis/web/dist/assets/{pipeline-list-BPW8hV-q.js → pipeline-list-AEnibjsp.js} +227 -227
  160. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-Bip16T7e.js → pipeline-monitor-DG7RbIOO.js} +298 -298
  161. package/node_modules/@comis/web/dist/assets/{scheduler-BGgwKd06.js → scheduler-uL1fYKAT.js} +486 -486
  162. package/node_modules/@comis/web/dist/assets/{security-D15st4xx.js → security-C3DywRLH.js} +389 -389
  163. package/node_modules/@comis/web/dist/assets/{session-detail-SGEYNJ0M.js → session-detail-BtqCNWXV.js} +294 -294
  164. package/node_modules/@comis/web/dist/assets/session-key-parser-Dkqcj2Ss.js +1 -0
  165. package/node_modules/@comis/web/dist/assets/session-list-CJXWa2XT.js +231 -0
  166. package/node_modules/@comis/web/dist/assets/{setup-wizard-nT0tz9QP.js → setup-wizard-ywn7oJvu.js} +486 -494
  167. package/node_modules/@comis/web/dist/assets/{skills-D8yVfSUy.js → skills-DX0KYnWD.js} +329 -329
  168. package/node_modules/@comis/web/dist/assets/{subagents-HHXMeHYo.js → subagents-B8p5YJEB.js} +74 -74
  169. package/node_modules/@comis/web/dist/assets/{workspace-manager-BQlr10iH.js → workspace-manager-CgzNIrw1.js} +236 -236
  170. package/node_modules/@comis/web/dist/index.html +3 -2
  171. package/node_modules/@comis/web/package.json +1 -1
  172. package/package.json +15 -15
  173. package/node_modules/@comis/skills/dist/builtin/platform/agents-list-tool.d.ts +0 -19
  174. package/node_modules/@comis/skills/dist/builtin/platform/agents-list-tool.js +0 -39
  175. package/node_modules/@comis/web/dist/assets/agent-editor-C26Q_xCs.js +0 -2173
  176. package/node_modules/@comis/web/dist/assets/billing-view-CtYvBqTE.js +0 -375
  177. package/node_modules/@comis/web/dist/assets/channel-list-B8dj3O9a.js +0 -323
  178. package/node_modules/@comis/web/dist/assets/directive-DoeGSK_T.js +0 -1
  179. package/node_modules/@comis/web/dist/assets/ic-chat-message-CFyDJd0z.js +0 -352
  180. package/node_modules/@comis/web/dist/assets/ic-data-table-CKUNTxHw.js +0 -277
  181. package/node_modules/@comis/web/dist/assets/ic-delivery-row-GP5Fkygs.js +0 -67
  182. package/node_modules/@comis/web/dist/assets/ic-graph-canvas-C8FuSMe1.js +0 -359
  183. package/node_modules/@comis/web/dist/assets/ic-icon-xeGTVhVG.js +0 -33
  184. package/node_modules/@comis/web/dist/assets/ic-relative-time-3FqpjeAI.js +0 -12
  185. package/node_modules/@comis/web/dist/assets/ic-tabs-B7QtM_v8.js +0 -95
  186. package/node_modules/@comis/web/dist/assets/ic-tag-CPPUnDLF.js +0 -33
  187. package/node_modules/@comis/web/dist/assets/index-CEcM1R_C.js +0 -2830
  188. package/node_modules/@comis/web/dist/assets/index-CIJFuItj.css +0 -1
  189. package/node_modules/@comis/web/dist/assets/observability-types-D7jUtSde.js +0 -1
  190. package/node_modules/@comis/web/dist/assets/pipeline-builder-DcUUIrm0.js +0 -1496
  191. package/node_modules/@comis/web/dist/assets/session-key-parser-DPORMVyU.js +0 -1
  192. package/node_modules/@comis/web/dist/assets/session-list-6ybUTxbY.js +0 -231
@@ -0,0 +1,1495 @@
1
+ import{c as e,f as t,h as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"./decorate-BvWYovGE.js";import{a as u}from"./index-BBkuC-EU.js";import"./ic-breadcrumb-DqN6G3gc.js";import"./ic-confirm-dialog-DGlPbV1T.js";import{a as d,i as f,n as p,o as m,r as h,t as g}from"./ic-graph-canvas-ByRjij68.js";import{n as _,t as v}from"./extract-variables-B7-Doo7l.js";var y=50,b={label:`Untitled Pipeline`,onFailure:`fail-fast`};function x(){let e=[],t=[],n={...b},r=new Set,i=null,a={...h},o=null,s=!1,c=[],l=[],u=new Set;function d(){for(let e of u)e()}function f(){return structuredClone({nodes:e,edges:t,settings:n})}function p(){c.push(f()),c.length>y&&c.shift(),l=[]}function m(r){e=structuredClone(r.nodes),t=structuredClone(r.edges),n=structuredClone(r.settings)}return{subscribe(e){return u.add(e),()=>{u.delete(e)}},getSnapshot(){return Object.freeze({nodes:[...e],edges:[...t],settings:{...n},selectedNodeIds:new Set(r),selectedEdgeId:i,viewport:{...a},validationResult:o,isDirty:s,canUndo:c.length>0,canRedo:l.length>0})},addNode(t){p(),e.push(t),s=!0,d()},updateNode(t,n){p(),e=e.map(e=>e.id===t?{...e,...n,id:e.id}:e),s=!0,d()},removeNode(n){p(),e=e.filter(e=>e.id!==n),t=t.filter(e=>e.source!==n&&e.target!==n),s=!0,d()},addEdge(e,n){p();let r={id:`${e}->${n}`,source:e,target:n};t.push(r),s=!0,d()},removeEdge(e){p(),t=t.filter(t=>t.id!==e),s=!0,d()},updateSettings(e){p(),n={...n,...e},s=!0,d()},moveNodes(t){p();for(let{nodeId:n,position:r}of t)e=e.map(e=>e.id===n?{...e,position:r}:e);s=!0,d()},selectNode(e,t=!1){i=null,t?(r=new Set(r),r.add(e)):r=new Set([e]),d()},selectAll(){r=new Set(e.map(e=>e.id)),d()},clearSelection(){r=new Set,i=null,d()},selectEdge(e){i=e,r=new Set,d()},clearEdgeSelection(){i=null,d()},setViewport(e){a={...e},d()},setValidation(e){o=e,d()},undo(){c.length!==0&&(l.push(f()),m(c.pop()),s=!0,d())},redo(){l.length!==0&&(c.push(f()),m(l.pop()),s=!0,d())},markClean(){s=!1,d()},reset(){e=[],t=[],n={...b},r=new Set,i=null,a={...h},o=null,s=!1,c=[],l=[],d()}}}function S(e,t,n){if(t===n)return!0;let r=new Map;for(let t of e){let e=r.get(t.source);e||(e=[],r.set(t.source,e)),e.push(t.target)}let i=r.get(t);i||(i=[],r.set(t,i)),i.push(n);let a=new Set,o=[n];for(;o.length>0;){let e=o.pop();if(e===t)return!0;if(a.has(e))continue;a.add(e);let n=r.get(e);if(n)for(let e of n)a.has(e)||o.push(e)}return!1}var C=class extends r{constructor(...e){super(...e),this.settings={label:`Untitled Pipeline`,onFailure:`fail-fast`},this.hasErrors=!1,this.isDirty=!1,this.validateResult=``,this._validating=!1}static{this.styles=[o,n`
2
+ :host {
3
+ display: block;
4
+ }
5
+
6
+ .settings-bar {
7
+ display: flex;
8
+ flex-wrap: wrap;
9
+ gap: 8px;
10
+ align-items: center;
11
+ padding: 8px 12px;
12
+ min-height: 48px;
13
+ background: var(--ic-surface);
14
+ border-bottom: 1px solid var(--ic-border);
15
+ }
16
+
17
+ .field {
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 4px;
21
+ }
22
+
23
+ .field label {
24
+ font-size: var(--ic-text-xs);
25
+ color: var(--ic-text-muted);
26
+ white-space: nowrap;
27
+ }
28
+
29
+ .field input,
30
+ .field select {
31
+ background: var(--ic-surface-2);
32
+ border: 1px solid var(--ic-border);
33
+ border-radius: var(--ic-radius-sm);
34
+ padding: 4px 8px;
35
+ color: var(--ic-text);
36
+ font-size: var(--ic-text-sm);
37
+ font-family: inherit;
38
+ }
39
+
40
+ .field input:focus,
41
+ .field select:focus {
42
+ border-color: var(--ic-accent);
43
+ outline: none;
44
+ }
45
+
46
+ .field-label-input {
47
+ width: 160px;
48
+ }
49
+
50
+ .field-number {
51
+ width: 80px;
52
+ }
53
+
54
+ .field-cost {
55
+ width: 90px;
56
+ }
57
+
58
+ .spacer {
59
+ flex: 1;
60
+ }
61
+
62
+ .btn-validate {
63
+ padding: 4px 14px;
64
+ background: var(--ic-accent);
65
+ color: var(--ic-text);
66
+ border: none;
67
+ border-radius: var(--ic-radius-sm);
68
+ font-size: var(--ic-text-sm);
69
+ font-family: inherit;
70
+ cursor: pointer;
71
+ white-space: nowrap;
72
+ }
73
+
74
+ .btn-validate:hover {
75
+ filter: brightness(1.1);
76
+ }
77
+
78
+ .btn-validate:disabled {
79
+ opacity: 0.5;
80
+ cursor: not-allowed;
81
+ }
82
+
83
+ .btn-save {
84
+ padding: 4px 14px;
85
+ background: var(--ic-surface-2);
86
+ color: var(--ic-text-muted);
87
+ border: 1px solid var(--ic-border);
88
+ border-radius: var(--ic-radius-sm);
89
+ font-size: var(--ic-text-sm);
90
+ font-family: inherit;
91
+ cursor: pointer;
92
+ white-space: nowrap;
93
+ }
94
+ .btn-save:hover:not(:disabled) {
95
+ background: var(--ic-accent);
96
+ color: var(--ic-text);
97
+ border-color: var(--ic-accent);
98
+ }
99
+ .btn-save:disabled {
100
+ opacity: 0.5;
101
+ cursor: not-allowed;
102
+ }
103
+
104
+ .btn-run {
105
+ padding: 4px 14px;
106
+ background: #22c55e;
107
+ color: #fff;
108
+ border: none;
109
+ border-radius: var(--ic-radius-sm);
110
+ font-size: var(--ic-text-sm);
111
+ font-family: inherit;
112
+ cursor: pointer;
113
+ white-space: nowrap;
114
+ }
115
+
116
+ .btn-run:hover:not(:disabled) {
117
+ filter: brightness(1.1);
118
+ }
119
+
120
+ .btn-run:disabled {
121
+ opacity: 0.5;
122
+ cursor: not-allowed;
123
+ }
124
+
125
+ .validate-result {
126
+ width: 100%;
127
+ padding: 4px 12px;
128
+ font-size: var(--ic-text-xs);
129
+ color: var(--ic-text-muted);
130
+ }
131
+
132
+ .validate-result.is-error {
133
+ color: var(--ic-error);
134
+ }
135
+ `]}_dispatchSettingsChange(e){this.dispatchEvent(new CustomEvent(`settings-change`,{detail:e,bubbles:!0,composed:!0}))}_onLabelChange(e){let t=e.target.value;this._dispatchSettingsChange({label:t})}_onPolicyChange(e){let t=e.target.value;this._dispatchSettingsChange({onFailure:t})}_onTimeoutChange(e){let t=e.target.value,n=t?parseInt(t,10):void 0;this._dispatchSettingsChange({timeoutMs:n&&n>0?n:void 0})}_onMaxTokensChange(e){let t=e.target.value,n=t?parseInt(t,10):void 0,r=this.settings.budget??{};this._dispatchSettingsChange({budget:{...r,maxTokens:n&&n>0?n:void 0}})}_onMaxCostChange(e){let t=e.target.value,n=t?parseFloat(t):void 0,r=this.settings.budget??{};this._dispatchSettingsChange({budget:{...r,maxCost:n&&n>0?n:void 0}})}_onValidate(){this.dispatchEvent(new CustomEvent(`validate`,{bubbles:!0,composed:!0}))}_onSaveDraft(){this.dispatchEvent(new CustomEvent(`save-draft`,{bubbles:!0,composed:!0}))}_onRun(){this.dispatchEvent(new CustomEvent(`run`,{bubbles:!0,composed:!0}))}render(){let e=this.validateResult.startsWith(`Error:`);return t`
136
+ <div class="settings-bar">
137
+ <div class="field">
138
+ <label>Label:</label>
139
+ <input
140
+ class="field-label-input"
141
+ type="text"
142
+ placeholder="Pipeline label"
143
+ .value=${this.settings.label}
144
+ @input=${this._onLabelChange}
145
+ />
146
+ </div>
147
+ <div class="field">
148
+ <label>Policy:</label>
149
+ <select .value=${this.settings.onFailure} @change=${this._onPolicyChange}>
150
+ <option value="fail-fast" ?selected=${this.settings.onFailure===`fail-fast`}>fail-fast</option>
151
+ <option value="continue" ?selected=${this.settings.onFailure===`continue`}>continue</option>
152
+ </select>
153
+ </div>
154
+ <div class="field">
155
+ <label>Timeout:</label>
156
+ <input
157
+ class="field-number"
158
+ type="number"
159
+ min="0"
160
+ placeholder="ms"
161
+ .value=${this.settings.timeoutMs==null?``:String(this.settings.timeoutMs)}
162
+ @input=${this._onTimeoutChange}
163
+ />
164
+ </div>
165
+ <div class="field">
166
+ <label>Max Tokens:</label>
167
+ <input
168
+ class="field-number"
169
+ type="number"
170
+ min="0"
171
+ placeholder="0"
172
+ .value=${this.settings.budget?.maxTokens==null?``:String(this.settings.budget.maxTokens)}
173
+ @input=${this._onMaxTokensChange}
174
+ />
175
+ </div>
176
+ <div class="field">
177
+ <label>Max Cost:</label>
178
+ <input
179
+ class="field-cost"
180
+ type="number"
181
+ min="0"
182
+ step="0.01"
183
+ placeholder="$0.00"
184
+ .value=${this.settings.budget?.maxCost==null?``:String(this.settings.budget.maxCost)}
185
+ @input=${this._onMaxCostChange}
186
+ />
187
+ </div>
188
+ <div class="spacer"></div>
189
+ <button
190
+ class="btn-validate"
191
+ ?disabled=${this._validating}
192
+ @click=${this._onValidate}
193
+ >
194
+ ${this._validating?`Validating...`:`Validate`}
195
+ </button>
196
+ <button
197
+ class="btn-save"
198
+ ?disabled=${!this.isDirty}
199
+ @click=${this._onSaveDraft}
200
+ >
201
+ Save Draft
202
+ </button>
203
+ <button
204
+ class="btn-run"
205
+ ?disabled=${this.hasErrors}
206
+ title=${this.hasErrors?`Fix validation errors before running`:`Run pipeline`}
207
+ @click=${this._onRun}
208
+ >
209
+ Run
210
+ </button>
211
+ </div>
212
+ ${this.validateResult?t`<div class="validate-result ${e?`is-error`:``}">${this.validateResult}</div>`:l}
213
+ `}};c([s({attribute:!1})],C.prototype,`settings`,void 0),c([s({type:Boolean})],C.prototype,`hasErrors`,void 0),c([s({type:Boolean})],C.prototype,`isDirty`,void 0),c([s()],C.prototype,`validateResult`,void 0),c([a()],C.prototype,`_validating`,void 0),C=c([e(`ic-graph-settings`)],C);var w=class extends r{constructor(...e){super(...e),this.validationResult=null,this._expandErrors=!1,this._expandWarnings=!1}static{this.styles=[o,n`
214
+ :host {
215
+ display: block;
216
+ position: absolute;
217
+ bottom: 0;
218
+ left: 0;
219
+ right: 0;
220
+ z-index: 10;
221
+ pointer-events: auto;
222
+ }
223
+
224
+ .validation-bar {
225
+ background: var(--ic-surface);
226
+ border-top: 1px solid var(--ic-border);
227
+ }
228
+
229
+ .status-row {
230
+ display: flex;
231
+ align-items: center;
232
+ gap: 12px;
233
+ padding: 6px 12px;
234
+ min-height: 32px;
235
+ cursor: default;
236
+ }
237
+
238
+ .status-icon {
239
+ font-size: 14px;
240
+ line-height: 1;
241
+ }
242
+
243
+ .status-icon.valid {
244
+ color: #22c55e;
245
+ }
246
+
247
+ .status-icon.invalid {
248
+ color: var(--ic-error);
249
+ }
250
+
251
+ .badge {
252
+ display: inline-flex;
253
+ align-items: center;
254
+ gap: 4px;
255
+ padding: 2px 8px;
256
+ border-radius: 9999px;
257
+ font-size: var(--ic-text-xs);
258
+ cursor: pointer;
259
+ user-select: none;
260
+ }
261
+
262
+ .badge:hover {
263
+ filter: brightness(1.2);
264
+ }
265
+
266
+ .badge-error {
267
+ background: color-mix(in srgb, var(--ic-error) 15%, transparent);
268
+ color: var(--ic-error);
269
+ }
270
+
271
+ .badge-warning {
272
+ background: color-mix(in srgb, #eab308 15%, transparent);
273
+ color: #eab308;
274
+ }
275
+
276
+ .valid-text {
277
+ font-size: var(--ic-text-xs);
278
+ color: #22c55e;
279
+ }
280
+
281
+ .message-list {
282
+ max-height: 200px;
283
+ overflow-y: auto;
284
+ border-top: 1px solid var(--ic-border);
285
+ }
286
+
287
+ .message-row {
288
+ display: flex;
289
+ align-items: center;
290
+ gap: 8px;
291
+ padding: 4px 12px;
292
+ font-size: var(--ic-text-xs);
293
+ cursor: pointer;
294
+ color: var(--ic-text-muted);
295
+ }
296
+
297
+ .message-row:hover {
298
+ background: var(--ic-surface-2);
299
+ }
300
+
301
+ .message-severity {
302
+ flex-shrink: 0;
303
+ width: 12px;
304
+ text-align: center;
305
+ }
306
+
307
+ .message-severity.error {
308
+ color: var(--ic-error);
309
+ }
310
+
311
+ .message-severity.warning {
312
+ color: #eab308;
313
+ }
314
+
315
+ .message-text {
316
+ flex: 1;
317
+ overflow: hidden;
318
+ text-overflow: ellipsis;
319
+ white-space: nowrap;
320
+ }
321
+
322
+ .message-nodes {
323
+ flex-shrink: 0;
324
+ font-family: var(--ic-font-mono);
325
+ color: var(--ic-text-dim);
326
+ }
327
+ `]}_onMessageClick(e){e.nodeIds&&e.nodeIds.length>0&&this.dispatchEvent(new CustomEvent(`highlight-nodes`,{detail:{nodeIds:e.nodeIds},bubbles:!0,composed:!0}))}render(){if(!this.validationResult)return l;let{valid:e,errors:n,warnings:r}=this.validationResult,i=n.length,a=r.length;return t`
328
+ <div class="validation-bar">
329
+ <div class="status-row">
330
+ ${i>0?t`<span class="status-icon invalid">\u2716</span>`:t`<span class="status-icon valid">\u2714</span>`}
331
+ ${i>0?t`<span
332
+ class="badge badge-error"
333
+ @click=${()=>{this._expandErrors=!this._expandErrors}}
334
+ >${i} error${i===1?``:`s`}</span>`:l}
335
+ ${a>0?t`<span
336
+ class="badge badge-warning"
337
+ @click=${()=>{this._expandWarnings=!this._expandWarnings}}
338
+ >${a} warning${a===1?``:`s`}</span>`:l}
339
+ ${e&&a===0?t`<span class="valid-text">Valid</span>`:l}
340
+ </div>
341
+ ${this._expandErrors&&i>0?this._renderMessageList(n):l}
342
+ ${this._expandWarnings&&a>0?this._renderMessageList(r):l}
343
+ </div>
344
+ `}_renderMessageList(e){return t`
345
+ <div class="message-list">
346
+ ${e.map(e=>t`
347
+ <div class="message-row" @click=${()=>this._onMessageClick(e)}>
348
+ <span class="message-severity ${e.severity}">${e.severity===`error`?`✖`:`⚠`}</span>
349
+ <span class="message-text">${e.message}</span>
350
+ ${e.nodeIds&&e.nodeIds.length>0?t`<span class="message-nodes">${e.nodeIds.join(`, `)}</span>`:l}
351
+ </div>
352
+ `)}
353
+ </div>
354
+ `}};c([s({attribute:!1})],w.prototype,`validationResult`,void 0),c([a()],w.prototype,`_expandErrors`,void 0),c([a()],w.prototype,`_expandWarnings`,void 0),w=c([e(`ic-graph-validation`)],w);function T(e,t){let n=[],r=[];if(e.length===0)return n.push({severity:`error`,message:`Graph must have at least 1 node`}),{valid:!1,errors:n,warnings:r};e.length>20&&n.push({severity:`error`,message:`Graph exceeds maximum of 20 nodes (current: ${e.length})`});let i=new Set,a=new Set;for(let t of e)a.has(t.id)?n.push({severity:`error`,message:`Duplicate node ID "${t.id}"`,nodeIds:[t.id]}):a.add(t.id),i.add(t.id);for(let t of e){(!t.task||t.task.trim().length===0)&&n.push({severity:`error`,message:`Node "${t.id}" has no task defined`,nodeIds:[t.id]});for(let e of t.dependsOn)e===t.id&&n.push({severity:`error`,message:`Node "${t.id}" has a self-dependency`,nodeIds:[t.id]});for(let e of t.dependsOn)e!==t.id&&!i.has(e)&&n.push({severity:`error`,message:`Node "${t.id}" depends on missing node "${e}"`,nodeIds:[t.id]})}let o=new Map,s=new Map;for(let t of e)o.set(t.id,0),s.set(t.id,[]);for(let e of t){let t=s.get(e.source);t&&t.push(e.target),o.set(e.target,(o.get(e.target)??0)+1)}for(let t of e)for(let e of t.dependsOn)if(i.has(e)){let n=s.get(e);n&&!n.includes(t.id)&&(n.push(t.id),o.set(t.id,(o.get(t.id)??0)+1))}let c=[];for(let[e,t]of o)t===0&&c.push(e);let l=0;for(;c.length>0;){let e=c.shift();l++;let t=s.get(e);if(t)for(let e of t){let t=(o.get(e)??1)-1;o.set(e,t),t===0&&c.push(e)}}if(l<i.size){let e=[];for(let[t,n]of o)n>0&&e.push(t);n.push({severity:`error`,message:`Cycle detected involving nodes: ${e.join(`, `)}`,nodeIds:e})}let u=new Set;for(let e of t)u.add(e.source),u.add(e.target);for(let t of e)for(let e of t.dependsOn)i.has(e)&&(u.add(t.id),u.add(e));for(let t of e){if(!t.agentId){let e=t.typeConfig;typeof e?.agent==`string`&&e.agent!==``||Array.isArray(e?.agents)&&e.agents.length>0||Array.isArray(e?.voters)&&e.voters.length>0||Array.isArray(e?.reviewers)&&e.reviewers.length>0||Array.isArray(e?.mappers)&&e.mappers.length>0||r.push({severity:`warning`,message:`Node "${t.id}" has no agent assigned`,nodeIds:[t.id]})}t.barrierMode&&t.dependsOn.length<=1&&r.push({severity:`warning`,message:`Node "${t.id}" has barrier mode "${t.barrierMode}" but only ${t.dependsOn.length} dependency`,nodeIds:[t.id]}),e.length>1&&!u.has(t.id)&&r.push({severity:`warning`,message:`Node "${t.id}" is disconnected from the graph`,nodeIds:[t.id]}),t.typeId&&!t.typeConfig&&n.push({severity:`error`,message:`Node "${t.id}" has typeId "${t.typeId}" but no typeConfig`,nodeIds:[t.id]}),!t.typeId&&t.typeConfig&&n.push({severity:`error`,message:`Node "${t.id}" has typeConfig but no typeId`,nodeIds:[t.id]}),t.typeId&&(t.retries??0)>0&&[`debate`,`vote`,`map-reduce`,`collaborate`].includes(t.typeId)&&r.push({severity:`warning`,message:`Node "${t.id}" has retries on a "${t.typeId}" node -- retrying multi-agent execution is expensive`,nodeIds:[t.id]}),t.typeId===`approval-gate`&&(t.retries??0)>0&&r.push({severity:`warning`,message:`Node "${t.id}" has retries on an approval-gate -- retrying will re-prompt the user`,nodeIds:[t.id]}),t.contextMode&&t.contextMode!==`full`&&t.dependsOn.length===0&&r.push({severity:`warning`,message:`Node "${t.id}" has contextMode "${t.contextMode}" but no dependencies to receive context from`,nodeIds:[t.id]})}return{valid:n.length===0,errors:n,warnings:r}}var E={agent:{label:`Agent`,description:`Run a single sub-agent with explicit driver config`},debate:{label:`Debate`,description:`Multi-round adversarial debate between agents`},vote:{label:`Vote`,description:`Parallel independent voting by multiple agents`},refine:{label:`Refine`,description:`Sequential refinement chain through reviewers`},collaborate:{label:`Collaborate`,description:`Sequential multi-perspective collaboration`},"approval-gate":{label:`Approval Gate`,description:`Human approval checkpoint with timeout`},"map-reduce":{label:`Map-Reduce`,description:`Parallel map tasks then single reduce`}};function D(e){switch(e){case`agent`:return{agent:``,model:``,max_steps:10};case`debate`:return{agents:[],rounds:2,synthesizer:``};case`vote`:return{voters:[],prompt_suffix:``,verdict_format:``,min_voters:0};case`refine`:return{reviewers:[]};case`collaborate`:return{agents:[],rounds:1};case`approval-gate`:return{message:``,timeout_minutes:60};case`map-reduce`:return{mappers:[],reducer:``,reducer_prompt:``};default:return{}}}var O=class extends r{constructor(...e){super(...e),this.node=null,this.allNodes=[],this.allEdges=[],this.rpcClient=null,this._agents=[],this._models=[],this._allowAgents=[],this._agentsLoading=!0,this._modelsLoading=!0,this._showVariables=!1,this._cycleErrors=new Map,this._agentsLoaded=!1,this._modelsLoaded=!1,this._allowListLoaded=!1,this._textareaRef=null}static{this.styles=[o,i,n`
355
+ :host {
356
+ display: block;
357
+ width: 320px;
358
+ border-left: 1px solid var(--ic-border);
359
+ overflow-y: auto;
360
+ background: var(--ic-surface);
361
+ padding: 16px;
362
+ }
363
+
364
+ .section-header {
365
+ font-size: var(--ic-text-sm);
366
+ font-weight: 600;
367
+ color: var(--ic-text);
368
+ margin: 16px 0 8px;
369
+ }
370
+
371
+ .section-header:first-of-type {
372
+ margin-top: 0;
373
+ }
374
+
375
+ h3 {
376
+ margin: 0 0 4px;
377
+ font-size: var(--ic-text-base);
378
+ color: var(--ic-text);
379
+ }
380
+
381
+ .node-id-label {
382
+ font-size: var(--ic-text-xs);
383
+ color: var(--ic-text-muted);
384
+ margin-bottom: 12px;
385
+ }
386
+
387
+ /* Form elements */
388
+ textarea,
389
+ input[type="text"],
390
+ input[type="number"],
391
+ select {
392
+ width: 100%;
393
+ padding: 6px 8px;
394
+ border: 1px solid var(--ic-border);
395
+ border-radius: var(--ic-radius-sm);
396
+ background: var(--ic-bg);
397
+ color: var(--ic-text);
398
+ font-family: var(--ic-font-sans);
399
+ font-size: var(--ic-text-sm);
400
+ }
401
+
402
+ textarea {
403
+ resize: vertical;
404
+ font-family: var(--ic-font-mono);
405
+ line-height: 1.4;
406
+ }
407
+
408
+ textarea:focus,
409
+ input:focus,
410
+ select:focus {
411
+ outline: 2px solid var(--ic-accent);
412
+ outline-offset: -1px;
413
+ border-color: var(--ic-accent);
414
+ }
415
+
416
+ /* Variables toggle */
417
+ .variables-toggle {
418
+ display: inline-flex;
419
+ align-items: center;
420
+ gap: 4px;
421
+ margin-top: 4px;
422
+ padding: 2px 8px;
423
+ border: 1px solid var(--ic-border);
424
+ border-radius: var(--ic-radius-sm);
425
+ background: transparent;
426
+ color: var(--ic-text-muted);
427
+ font-size: var(--ic-text-xs);
428
+ cursor: pointer;
429
+ }
430
+
431
+ .variables-toggle:hover {
432
+ background: var(--ic-surface-2);
433
+ color: var(--ic-text);
434
+ }
435
+
436
+ .variables-list {
437
+ display: flex;
438
+ flex-wrap: wrap;
439
+ gap: 4px;
440
+ margin-top: 6px;
441
+ }
442
+
443
+ .variable-chip {
444
+ display: inline-block;
445
+ padding: 2px 8px;
446
+ border: 1px solid var(--ic-border);
447
+ border-radius: 9999px;
448
+ background: var(--ic-surface-2);
449
+ color: var(--ic-text-muted);
450
+ font-family: var(--ic-font-mono);
451
+ font-size: var(--ic-text-xs);
452
+ cursor: pointer;
453
+ user-select: none;
454
+ }
455
+
456
+ .variable-chip:hover {
457
+ background: color-mix(in srgb, var(--ic-accent) 15%, transparent);
458
+ color: var(--ic-accent);
459
+ border-color: var(--ic-accent);
460
+ }
461
+
462
+ .no-variables {
463
+ font-size: var(--ic-text-xs);
464
+ color: var(--ic-text-dim);
465
+ font-style: italic;
466
+ }
467
+
468
+ /* Agent info */
469
+ .agent-row {
470
+ display: flex;
471
+ align-items: center;
472
+ gap: 8px;
473
+ }
474
+
475
+ .agent-row select {
476
+ flex: 1;
477
+ }
478
+
479
+ .status-dot {
480
+ width: 8px;
481
+ height: 8px;
482
+ border-radius: 50%;
483
+ flex-shrink: 0;
484
+ }
485
+
486
+ .status-dot--active {
487
+ background: var(--ic-success, #22c55e);
488
+ }
489
+
490
+ .status-dot--suspended {
491
+ background: var(--ic-danger, #ef4444);
492
+ }
493
+
494
+ .agent-info {
495
+ font-size: var(--ic-text-xs);
496
+ color: var(--ic-text-muted);
497
+ margin-top: 4px;
498
+ }
499
+
500
+ .allowlist-warning {
501
+ margin-top: 6px;
502
+ padding: 6px 8px;
503
+ border-radius: var(--ic-radius-sm);
504
+ background: color-mix(in srgb, var(--ic-warning, #f59e0b) 10%, transparent);
505
+ border: 1px solid color-mix(in srgb, var(--ic-warning, #f59e0b) 30%, transparent);
506
+ color: var(--ic-warning, #f59e0b);
507
+ font-size: var(--ic-text-xs);
508
+ }
509
+
510
+ /* Dependency checkboxes */
511
+ .dep-list {
512
+ display: flex;
513
+ flex-direction: column;
514
+ gap: 4px;
515
+ }
516
+
517
+ .dep-item {
518
+ display: flex;
519
+ align-items: center;
520
+ gap: 6px;
521
+ font-size: var(--ic-text-sm);
522
+ color: var(--ic-text);
523
+ }
524
+
525
+ .dep-item input[type="checkbox"] {
526
+ width: auto;
527
+ margin: 0;
528
+ cursor: pointer;
529
+ }
530
+
531
+ .dep-task-preview {
532
+ color: var(--ic-text-muted);
533
+ font-size: var(--ic-text-xs);
534
+ overflow: hidden;
535
+ text-overflow: ellipsis;
536
+ white-space: nowrap;
537
+ max-width: 150px;
538
+ }
539
+
540
+ .cycle-error {
541
+ color: var(--ic-danger, #ef4444);
542
+ font-size: var(--ic-text-xs);
543
+ margin-left: 4px;
544
+ }
545
+
546
+ /* Constraint fields */
547
+ .constraint-row {
548
+ margin-bottom: 8px;
549
+ }
550
+
551
+ .constraint-label {
552
+ font-size: var(--ic-text-xs);
553
+ color: var(--ic-text-muted);
554
+ margin-bottom: 2px;
555
+ }
556
+
557
+ .constraint-help {
558
+ font-size: var(--ic-text-xs);
559
+ color: var(--ic-text-dim);
560
+ margin-top: 2px;
561
+ }
562
+
563
+ /* Actions */
564
+ .actions {
565
+ display: flex;
566
+ gap: 8px;
567
+ margin-top: 16px;
568
+ }
569
+
570
+ .btn {
571
+ flex: 1;
572
+ padding: 6px 12px;
573
+ border: 1px solid var(--ic-border);
574
+ border-radius: var(--ic-radius-sm);
575
+ font-size: var(--ic-text-sm);
576
+ cursor: pointer;
577
+ text-align: center;
578
+ }
579
+
580
+ .btn-accent {
581
+ background: color-mix(in srgb, var(--ic-accent) 10%, transparent);
582
+ color: var(--ic-accent);
583
+ border-color: color-mix(in srgb, var(--ic-accent) 30%, transparent);
584
+ }
585
+
586
+ .btn-accent:hover {
587
+ background: color-mix(in srgb, var(--ic-accent) 20%, transparent);
588
+ }
589
+
590
+ .btn-danger {
591
+ background: color-mix(in srgb, var(--ic-danger, #ef4444) 10%, transparent);
592
+ color: var(--ic-danger, #ef4444);
593
+ border-color: color-mix(in srgb, var(--ic-danger, #ef4444) 30%, transparent);
594
+ }
595
+
596
+ .btn-danger:hover {
597
+ background: color-mix(in srgb, var(--ic-danger, #ef4444) 20%, transparent);
598
+ }
599
+
600
+ /* Loading state */
601
+ .loading {
602
+ font-size: var(--ic-text-xs);
603
+ color: var(--ic-text-dim);
604
+ font-style: italic;
605
+ }
606
+
607
+ .empty-state {
608
+ padding: 32px 16px;
609
+ text-align: center;
610
+ color: var(--ic-text-muted);
611
+ font-size: var(--ic-text-sm);
612
+ }
613
+
614
+ /* Node type system */
615
+ .type-select {
616
+ width: 100%;
617
+ padding: 6px 8px;
618
+ background: var(--ic-input-bg);
619
+ color: var(--ic-text);
620
+ border: 1px solid var(--ic-border);
621
+ border-radius: 4px;
622
+ font-size: var(--ic-text-sm);
623
+ margin-bottom: 8px;
624
+ }
625
+
626
+ .type-description {
627
+ font-size: var(--ic-text-xs);
628
+ color: var(--ic-text-secondary);
629
+ margin-bottom: 12px;
630
+ }
631
+
632
+ .type-agent-list {
633
+ display: flex;
634
+ flex-direction: column;
635
+ gap: 4px;
636
+ margin-bottom: 8px;
637
+ }
638
+
639
+ .type-agent-row {
640
+ display: flex;
641
+ gap: 4px;
642
+ align-items: center;
643
+ }
644
+
645
+ .type-agent-row select {
646
+ flex: 1;
647
+ }
648
+
649
+ .type-remove-btn {
650
+ background: none;
651
+ border: 1px solid var(--ic-border);
652
+ color: var(--ic-text-secondary);
653
+ border-radius: 4px;
654
+ padding: 4px 8px;
655
+ cursor: pointer;
656
+ font-size: var(--ic-text-xs);
657
+ }
658
+
659
+ .type-remove-btn:hover {
660
+ border-color: var(--ic-error);
661
+ color: var(--ic-error);
662
+ }
663
+
664
+ .type-add-btn {
665
+ background: none;
666
+ border: 1px dashed var(--ic-border);
667
+ color: var(--ic-text-secondary);
668
+ border-radius: 4px;
669
+ padding: 6px;
670
+ cursor: pointer;
671
+ font-size: var(--ic-text-xs);
672
+ width: 100%;
673
+ text-align: center;
674
+ }
675
+
676
+ .type-add-btn:hover {
677
+ border-color: var(--ic-accent);
678
+ color: var(--ic-accent);
679
+ }
680
+
681
+ .type-mapper-row {
682
+ display: flex;
683
+ flex-direction: column;
684
+ gap: 4px;
685
+ padding: 8px;
686
+ border: 1px solid var(--ic-border);
687
+ border-radius: 4px;
688
+ margin-bottom: 4px;
689
+ }
690
+
691
+ .type-mapper-header {
692
+ display: flex;
693
+ justify-content: space-between;
694
+ align-items: center;
695
+ }
696
+ `]}connectedCallback(){super.connectedCallback(),this._loadAgents(),this._loadModels(),this._loadAllowList()}updated(e){e.has(`rpcClient`)&&this.rpcClient&&(this._agentsLoaded||this._loadAgents(),this._modelsLoaded||this._loadModels(),this._allowListLoaded||this._loadAllowList())}async _loadAgents(){if(this._agentsLoaded||!this.rpcClient){this._agentsLoading=!1;return}try{let e=(await this.rpcClient.call(`agents.list`)).agents??[],t=await Promise.allSettled(e.map(e=>this.rpcClient.call(`agents.get`,{agentId:e})));this._agents=t.filter(e=>e.status===`fulfilled`).map(e=>({id:e.value.agentId,model:e.value.config?.model??`unknown`,provider:e.value.config?.provider??`unknown`,suspended:e.value.suspended===!0})).sort((e,t)=>e.id.localeCompare(t.id)),this._agentsLoaded=!0}catch{this._agents=[]}finally{this._agentsLoading=!1}}async _loadModels(){if(this._modelsLoaded||!this.rpcClient){this._modelsLoading=!1;return}try{let e=await this.rpcClient.call(`models.list`,{});this._models=(e.providers??[]).flatMap(e=>(e.models??[]).map(t=>({provider:e.name,modelId:typeof t==`string`?t:t.modelId}))),this._modelsLoaded=!0}catch{this._models=[]}finally{this._modelsLoading=!1}}async _loadAllowList(){if(!(this._allowListLoaded||!this.rpcClient))try{let e=await this.rpcClient.call(`config.read`,{section:`security`});this._allowAgents=e?.agentToAgent?.allowAgents??[],this._allowListLoaded=!0}catch{this._allowAgents=[],this._allowListLoaded=!0}}render(){if(!this.node)return t`<div class="empty-state">Select a node to edit</div>`;let e=this.node,n=this._getDependencies(e).length;return t`
697
+ ${this._renderHeader(e)}
698
+ ${this._renderTask(e)}
699
+ ${e.typeId?l:this._renderAgent(e)}
700
+ ${this._renderDependencies(e)}
701
+ ${this._renderConstraints(e,n)}
702
+ ${this._renderRetries(e)}
703
+ ${this._renderContextMode(e)}
704
+ ${this._renderNodeType(e)}
705
+ ${this._renderModelOverride(e)}
706
+ ${this._renderActions(e)}
707
+ `}_renderHeader(e){return t`
708
+ <h3>${e.id}</h3>
709
+ <div class="node-id-label">Node ID: ${e.id}</div>
710
+ `}_renderTask(e){let n=this._getDependencies(e);return t`
711
+ <div class="section-header">Task</div>
712
+ <textarea
713
+ rows="4"
714
+ .value=${e.task}
715
+ @input=${t=>{let n=t.target;this._textareaRef=n,this._dispatchNodeUpdate(e.id,{task:n.value})}}
716
+ placeholder="Describe the task for this node..."
717
+ ></textarea>
718
+ <button
719
+ class="variables-toggle"
720
+ @click=${()=>{this._showVariables=!this._showVariables}}
721
+ >
722
+ ${this._showVariables?`▼`:`▶`} Variables
723
+ </button>
724
+ ${this._showVariables?this._renderVariablesList(n):l}
725
+ `}_renderVariablesList(e){return e.length===0?t`<div class="no-variables">No dependencies -- add dependencies to use variables</div>`:t`
726
+ <div class="variables-list">
727
+ ${e.map(e=>t`
728
+ <span
729
+ class="variable-chip"
730
+ @click=${()=>this._insertVariable(`{{${e.source}.result}}`)}
731
+ >{{${e.source}.result}}</span>
732
+ `)}
733
+ </div>
734
+ `}_insertVariable(e){let t=this._textareaRef??this.renderRoot.querySelector(`textarea`);if(!t)return;let n=t.selectionStart,r=t.selectionEnd,i=t.value,a=i.substring(0,n)+e+i.substring(r);t.value=a,t.selectionStart=t.selectionEnd=n+e.length,t.focus(),this.node&&this._dispatchNodeUpdate(this.node.id,{task:a})}_renderAgent(e){let n=this._agents.find(t=>t.id===e.agentId),r=this._allowAgents.length>0&&e.agentId!=null&&e.agentId!==``&&!this._allowAgents.includes(e.agentId);return t`
735
+ <div class="section-header">Agent</div>
736
+ ${this._agentsLoading?t`<div class="loading">Loading agents...</div>`:t`
737
+ <div class="agent-row">
738
+ <select
739
+ .value=${e.agentId??``}
740
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{agentId:n||void 0})}}
741
+ >
742
+ <option value="">-- No agent (uses default) --</option>
743
+ ${this._agents.map(n=>t`
744
+ <option value=${n.id} ?selected=${n.id===e.agentId}>
745
+ ${n.id}${n.suspended?` (suspended)`:``}
746
+ </option>
747
+ `)}
748
+ </select>
749
+ ${n?t`<span
750
+ class="status-dot ${n.suspended?`status-dot--suspended`:`status-dot--active`}"
751
+ title=${n.suspended?`Suspended`:`Active`}
752
+ ></span>`:l}
753
+ </div>
754
+ ${n?t`<div class="agent-info">${n.model} (${n.provider})</div>`:l}
755
+ ${r?t`<div class="allowlist-warning">This agent is not in the security allowlist and may be restricted</div>`:l}
756
+ `}
757
+ `}_renderDependencies(e){let n=this.allNodes.filter(t=>t.id!==e.id).slice().sort((e,t)=>{let n=e.position.y-t.position.y;return n===0?e.position.x-t.position.x:n});return n.length===0?t`
758
+ <div class="section-header">Dependencies</div>
759
+ <div class="loading">No other nodes in graph</div>
760
+ `:t`
761
+ <div class="section-header">Dependencies</div>
762
+ <div class="dep-list">
763
+ ${n.map(n=>{let r=this.allEdges.some(t=>t.source===n.id&&t.target===e.id),i=this._cycleErrors.get(n.id)??!1;return t`
764
+ <label class="dep-item">
765
+ <input
766
+ type="checkbox"
767
+ .checked=${r}
768
+ @change=${t=>{let r=t.target.checked;this._handleDependencyChange(e.id,n.id,r)}}
769
+ />
770
+ <span>${n.id}</span>
771
+ <span class="dep-task-preview">${this._truncate(n.task,30)}</span>
772
+ ${i?t`<span class="cycle-error">Would create cycle</span>`:l}
773
+ </label>
774
+ `})}
775
+ </div>
776
+ `}_handleDependencyChange(e,t,n){if(n){if(S(this.allEdges,t,e)){let e=new Map(this._cycleErrors);e.set(t,!0),this._cycleErrors=e,setTimeout(()=>{let e=new Map(this._cycleErrors);e.delete(t),this._cycleErrors=e},2e3);return}this.dispatchEvent(new CustomEvent(`edge-add`,{detail:{source:t,target:e},bubbles:!0,composed:!0}))}else this.dispatchEvent(new CustomEvent(`edge-remove`,{detail:{source:t,target:e},bubbles:!0,composed:!0}))}_renderConstraints(e,n){return t`
777
+ <div class="section-header">Constraints</div>
778
+
779
+ ${n>=2?t`
780
+ <div class="constraint-row">
781
+ <div class="constraint-label">Barrier Mode</div>
782
+ <select
783
+ .value=${e.barrierMode??`all`}
784
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{barrierMode:n})}}
785
+ >
786
+ <option value="all">all</option>
787
+ <option value="majority">majority</option>
788
+ <option value="best-effort">best-effort</option>
789
+ </select>
790
+ <div class="constraint-help">
791
+ ${{all:`Wait for all dependencies to complete`,majority:`Proceed when >50% of dependencies complete`,"best-effort":`Proceed when any dependency completes`}[e.barrierMode??`all`]}
792
+ </div>
793
+ </div>
794
+ `:l}
795
+
796
+ <div class="constraint-row">
797
+ <div class="constraint-label">Timeout (ms)</div>
798
+ <input
799
+ type="number"
800
+ min="0"
801
+ step="1000"
802
+ placeholder="Default"
803
+ .value=${e.timeoutMs==null?``:String(e.timeoutMs)}
804
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{timeoutMs:n?Number(n):void 0})}}
805
+ />
806
+ </div>
807
+
808
+ <div class="constraint-row">
809
+ <div class="constraint-label">Max Steps</div>
810
+ <input
811
+ type="number"
812
+ min="1"
813
+ max="50"
814
+ placeholder="Default"
815
+ .value=${e.maxSteps==null?``:String(e.maxSteps)}
816
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{maxSteps:n?Number(n):void 0})}}
817
+ />
818
+ </div>
819
+ `}_renderRetries(e){return t`
820
+ <div class="constraint-row">
821
+ <div class="constraint-label">Retries</div>
822
+ <input
823
+ type="number"
824
+ min="0"
825
+ max="3"
826
+ step="1"
827
+ placeholder="0"
828
+ .value=${e.retries==null?``:String(e.retries)}
829
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{retries:n?Number(n):void 0})}}
830
+ />
831
+ <div class="constraint-help">Automatic retry with exponential backoff (0-3)</div>
832
+ </div>
833
+ `}_renderContextMode(e){return t`
834
+ <div class="constraint-row">
835
+ <div class="constraint-label">Context Mode</div>
836
+ <select
837
+ .value=${e.contextMode??`full`}
838
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{contextMode:n===`full`?void 0:n})}}
839
+ >
840
+ <option value="full">full (complete upstream outputs)</option>
841
+ <option value="summary">summary (truncated + shared dir ref)</option>
842
+ <option value="none">none (inline templates only)</option>
843
+ </select>
844
+ </div>
845
+ `}_renderNodeType(e){return t`
846
+ <div class="section-header">Node Type</div>
847
+ <select
848
+ class="type-select"
849
+ .value=${e.typeId??``}
850
+ @change=${t=>{let n=t.target.value;n===``?this._dispatchNodeUpdate(e.id,{typeId:void 0,typeConfig:void 0}):this._dispatchNodeUpdate(e.id,{typeId:n,typeConfig:D(n)})}}
851
+ >
852
+ <option value="">Standard (no type driver)</option>
853
+ ${Object.entries(E).map(([n,r])=>t`
854
+ <option value=${n} ?selected=${e.typeId===n}>${r.label}</option>
855
+ `)}
856
+ </select>
857
+ ${e.typeId&&E[e.typeId]?t`<div class="type-description">${E[e.typeId].description}</div>`:l}
858
+ ${e.typeId?this._renderTypeConfigForm(e):l}
859
+ `}_renderTypeConfigForm(e){let t=e.typeConfig??{};switch(e.typeId){case`agent`:return this._renderAgentTypeConfig(e,t);case`debate`:return this._renderDebateTypeConfig(e,t);case`vote`:return this._renderVoteTypeConfig(e,t);case`refine`:return this._renderRefineTypeConfig(e,t);case`collaborate`:return this._renderCollaborateTypeConfig(e,t);case`approval-gate`:return this._renderApprovalGateTypeConfig(e,t);case`map-reduce`:return this._renderMapReduceTypeConfig(e,t);default:return l}}_renderAgentTypeConfig(e,n){return t`
860
+ <div class="constraint-row">
861
+ <div class="constraint-label">Agent</div>
862
+ <select
863
+ .value=${String(n.agent??``)}
864
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agent:r||void 0}})}}
865
+ >
866
+ <option value="">-- Select agent --</option>
867
+ ${this._agents.map(e=>t`
868
+ <option value=${e.id} ?selected=${e.id===n.agent}>${e.id}${e.suspended?` (suspended)`:``}</option>
869
+ `)}
870
+ </select>
871
+ </div>
872
+ <div class="constraint-row">
873
+ <div class="constraint-label">Model</div>
874
+ <select
875
+ .value=${String(n.model??``)}
876
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,model:r||void 0}})}}
877
+ >
878
+ <option value="">-- Default --</option>
879
+ ${this._models.map(e=>t`
880
+ <option value=${e.modelId} ?selected=${e.modelId===n.model}>${e.modelId}</option>
881
+ `)}
882
+ </select>
883
+ </div>
884
+ <div class="constraint-row">
885
+ <div class="constraint-label">Max Steps</div>
886
+ <input type="number" min="1" max="50" placeholder="10"
887
+ .value=${n.max_steps==null?``:String(n.max_steps)}
888
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,max_steps:r?Number(r):void 0}})}}
889
+ />
890
+ </div>
891
+ `}_renderDebateTypeConfig(e,n){let r=Array.isArray(n.agents)?n.agents:[];return t`
892
+ <div class="constraint-label">Debate Agents (min 2)</div>
893
+ <div class="type-agent-list">
894
+ ${r.map((i,a)=>t`
895
+ <div class="type-agent-row">
896
+ <select .value=${i} @change=${t=>{let i=t.target.value,o=[...r];o[a]=i,this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agents:o}})}}>
897
+ <option value="">-- Select agent --</option>
898
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===i}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
899
+ </select>
900
+ <button class="type-remove-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agents:r.filter((e,t)=>t!==a)}})}}>Remove</button>
901
+ </div>
902
+ `)}
903
+ <button class="type-add-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agents:[...r,``]}})}}>+ Add agent</button>
904
+ </div>
905
+ <div class="constraint-row">
906
+ <div class="constraint-label">Rounds</div>
907
+ <input type="number" min="1" max="5" placeholder="2"
908
+ .value=${n.rounds==null?``:String(n.rounds)}
909
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,rounds:r?Number(r):void 0}})}}
910
+ />
911
+ </div>
912
+ <div class="constraint-row">
913
+ <div class="constraint-label">Synthesizer</div>
914
+ <select .value=${String(n.synthesizer??``)} @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,synthesizer:r||void 0}})}}>
915
+ <option value="">-- None --</option>
916
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===n.synthesizer}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
917
+ </select>
918
+ </div>
919
+ `}_renderVoteTypeConfig(e,n){let r=Array.isArray(n.voters)?n.voters:[];return t`
920
+ <div class="constraint-label">Voters (min 2)</div>
921
+ <div class="type-agent-list">
922
+ ${r.map((i,a)=>t`
923
+ <div class="type-agent-row">
924
+ <select .value=${i} @change=${t=>{let i=t.target.value,o=[...r];o[a]=i,this._dispatchNodeUpdate(e.id,{typeConfig:{...n,voters:o}})}}>
925
+ <option value="">-- Select agent --</option>
926
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===i}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
927
+ </select>
928
+ <button class="type-remove-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,voters:r.filter((e,t)=>t!==a)}})}}>Remove</button>
929
+ </div>
930
+ `)}
931
+ <button class="type-add-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,voters:[...r,``]}})}}>+ Add voter</button>
932
+ </div>
933
+ <div class="constraint-row">
934
+ <div class="constraint-label">Verdict Format</div>
935
+ <input type="text" placeholder="YES or NO with justification"
936
+ .value=${String(n.verdict_format??``)}
937
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,verdict_format:r||void 0}})}}
938
+ />
939
+ </div>
940
+ <div class="constraint-row">
941
+ <div class="constraint-label">Prompt Suffix</div>
942
+ <textarea rows="2" placeholder="Additional instructions for voters..."
943
+ .value=${String(n.prompt_suffix??``)}
944
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,prompt_suffix:r||void 0}})}}
945
+ ></textarea>
946
+ </div>
947
+ <div class="constraint-row">
948
+ <div class="constraint-label">Min Voters</div>
949
+ <input type="number" min="0" max="20" placeholder="0 (all)"
950
+ .value=${n.min_voters==null?``:String(n.min_voters)}
951
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,min_voters:r?Number(r):void 0}})}}
952
+ />
953
+ </div>
954
+ `}_renderRefineTypeConfig(e,n){let r=Array.isArray(n.reviewers)?n.reviewers:[];return t`
955
+ <div class="constraint-label">Reviewers (min 2, sequential order)</div>
956
+ <div class="type-agent-list">
957
+ ${r.map((i,a)=>t`
958
+ <div class="type-agent-row">
959
+ <select .value=${i} @change=${t=>{let i=t.target.value,o=[...r];o[a]=i,this._dispatchNodeUpdate(e.id,{typeConfig:{...n,reviewers:o}})}}>
960
+ <option value="">-- Select agent --</option>
961
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===i}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
962
+ </select>
963
+ <button class="type-remove-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,reviewers:r.filter((e,t)=>t!==a)}})}}>Remove</button>
964
+ </div>
965
+ `)}
966
+ <button class="type-add-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,reviewers:[...r,``]}})}}>+ Add reviewer</button>
967
+ </div>
968
+ `}_renderCollaborateTypeConfig(e,n){let r=Array.isArray(n.agents)?n.agents:[];return t`
969
+ <div class="constraint-label">Collaborators (min 2)</div>
970
+ <div class="type-agent-list">
971
+ ${r.map((i,a)=>t`
972
+ <div class="type-agent-row">
973
+ <select .value=${i} @change=${t=>{let i=t.target.value,o=[...r];o[a]=i,this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agents:o}})}}>
974
+ <option value="">-- Select agent --</option>
975
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===i}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
976
+ </select>
977
+ <button class="type-remove-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agents:r.filter((e,t)=>t!==a)}})}}>Remove</button>
978
+ </div>
979
+ `)}
980
+ <button class="type-add-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,agents:[...r,``]}})}}>+ Add collaborator</button>
981
+ </div>
982
+ <div class="constraint-row">
983
+ <div class="constraint-label">Rounds</div>
984
+ <input type="number" min="1" max="3" placeholder="1"
985
+ .value=${n.rounds==null?``:String(n.rounds)}
986
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,rounds:r?Number(r):void 0}})}}
987
+ />
988
+ </div>
989
+ `}_renderApprovalGateTypeConfig(e,n){return t`
990
+ <div class="constraint-row">
991
+ <div class="constraint-label">Message</div>
992
+ <textarea rows="2" placeholder="Approval request message..."
993
+ .value=${String(n.message??``)}
994
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,message:r||void 0}})}}
995
+ ></textarea>
996
+ </div>
997
+ <div class="constraint-row">
998
+ <div class="constraint-label">Timeout (min)</div>
999
+ <input type="number" min="1" max="1440" placeholder="60"
1000
+ .value=${n.timeout_minutes==null?``:String(n.timeout_minutes)}
1001
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,timeout_minutes:r?Number(r):void 0}})}}
1002
+ />
1003
+ </div>
1004
+ `}_renderMapReduceTypeConfig(e,n){let r=Array.isArray(n.mappers)?n.mappers:[];return t`
1005
+ <div class="constraint-label">Mappers (min 2)</div>
1006
+ <div class="type-agent-list">
1007
+ ${r.map((i,a)=>t`
1008
+ <div class="type-mapper-row">
1009
+ <div class="type-mapper-header">
1010
+ <span class="constraint-label">Mapper ${a+1}</span>
1011
+ <button class="type-remove-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,mappers:r.filter((e,t)=>t!==a)}})}}>Remove</button>
1012
+ </div>
1013
+ <select .value=${i.agent??``} @change=${t=>{let o=t.target.value,s=[...r];s[a]={...i,agent:o},this._dispatchNodeUpdate(e.id,{typeConfig:{...n,mappers:s}})}}>
1014
+ <option value="">-- Select agent --</option>
1015
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===i.agent}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
1016
+ </select>
1017
+ <input type="text" placeholder="Task suffix (optional)"
1018
+ .value=${i.task_suffix??``}
1019
+ @change=${t=>{let o=t.target.value,s=[...r];s[a]={...i,task_suffix:o||void 0},this._dispatchNodeUpdate(e.id,{typeConfig:{...n,mappers:s}})}}
1020
+ />
1021
+ </div>
1022
+ `)}
1023
+ <button class="type-add-btn" @click=${()=>{this._dispatchNodeUpdate(e.id,{typeConfig:{...n,mappers:[...r,{agent:``}]}})}}>+ Add mapper</button>
1024
+ </div>
1025
+ <div class="constraint-row">
1026
+ <div class="constraint-label">Reducer Agent</div>
1027
+ <select .value=${String(n.reducer??``)} @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,reducer:r||void 0}})}}>
1028
+ <option value="">-- Select agent --</option>
1029
+ ${this._agents.map(e=>t`<option value=${e.id} ?selected=${e.id===n.reducer}>${e.id}${e.suspended?` (suspended)`:``}</option>`)}
1030
+ </select>
1031
+ </div>
1032
+ <div class="constraint-row">
1033
+ <div class="constraint-label">Reducer Prompt</div>
1034
+ <textarea rows="2" placeholder="Instructions for the reducer..."
1035
+ .value=${String(n.reducer_prompt??``)}
1036
+ @change=${t=>{let r=t.target.value;this._dispatchNodeUpdate(e.id,{typeConfig:{...n,reducer_prompt:r||void 0}})}}
1037
+ ></textarea>
1038
+ </div>
1039
+ `}_renderModelOverride(e){let n=new Map;for(let e of this._models){let t=n.get(e.provider);t||(t=[],n.set(e.provider,t)),t.push(e.modelId)}return t`
1040
+ <div class="section-header">Model Override</div>
1041
+ ${this._modelsLoading?t`<div class="loading">Loading models...</div>`:t`
1042
+ <select
1043
+ .value=${e.modelId??``}
1044
+ @change=${t=>{let n=t.target.value;this._dispatchNodeUpdate(e.id,{modelId:n||void 0})}}
1045
+ >
1046
+ <option value="">-- Use agent default --</option>
1047
+ ${[...n.entries()].map(([n,r])=>t`
1048
+ <optgroup label=${n}>
1049
+ ${r.map(n=>t`
1050
+ <option
1051
+ value=${n}
1052
+ ?selected=${n===e.modelId}
1053
+ >
1054
+ ${n}
1055
+ </option>
1056
+ `)}
1057
+ </optgroup>
1058
+ `)}
1059
+ </select>
1060
+ `}
1061
+ `}_renderActions(e){return t`
1062
+ <div class="actions">
1063
+ <button
1064
+ class="btn btn-accent"
1065
+ @click=${()=>{this.dispatchEvent(new CustomEvent(`node-duplicate`,{detail:{nodeId:e.id},bubbles:!0,composed:!0}))}}
1066
+ >
1067
+ Duplicate
1068
+ </button>
1069
+ <button
1070
+ class="btn btn-danger"
1071
+ @click=${()=>{this.dispatchEvent(new CustomEvent(`node-delete`,{detail:{nodeId:e.id},bubbles:!0,composed:!0}))}}
1072
+ >
1073
+ Delete
1074
+ </button>
1075
+ </div>
1076
+ `}_getDependencies(e){return this.allEdges.filter(t=>t.target===e.id)}_dispatchNodeUpdate(e,t){this.dispatchEvent(new CustomEvent(`node-update`,{detail:{nodeId:e,partial:t},bubbles:!0,composed:!0}))}_truncate(e,t){return e.length>t?e.slice(0,t-1)+`…`:e}};c([s({attribute:!1})],O.prototype,`node`,void 0),c([s({attribute:!1})],O.prototype,`allNodes`,void 0),c([s({attribute:!1})],O.prototype,`allEdges`,void 0),c([s({attribute:!1})],O.prototype,`rpcClient`,void 0),c([a()],O.prototype,`_agents`,void 0),c([a()],O.prototype,`_models`,void 0),c([a()],O.prototype,`_allowAgents`,void 0),c([a()],O.prototype,`_agentsLoading`,void 0),c([a()],O.prototype,`_modelsLoading`,void 0),c([a()],O.prototype,`_showVariables`,void 0),c([a()],O.prototype,`_cycleErrors`,void 0),O=c([e(`ic-node-editor`)],O);function k(){return{nodes:[{id:`step-1`,task:`Research the latest developments in renewable energy technology. Focus on solar, wind, and battery storage advances from the past year.`,dependsOn:[],position:{x:300,y:50}},{id:`step-2`,task:`Analyze the research findings and identify the top 3 most promising technologies.
1077
+
1078
+ Research data:
1079
+ {{step-1.result}}`,dependsOn:[`step-1`],position:{x:300,y:220}},{id:`step-3`,task:`Write a concise executive summary based on the analysis.
1080
+
1081
+ Analysis:
1082
+ {{step-2.result}}`,dependsOn:[`step-2`],position:{x:300,y:390}}],edges:[{id:`step-1->step-2`,source:`step-1`,target:`step-2`},{id:`step-2->step-3`,source:`step-2`,target:`step-3`}],settings:{label:`Linear Chain`}}}function A(){return{nodes:[{id:`start`,task:`Define the key aspects to investigate about the given topic. List 2 focus areas, one per line.`,dependsOn:[],position:{x:300,y:50}},{id:`worker-1`,task:`Investigate the first focus area from the plan. Provide detailed findings.
1083
+
1084
+ Plan:
1085
+ {{start.result}}`,dependsOn:[`start`],position:{x:180,y:220}},{id:`worker-2`,task:`Investigate the second focus area from the plan. Provide detailed findings.
1086
+
1087
+ Plan:
1088
+ {{start.result}}`,dependsOn:[`start`],position:{x:420,y:220}},{id:`merge`,task:`Synthesize both sets of findings into a unified report.
1089
+
1090
+ Findings 1:
1091
+ {{worker-1.result}}
1092
+
1093
+ Findings 2:
1094
+ {{worker-2.result}}`,dependsOn:[`worker-1`,`worker-2`],position:{x:300,y:390}}],edges:[{id:`start->worker-1`,source:`start`,target:`worker-1`},{id:`start->worker-2`,source:`start`,target:`worker-2`},{id:`worker-1->merge`,source:`worker-1`,target:`merge`},{id:`worker-2->merge`,source:`worker-2`,target:`merge`}],settings:{label:`Fan-out Fan-in`}}}function j(){return{nodes:[{id:`track-a1`,task:`Gather quantitative data and statistics on the topic.`,dependsOn:[],position:{x:200,y:50}},{id:`track-a2`,task:`Create charts and visualizations from the quantitative data.
1095
+
1096
+ Data:
1097
+ {{track-a1.result}}`,dependsOn:[`track-a1`],position:{x:200,y:220}},{id:`track-b1`,task:`Collect qualitative insights and expert opinions on the topic.`,dependsOn:[],position:{x:450,y:50}},{id:`track-b2`,task:`Summarize the qualitative insights into key themes.
1098
+
1099
+ Insights:
1100
+ {{track-b1.result}}`,dependsOn:[`track-b1`],position:{x:450,y:220}}],edges:[{id:`track-a1->track-a2`,source:`track-a1`,target:`track-a2`},{id:`track-b1->track-b2`,source:`track-b1`,target:`track-b2`}],settings:{label:`Parallel Tracks`}}}function M(){return{nodes:[{id:`worker-1`,task:`Monitor social media channels for brand mentions and sentiment.`,dependsOn:[],position:{x:150,y:100}},{id:`worker-2`,task:`Check system health dashboards and report any anomalies.`,dependsOn:[],position:{x:350,y:100}},{id:`worker-3`,task:`Review and categorize incoming support tickets by priority.`,dependsOn:[],position:{x:550,y:100}}],edges:[],settings:{label:`Independent Workers`}}}function N(){return{nodes:[{id:`top`,task:`Break down the project requirements into technical and business categories.`,dependsOn:[],position:{x:300,y:50}},{id:`left`,task:`Evaluate the technical requirements and estimate implementation effort.
1101
+
1102
+ Requirements:
1103
+ {{top.result}}`,dependsOn:[`top`],position:{x:180,y:220}},{id:`right`,task:`Assess the business requirements and estimate business value.
1104
+
1105
+ Requirements:
1106
+ {{top.result}}`,dependsOn:[`top`],position:{x:420,y:220}},{id:`bottom`,task:`Create a prioritized roadmap combining technical effort and business value.
1107
+
1108
+ Technical evaluation:
1109
+ {{left.result}}
1110
+
1111
+ Business evaluation:
1112
+ {{right.result}}`,dependsOn:[`left`,`right`],position:{x:300,y:390}}],edges:[{id:`top->left`,source:`top`,target:`left`},{id:`top->right`,source:`top`,target:`right`},{id:`left->bottom`,source:`left`,target:`bottom`},{id:`right->bottom`,source:`right`,target:`bottom`}],settings:{label:`Diamond`}}}function P(){return{nodes:[{id:`research`,task:`Research the given topic and prepare a comprehensive briefing document with key facts, statistics, and relevant context.`,dependsOn:[],position:{x:300,y:50}},{id:`debate`,task:`Debate the implications and best course of action based on the research.
1113
+
1114
+ Research briefing:
1115
+ {{research.result}}`,dependsOn:[`research`],typeId:`debate`,typeConfig:{agents:[],rounds:2},position:{x:300,y:220}},{id:`conclusion`,task:`Based on the debate transcript, write a balanced conclusion with actionable recommendations.
1116
+
1117
+ Debate outcome:
1118
+ {{debate.result}}`,dependsOn:[`debate`],position:{x:300,y:390}}],edges:[{id:`research->debate`,source:`research`,target:`debate`},{id:`debate->conclusion`,source:`debate`,target:`conclusion`}],settings:{label:`Debate Pipeline`}}}function F(){return{nodes:[{id:`research`,task:`Research the given topic thoroughly and prepare a comprehensive briefing with key facts and arguments for and against.`,dependsOn:[],position:{x:300,y:50}},{id:`vote`,task:`Based on the research, vote on the best course of action.
1119
+
1120
+ Research briefing:
1121
+ {{research.result}}`,dependsOn:[`research`],typeId:`vote`,typeConfig:{voters:[],verdict_format:`YES or NO with one-line justification`},position:{x:300,y:220}},{id:`summarize`,task:`Summarize the voting results and recommend next steps based on the majority decision.
1122
+
1123
+ Vote results:
1124
+ {{vote.result}}`,dependsOn:[`vote`],position:{x:300,y:390}}],edges:[{id:`research->vote`,source:`research`,target:`vote`},{id:`vote->summarize`,source:`vote`,target:`summarize`}],settings:{label:`Vote Pipeline`}}}function I(){return{nodes:[{id:`draft`,task:`Write a first draft addressing the given topic. Include all key points but don't worry about polish.`,dependsOn:[],position:{x:300,y:50}},{id:`refine`,task:`Review and refine the draft. Each reviewer improves upon the previous version.
1125
+
1126
+ Draft:
1127
+ {{draft.result}}`,dependsOn:[`draft`],typeId:`refine`,typeConfig:{reviewers:[]},position:{x:300,y:220}},{id:`publish`,task:`Format the refined document for publication. Add headers, sections, and a summary.
1128
+
1129
+ Refined content:
1130
+ {{refine.result}}`,dependsOn:[`refine`],position:{x:300,y:390}}],edges:[{id:`draft->refine`,source:`draft`,target:`refine`},{id:`refine->publish`,source:`refine`,target:`publish`}],settings:{label:`Refine Chain`}}}function L(){return{nodes:[{id:`plan`,task:`Break the topic into distinct sub-topics that can be researched independently. List each sub-topic clearly.`,dependsOn:[],position:{x:300,y:50}},{id:`analyze`,task:`Each mapper researches their assigned sub-topic in depth.
1131
+
1132
+ Sub-topics:
1133
+ {{plan.result}}`,dependsOn:[`plan`],typeId:`map-reduce`,typeConfig:{mappers:[],reducer:``,reducer_prompt:`Synthesize all mapper outputs into a comprehensive report with sections for each sub-topic.`},position:{x:300,y:220}},{id:`report`,task:`Format the synthesized analysis into a polished final report with executive summary.
1134
+
1135
+ Analysis:
1136
+ {{analyze.result}}`,dependsOn:[`analyze`],position:{x:300,y:390}}],edges:[{id:`plan->analyze`,source:`plan`,target:`analyze`},{id:`analyze->report`,source:`analyze`,target:`report`}],settings:{label:`Map-Reduce Pipeline`}}}function R(){return{nodes:[{id:`prepare`,task:`Analyze the request and prepare a detailed action plan. Include cost estimates and risk assessment.`,dependsOn:[],position:{x:300,y:50}},{id:`approve`,task:`Review the action plan and approve or deny execution.
1137
+
1138
+ Action plan:
1139
+ {{prepare.result}}`,dependsOn:[`prepare`],typeId:`approval-gate`,typeConfig:{message:`Please review the action plan and reply APPROVE or DENY.`,timeout_minutes:60},position:{x:300,y:220}},{id:`execute`,task:`Execute the approved action plan.
1140
+
1141
+ Approved plan:
1142
+ {{prepare.result}}
1143
+
1144
+ Approval:
1145
+ {{approve.result}}`,dependsOn:[`approve`],position:{x:300,y:390}}],edges:[{id:`prepare->approve`,source:`prepare`,target:`approve`},{id:`approve->execute`,source:`approve`,target:`execute`}],settings:{label:`Approval Gate Pipeline`}}}function z(){return{nodes:[],edges:[],settings:{label:`Untitled Pipeline`}}}var B=[{id:`linear-chain`,name:`Linear Chain`,description:`Sequential pipeline: each step depends on the previous one.`,nodeCount:`3 nodes`,icon:`↓`,create:k},{id:`fan-out-fan-in`,name:`Fan-out Fan-in`,description:`Parallel workers with a single merge point.`,nodeCount:`4 nodes`,icon:`↔`,create:A},{id:`parallel-tracks`,name:`Parallel Tracks`,description:`Two independent streams running side by side.`,nodeCount:`4 nodes`,icon:`≡`,create:j},{id:`independent-workers`,name:`Independent Workers`,description:`Unconnected nodes that run in parallel with no dependencies.`,nodeCount:`3 nodes`,icon:`☰`,create:M},{id:`diamond`,name:`Diamond`,description:`Fork into two paths, then converge at the end.`,nodeCount:`4 nodes`,icon:`◈`,create:N},{id:`debate`,name:`Debate Pipeline`,description:`Research, multi-agent debate, then synthesize conclusions.`,nodeCount:`3 nodes`,icon:`⚔`,create:P},{id:`vote-pipeline`,name:`Vote Pipeline`,description:`Research a topic, have multiple agents vote, then summarize results.`,nodeCount:`3 nodes`,icon:`✔`,create:F},{id:`refine-chain`,name:`Refine Chain`,description:`Draft content, refine through sequential reviewers, then publish.`,nodeCount:`3 nodes`,icon:`✎`,create:I},{id:`map-reduce`,name:`Map-Reduce`,description:`Split work across parallel mappers, then reduce into a single output.`,nodeCount:`3 nodes`,icon:`⇄`,create:L},{id:`approval-gate`,name:`Approval Gate`,description:`Prepare an action, wait for human approval, then execute.`,nodeCount:`3 nodes`,icon:`☑`,create:R},{id:`blank`,name:`Blank Canvas`,description:`Start from scratch with an empty graph.`,nodeCount:`0 nodes`,icon:`➕`,create:z}],V=class extends r{constructor(...e){super(...e),this.open=!1,this._showJsonImport=!1,this._jsonError=``,this._jsonText=``,this._onKeyDown=e=>{if(e.key===`Escape`){e.preventDefault(),this._fireCancel();return}if(e.key===`Tab`){let t=this.shadowRoot?.querySelectorAll(`button:not([disabled]), textarea`);if(!t||t.length===0)return;let n=t[0],r=t[t.length-1],i=this.shadowRoot?.activeElement;e.shiftKey&&i===n?(e.preventDefault(),r.focus()):!e.shiftKey&&i===r&&(e.preventDefault(),n.focus())}}}static{this.styles=[o,i,n`
1146
+ :host {
1147
+ display: contents;
1148
+ }
1149
+
1150
+ .backdrop {
1151
+ position: fixed;
1152
+ inset: 0;
1153
+ background: rgba(0, 0, 0, 0.6);
1154
+ z-index: 9999;
1155
+ display: flex;
1156
+ align-items: center;
1157
+ justify-content: center;
1158
+ }
1159
+
1160
+ .dialog {
1161
+ max-width: 40rem;
1162
+ width: calc(100% - var(--ic-space-lg) * 2);
1163
+ max-height: calc(100vh - var(--ic-space-lg) * 2);
1164
+ overflow-y: auto;
1165
+ background: var(--ic-surface);
1166
+ border: 1px solid var(--ic-border);
1167
+ border-radius: var(--ic-radius-lg);
1168
+ padding: var(--ic-space-lg);
1169
+ box-shadow: var(--ic-shadow-lg);
1170
+ }
1171
+
1172
+ .header {
1173
+ display: flex;
1174
+ justify-content: space-between;
1175
+ align-items: center;
1176
+ margin-bottom: var(--ic-space-md);
1177
+ }
1178
+
1179
+ .title {
1180
+ font-size: var(--ic-text-lg);
1181
+ font-weight: 600;
1182
+ color: var(--ic-text);
1183
+ margin: 0;
1184
+ }
1185
+
1186
+ .toggle-link {
1187
+ background: none;
1188
+ border: none;
1189
+ color: var(--ic-accent);
1190
+ font-size: var(--ic-text-sm);
1191
+ cursor: pointer;
1192
+ padding: 0;
1193
+ font-family: inherit;
1194
+ text-decoration: underline;
1195
+ }
1196
+
1197
+ .toggle-link:hover {
1198
+ color: var(--ic-accent-hover);
1199
+ }
1200
+
1201
+ /* Template grid */
1202
+
1203
+ .template-grid {
1204
+ display: grid;
1205
+ grid-template-columns: 1fr 1fr;
1206
+ gap: var(--ic-space-md);
1207
+ margin-bottom: var(--ic-space-lg);
1208
+ }
1209
+
1210
+ @media (max-width: 480px) {
1211
+ .template-grid {
1212
+ grid-template-columns: 1fr;
1213
+ }
1214
+ }
1215
+
1216
+ .template-card {
1217
+ border: 1px solid var(--ic-border);
1218
+ border-radius: var(--ic-radius-md);
1219
+ padding: var(--ic-space-md);
1220
+ cursor: pointer;
1221
+ transition:
1222
+ border-color var(--ic-transition),
1223
+ background var(--ic-transition);
1224
+ text-align: center;
1225
+ background: transparent;
1226
+ color: inherit;
1227
+ font-family: inherit;
1228
+ width: 100%;
1229
+ }
1230
+
1231
+ .template-card:hover {
1232
+ border-color: var(--ic-accent);
1233
+ background: var(--ic-surface-2, rgba(255, 255, 255, 0.03));
1234
+ }
1235
+
1236
+ .card-icon {
1237
+ font-size: 2rem;
1238
+ line-height: 1;
1239
+ margin-bottom: var(--ic-space-xs);
1240
+ }
1241
+
1242
+ .card-name {
1243
+ font-size: var(--ic-text-sm);
1244
+ font-weight: 600;
1245
+ color: var(--ic-text);
1246
+ margin-bottom: var(--ic-space-xs);
1247
+ }
1248
+
1249
+ .card-desc {
1250
+ font-size: var(--ic-text-xs);
1251
+ color: var(--ic-text-muted);
1252
+ line-height: 1.4;
1253
+ margin-bottom: var(--ic-space-xs);
1254
+ }
1255
+
1256
+ .card-meta {
1257
+ font-size: var(--ic-text-xs);
1258
+ color: var(--ic-text-dim, var(--ic-text-muted));
1259
+ }
1260
+
1261
+ /* JSON import */
1262
+
1263
+ .json-section {
1264
+ margin-bottom: var(--ic-space-lg);
1265
+ }
1266
+
1267
+ .json-textarea {
1268
+ width: 100%;
1269
+ min-height: 12rem;
1270
+ padding: var(--ic-space-sm);
1271
+ background: var(--ic-surface-2, var(--ic-surface));
1272
+ color: var(--ic-text);
1273
+ border: 1px solid var(--ic-border);
1274
+ border-radius: var(--ic-radius-md);
1275
+ font-family: monospace;
1276
+ font-size: var(--ic-text-sm);
1277
+ resize: vertical;
1278
+ }
1279
+
1280
+ .json-textarea::placeholder {
1281
+ color: var(--ic-text-muted);
1282
+ }
1283
+
1284
+ .json-error {
1285
+ color: var(--ic-error);
1286
+ font-size: var(--ic-text-xs);
1287
+ margin-top: var(--ic-space-xs);
1288
+ }
1289
+
1290
+ .import-btn {
1291
+ margin-top: var(--ic-space-sm);
1292
+ padding: var(--ic-space-sm) var(--ic-space-md);
1293
+ background: var(--ic-accent);
1294
+ border: 1px solid var(--ic-accent);
1295
+ border-radius: var(--ic-radius-md);
1296
+ color: #fff;
1297
+ font-size: var(--ic-text-sm);
1298
+ font-family: inherit;
1299
+ cursor: pointer;
1300
+ transition: background var(--ic-transition);
1301
+ }
1302
+
1303
+ .import-btn:hover {
1304
+ background: var(--ic-accent-hover);
1305
+ }
1306
+
1307
+ /* Footer */
1308
+
1309
+ .footer {
1310
+ display: flex;
1311
+ justify-content: flex-end;
1312
+ }
1313
+
1314
+ .cancel-btn {
1315
+ padding: var(--ic-space-sm) var(--ic-space-md);
1316
+ border-radius: var(--ic-radius-md);
1317
+ font-size: var(--ic-text-sm);
1318
+ font-family: inherit;
1319
+ cursor: pointer;
1320
+ background: transparent;
1321
+ border: 1px solid var(--ic-border);
1322
+ color: var(--ic-text-muted);
1323
+ transition:
1324
+ background var(--ic-transition),
1325
+ border-color var(--ic-transition);
1326
+ }
1327
+
1328
+ .cancel-btn:hover {
1329
+ border-color: var(--ic-text-dim, var(--ic-text-muted));
1330
+ color: var(--ic-text);
1331
+ }
1332
+ `]}updated(e){e.has(`open`)&&this.open&&(this._showJsonImport=!1,this._jsonError=``,this._jsonText=``,this.updateComplete.then(()=>{(this.shadowRoot?.querySelector(`button.template-card, button.cancel-btn`))?.focus()}))}_onBackdropClick(e){e.target.classList.contains(`backdrop`)&&this._fireCancel()}_onTemplateClick(e){let{nodes:t,edges:n,settings:r}=e.create();this.dispatchEvent(new CustomEvent(`template-select`,{detail:{nodes:t,edges:n,settings:r},bubbles:!0,composed:!0})),this._fireCancel()}_onToggleJsonImport(){this._showJsonImport=!this._showJsonImport,this._jsonError=``}_onJsonInput(e){this._jsonText=e.target.value,this._jsonError=``}_onJsonImport(){let e=this._jsonText.trim();if(!e){this._jsonError=`Please paste JSON content.`;return}let t;try{t=JSON.parse(e)}catch{this._jsonError=`Invalid JSON. Please check your syntax.`;return}let n=t.nodes;if(!Array.isArray(n)||n.length===0){this._jsonError=`JSON must contain a "nodes" array with at least one node.`;return}for(let e=0;e<n.length;e++){let t=n[e];if(!t||typeof t!=`object`){this._jsonError=`Node at index ${e} is not a valid object.`;return}let r=t.nodeId??t.id;if(typeof r!=`string`||!r){this._jsonError=`Node at index ${e} is missing "nodeId" or "id" (string).`;return}if(typeof t.task!=`string`||!t.task){this._jsonError=`Node at index ${e} is missing "task" (string).`;return}}let{nodes:r,edges:i}=U(n),a={label:typeof t.label==`string`&&t.label?t.label:`Imported Pipeline`,onFailure:t.onFailure===`continue`?`continue`:`fail-fast`};typeof t.timeoutMs==`number`&&(a.timeoutMs=t.timeoutMs),this.dispatchEvent(new CustomEvent(`template-select`,{detail:{nodes:r,edges:i,settings:a},bubbles:!0,composed:!0})),this._fireCancel()}_fireCancel(){this.dispatchEvent(new CustomEvent(`cancel`))}render(){return this.open?t`
1333
+ <div
1334
+ class="backdrop"
1335
+ @click=${this._onBackdropClick}
1336
+ @keydown=${this._onKeyDown}
1337
+ >
1338
+ <div
1339
+ class="dialog"
1340
+ role="dialog"
1341
+ aria-modal="true"
1342
+ aria-labelledby="picker-title"
1343
+ >
1344
+ <div class="header">
1345
+ <h2 class="title" id="picker-title">Choose a Template</h2>
1346
+ <button
1347
+ class="toggle-link"
1348
+ @click=${this._onToggleJsonImport}
1349
+ >
1350
+ ${this._showJsonImport?`Back to templates`:`Or import JSON`}
1351
+ </button>
1352
+ </div>
1353
+
1354
+ ${this._showJsonImport?this._renderJsonImport():this._renderTemplateGrid()}
1355
+
1356
+ <div class="footer">
1357
+ <button class="cancel-btn" @click=${this._fireCancel}>
1358
+ Cancel
1359
+ </button>
1360
+ </div>
1361
+ </div>
1362
+ </div>
1363
+ `:l}_renderTemplateGrid(){return t`
1364
+ <div class="template-grid">
1365
+ ${B.map(e=>t`
1366
+ <button
1367
+ class="template-card"
1368
+ @click=${()=>this._onTemplateClick(e)}
1369
+ >
1370
+ <div class="card-icon">${e.icon}</div>
1371
+ <div class="card-name">${e.name}</div>
1372
+ <div class="card-desc">${e.description}</div>
1373
+ <div class="card-meta">${e.nodeCount}</div>
1374
+ </button>
1375
+ `)}
1376
+ </div>
1377
+ `}_renderJsonImport(){return t`
1378
+ <div class="json-section">
1379
+ <textarea
1380
+ class="json-textarea"
1381
+ rows="12"
1382
+ placeholder="Paste ExecutionGraph JSON..."
1383
+ .value=${this._jsonText}
1384
+ @input=${this._onJsonInput}
1385
+ ></textarea>
1386
+ ${this._jsonError?t`<div class="json-error">${this._jsonError}</div>`:l}
1387
+ <button class="import-btn" @click=${this._onJsonImport}>
1388
+ Import
1389
+ </button>
1390
+ </div>
1391
+ `}};c([s({type:Boolean,reflect:!0})],V.prototype,`open`,void 0),c([a()],V.prototype,`_showJsonImport`,void 0),c([a()],V.prototype,`_jsonError`,void 0),c([a()],V.prototype,`_jsonText`,void 0),V=c([e(`ic-template-picker`)],V);var H=170;function U(e){let t=[],n=[];for(let r=0;r<e.length;r++){let i=e[r],a=(i.nodeId??i.id).trim(),o=i.task.trim(),s=Array.isArray(i.dependsOn)?i.dependsOn.filter(e=>typeof e==`string`):[],c={id:a,task:o,dependsOn:s,position:{x:300,y:50+r*H},...typeof i.agentId==`string`&&i.agentId?{agentId:i.agentId}:{},...typeof i.maxSteps==`number`?{maxSteps:i.maxSteps}:{},...typeof i.timeoutMs==`number`?{timeoutMs:i.timeoutMs}:{},...i.barrierMode===`all`||i.barrierMode===`majority`||i.barrierMode===`best-effort`?{barrierMode:i.barrierMode}:{},...typeof i.model==`string`&&i.model?{modelId:i.model}:typeof i.modelId==`string`&&i.modelId?{modelId:i.modelId}:{},...typeof i.retries==`number`&&i.retries>=0&&i.retries<=3?{retries:i.retries}:{},...i.contextMode===`full`||i.contextMode===`summary`||i.contextMode===`none`?{contextMode:i.contextMode}:i.context_mode===`full`||i.context_mode===`summary`||i.context_mode===`none`?{contextMode:i.context_mode}:{},typeId:i.typeId,typeConfig:i.typeConfig&&typeof i.typeConfig==`object`?i.typeConfig:void 0};t.push(c);for(let e of s)n.push({id:`${e}->${a}`,source:e,target:a})}return{nodes:t,edges:n}}var W=24,G=class extends r{constructor(...e){super(...e),this.rpcClient=null,this.graphId=``,this._graphState=null,this._stateUnsub=null,this._rpcStatusUnsub=null,this._serverLoadDone=!1,this._nodeCounter=0,this._viewport={x:0,y:0,scale:1},this._nodes=[],this._edges=[],this._selectedNodeIds=new Set,this._selectedEdgeId=null,this._showDeleteConfirm=!1,this._deleteMessage=``,this._snapToGrid=!1,this._validationResult=null,this._settings={label:`Untitled Pipeline`,onFailure:`fail-fast`},this._highlightNodeIds=[],this._validateResultText=``,this._showTemplatePicker=!1,this._showVariablePrompt=!1,this._variableNames=[],this._draftId=``,this._isDirty=!1,this._pendingDeleteNodeIds=[],this._pendingDeleteEdgeId=null,this._validationTimer=null,this._beforeUnloadHandler=e=>{this._isDirty&&e.preventDefault()},this._hashChangeHandler=()=>{this._isDirty&&this._builderHash&&(window.confirm(`You have unsaved changes. Leave anyway?`)||(window.location.hash=this._builderHash))},this._builderHash=``,this._onKeyDown=e=>{let t=e.composedPath()[0];if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement||t instanceof Element&&t.closest(`[contenteditable]`))return;let n=e.metaKey||e.ctrlKey;if(n&&e.shiftKey&&e.key===`z`){e.preventDefault(),this._graphState?.redo();return}if(n&&!e.shiftKey&&e.key===`z`){e.preventDefault(),this._graphState?.undo();return}if(n&&e.key===`a`){e.preventDefault(),this._graphState?.selectAll();return}if(n&&e.key===`d`){e.preventDefault(),this._duplicateSelected();return}if(!n){if(e.key===`Backspace`||e.key===`Delete`){e.preventDefault(),this._deleteSelected();return}if(e.key===`Escape`){this._graphState?.clearSelection(),this.renderRoot.querySelector(`ic-graph-canvas`)?.cancelInteraction();return}if(e.key===`n`||e.key===`N`){this._addNodeAtViewportCenter();return}if(e.key===`f`||e.key===`F`){this._fitView();return}if(e.key===`l`||e.key===`L`){this._autoLayout();return}if(e.key===`+`||e.key===`=`){this._zoomStep(1);return}if(e.key===`-`){this._zoomStep(-1);return}if(e.key===`0`){this._graphState?.setViewport({x:0,y:0,scale:1});return}if(e.key===`Tab`){e.preventDefault(),this._cycleNodeSelection(e.shiftKey?-1:1);return}if(e.key===`ArrowUp`||e.key===`ArrowDown`||e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault(),this._nudgeSelected(e.key);return}}}}static{this.styles=[o,i,n`
1392
+ :host { display: block; height: 100%; }
1393
+ .builder-container { display: flex; flex-direction: column; height: calc(100vh - 120px); }
1394
+ .toolbar { display: flex; gap: 4px; padding: 4px 0; }
1395
+ .toolbar-btn { padding: 4px 12px; background: var(--ic-surface-2); border: 1px solid var(--ic-border);
1396
+ border-radius: var(--ic-radius-sm); color: var(--ic-text-muted); font-size: var(--ic-text-xs); cursor: pointer; }
1397
+ .toolbar-btn:hover { background: var(--ic-accent); color: var(--ic-text); }
1398
+ .toolbar-btn--active { background: var(--ic-accent); color: var(--ic-text); border-color: var(--ic-accent); }
1399
+ .builder-body { display: flex; flex: 1; overflow: hidden; }
1400
+ .canvas-area { flex: 1; position: relative; border: 1px solid var(--ic-border); border-radius: var(--ic-radius-md);
1401
+ background: var(--ic-bg); overflow: hidden; }
1402
+ .mobile-message { display: none; text-align: center; padding: 3rem 1.5rem; color: var(--ic-text-muted); }
1403
+ .mobile-message h2 { font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem; }
1404
+ .mobile-message p { font-size: var(--ic-text-sm); color: var(--ic-text-dim); }
1405
+ @media (max-width: 767px) {
1406
+ .builder-container { display: none; }
1407
+ .mobile-message { display: block; }
1408
+ }
1409
+ `]}connectedCallback(){super.connectedCallback(),this._graphState=x(),this._stateUnsub=this._graphState.subscribe(()=>{let e=this._graphState.getSnapshot();this._viewport=e.viewport,this._nodes=e.nodes,this._edges=e.edges,this._selectedNodeIds=e.selectedNodeIds,this._selectedEdgeId=e.selectedEdgeId,this._settings=e.settings,this._isDirty=e.isDirty,this._validationTimer&&clearTimeout(this._validationTimer),this._validationTimer=setTimeout(()=>{let e=T(this._nodes,this._edges);this._graphState?.setValidation(e),this._validationResult=e},150)});let e=this._graphState.getSnapshot();this._viewport=e.viewport,this._nodes=e.nodes,this._edges=e.edges,this._selectedNodeIds=e.selectedNodeIds,this._selectedEdgeId=e.selectedEdgeId,this._settings=e.settings,document.addEventListener(`keydown`,this._onKeyDown),window.addEventListener(`beforeunload`,this._beforeUnloadHandler),this._builderHash=window.location.hash,window.addEventListener(`hashchange`,this._hashChangeHandler),this.graphId?(this._draftId=this.graphId,this._loadGraph()):(this._draftId=crypto.randomUUID(),this._showTemplatePicker=!0)}disconnectedCallback(){document.removeEventListener(`keydown`,this._onKeyDown),window.removeEventListener(`beforeunload`,this._beforeUnloadHandler),window.removeEventListener(`hashchange`,this._hashChangeHandler),this._rpcStatusUnsub?.(),this._rpcStatusUnsub=null,this._validationTimer&&=(clearTimeout(this._validationTimer),null),this._stateUnsub&&=(this._stateUnsub(),null),this._graphState=null,super.disconnectedCallback()}updated(e){e.has(`rpcClient`)&&this.rpcClient&&this.graphId&&!this._serverLoadDone&&(this._rpcStatusUnsub?.(),this.rpcClient.status===`connected`?this._loadGraph():this._rpcStatusUnsub=this.rpcClient.onStatusChange(e=>{e===`connected`&&!this._serverLoadDone&&(this._rpcStatusUnsub=null,this._loadGraph())}))}get _breadcrumbs(){let e=[{label:`Pipelines`,route:`pipelines`}];return this.graphId?(e.push({label:this.graphId}),e.push({label:`Edit`})):e.push({label:`New Pipeline`}),e}_onNodeSelect(e){let{nodeId:t,multi:n}=e.detail;this._graphState?.selectNode(t,n)}_onNodeDragEnd(e){this._graphState?.moveNodes(e.detail.moves)}_onEdgeCreate(e){let{source:t,target:n}=e.detail,r=this._graphState?.getSnapshot();if(!r||t===n||r.edges.some(e=>e.source===t&&e.target===n)||S(r.edges,t,n))return;this._graphState?.addEdge(t,n);let i=r.nodes.find(e=>e.id===n);i&&!i.dependsOn.includes(t)&&this._graphState?.updateNode(n,{dependsOn:[...i.dependsOn,t]})}_onCanvasClick(){this._graphState?.clearSelection()}_onHighlightNodes(e){this._highlightNodeIds=e.detail.nodeIds,setTimeout(()=>{this._highlightNodeIds=[]},3e3)}_onNodeUpdate(e){this._graphState?.updateNode(e.detail.nodeId,e.detail.partial)}_onNodeDelete(e){this._graphState?.selectNode(e.detail.nodeId),this._deleteSelected()}_onNodeDuplicate(e){this._graphState?.selectNode(e.detail.nodeId),this._duplicateSelected()}_onEditorEdgeAdd(e){let{source:t,target:n}=e.detail;if(!this._graphState)return;let r=this._graphState.getSnapshot();if(t===n||r.edges.some(e=>e.source===t&&e.target===n)||S(r.edges,t,n))return;this._graphState.addEdge(t,n);let i=r.nodes.find(e=>e.id===n);i&&!i.dependsOn.includes(t)&&this._graphState.updateNode(n,{dependsOn:[...i.dependsOn,t]})}_onEditorEdgeRemove(e){let{source:t,target:n}=e.detail;if(!this._graphState)return;let r=this._graphState.getSnapshot(),i=`${t}->${n}`;r.edges.find(e=>e.id===i)&&this._graphState.removeEdge(i);let a=r.nodes.find(e=>e.id===n);if(a){let e=a.dependsOn.filter(e=>e!==t);this._graphState.updateNode(n,{dependsOn:e})}}async _onValidate(){if(!this.rpcClient||!this._graphState)return;let e=this._graphState.getSnapshot(),t={nodes:e.nodes.map(t=>{let n=e.edges.filter(e=>e.target===t.id).map(e=>e.source);return{nodeId:t.id,task:t.task,agentId:t.agentId,dependsOn:n,maxSteps:t.maxSteps,timeoutMs:t.timeoutMs,barrierMode:t.barrierMode,model:t.modelId,retries:t.retries,type_id:t.typeId,type_config:t.typeConfig,context_mode:t.contextMode}}),label:e.settings.label||void 0,onFailure:e.settings.onFailure,timeoutMs:e.settings.timeoutMs,budget:e.settings.budget};try{let n=await this.rpcClient.call(`graph.define`,t);this._validateResultText=`Valid: ${n.nodeCount??e.nodes.length} nodes${Array.isArray(n.executionOrder)?`, order: ${n.executionOrder.join(` -> `)}`:``}`}catch(e){this._validateResultText=`Error: ${e instanceof Error?e.message:String(e)}`}}_addNodeAtViewportCenter(){if(!this._graphState)return;let e=this._graphState.getSnapshot();this._nodeCounter=Math.max(this._nodeCounter,e.nodes.length);let t;do this._nodeCounter++,t=`node-${this._nodeCounter}`;while(e.nodes.some(e=>e.id===t));let n=this.renderRoot.querySelector(`.canvas-area`)?.getBoundingClientRect(),r=200,i=200;if(n){let e=d(n.left+n.width/2,n.top+n.height/2,n,this._viewport);r=e.x-200/2,i=e.y-80/2}this._graphState.addNode({id:t,task:``,dependsOn:[],position:{x:r,y:i}})}_duplicateSelected(){if(!this._graphState)return;let e=this._graphState.getSnapshot();if(e.selectedNodeIds.size!==0)for(let t of e.selectedNodeIds){let n=e.nodes.find(e=>e.id===t);if(!n)continue;let r=`${n.id}-copy`,i=1,a=new Set(e.nodes.map(e=>e.id));for(;a.has(r);)i++,r=`${n.id}-copy-${i}`;a.add(r),this._graphState.addNode({id:r,task:n.task,agentId:n.agentId,dependsOn:[],maxSteps:n.maxSteps,timeoutMs:n.timeoutMs,barrierMode:n.barrierMode,modelId:n.modelId,retries:n.retries,typeId:n.typeId,typeConfig:n.typeConfig?{...n.typeConfig}:void 0,contextMode:n.contextMode,position:{x:n.position.x+60,y:n.position.y+40}})}}_deleteSelected(){if(!this._graphState)return;let e=this._graphState.getSnapshot();if(e.selectedEdgeId&&e.selectedNodeIds.size===0){this._graphState.removeEdge(e.selectedEdgeId);return}if(e.selectedNodeIds.size===0)return;let t=[...e.selectedNodeIds],n=[];for(let r of t)for(let t of e.edges)t.source===r&&!e.selectedNodeIds.has(t.target)&&n.push(`"${t.target}" depends on "${r}"`);if(n.length>0)this._deleteMessage=`Deleting will break dependencies:\n${n.join(`
1410
+ `)}`,this._pendingDeleteNodeIds=t,this._showDeleteConfirm=!0;else for(let e of t)this._graphState.removeNode(e)}_confirmDelete(){if(this._graphState){for(let e of this._pendingDeleteNodeIds)this._graphState.removeNode(e);this._pendingDeleteEdgeId&&this._graphState.removeEdge(this._pendingDeleteEdgeId),this._showDeleteConfirm=!1,this._pendingDeleteNodeIds=[],this._pendingDeleteEdgeId=null}}_fitView(){if(!this._graphState)return;let e=this._graphState.getSnapshot();if(e.nodes.length===0)return;let t=this.renderRoot.querySelector(`.canvas-area`)?.getBoundingClientRect();if(!t)return;let n=p(e.nodes,t.width,t.height);this._graphState.setViewport(n)}_autoLayout(){if(!this._graphState)return;let e=this._graphState.getSnapshot();if(e.nodes.length===0)return;let t=g(e.nodes,e.edges),n=[];for(let[e,r]of t.positions)n.push({nodeId:e,position:r});this._graphState.moveNodes(n)}_zoomStep(e){if(!this._graphState)return;let t=this.renderRoot.querySelector(`.canvas-area`)?.getBoundingClientRect();if(!t)return;let n=t.width/2,r=t.height/2,i=e>0?-100:100,a=m(this._viewport,n,r,i,f,2);this._graphState.setViewport(a)}_cycleNodeSelection(e){if(!this._graphState)return;let t=this._graphState.getSnapshot();if(t.nodes.length===0)return;let n=[...t.nodes].sort((e,t)=>e.position.y===t.position.y?e.position.x-t.position.x:e.position.y-t.position.y),r=-1;if(t.selectedNodeIds.size===1){let e=[...t.selectedNodeIds][0];r=n.findIndex(t=>t.id===e)}let i=r+e;i<0&&(i=n.length-1),i>=n.length&&(i=0),this._graphState.selectNode(n[i].id)}_nudgeSelected(e){if(!this._graphState)return;let t=this._graphState.getSnapshot();if(t.selectedNodeIds.size===0)return;let n=0,r=0;switch(e){case`ArrowUp`:r=-W;break;case`ArrowDown`:r=W;break;case`ArrowLeft`:n=-W;break;case`ArrowRight`:n=W;break}let i=[];for(let e of t.selectedNodeIds){let a=t.nodes.find(t=>t.id===e);if(!a)continue;let o=a.position.x+n,s=a.position.y+r;this._snapToGrid&&(o=Math.round(o/W)*W,s=Math.round(s/W)*W),i.push({nodeId:e,position:{x:o,y:s}})}this._graphState.moveNodes(i)}async _loadGraph(){if(!(!this._graphState||!this.graphId)&&this.rpcClient)try{let e=await this.rpcClient.call(`graph.load`,{id:this.graphId});if(e&&this._graphState){this._graphState.reset();let t=[],n=[];for(let n of e.nodes){let e={id:n.id??n.nodeId,task:n.task??``,agentId:n.agentId??n.agent,dependsOn:n.dependsOn??[],maxSteps:n.maxSteps,timeoutMs:n.timeoutMs,barrierMode:n.barrierMode,modelId:n.modelId??n.model,retries:typeof n.retries==`number`?n.retries:void 0,contextMode:n.contextMode===`full`||n.contextMode===`summary`||n.contextMode===`none`?n.contextMode:n.context_mode===`full`||n.context_mode===`summary`||n.context_mode===`none`?n.context_mode:void 0,typeId:n.typeId,typeConfig:n.typeConfig&&typeof n.typeConfig==`object`?n.typeConfig:void 0,position:n.position??{x:0,y:0}};t.push(e)}if(e.edges&&e.edges.length>0)for(let t of e.edges)n.push(t);else for(let e of t)for(let t of e.dependsOn)n.push({id:`${t}->${e.id}`,source:t,target:e.id});if(t.length>0&&t.every(e=>e.position.x===0&&e.position.y===0)){let e=g(t,n);for(let n of t){let t=e.positions.get(n.id);t&&(n.position=t)}}for(let e of t)this._graphState.addNode(e);for(let e of n)this._graphState.addEdge(e.source,e.target);let r={...e.settings,...e.label?{label:e.label}:{}};Object.keys(r).length>0&&this._graphState.updateSettings(r),this._serverLoadDone=!0}}catch{}}_onTemplateSelect(e){if(!this._graphState)return;let{nodes:t,edges:n,settings:r}=e.detail;this._graphState.reset();for(let e of t)this._graphState.addNode(e);for(let e of n)this._graphState.addEdge(e.source,e.target);(r.label||r.onFailure)&&this._graphState.updateSettings(r),this._showTemplatePicker=!1}async _onSaveDraft(){if(!this._graphState)return;let e=this._graphState.getSnapshot();if(!this.rpcClient){u.show(`Cannot save: not connected to daemon`,`error`);return}try{await this.rpcClient.call(`graph.save`,{id:this._draftId,label:e.settings.label,nodes:e.nodes,edges:e.edges,settings:e.settings}),this._graphState.markClean(),u.show(`Pipeline saved`,`success`)}catch(e){u.show(`Save failed: ${e instanceof Error?e.message:`Unknown error`}`,`error`)}}async _onRun(){if(!this.rpcClient||!this._graphState)return;let e=this._graphState.getSnapshot(),t=v(e.nodes.map(e=>e.task));if(t.length>0){this._variableNames=t,this._showVariablePrompt=!0;return}await this._executeGraph(e.nodes.map(e=>e.task))}async _onVariableConfirm(e){if(this._showVariablePrompt=!1,!this.rpcClient||!this._graphState)return;let t=this._graphState.getSnapshot().nodes.map(t=>_(t.task,e.detail.values));await this._executeGraph(t)}async _executeGraph(e){if(!this.rpcClient||!this._graphState)return;let t=this._graphState.getSnapshot(),n={nodes:t.nodes.map((n,r)=>{let i=t.edges.filter(e=>e.target===n.id).map(e=>e.source);return{nodeId:n.id,task:e[r],agentId:n.agentId,dependsOn:i,maxSteps:n.maxSteps,timeoutMs:n.timeoutMs,barrierMode:n.barrierMode,model:n.modelId,retries:n.retries,type_id:n.typeId,type_config:n.typeConfig,context_mode:n.contextMode}}),label:t.settings.label||void 0,onFailure:t.settings.onFailure,timeoutMs:t.settings.timeoutMs,budget:t.settings.budget};try{let e=await this.rpcClient.call(`graph.execute`,n);this.dispatchEvent(new CustomEvent(`navigate`,{detail:`pipelines/${e.graphId}`,bubbles:!0,composed:!0}))}catch(e){u.show(`Run failed: ${e instanceof Error?e.message:String(e)}`,`error`)}}render(){let e=this._graphState?.getSnapshot(),n=e&&e.selectedNodeIds.size===1?e.nodes.find(t=>e.selectedNodeIds.has(t.id))??null:null;return t`
1411
+ <ic-breadcrumb .items=${this._breadcrumbs}
1412
+ @navigate=${e=>this.dispatchEvent(new CustomEvent(`navigate`,{detail:e.detail,bubbles:!0,composed:!0}))}
1413
+ ></ic-breadcrumb>
1414
+ <div class="mobile-message">
1415
+ <h2>Desktop Required</h2>
1416
+ <p>The pipeline builder requires a desktop browser. Please use a screen wider than 768px.</p>
1417
+ </div>
1418
+ <div class="builder-container">
1419
+ <ic-graph-settings
1420
+ .settings=${this._settings}
1421
+ .hasErrors=${(this._validationResult?.errors.length??0)>0}
1422
+ .isDirty=${this._isDirty}
1423
+ .validateResult=${this._validateResultText}
1424
+ @settings-change=${e=>this._graphState?.updateSettings(e.detail)}
1425
+ @validate=${this._onValidate}
1426
+ @save-draft=${this._onSaveDraft}
1427
+ @run=${this._onRun}
1428
+ ></ic-graph-settings>
1429
+ <div class="toolbar">
1430
+ <button class="toolbar-btn ${this._snapToGrid?`toolbar-btn--active`:``}"
1431
+ @click=${()=>{this._snapToGrid=!this._snapToGrid}}
1432
+ title="Snap to grid (24px)">Grid</button>
1433
+ <button class="toolbar-btn"
1434
+ @click=${()=>{this._showTemplatePicker=!0}}
1435
+ title="Choose a template">Templates</button>
1436
+ </div>
1437
+ <div class="builder-body">
1438
+ <div class="canvas-area">
1439
+ <ic-graph-canvas
1440
+ .viewport=${this._viewport}
1441
+ .nodes=${this._nodes}
1442
+ .edges=${this._edges}
1443
+ .selectedNodeIds=${this._selectedNodeIds}
1444
+ .selectedEdgeId=${this._selectedEdgeId}
1445
+ .snapToGrid=${this._snapToGrid}
1446
+ .highlightNodeIds=${this._highlightNodeIds}
1447
+ @viewport-change=${e=>{this._graphState?.setViewport(e.detail)}}
1448
+ @edge-select=${e=>{this._graphState?.selectEdge(e.detail)}}
1449
+ @node-select=${this._onNodeSelect}
1450
+ @node-drag-end=${this._onNodeDragEnd}
1451
+ @edge-create=${this._onEdgeCreate}
1452
+ @canvas-click=${this._onCanvasClick}
1453
+ ></ic-graph-canvas>
1454
+ <ic-graph-validation
1455
+ .validationResult=${this._validationResult}
1456
+ @highlight-nodes=${this._onHighlightNodes}
1457
+ ></ic-graph-validation>
1458
+ </div>
1459
+ ${n?t`
1460
+ <ic-node-editor
1461
+ .node=${n}
1462
+ .allNodes=${this._nodes}
1463
+ .allEdges=${this._edges}
1464
+ .rpcClient=${this.rpcClient}
1465
+ @node-update=${this._onNodeUpdate}
1466
+ @node-delete=${this._onNodeDelete}
1467
+ @node-duplicate=${this._onNodeDuplicate}
1468
+ @edge-add=${this._onEditorEdgeAdd}
1469
+ @edge-remove=${this._onEditorEdgeRemove}
1470
+ ></ic-node-editor>
1471
+ `:l}
1472
+ </div>
1473
+ </div>
1474
+ <ic-confirm-dialog
1475
+ ?open=${this._showDeleteConfirm}
1476
+ title="Delete Node"
1477
+ .message=${this._deleteMessage}
1478
+ variant="danger"
1479
+ confirmLabel="Delete"
1480
+ @confirm=${this._confirmDelete}
1481
+ @cancel=${()=>{this._showDeleteConfirm=!1,this._pendingDeleteNodeIds=[],this._pendingDeleteEdgeId=null}}
1482
+ ></ic-confirm-dialog>
1483
+ <ic-template-picker
1484
+ ?open=${this._showTemplatePicker}
1485
+ @template-select=${this._onTemplateSelect}
1486
+ @cancel=${()=>{this._showTemplatePicker=!1}}
1487
+ ></ic-template-picker>
1488
+ <ic-variable-prompt
1489
+ ?open=${this._showVariablePrompt}
1490
+ .variables=${this._variableNames}
1491
+ .pipelineLabel=${this._settings.label}
1492
+ @confirm=${this._onVariableConfirm}
1493
+ @cancel=${()=>{this._showVariablePrompt=!1}}
1494
+ ></ic-variable-prompt>
1495
+ `}};c([s({attribute:!1})],G.prototype,`rpcClient`,void 0),c([s()],G.prototype,`graphId`,void 0),c([a()],G.prototype,`_viewport`,void 0),c([a()],G.prototype,`_nodes`,void 0),c([a()],G.prototype,`_edges`,void 0),c([a()],G.prototype,`_selectedNodeIds`,void 0),c([a()],G.prototype,`_selectedEdgeId`,void 0),c([a()],G.prototype,`_showDeleteConfirm`,void 0),c([a()],G.prototype,`_deleteMessage`,void 0),c([a()],G.prototype,`_snapToGrid`,void 0),c([a()],G.prototype,`_validationResult`,void 0),c([a()],G.prototype,`_settings`,void 0),c([a()],G.prototype,`_highlightNodeIds`,void 0),c([a()],G.prototype,`_validateResultText`,void 0),c([a()],G.prototype,`_showTemplatePicker`,void 0),c([a()],G.prototype,`_showVariablePrompt`,void 0),c([a()],G.prototype,`_variableNames`,void 0),c([a()],G.prototype,`_draftId`,void 0),c([a()],G.prototype,`_isDirty`,void 0),G=c([e(`ic-pipeline-builder`)],G);export{G as IcPipelineBuilder};