@vibe-forge/client 0.8.3 → 0.9.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 (59) hide show
  1. package/dist/assets/{arc-CZwEW7WR.js → arc-D9HxM0yv.js} +1 -1
  2. package/dist/assets/{blockDiagram-c4efeb88--ejJ1hay.js → blockDiagram-c4efeb88-C_pTeiD4.js} +1 -1
  3. package/dist/assets/{c4Diagram-c83219d4-D0N419di.js → c4Diagram-c83219d4-_oYrCrLr.js} +1 -1
  4. package/dist/assets/channel-Di8KkPU4.js +1 -0
  5. package/dist/assets/{classDiagram-beda092f-BRVsm_of.js → classDiagram-beda092f-9dnkgPhR.js} +1 -1
  6. package/dist/assets/{classDiagram-v2-2358418a-OShdAlFU.js → classDiagram-v2-2358418a-BUIeZpdO.js} +1 -1
  7. package/dist/assets/clone-B065n6L-.js +1 -0
  8. package/dist/assets/{createText-1719965b-psgY2hME.js → createText-1719965b-DuRFplcD.js} +1 -1
  9. package/dist/assets/{edges-96097737-BA56Qmd2.js → edges-96097737-CTpq6Ih_.js} +1 -1
  10. package/dist/assets/{erDiagram-0228fc6a-Dyrrgc5j.js → erDiagram-0228fc6a-CWFgdO1E.js} +1 -1
  11. package/dist/assets/{flowDb-c6c81e3f-CRgQ7Xd3.js → flowDb-c6c81e3f-8Vdx29oZ.js} +1 -1
  12. package/dist/assets/{flowDiagram-50d868cf-B73a9Glk.js → flowDiagram-50d868cf-6S9wOVNl.js} +1 -1
  13. package/dist/assets/flowDiagram-v2-4f6560a1-nj-oVLPK.js +1 -0
  14. package/dist/assets/{flowchart-elk-definition-6af322e1-DtsYC0Wf.js → flowchart-elk-definition-6af322e1-DVcZ-ZBQ.js} +1 -1
  15. package/dist/assets/{ganttDiagram-a2739b55-gzdnsQCV.js → ganttDiagram-a2739b55-DY1QSl-x.js} +1 -1
  16. package/dist/assets/{gitGraphDiagram-82fe8481-RHa92Mol.js → gitGraphDiagram-82fe8481-BP08OBKL.js} +1 -1
  17. package/dist/assets/{graph-Uj8iC7DB.js → graph-D8GCszcN.js} +1 -1
  18. package/dist/assets/{index-5325376f-B2Q_MiDU.js → index-5325376f-OOoAXU1u.js} +1 -1
  19. package/dist/assets/{index-DGEAe87I.css → index-BZe1Qtye.css} +1 -1
  20. package/dist/assets/{index-ADFje5Kc.js → index-DV3eI2aD.js} +77 -77
  21. package/dist/assets/{infoDiagram-8eee0895-BIrv_GjX.js → infoDiagram-8eee0895-BHgkXjhJ.js} +1 -1
  22. package/dist/assets/{journeyDiagram-c64418c1-DMZd-Mfh.js → journeyDiagram-c64418c1-BljInElp.js} +1 -1
  23. package/dist/assets/{layout-Bwa2VjOX.js → layout-Cw-SwAFD.js} +1 -1
  24. package/dist/assets/{line-BDn4wwV7.js → line-Q-uZLuUr.js} +1 -1
  25. package/dist/assets/{linear-DQPiAjW8.js → linear-BahOnNn3.js} +1 -1
  26. package/dist/assets/{mermaid.core-B5GfAmDT.js → mermaid.core-BR0Qh3Rd.js} +4 -4
  27. package/dist/assets/{mindmap-definition-8da855dc-BTOOR2ac.js → mindmap-definition-8da855dc-Brq2OJUZ.js} +1 -1
  28. package/dist/assets/{pieDiagram-a8764435-C3QNifd4.js → pieDiagram-a8764435-uhYdiXro.js} +1 -1
  29. package/dist/assets/{quadrantDiagram-1e28029f-Ds5ATncA.js → quadrantDiagram-1e28029f-TwqtEe7e.js} +1 -1
  30. package/dist/assets/{requirementDiagram-08caed73-CVdpqqVi.js → requirementDiagram-08caed73-DSXnPRDS.js} +1 -1
  31. package/dist/assets/{sankeyDiagram-a04cb91d-CxP85079.js → sankeyDiagram-a04cb91d-EADpJeAn.js} +1 -1
  32. package/dist/assets/{sequenceDiagram-c5b8d532-BeaQEYgt.js → sequenceDiagram-c5b8d532-C8qXvt9z.js} +1 -1
  33. package/dist/assets/{stateDiagram-1ecb1508-Bv-YlfIf.js → stateDiagram-1ecb1508-5W0ghy_S.js} +1 -1
  34. package/dist/assets/{stateDiagram-v2-c2b004d7-CWKsGrvN.js → stateDiagram-v2-c2b004d7-BfwOQJw4.js} +1 -1
  35. package/dist/assets/{styles-b4e223ce-DzdnfR-A.js → styles-b4e223ce-EkKH_ULb.js} +1 -1
  36. package/dist/assets/{styles-ca3715f6-BS5E4Xdv.js → styles-ca3715f6-DwhrtqlU.js} +1 -1
  37. package/dist/assets/{styles-d45a18b0-t7c5i-_-.js → styles-d45a18b0-yqL8KH6x.js} +1 -1
  38. package/dist/assets/{svgDrawCommon-b86b1483-CyA-VVES.js → svgDrawCommon-b86b1483--5VjnjhC.js} +1 -1
  39. package/dist/assets/{timeline-definition-faaaa080-BuFEjpzk.js → timeline-definition-faaaa080-CWOTwik9.js} +1 -1
  40. package/dist/assets/{xychartDiagram-f5964ef8-B4b4QqYX.js → xychartDiagram-f5964ef8-CZg47H1t.js} +1 -1
  41. package/dist/favicon.svg +5 -0
  42. package/dist/index.html +3 -2
  43. package/index.html +2 -1
  44. package/package.json +10 -10
  45. package/public/favicon.svg +5 -0
  46. package/src/components/chat/sender/Sender.scss +140 -0
  47. package/src/components/chat/sender/Sender.tsx +75 -33
  48. package/src/components/chat/sender/interaction-request.ts +5 -0
  49. package/src/components/config/ConfigSectionForm.tsx +0 -1
  50. package/src/components/config/configSchema.ts +2 -23
  51. package/src/hooks/chat/interaction-state.ts +37 -0
  52. package/src/hooks/chat/use-chat-session-messages.ts +11 -4
  53. package/src/hooks/use-session-subscription.ts +31 -8
  54. package/src/resources/locales/en.json +11 -0
  55. package/src/resources/locales/zh.json +11 -0
  56. package/src/runtime-config.ts +18 -9
  57. package/dist/assets/channel-dXWmEygA.js +0 -1
  58. package/dist/assets/clone-C4IafnWc.js +0 -1
  59. package/dist/assets/flowDiagram-v2-4f6560a1-Ccm4QuQe.js +0 -1
