@ngocsangairvds/vsaf 5.1.17 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +55 -1
  2. package/package.json +1 -1
  3. package/packages/cli/dist/commands/abandon.d.ts +6 -0
  4. package/packages/cli/dist/commands/abandon.d.ts.map +1 -0
  5. package/packages/cli/dist/commands/abandon.js +42 -0
  6. package/packages/cli/dist/commands/abandon.js.map +1 -0
  7. package/packages/cli/dist/commands/ai.d.ts +21 -0
  8. package/packages/cli/dist/commands/ai.d.ts.map +1 -0
  9. package/packages/cli/dist/commands/ai.js +76 -0
  10. package/packages/cli/dist/commands/ai.js.map +1 -0
  11. package/packages/cli/dist/commands/approve.d.ts +19 -0
  12. package/packages/cli/dist/commands/approve.d.ts.map +1 -0
  13. package/packages/cli/dist/commands/approve.js +115 -0
  14. package/packages/cli/dist/commands/approve.js.map +1 -0
  15. package/packages/cli/dist/commands/chat.d.ts +41 -0
  16. package/packages/cli/dist/commands/chat.d.ts.map +1 -0
  17. package/packages/cli/dist/commands/chat.js +129 -0
  18. package/packages/cli/dist/commands/chat.js.map +1 -0
  19. package/packages/cli/dist/commands/isolation.d.ts +20 -0
  20. package/packages/cli/dist/commands/isolation.d.ts.map +1 -0
  21. package/packages/cli/dist/commands/isolation.js +104 -0
  22. package/packages/cli/dist/commands/isolation.js.map +1 -0
  23. package/packages/cli/dist/commands/run.d.ts +36 -1
  24. package/packages/cli/dist/commands/run.d.ts.map +1 -1
  25. package/packages/cli/dist/commands/run.js +161 -15
  26. package/packages/cli/dist/commands/run.js.map +1 -1
  27. package/packages/cli/dist/commands/telemetry.d.ts +10 -0
  28. package/packages/cli/dist/commands/telemetry.d.ts.map +1 -0
  29. package/packages/cli/dist/commands/telemetry.js +51 -0
  30. package/packages/cli/dist/commands/telemetry.js.map +1 -0
  31. package/packages/cli/dist/commands/validate.d.ts +12 -0
  32. package/packages/cli/dist/commands/validate.d.ts.map +1 -0
  33. package/packages/cli/dist/commands/validate.js +83 -0
  34. package/packages/cli/dist/commands/validate.js.map +1 -0
  35. package/packages/cli/dist/commands/workflow.d.ts +29 -0
  36. package/packages/cli/dist/commands/workflow.d.ts.map +1 -0
  37. package/packages/cli/dist/commands/workflow.js +147 -0
  38. package/packages/cli/dist/commands/workflow.js.map +1 -0
  39. package/packages/cli/dist/index.js +253 -6
  40. package/packages/cli/dist/index.js.map +1 -1
  41. package/packages/cli/dist/mcp/server.d.ts +9 -0
  42. package/packages/cli/dist/mcp/server.d.ts.map +1 -1
  43. package/packages/cli/dist/mcp/server.js +38 -2
  44. package/packages/cli/dist/mcp/server.js.map +1 -1
  45. package/packages/cli/dist/server/app.d.ts.map +1 -1
  46. package/packages/cli/dist/server/app.js +2 -0
  47. package/packages/cli/dist/server/app.js.map +1 -1
  48. package/packages/cli/dist/server/routes/conversations.d.ts +6 -0
  49. package/packages/cli/dist/server/routes/conversations.d.ts.map +1 -0
  50. package/packages/cli/dist/server/routes/conversations.js +145 -0
  51. package/packages/cli/dist/server/routes/conversations.js.map +1 -0
  52. package/packages/cli/dist/server/routes/runs.d.ts.map +1 -1
  53. package/packages/cli/dist/server/routes/runs.js +15 -3
  54. package/packages/cli/dist/server/routes/runs.js.map +1 -1
  55. package/packages/cli/dist/server/services/execution-manager.d.ts +25 -0
  56. package/packages/cli/dist/server/services/execution-manager.d.ts.map +1 -1
  57. package/packages/cli/dist/server/services/execution-manager.js +255 -95
  58. package/packages/cli/dist/server/services/execution-manager.js.map +1 -1
  59. package/packages/core/dist/config/ai-config.d.ts +24 -0
  60. package/packages/core/dist/config/ai-config.d.ts.map +1 -0
  61. package/packages/core/dist/config/ai-config.js +170 -0
  62. package/packages/core/dist/config/ai-config.js.map +1 -0
  63. package/packages/core/dist/engine/dag-executor.d.ts +18 -0
  64. package/packages/core/dist/engine/dag-executor.d.ts.map +1 -1
  65. package/packages/core/dist/engine/dag-executor.js +181 -8
  66. package/packages/core/dist/engine/dag-executor.js.map +1 -1
  67. package/packages/core/dist/engine/dag-parser.d.ts.map +1 -1
  68. package/packages/core/dist/engine/dag-parser.js +32 -1
  69. package/packages/core/dist/engine/dag-parser.js.map +1 -1
  70. package/packages/core/dist/engine/loop-signal.d.ts +7 -0
  71. package/packages/core/dist/engine/loop-signal.d.ts.map +1 -0
  72. package/packages/core/dist/engine/loop-signal.js +21 -0
  73. package/packages/core/dist/engine/loop-signal.js.map +1 -0
  74. package/packages/core/dist/engine/node-runner.d.ts +4 -1
  75. package/packages/core/dist/engine/node-runner.d.ts.map +1 -1
  76. package/packages/core/dist/engine/node-runner.js +14 -6
  77. package/packages/core/dist/engine/node-runner.js.map +1 -1
  78. package/packages/core/dist/index.d.ts +5 -2
  79. package/packages/core/dist/index.d.ts.map +1 -1
  80. package/packages/core/dist/index.js +25 -1
  81. package/packages/core/dist/index.js.map +1 -1
  82. package/packages/core/dist/runtime/executor.d.ts +1 -1
  83. package/packages/core/dist/runtime/executor.d.ts.map +1 -1
  84. package/packages/core/dist/runtime/executor.js +12 -8
  85. package/packages/core/dist/runtime/executor.js.map +1 -1
  86. package/packages/core/dist/schema/workflow-schema.d.ts +94 -14
  87. package/packages/core/dist/schema/workflow-schema.d.ts.map +1 -1
  88. package/packages/core/dist/schema/workflow-schema.js +38 -6
  89. package/packages/core/dist/schema/workflow-schema.js.map +1 -1
  90. package/packages/core/dist/store/recovery.d.ts.map +1 -1
  91. package/packages/core/dist/store/recovery.js +7 -0
  92. package/packages/core/dist/store/recovery.js.map +1 -1
  93. package/packages/core/dist/store/run-store.d.ts +5 -3
  94. package/packages/core/dist/store/run-store.d.ts.map +1 -1
  95. package/packages/core/dist/store/run-store.js +12 -4
  96. package/packages/core/dist/store/run-store.js.map +1 -1
  97. package/packages/core/dist/store/sqlite-schema.d.ts +1 -1
  98. package/packages/core/dist/store/sqlite-schema.d.ts.map +1 -1
  99. package/packages/core/dist/store/sqlite-schema.js +20 -0
  100. package/packages/core/dist/store/sqlite-schema.js.map +1 -1
  101. package/packages/core/dist/store/sqlite-workflow-store.d.ts +26 -0
  102. package/packages/core/dist/store/sqlite-workflow-store.d.ts.map +1 -1
  103. package/packages/core/dist/store/sqlite-workflow-store.js +106 -0
  104. package/packages/core/dist/store/sqlite-workflow-store.js.map +1 -1
  105. package/packages/core/dist/store/types.d.ts +15 -0
  106. package/packages/core/dist/store/types.d.ts.map +1 -1
  107. package/packages/core/dist/store/types.js.map +1 -1
  108. package/packages/core/dist/telemetry/telemetry.d.ts +31 -0
  109. package/packages/core/dist/telemetry/telemetry.d.ts.map +1 -0
  110. package/packages/core/dist/telemetry/telemetry.js +177 -0
  111. package/packages/core/dist/telemetry/telemetry.js.map +1 -0
  112. package/packages/core/dist/types/dag.d.ts +16 -0
  113. package/packages/core/dist/types/dag.d.ts.map +1 -1
  114. package/packages/core/dist/types/workflow.d.ts +18 -1
  115. package/packages/core/dist/types/workflow.d.ts.map +1 -1
  116. package/packages/web/dist/web/browser/chunk-2JHYGCCN.js +1 -0
  117. package/packages/web/dist/web/browser/chunk-BMQT4ZPK.js +1 -0
  118. package/packages/web/dist/web/browser/chunk-GWHJRWJM.js +1 -0
  119. package/packages/web/dist/web/browser/chunk-OZ6BRCXC.js +1 -0
  120. package/packages/web/dist/web/browser/chunk-Q7N6DAKT.js +1 -0
  121. package/packages/web/dist/web/browser/chunk-SEBU2SK7.js +1 -0
  122. package/packages/web/dist/web/browser/chunk-SOS4TH5D.js +4 -0
  123. package/packages/web/dist/web/browser/chunk-WSAVMPNK.js +5 -0
  124. package/packages/web/dist/web/browser/index.html +1 -1
  125. package/packages/web/dist/web/browser/main-UPZIVGM6.js +1 -0
  126. package/workflows/sdlc/hotfix-tdd.yaml +1 -1
  127. package/workflows/sdlc/hotfix.yaml +7 -4
  128. package/workflows/sdlc/master-sdlc.yaml +18 -9
  129. package/packages/web/dist/web/browser/chunk-5WD7R336.js +0 -1
  130. package/packages/web/dist/web/browser/chunk-FXYDTGOX.js +0 -1
  131. package/packages/web/dist/web/browser/chunk-K4DHLOOA.js +0 -1
  132. package/packages/web/dist/web/browser/chunk-V2CDNNWN.js +0 -1
  133. package/packages/web/dist/web/browser/chunk-WJT4QH2P.js +0 -4
  134. package/packages/web/dist/web/browser/chunk-WMJLW2L6.js +0 -5
  135. package/packages/web/dist/web/browser/chunk-XHOL7AER.js +0 -1
  136. package/packages/web/dist/web/browser/chunk-YBYFKZWR.js +0 -1
  137. package/packages/web/dist/web/browser/main-SYHKSBNJ.js +0 -1