@@ -1,4 +1,4 @@
1
- import{s as zt,a as Ft,v as wt,x as Nt,b as Xt,c as Yt,l as St,aH as Ht,e as $t,z as Ut,ap as ot,aJ as Ct,aL as qt,aY as jt,i as Gt}from"./mermaid.core-B5GfAmDT.js";import{a as Qt}from"./createText-1719965b-psgY2hME.js";import"./index-ADFje5Kc.js";import{i as Kt}from"./init-Gi6I4Gst.js";import{o as Jt}from"./ordinal-Cboi1Yqb.js";import{l as ft}from"./linear-DQPiAjW8.js";import{l as pt}from"./line-BDn4wwV7.js";import"./array-BKyUJesY.js";import"./path-CbwjOpE9.js";function Zt(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function st(){var e=Jt().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,c,f=!1,d=0,R=0,_=.5;delete e.unknown;function A(){var m=t().length,T=n<s,S=T?n:s,P=T?s:n;o=(P-S)/Math.max(1,m-d+R*2),f&&(o=Math.floor(o)),S+=(P-S-o*(m-d))*_,c=o*(1-d),f&&(S=Math.round(S),c=Math.round(c));var p=Zt(m).map(function(C){return S+o*C});return i(T?p.reverse():p)}return e.domain=function(m){return arguments.length?(t(m),A()):t()},e.range=function(m){return arguments.length?([s,n]=m,s=+s,n=+n,A()):[s,n]},e.rangeRound=function(m){return[s,n]=m,s=+s,n=+n,f=!0,A()},e.bandwidth=function(){return c},e.step=function(){return o},e.round=function(m){return arguments.length?(f=!!m,A()):f},e.padding=function(m){return arguments.length?(d=Math.min(1,R=+m),A()):d},e.paddingInner=function(m){return arguments.length?(d=Math.min(1,m),A()):d},e.paddingOuter=function(m){return arguments.length?(R=+m,A()):R},e.align=function(m){return arguments.length?(_=Math.max(0,Math.min(1,m)),A()):_},e.copy=function(){return st(t(),[s,n]).round(f).paddingInner(d).paddingOuter(R).align(_)},Kt.apply(A(),arguments)}var nt=function(){var e=function(V,r,l,u){for(l=l||{},u=V.length;u--;l[V[u]]=r);return l},t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],c=[1,7],f=[1,5,10,12,14,16,18,19,21,23,34,35,36],d=[1,25],R=[1,26],_=[1,28],A=[1,29],m=[1,30],T=[1,31],S=[1,32],P=[1,33],p=[1,34],C=[1,35],h=[1,36],L=[1,37],z=[1,43],lt=[1,42],ct=[1,47],$=[1,50],w=[1,10,12,14,16,18,19,21,23,34,35,36],Q=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],v=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],ut=[1,64],K={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:function(r,l,u,g,b,a,F){var x=a.length-1;switch(b){case 5:g.setOrientation(a[x]);break;case 9:g.setDiagramTitle(a[x].text.trim());break;case 12:g.setLineData({text:"",type:"text"},a[x]);break;case 13:g.setLineData(a[x-1],a[x]);break;case 14:g.setBarData({text:"",type:"text"},a[x]);break;case 15:g.setBarData(a[x-1],a[x]);break;case 16:this.$=a[x].trim(),g.setAccTitle(this.$);break;case 17:case 18:this.$=a[x].trim(),g.setAccDescription(this.$);break;case 19:this.$=a[x-1];break;case 20:this.$=[Number(a[x-2]),...a[x]];break;case 21:this.$=[Number(a[x])];break;case 22:g.setXAxisTitle(a[x]);break;case 23:g.setXAxisTitle(a[x-1]);break;case 24:g.setXAxisTitle({type:"text",text:""});break;case 25:g.setXAxisBand(a[x]);break;case 26:g.setXAxisRangeData(Number(a[x-2]),Number(a[x]));break;case 27:this.$=a[x-1];break;case 28:this.$=[a[x-2],...a[x]];break;case 29:this.$=[a[x]];break;case 30:g.setYAxisTitle(a[x]);break;case 31:g.setYAxisTitle(a[x-1]);break;case 32:g.setYAxisTitle({type:"text",text:""});break;case 33:g.setYAxisRangeData(Number(a[x-2]),Number(a[x]));break;case 37:this.$={text:a[x],type:"text"};break;case 38:this.$={text:a[x],type:"text"};break;case 39:this.$={text:a[x],type:"markdown"};break;case 40:this.$=a[x];break;case 41:this.$=a[x-1]+""+a[x];break}},table:[e(t,i,{3:1,4:2,7:4,5:s,34:n,35:o,36:c}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,34:n,35:o,36:c}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:o,36:c}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(f,[2,34]),e(f,[2,35]),e(f,[2,36]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,34:n,35:o,36:c}),{1:[2,3]},e(f,[2,5]),e(t,[2,7],{4:22,34:n,35:o,36:c}),{11:23,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:39,13:38,24:z,27:lt,29:40,30:41,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:45,15:44,27:ct,33:46,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:49,17:48,24:$,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:52,17:51,24:$,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{20:[1,53]},{22:[1,54]},e(w,[2,18]),{1:[2,2]},e(w,[2,8]),e(w,[2,9]),e(Q,[2,37],{40:55,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L}),e(Q,[2,38]),e(Q,[2,39]),e(v,[2,40]),e(v,[2,42]),e(v,[2,43]),e(v,[2,44]),e(v,[2,45]),e(v,[2,46]),e(v,[2,47]),e(v,[2,48]),e(v,[2,49]),e(v,[2,50]),e(v,[2,51]),e(w,[2,10]),e(w,[2,22],{30:41,29:56,24:z,27:lt}),e(w,[2,24]),e(w,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},e(w,[2,11]),e(w,[2,30],{33:60,27:ct}),e(w,[2,32]),{31:[1,61]},e(w,[2,12]),{17:62,24:$},{25:63,27:ut},e(w,[2,14]),{17:65,24:$},e(w,[2,16]),e(w,[2,17]),e(v,[2,41]),e(w,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},e(w,[2,31]),{27:[1,69]},e(w,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},e(w,[2,15]),e(w,[2,26]),e(w,[2,27]),{11:59,32:72,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},e(w,[2,33]),e(w,[2,19]),{25:73,27:ut},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(r,l){if(l.recoverable)this.trace(r);else{var u=new Error(r);throw u.hash=l,u}},parse:function(r){var l=this,u=[0],g=[],b=[null],a=[],F=this.table,x="",U=0,gt=0,Vt=2,xt=1,Bt=a.slice.call(arguments,1),k=Object.create(this.lexer),B={yy:{}};for(var Z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Z)&&(B.yy[Z]=this.yy[Z]);k.setInput(r,B.yy),B.yy.lexer=k,B.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var tt=k.yylloc;a.push(tt);var Wt=k.options&&k.options.ranges;typeof B.yy.parseError=="function"?this.parseError=B.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ot(){var I;return I=g.pop()||k.lex()||xt,typeof I!="number"&&(I instanceof Array&&(g=I,I=g.pop()),I=l.symbols_[I]||I),I}for(var D,W,E,it,O={},q,M,dt,j;;){if(W=u[u.length-1],this.defaultActions[W]?E=this.defaultActions[W]:((D===null||typeof D>"u")&&(D=Ot()),E=F[W]&&F[W][D]),typeof E>"u"||!E.length||!E[0]){var et="";j=[];for(q in F[W])this.terminals_[q]&&q>Vt&&j.push("'"+this.terminals_[q]+"'");k.showPosition?et="Parse error on line "+(U+1)+`:
1
+ import{s as zt,a as Ft,v as wt,x as Nt,b as Xt,c as Yt,l as St,aH as Ht,e as $t,z as Ut,ap as ot,aJ as Ct,aL as qt,aY as jt,i as Gt}from"./mermaid.core-BR0Qh3Rd.js";import{a as Qt}from"./createText-1719965b-DuRFplcD.js";import"./index-DV3eI2aD.js";import{i as Kt}from"./init-Gi6I4Gst.js";import{o as Jt}from"./ordinal-Cboi1Yqb.js";import{l as ft}from"./linear-BahOnNn3.js";import{l as pt}from"./line-Q-uZLuUr.js";import"./array-BKyUJesY.js";import"./path-CbwjOpE9.js";function Zt(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function st(){var e=Jt().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,c,f=!1,d=0,R=0,_=.5;delete e.unknown;function A(){var m=t().length,T=n<s,S=T?n:s,P=T?s:n;o=(P-S)/Math.max(1,m-d+R*2),f&&(o=Math.floor(o)),S+=(P-S-o*(m-d))*_,c=o*(1-d),f&&(S=Math.round(S),c=Math.round(c));var p=Zt(m).map(function(C){return S+o*C});return i(T?p.reverse():p)}return e.domain=function(m){return arguments.length?(t(m),A()):t()},e.range=function(m){return arguments.length?([s,n]=m,s=+s,n=+n,A()):[s,n]},e.rangeRound=function(m){return[s,n]=m,s=+s,n=+n,f=!0,A()},e.bandwidth=function(){return c},e.step=function(){return o},e.round=function(m){return arguments.length?(f=!!m,A()):f},e.padding=function(m){return arguments.length?(d=Math.min(1,R=+m),A()):d},e.paddingInner=function(m){return arguments.length?(d=Math.min(1,m),A()):d},e.paddingOuter=function(m){return arguments.length?(R=+m,A()):R},e.align=function(m){return arguments.length?(_=Math.max(0,Math.min(1,m)),A()):_},e.copy=function(){return st(t(),[s,n]).round(f).paddingInner(d).paddingOuter(R).align(_)},Kt.apply(A(),arguments)}var nt=function(){var e=function(V,r,l,u){for(l=l||{},u=V.length;u--;l[V[u]]=r);return l},t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],c=[1,7],f=[1,5,10,12,14,16,18,19,21,23,34,35,36],d=[1,25],R=[1,26],_=[1,28],A=[1,29],m=[1,30],T=[1,31],S=[1,32],P=[1,33],p=[1,34],C=[1,35],h=[1,36],L=[1,37],z=[1,43],lt=[1,42],ct=[1,47],$=[1,50],w=[1,10,12,14,16,18,19,21,23,34,35,36],Q=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],v=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],ut=[1,64],K={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:function(r,l,u,g,b,a,F){var x=a.length-1;switch(b){case 5:g.setOrientation(a[x]);break;case 9:g.setDiagramTitle(a[x].text.trim());break;case 12:g.setLineData({text:"",type:"text"},a[x]);break;case 13:g.setLineData(a[x-1],a[x]);break;case 14:g.setBarData({text:"",type:"text"},a[x]);break;case 15:g.setBarData(a[x-1],a[x]);break;case 16:this.$=a[x].trim(),g.setAccTitle(this.$);break;case 17:case 18:this.$=a[x].trim(),g.setAccDescription(this.$);break;case 19:this.$=a[x-1];break;case 20:this.$=[Number(a[x-2]),...a[x]];break;case 21:this.$=[Number(a[x])];break;case 22:g.setXAxisTitle(a[x]);break;case 23:g.setXAxisTitle(a[x-1]);break;case 24:g.setXAxisTitle({type:"text",text:""});break;case 25:g.setXAxisBand(a[x]);break;case 26:g.setXAxisRangeData(Number(a[x-2]),Number(a[x]));break;case 27:this.$=a[x-1];break;case 28:this.$=[a[x-2],...a[x]];break;case 29:this.$=[a[x]];break;case 30:g.setYAxisTitle(a[x]);break;case 31:g.setYAxisTitle(a[x-1]);break;case 32:g.setYAxisTitle({type:"text",text:""});break;case 33:g.setYAxisRangeData(Number(a[x-2]),Number(a[x]));break;case 37:this.$={text:a[x],type:"text"};break;case 38:this.$={text:a[x],type:"text"};break;case 39:this.$={text:a[x],type:"markdown"};break;case 40:this.$=a[x];break;case 41:this.$=a[x-1]+""+a[x];break}},table:[e(t,i,{3:1,4:2,7:4,5:s,34:n,35:o,36:c}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,34:n,35:o,36:c}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:o,36:c}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(f,[2,34]),e(f,[2,35]),e(f,[2,36]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,34:n,35:o,36:c}),{1:[2,3]},e(f,[2,5]),e(t,[2,7],{4:22,34:n,35:o,36:c}),{11:23,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:39,13:38,24:z,27:lt,29:40,30:41,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:45,15:44,27:ct,33:46,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:49,17:48,24:$,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{11:52,17:51,24:$,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},{20:[1,53]},{22:[1,54]},e(w,[2,18]),{1:[2,2]},e(w,[2,8]),e(w,[2,9]),e(Q,[2,37],{40:55,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L}),e(Q,[2,38]),e(Q,[2,39]),e(v,[2,40]),e(v,[2,42]),e(v,[2,43]),e(v,[2,44]),e(v,[2,45]),e(v,[2,46]),e(v,[2,47]),e(v,[2,48]),e(v,[2,49]),e(v,[2,50]),e(v,[2,51]),e(w,[2,10]),e(w,[2,22],{30:41,29:56,24:z,27:lt}),e(w,[2,24]),e(w,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},e(w,[2,11]),e(w,[2,30],{33:60,27:ct}),e(w,[2,32]),{31:[1,61]},e(w,[2,12]),{17:62,24:$},{25:63,27:ut},e(w,[2,14]),{17:65,24:$},e(w,[2,16]),e(w,[2,17]),e(v,[2,41]),e(w,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},e(w,[2,31]),{27:[1,69]},e(w,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},e(w,[2,15]),e(w,[2,26]),e(w,[2,27]),{11:59,32:72,37:24,38:d,39:R,40:27,41:_,42:A,43:m,44:T,45:S,46:P,47:p,48:C,49:h,50:L},e(w,[2,33]),e(w,[2,19]),{25:73,27:ut},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(r,l){if(l.recoverable)this.trace(r);else{var u=new Error(r);throw u.hash=l,u}},parse:function(r){var l=this,u=[0],g=[],b=[null],a=[],F=this.table,x="",U=0,gt=0,Vt=2,xt=1,Bt=a.slice.call(arguments,1),k=Object.create(this.lexer),B={yy:{}};for(var Z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Z)&&(B.yy[Z]=this.yy[Z]);k.setInput(r,B.yy),B.yy.lexer=k,B.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var tt=k.yylloc;a.push(tt);var Wt=k.options&&k.options.ranges;typeof B.yy.parseError=="function"?this.parseError=B.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ot(){var I;return I=g.pop()||k.lex()||xt,typeof I!="number"&&(I instanceof Array&&(g=I,I=g.pop()),I=l.symbols_[I]||I),I}for(var D,W,E,it,O={},q,M,dt,j;;){if(W=u[u.length-1],this.defaultActions[W]?E=this.defaultActions[W]:((D===null||typeof D>"u")&&(D=Ot()),E=F[W]&&F[W][D]),typeof E>"u"||!E.length||!E[0]){var et="";j=[];for(q in F[W])this.terminals_[q]&&q>Vt&&j.push("'"+this.terminals_[q]+"'");k.showPosition?et="Parse error on line "+(U+1)+`:
2
2
  `+k.showPosition()+`
3
3
  Expecting `+j.join(", ")+", got '"+(this.terminals_[D]||D)+"'":et="Parse error on line "+(U+1)+": Unexpected "+(D==xt?"end of input":"'"+(this.terminals_[D]||D)+"'"),this.parseError(et,{text:k.match,token:this.terminals_[D]||D,line:k.yylineno,loc:tt,expected:j})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+W+", token: "+D);switch(E[0]){case 1:u.push(D),b.push(k.yytext),a.push(k.yylloc),u.push(E[1]),D=null,gt=k.yyleng,x=k.yytext,U=k.yylineno,tt=k.yylloc;break;case 2:if(M=this.productions_[E[1]][1],O.$=b[b.length-M],O._$={first_line:a[a.length-(M||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(M||1)].first_column,last_column:a[a.length-1].last_column},Wt&&(O._$.range=[a[a.length-(M||1)].range[0],a[a.length-1].range[1]]),it=this.performAction.apply(O,[x,gt,U,B.yy,E[1],b,a].concat(Bt)),typeof it<"u")return it;M&&(u=u.slice(0,-1*M*2),b=b.slice(0,-1*M),a=a.slice(0,-1*M)),u.push(this.productions_[E[1]][0]),b.push(O.$),a.push(O._$),dt=F[u[u.length-2]][u[u.length-1]],u.push(dt);break;case 3:return!0}}return!0}},It=function(){var V={EOF:1,parseError:function(l,u){if(this.yy.parser)this.yy.parser.parseError(l,u);else throw new Error(l)},setInput:function(r,l){return this.yy=l||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var l=r.match(/(?:\r\n?|\n).*/g);return l?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},unput:function(r){var l=r.length,u=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-l),this.offset-=l;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),u.length-1&&(this.yylineno-=u.length-1);var b=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:u?(u.length===g.length?this.yylloc.first_column:0)+g[g.length-u.length].length-u[0].length:this.yylloc.first_column-l},this.options.ranges&&(this.yylloc.range=[b[0],b[0]+this.yyleng-l]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
4
4
  `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(r){this.unput(this.match.slice(r))},pastInput:function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var r=this.pastInput(),l=new Array(r.length+1).join("-");return r+this.upcomingInput()+`
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="16" fill="#111827"/>
3
+ <path d="M18 18h28v8H27v10h16v8H27v14h-9V18Z" fill="#f8fafc"/>
4
+ <path d="M38 18h8L34 58h-8l12-40Z" fill="#60a5fa"/>
5
+ </svg>
package/dist/index.html CHANGED
@@ -3,9 +3,10 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" href="./favicon.svg" type="image/svg+xml" />
6
7
  <title>Vibe Forge Web</title>
7
- <script type="module" crossorigin src="/__VF_PROJECT_AI_CLIENT_BASE__/assets/index-ADFje5Kc.js"></script>
8
- <link rel="stylesheet" crossorigin href="/__VF_PROJECT_AI_CLIENT_BASE__/assets/index-DGEAe87I.css">
8
+ <script type="module" crossorigin src="/__VF_PROJECT_AI_CLIENT_BASE__/assets/index-DV3eI2aD.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/__VF_PROJECT_AI_CLIENT_BASE__/assets/index-BZe1Qtye.css">
9
10
  </head>
10
11
  <body>
11
12
  <div id="root"></div>
package/index.html CHANGED
@@ -3,10 +3,11 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" href="./favicon.svg" type="image/svg+xml" />
6
7
  <title>Vibe Forge Web</title>
7
8
  </head>
8
9
  <body>
9
10
  <div id="root"></div>
10
- <script type="module" src="/src/main.tsx"></script>
11
+ <script type="module" src="./src/main.tsx"></script>
11
12
  </body>
12
13
  </html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vibe-forge/client",
3
3
  "type": "module",
4
- "version": "0.8.3",
4
+ "version": "0.9.0",
5
5
  "imports": {
6
6
  "#~/*": [
7
7
  "./src/*",
@@ -36,15 +36,15 @@
36
36
  "swr": "^2.2.5",
37
37
  "vite": "^5.4.8",
38
38
  "zod": "^3.24.1",
39
- "@vibe-forge/channel-lark": "^0.8.0",
40
- "@vibe-forge/core": "^0.8.3",
41
- "@vibe-forge/adapter-codex": "^0.8.3",
42
- "@vibe-forge/adapter-claude-code": "^0.8.3",
43
- "@vibe-forge/plugin-chrome-devtools": "^0.8.0",
44
- "@vibe-forge/adapter-opencode": "^0.8.3",
45
- "@vibe-forge/register": "^0.8.0",
46
- "@vibe-forge/utils": "^0.8.3",
47
- "@vibe-forge/types": "^0.8.3"
39
+ "@vibe-forge/channel-lark": "^0.9.0",
40
+ "@vibe-forge/core": "^0.9.0",
41
+ "@vibe-forge/adapter-claude-code": "^0.9.0",
42
+ "@vibe-forge/adapter-codex": "^0.9.0",
43
+ "@vibe-forge/adapter-opencode": "^0.9.0",
44
+ "@vibe-forge/plugin-chrome-devtools": "^0.9.0",
45
+ "@vibe-forge/types": "^0.9.0",
46
+ "@vibe-forge/utils": "^0.9.0",
47
+ "@vibe-forge/register": "^0.9.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/react": "^18.3.12",
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="16" fill="#111827"/>
3
+ <path d="M18 18h28v8H27v10h16v8H27v14h-9V18Z" fill="#f8fafc"/>
4
+ <path d="M38 18h8L34 58h-8l12-40Z" fill="#60a5fa"/>
5
+ </svg>
@@ -4,6 +4,140 @@
4
4
  background-color: var(--bg-color);
5
5
  }
6
6
 
7
+ .chat-input-wrapper--permission {
8
+ .interaction-panel {
9
+ max-height: none;
10
+ overflow-y: visible;
11
+ margin-bottom: 0;
12
+ }
13
+ }
14
+
15
+ .interaction-panel {
16
+ display: flex;
17
+ flex-direction: column;
18
+ max-height: 260px;
19
+ overflow-y: auto;
20
+ margin-bottom: 10px;
21
+ gap: 10px;
22
+ padding: 10px;
23
+ border: 1px solid rgba(217, 119, 6, .18);
24
+ border-radius: 12px;
25
+ background:
26
+ linear-gradient(180deg, rgba(255, 251, 235, .9), rgba(255, 255, 255, .96));
27
+
28
+ &__badge {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ gap: 6px;
32
+ align-self: flex-start;
33
+ padding: 4px 10px;
34
+ border-radius: 999px;
35
+ background: rgba(245, 158, 11, .12);
36
+ color: #b45309;
37
+ font-size: 12px;
38
+ font-weight: 600;
39
+
40
+ .material-symbols-rounded {
41
+ font-size: 14px;
42
+ }
43
+ }
44
+
45
+ &__context {
46
+ display: flex;
47
+ flex-direction: column;
48
+ gap: 8px;
49
+ padding: 10px;
50
+ border-radius: 10px;
51
+ background: rgba(255, 255, 255, .72);
52
+ border: 1px solid rgba(217, 119, 6, .12);
53
+ }
54
+
55
+ &__meta {
56
+ display: grid;
57
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
58
+ gap: 8px;
59
+ }
60
+
61
+ &__meta-item {
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 4px;
65
+
66
+ code {
67
+ width: fit-content;
68
+ max-width: 100%;
69
+ padding: 2px 8px;
70
+ border-radius: 999px;
71
+ background: rgba(15, 23, 42, .06);
72
+ color: var(--text-color);
73
+ font-size: 12px;
74
+ overflow-wrap: anywhere;
75
+ }
76
+ }
77
+
78
+ &__meta-label,
79
+ &__section-title {
80
+ color: var(--sub-text-color, #6b7280);
81
+ font-size: 12px;
82
+ font-weight: 600;
83
+ }
84
+
85
+ &__section {
86
+ display: flex;
87
+ flex-direction: column;
88
+ gap: 6px;
89
+ }
90
+
91
+ &__chips {
92
+ display: flex;
93
+ flex-wrap: wrap;
94
+ gap: 6px;
95
+ }
96
+
97
+ &__chip {
98
+ padding: 3px 8px;
99
+ border-radius: 999px;
100
+ background: rgba(191, 219, 254, .45);
101
+ color: #1d4ed8;
102
+ font-size: 12px;
103
+ }
104
+
105
+ &__reasons {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 4px;
109
+ }
110
+
111
+ &__reason {
112
+ color: var(--text-color);
113
+ font-size: 12px;
114
+ line-height: 1.5;
115
+ }
116
+
117
+ &__option.ant-btn {
118
+ height: auto;
119
+ text-align: left;
120
+ display: block;
121
+ padding: 8px 12px;
122
+ }
123
+
124
+ &__option-label {
125
+ font-weight: 500;
126
+ }
127
+
128
+ &__option-description {
129
+ margin-top: 4px;
130
+ color: var(--placeholder-color, #9ca3af);
131
+ font-size: 12px;
132
+ }
133
+ }
134
+
135
+ .interaction-question {
136
+ font-weight: 700;
137
+ color: var(--text-color);
138
+ line-height: 1.5;
139
+ }
140
+
7
141
  .chat-input-container {
8
142
  position: relative;
9
143
  display: flex;
@@ -451,6 +585,7 @@
451
585
 
452
586
  .adapter-select,
453
587
  .model-select,
588
+ .effort-select,
454
589
  .permission-mode-select {
455
590
  .ant-select-selector {
456
591
  height: 28px !important;
@@ -499,10 +634,15 @@
499
634
  min-width: 160px;
500
635
  }
501
636
 
637
+ .effort-select {
638
+ min-width: 72px;
639
+ }
640
+
502
641
  .permission-mode-select {
503
642
  min-width: 120px;
504
643
  }
505
644
 
645
+ .effort-select-popup,
506
646
  .permission-mode-select-popup {
507
647
  .ant-select-item-option-content {
508
648
  font-size: 12px;
@@ -13,6 +13,7 @@ import type { SessionInfo } from '@vibe-forge/types'
13
13
  import { isShortcutMatch } from '../../../utils/shortcutUtils'
14
14
  import type { CompletionItem } from './CompletionMenu'
15
15
  import { CompletionMenu } from './CompletionMenu'
16
+ import { shouldHideSenderForInteraction } from './interaction-request'
16
17
  import { ThinkingStatus } from './ThinkingStatus'
17
18
 
18
19
  const { TextArea } = Input
@@ -590,38 +591,75 @@ export function Sender({
590
591
  }
591
592
  }
592
593
 
594
+ const permissionContext = interactionRequest?.payload.kind === 'permission'
595
+ ? interactionRequest.payload.permissionContext
596
+ : undefined
597
+ const hideSender = shouldHideSenderForInteraction(interactionRequest)
598
+ const deniedTools = permissionContext?.deniedTools?.filter(tool => tool.trim() !== '') ?? []
599
+ const reasons = permissionContext?.reasons?.filter(reason => reason.trim() !== '') ?? []
600
+
593
601
  return (
594
- <div className='chat-input-wrapper'>
602
+ <div className={`chat-input-wrapper ${hideSender ? 'chat-input-wrapper--permission' : ''}`.trim()}>
595
603
  {isThinking && <ThinkingStatus />}
596
604
  {interactionRequest != null && (
597
- <div
598
- className='interaction-panel'
599
- style={{
600
- display: 'flex',
601
- flexDirection: 'column',
602
- maxHeight: '200px',
603
- overflowY: 'auto',
604
- marginBottom: '10px',
605
- gap: '8px',
606
- padding: '8px',
607
- border: '1px solid var(--border-color)',
608
- borderRadius: '8px',
609
- backgroundColor: 'var(--bg-color)'
610
- }}
611
- >
612
- <div className='interaction-question' style={{ fontWeight: 'bold' }}>
605
+ <div className='interaction-panel'>
606
+ {permissionContext != null && (
607
+ <div className='interaction-panel__badge'>
608
+ <span className='material-symbols-rounded'>lock</span>
609
+ <span>{t('chat.permissionRequestBadge')}</span>
610
+ </div>
611
+ )}
612
+ <div className='interaction-question'>
613
613
  {interactionRequest.payload.question}
614
614
  </div>
615
+ {permissionContext != null && (
616
+ <div className='interaction-panel__context'>
617
+ <div className='interaction-panel__meta'>
618
+ {permissionContext.currentMode != null && permissionContext.currentMode !== '' && (
619
+ <div className='interaction-panel__meta-item'>
620
+ <span className='interaction-panel__meta-label'>{t('chat.permissionCurrentMode')}</span>
621
+ <code>{permissionContext.currentMode}</code>
622
+ </div>
623
+ )}
624
+ {permissionContext.suggestedMode != null && permissionContext.suggestedMode !== '' && (
625
+ <div className='interaction-panel__meta-item'>
626
+ <span className='interaction-panel__meta-label'>{t('chat.permissionSuggestedMode')}</span>
627
+ <code>{permissionContext.suggestedMode}</code>
628
+ </div>
629
+ )}
630
+ </div>
631
+ {deniedTools.length > 0 && (
632
+ <div className='interaction-panel__section'>
633
+ <div className='interaction-panel__section-title'>{t('chat.permissionDeniedTools')}</div>
634
+ <div className='interaction-panel__chips'>
635
+ {deniedTools.map(tool => (
636
+ <code key={tool} className='interaction-panel__chip'>{tool}</code>
637
+ ))}
638
+ </div>
639
+ </div>
640
+ )}
641
+ {reasons.length > 0 && (
642
+ <div className='interaction-panel__section'>
643
+ <div className='interaction-panel__section-title'>{t('chat.permissionReasons')}</div>
644
+ <div className='interaction-panel__reasons'>
645
+ {reasons.map(reason => (
646
+ <div key={reason} className='interaction-panel__reason'>{reason}</div>
647
+ ))}
648
+ </div>
649
+ </div>
650
+ )}
651
+ </div>
652
+ )}
615
653
  {interactionRequest.payload.options?.map((option: NonNullable<AskUserQuestionParams['options']>[number]) => (
616
654
  <Button
617
- key={option.label}
655
+ key={option.value ?? option.label}
618
656
  block
619
- style={{ height: 'auto', textAlign: 'left', display: 'block', padding: '8px 12px' }}
620
- onClick={() => onInteractionResponse?.(interactionRequest.id, option.label)}
657
+ className='interaction-panel__option'
658
+ onClick={() => onInteractionResponse?.(interactionRequest.id, option.value ?? option.label)}
621
659
  >
622
- <div style={{ fontWeight: 500 }}>{option.label}</div>
660
+ <div className='interaction-panel__option-label'>{option.label}</div>
623
661
  {option.description && (
624
- <div style={{ fontSize: '12px', color: 'var(--sub-text-color)', marginTop: '4px' }}>
662
+ <div className='interaction-panel__option-description'>
625
663
  {option.description}
626
664
  </div>
627
665
  )}
@@ -629,7 +667,8 @@ export function Sender({
629
667
  ))}
630
668
  </div>
631
669
  )}
632
- <div className='chat-input-container'>
670
+ {!hideSender && (
671
+ <div className='chat-input-container'>
633
672
  {connectionError && connectionError.trim() !== '' && (
634
673
  <div className='connection-error-banner'>
635
674
  <div className='connection-error-content'>
@@ -692,28 +731,28 @@ export function Sender({
692
731
  className='file-input-hidden'
693
732
  />
694
733
  <div className='toolbar-left'>
695
- <Tooltip title='快捷指令'>
734
+ <Tooltip title={t('chat.tooltipSlashCommands')}>
696
735
  <span>
697
736
  <div className='toolbar-btn' onClick={() => handleTriggerClick('/')}>
698
737
  <span className='material-symbols-rounded'>terminal</span>
699
738
  </div>
700
739
  </span>
701
740
  </Tooltip>
702
- <Tooltip title='提及代理'>
741
+ <Tooltip title={t('chat.tooltipMentionAgents')}>
703
742
  <span>
704
743
  <div className='toolbar-btn' onClick={() => handleTriggerClick('@')}>
705
744
  <span className='material-symbols-rounded'>smart_toy</span>
706
745
  </div>
707
746
  </span>
708
747
  </Tooltip>
709
- <Tooltip title='注入上下文'>
748
+ <Tooltip title={t('chat.tooltipInjectContext')}>
710
749
  <span>
711
750
  <div className='toolbar-btn' onClick={() => handleTriggerClick('#')}>
712
751
  <span className='material-symbols-rounded'>description</span>
713
752
  </div>
714
753
  </span>
715
754
  </Tooltip>
716
- <Tooltip title='上传图片'>
755
+ <Tooltip title={t('chat.tooltipUploadImages')}>
717
756
  <span>
718
757
  <div className='toolbar-btn' onClick={handleImageUpload}>
719
758
  <span className='material-symbols-rounded'>image</span>
@@ -850,7 +889,7 @@ export function Sender({
850
889
  allowClear={false}
851
890
  disabled={modelUnavailable || isThinking}
852
891
  onChange={(value) => onEffortChange(value)}
853
- placeholder='Effort'
892
+ placeholder={t('chat.effortSelectPlaceholder')}
854
893
  optionLabelProp='label'
855
894
  popupMatchSelectWidth={false}
856
895
  />
@@ -865,7 +904,7 @@ export function Sender({
865
904
  allowClear={false}
866
905
  disabled={modelUnavailable || isThinking}
867
906
  onChange={(value) => onPermissionModeChange(value)}
868
- placeholder='权限模式'
907
+ placeholder={t('chat.permissionModeSelectPlaceholder')}
869
908
  optionLabelProp='label'
870
909
  popupMatchSelectWidth={false}
871
910
  />
@@ -882,10 +921,13 @@ export function Sender({
882
921
  </div>
883
922
  </div>
884
923
  </div>
885
- </div>
886
- <div className='chat-input-hint'>
887
- {t('chat.hint')}
888
- </div>
924
+ </div>
925
+ )}
926
+ {!hideSender && (
927
+ <div className='chat-input-hint'>
928
+ {t('chat.hint')}
929
+ </div>
930
+ )}
889
931
  </div>
890
932
  )
891
933
  }
@@ -0,0 +1,5 @@
1
+ import type { AskUserQuestionParams } from '@vibe-forge/core'
2
+
3
+ export const shouldHideSenderForInteraction = (
4
+ interactionRequest: { id: string; payload: AskUserQuestionParams } | null | undefined
5
+ ) => interactionRequest?.payload.kind === 'permission'
@@ -102,7 +102,6 @@ export const SectionForm = ({
102
102
  if (sectionKey === 'channels') return t('config.editor.newChannelName')
103
103
  if (sectionKey === 'adapters') return t('config.editor.newAdapterName')
104
104
  if (sectionKey === 'plugins') {
105
- if (field.path.join('.') === 'extraKnownMarketplaces') return t('config.editor.newMarketplaceName')
106
105
  return t('config.editor.newPluginName')
107
106
  }
108
107
  if (sectionKey === 'mcp') return t('config.editor.newMcpServerName')
@@ -309,30 +309,9 @@ export const configSchema: Record<string, FieldSpec[]> = {
309
309
  plugins: [
310
310
  {
311
311
  path: ['plugins'],
312
- type: 'record',
313
- recordKind: 'json',
314
- defaultValue: {},
312
+ type: 'json',
313
+ defaultValue: [],
315
314
  icon: 'extension'
316
- },
317
- {
318
- path: ['enabledPlugins'],
319
- type: 'record',
320
- recordKind: 'boolean',
321
- defaultValue: {},
322
- group: 'base',
323
- icon: 'toggle_on',
324
- labelKey: 'config.fields.plugins.enabled.label',
325
- descriptionKey: 'config.fields.plugins.enabled.desc'
326
- },
327
- {
328
- path: ['extraKnownMarketplaces'],
329
- type: 'record',
330
- recordKind: 'json',
331
- defaultValue: {},
332
- group: 'base',
333
- icon: 'storefront',
334
- labelKey: 'config.fields.plugins.marketplaces.label',
335
- descriptionKey: 'config.fields.plugins.marketplaces.desc'
336
315
  }
337
316
  ],
338
317
  mcp: [
@@ -0,0 +1,37 @@
1
+ import type { AskUserQuestionParams, Session, WSEvent } from '@vibe-forge/core'
2
+
3
+ export interface InteractionRequestState {
4
+ id: string
5
+ payload: AskUserQuestionParams
6
+ }
7
+
8
+ export const applyInteractionStateEvent = (
9
+ currentInteraction: InteractionRequestState | null,
10
+ data: WSEvent
11
+ ) => {
12
+ if (data.type === 'interaction_request') {
13
+ return { id: data.id, payload: data.payload }
14
+ }
15
+
16
+ if (data.type === 'interaction_response') {
17
+ return currentInteraction?.id === data.id || currentInteraction == null
18
+ ? null
19
+ : currentInteraction
20
+ }
21
+
22
+ if (data.type === 'session_updated') {
23
+ const session = data.session as Session | { id: string; isDeleted: boolean }
24
+ if ('isDeleted' in session) {
25
+ return null
26
+ }
27
+ if (session.status !== 'waiting_input') {
28
+ return null
29
+ }
30
+ }
31
+
32
+ if (data.type === 'error' && data.data != null && typeof data.data === 'object' && 'fatal' in data.data) {
33
+ return (data.data as { fatal?: boolean }).fatal !== false ? null : currentInteraction
34
+ }
35
+
36
+ return currentInteraction
37
+ }
@@ -6,6 +6,7 @@ import { getSessionMessages } from '#~/api.js'
6
6
  import { connectionManager } from '#~/connectionManager.js'
7
7
  import type { AskUserQuestionParams, ChatMessage, Session, WSEvent } from '@vibe-forge/core'
8
8
  import type { SessionInfo } from '@vibe-forge/types'
9
+ import { applyInteractionStateEvent } from './interaction-state'
9
10
  import type { ChatEffort } from './use-chat-effort'
10
11
  import type { PermissionMode } from './use-chat-permission-mode'
11
12
 
@@ -64,6 +65,7 @@ export function useChatSessionMessages({
64
65
  const lastConnectedPermissionModeRef = useRef<string | undefined>(undefined)
65
66
  const lastConnectedAdapterRef = useRef<string | undefined>(undefined)
66
67
  const expectedCloseRef = useRef(false)
68
+ const interactionRequestRef = useRef<{ id: string; payload: AskUserQuestionParams } | null>(null)
67
69
 
68
70
  const retryConnection = useCallback(() => {
69
71
  if (session?.id == null || session.id === '') return
@@ -79,6 +81,7 @@ export function useChatSessionMessages({
79
81
  setIsReady(false)
80
82
  setConnectionError(null)
81
83
  setInteractionRequest(null)
84
+ interactionRequestRef.current = null
82
85
  isInitialLoadRef.current = true
83
86
 
84
87
  if (session?.id == null || session.id === '') {
@@ -109,9 +112,8 @@ export function useChatSessionMessages({
109
112
  }, false)
110
113
  }
111
114
 
112
- if (res.interaction) {
113
- setInteractionRequest(res.interaction)
114
- }
115
+ interactionRequestRef.current = res.interaction ?? null
116
+ setInteractionRequest(interactionRequestRef.current)
115
117
 
116
118
  let currentMessages: ChatMessage[] = []
117
119
  let currentSessionInfo: SessionInfo | null = null
@@ -207,6 +209,11 @@ export function useChatSessionMessages({
207
209
  },
208
210
  onMessage(data: WSEvent) {
209
211
  if (isDisposed) return
212
+ const nextInteraction = applyInteractionStateEvent(interactionRequestRef.current, data)
213
+ if (nextInteraction !== interactionRequestRef.current) {
214
+ interactionRequestRef.current = nextInteraction
215
+ setInteractionRequest(nextInteraction)
216
+ }
210
217
  if (data.type === 'error') {
211
218
  setConnectionError(data.data?.message ?? data.message ?? 'Unknown error')
212
219
  return
@@ -269,7 +276,7 @@ export function useChatSessionMessages({
269
276
  }
270
277
 
271
278
  if (data.type === 'interaction_request') {
272
- setInteractionRequest({ id: data.id, payload: data.payload })
279
+ return
273
280
  }
274
281
  },
275
282
  onError() {