@@ -0,0 +1 @@
1
+ import{a as R,b as F,c as V,d as A,e as H,f as K,j as z,k as W}from"./chunk-OZ6BRCXC.js";import{$ as w,C as a,Da as D,G as M,Ha as T,Ka as L,N as x,O as p,P as g,R as u,S as f,T as v,U as i,V as o,_ as S,aa as l,da as O,fa as r,ga as m,ia as k,ja as P,ka as I,la as E,oa as N,p as C,q as _,r as y,x as d}from"./chunk-WSAVMPNK.js";function B(t){let n=t.metadata?.category;return n==="gate"?"gate":n==="workflow_status"?"status":"text"}function $(t){return t.title?t.title:t.runs.length>0?t.runs[0].workflow_name:t.id}var G=t=>["/conversations",t],h=(t,n)=>n.id;function q(t,n){t&1&&(i(0,"p",2),r(1,"No conversations yet. Start a run or send a message."),o())}function J(t,n){if(t&1&&(i(0,"span",8),r(1),o()),t&2){let e=n.$implicit;x("data-status",e.status),a(),k("",e.workflow_name," \xB7 ",e.status)}}function Q(t,n){if(t&1&&(i(0,"a",5)(1,"span",6),r(2),o(),i(3,"span",7),u(4,J,2,3,"span",8,h),o()()),t&2){let e=n.$implicit,s=l();O("active",e.id===s.selectedId()),v("routerLink",N(4,G,e.id)),a(2),m(s.label(e)),a(2),f(e.runs)}}function U(t,n){t&1&&(i(0,"p",2),r(1,"Select a conversation to view its messages."),o())}function X(t,n){if(t&1&&(i(0,"div",10)(1,"span",15),r(2),o(),i(3,"p",16),r(4),o()()),t&2){let e=n.$implicit,s=l(2);x("data-role",e.role)("data-kind",s.kind(e)),a(2),m(e.role),a(2),m(e.content)}}function Y(t,n){if(t&1&&(i(0,"p",14),r(1),o()),t&2){let e=l(2);a(),m(e.lastReply())}}function Z(t,n){if(t&1){let e=S();i(0,"div",9),u(1,X,5,4,"div",10,h),o(),i(3,"form",11),w("ngSubmit",function(){_(e);let c=l();return y(c.send())}),i(4,"input",12),E("ngModelChange",function(c){_(e);let b=l();return I(b.draft,c)||(b.draft=c),y(c)}),o(),i(5,"button",13),r(6,"Send"),o()(),p(7,Y,2,1,"p",14)}if(t&2){let e=l();a(),f(e.messages()),a(3),P("ngModel",e.draft),v("disabled",e.sending()),a(),v("disabled",e.sending()||!e.draft.trim()),a(2),g(e.lastReply()?7:-1)}}var j=class t{api=C(W);route=C(T);pollHandle;paramSub;conversations=d([]);messages=d([]);selectedId=d(null);sending=d(!1);lastReply=d("");draft="";ngOnInit(){this.paramSub=this.route.paramMap.subscribe(n=>{this.selectedId.set(n.get("conversationId")),this.refresh()}),this.pollHandle=setInterval(()=>this.refreshMessages(),4e3)}ngOnDestroy(){this.pollHandle&&clearInterval(this.pollHandle),this.paramSub?.unsubscribe()}label=$;kind=B;refresh(){this.api.listConversations().subscribe(n=>this.conversations.set(n.conversations)),this.refreshMessages()}refreshMessages(){let n=this.selectedId();n&&this.api.getConversationMessages(n).subscribe({next:e=>this.messages.set(e.messages),error:()=>this.messages.set([])})}send(){let n=this.selectedId(),e=this.draft.trim();!n||!e||(this.sending.set(!0),this.api.sendConversationMessage(n,e).subscribe({next:s=>{this.lastReply.set(s.reply),this.draft="",this.sending.set(!1),this.refresh()},error:()=>this.sending.set(!1)}))}static \u0275fac=function(e){return new(e||t)};static \u0275cmp=M({type:t,selectors:[["app-conversations"]],decls:10,vars:2,consts:[[1,"conversations-layout"],[1,"conversations-sidebar"],[1,"empty"],[1,"conversation-item",3,"active","routerLink"],[1,"chat-panel"],[1,"conversation-item",3,"routerLink"],[1,"conversation-title"],[1,"conversation-meta"],[1,"run-chip"],[1,"message-list"],[1,"message"],[1,"message-input",3,"ngSubmit"],["type","text","name","draft","placeholder","Reply to the paused run or leave a note\u2026","aria-label","Message",3,"ngModelChange","ngModel","disabled"],["type","submit",3,"disabled"],[1,"chat-hint"],[1,"message-role"],[1,"message-content"]],template:function(e,s){e&1&&(i(0,"div",0)(1,"aside",1)(2,"h2"),r(3,"Conversations"),o(),p(4,q,2,0,"p",2),u(5,Q,6,6,"a",3,h),o(),i(7,"section",4),p(8,U,2,0,"p",2)(9,Z,8,4),o()()),e&2&&(a(4),g(s.conversations().length===0?4:-1),a(),f(s.conversations()),a(3),g(s.selectedId()?9:8))},dependencies:[D,z,K,R,F,V,H,A,L],styles:[".conversations-layout[_ngcontent-%COMP%]{display:flex;gap:1rem;min-height:70vh}.conversations-sidebar[_ngcontent-%COMP%]{width:280px;border-right:1px solid var(--border-color, #333);padding-right:1rem}.conversation-item[_ngcontent-%COMP%]{display:block;padding:.5rem;border-radius:6px;text-decoration:none;color:inherit}.conversation-item.active[_ngcontent-%COMP%]{background:#8080ff1f}.conversation-title[_ngcontent-%COMP%]{display:block;font-weight:600}.run-chip[_ngcontent-%COMP%]{font-size:.75rem;opacity:.75;margin-right:.5rem}.chat-panel[_ngcontent-%COMP%]{flex:1;display:flex;flex-direction:column}.message-list[_ngcontent-%COMP%]{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:.5rem}.message[_ngcontent-%COMP%]{max-width:70%;padding:.5rem .75rem;border-radius:8px;background:#8080801f}.message[data-role=user][_ngcontent-%COMP%]{align-self:flex-end;background:#5078ff2e}.message[data-kind=gate][_ngcontent-%COMP%]{border-left:3px solid orange}.message[data-kind=status][_ngcontent-%COMP%]{opacity:.8;font-style:italic}.message-role[_ngcontent-%COMP%]{font-size:.7rem;text-transform:uppercase;opacity:.6}.message-content[_ngcontent-%COMP%]{margin:.25rem 0 0;white-space:pre-wrap}.message-input[_ngcontent-%COMP%]{display:flex;gap:.5rem;margin-top:1rem}.message-input[_ngcontent-%COMP%] input[_ngcontent-%COMP%]{flex:1}.empty[_ngcontent-%COMP%]{opacity:.7;padding:1rem 0}.chat-hint[_ngcontent-%COMP%]{opacity:.7;font-size:.85rem}"]})};export{j as ConversationsComponent};
@@ -0,0 +1,4 @@
1
+ import{a as U,b as X,e as Q,g as Z,h as ee,i as te,j as ne,k as oe}from"./chunk-OZ6BRCXC.js";import{$ as f,Aa as q,C as s,Da as G,G as V,Ha as H,Ja as J,K as _,Ka as K,N as F,T as u,U as i,V as r,W as O,X as D,Y as $,_ as C,a as B,aa as p,b as T,ba as z,ca as L,da as P,ea as R,fa as d,ga as w,ha as v,ia as N,ja as h,ka as x,la as b,oa as Y,p as M,q as m,r as g,ra as A,s as S,t as I,za as j}from"./chunk-WSAVMPNK.js";var le=l=>["/runs",l];function de(l,n){if(l&1){let e=C();i(0,"button",39),f("dragstart",function(o){let a=m(e).$implicit,c=p();return g(c.onPaletteDragStart(o,a.type))})("click",function(){let o=m(e).$implicit,a=p();return g(a.addNode(o.type))}),i(1,"span",40),d(2),r(),i(3,"span")(4,"strong"),d(5),r(),i(6,"small"),d(7),r()()()}if(l&2){let e=n.$implicit,t=p();s(2),w(t.iconFor(e.type)),s(3),w(e.label),s(2),w(e.description)}}function se(l,n){if(l&1){let e=C();i(0,"button",41),f("click",function(){let o=m(e).$implicit,a=p();return g(a.loadWorkflow(o.id))}),i(1,"span"),d(2),r(),i(3,"small"),d(4),r()()}if(l&2){let e=n.$implicit;s(2),w(e.name),s(2),v("",e.nodeCount," nodes")}}function ce(l,n){if(l&1&&(i(0,"div",42),d(1),r()),l&2){let e=p();P("error",e.saveState==="error"),s(),v(" ",e.statusMessage," ")}}function pe(l,n){l&1&&(i(0,"div",43)(1,"h2"),d(2,"Drop nodes here"),r(),i(3,"p"),d(4,"Build a DAG by adding Bash, Command, and Prompt nodes."),r()())}function me(l,n){if(l&1&&(S(),O(0,"line")),l&2){let e=n.$implicit;F("x1",e.x1)("y1",e.y1)("x2",e.x2)("y2",e.y2)}}function ge(l,n){if(l&1){let e=C();i(0,"button",44),f("click",function(){let o=m(e).$implicit,a=p();return g(a.selectNode(o))})("dragstart",function(o){let a=m(e).$implicit,c=p();return g(c.onNodeDragStart(o,a))}),i(1,"span",45),d(2),r(),i(3,"span",46)(4,"strong"),d(5),r(),i(6,"small"),d(7),r()()()}if(l&2){let e=n.$implicit,t=p();L("left",e.x,"px")("top",e.y,"px"),P("selected",(t.selectedNode==null?null:t.selectedNode.id)===e.id),s(2),w(t.iconFor(e.type)),s(3),w(e.id),s(2),N("",e.type," \xB7 ",e.dependsOn.length||0," deps")}}function ue(l,n){if(l&1&&(i(0,"option",67),d(1),r()),l&2){let e=n.$implicit;u("value",e.name)("disabled",!e.available),s(),N(" ",e.name,"",e.available?"":" \u2014 not available on this machine"," ")}}function fe(l,n){if(l&1&&O(0,"option",68),l&2){let e=n.$implicit;u("value",e)}}function _e(l,n){if(l&1){let e=C();i(0,"label",69)(1,"input",70),f("change",function(o){let a=m(e).$implicit,c=p(2);return g(c.toggleDependency(a.id,o))}),r(),i(2,"span"),d(3),r()()}if(l&2){let e=n.$implicit,t=p(2);s(),u("checked",t.selectedNode.dependsOn.includes(e.id)),s(2),w(e.id)}}function we(l,n){if(l&1){let e=C();D(0),i(1,"div",34),d(2,"Inspector"),r(),i(3,"label",47),d(4,"Node ID"),r(),i(5,"input",48),f("ngModelChange",function(o){m(e);let a=p();return g(a.renameSelectedNode(o))}),r(),i(6,"label",49),d(7,"Type"),r(),i(8,"select",50),b("ngModelChange",function(o){m(e);let a=p();return x(a.selectedNode.type,o)||(a.selectedNode.type=o),g(o)}),f("ngModelChange",function(){m(e);let o=p();return g(o.refreshYaml())}),i(9,"option",51),d(10,"bash"),r(),i(11,"option",52),d(12,"command"),r(),i(13,"option",53),d(14,"prompt"),r()(),i(15,"label",54),d(16,"Content"),r(),i(17,"textarea",55),b("ngModelChange",function(o){m(e);let a=p();return x(a.selectedNode.content,o)||(a.selectedNode.content=o),g(o)}),f("ngModelChange",function(){m(e);let o=p();return g(o.refreshYaml())}),r(),i(18,"label",56),d(19,"Provider"),r(),i(20,"select",57),b("ngModelChange",function(o){m(e);let a=p();return x(a.selectedNode.provider,o)||(a.selectedNode.provider=o),g(o)}),f("ngModelChange",function(){m(e);let o=p();return g(o.refreshYaml())}),i(21,"option",58),d(22,"(inherit workflow)"),r(),_(23,ue,2,4,"option",59),r(),i(24,"label",60),d(25,"Model"),r(),i(26,"input",61),b("ngModelChange",function(o){m(e);let a=p();return x(a.selectedNode.model,o)||(a.selectedNode.model=o),g(o)}),f("ngModelChange",function(){m(e);let o=p();return g(o.refreshYaml())}),r(),i(27,"datalist",62),_(28,fe,1,1,"option",63),r(),i(29,"label",64),d(30,"Depends on"),r(),_(31,_e,4,2,"label",65),i(32,"button",66),f("click",function(){m(e);let o=p();return g(o.deleteSelectedNode())}),d(33,"Delete Node"),r(),$()}if(l&2){let e=p();s(5),u("ngModel",e.selectedNode.id),s(3),h("ngModel",e.selectedNode.type),s(9),h("ngModel",e.selectedNode.content),s(3),h("ngModel",e.selectedNode.provider),s(3),u("ngForOf",e.providers),s(3),h("ngModel",e.selectedNode.model),s(2),u("ngForOf",e.modelSuggestions),s(3),u("ngForOf",e.dependencyCandidates)}}function he(l,n){l&1&&(i(0,"div",34),d(1,"Inspector"),r(),i(2,"p",71),d(3,"Select a node to edit its ID, type, command body, and dependencies."),r())}function xe(l,n){if(l&1&&(i(0,"a",72)(1,"span")(2,"strong"),d(3),r(),i(4,"small"),d(5),r()(),i(6,"em"),d(7),r()()),l&2){let e=n.$implicit,t=p();u("routerLink",Y(6,le,e.runId)),s(3),w(e.workflow),s(2),w(e.runId),s(),R(t.statusClass(e.status)),s(),w(e.status)}}function be(l,n){l&1&&(i(0,"p",71),d(1,"No runs yet."),r())}var ie=class l{api=M(oe);router=M(J);route=M(H);palette=[{type:"bash",label:"Bash",description:"Run a shell step"},{type:"command",label:"Command",description:"Use a .vsaf command"},{type:"prompt",label:"Prompt",description:"Call an AI provider"}];workflowName="new-workflow";workflowFolder="";description="Draft workflow";nodes=[];selectedNode;workflows=[];runs=[];providers=[];yamlPreview="";saveState="idle";statusMessage="";draggingType;draggingNodeId;ngOnInit(){this.workflowFolder=W(this.route.snapshot.queryParamMap.get("folder")??""),this.refreshData(),this.resetBuilder();let n=this.route.snapshot.queryParamMap.get("edit");n&&this.loadWorkflow(n)}refreshData(){this.api.getWorkflows().subscribe(n=>this.workflows=n),this.api.getRuns().subscribe(n=>this.runs=n.slice().reverse().slice(0,8)),this.api.getProviders().subscribe({next:n=>this.providers=n.providers??[],error:()=>this.providers=[]})}get modelSuggestions(){let n=this.selectedNode?.provider||re;return this.providers.find(e=>e.name===n)?.defaultModels??[]}resetBuilder(){this.workflowName="new-workflow",this.description="Draft workflow",this.nodes=[this.makeNode("bash",80,100,"setup"),this.makeNode("command",330,170,"review")],this.nodes[1].dependsOn=[this.nodes[0].id],this.selectedNode=this.nodes[0],this.setStatus(""),this.refreshYaml()}get workflowId(){let n=W(this.workflowFolder),e=y(this.workflowName);return n?`${n}/${e}`:e}onPaletteDragStart(n,e){this.draggingType=e,n.dataTransfer?.setData("application/x-vsaf-node-type",e),n.dataTransfer?.setData("text/plain",e)}onNodeDragStart(n,e){this.draggingNodeId=e.id,n.dataTransfer?.setData("application/x-vsaf-node-id",e.id)}onCanvasDragOver(n){n.preventDefault()}onCanvasDrop(n){n.preventDefault();let e=n.currentTarget.getBoundingClientRect(),t=Math.max(18,n.clientX-e.left-95),o=Math.max(18,n.clientY-e.top-24),a=n.dataTransfer?.getData("application/x-vsaf-node-id")||this.draggingNodeId;if(a){let k=this.nodes.find(ae=>ae.id===a);k&&(k.x=t,k.y=o,this.selectNode(k),this.refreshYaml()),this.draggingNodeId=void 0;return}let c=n.dataTransfer?.getData("application/x-vsaf-node-type")||this.draggingType;c&&this.addNode(c,t,o),this.draggingType=void 0}addNode(n,e=90+this.nodes.length*34,t=90+this.nodes.length*42){let o=this.makeNode(n,e,t);this.nodes=[...this.nodes,o],this.selectNode(o),this.refreshYaml()}selectNode(n){this.selectedNode=n}renameSelectedNode(n){if(!this.selectedNode)return;let e=y(n);if(!e)return;let t=this.selectedNode.id;if(t!==e){if(this.nodes.some(o=>o.id===e)){this.setStatus(`Node ID already exists: ${e}`,"error");return}this.selectedNode.id=e;for(let o of this.nodes)o.dependsOn=o.dependsOn.map(a=>a===t?e:a);this.refreshYaml()}}toggleDependency(n,e){if(!this.selectedNode)return;e.target.checked?this.selectedNode.dependsOn=[...new Set([...this.selectedNode.dependsOn,n])]:this.selectedNode.dependsOn=this.selectedNode.dependsOn.filter(o=>o!==n),this.refreshYaml()}deleteSelectedNode(){if(!this.selectedNode)return;let n=this.selectedNode.id;this.nodes=this.nodes.filter(e=>e.id!==n).map(e=>T(B({},e),{dependsOn:e.dependsOn.filter(t=>t!==n)})),this.selectedNode=this.nodes[0],this.refreshYaml()}loadWorkflow(n){this.api.getWorkflow(n).subscribe(e=>{let t=e.id.lastIndexOf("/");this.workflowFolder=t>=0?e.id.slice(0,t):"",this.workflowName=t>=0?e.id.slice(t+1):e.id,this.description=e.description||"Workflow loaded from disk",this.nodes=e.nodes.map((o,a)=>({id:o.id,type:o.type,title:o.id,content:o.content,dependsOn:o.dependsOn,provider:o.provider??"",model:o.model??"",x:80+a%3*250,y:80+Math.floor(a/3)*120})),this.selectedNode=this.nodes[0],this.setStatus(`Loaded ${e.name}`),this.refreshYaml()})}saveWorkflow(){this.saveCurrentWorkflow()}runWorkflow(){this.saveCurrentWorkflow(n=>{this.api.startRun(n,"").subscribe({next:e=>this.router.navigate(["/runs",e.runId]),error:e=>this.setStatus(e?.error?.error??e?.message??"Run failed","error")})})}refreshYaml(){this.yamlPreview=ye(this.workflowName,this.description,this.nodes),this.saveState==="saved"&&(this.saveState="idle")}get dependencyCandidates(){return this.selectedNode?this.nodes.filter(n=>n.id!==this.selectedNode.id):[]}get edges(){let n=new Map(this.nodes.map(t=>[t.id,t])),e=[];for(let t of this.nodes)for(let o of t.dependsOn){let a=n.get(o);a&&e.push({x1:a.x+190,y1:a.y+28,x2:t.x,y2:t.y+28})}return e}iconFor(n){switch(n){case"bash":return"$";case"command":return"/";case"prompt":return"AI"}}statusClass(n){switch(n){case"completed":return"status-completed";case"failed":return"status-failed";case"running":return"status-running";default:return"status-default"}}saveCurrentWorkflow(n){let e=y(this.workflowName),t=W(this.workflowFolder),o=t?`${t}/${e}`:e;if(!e||this.nodes.length===0){this.setStatus("Workflow name and at least one node are required.","error");return}this.workflowName=e,this.refreshYaml(),this.saveState="saving",this.api.saveWorkflow(o,this.yamlPreview).subscribe({next:()=>{this.saveState="saved",this.setStatus(`Saved ${o}`),this.refreshData(),n?.(o)},error:a=>{this.saveState="error",this.setStatus(a?.error?.error??a?.message??"Save failed","error")}})}makeNode(n,e,t,o=n){let a=ve(this.nodes.map(c=>c.id),`${n}-${o}`);return{id:a,type:n,title:a,content:Ce(n,a),dependsOn:[],provider:"",model:"",x:e,y:t}}setStatus(n,e="idle"){this.statusMessage=n,this.saveState=e}static \u0275fac=function(e){return new(e||l)};static \u0275cmp=V({type:l,selectors:[["app-workflow-builder"]],decls:63,vars:19,consts:[["noSelection",""],[1,"builder-shell"],[1,"sidebar"],[1,"brand-row"],[1,"brand-mark"],[1,"brand-title"],[1,"brand-subtitle"],["for","workflow-folder",1,"field-label"],["id","workflow-folder","placeholder","e.g. sdlc/release",1,"text-input",3,"ngModelChange","ngModel"],["for","workflow-name",1,"field-label"],["id","workflow-name",1,"text-input",3,"ngModelChange","ngModel"],["for","workflow-description",1,"field-label"],["id","workflow-description","rows","3",1,"text-area",3,"ngModelChange","ngModel"],[1,"section-title"],["type","button","class","palette-item","draggable","true",3,"dragstart","click",4,"ngFor","ngForOf"],["type","button","class","workflow-link",3,"click",4,"ngFor","ngForOf"],[1,"workspace"],[1,"toolbar"],[1,"toolbar-actions"],["type","button",1,"ghost-button",3,"click"],["type","button",1,"primary-button",3,"click","disabled"],["type","button",1,"run-button",3,"click","disabled"],["class","status-row",3,"error",4,"ngIf"],[1,"builder-grid"],[1,"canvas",3,"dragover","drop"],[1,"canvas-grid"],["class","empty-state",4,"ngIf"],["aria-hidden","true",1,"edges"],[4,"ngFor","ngForOf"],["type","button","class","node-card","draggable","true",3,"selected","left","top","click","dragstart",4,"ngFor","ngForOf"],[1,"inspector"],[4,"ngIf","ngIfElse"],[1,"bottom-grid"],[1,"yaml-panel"],[1,"panel-title"],[1,"yaml-editor",3,"ngModelChange","ngModel"],[1,"runs-panel"],["class","run-row",3,"routerLink",4,"ngFor","ngForOf"],["class","muted",4,"ngIf"],["type","button","draggable","true",1,"palette-item",3,"dragstart","click"],[1,"palette-icon"],["type","button",1,"workflow-link",3,"click"],[1,"status-row"],[1,"empty-state"],["type","button","draggable","true",1,"node-card",3,"click","dragstart"],[1,"node-kind"],[1,"node-copy"],["for","node-id",1,"field-label"],["id","node-id",1,"text-input",3,"ngModelChange","ngModel"],["for","node-type",1,"field-label"],["id","node-type",1,"text-input",3,"ngModelChange","ngModel"],["value","bash"],["value","command"],["value","prompt"],["for","node-content",1,"field-label"],["id","node-content","rows","7",1,"text-area","mono",3,"ngModelChange","ngModel"],["for","node-provider",1,"field-label"],["id","node-provider",1,"text-input",3,"ngModelChange","ngModel"],["value",""],[3,"value","disabled",4,"ngFor","ngForOf"],["for","node-model",1,"field-label"],["id","node-model","list","builder-model-suggestions","placeholder","(inherit)",1,"text-input",3,"ngModelChange","ngModel"],["id","builder-model-suggestions"],[3,"value",4,"ngFor","ngForOf"],[1,"field-label"],["class","check-row",4,"ngFor","ngForOf"],["type","button",1,"danger-button",3,"click"],[3,"value","disabled"],[3,"value"],[1,"check-row"],["type","checkbox",3,"change","checked"],[1,"muted"],[1,"run-row",3,"routerLink"]],template:function(e,t){if(e&1){let o=C();i(0,"section",1)(1,"aside",2)(2,"div",3)(3,"div",4),d(4,"V"),r(),i(5,"div")(6,"div",5),d(7,"VSAF Builder"),r(),i(8,"div",6),d(9,"Workflow canvas"),r()()(),i(10,"label",7),d(11,"Folder"),r(),i(12,"input",8),b("ngModelChange",function(c){return m(o),x(t.workflowFolder,c)||(t.workflowFolder=c),g(c)}),r(),i(13,"label",9),d(14,"Workflow name"),r(),i(15,"input",10),b("ngModelChange",function(c){return m(o),x(t.workflowName,c)||(t.workflowName=c),g(c)}),f("ngModelChange",function(){return t.refreshYaml()}),r(),i(16,"label",11),d(17,"Description"),r(),i(18,"textarea",12),b("ngModelChange",function(c){return m(o),x(t.description,c)||(t.description=c),g(c)}),f("ngModelChange",function(){return t.refreshYaml()}),r(),i(19,"div",13),d(20,"Node Palette"),r(),_(21,de,8,3,"button",14),i(22,"div",13),d(23,"Existing"),r(),_(24,se,5,2,"button",15),r(),i(25,"main",16)(26,"header",17)(27,"div")(28,"h1"),d(29),r(),i(30,"p"),d(31),r()(),i(32,"div",18)(33,"button",19),f("click",function(){return t.resetBuilder()}),d(34,"New"),r(),i(35,"button",19),f("click",function(){return t.refreshData()}),d(36,"Reload"),r(),i(37,"button",20),f("click",function(){return t.saveWorkflow()}),d(38),r(),i(39,"button",21),f("click",function(){return t.runWorkflow()}),d(40,"Run"),r()()(),_(41,ce,2,3,"div",22),i(42,"div",23)(43,"section",24),f("dragover",function(c){return t.onCanvasDragOver(c)})("drop",function(c){return t.onCanvasDrop(c)}),O(44,"div",25),_(45,pe,5,0,"div",26),S(),i(46,"svg",27),_(47,me,1,4,"line",28),r(),_(48,ge,8,10,"button",29),r(),I(),i(49,"aside",30),_(50,we,34,8,"ng-container",31)(51,he,4,0,"ng-template",null,0,A),r()(),i(53,"section",32)(54,"div",33)(55,"div",34),d(56,"Workflow YAML"),r(),i(57,"textarea",35),b("ngModelChange",function(c){return m(o),x(t.yamlPreview,c)||(t.yamlPreview=c),g(c)}),r()(),i(58,"div",36)(59,"div",34),d(60,"Recent Runs"),r(),_(61,xe,8,8,"a",37)(62,be,2,0,"p",38),r()()()()}if(e&2){let o=z(52);s(12),h("ngModel",t.workflowFolder),s(3),h("ngModel",t.workflowName),s(3),h("ngModel",t.description),s(3),u("ngForOf",t.palette),s(3),u("ngForOf",t.workflows),s(5),w(t.workflowId||"untitled-workflow"),s(2),v("",t.nodes.length," nodes \xB7 drag from palette or click a node to edit"),s(6),u("disabled",t.saveState==="saving"),s(),v(" ",t.saveState==="saving"?"Saving...":"Save Workflow"," "),s(),u("disabled",t.nodes.length===0),s(2),u("ngIf",t.statusMessage),s(4),u("ngIf",t.nodes.length===0),s(2),u("ngForOf",t.edges),s(),u("ngForOf",t.nodes),s(2),u("ngIf",t.selectedNode)("ngIfElse",o),s(7),h("ngModel",t.yamlPreview),s(4),u("ngForOf",t.runs),s(),u("ngIf",t.runs.length===0)}},dependencies:[G,j,q,ne,ee,te,U,Z,X,Q,K],styles:["[_nghost-%COMP%]{display:block;min-height:calc(100vh - 56px);background:#101114;color:#e7e7ea}button[_ngcontent-%COMP%], input[_ngcontent-%COMP%], textarea[_ngcontent-%COMP%], select[_ngcontent-%COMP%]{font:inherit}.builder-shell[_ngcontent-%COMP%]{display:grid;grid-template-columns:280px minmax(0,1fr);min-height:calc(100vh - 56px)}.sidebar[_ngcontent-%COMP%]{border-right:1px solid #2b2d33;background:#17181d;padding:16px;overflow:auto}.brand-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:10px;margin-bottom:22px}.brand-mark[_ngcontent-%COMP%]{display:grid;place-items:center;width:34px;height:34px;border-radius:8px;background:#6366f1;color:#fff;font-weight:700}.brand-title[_ngcontent-%COMP%]{font-size:15px;font-weight:700}.brand-subtitle[_ngcontent-%COMP%], .muted[_ngcontent-%COMP%], small[_ngcontent-%COMP%]{color:#9ca3af}.field-label[_ngcontent-%COMP%], .section-title[_ngcontent-%COMP%]{display:block;margin:14px 0 7px;color:#a1a1aa;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em}.text-input[_ngcontent-%COMP%], .text-area[_ngcontent-%COMP%]{width:100%;box-sizing:border-box;border:1px solid #333640;border-radius:7px;background:#101114;color:#f4f4f5;padding:9px 10px;outline:none}.text-input[_ngcontent-%COMP%]:focus, .text-area[_ngcontent-%COMP%]:focus, .yaml-editor[_ngcontent-%COMP%]:focus{border-color:#6366f1;box-shadow:0 0 0 2px #6366f12e}.text-area[_ngcontent-%COMP%]{resize:vertical}.mono[_ngcontent-%COMP%], .yaml-editor[_ngcontent-%COMP%]{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.palette-item[_ngcontent-%COMP%], .workflow-link[_ngcontent-%COMP%]{display:flex;align-items:center;gap:10px;width:100%;border:1px solid #2b2d33;border-radius:8px;background:#1f2128;color:#e7e7ea;padding:10px;margin-bottom:8px;text-align:left;cursor:grab}.palette-item[_ngcontent-%COMP%]:hover, .workflow-link[_ngcontent-%COMP%]:hover{border-color:#4f46e5;background:#242633}.palette-icon[_ngcontent-%COMP%]{display:grid;place-items:center;width:28px;height:28px;border-radius:7px;background:#111827;color:#a5b4fc}.palette-item[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .workflow-link[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{display:block;font-size:13px}.palette-item[_ngcontent-%COMP%] small[_ngcontent-%COMP%], .workflow-link[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{display:block;font-size:11px;margin-top:2px}.workflow-link[_ngcontent-%COMP%]{justify-content:space-between;cursor:pointer}.workspace[_ngcontent-%COMP%]{min-width:0;padding:18px;overflow:auto}.toolbar[_ngcontent-%COMP%]{display:flex;justify-content:space-between;gap:16px;align-items:center;margin-bottom:12px}.toolbar[_ngcontent-%COMP%] h1[_ngcontent-%COMP%]{margin:0;font-size:20px}.toolbar[_ngcontent-%COMP%] p[_ngcontent-%COMP%]{margin:4px 0 0;color:#9ca3af;font-size:13px}.toolbar-actions[_ngcontent-%COMP%]{display:flex;gap:8px;flex-wrap:wrap}.ghost-button[_ngcontent-%COMP%], .primary-button[_ngcontent-%COMP%], .run-button[_ngcontent-%COMP%], .danger-button[_ngcontent-%COMP%]{border:1px solid #333640;border-radius:7px;padding:8px 12px;color:#f4f4f5;background:#20222a;cursor:pointer}.primary-button[_ngcontent-%COMP%]{background:#4f46e5;border-color:#4f46e5}.run-button[_ngcontent-%COMP%]{background:#059669;border-color:#059669}.danger-button[_ngcontent-%COMP%]{width:100%;margin-top:14px;background:#3f1d24;border-color:#7f1d1d;color:#fecaca}.primary-button[_ngcontent-%COMP%]:disabled, .run-button[_ngcontent-%COMP%]:disabled{opacity:.55;cursor:not-allowed}.status-row[_ngcontent-%COMP%]{border:1px solid #1f5f45;border-radius:8px;background:#092d22;color:#a7f3d0;padding:10px 12px;margin-bottom:12px;font-size:13px}.status-row.error[_ngcontent-%COMP%]{border-color:#7f1d1d;background:#2a1217;color:#fecaca}.builder-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:minmax(520px,1fr) 320px;gap:14px;min-height:470px}.canvas[_ngcontent-%COMP%]{position:relative;overflow:hidden;min-height:470px;border:1px solid #2b2d33;border-radius:8px;background:#15161b}.canvas-grid[_ngcontent-%COMP%]{position:absolute;inset:0;background-image:linear-gradient(#24262e 1px,transparent 1px),linear-gradient(90deg,#24262e 1px,transparent 1px);background-size:28px 28px;opacity:.45}.empty-state[_ngcontent-%COMP%]{position:absolute;inset:0;display:grid;place-content:center;text-align:center;color:#9ca3af;pointer-events:none}.empty-state[_ngcontent-%COMP%] h2[_ngcontent-%COMP%]{margin:0 0 6px;color:#e7e7ea}.edges[_ngcontent-%COMP%]{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}.edges[_ngcontent-%COMP%] line[_ngcontent-%COMP%]{stroke:#6366f1;stroke-width:2;stroke-dasharray:5 5;opacity:.8}.node-card[_ngcontent-%COMP%]{position:absolute;z-index:2;display:flex;align-items:center;gap:10px;width:190px;border:1px solid #3f4250;border-radius:8px;background:#20222a;color:#f4f4f5;padding:11px;cursor:move;text-align:left;box-shadow:0 12px 28px #00000038}.node-card.selected[_ngcontent-%COMP%]{border-color:#818cf8;box-shadow:0 0 0 2px #6366f147,0 12px 28px #00000038}.node-kind[_ngcontent-%COMP%]{display:grid;place-items:center;width:30px;height:30px;border-radius:7px;background:#111827;color:#a5b4fc}.node-copy[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .node-copy[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.node-copy[_ngcontent-%COMP%]{min-width:0}.inspector[_ngcontent-%COMP%], .yaml-panel[_ngcontent-%COMP%], .runs-panel[_ngcontent-%COMP%]{border:1px solid #2b2d33;border-radius:8px;background:#17181d;padding:14px}.panel-title[_ngcontent-%COMP%]{margin-bottom:12px;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:#d4d4d8}.check-row[_ngcontent-%COMP%]{display:flex;align-items:center;gap:8px;margin:8px 0;color:#d4d4d8;font-size:13px}.bottom-grid[_ngcontent-%COMP%]{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:14px;margin-top:14px}.yaml-editor[_ngcontent-%COMP%]{width:100%;min-height:260px;box-sizing:border-box;border:1px solid #333640;border-radius:7px;background:#0f1014;color:#d4d4d8;padding:12px;resize:vertical}.run-row[_ngcontent-%COMP%]{display:flex;justify-content:space-between;gap:12px;padding:10px 0;color:#e7e7ea;text-decoration:none;border-bottom:1px solid #252730}.run-row[_ngcontent-%COMP%] strong[_ngcontent-%COMP%], .run-row[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{display:block}.run-row[_ngcontent-%COMP%] small[_ngcontent-%COMP%]{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px}.status-completed[_ngcontent-%COMP%]{color:#34d399}.status-failed[_ngcontent-%COMP%]{color:#f87171}.status-running[_ngcontent-%COMP%]{color:#60a5fa}.status-default[_ngcontent-%COMP%]{color:#a1a1aa}@media(max-width:980px){.builder-shell[_ngcontent-%COMP%], .builder-grid[_ngcontent-%COMP%], .bottom-grid[_ngcontent-%COMP%]{grid-template-columns:1fr}.sidebar[_ngcontent-%COMP%]{border-right:0;border-bottom:1px solid #2b2d33}.toolbar[_ngcontent-%COMP%]{align-items:flex-start;flex-direction:column}}"]})};function Ce(l,n){switch(l){case"bash":return`echo "${n}"`;case"command":return n;case"prompt":return`Complete ${n} and summarize the result.`}}var re="claude";function ye(l,n,e){let t=[`name: ${y(l)||"new-workflow"}`,`description: ${E(n||"Draft workflow")}`,`provider: ${re}`,"model: sonnet","nodes:"];for(let o of e)if(t.push(` - id: ${o.id}`),o.dependsOn.length>0&&t.push(` depends_on: [${o.dependsOn.join(", ")}]`),o.provider&&t.push(` provider: ${o.provider}`),o.model&&t.push(` model: ${o.model}`),o.type==="bash")t.push(` bash: ${E(o.content||"echo ok")}`);else if(o.type==="command")t.push(` command: ${E(o.content||o.id)}`);else{t.push(" prompt: |");for(let a of(o.content||`Complete ${o.id}`).split(`
2
+ `))t.push(` ${a}`)}return`${t.join(`
3
+ `)}
4
+ `}function y(l){return l.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function W(l){return l.split("/").map(y).filter(Boolean).join("/")}function ve(l,n){let e=y(n)||"node";if(!l.includes(e))return e;let t=2;for(;l.includes(`${e}-${t}`);)t++;return`${e}-${t}`}function E(l){return JSON.stringify(l)}export{ie as WorkflowBuilderComponent};