@jwcode/cli 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +401 -0
- package/README.md +25 -0
- package/dist/cli.js +28 -28
- package/package.json +6 -16
- package/scripts/download-jre.js +201 -0
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`)){let o=n.trim().split(/\s+/).pop();if(o)try{
|
|
4
|
-
[jwcode] Shutting down...`),process.platform==="win32")try{
|
|
5
|
-
`);let r="[200~",
|
|
6
|
-
`)}catch{}}
|
|
7
|
-
`),s}_startReadLoop(){this.ws&&this.ws.on("message",e=>{let n;try{n=JSON.parse(e.toString())}catch{return}n.type==="auth_required"||n.type==="auth_success"||n.type==="auth_failed"||this.dispatch(n)})}_startHeartbeat(){this._stopHeartbeat(),this.pingTimer=setInterval(()=>{if(this.ws?.readyState===
|
|
8
|
-
`),this.dispatch({type:"error",data:"Connection lost \u2014 max retries reached."});return}this._reconnecting=!0,this._reconnectRetries++,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.reconnectTimer=setTimeout(async()=>{try{
|
|
9
|
-
`),this.dispatch({type:"notification",data:`Reconnecting (${this._reconnectRetries})...`}),await this.connect(),this.dispatch({type:"notification",data:"Reconnected."})}catch{this.reconnectDelay=Math.min(this.reconnectDelay*2,zo),this._reconnecting=!1,this._startReconnect()}},this.reconnectDelay)}}dispatch(e){let n=this.handlers.get(e.type);if(n)for(let o of n)try{o(e)}catch(s){console.error(`Handler error [${e.type}]:`,s)}}send(e,n,o){if(V("send",e+(n?" msg="+n.slice(0,40):"")+(o?" data="+JSON.stringify(o).slice(0,60):"")),!this.ws||this.ws.readyState!==Rt.OPEN){console.warn(`[ws] Not connected, dropping: ${e}`);return}let s={type:e,sessionId:this.sessionId};n!==void 0&&(s.message=n),o&&(s.data=JSON.stringify(o));try{this.ws.send(JSON.stringify(s))}catch(i){console.error(`[ws] send error [${e}]:`,i)}}chat(e,n=!1){this.send(n?"plan":"chat",e)}stop(){V("send","stop"),this.send("stop")}pause(){this.send("pause")}resume(){this.send("resume")}planConfirm(){this.send("plan_confirm")}updateDocs(){this.send("update_docs")}doctor(){this.send("doctor")}rewind(){this.send("rewind")}compact(){this.send("compact")}switchModel(e){this.send("model_change",void 0,{model:e})}approveHook(e){V("send","approveHook "+e),this.send("hook_allow",void 0,{approvalId:e})}denyHook(e){V("send","denyHook "+e),this.send("hook_deny",void 0,{approvalId:e})}exit(){this.send("exit")}init(){this.send("init")}effort(e){this.send("effort",void 0,{level:e})}branch(e){this.send("branch",void 0,{name:e})}mcp(e){this.send("mcp",void 0,{action:e})}skills(){this.send("skills")}agents(){this.send("agents")}config(e){this.send("config",void 0,{action:e})}plugin(e){this.send("plugin",void 0,{action:e})}async listFiles(e){try{let n=e?`${this.backendUrl}/api/files?path=${encodeURIComponent(e)}`:`${this.backendUrl}/api/files`,o=await fetch(n);if(!o.ok)return[];let s=await o.json(),i=[],d=c(f=>{for(let p of f)p.type==="file"&&i.push(p.path),p.children&&d(p.children)},"walk");return d(s?.data||s||[]),i}catch{return[]}}async readFileContent(e){try{let n=await fetch(`${this.backendUrl}/api/files/read?path=${encodeURIComponent(e)}`);if(!n.ok)return null;let o=await n.json();return o?.data||o}catch{return null}}async listSessions(){try{let n=await(await fetch(`${this.backendUrl}/api/sessions`)).json();return n?.data||n||[]}catch{return[]}}async deleteSession(e){try{return(await(await fetch(`${this.backendUrl}/api/sessions/${e}`,{method:"DELETE"})).json())?.success===!0}catch{return!1}}async getSessionMessages(e){try{return(await(await fetch(`${this.backendUrl}/api/sessions/${e}/messages`)).json())?.data||[]}catch{return[]}}async close(){this._running=!1,this._reconnecting=!1,this._stopHeartbeat(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}};import{memo as cr,useState as lr,useEffect as dr,useRef as ur}from"react";import{Box as Qe,Text as R}from"ink";import{useSyncExternalStore as Qo,useRef as Zo}from"react";function hn(t,e){let n=t,o=new Set;return{getState:c(()=>n,"getState"),setState:c(s=>{let i=n,d=s(i);if(!Object.is(d,i)){n=d,e?.({newState:d,oldState:i});for(let f of o)f()}},"setState"),subscribe:c(s=>(o.add(s),()=>o.delete(s)),"subscribe")}}c(hn,"createStore");var er={messages:[],currentMessage:null,usage:{promptTokens:0,completionTokens:0,totalTokens:0,usageRatio:0},planMode:!1,autoMode:!1,planWaiting:!1,scrollOffset:0,modelName:"",connected:!1,statusText:"connecting...",tokenRate:0,toolCallsExpanded:!1,planTasks:[],pdcaPhase:"",degradation:{active:!1,retryCount:0,maxRetries:0,mode:"normal",message:""},compactionProgress:null,contentHeight:0},Et=null;function xe(){return Et||(Et=hn(er)),Et}c(xe,"getStore");var tr=c(t=>t.currentMessage!==null,"selIsGenerating");var nr=c(t=>t.planTasks,"selPlanTasks"),or=c(t=>t.pdcaPhase,"selPdcaPhase"),rr=c(t=>t.degradation,"selDegradation"),sr=c(t=>({messages:t.messages,currentMessage:t.currentMessage,scrollOffset:t.scrollOffset,contentHeight:t.contentHeight}),"selChatArea"),ar=c(t=>({usage:t.usage,modelName:t.modelName,planMode:t.planMode,autoMode:t.autoMode,connected:t.connected,statusText:t.statusText,messagesLen:t.messages.length,tokenRate:t.tokenRate,compactionProgress:t.compactionProgress}),"selStatusLine");function ir(t,e){if(Object.is(t,e))return!0;if(t===null||e===null||typeof t!="object"||typeof e!="object")return!1;let n=Object.keys(t),o=Object.keys(e);return n.length!==o.length?!1:n.every(s=>Object.is(t[s],e[s]))}c(ir,"shallowEqual");function oe(t){let e=xe(),n=Zo(null),o=c(()=>{let s=t(e.getState()),i=n.current;return i!==null&&ir(s,i.value)?i.value:(n.current={value:s},s)},"getSnapshot");return Qo(e.subscribe,o,o)}c(oe,"useAppSlice");var xn=c(()=>oe(tr),"useAppIsGenerating"),wn=c(()=>oe(sr),"useAppChatArea"),Pt=c(()=>oe(ar),"useAppStatusLine");var Tn=c(()=>oe(nr),"useAppPlanTasks"),bn=c(()=>oe(or),"useAppPdcaPhase"),Sn=c(()=>oe(rr),"useAppDegradation");function A(t){xe().setState(t)}c(A,"updateAppState");import{Fragment as Ae,jsx as O,jsxs as X}from"react/jsx-runtime";function ut(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${Math.round(t/1e3)}K`:String(t)}c(ut,"formatTokens");function pr(t){return t<=0?"":t>=100?`${Math.round(t)}t/s`:t>=10?`${t.toFixed(1)}t/s`:`${t.toFixed(1)}t/s`}c(pr,"formatRate");function fr(t){if(t<=0)return"";if(t>=60){let e=Math.floor(t/60),n=t%60;return`${e}m${n}s`}return`${t}s`}c(fr,"formatElapsed");var yn=cr(c(function(){V("app","StatusLine mount planMode="+Pt().planMode);let{usage:e,modelName:n,planMode:o,autoMode:s,connected:i,statusText:d,messagesLen:f,tokenRate:p,compactionProgress:m}=Pt(),b=Sn(),h=bn(),x=Tn(),S=f,C=xn(),k=ur(0),[w,M]=lr(Date.now());dr(()=>{if(C){k.current===0&&(k.current=Date.now());let re=setInterval(()=>M(Date.now()),1e3);return()=>clearInterval(re)}else k.current=0},[C]);let a=C?Math.floor((w-k.current)/1e3):0,r=Math.min(100,Math.round(e.usageRatio*100)),g=Math.round(r/10),l="\u2588".repeat(g)+"\u2591".repeat(10-g),T=n||(i?"ready":"connecting..."),y=o?" Plan ":" Act ",E=o?u.plan:u.success,W=o?"mode-plan":"mode-act",_=i?"\u25CF":"\u25CB",D=i?u.connected:u.disconnected,P=d.startsWith("Error:"),Ce=r>90?u.error:r>70?u.warning:u.text,Pe=pr(p),Ie=fr(a),Me=e.promptTokens,$=e.completionTokens;return X(Qe,{flexDirection:"column",width:"100%",paddingRight:1,children:[X(Qe,{height:1,children:[O(R,{bold:!0,color:u.primary,children:"jwcode"}),O(R,{children:" "}),X(R,{backgroundColor:E,color:"black",children:[" ",y," "]},W),O(R,{children:" "}),s&&X(Ae,{children:[O(R,{backgroundColor:u.auto,color:"black",children:" AUTO "}),O(R,{children:" "})]}),h&&X(Ae,{children:[X(R,{backgroundColor:u.warning,color:"black",children:[" ",h," "]}),O(R,{children:" "})]}),x.length>0&&X(Ae,{children:[O(R,{color:u.primary,children:x.filter(re=>re.status==="completed").length}),O(R,{dimColor:!0,children:"/"}),O(R,{color:u.text,children:x.length}),O(R,{dimColor:!0,children:" tasks"}),O(R,{children:" "})]}),X(R,{color:D,children:[_," "]}),O(R,{color:u.success,children:T}),O(R,{children:" "}),X(R,{dimColor:!0,children:[S,"msgs"]}),Me>0||$>0?X(Ae,{children:[O(R,{children:" "}),O(R,{color:u.info,children:ut(Me)}),O(R,{dimColor:!0,children:"+"}),O(R,{color:u.success,children:ut($)}),O(R,{dimColor:!0,children:"="}),O(R,{color:u.warning,children:ut(e.totalTokens)})]}):X(Ae,{children:[O(R,{children:" t:"}),O(R,{color:u.warning,children:ut(e.totalTokens)})]}),O(R,{children:" "}),X(R,{color:Ce,children:[l," ",r,"%"]}),C&&Pe&&X(Ae,{children:[O(R,{children:" "}),O(R,{color:u.tool,children:Pe})]}),C&&Ie&&X(Ae,{children:[O(R,{children:" "}),O(R,{color:u.primary,children:Ie})]})]}),O(Qe,{height:1,children:b.active?X(R,{color:u.warning,dimColor:!0,children:["[",b.mode.toUpperCase(),"] ",b.message,b.retryCount>0?` (${b.retryCount}/${b.maxRetries})`:""]}):O(R,{children:" "})}),O(Qe,{height:1,children:m?X(Ae,{children:[X(R,{color:m.percent>=100?u.success:u.primary,children:[m.percent>=100?"\u2713":"\u2699"," ",m.message]}),O(R,{children:" "}),X(R,{color:u.warning,children:["\u2588".repeat(Math.round(m.percent/10)),"\u2591".repeat(10-Math.round(m.percent/10))]}),X(R,{dimColor:!0,children:[" ",m.percent,"%"]})]}):O(R,{children:" "})}),O(Qe,{height:1,children:d&&d!=="connecting..."?O(R,{color:P?u.error:u.muted,dimColor:!P,children:d.slice(0,100)}):O(R,{children:" "})})]})},"StatusLine"));import{Box as Y,Text as H}from"ink";import{useState as Dn,useMemo as Rr,useRef as ft,useLayoutEffect as Dr,useCallback as En,memo as tt,forwardRef as On}from"react";import{measureElement as Er}from"ink";import{useEffect as mr,useRef as It}from"react";import{useStdin as gr}from"ink";var hr="\x1B[?1000h\x1B[?1002h\x1B[?1006h",xr="\x1B[?1006l\x1B[?1002l\x1B[?1000l",Ze={topRow:0,trackHeight:0,contentHeight:0,viewportHeight:0,termCols:80};function kn(t){Ze=t}c(kn,"setScrollGeometry");function wr(t){let e=t.match(/\x1b\[<(\d+);(\d+);(\d+)([Mm])/);return e?{btn:parseInt(e[1],10),col:parseInt(e[2],10),row:parseInt(e[3],10),final:e[4]}:null}c(wr,"parseSgr");var Tr=2;function Cn(){let{stdin:t,internal_eventEmitter:e}=gr(),n=It(""),o=It(!1),s=It(0);mr(()=>{if(!t||!e||process.env.JWCODE_NO_MOUSE==="1")return;t.write(hr);let i=c(d=>{let f=typeof d=="string"?d:d.toString("utf-8");n.current+=f;let p=wr(n.current),m=0;if(p){let h=`\x1B[<${p.btn};${p.col};${p.row}`+p.final,x=n.current.indexOf(h)+h.length;if(p.btn===64||p.btn===65){let S=p.btn===64?3:-3;A(C=>{let k=Math.max(0,Ze.contentHeight-Ze.viewportHeight),w=Math.max(0,Math.min(C.scrollOffset+S,k));return{...C,scrollOffset:w}})}if(p.btn===0&&p.final==="M"){let S=Ze;if(p.col>S.termCols-Tr&&S.trackHeight>0&&S.contentHeight>S.viewportHeight){let k=p.row-S.topRow-1;if(k>=0&&k<S.trackHeight){let w=S.contentHeight-S.viewportHeight,M=1-k/Math.max(1,S.trackHeight-1),a=Math.round(M*w);A(r=>({...r,scrollOffset:Math.max(0,Math.min(a,w))})),o.current=!0,s.current=Date.now()}}}if(p.btn===32&&o.current){let S=Date.now();if(S-s.current<33){m=x,n.current=n.current.slice(m);return}s.current=S;let C=Ze,k=p.row-C.topRow-1,w=C.contentHeight-C.viewportHeight,M=1-Math.max(0,Math.min(1,k/Math.max(1,C.trackHeight-1))),a=Math.round(M*w);A(r=>({...r,scrollOffset:Math.max(0,Math.min(a,w))}))}p.btn===0&&p.final==="m"&&(o.current=!1),m=x}m>0?n.current=n.current.slice(m):n.current.length>128&&(n.current=n.current.slice(-64))},"onData");return e.on("input",i),()=>{e.removeListener("input",i),t.write(xr),n.current="",o.current=!1}},[t,e])}c(Cn,"useMouseWheel");import{memo as An,useState as br,useMemo as pt}from"react";import{Box as we,Text as Te}from"ink";import{jsx as be,jsxs as ue}from"react/jsx-runtime";var Sr=/^(---|\+\+\+) /,yr=/^@@ /,kr=/^\\(?!.*\\$)/;var Mn=30;function Cr(t){let e=t.split(`
|
|
10
|
-
`),n=[];for(let o of e){let s="context";
|
|
11
|
-
`);
|
|
12
|
-
`),n=!1,o=!1,s=0;for(let
|
|
13
|
-
`),s=o.filter(
|
|
14
|
-
... (truncated)`:t;return F(Y,{flexDirection:"column",paddingLeft:2,children:[F(H,{dimColor:!0,children:["Diff: ",d]}),I(Ot,{content:p,terminalCols:e})]})}let n=t.length>500?t.slice(0,500)+"...":t;return I(H,{color:u.muted,dimColor:!0,children:n})}c(Nr,"ToolResult");var Hr=tt(c(function({step:e}){let n=e.status==="success"?"[ok]":e.status==="error"?"[!!]":e.status==="running"?"[..]":"[--]",o=e.status==="success"?u.success:e.status==="error"?u.error:e.status==="running"?u.primary:u.primary,s=e.duration?ht(e.duration):e.status==="running"&&e.timestamp?ht(Math.floor((Date.now()-e.timestamp)/1e3)):"";return F(Y,{flexDirection:"column",children:[F(Y,{children:[F(H,{color:o,children:[" ",n," "]}),I(H,{bold:!0,color:o,children:e.title}),s&&F(Wn,{children:[I(H,{dimColor:!0,children:" "}),I(H,{color:u.muted,dimColor:!0,children:s})]})]}),e.thought&&F(H,{color:u.info,dimColor:!0,children:[" ",Ge(e.thought,200)]}),e.action&&F(H,{color:u.warning,children:[" ",Ge(e.action,200)]}),e.result&&F(H,{color:u.success,children:[" ",Ge(e.result,300)]})]})},"StepDisplay")),Hn=tt(c(function({tc:e,collapsed:n,onToggle:o,terminalCols:s}){let i=e.status==="complete"?"[ok]":e.status==="running"?"[..]":"[!!]",d=e.status==="complete"?u.success:e.status==="running"?u.warning:u.error,f=e.duration?ht(e.duration):e.status==="running"&&e.timestamp?ht(Math.floor((Date.now()-e.timestamp)/1e3)):"";return F(Y,{flexDirection:"column",paddingLeft:1,children:[F(Y,{children:[F(H,{color:d,children:[" ",i," "]}),I(H,{bold:!0,color:u.tool,children:e.name}),f&&F(Wn,{children:[I(H,{dimColor:!0,children:" "}),I(H,{color:u.muted,dimColor:!0,children:f})]}),I(H,{dimColor:!0,children:" "}),F(H,{color:u.info,dimColor:!0,children:["[",n?"+":"-","]"]})]}),!n&&e.args&&I(Y,{paddingLeft:4,children:I(H,{dimColor:!0,children:Ge(Ur(e.args),200)})}),e.result&&I(Y,{paddingLeft:2,flexDirection:"column",children:I(Nr,{result:e.result,terminalCols:s})})]})},"ToolCallDisplay")),Wr=tt(On(c(function({msg:e,expandedMessages:n,expandedTools:o,toolCallsExpanded:s,onToggleTool:i,onToggleMessage:d,terminalCols:f},p){return F(Y,{flexDirection:"column",marginBottom:1,ref:p,children:[e.type==="user"&&F(Y,{flexDirection:"column",children:[I(H,{dimColor:!0,children:Pn}),F(H,{color:u.user,bold:!0,children:[">"," ",e.content]})]}),e.type==="assistant"&&F(Y,{flexDirection:"column",children:[I(H,{children:" "}),e.steps.map((m,b)=>I(Hr,{step:m},m.id||b)),e.thinking&&F(Y,{flexDirection:"column",children:[I(H,{dimColor:!0,italic:!0,children:n.has(e.id)?e.thinking:Ge(e.thinking,gt)}),e.thinking.length>gt&&F(H,{dimColor:!0,children:["[",e.thinking.length-gt," more chars]"," -> to expand"]})]}),e.toolCalls.map((m,b)=>{let h=m.id||m.name||"tool-"+e.id+"-"+b,x=Bn(e.toolCalls,b),S=o.has(h);return I(Hn,{tc:m,terminalCols:f,collapsed:s||S?!1:x,onToggle:()=>i(h)},h)}),e.content&&I(Y,{paddingLeft:1,children:I(Nn,{content:e.content,terminalCols:f})}),I(H,{dimColor:!0,children:Pn})]}),e.type==="system"&&I(Y,{children:F(H,{color:u.error,children:["Error: ",e.content]})})]})},"MessageItem")),(t,e)=>t.msg.id===e.msg.id&&t.msg.content===e.msg.content&&t.msg.thinking===e.msg.thinking&&t.msg.type===e.msg.type&&t.expandedMessages.has(t.msg.id)===e.expandedMessages.has(e.msg.id)&&t.toolCallsExpanded===e.toolCallsExpanded&&t.terminalCols===e.terminalCols),$r=tt(On(c(function({msg:e,expandedTools:n,toolCallsExpanded:o,onToggleTool:s,terminalCols:i},d){return F(Y,{flexDirection:"column",ref:d,children:[e.thinking&&I(H,{dimColor:!0,italic:!0,children:Ge(e.thinking,gt)}),e.toolCalls.map((f,p)=>{let m=f.id||f.name||"tool-"+e.id+"-"+p,b=Bn(e.toolCalls,p),h=n.has(m);return I(Hn,{tc:f,terminalCols:i,collapsed:o||h?!1:b,onToggle:()=>s(m)},m)}),e.content&&I(Y,{paddingLeft:1,children:I(Nn,{content:e.content,terminalCols:i})})]})},"StreamingMessage")),(t,e)=>t.msg.id===e.msg.id&&t.msg.content===e.msg.content&&t.msg.thinking===e.msg.thinking&&t.toolCallsExpanded===e.toolCallsExpanded&&t.terminalCols===e.terminalCols);function mt(t,e){if(t.type==="user")return 3;let n=4;t.thinking&&(n+=Math.ceil(t.thinking.length/Math.max(1,e))+1),n+=t.steps.length;for(let o of t.toolCalls)n+=2,o.result&&(n+=Math.min(20,Math.ceil(o.result.length/Math.max(1,e))));return t.content&&(n+=Math.ceil(t.content.length/Math.max(1,e))),n}c(mt,"defaultMessageHeight");function jr(t){let e=t,n=0;for(;e;){let o=e.yogaNode;if(!o||typeof o.getComputedTop!="function")break;n+=o.getComputedTop(),e=e.parentNode??null}return n}c(jr,"getAbsoluteTopRow");var Bt=tt(c(function({terminalCols:e,terminalRows:n}){let{messages:o,currentMessage:s,scrollOffset:i}=wn(),d=oe(_=>_.toolCallsExpanded),[f,p]=Dn(new Set),[m,b]=Dn(new Set),h=Math.max(3,n-Pr),x=ft(new Map),S=ft(new Map),C=ft(0),k=ft(null),w=Rr(()=>s?o.filter(_=>_.id!==s.id):o,[o,s&&s.id]),M=Math.min(i,Math.max(0,C.current-h)),a=w.length,r=0;if(M===0){let _=0;for(let D=a-1;D>=0;D--){let P=S.current.get(w[D].id)??mt(w[D],Math.max(10,e-4));if(_+=P,_>h){r=D+1;break}r=D}}else{let _=0,D=M+h;for(let P=a-1;P>=0;P--){let Ce=S.current.get(w[P].id)??mt(w[P],Math.max(10,e-4));if(_+=Ce,_>D){r=P;break}r=P}}r=Math.max(0,r);let g=w.slice(r),l=En(_=>{p(D=>{let P=new Set(D);return P.has(_)?P.delete(_):P.add(_),P})},[]),T=En(_=>{b(D=>{let P=new Set(D);return P.has(_)?P.delete(_):P.add(_),P})},[]),y=C.current,E=y>h||i>0,W=c(_=>D=>{D?x.current.set(_,D):x.current.delete(_)},"registerMessageRef");return Dr(()=>{let _=0,D=x.current,P=S.current,Ce=Math.max(10,e-4);for(let[$,re]of D)try{let{height:Ye}=Er(re);Ye>0&&(P.set($,Ye),_+=Ye)}catch{}for(let $ of w)if(!D.has($.id)){let re=P.get($.id)??mt($,Ce);P.set($.id,re),_+=re}if(s){let $=s,re=P.get($.id)??mt($,Ce);P.set($.id,re),_+=re}_+=1,_!==C.current&&(C.current=_,A($=>$.contentHeight===_?$:{...$,contentHeight:_}));let Pe=jr(k.current)+1;kn({topRow:Pe,trackHeight:Math.max(2,h-2),contentHeight:_,viewportHeight:h,termCols:e});let Ie=Math.max(0,_-h);i>Ie&&A($=>({...$,scrollOffset:Ie}));let Me=new Set(w.map($=>$.id));s&&Me.add(s.id);for(let $ of S.current.keys())Me.has($)||(S.current.delete($),x.current.delete($))},[w,s?.id,e,h,i,f.size,m.size,d]),F(Y,{flexDirection:"row",width:"100%",overflow:"hidden",ref:k,children:[F(Y,{flexGrow:1,flexDirection:"column",overflow:"hidden",children:[I(Y,{children:I(H,{dimColor:!E,bold:E,children:E?`[${r+1}-${a} / ${a}]`:`[${a}]`})}),g.map(_=>I(Wr,{ref:W(_.id),msg:_,expandedMessages:m,expandedTools:f,terminalCols:e,toolCallsExpanded:d,onToggleTool:l,onToggleMessage:T},_.id)),s&&I($r,{ref:W(s.id),msg:s,terminalCols:e,expandedTools:f,toolCallsExpanded:d,onToggleTool:l},s.id)]}),E&&I(Br,{contentHeight:y,offset:M,viewportHeight:h})]})},"ChatArea"));function Ur(t){if(typeof t!="string")return JSON.stringify(t,null,2);try{return JSON.stringify(JSON.parse(t),null,2)}catch{return t}}c(Ur,"formatJson");function Ge(t,e){let n=typeof t=="string"?t:String(t??"");return n.length<=e?n:n.slice(0,e)+"..."}c(Ge,"truncate");import{useState as $n,useMemo as Gr,useEffect as jn}from"react";import{Box as Tt,Text as Le,useInput as Kr,useStdout as qr}from"ink";var Jr=[{cmd:"/help",desc:"\u663E\u793A\u6240\u6709\u547D\u4EE4",via:"local",action:null},{cmd:"/plan",desc:"\u5207\u6362\u89C4\u5212\u6A21\u5F0F (\u5148\u89C4\u5212\u518D\u6267\u884C)",via:"local",action:"plan_mode"},{cmd:"/auto",desc:"\u5207\u6362\u81EA\u52A8\u6A21\u5F0F (\u81EA\u52A8\u6279\u51C6\u5DE5\u5177\u6267\u884C)",via:"local",action:"auto_mode"},{cmd:"/context",desc:"\u663E\u793A\u5F53\u524D\u4F1A\u8BDD\u72B6\u6001",via:"local",action:"show_context"},{cmd:"/exit",desc:"\u9000\u51FA JWCode",via:"local",action:"__exit__"}],Fr=[{cmd:"/confirm",desc:"\u786E\u8BA4\u5F53\u524D\u89C4\u5212\u5E76\u5F00\u59CB\u6267\u884C",via:"ws",action:"__confirm_plan"},{cmd:"/cancel",desc:"\u53D6\u6D88\u5F53\u524D\u89C4\u5212",via:"ws",action:"__cancel_plan"},{cmd:"/stop",desc:"\u505C\u6B62\u5F53\u524D AI \u751F\u6210",via:"ws",action:"stop"},{cmd:"/pause",desc:"\u6682\u505C\u5F53\u524D AI \u751F\u6210",via:"ws",action:"pause"},{cmd:"/resume",desc:"\u6062\u590D\u6682\u505C\u7684 AI \u751F\u6210",via:"ws",action:"resume"},{cmd:"/clear",desc:"\u6E05\u9664\u5F53\u524D\u4F1A\u8BDD\u6D88\u606F",via:"ws",action:"clear"},{cmd:"/doctor",desc:"\u8FD0\u884C\u7CFB\u7EDF\u81EA\u8BCA\u65AD",via:"ws",action:"doctor"},{cmd:"/rewind",desc:"\u56DE\u6EDA\u5230\u6700\u8FD1\u7684\u68C0\u67E5\u70B9",via:"ws",action:"rewind"},{cmd:"/compact",desc:"\u538B\u7F29\u4F1A\u8BDD\u4E0A\u4E0B\u6587 (\u91CA\u653E token)",via:"ws",action:"compact"},{cmd:"/model",desc:"\u5207\u6362 AI \u6A21\u578B (\u7528\u6CD5: /model <\u6A21\u578B\u540D> \u6216 /model \u6253\u5F00\u9009\u62E9\u5668)",via:"ws",action:"model_change"},{cmd:"/setup",desc:"\u914D\u7F6E AI \u63D0\u4F9B\u5546\u548C API Key",via:"local",action:"setup_wizard"},{cmd:"/init",desc:"\u5206\u6790\u9879\u76EE\u5E76\u751F\u6210 JWCODE.md \u9879\u76EE\u8BB0\u5FC6\u6587\u4EF6",via:"ws",action:"init"},{cmd:"/effort",desc:"\u8BBE\u7F6E\u4EFB\u52A1\u52AA\u529B\u7EA7\u522B (low/medium/high)",via:"ws",action:"effort"},{cmd:"/branch",desc:"\u521B\u5EFA\u5206\u652F\u4F1A\u8BDD (\u7528\u6CD5: /branch <\u540D\u79F0>)",via:"ws",action:"branch"},{cmd:"/mcp",desc:"MCP \u670D\u52A1\u5668\u7BA1\u7406 (list/add/remove)",via:"ws",action:"mcp"},{cmd:"/skills",desc:"\u67E5\u770B\u53EF\u7528 Skills \u5217\u8868",via:"ws",action:"skills"},{cmd:"/agents",desc:"\u5217\u51FA\u914D\u7F6E\u7684 Agent \u4EE3\u7406",via:"ws",action:"agents"},{cmd:"/config",desc:"\u7BA1\u7406\u914D\u7F6E (get/set/list)",via:"ws",action:"config"},{cmd:"/plugin",desc:"\u63D2\u4EF6\u7BA1\u7406 (install/list/remove)",via:"ws",action:"plugin"},{cmd:"/tokens",desc:"\u663E\u793A Token \u4F7F\u7528\u8BE6\u60C5",via:"ws",action:"tokens"},{cmd:"/memory",desc:"\u6D4F\u89C8\u9879\u76EE\u8BB0\u5FC6",via:"ws",action:"memory"},{cmd:"/export",desc:"\u5BFC\u51FA\u4F1A\u8BDD (\u7528\u6CD5: /export <\u8DEF\u5F84>)",via:"ws",action:"export"},{cmd:"/checkpoint",desc:"\u8BBE\u7F6E\u6216\u6062\u590D\u68C0\u67E5\u70B9",via:"ws",action:"checkpoint"},{cmd:"/test",desc:"\u8FD0\u884C\u5F53\u524D\u9879\u76EE\u6D4B\u8BD5",via:"ws",action:"test"},{cmd:"/lint",desc:"\u5BF9\u53D8\u66F4\u6587\u4EF6\u8FD0\u884C Linter",via:"ws",action:"lint"},{cmd:"/search",desc:"\u641C\u7D22\u4EE3\u7801\u5E93 (\u7528\u6CD5: /search <\u5173\u952E\u8BCD>)",via:"ws",action:"search"},{cmd:"/project",desc:"\u751F\u6210\u9879\u76EE\u6587\u6863",via:"ws",action:"project"}],Nt=[...Jr,...Fr],xt={"/help":null,"/plan":{action:"plan_mode"},"/auto":{action:"auto_mode"},"/context":{action:"show_context"},"/exit":{action:"__exit__"},"/quit":{action:"__exit__"},"/confirm":{action:"__confirm_plan"},"/cancel":{action:"__cancel_plan"},"/stop":{action:"stop"},"/pause":{action:"pause"},"/resume":{action:"resume"},"/clear":{action:"clear"},"/doctor":{action:"doctor"},"/rewind":{action:"rewind"},"/compact":{action:"compact"},"/model":{action:"model_change",needsArg:!1},"/setup":{action:"setup_wizard"},"/init":{action:"init"},"/effort":{action:"effort",needsArg:!0},"/branch":{action:"branch",needsArg:!0},"/mcp":{action:"mcp",needsArg:!0},"/skills":{action:"skills"},"/agents":{action:"agents"},"/config":{action:"config",needsArg:!0},"/plugin":{action:"plugin",needsArg:!0},"/tokens":{action:"tokens"},"/memory":{action:"memory"},"/export":{action:"export",needsArg:!0},"/checkpoint":{action:"checkpoint"},"/test":{action:"test"},"/lint":{action:"lint"},"/search":{action:"search",needsArg:!0},"/project":{action:"project"}},wt=`
|
|
2
|
+
var pn=Object.defineProperty;var i=(t,e)=>pn(t,"name",{value:e,configurable:!0}),No=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,n)=>(typeof require<"u"?require:e)[n]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var fn=(t,e)=>()=>(t&&(e=t(t=0)),e);var mn=(t,e)=>{for(var n in e)pn(t,n,{get:e[n],enumerable:!0})};var Zt={};mn(Zt,{buildBackend:()=>St,cleanupBackend:()=>hs,clearDaemonInfo:()=>lo,findAvailablePorts:()=>Xt,findInstallDir:()=>qt,findJar:()=>ve,findJava:()=>Vt,findMvn:()=>ao,findRunningDaemon:()=>Qt,isDaemonAlive:()=>uo,killPort:()=>st,portInUse:()=>We,readDaemonInfo:()=>co,startBackend:()=>gs,startDaemon:()=>zt,waitForBackend:()=>Yt,writeDaemonInfo:()=>yt});import{spawn as so,spawnSync as us,execSync as Pe}from"node:child_process";import{existsSync as xe,readdirSync as Gt,statSync as ps}from"node:fs";import{join as oe,dirname as Ft}from"node:path";import{homedir as Kt}from"node:os";import{fileURLToPath as fs}from"node:url";import{mkdirSync as xs,writeFileSync as ws,readFileSync as Ts,unlinkSync as bs}from"node:fs";function qt(){let t=oe(Jt,"..","backend","jwcode-web.jar");if(xe(t))return oe(Jt,"..");let e=oe(Jt,"..","..");for(;e!==Ft(e);){if(xe(oe(e,"pom.xml")))return e;e=Ft(e)}return process.cwd()}function ve(t){let e=oe(t,"backend","jwcode-web.jar");if(xe(e))return e;let n=oe(t,"jwcode-web","target","jwcode-web.jar");if(xe(n))return n;let o=oe(t,"jwcode-web","target");if(xe(o))try{let s=Gt(o).filter(c=>c.startsWith("jwcode-web")&&c.endsWith(".jar")).map(c=>({name:c,mtime:ps(oe(o,c)).mtimeMs})).sort((c,d)=>d.mtime-c.mtime);if(s.length>0)return oe(o,s[0].name)}catch{}return null}function ao(){let t=process.env.PATH?.split(";")||[];for(let e of t)for(let n of["mvn.cmd","mvn.bat","mvn"]){let o=oe(e,n);if(xe(o))return o}for(let e of["C:\\Program Files",Kt()])try{for(let n of Gt(e,{withFileTypes:!0}))if(n.isDirectory()&&n.name.startsWith("apache-maven")){let o=oe(e,n.name,"bin","mvn.cmd");if(xe(o))return o}}catch{}return"mvn"}function Vt(t){if(t){let n=oe(t,"backend","jre","bin",process.platform==="win32"?"java.exe":"java");if(xe(n))return n}let e=process.env.PATH?.split(";")||[];for(let n of e)for(let o of["java.exe","java"]){let s=oe(n,o);if(xe(s))return s}for(let n of["C:\\Program Files\\Java","C:\\Program Files (x86)\\Java",Kt()])try{for(let o of Gt(n,{withFileTypes:!0}))if(o.isDirectory()&&(o.name.startsWith("jdk")||o.name.startsWith("openjdk"))){let s=oe(n,o.name,"bin","java.exe");if(xe(s))return s}}catch{}return"java"}function St(t){let n=`"${ao()}" package -pl jwcode-web -am -q -DskipTests`;console.log(`[launcher] Building: ${n}`);try{let o=us(n,[],{cwd:t,stdio:"pipe",shell:!0,windowsHide:!0});if(o.status!==0)throw new Error(o.stderr.toString()||o.stdout.toString())}catch(o){console.error("[launcher] Build failed:",String(o)),process.exit(1)}ve(t)||(console.error("[launcher] Build succeeded but jar not found"),process.exit(1))}function We(t){try{return process.platform==="win32"?Pe(`netstat -ano | findstr :${t} | findstr LISTENING`,{encoding:"utf-8"}).trim().length>0:(Pe(`lsof -ti:${t}`,{stdio:"ignore"}),!0)}catch{return!1}}function Xt(t=8080,e=20){for(let n=t;n<t+e;n++){if(!We(n)&&!We(n+1))return{httpPort:n,wsPort:n+1};We(n+1)&&n++}throw new Error(`No available port pair found in range ${t}-${t+e}`)}function st(t){try{if(process.platform==="win32"){let e=Pe(`netstat -ano | findstr :${t} | findstr LISTENING`,{encoding:"utf-8"});for(let n of e.trim().split(`
|
|
3
|
+
`)){let o=n.trim().split(/\s+/).pop();if(o)try{Pe(`taskkill /F /PID ${o}`,{stdio:"ignore"}),console.log(`[launcher] Killed process on port ${t} (PID ${o})`)}catch{}}}else Pe(`lsof -ti:${t} | xargs kill -9 2>/dev/null`,{stdio:"ignore"})}catch{}}function Yt(t,e=60){let n=Date.now(),o=`http://localhost:${t}/api/system/status`;return new Promise(s=>{function c(){if(Date.now()-n>e*1e3){console.log(`[launcher] WARNING: Backend not responding after ${e}s`),s();return}fetch(o,{signal:AbortSignal.timeout(2e3)}).then(async d=>{let f=await d.text();d.status===200&&(f.includes("running")||f.includes("status"))?(console.log(`[launcher] Backend ready on port ${t}`),s()):setTimeout(c,1e3)}).catch(()=>setTimeout(c,1e3))}i(c,"check"),c()})}function gs(t){let{installDir:e,workspaceDir:n,port:o,wsPort:s,forceKill:c}=t,d=Vt(e),f=ve(e);f||(console.error("[launcher] Backend JAR not found. Run with --build first, or ensure backend/jwcode-web.jar exists."),process.exit(1)),c&&(st(o),st(s)),console.log(`[launcher] Starting backend: ${d} -jar ${f}`),console.log(`[launcher] Workspace: ${n}`);let m=["-jar",f,String(o),String(s),n],g=so(d,m,{cwd:n,env:{...process.env,JWCODE_WS_PORT:String(s)},stdio:["ignore","pipe","pipe"],windowsHide:!0});return g.stdout?.on("data",()=>{}),g.stderr?.on("data",w=>{let T=w.toString("utf-8").trim();T&&(T.includes("Address already in use")||T.includes("BindException"))&&console.error(`[backend] ERROR: Port ${o} is in use.`)}),g.on("exit",w=>{w!==0&&w!==null&&console.error(`[launcher] Backend process exited with code ${w}`)}),g}function hs(t){if(t)if(console.log(`
|
|
4
|
+
[jwcode] Shutting down...`),process.platform==="win32")try{Pe(`taskkill /F /T /PID ${t.pid}`,{stdio:"ignore"})}catch{try{t.kill()}catch{}}else{try{process.kill(-t.pid,"SIGTERM")}catch{}t.kill("SIGTERM"),setTimeout(()=>{if(t&&!t.killed){try{process.kill(-t.pid,"SIGKILL")}catch{}t.kill("SIGKILL")}},5e3)}}function yt(t,e,n,o){try{xs(io,{recursive:!0})}catch{}let s={pid:t,httpPort:e,wsPort:n,workspaceDir:o,startedAt:new Date().toISOString(),lastActivity:new Date().toISOString()};ws(bt,JSON.stringify(s,null,2),"utf-8")}function co(){try{return xe(bt)?JSON.parse(Ts(bt,"utf-8")):null}catch{return null}}function lo(){try{bs(bt)}catch{}}function uo(t){try{return process.platform==="win32"?Pe(`tasklist /FI "PID eq ${t.pid}" /NH`,{encoding:"utf-8",timeout:3e3}).includes(String(t.pid)):(Pe(`kill -0 ${t.pid}`,{stdio:"ignore"}),!0)}catch{return!1}}function zt(t){let{installDir:e,workspaceDir:n,port:o,wsPort:s,forceKill:c}=t,d=Vt(e),f=ve(e);f||(console.error("[launcher] Backend JAR not found. Run: npm install -g @jwcode/cli"),process.exit(1)),c&&(st(o),st(s));let m=["-jar",f,String(o),String(s),n],g=t.idleTimeout??300,w=so(d,m,{cwd:n,env:{...process.env,JWCODE_WS_PORT:String(s),JWCODE_DAEMON_IDLE_TIMEOUT:String(g)},stdio:"ignore",detached:!0,windowsHide:!0});return w.unref(),yt(w.pid,o,s,n),console.log(`[daemon] Started JWCode daemon (PID ${w.pid}) on ports ${o}/${s}`),w}function Qt(t){let e=co();return e?uo(e)?t&&e.workspaceDir!==t?null:e:(lo(),null):null}var ms,Jt,io,bt,kt=fn(()=>{"use strict";ms=fs(import.meta.url),Jt=Ft(ms);i(qt,"findInstallDir");i(ve,"findJar");i(ao,"findMvn");i(Vt,"findJava");i(St,"buildBackend");i(We,"portInUse");i(Xt,"findAvailablePorts");i(st,"killPort");i(Yt,"waitForBackend");i(gs,"startBackend");i(hs,"cleanupBackend");io=oe(Kt(),".jwcode"),bt=oe(io,"daemon.json");i(yt,"writeDaemonInfo");i(co,"readDaemonInfo");i(lo,"clearDaemonInfo");i(uo,"isDaemonAlive");i(zt,"startDaemon");i(Qt,"findRunningDaemon")});var tn={};mn(tn,{checkDaemonHealth:()=>Bs,checkForUpdates:()=>Os,runNpmUpdate:()=>Ls});import{execSync as Ms}from"node:child_process";import{homedir as mo}from"node:os";import{join as go}from"node:path";import{existsSync as vs,readFileSync as As,writeFileSync as _s,mkdirSync as Rs}from"node:fs";function Ps(){try{return vs(en)?JSON.parse(As(en,"utf-8")):null}catch{return null}}function Is(t){try{Rs(go(mo(),".jwcode"),{recursive:!0}),_s(en,JSON.stringify({lastCheck:Date.now(),latestVersion:t}))}catch{}}async function Os(t){let e=Ps();if(e&&Date.now()-e.lastCheck<Es)return{latest:e.latestVersion,current:t,url:"",body:"",publishedAt:"",updateAvailable:e.latestVersion!==t};try{let n=await fetch(Ds,{headers:{Accept:"application/vnd.github+json","User-Agent":"JWCode-CLI"}});if(!n.ok)return null;let o=await n.json(),s=(o.tag_name||"").replace(/^v/,"");return Is(s),{latest:s,current:t,url:o.html_url||"",body:o.body||"",publishedAt:o.published_at||"",updateAvailable:s!==t}}catch{return null}}function Ls(){try{let t=process.platform==="win32"?"npm.cmd":"npm";return{ok:!0,message:Ms(`"${t}" install -g @jwcode/cli@latest`,{encoding:"utf-8",stdio:"pipe",timeout:12e4}).trim()}}catch(t){return{ok:!1,message:String(t.stderr||t.message||t)}}}async function Bs(t){try{let e=await fetch(`http://localhost:${t}/api/system/status`,{signal:AbortSignal.timeout(5e3)});if(e.status===200){let n=await e.json();return n?.status==="running"||n?.success===!0}return!1}catch{return!1}}var Ds,en,Es,nn=fn(()=>{"use strict";Ds="https://api.github.com/repos/jwcode/jwcode/releases/latest",en=go(mo(),".jwcode","last_update_check.json"),Es=360*60*1e3;i(Ps,"readCache");i(Is,"writeCache");i(Os,"checkForUpdates");i(Ls,"runNpmUpdate");i(Bs,"checkDaemonHealth")});import{render as on}from"ink";import{createElement as rn}from"react";import{useState as ie,useEffect as jt,useRef as ot,useCallback as te}from"react";import{Box as Q,Text as ae,useStdout as as}from"ink";import{useState as qo,useRef as Ue,useEffect as ct}from"react";import{Box as Rt,Text as Te,useInput as Vo}from"ink";var Ho=0,Wo=new Map;function $o(t){let e=++Ho;return Wo.set(e,t),e}i($o,"storePaste");function _t(t){let e=$o(t),n=(t.match(/\n/g)||[]).length+1,o=[`Pasted text #${e} +${t.length} chars`];return n>1&&o.push(`+${n} lines`),{id:e,label:`[${o.join(" ")}]`}}i(_t,"pasteSummary");var hn={bg:"",text:"#ffffff",muted:"#999999",border:"#505050",brand:"#d77757",primary:"#d77757",success:"#4eba65",warning:"#ffc107",error:"#ff6b80",info:"#b1b9f9",user:"#7ab4e8",assistant:"#ffffff",system:"#ff6b80",tool:"#b1b9f9",thinking:"#999999",plan:"#48968c",auto:"#ff7814",connected:"#4eba65",disconnected:"#ff6b80",diffAdded:"#38a660",diffRemoved:"#b3596b",diffAddedBg:"#225c2b",diffRemovedBg:"#7a2936",diffHeader:"#b1b9f9",diffFileHeader:"#d77757",diffPlaceholder:"#505050"},jo={...hn,text:"#1f2328",assistant:"#1f2328",muted:"#656d76",border:"#d0d7de",primary:"#cf5a2f",diffAdded:"#116329",diffRemoved:"#cf222e",diffAddedBg:"#dafbe1",diffRemovedBg:"#ffebe9",diffHeader:"#0550ae",diffFileHeader:"#cf5a2f",diffPlaceholder:"#6e7781"},Uo={dark:hn,light:jo};function Jo(){return process.env.JWCODE_THEME==="light"?"light":"dark"}i(Jo,"detectTheme");function Fo(){try{let t=process.env.JWCODE_THEME_COLORS;if(t)return JSON.parse(t)}catch{}return null}i(Fo,"loadCustomColors");var Go=Jo(),gn=Fo();function Ko(){let t=Uo[Go];return gn?{...t,...gn}:t}i(Ko,"getTheme");var u=Ko();import{jsx as Ie,jsxs as Je}from"react/jsx-runtime";function Xo(t){let e=0,n=0;for(let o of t)/[一-鿿㐀-䶿豈-]/.test(o)?e++:n++;return Math.ceil(e/1.5+n/4)}i(Xo,"estimateTokens");function Ye({value:t,onChange:e,onSubmit:n,placeholder:o,disabled:s}){let c=Ue(t.length),[,d]=qo(0),f=Ue(t),m=Ue(e),g=Ue(n),w=Ue(s);ct(()=>{f.current=t}),ct(()=>{m.current=e}),ct(()=>{g.current=n}),ct(()=>{w.current=s}),c.current>t.length&&(c.current=t.length);let T=Ue({accumulating:!1,buf:""});Vo((M,a)=>{if(w.current)return;process.stderr.write(`[TextInput] input=${JSON.stringify(M.slice(0,20))} key.bs=${a.backspace} key.del=${a.delete} key.esc=${a.escape} key.ret=${a.return} key.ctrl=${a.ctrl} key.meta=${a.meta} key.tab=${a.tab} cursor=${c.current} val="${f.current.slice(0,20)}"
|
|
5
|
+
`);let r="[200~",p="[201~";if(M.includes(r)){if(T.current.accumulating=!0,T.current.buf=M.split(r).slice(1).join(r),T.current.buf.includes(p)){let l=T.current.buf.split(p);T.current.buf=l[0]||"",T.current.accumulating=!1;let{label:x}=_t(T.current.buf);m.current(f.current+x)}return}if(T.current.accumulating&&M.includes(p)){let l=M.split(p);T.current.buf+=l[0]||"",T.current.accumulating=!1;let{label:x}=_t(T.current.buf);m.current(f.current+x);return}if(T.current.accumulating){T.current.buf+=M;return}if(a.return){g.current(f.current);return}if(a.leftArrow){c.current=Math.max(0,c.current-1),d(l=>l+1);return}if(a.rightArrow){c.current=Math.min(f.current.length,c.current+1),d(l=>l+1);return}if(a.backspace){if(c.current>0){let l=c.current,x=f.current;m.current(x.slice(0,l-1)+x.slice(l)),c.current=l-1,d(b=>b+1)}return}if(a.delete&&c.current<f.current.length){let l=c.current,x=f.current;m.current(x.slice(0,l)+x.slice(l+1));return}if((M==="\x7F"||M==="\b"||M==="\x7F")&&!a.ctrl&&!a.meta){if(c.current>0){let l=c.current,x=f.current;m.current(x.slice(0,l-1)+x.slice(l)),c.current=l-1,d(b=>b+1)}return}if(M&&!a.ctrl&&!a.meta&&!a.tab&&!a.escape){let l=c.current,x=f.current;m.current(x.slice(0,l)+M+x.slice(l)),c.current=l+M.length,d(b=>b+1)}});let h=t||"",k=!h&&o,_=h?Xo(h):0,y=h.length,S=Math.min(c.current,t.length);return Je(Rt,{flexDirection:"column",children:[Ie(Rt,{children:h?Je(Te,{children:[Ie(Te,{children:t.slice(0,S)}),Ie(Te,{inverse:!0,children:t[S]||" "}),Ie(Te,{children:t.slice(S+1)})]}):Je(Te,{children:[Ie(Te,{dimColor:!0,children:o}),Ie(Te,{dimColor:!0,children:"\u25B6"})]})}),y>0&&Je(Rt,{children:[Je(Te,{dimColor:!0,children:[" ",y," chars ~ ",_," tokens"]}),Je(Te,{dimColor:!0,children:[" [",S+1,"/",y,"]"]}),_>1e5&&Ie(Te,{color:u.error,children:" WARN: Approaching context limit"})]})]})}i(Ye,"TextInput");import Dt from"ws";var Yo=3e4,zo=3e4,xn=50;function Et(t){try{process.stderr.write(t)}catch{}}i(Et,"stderr");function X(t,e){try{process.stderr.write("[dbg "+t+"] "+e+`
|
|
6
|
+
`)}catch{}}i(X,"debugLog");var lt=class{static{i(this,"JwCodeClient")}ws=null;handlers=new Map;_running=!1;_reconnecting=!1;_reconnectRetries=0;pingTimer=null;reconnectDelay=1e3;reconnectTimer=null;sessionId=null;backendUrl;wsUrl;token;constructor(e,n,o="default-token"){this.backendUrl=e,this.wsUrl=n,this.token=o}on(e,n){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(n),()=>this.handlers.get(e)?.delete(n)}async connect(){if(this._running=!0,this.ws){try{this.ws.close()}catch{}this.ws=null}return new Promise((e,n)=>{let o=!1,s=i((d,f)=>{o||(o=!0,d(f))},"settle");try{this.ws=new Dt(this.wsUrl)}catch(d){s(n,d);return}let c=this.ws._socket;c&&c.on("error",()=>{}),this.ws.on("message",d=>{let f;try{f=JSON.parse(d.toString())}catch{return}if(f.type==="auth_required"){this.ws.send(JSON.stringify({type:"auth",token:this.token}));return}if(f.type==="auth_success"){this._createSession().then(m=>{this.sessionId=m,this._startHeartbeat(),this._startReadLoop(),this._reconnecting=!1,this._reconnectRetries=0,this.reconnectDelay=1e3,s(e,m)}).catch(m=>s(n,m));return}if(f.type==="auth_failed"){s(n,new Error(`Auth failed: ${JSON.stringify(f)}`));return}}),this.ws.on("error",d=>{this.sessionId?this.dispatch({type:"error",data:`WebSocket error: ${d.message}`}):s(n,d)}),this.ws.on("close",()=>{this._stopHeartbeat(),!this.sessionId&&!this._reconnecting&&s(n,new Error("Connection closed before authentication")),this._running&&!this._reconnecting&&this._startReconnect()})})}async _createSession(){let n=await(await fetch(`${this.backendUrl}/api/sessions`,{method:"POST"})).json(),s=(n.data||{}).sessionId||n.sessionId||n.id||"default-session";return Et(`[ws] Session: ${s}
|
|
7
|
+
`),s}_startReadLoop(){this.ws&&this.ws.on("message",e=>{let n;try{n=JSON.parse(e.toString())}catch{return}n.type==="auth_required"||n.type==="auth_success"||n.type==="auth_failed"||this.dispatch(n)})}_startHeartbeat(){this._stopHeartbeat(),this.pingTimer=setInterval(()=>{if(this.ws?.readyState===Dt.OPEN)try{this.ws.send(JSON.stringify({type:"ping"}))}catch{}},Yo)}_stopHeartbeat(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null)}_startReconnect(){if(!(!this._running||this._reconnecting)){if(this._reconnectRetries>=xn){Et(`[ws] Max reconnect retries (${xn}) reached, giving up.
|
|
8
|
+
`),this.dispatch({type:"error",data:"Connection lost \u2014 max retries reached."});return}this._reconnecting=!0,this._reconnectRetries++,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.reconnectTimer=setTimeout(async()=>{try{Et(`[ws] Reconnecting (attempt ${this._reconnectRetries})...
|
|
9
|
+
`),this.dispatch({type:"notification",data:`Reconnecting (${this._reconnectRetries})...`}),await this.connect(),this.dispatch({type:"notification",data:"Reconnected."})}catch{this.reconnectDelay=Math.min(this.reconnectDelay*2,zo),this._reconnecting=!1,this._startReconnect()}},this.reconnectDelay)}}dispatch(e){let n=this.handlers.get(e.type);if(n)for(let o of n)try{o(e)}catch(s){console.error(`Handler error [${e.type}]:`,s)}}send(e,n,o){if(X("send",e+(n?" msg="+n.slice(0,40):"")+(o?" data="+JSON.stringify(o).slice(0,60):"")),!this.ws||this.ws.readyState!==Dt.OPEN){console.warn(`[ws] Not connected, dropping: ${e}`);return}let s={type:e,sessionId:this.sessionId};n!==void 0&&(s.message=n),o&&(s.data=JSON.stringify(o));try{this.ws.send(JSON.stringify(s))}catch(c){console.error(`[ws] send error [${e}]:`,c)}}chat(e,n=!1){this.send(n?"plan":"chat",e)}stop(){X("send","stop"),this.send("stop")}pause(){this.send("pause")}resume(){this.send("resume")}planConfirm(){this.send("plan_confirm")}updateDocs(){this.send("update_docs")}doctor(){this.send("doctor")}rewind(){this.send("rewind")}compact(){this.send("compact")}switchModel(e){this.send("model_change",void 0,{model:e})}approveHook(e){X("send","approveHook "+e),this.send("hook_allow",void 0,{approvalId:e})}denyHook(e){X("send","denyHook "+e),this.send("hook_deny",void 0,{approvalId:e})}exit(){this.send("exit")}init(){this.send("init")}effort(e){this.send("effort",void 0,{level:e})}branch(e){this.send("branch",void 0,{name:e})}mcp(e){this.send("mcp",void 0,{action:e})}skills(){this.send("skills")}agents(){this.send("agents")}config(e){this.send("config",void 0,{action:e})}plugin(e){this.send("plugin",void 0,{action:e})}async listFiles(e){try{let n=e?`${this.backendUrl}/api/files?path=${encodeURIComponent(e)}`:`${this.backendUrl}/api/files`,o=await fetch(n);if(!o.ok)return[];let s=await o.json(),c=[],d=i(f=>{for(let m of f)m.type==="file"&&c.push(m.path),m.children&&d(m.children)},"walk");return d(s?.data||s||[]),c}catch{return[]}}async readFileContent(e){try{let n=await fetch(`${this.backendUrl}/api/files/read?path=${encodeURIComponent(e)}`);if(!n.ok)return null;let o=await n.json();return o?.data||o}catch{return null}}async listSessions(){try{let n=await(await fetch(`${this.backendUrl}/api/sessions`)).json();return n?.data||n||[]}catch{return[]}}async deleteSession(e){try{return(await(await fetch(`${this.backendUrl}/api/sessions/${e}`,{method:"DELETE"})).json())?.success===!0}catch{return!1}}async getSessionMessages(e){try{return(await(await fetch(`${this.backendUrl}/api/sessions/${e}/messages`)).json())?.data||[]}catch{return[]}}async close(){this._running=!1,this._reconnecting=!1,this._stopHeartbeat(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(),this.ws=null)}};import{memo as cr,useState as lr,useEffect as dr,useRef as ur}from"react";import{Box as ze,Text as R}from"ink";import{useSyncExternalStore as Qo,useRef as Zo}from"react";function wn(t,e){let n=t,o=new Set;return{getState:i(()=>n,"getState"),setState:i(s=>{let c=n,d=s(c);if(!Object.is(d,c)){n=d,e?.({newState:d,oldState:c});for(let f of o)f()}},"setState"),subscribe:i(s=>(o.add(s),()=>o.delete(s)),"subscribe")}}i(wn,"createStore");var er={messages:[],currentMessage:null,usage:{promptTokens:0,completionTokens:0,totalTokens:0,usageRatio:0},planMode:!1,autoMode:!1,planWaiting:!1,scrollOffset:0,modelName:"",connected:!1,statusText:"connecting...",tokenRate:0,toolCallsExpanded:!1,planTasks:[],pdcaPhase:"",degradation:{active:!1,retryCount:0,maxRetries:0,mode:"normal",message:""},compactionProgress:null,contentHeight:0},Pt=null;function be(){return Pt||(Pt=wn(er)),Pt}i(be,"getStore");var tr=i(t=>t.currentMessage!==null,"selIsGenerating");var nr=i(t=>t.planTasks,"selPlanTasks"),or=i(t=>t.pdcaPhase,"selPdcaPhase"),rr=i(t=>t.degradation,"selDegradation"),sr=i(t=>({messages:t.messages,currentMessage:t.currentMessage,scrollOffset:t.scrollOffset,contentHeight:t.contentHeight}),"selChatArea"),ar=i(t=>({usage:t.usage,modelName:t.modelName,planMode:t.planMode,autoMode:t.autoMode,connected:t.connected,statusText:t.statusText,messagesLen:t.messages.length,tokenRate:t.tokenRate,compactionProgress:t.compactionProgress}),"selStatusLine");function ir(t,e){if(Object.is(t,e))return!0;if(t===null||e===null||typeof t!="object"||typeof e!="object")return!1;let n=Object.keys(t),o=Object.keys(e);return n.length!==o.length?!1:n.every(s=>Object.is(t[s],e[s]))}i(ir,"shallowEqual");function re(t){let e=be(),n=Zo(null),o=i(()=>{let s=t(e.getState()),c=n.current;return c!==null&&ir(s,c.value)?c.value:(n.current={value:s},s)},"getSnapshot");return Qo(e.subscribe,o,o)}i(re,"useAppSlice");var Tn=i(()=>re(tr),"useAppIsGenerating"),bn=i(()=>re(sr),"useAppChatArea"),It=i(()=>re(ar),"useAppStatusLine");var Sn=i(()=>re(nr),"useAppPlanTasks"),yn=i(()=>re(or),"useAppPdcaPhase"),kn=i(()=>re(rr),"useAppDegradation");function A(t){be().setState(t)}i(A,"updateAppState");import{Fragment as _e,jsx as I,jsxs as Y}from"react/jsx-runtime";function dt(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${Math.round(t/1e3)}K`:String(t)}i(dt,"formatTokens");function pr(t){return t<=0?"":t>=100?`${Math.round(t)}t/s`:t>=10?`${t.toFixed(1)}t/s`:`${t.toFixed(1)}t/s`}i(pr,"formatRate");function fr(t){if(t<=0)return"";if(t>=60){let e=Math.floor(t/60),n=t%60;return`${e}m${n}s`}return`${t}s`}i(fr,"formatElapsed");var Cn=cr(i(function(){X("app","StatusLine mount planMode="+It().planMode);let{usage:e,modelName:n,planMode:o,autoMode:s,connected:c,statusText:d,messagesLen:f,tokenRate:m,compactionProgress:g}=It(),w=kn(),T=yn(),h=Sn(),k=f,_=Tn(),y=ur(0),[S,M]=lr(Date.now());dr(()=>{if(_){y.current===0&&(y.current=Date.now());let we=setInterval(()=>M(Date.now()),1e3);return()=>clearInterval(we)}else y.current=0},[_]);let a=_?Math.floor((S-y.current)/1e3):0,r=Math.min(100,Math.round(e.usageRatio*100)),p=Math.round(r/10),l="\u2588".repeat(p)+"\u2591".repeat(10-p),x=n||(c?"ready":"connecting..."),b=o?" Plan ":" Act ",P=o?u.plan:u.success,B=o?"mode-plan":"mode-act",K=c?"\u25CF":"\u25CB",v=c?u.connected:u.disconnected,D=d.startsWith("Error:"),H=r>90?u.error:r>70?u.warning:u.text,ce=pr(m),$e=fr(a),V=e.promptTokens,se=e.completionTokens;return Y(ze,{flexDirection:"column",width:"100%",paddingRight:1,children:[Y(ze,{height:1,children:[I(R,{bold:!0,color:u.primary,children:"jwcode"}),I(R,{children:" "}),Y(R,{backgroundColor:P,color:"black",children:[" ",b," "]},B),I(R,{children:" "}),s&&Y(_e,{children:[I(R,{backgroundColor:u.auto,color:"black",children:" AUTO "}),I(R,{children:" "})]}),T&&Y(_e,{children:[Y(R,{backgroundColor:u.warning,color:"black",children:[" ",T," "]}),I(R,{children:" "})]}),h.length>0&&Y(_e,{children:[I(R,{color:u.primary,children:h.filter(we=>we.status==="completed").length}),I(R,{dimColor:!0,children:"/"}),I(R,{color:u.text,children:h.length}),I(R,{dimColor:!0,children:" tasks"}),I(R,{children:" "})]}),Y(R,{color:v,children:[K," "]}),I(R,{color:u.success,children:x}),I(R,{children:" "}),Y(R,{dimColor:!0,children:[k,"msgs"]}),V>0||se>0?Y(_e,{children:[I(R,{children:" "}),I(R,{color:u.info,children:dt(V)}),I(R,{dimColor:!0,children:"+"}),I(R,{color:u.success,children:dt(se)}),I(R,{dimColor:!0,children:"="}),I(R,{color:u.warning,children:dt(e.totalTokens)})]}):Y(_e,{children:[I(R,{children:" t:"}),I(R,{color:u.warning,children:dt(e.totalTokens)})]}),I(R,{children:" "}),Y(R,{color:H,children:[l," ",r,"%"]}),_&&ce&&Y(_e,{children:[I(R,{children:" "}),I(R,{color:u.tool,children:ce})]}),_&&$e&&Y(_e,{children:[I(R,{children:" "}),I(R,{color:u.primary,children:$e})]})]}),I(ze,{height:1,children:w.active?Y(R,{color:u.warning,dimColor:!0,children:["[",w.mode.toUpperCase(),"] ",w.message,w.retryCount>0?` (${w.retryCount}/${w.maxRetries})`:""]}):I(R,{children:" "})}),I(ze,{height:1,children:g?Y(_e,{children:[Y(R,{color:g.percent>=100?u.success:u.primary,children:[g.percent>=100?"\u2713":"\u2699"," ",g.message]}),I(R,{children:" "}),Y(R,{color:u.warning,children:["\u2588".repeat(Math.round(g.percent/10)),"\u2591".repeat(10-Math.round(g.percent/10))]}),Y(R,{dimColor:!0,children:[" ",g.percent,"%"]})]}):I(R,{children:" "})}),I(ze,{height:1,children:d&&d!=="connecting..."?I(R,{color:D?u.error:u.muted,dimColor:!D,children:d.slice(0,100)}):I(R,{children:" "})})]})},"StatusLine"));import{Box as z,Text as $}from"ink";import{useState as Bt,useMemo as Cr,useRef as pt,useLayoutEffect as ft,memo as Ze,forwardRef as In}from"react";import{measureElement as Mr}from"ink";import{useEffect as ba,useRef as Sa}from"react";import{useStdin as ka}from"ink";var mr={topRow:0,trackHeight:0,contentHeight:0,viewportHeight:0,termCols:80};function Mn(t){mr=t}i(Mn,"setScrollGeometry");import{memo as _n,useState as gr,useMemo as ut}from"react";import{Box as Se,Text as ye}from"ink";import{jsx as ke,jsxs as fe}from"react/jsx-runtime";var hr=/^(---|\+\+\+) /,xr=/^@@ /,wr=/^\\(?!.*\\$)/;var vn=30;function Tr(t){let e=t.split(`
|
|
10
|
+
`),n=[];for(let o of e){let s="context";hr.test(o)?s="fileHeader":xr.test(o)?s="hunkHeader":o.startsWith("+")?s="addition":o.startsWith("-")?s="deletion":wr.test(o)&&(s="placeholder");let c=o;(s==="addition"||s==="deletion")&&(c=o.slice(1)),n.push({type:s,text:c,raw:o})}return n}i(Tr,"parseDiff");function An(t,e){return t.filter(n=>n.type===e).length}i(An,"countByType");var Ot=_n(i(function({content:e,terminalCols:n=120,startCollapsed:o}){let s=ut(()=>Tr(e),[e]),c=s.length,d=ut(()=>An(s,"addition"),[s]),f=ut(()=>An(s,"deletion"),[s]),m=o??c>vn,[g,w]=gr(m),T=i(()=>w(a=>!a),"toggle"),h=n-6,k=ut(()=>{let a=[];for(let r of s)if(r.type==="fileHeader"&&r.raw.startsWith("+++")){let p=r.raw.replace(/^\+\+\+ (a|b)\//,"").trim();p&&p!=="/dev/null"&&a.push(p)}return[...new Set(a)]},[s]),_=k.length>0?k.join(", ")+` \u2192 +${d}/-${f}`:`Diff \u2192 +${d}/-${f}`;if(c===0)return null;let y=vn,S=g?s.slice(0,y):s,M=c-y;return fe(Se,{flexDirection:"column",paddingLeft:1,children:[fe(Se,{children:[fe(ye,{color:u.primary,bold:!0,children:[" ","[",g?"+":"-","]"," "]}),ke(ye,{color:u.muted,children:_})]}),ke(Se,{flexDirection:"column",children:S.map((a,r)=>ke(Sr,{line:a,maxWidth:h},r))}),g&&M>0&&fe(Se,{children:[fe(ye,{color:u.info,dimColor:!0,children:[" \u2026 ",M," more lines"," "]}),ke(ye,{color:u.primary,dimColor:!0,underline:!0,children:"[click or press to expand]"})]})]})},"DiffDisplay"));function br(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}i(br,"truncateLine");var Sr=_n(i(function({line:e,maxWidth:n}){let o=br(e.text,n);switch(e.type){case"fileHeader":return ke(Se,{children:fe(ye,{color:u.diffFileHeader,bold:!0,dimColor:!1,children:[" ",e.raw.slice(0,n)]})});case"hunkHeader":return ke(Se,{children:fe(ye,{color:u.diffHeader,dimColor:!0,children:[" ",e.raw.slice(0,n)]})});case"addition":return ke(Se,{children:fe(ye,{color:u.diffAdded,backgroundColor:u.diffAddedBg,children:[" + ",o]})});case"deletion":return ke(Se,{children:fe(ye,{color:u.diffRemoved,backgroundColor:u.diffRemovedBg,children:[" - ",o]})});case"placeholder":return ke(Se,{children:fe(ye,{color:u.diffPlaceholder,dimColor:!0,children:[" ",e.raw.slice(0,n)]})});default:return ke(Se,{children:fe(ye,{color:u.muted,dimColor:!0,children:[" ",o]})})}},"RenderDiffLine"));import{Box as le,Text as ee}from"ink";import{memo as yr}from"react";import{jsx as F,jsxs as Fe}from"react/jsx-runtime";var Lt=null;function kr(){if(!Lt)try{Lt=No("marked")}catch{return null}return Lt}i(kr,"getMarked");function Rn(t,e){let n=[],o=0;for(let s of t){let c=s,d=e+"-"+o++;switch(c.type){case"strong":n.push(F(ee,{bold:!0,children:Qe(c.tokens||[])},d));break;case"em":n.push(F(ee,{italic:!0,children:Qe(c.tokens||[])},d));break;case"codespan":n.push(F(ee,{color:u.warning,backgroundColor:"#2d2d2d",children:c.text||""},d));break;case"link":{let f=Qe(c.tokens||[]),m=c.href||"";n.push(F(ee,{color:u.info,children:f+" ("+m+")"},d));break}default:n.push(F(ee,{children:c.text||c.raw||""},d));break}}return n}i(Rn,"renderInlineTokens");function Qe(t){return t.map(e=>e.text||e.raw||"").join("")}i(Qe,"renderPlainText");var Dn=yr(i(function({content:e,terminalCols:n}){let o=kr();if(!o||!e)return F(ee,{children:e});let s=[];try{s=new o.Lexer().lex(e)}catch{return F(ee,{children:e})}let c=[],d=0;for(let f of s){let m="md-"+d++,g=f;switch(g.type){case"heading":{let w=g.depth||1,T="#".repeat(w)+" ";c.push(F(le,{marginTop:w===1?1:0,children:Fe(ee,{bold:!0,color:w<=2?u.primary:u.muted,children:[T,Qe(g.tokens||[])]})},m));break}case"paragraph":c.push(F(le,{paddingLeft:0,children:F(ee,{children:Rn(g.tokens||[],m)})},m));break;case"code":{let w=g.lang||"",T=g.text||"",h=Math.min(n-4,100),k=T.split(`
|
|
11
|
+
`);c.push(Fe(le,{flexDirection:"column",marginY:0,children:[w&&F(le,{paddingLeft:1,children:Fe(ee,{dimColor:!0,children:["\u250C\u2500 ",w]})}),k.map((_,y)=>F(le,{paddingLeft:2,children:F(ee,{color:u.muted,dimColor:!0,children:_.slice(0,h)})},m+"-l"+y))]},m));break}case"blockquote":c.push(F(le,{flexDirection:"column",paddingLeft:2,children:(g.tokens||[]).map((w,T)=>Fe(le,{children:[Fe(ee,{dimColor:!0,children:["\u2502"," "]}),F(ee,{italic:!0,children:w.text||Qe(w.tokens||[])})]},m+"-b"+T))},m));break;case"list":{let w=g.items||[];c.push(F(le,{flexDirection:"column",children:w.map((T,h)=>{let k=g.ordered?(g.start||1)+h+". ":" \u2022 ";return Fe(le,{paddingLeft:1,children:[F(ee,{dimColor:!0,children:k}),F(le,{flexDirection:"column",children:(T.tokens||[]).map((_,y)=>_.type==="text"?F(ee,{children:Rn(_.tokens||[],m+"-it"+y)},m+"-it"+y):F(ee,{children:_.text||""},m+"-ip"+y))})]},m+"-i"+h)})},m));break}case"hr":c.push(F(le,{children:F(ee,{dimColor:!0,children:"\u2500".repeat(Math.min(n-2,60))})},m));break;case"space":break;default:g.raw&&c.push(F(ee,{children:g.raw.trimEnd()},m));break}}return F(le,{flexDirection:"column",children:c})},"MarkdownRenderer"));import{Fragment as Hn,jsx as E,jsxs as J}from"react/jsx-runtime";var En="-".repeat(60),gt=200,vr=6;function ht(t){if(t<=0)return"";if(t>=60){let e=Math.floor(t/60),n=t%60;return e+"m"+n+"s"}return t+"s"}i(ht,"formatDuration");function On(t){if(!t||t.length<20)return!1;let e=t.split(`
|
|
12
|
+
`),n=!1,o=!1,s=0;for(let c of e)/^--- .+\/|^\+\+\+ .+\//.test(c)&&(n=!0),/^@@ -\d+,\d+ +\d+,\d+ @@/.test(c)&&(o=!0),/^[+-]/.test(c)&&!/^[+-]{3}/.test(c)&&!/^[+-]{4}/.test(c)&&s++;return(n||o)&&s>=2}i(On,"isDiffContent");function Ln(t,e){let n=t[e];if(!n)return!0;if(n.status==="running")return!1;let o=-1;for(let s=t.length-1;s>=0;s--)if(t[s].status==="complete"||t[s].status==="error"){o=s;break}return e!==o}i(Ln,"shouldStartCollapsed");var Ar="\xB7",Pn="#",_r="^",Rr="v";function Dr({contentHeight:t,offset:e,viewportHeight:n}){let o=Math.max(2,n-2),s=Math.max(1,Math.floor(o*n/Math.max(t,1))),c=Math.max(0,t-n),d=c>0?Math.round((o-s)*e/c):0,f=[];for(let m=0;m<o;m++)m>=d&&m<d+s?f.push(Pn):f.push(Ar);return J(z,{flexDirection:"column",width:2,flexShrink:0,minWidth:2,children:[E($,{color:u.border,children:_r}),f.map((m,g)=>E($,{color:m===Pn?u.text:u.border,children:m},g)),E($,{color:u.border,children:Rr})]})}i(Dr,"Scrollbar");function Bn({content:t,terminalCols:e}){return On(t)?E(Ot,{content:t,terminalCols:e}):E(Dn,{content:t,terminalCols:e})}i(Bn,"MessageContent");function Er({result:t,terminalCols:e}){if(On(t)){let o=t.split(`
|
|
13
|
+
`),s=o.filter(g=>g.startsWith("+")&&!g.startsWith("+++")).length,c=o.filter(g=>g.startsWith("-")&&!g.startsWith("---")).length,d=`+${s}/-${c}`,m=t.length>2e3?t.slice(0,2e3)+`
|
|
14
|
+
... (truncated)`:t;return J(z,{flexDirection:"column",paddingLeft:2,children:[J($,{dimColor:!0,children:["Diff: ",d]}),E(Ot,{content:m,terminalCols:e})]})}let n=t.length>500?t.slice(0,500)+"...":t;return E($,{color:u.muted,dimColor:!0,children:n})}i(Er,"ToolResult");var Pr=Ze(i(function({step:e}){let n=e.status==="success"?"[ok]":e.status==="error"?"[!!]":e.status==="running"?"[..]":"[--]",o=e.status==="success"?u.success:e.status==="error"?u.error:e.status==="running"?u.primary:u.primary,s=e.duration?ht(e.duration):e.status==="running"&&e.timestamp?ht(Math.floor((Date.now()-e.timestamp)/1e3)):"";return J(z,{flexDirection:"column",children:[J(z,{children:[J($,{color:o,children:[" ",n," "]}),E($,{bold:!0,color:o,children:e.title}),s&&J(Hn,{children:[E($,{dimColor:!0,children:" "}),E($,{color:u.muted,dimColor:!0,children:s})]})]}),e.thought&&J($,{color:u.info,dimColor:!0,children:[" ",Ge(e.thought,200)]}),e.action&&J($,{color:u.warning,children:[" ",Ge(e.action,200)]}),e.result&&J($,{color:u.success,children:[" ",Ge(e.result,300)]})]})},"StepDisplay")),Nn=Ze(i(function({tc:e,collapsed:n,onToggle:o,terminalCols:s}){let c=e.status==="complete"?"[ok]":e.status==="running"?"[..]":"[!!]",d=e.status==="complete"?u.success:e.status==="running"?u.warning:u.error,f=e.duration?ht(e.duration):e.status==="running"&&e.timestamp?ht(Math.floor((Date.now()-e.timestamp)/1e3)):"";return J(z,{flexDirection:"column",paddingLeft:1,children:[J(z,{children:[J($,{color:d,children:[" ",c," "]}),E($,{bold:!0,color:u.tool,children:e.name}),f&&J(Hn,{children:[E($,{dimColor:!0,children:" "}),E($,{color:u.muted,dimColor:!0,children:f})]}),E($,{dimColor:!0,children:" "}),J($,{color:u.info,dimColor:!0,children:["[",n?"+":"-","]"]})]}),!n&&e.args&&E(z,{paddingLeft:4,children:E($,{dimColor:!0,children:Ge(Br(e.args),200)})}),e.result&&E(z,{paddingLeft:2,flexDirection:"column",children:E(Er,{result:e.result,terminalCols:s})})]})},"ToolCallDisplay")),Ir=Ze(In(i(function({msg:e,expandedMessages:n,expandedTools:o,toolCallsExpanded:s,onToggleTool:c,onToggleMessage:d,terminalCols:f},m){return J(z,{flexDirection:"column",marginBottom:1,ref:m,children:[e.type==="user"&&J(z,{flexDirection:"column",children:[E($,{dimColor:!0,children:En}),J($,{color:u.user,bold:!0,children:[">"," ",e.content]})]}),e.type==="assistant"&&J(z,{flexDirection:"column",children:[E($,{children:" "}),e.steps.map((g,w)=>E(Pr,{step:g},g.id||w)),e.thinking&&J(z,{flexDirection:"column",children:[E($,{dimColor:!0,italic:!0,children:n.has(e.id)?e.thinking:Ge(e.thinking,gt)}),e.thinking.length>gt&&J($,{dimColor:!0,children:["[",e.thinking.length-gt," more chars]"," -> to expand"]})]}),e.toolCalls.map((g,w)=>{let T=g.id||g.name||"tool-"+e.id+"-"+w,h=Ln(e.toolCalls,w),k=o.has(T);return E(Nn,{tc:g,terminalCols:f,collapsed:s||k?!1:h,onToggle:()=>c(T)},T)}),e.content&&E(z,{paddingLeft:1,children:E(Bn,{content:e.content,terminalCols:f})}),E($,{dimColor:!0,children:En})]}),e.type==="system"&&E(z,{children:J($,{color:u.error,children:["Error: ",e.content]})})]})},"MessageItem")),(t,e)=>t.msg.id===e.msg.id&&t.msg.content===e.msg.content&&t.msg.thinking===e.msg.thinking&&t.msg.type===e.msg.type&&t.expandedMessages.has(t.msg.id)===e.expandedMessages.has(e.msg.id)&&t.toolCallsExpanded===e.toolCallsExpanded&&t.terminalCols===e.terminalCols),Or=Ze(In(i(function({msg:e,expandedTools:n,toolCallsExpanded:o,onToggleTool:s,terminalCols:c},d){return J(z,{flexDirection:"column",ref:d,children:[e.thinking&&E($,{dimColor:!0,italic:!0,children:Ge(e.thinking,gt)}),e.toolCalls.map((f,m)=>{let g=f.id||f.name||"tool-"+e.id+"-"+m,w=Ln(e.toolCalls,m),T=n.has(g);return E(Nn,{tc:f,terminalCols:c,collapsed:o||T?!1:w,onToggle:()=>s(g)},g)}),e.content&&E(z,{paddingLeft:1,children:E(Bn,{content:e.content,terminalCols:c})})]})},"StreamingMessage")));function mt(t,e){if(t.type==="user")return 3;let n=4;t.thinking&&(n+=Math.ceil(t.thinking.length/Math.max(1,e))+1),n+=t.steps.length;for(let o of t.toolCalls)n+=2,o.result&&(n+=Math.min(20,Math.ceil(o.result.length/Math.max(1,e))));return t.content&&(n+=Math.ceil(t.content.length/Math.max(1,e))),n}i(mt,"defaultMessageHeight");function Lr(t){let e=t,n=0;for(;e;){let o=e.yogaNode;if(!o||typeof o.getComputedTop!="function")break;n+=o.getComputedTop(),e=e.parentNode??null}return n}i(Lr,"getAbsoluteTopRow");var Nt=Ze(i(function({terminalCols:e,terminalRows:n}){let{messages:o,currentMessage:s,scrollOffset:c}=bn(),d=re(v=>v.toolCallsExpanded),[f,m]=Bt(new Set),[g,w]=Bt(new Set),[,T]=Bt(0),h=Math.max(3,n-vr),k=pt(new Map),_=pt(new Map),y=pt(0),S=pt(null),M=Cr(()=>s?o.filter(v=>v.id!==s.id):o,[o,s&&s.id]);ft(()=>{let v=0,D=k.current,H=_.current,ce=Math.max(10,e-4);for(let[V,se]of D)try{let{height:we}=Mr(se);we>0&&(H.set(V,we),v+=we)}catch{}for(let V of M)if(!D.has(V.id)){let se=H.get(V.id)??mt(V,ce);H.set(V.id,se),v+=se}if(s){let V=s,se=H.get(V.id)??mt(V,ce);H.set(V.id,se),v+=se}v+=1,v!==y.current&&(y.current=v,A(V=>V.contentHeight===v?V:{...V,contentHeight:v}));let $e=Lr(S.current)+1;Mn({topRow:$e,trackHeight:Math.max(2,h-2),contentHeight:v,viewportHeight:h,termCols:e})});let a=Math.min(c,Math.max(0,y.current-h)),r=M.length,p=0;if(a===0){let v=0;for(let D=r-1;D>=0;D--){let H=_.current.get(M[D].id)??mt(M[D],Math.max(10,e-4));if(v+=H,v>h){p=D+1;break}p=D}}else{let v=0,D=a+h;for(let H=r-1;H>=0;H--){let ce=_.current.get(M[H].id)??mt(M[H],Math.max(10,e-4));if(v+=ce,v>D){p=H;break}p=H}}p=Math.max(0,p);let l=M.slice(p);ft(()=>{let v=Math.max(0,y.current-h);c>v&&A(D=>({...D,scrollOffset:v}))},[c,h]),ft(()=>{let v=new Set(M.map(D=>D.id));s&&v.add(s.id);for(let D of _.current.keys())v.has(D)||(_.current.delete(D),k.current.delete(D))});let x=i(v=>{m(D=>{let H=new Set(D);return H.has(v)?H.delete(v):H.add(v),H})},"toggleExpandTool"),b=i(v=>{w(D=>{let H=new Set(D);return H.has(v)?H.delete(v):H.add(v),H})},"toggleExpandMessage"),P=y.current,B=P>h||c>0,K=i(v=>D=>{D?k.current.set(v,D):k.current.delete(v)},"registerMessageRef");return ft(()=>{T(v=>v+1)},[p,l.length,s&&s.id,f.size,g.size,d]),J(z,{flexDirection:"row",width:"100%",overflow:"hidden",ref:S,children:[J(z,{flexGrow:1,flexDirection:"column",overflow:"hidden",children:[E(z,{children:E($,{dimColor:!B,bold:B,children:B?`[${p+1}-${r} / ${r}]`:`[${r}]`})}),l.map(v=>E(Ir,{ref:K(v.id),msg:v,expandedMessages:g,expandedTools:f,terminalCols:e,toolCallsExpanded:d,onToggleTool:x,onToggleMessage:b},v.id)),s&&E(Or,{ref:K(s.id),msg:s,terminalCols:e,expandedTools:f,toolCallsExpanded:d,onToggleTool:x},s.id)]}),B&&E(Dr,{contentHeight:P,offset:a,viewportHeight:h})]})},"ChatArea"));function Br(t){if(typeof t!="string")return JSON.stringify(t,null,2);try{return JSON.stringify(JSON.parse(t),null,2)}catch{return t}}i(Br,"formatJson");function Ge(t,e){let n=typeof t=="string"?t:String(t??"");return n.length<=e?n:n.slice(0,e)+"..."}i(Ge,"truncate");import{useState as Wn,useMemo as Wr,useEffect as $n}from"react";import{Box as Tt,Text as Oe,useInput as $r,useStdout as jr}from"ink";var Nr=[{cmd:"/help",desc:"\u663E\u793A\u6240\u6709\u547D\u4EE4",via:"local",action:null},{cmd:"/plan",desc:"\u5207\u6362\u89C4\u5212\u6A21\u5F0F (\u5148\u89C4\u5212\u518D\u6267\u884C)",via:"local",action:"plan_mode"},{cmd:"/auto",desc:"\u5207\u6362\u81EA\u52A8\u6A21\u5F0F (\u81EA\u52A8\u6279\u51C6\u5DE5\u5177\u6267\u884C)",via:"local",action:"auto_mode"},{cmd:"/context",desc:"\u663E\u793A\u5F53\u524D\u4F1A\u8BDD\u72B6\u6001",via:"local",action:"show_context"},{cmd:"/exit",desc:"\u9000\u51FA JWCode",via:"local",action:"__exit__"}],Hr=[{cmd:"/confirm",desc:"\u786E\u8BA4\u5F53\u524D\u89C4\u5212\u5E76\u5F00\u59CB\u6267\u884C",via:"ws",action:"__confirm_plan"},{cmd:"/cancel",desc:"\u53D6\u6D88\u5F53\u524D\u89C4\u5212",via:"ws",action:"__cancel_plan"},{cmd:"/stop",desc:"\u505C\u6B62\u5F53\u524D AI \u751F\u6210",via:"ws",action:"stop"},{cmd:"/pause",desc:"\u6682\u505C\u5F53\u524D AI \u751F\u6210",via:"ws",action:"pause"},{cmd:"/resume",desc:"\u6062\u590D\u6682\u505C\u7684 AI \u751F\u6210",via:"ws",action:"resume"},{cmd:"/clear",desc:"\u6E05\u9664\u5F53\u524D\u4F1A\u8BDD\u6D88\u606F",via:"ws",action:"clear"},{cmd:"/doctor",desc:"\u8FD0\u884C\u7CFB\u7EDF\u81EA\u8BCA\u65AD",via:"ws",action:"doctor"},{cmd:"/rewind",desc:"\u56DE\u6EDA\u5230\u6700\u8FD1\u7684\u68C0\u67E5\u70B9",via:"ws",action:"rewind"},{cmd:"/compact",desc:"\u538B\u7F29\u4F1A\u8BDD\u4E0A\u4E0B\u6587 (\u91CA\u653E token)",via:"ws",action:"compact"},{cmd:"/model",desc:"\u5207\u6362 AI \u6A21\u578B (\u7528\u6CD5: /model <\u6A21\u578B\u540D> \u6216 /model \u6253\u5F00\u9009\u62E9\u5668)",via:"ws",action:"model_change"},{cmd:"/setup",desc:"\u914D\u7F6E AI \u63D0\u4F9B\u5546\u548C API Key",via:"local",action:"setup_wizard"},{cmd:"/init",desc:"\u5206\u6790\u9879\u76EE\u5E76\u751F\u6210 JWCODE.md \u9879\u76EE\u8BB0\u5FC6\u6587\u4EF6",via:"ws",action:"init"},{cmd:"/effort",desc:"\u8BBE\u7F6E\u4EFB\u52A1\u52AA\u529B\u7EA7\u522B (low/medium/high)",via:"ws",action:"effort"},{cmd:"/branch",desc:"\u521B\u5EFA\u5206\u652F\u4F1A\u8BDD (\u7528\u6CD5: /branch <\u540D\u79F0>)",via:"ws",action:"branch"},{cmd:"/mcp",desc:"MCP \u670D\u52A1\u5668\u7BA1\u7406 (list/add/remove)",via:"ws",action:"mcp"},{cmd:"/skills",desc:"\u67E5\u770B\u53EF\u7528 Skills \u5217\u8868",via:"ws",action:"skills"},{cmd:"/agents",desc:"\u5217\u51FA\u914D\u7F6E\u7684 Agent \u4EE3\u7406",via:"ws",action:"agents"},{cmd:"/config",desc:"\u7BA1\u7406\u914D\u7F6E (get/set/list)",via:"ws",action:"config"},{cmd:"/plugin",desc:"\u63D2\u4EF6\u7BA1\u7406 (install/list/remove)",via:"ws",action:"plugin"},{cmd:"/tokens",desc:"\u663E\u793A Token \u4F7F\u7528\u8BE6\u60C5",via:"ws",action:"tokens"},{cmd:"/memory",desc:"\u6D4F\u89C8\u9879\u76EE\u8BB0\u5FC6",via:"ws",action:"memory"},{cmd:"/export",desc:"\u5BFC\u51FA\u4F1A\u8BDD (\u7528\u6CD5: /export <\u8DEF\u5F84>)",via:"ws",action:"export"},{cmd:"/checkpoint",desc:"\u8BBE\u7F6E\u6216\u6062\u590D\u68C0\u67E5\u70B9",via:"ws",action:"checkpoint"},{cmd:"/test",desc:"\u8FD0\u884C\u5F53\u524D\u9879\u76EE\u6D4B\u8BD5",via:"ws",action:"test"},{cmd:"/lint",desc:"\u5BF9\u53D8\u66F4\u6587\u4EF6\u8FD0\u884C Linter",via:"ws",action:"lint"},{cmd:"/search",desc:"\u641C\u7D22\u4EE3\u7801\u5E93 (\u7528\u6CD5: /search <\u5173\u952E\u8BCD>)",via:"ws",action:"search"},{cmd:"/project",desc:"\u751F\u6210\u9879\u76EE\u6587\u6863",via:"ws",action:"project"}],Ht=[...Nr,...Hr],xt={"/help":null,"/plan":{action:"plan_mode"},"/auto":{action:"auto_mode"},"/context":{action:"show_context"},"/exit":{action:"__exit__"},"/quit":{action:"__exit__"},"/confirm":{action:"__confirm_plan"},"/cancel":{action:"__cancel_plan"},"/stop":{action:"stop"},"/pause":{action:"pause"},"/resume":{action:"resume"},"/clear":{action:"clear"},"/doctor":{action:"doctor"},"/rewind":{action:"rewind"},"/compact":{action:"compact"},"/model":{action:"model_change",needsArg:!1},"/setup":{action:"setup_wizard"},"/init":{action:"init"},"/effort":{action:"effort",needsArg:!0},"/branch":{action:"branch",needsArg:!0},"/mcp":{action:"mcp",needsArg:!0},"/skills":{action:"skills"},"/agents":{action:"agents"},"/config":{action:"config",needsArg:!0},"/plugin":{action:"plugin",needsArg:!0},"/tokens":{action:"tokens"},"/memory":{action:"memory"},"/export":{action:"export",needsArg:!0},"/checkpoint":{action:"checkpoint"},"/test":{action:"test"},"/lint":{action:"lint"},"/search":{action:"search",needsArg:!0},"/project":{action:"project"}},wt=`
|
|
15
15
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
16
16
|
\u2551 JWCode \u547D\u4EE4\u5E2E\u52A9 \u2551
|
|
17
17
|
\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
|
|
@@ -61,23 +61,23 @@ var dn=Object.defineProperty;var c=(t,e)=>dn(t,"name",{value:e,configurable:!0})
|
|
|
61
61
|
\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
|
|
62
62
|
\u2551 \u666E\u901A\u8F93\u5165\u5373\u53D1\u9001\u804A\u5929\u6D88\u606F \u2551
|
|
63
63
|
\u2551 \u8F93\u5165\u6846\u663E\u793A\u5B57\u7B26\u6570+token\u4F30\u7B97 \u2551
|
|
64
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;import{jsx as
|
|
65
|
-
`+e.slice(0,160)}return e.length>200?e.slice(0,200)+"...":e}
|
|
66
|
-
`,
|
|
64
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;import{jsx as et,jsxs as Ke}from"react/jsx-runtime";function jn({filter:t,onSelect:e}){let[n,o]=Wn(0),[s,c]=Wn(0),{stdout:d}=jr(),f=d?.rows||24,m=Wr(()=>{let T=t.replace(/^\//,"").toLowerCase();return T?Ht.filter(h=>h.cmd.toLowerCase().includes(T)||h.desc.includes(T)):Ht},[t]);$n(()=>{o(0),c(0)},[t]);let g=Math.max(5,Math.min(f-13,10));$n(()=>{c(T=>n<T?n:n>=T+g?n-g+1:T)},[n,g]);let w=m.slice(s,s+g);return $r((T,h)=>{if(h.escape){e(null);return}if(h.downArrow){o(k=>Math.min(k+1,m.length-1));return}if(h.upArrow){o(k=>Math.max(k-1,0));return}if(h.pageDown){o(k=>Math.min(k+g,m.length-1));return}if(h.pageUp){o(k=>Math.max(k-g,0));return}if(h.home){o(0);return}if(h.end){o(m.length-1);return}h.return&&m.length>0&&n>=0&&n<m.length&&e(m[n].cmd)}),Ke(Tt,{flexDirection:"column",borderStyle:"single",borderColor:u.primary,paddingX:1,width:52,children:[Ke(Tt,{children:[et(Oe,{bold:!0,color:u.primary,children:"\u547D\u4EE4\u5217\u8868"}),et(Oe,{dimColor:!0,children:" \u2191\u2193\u9009\u62E9 / PgUp/PgDn\u7FFB\u9875 / \u56DE\u8F66\u786E\u8BA4 / Esc\u53D6\u6D88"})]}),w.map((T,h)=>{let k=s+h;return Ke(Tt,{paddingLeft:1,children:[et(Oe,{color:k===n?u.primary:void 0,bold:k===n,children:k===n?"> ":" "}),et(Oe,{color:u.success,children:T.cmd}),Ke(Oe,{dimColor:!0,children:[" ",T.desc]}),Ke(Oe,{color:T.via==="ws"?u.warning:u.info,dimColor:k!==n,children:["(",T.via==="ws"?"\u540E\u7AEF":"\u672C\u5730",")"]})]},T.cmd)}),m.length>g&&et(Tt,{children:Ke(Oe,{dimColor:!0,children:[" ",s+1,"-",Math.min(s+g,m.length)," / ",m.length]})})]})}i(jn,"CommandPalette");import{useState as Un,useMemo as Ur,useEffect as Jn}from"react";import{Box as tt,Text as Re,useInput as Jr,useStdout as Fr}from"ink";import{jsx as De,jsxs as nt}from"react/jsx-runtime";var Fn=60;function Gr(t){let e=t.replace(/\\/g,"/").split("/");return e[e.length-1]||t}i(Gr,"basename");function Kr(t){let e=t.replace(/\\/g,"/").split("/");return e.pop(),e.join("/")||"."}i(Kr,"dirname");function Gn({query:t,files:e,onSelect:n}){let[o,s]=Un(0),[c,d]=Un(0),{stdout:f}=Fr(),m=f?.rows||24,g=Ur(()=>{if(!t)return e;let h=t.toLowerCase().replace(/\\/g,"/");return e.filter(k=>k.toLowerCase().replace(/\\/g,"/").includes(h))},[e,t]);Jn(()=>{s(0),d(0)},[t]);let w=Math.max(4,Math.min(m-13,8));Jn(()=>{d(h=>o<h?o:o>=h+w?o-w+1:h)},[o,w]);let T=g.slice(c,c+w);return Jr((h,k)=>{if(k.escape){n(null);return}if(k.downArrow){s(_=>Math.min(_+1,g.length-1));return}if(k.upArrow){s(_=>Math.max(_-1,0));return}if(k.pageDown){s(_=>Math.min(_+w,g.length-1));return}if(k.pageUp){s(_=>Math.max(_-w,0));return}k.return&&g.length>0&&o>=0&&o<g.length&&n(g[o])}),nt(tt,{flexDirection:"column",borderStyle:"single",borderColor:u.warning,paddingX:1,width:64,children:[nt(tt,{children:[De(Re,{bold:!0,color:u.warning,children:"@ \u641C\u7D22: "}),De(Re,{color:u.success,children:t||"(\u8F93\u5165\u6587\u4EF6\u540D)"}),De(Re,{dimColor:!0,children:" \u2191\u2193 \u9009\u62E9 \xB7 Enter \u63D2\u5165 \xB7 Esc \u5173\u95ED"})]}),g.length===0&&De(tt,{paddingLeft:1,children:De(Re,{dimColor:!0,children:" \u672A\u627E\u5230\u5339\u914D\u6587\u4EF6"})}),T.map((h,k)=>{let _=c+k,y=Gr(h),S=Kr(h),M=h.length>Fn?"..."+h.slice(-(Fn-3)):h;return nt(tt,{paddingLeft:1,children:[De(Re,{color:_===o?u.warning:void 0,bold:_===o,children:_===o?"\u276F ":" "}),De(Re,{color:u.success,children:y}),nt(Re,{dimColor:!0,children:[" \u2014 ",S]})]},h)}),g.length>w&&De(tt,{children:nt(Re,{dimColor:!0,children:[" ",c+1,"-",Math.min(c+w,g.length)," / ",g.length]})})]})}i(Gn,"FilePalette");import{useState as Wt,useMemo as qr,useEffect as Kn}from"react";import{Box as qe,Text as me,useInput as Vr,useStdout as Xr}from"ink";import{jsx as Me,jsxs as Ee}from"react/jsx-runtime";function qn({sessions:t,onSelect:e,onDelete:n}){let[o,s]=Wt(0),[c,d]=Wt(0),[f,m]=Wt(""),{stdout:g}=Xr(),w=g?.rows||24,T=qr(()=>{let y=f.toLowerCase();return y?t.filter(S=>S.title.toLowerCase().includes(y)||S.id.toLowerCase().includes(y)):t},[t,f]);Kn(()=>{s(0),d(0)},[f]);let h=Math.max(5,Math.min(w-12,10));Kn(()=>{d(y=>o<y?o:o>=y+h?o-h+1:y)},[o,h]);let k=T.slice(c,c+h);Vr((y,S)=>{if(S.escape){e(null);return}if(S.downArrow){s(M=>Math.min(M+1,T.length-1));return}if(S.upArrow){s(M=>Math.max(M-1,0));return}if(S.pageDown){s(M=>Math.min(M+h,T.length-1));return}if(S.pageUp){s(M=>Math.max(M-h,0));return}S.return&&T.length>0&&o>=0&&o<T.length&&e(T[o]),S.delete&&n&&T.length>0&&o>=0&&o<T.length&&n(T[o].id),!S.ctrl&&!S.meta&&y&&y.length===1&&!S.return&&!S.escape&&m(M=>M+y),(S.backspace||S.delete)&&m(M=>M.slice(0,-1))});let _=i(y=>{try{let S=new Date(y);return S.toLocaleDateString()+" "+S.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}catch{return y}},"formatDate");return Ee(qe,{flexDirection:"column",borderStyle:"single",borderColor:u.primary,paddingX:1,width:66,children:[Ee(qe,{children:[Me(me,{bold:!0,color:u.primary,children:"Session History"}),Me(me,{dimColor:!0,children:" type to filter / Enter resume / Del delete / Esc close"})]}),f&&Ee(qe,{paddingLeft:1,children:[Me(me,{dimColor:!0,children:"Filter: "}),Me(me,{color:u.warning,children:f})]}),k.length===0&&Me(qe,{paddingLeft:2,children:Me(me,{dimColor:!0,children:"No sessions found."})}),k.map((y,S)=>{let M=c+S;return Ee(qe,{paddingLeft:1,children:[Me(me,{color:M===o?u.primary:void 0,bold:M===o,children:M===o?"> ":" "}),Me(me,{color:u.success,children:y.id}),Ee(me,{dimColor:!0,children:[" ",y.title.slice(0,30)]}),Ee(me,{color:u.muted,children:[" [",y.messageCount," msgs]"]}),Ee(me,{dimColor:!0,children:[" ",_(y.updatedAt||y.createdAt)]})]},y.id)}),T.length>h&&Me(qe,{children:Ee(me,{dimColor:!0,children:[" ",c+1,"-",Math.min(c+h,T.length)," / ",T.length]})})]})}i(qn,"SessionPicker");import{useState as Vn,useEffect as Xn,useRef as Yr}from"react";import{Box as de,Text as ge,useInput as zr}from"ink";import{jsx as ue,jsxs as he}from"react/jsx-runtime";var Yn=15;function Qr(t,e){let n=t.toLowerCase();return/\b(rm|del|delete|drop|truncate|format|mkfs)\b/.test(n)?{level:"CRITICAL",reason:"Destructive - may delete data"}:/\b(bash|shell|exec|cmd|powershell|terminal)\b/.test(n)?/\b(rm\s+-rf|sudo|chmod\s+777|curl.*\|\s*(ba)?sh|wget.*-O|>\/dev\/|mkfs)\b/i.test(e)?{level:"CRITICAL",reason:"High-risk command - system-level operation"}:{level:"HIGH",reason:"Shell command execution"}:/\b(write|edit|save|upload|deploy|publish)\b/i.test(n)?{level:"HIGH",reason:"File write operation"}:/\b(install|uninstall|npm|pip|cargo|gem|apt|brew)\b/i.test(n)?{level:"HIGH",reason:"Package manager operation"}:/\b(git)\b/.test(n)&&/\b(push|force|hard\s*reset|rebase)\b/i.test(e)?{level:"HIGH",reason:"Git destructive operation"}:/\b(http|fetch|curl|wget|api|request|download)\b/i.test(n)?{level:"MEDIUM",reason:"Network request"}:/\b(read|open|list|ls|dir|cat|view|search|find|grep|glob)\b/i.test(n)?{level:"LOW",reason:"Read-only operation"}:{level:"MEDIUM",reason:"Tool invocation"}}i(Qr,"classifyRisk");var Zr={CRITICAL:u.error,HIGH:u.warning,MEDIUM:u.warning,LOW:u.info},es={CRITICAL:"!",HIGH:"!",MEDIUM:"*",LOW:"~"};function ts(t,e){if(/\b(bash|shell|exec|cmd|powershell|terminal)\b/i.test(t))return e.slice(0,200);if(/\b(write|edit|save|create)\b/i.test(t)){let n=e.match(/(?:file_path|path|file)["\s:=]+([^\s",}]+)/i);if(n)return"File: "+n[1]+`
|
|
65
|
+
`+e.slice(0,160)}return e.length>200?e.slice(0,200)+"...":e}i(ts,"extractPreview");function zn({toolName:t,payload:e,onAllow:n,onDeny:o,onAllowSession:s,onAutoMode:c,queuePosition:d}){let[f,m]=Vn(0),[g,w]=Vn(Yn),T=Yr(null),{level:h,reason:k}=Qr(t,e),_=Zr[h],y=ts(t,e);Xn(()=>(w(Yn),T.current=setInterval(()=>{w(p=>p<=1?(T.current&&clearInterval(T.current),0):p-1)},1e3),()=>{T.current&&clearInterval(T.current)}),[t,e]),Xn(()=>{g===0&&n()},[g,n]);let S=g<=5,M=[{label:"Allow \u2014 execute this command",hint:"Press Enter or y to confirm",action:n},{label:"Deny \u2014 cancel this operation",hint:"Press Esc or n to cancel",action:o},{label:"Allow always this session",hint:"Don't ask again for "+t,action:s},{label:"Auto mode \u2014 allow all hooks",hint:"All future hooks will be auto-approved",action:c}],a=i(()=>M[f].action(),"execSelected");zr((p,l)=>{if(l.escape){o();return}if(l.upArrow){m(x=>x===0?3:x-1);return}if(l.downArrow){m(x=>x===3?0:x+1);return}if(l.return){a();return}if(p==="1"){n();return}if(p==="2"){o();return}if(p==="3"){s();return}if(p==="4"){c();return}if(p==="y"||p==="Y"){n();return}if(p==="n"||p==="N"){o();return}});let r=h==="CRITICAL"?u.error:u.warning;return he(de,{flexDirection:"column",borderStyle:"round",borderColor:r,marginTop:1,children:[he(de,{paddingLeft:1,paddingRight:1,justifyContent:"space-between",children:[he(de,{gap:1,children:[ue(ge,{bold:!0,children:"Permission Required"}),he(ge,{dimColor:!0,children:["\xB7 ",t]}),d&&d.total>1&&he(ge,{dimColor:!0,children:["(",d.current,"/",d.total,")"]})]}),he(ge,{color:S?u.error:u.muted,children:["Auto ",g,"s"]})]}),he(de,{paddingLeft:1,paddingRight:1,children:[he(ge,{color:_,bold:h==="CRITICAL",children:[es[h]," ",h]}),he(ge,{dimColor:!0,children:[" \u2014 ",k]})]}),y?ue(de,{flexDirection:"column",paddingLeft:1,paddingRight:1,marginTop:1,children:ue(de,{marginLeft:2,children:ue(ge,{color:u.tool,children:y})})}):null,h==="CRITICAL"&&ue(de,{paddingLeft:1,paddingRight:1,marginTop:1,children:ue(ge,{color:u.error,children:"This may cause irreversible changes \u2014 verify carefully"})}),ue(de,{flexDirection:"column",marginTop:1,children:M.map((p,l)=>he(de,{flexDirection:"column",paddingLeft:1,paddingRight:1,children:[ue(de,{children:he(ge,{color:f===l?u.brand:u.muted,children:[f===l?"\u276F":" "," ",l+1,". ",p.label]})}),ue(de,{marginLeft:4,children:ue(ge,{dimColor:!0,children:p.hint})})]},l))}),ue(de,{paddingLeft:1,paddingRight:1,marginTop:1,children:ue(ge,{dimColor:!0,children:"1/2/3/4 to select \xB7 \u2191\u2193 to navigate \xB7 Enter to confirm \xB7 Esc to deny"})})]})}i(zn,"ApprovalModal");function Le(t){if(typeof t.data=="string")try{return JSON.parse(t.data)}catch{return{}}return t.data||{}}i(Le,"parseData");function Be(t,e=""){return{id:`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,type:t,content:e,thinking:"",steps:[],toolCalls:[],timestamp:Date.now()}}i(Be,"createMessage");import{useCallback as ns}from"react";var Qn=200;function $t(t,e){let n=[...t.messages,e];return n.length>Qn?n.slice(n.length-Qn):n}i($t,"appendMessage");function Zn(t){let e=typeof t=="string"?t:JSON.stringify(t);for(let n=0;n<10;n++)try{let o=JSON.parse(e);if(o&&typeof o=="object"&&!Array.isArray(o)){if(typeof o.command=="string")return o.command;if(typeof o.command=="object"){e=JSON.stringify(o.command);continue}return JSON.stringify(o,null,2)}return e}catch{return e}return e}i(Zn,"cleanArgs");function eo(t,e){return ns(n=>{let o="",s="",c=[],d=[],f=null,m=!1;function g(){m=!1;let a=o;o="";let r=s;s="";let p=c;c=[];let l=d;d=[],!(!a&&!r&&p.length===0&&l.length===0)&&A(x=>{if(!x.currentMessage)return x;let b=x.currentMessage;a&&(b={...b,content:b.content+a}),r&&(b={...b,thinking:b.thinking+r});for(let P of p)b=P(b);for(let P of l)b=P(b);return{...x,currentMessage:b}})}i(g,"doStreamFlush");function w(){m||(m=!0,f=setTimeout(g,32))}i(w,"scheduleStreamFlush");function T(){f&&(clearTimeout(f),f=null),m=!1,g()}i(T,"flushNow");let h=0,k=0,_=!0,y=null,S=!1;function M(){S=!1;let a=y;if(!a)return;y=null;let r=Number(a.promptTokens)||0,p=Number(a.completionTokens)||0,l=Number(a.totalTokens)||0,x=Number(a.usageRatio)||0;if(l<=0)return;let b=Date.now(),P=0;if(k>0&&h>0&&b>k&&l>h){let B=l-h,K=(b-k)/1e3,v=B/K,D=be().getState().tokenRate;P=D>0?D*.6+v*.4:v}h=l,k=b,A(B=>({...B,usage:{promptTokens:r,completionTokens:p,totalTokens:l,usageRatio:x},modelName:a.model||B.modelName,tokenRate:P}))}i(M,"flushToken"),n.on("start",()=>{X("evt",">> STREAM START"),T();let a=Be("assistant");A(r=>({...r,currentMessage:a,messages:$t(r,a),scrollOffset:0}))}),n.on("content",a=>{let r=typeof a.data=="string"?a.data:a.data?String(a.data):"";o+=r,w()}),n.on("thinking",a=>{s+=typeof a.data=="string"?a.data:"",w()}),n.on("tool_call",a=>{let r=Le(a);X("evt","tool_call: "+(r.name||"?")+(r.complete?" complete":" running")),c.push(p=>{let l=r.id?p.toolCalls.findIndex(b=>b.id===r.id):-1;l<0&&r.name&&(l=p.toolCalls.findIndex(b=>b.name===r.name&&b.status==="running"));let x=[...p.toolCalls];if(l>=0){let b={...x[l]};r.args&&(b.args=Zn(r.args)),r.complete&&(b.status="complete"),r.result&&(b.result=r.result),x[l]=b}else x.push({id:r.id||(r.name?`${r.name}-${Date.now()}`:""),name:r.name||"",args:r.args?Zn(r.args):void 0,status:r.complete?"complete":"running",complete:!!r.complete,timestamp:Date.now()});return{...p,toolCalls:x}}),w()}),n.on("tool_result",a=>{let r=Le(a);c.push(p=>{let l=[...p.toolCalls];for(let x=l.length-1;x>=0;x--)if(l[x].name===r.toolName&&!l[x].result){let b=l[x],P=b.timestamp?Math.floor((Date.now()-b.timestamp)/1e3):void 0;l[x]={...b,result:r.result||"",status:"complete",duration:P};break}return{...p,toolCalls:l}}),w()}),n.on("complete",()=>{X("evt",">> STREAM COMPLETE"),T(),A(a=>{if(!a.currentMessage)return a;let r=[...a.messages],p=a.currentMessage;for(let l=r.length-1;l>=0;l--)if(r[l].type==="assistant"&&r[l].id===p.id){r[l]=p;break}return{...a,currentMessage:null,messages:r}})}),n.on("error",a=>{let r=String(a.data||"Error");X("evt","error: "+r.slice(0,80)),A(p=>({...p,statusText:"Error: "+r.slice(0,120)}))}),n.on("step_start",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);d.push(p=>{let l={id:r.id||"step-"+Date.now(),title:r.title||r.description||"",thought:r.thought,action:r.action,status:"running",tools:[],timestamp:Date.now()};return{...p,steps:[...p.steps,l]}}),w()}),n.on("step_thinking",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);d.push(p=>{let l=[...p.steps],x=r.id?l.findIndex(b=>b.id===r.id):l.length-1;return x>=0&&(l[x]={...l[x],status:"thinking",thought:r.thought||l[x].thought}),{...p,steps:l}}),w()}),n.on("step_action",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);d.push(p=>{let l=[...p.steps],x=r.id?l.findIndex(b=>b.id===r.id):l.length-1;return x>=0&&(l[x]={...l[x],status:"action",action:r.action||l[x].action}),{...p,steps:l}}),w()}),n.on("step_complete",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);d.push(p=>{let l=[...p.steps],x=r.id?l.findIndex(b=>b.id===r.id):l.length-1;if(x>=0){let b=r.duration?Number(r.duration):l[x].timestamp?Math.floor((Date.now()-l[x].timestamp)/1e3):void 0;l[x]={...l[x],status:r.status==="error"?"error":"success",result:r.result,duration:b}}return{...p,steps:l}}),w()}),n.on("plan_start",()=>{X("evt",">> PLAN START"),T();let a=Be("assistant");A(r=>({...r,planWaiting:!1,currentMessage:a,messages:$t(r,a),scrollOffset:0}))}),n.on("plan_thinking",a=>{let r=typeof a.data=="string"?a.data:a.data?String(a.data):"";s+=r+`
|
|
66
|
+
`,w()}),n.on("plan_tasks",()=>{o+=`
|
|
67
67
|
Task list generated
|
|
68
|
-
`,
|
|
69
|
-
`),
|
|
70
|
-
\`\`\`${
|
|
71
|
-
${
|
|
68
|
+
`,w()}),n.on("plan_error",a=>{let r=String(a.data||"Plan failed");A(p=>({...p,planWaiting:!1,statusText:"Plan error: "+r.slice(0,120)}))}),n.on("plan_mode_enter",()=>{X("evt","plan_mode_enter"),A(a=>({...a,planMode:!0,statusText:"Entered plan mode"}))}),n.on("plan_mode_exit",()=>{X("evt","plan_mode_exit"),A(a=>({...a,planMode:!1,statusText:"Exited plan mode"}))}),n.on("plan_task_start",a=>{let r=Le(a);A(p=>{let l=[...p.planTasks],x=l.findIndex(b=>b.id===r.id);return x>=0?l[x]={...l[x],...r,status:"running",timestamp:Date.now()}:l.push({...r,status:"running",timestamp:Date.now()}),{...p,planTasks:l,pdcaPhase:p.pdcaPhase||"Do"}})}),n.on("plan_task_update",a=>{let r=Le(a);A(p=>{let l=[...p.planTasks],x=l.findIndex(b=>b.id===r.id);return x>=0&&(l[x]={...l[x],...r}),{...p,planTasks:l}})}),n.on("plan_task_result",a=>{let r=Le(a);A(p=>{let l=[...p.planTasks],x=l.findIndex(b=>b.id===r.id);if(x>=0){let b=l[x].timestamp?Math.floor((Date.now()-l[x].timestamp)/1e3):void 0;l[x]={...l[x],...r,status:r.status||"completed",duration:b}}else l.push({...r});return{...p,planTasks:l}})}),n.on("plan_complete",a=>{T();let r=a.status;X("evt",">> PLAN COMPLETE status="+(r||"none"));let p=typeof a.data=="string"?a.data:"";A(l=>{if(!l.currentMessage)return l;let x=[...l.messages],b=l.currentMessage;for(let P=x.length-1;P>=0;P--)if(x[P].type==="assistant"&&x[P].id===b.id){x[P]={...b,content:p||"Plan complete."};break}return{...l,currentMessage:null,messages:x,planWaiting:r==="waiting_confirm"}})}),n.on("token_update",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);_=!1,(Number(r.totalTokens)||0)>0&&(y=r,S||(S=!0,setTimeout(M,100)))}),n.on("compaction_progress",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);A(p=>({...p,compactionProgress:{stage:String(r.stage||""),percent:Number(r.percent)||0,message:String(r.message||"")}}))}),n.on("context_compressed",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);let p=Number(r.originalCount)||0,l=Number(r.compressedCount)||0,x=Number(r.tokensSaved)||0,b=x>=1e3?(x/1e3).toFixed(1)+"K":String(x);A(P=>({...P,statusText:"Context compressed "+p+" to "+l+" messages, freed "+b+" tokens",usage:{...P.usage,usageRatio:Math.max(0,P.usage.usageRatio-.15)},compactionProgress:null}))}),n.on("hook_ask",a=>{let r=Le(a),p=r.toolName||"";X("evt","hook_ask: "+p+" autoMode="+String(be().getState().autoMode));let l=r.approvalId||"",x=r.toolName||"";if(be().getState().autoMode||e.current.has(x)){n.approveHook(l);return}t(b=>b.some(P=>P.approvalId===l)?b:[...b,{approvalId:l,toolName:r.toolName||"",payload:r.askPayload||r.payload||JSON.stringify(r)}])}),n.on("doctor_result",a=>{let r=String(a.data||""),p=r.length>300?r.slice(0,300)+"...":r,l=Be("assistant",p);A(x=>({...x,messages:$t(x,l),statusText:"Doctor diagnosis complete"}))}),n.on("degradation_update",a=>{let r={};if(typeof a.data=="string")try{r=JSON.parse(a.data)}catch{}else a.data&&typeof a.data=="object"&&(r=a.data);A(p=>({...p,degradation:{active:r.active||!1,retryCount:Number(r.retryCount)||0,maxRetries:Number(r.maxRetries)||0,mode:r.mode||"normal",message:r.message||""}}))}),n.on("todo_update",a=>{let r=String(a.data||"");A(p=>({...p,statusText:"TODO: "+r.slice(0,100)}))}),n.on("todo_item_done",a=>{let r=String(a.data||"");A(p=>({...p,statusText:"Done: "+r.slice(0,100)}))}),n.on("todo_progress",a=>{let r=String(a.data||"");A(p=>({...p,statusText:r.slice(0,100)}))}),n.on("workspace_changed",a=>{let r=String(a.data||"Workspace changed");A(p=>({...p,statusText:r.slice(0,100)}))}),n.on("generation_paused",()=>{A(a=>({...a,statusText:"Generation paused -- press ESC to resume or ESC ESC to stop"}))}),n.on("generation_resumed",()=>{A(a=>({...a,statusText:""}))}),n.on("notification",a=>{let r=String(a.data||"");A(p=>({...p,statusText:r,connected:r==="Reconnected."?!0:p.connected}))})},[t])}i(eo,"useStreamHandlers");import{useRef as os}from"react";import{useInput as rs}from"ink";function to(t){let{showApproval:e,showHelp:n,isGenerating:o,terminalRows:s,viewportHeight:c,paletteOpen:d,clientRef:f,onDenyApproval:m,onCloseHelp:g,setHelpScroll:w,onToggleHelp:T,onNewSession:h,onSessionHistory:k}=t,_=os(0);rs((y,S)=>{if(S.f1||S.ctrl&&y==="h"){T?T():n&&g();return}if(S.ctrl&&y==="n"&&!e&&!o){h?.();return}if(S.ctrl&&y==="r"&&!e&&!o){k?.();return}if(S.escape){if(e)return;if(n){g();return}if(o){let r=Date.now(),p=_.current;_.current=r,p>0&&r-p<500?(f.current?.stop(),A(l=>({...l,statusText:"Stopped (ESC\xD72)"}))):(f.current?.pause(),A(l=>({...l,statusText:"Paused \u2014 press ESC again to stop"})));return}}if(S.ctrl&&y==="s"&&!e){o&&(f.current?.pause(),A(r=>({...r,statusText:"Paused (Ctrl+S). Press again to resume."})));return}if(S.ctrl&&y==="l"&&!e&&!o){A(r=>({...r,messages:[],currentMessage:null,scrollOffset:0,contentHeight:0,statusText:"Screen cleared"}));return}if(S.ctrl&&y==="o"){A(r=>({...r,toolCallsExpanded:!r.toolCallsExpanded}));return}if(S.ctrl&&y==="e"){A(r=>({...r,toolCallsExpanded:!r.toolCallsExpanded}));return}if(n){let r=wt.split(`
|
|
69
|
+
`),p=Math.max(5,s-12);if(S.pageUp||S.upArrow){w(l=>Math.min(l+(S.pageUp?p:1),r.length-1));return}if(S.pageDown||S.downArrow){w(l=>Math.max(0,l-(S.pageDown?p:1)));return}if(S.home){w(()=>r.length-1);return}if(S.end){w(()=>0);return}}let M=i(()=>{let{contentHeight:r}=be().getState();return Math.max(0,r-c)},"maxOffsetLive"),a=Math.max(1,c-2);if(S.pageUp){A(r=>({...r,scrollOffset:Math.min(M(),r.scrollOffset+a)}));return}if(S.upArrow&&!e&&!d){A(r=>({...r,scrollOffset:Math.min(M(),r.scrollOffset+1)}));return}if(S.pageDown){A(r=>({...r,scrollOffset:Math.max(0,r.scrollOffset-a)}));return}if(S.downArrow&&!e&&!d){A(r=>({...r,scrollOffset:Math.max(0,r.scrollOffset-1)}));return}if(S.home){A(r=>({...r,scrollOffset:M()}));return}if(S.end){A(r=>({...r,scrollOffset:0}));return}if(S.tab){A(r=>({...r,planMode:!r.planMode,planWaiting:!1}));return}})}i(to,"useKeyboardInput");var ss=null;function no(t){ss=t}i(no,"setClient");import{jsx as O,jsxs as Ce}from"react/jsx-runtime";function oo(t){for(let e=t.length-1;e>=0;e--)if(t[e]==="@"){if(e>0&&/\w/.test(t[e-1]))continue;return e}return-1}i(oo,"findAtTrigger");function Ut({backendUrl:t,wsUrl:e,onExit:n}){let[o,s]=ie(""),[c,d]=ie(!1),[f,m]=ie(!1),[g,w]=ie(""),[T,h]=ie([]),k=ot(null),_=ot([]),[y,S]=ie(!1),[M,a]=ie(0),[r,p]=ie([]),l=r.length>0?r[0]:null,x=ot(new Set),b=ot(null),{stdout:P}=as(),[B,K]=ie(P?.rows||24),[v,D]=ie(P?.columns||80);jt(()=>{let C=i(()=>{K(P?.rows||24),D(P?.columns||80)},"onResize");return P?.on?.("resize",C),()=>{P?.off?.("resize",C)}},[P]);let H=6,ce=re(C=>C.connected),$e=re(C=>C.planWaiting),V=re(C=>C.currentMessage!==null),se=re(C=>C.messages.length),we=re(C=>C.modelName),Mt=re(C=>C.planMode),[sn,an]=ie(!1),[bo,cn]=ie([]),[So,yo]=ie(0),vt=ot("");jt(()=>{let C=Mt+"-"+ce+"-"+(se===0);vt.current&&vt.current!==C&&yo(W=>W+1),vt.current=C},[Mt,ce,se]);let ln=eo(p,x);jt(()=>{let C=new lt(t,e);return b.current=C,no(C),ln(C),C.connect().then(async()=>{try{let j=(await(await fetch(t+"/api/models")).json()).data?.models?.[0]?.name||"";A(Ae=>({...Ae,connected:!0,modelName:j}))}catch{A(W=>({...W,connected:!0}))}}).catch(W=>{A(N=>({...N,statusText:"Connection failed: "+W.message}))}),()=>{C.close()}},[t,e,ln]);let dn=te(C=>{let W=C.trim();if(!W||!b.current)return;s(""),S(!1),d(!1);let N=W.startsWith("/")?W.split(/\s+/):[],q=N[0]||null,j=N.slice(1).join(" ");if(q&&q in xt){let Ae=xt[q];if(Ae===null){S(!0),a(0);return}let{action:pe,needsArg:it}=Ae,U=b.current;switch(pe){case"__exit__":n();return;case"__confirm_plan":A(Z=>Z.planWaiting?(U?.planConfirm(),{...Z,planWaiting:!1}):Z);return;case"__cancel_plan":A(Z=>({...Z,planWaiting:!1}));return;case"plan_mode":A(Z=>({...Z,planMode:!Z.planMode}));return;case"auto_mode":X("app","auto_mode toggle"),A(Z=>({...Z,autoMode:!Z.autoMode}));return;case"clear":A(Z=>({...Z,messages:[],currentMessage:null,contentHeight:0,scrollOffset:0}));return;case"model_change":it&&j&&U?.switchModel(j);return;case"show_context":A(Z=>({...Z,statusText:"Messages: "+Z.messages.length+" | Plan: "+(Z.planMode?"On":"Off")+" | Model: "+(Z.modelName||"N/A")}));return;case"stop":U?.stop();return;case"pause":U?.pause();return;case"resume":U?.resume();return;case"doctor":U?.doctor();return;case"rewind":U?.rewind();return;case"compact":U?.compact();return;case"init":U?.init();return;case"effort":j&&U?.effort(j);return;case"branch":j&&U?.branch(j);return;case"mcp":j&&U?.mcp(j);return;case"skills":U?.skills();return;case"agents":U?.agents();return;case"config":j&&U?.config(j);return;case"plugin":j&&U?.plugin(j);return;case"tokens":U?.send("tokens");return;case"memory":U?.send("memory");return;case"export":j&&U?.send("export",void 0,{path:j});return;case"checkpoint":U?.send("checkpoint");return;case"test":U?.send("test");return;case"lint":U?.send("lint");return;case"search":j&&U?.send("search",void 0,{query:j});return;case"project":U?.send("project");return}return}W.startsWith("/")&&!(q&&q in xt)||ko(W)},[n]),ko=te(async C=>{let W=b.current;if(!W)return;let N=C,q=_.current;_.current=[];let j=[];for(let pe of q)try{let it=await W.readFileContent(pe);if(it){N=N.replace(pe,"").trim();let U=pe.split(".").pop()||"";j.push(`<context ref="${pe}">
|
|
70
|
+
\`\`\`${U}
|
|
71
|
+
${it}
|
|
72
72
|
\`\`\`
|
|
73
|
-
</context>`)}}catch{}
|
|
73
|
+
</context>`)}}catch{}j.length>0&&(N=j.join(`
|
|
74
74
|
|
|
75
75
|
`)+`
|
|
76
76
|
|
|
77
|
-
`+N.trim(),N=N.trim());let ve=Ne("user",N);A(de=>({...de,messages:[...de.messages,ve]})),j.chat(N,xe().getState().planMode)},[]),Co=ee(v=>{i||f||cn(v)},[cn,i,f]),Mo=ee(v=>{s(v),d(v.startsWith("/"));let j=so(v);if(j>=0){let N=v.slice(j+1);if(/^[\w.\-\\\/\s]*$/.test(N)&&N.length<200){b(N),p(!0),S.current&&clearTimeout(S.current),S.current=setTimeout(async()=>{let q=y.current;if(q){let U=await q.listFiles(N.trim()||void 0);x(U)}},150);return}}p(!1),b("")},[]),vo=ee(v=>{if(v){let j=so(o);if(j>=0){let N=o.slice(0,j)+v+" ";s(N),C.current.push(v)}}p(!1),b(""),x([])},[o]),Ao=ee(v=>{v?(s(v),d(!1)):(d(!1),s(""))},[]),it=ee(()=>{g(v=>v.length>1?v.slice(1):[])},[]),je=ee(v=>{y.current?.approveHook(v),it()},[it]),vt=ee(v=>{y.current?.denyHook(v),it()},[it]),ln=i||f||on,_o=ee(()=>{A(v=>({...v,messages:[],currentMessage:null,scrollOffset:0,contentHeight:0,statusText:"New session started"})),y.current&&y.current.send("create_session")},[]),Ro=ee(async()=>{if(y.current){let v=await y.current.listSessions();sn(v),rn(!0)}},[]),Do=ee(async v=>{if(rn(!1),!v||!y.current)return;let N=(await y.current.getSessionMessages(v.id)).map(q=>Ne(q.type==="chat"||q.type==="plan"?"user":"assistant",q.data||q.message||JSON.stringify(q)));A(q=>({...q,messages:N.length>0?N:q.messages,scrollOffset:0,contentHeight:0,statusText:`Loaded session: ${v.id} (${N.length} msgs)`}))},[]),Eo=ee(async v=>{if(y.current){await y.current.deleteSession(v);let j=await y.current.listSessions();sn(j)}},[]),Po=c(()=>{k?w(!1):(w(!0),a(0))},"handleToggleHelp");no({showApproval:l!==null,showHelp:k,isGenerating:Me,terminalRows:W,viewportHeight:Math.max(3,W-Ce),paletteOpen:ln,clientRef:y,onDenyApproval:c(()=>{l&&vt(l.approvalId)},"onDenyApproval"),onCloseHelp:c(()=>w(!1),"onCloseHelp"),setHelpScroll:a,onToggleHelp:Po,onNewSession:_o,onSessionHistory:Ro});let Io=ee(()=>{l&&je(l.approvalId)},[l,je]),Oo=ee(()=>{l&&vt(l.approvalId)},[l,vt]),Lo=ee(()=>{l&&(T.current.add(l.toolName),je(l.approvalId))},[l,je]),Bo=ee(()=>{V("app","autoMode button pressed"),A(v=>({...v,autoMode:!0})),l&&je(l.approvalId)},[l,je]);return Se(z,{flexDirection:"column",width:"100%",children:[Pe?Se(z,{flexDirection:"column",children:[$===0&&!Me&&!!re&&Se(z,{flexDirection:"column",flexShrink:0,marginBottom:1,children:[Se(z,{flexDirection:"column",paddingX:1,children:[L(z,{children:L(se,{color:u.primary,bold:!0,children:">_ JWCode v3.0.0"})}),Se(z,{children:[L(se,{dimColor:!0,children:"model: "}),L(se,{color:u.success,children:re||"connecting..."}),L(se,{dimColor:!0,children:" /model to change"})]}),Se(z,{children:[L(se,{dimColor:!0,children:"directory: "}),L(se,{color:u.warning,children:process.cwd()})]})]}),L(z,{paddingLeft:3,children:L(se,{dimColor:!0,children:"Tip: Type / for commands, @ to reference files"})}),L(z,{paddingLeft:3,children:L(se,{dimColor:!0,children:"TUI shortcuts: F1 help | Ctrl+L clear | Ctrl+S pause | Ctrl+N new | Ctrl+R history | Tab mode | PgUp/PgDn scroll"})})]},"welcome"),L(z,{flexGrow:ln?0:1,flexDirection:"column",children:L(Bt,{terminalCols:D,terminalRows:W})}),Se(z,{flexDirection:"row",borderStyle:"single",borderColor:u.primary,paddingLeft:1,children:[L(se,{color:u.success,bold:!0,children:"> "}),L(ze,{value:o,onChange:Mo,onSubmit:Co,placeholder:"Type a message or / for commands...",disabled:l!==null})]}),Se(z,{flexDirection:"column",children:[i&&L(Un,{filter:o,onSelect:Ao},"command-palette"),f&&L(Kn,{query:m,files:h,onSelect:vo},"file-palette"),on&&L(Vn,{sessions:yo,onSelect:Do,onDelete:Eo},"session-picker"),k&&(()=>{let v=wt.split("\\n"),j=Math.max(5,Math.min(W-12,10)),N=Math.max(0,v.length-M),q=Math.max(0,N-j),U=v.slice(q,N);return Se(z,{flexDirection:"column",borderStyle:"single",borderColor:u.primary,paddingX:1,children:[v.length>j&&L(z,{children:L(se,{dimColor:!0,children:" "+(q+1)+"-"+N+" / "+v.length+" PgUp/PgDn scroll / Esc close"})}),U.map((ve,de)=>L(se,{color:u.primary,children:ve},de))]},"help-box")})(),l&&L(Qn,{toolName:l.toolName,payload:l.payload,onAllow:Io,onDeny:Oo,onAllowSession:Lo,onAutoMode:Bo,queuePosition:{current:1,total:r.length}},"approval-modal")]})]}):Se(z,{flexDirection:"column",children:[L(z,{flexGrow:1,flexDirection:"column",children:L(Bt,{terminalCols:D,terminalRows:W})}),L(z,{paddingLeft:1,children:L(se,{dimColor:!0,children:"Connecting..."})})]}),L(yn,{},Ye?"status-plan":"status-act"),!Pe&&L(z,{height:1,children:L(se,{color:u.error,children:"Backend not connected -- WebSocket reconnecting."})}),Ie&&L(z,{height:1,children:L(se,{color:u.warning,bold:!0,children:"Plan ready -- /confirm to execute, /cancel to discard."})})]})}c($t,"App");import{useState as He,useCallback as fs,useEffect as ms}from"react";import{Box as We,Text as B,useInput as gs}from"ink";import{Fragment as hs,jsx as K,jsxs as te}from"react/jsx-runtime";var Ve={openai:{name:"OpenAI",baseUrl:"https://api.openai.com/v1",apiType:"openai-completions",defaultModel:"gpt-4o"},anthropic:{name:"Anthropic",baseUrl:"https://api.anthropic.com/v1",apiType:"anthropic-messages",defaultModel:"claude-sonnet-4-6"},deepseek:{name:"DeepSeek",baseUrl:"https://api.deepseek.com/v1",apiType:"openai-completions",defaultModel:"deepseek-chat"},moonshot:{name:"Moonshot / Kimi",baseUrl:"https://api.moonshot.cn/v1",apiType:"openai-completions",defaultModel:"moonshot-v1-8k"},qwen:{name:"\u901A\u4E49\u5343\u95EE (Qwen)",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode/v1",apiType:"openai-completions",defaultModel:"qwen-plus"},zhipu:{name:"\u667A\u8C31 (GLM)",baseUrl:"https://open.bigmodel.cn/api/paas/v4",apiType:"openai-completions",defaultModel:"glm-4-plus"},baichuan:{name:"\u767E\u5DDD (Baichuan)",baseUrl:"https://api.baichuan-ai.com/v1",apiType:"openai-completions",defaultModel:"Baichuan4"},minimax:{name:"MiniMax / \u6D77\u87BA",baseUrl:"https://api.minimax.chat/v1",apiType:"openai-completions",defaultModel:"abab6.5s-chat"},doubao:{name:"\u8C46\u5305 (Doubao)",baseUrl:"https://ark.cn-beijing.volces.com/api/v3",apiType:"openai-completions",defaultModel:"doubao-pro-32k"},hunyuan:{name:"\u817E\u8BAF\u6DF7\u5143 (Hunyuan)",baseUrl:"https://api.hunyuan.cloud.tencent.com/v1",apiType:"openai-completions",defaultModel:"hunyuan-pro"},spark:{name:"\u8BAF\u98DE\u661F\u706B (Spark)",baseUrl:"https://spark-api-open.xf-yun.com/v1",apiType:"openai-completions",defaultModel:"generalv3.5"},custom:{name:"Custom (\u81EA\u5B9A\u4E49)",baseUrl:"",apiType:"openai-completions",defaultModel:""}},st=Object.keys(Ve),ao=c(({backendUrl:t,onComplete:e,onCancel:n,mode:o="fullscreen"})=>{let[s,i]=He("select_provider"),[d,f]=He(0),[p,m]=He(""),[b,h]=He(""),[x,S]=He(""),[C,k]=He(""),[w,M]=He(""),a=o==="modal",r=fs(async()=>{i("saving");try{let W=Ve[p],_=x||W.baseUrl,D=await fetch(`${t}/api/config/provider`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:p,baseUrl:_,apiType:W.apiType,apiKey:b,setDefault:!0,models:[{id:C,name:C,enabled:!0,priority:10}]})});if(!D.ok){let P=await D.text();throw new Error(P||`HTTP ${D.status}`)}i("done"),setTimeout(e,1200)}catch(W){M(String(W)),i("error")}},[t,p,x,b,C,e]);ms(()=>{if(s==="done")return;c(async()=>{try{(await(await fetch(`${t}/api/config/provider`)).json())?.data?.configured&&e()}catch{}},"check")()},[s,t,e]),gs((W,_)=>{if(_.escape&&a&&n){n();return}if(s==="select_provider"){if(_.upArrow||W==="k")f(D=>(D-1+st.length)%st.length);else if(_.downArrow||W==="j")f(D=>(D+1)%st.length);else if(_.return){let D=st[d];m(D);let P=Ve[D];S(P.baseUrl),k(P.defaultModel),i("enter_key")}return}if(s==="error"){if(_.escape&&a&&n){n();return}_.return&&(i("enter_key"),M(""))}});let g=c(()=>{if(b.trim().length<10){M("API key too short (min 10 characters).");return}M(""),p==="custom"?i("enter_model"):r()},"handleKeySubmit"),l=c(()=>{if(C.trim().length===0){M("Model name is required.");return}r()},"handleModelSubmit");if(s==="done")return te(We,{flexDirection:"column",padding:1,children:[K(B,{color:u.success,children:"\u2713 Configuration saved!"}),o==="fullscreen"&&K(B,{dimColor:!0,children:"Starting JWCode..."})]});let T=a?"single":"round",y=a?u.warning:u.primary,E=a?"Add Provider":"JWCode \u2014 First Run Setup";return te(We,{flexDirection:"column",padding:1,borderStyle:T,borderColor:y,children:[K(We,{marginBottom:1,children:K(B,{bold:!0,color:u.primary,children:E})}),o==="fullscreen"&&te(hs,{children:[K(B,{children:"Configure your AI provider to get started."}),K(B,{children:" "})]}),a&&n&&K(B,{dimColor:!0,children:"Esc to close"}),s==="select_provider"&&te(We,{flexDirection:"column",children:[K(B,{children:"Select provider (\u2191\u2193 to navigate, Enter to confirm):"}),st.map((W,_)=>te(B,{children:[_===d?"\u276F ":" ",K(B,{color:_===d?"green":void 0,bold:_===d,children:Ve[W].name}),_===d?" \u25C0":""]},W))]}),s==="enter_key"&&te(We,{flexDirection:"column",children:[te(B,{children:["Provider: ",K(B,{color:u.success,children:Ve[p].name})]}),te(B,{children:["Base URL: ",K(B,{color:u.info,children:x})]}),K(B,{children:" "}),K(B,{children:"Enter API Key:"}),K(ze,{value:b,onChange:h,onSubmit:g,placeholder:"sk-..."}),K(B,{dimColor:!0,children:"Press Enter to confirm"}),w&&te(B,{color:u.error,children:["Error: ",w]})]}),s==="enter_model"&&te(We,{flexDirection:"column",children:[te(B,{children:["Provider: ",K(B,{color:u.success,children:Ve[p].name})]}),te(B,{children:["API Key: ",K(B,{color:u.success,children:"configured"})]}),K(B,{children:" "}),te(B,{children:["Base URL: ",K(B,{color:u.info,children:x})]}),K(B,{children:" "}),K(B,{children:"Model ID:"}),K(ze,{value:C,onChange:k,onSubmit:l,placeholder:"model-name"}),K(B,{dimColor:!0,children:"Press Enter to confirm, type to edit model name"}),w&&te(B,{color:u.error,children:["Error: ",w]})]}),s==="saving"&&K(B,{color:u.warning,children:"Saving configuration to ~/.jwcode/config.yaml..."}),s==="error"&&te(We,{flexDirection:"column",children:[te(B,{color:u.error,children:["Failed to save: ",w]}),te(B,{children:["Press Enter to retry",a?", Esc to cancel":"","."]})]})]})},"SetupWizard");Ct();import{existsSync as wo}from"node:fs";import{join as To}from"node:path";import{readFileSync as As,existsSync as _s}from"node:fs";import{join as mo}from"node:path";import{homedir as Rs}from"node:os";var Xe={backend_url:"http://localhost:8080",ws_url:"ws://localhost:8081/ws",ws_auth_token:"default-token",workspace_dir:""};function Ds(t){let e={};for(let n of t.split(`
|
|
78
|
-
`)){let o=n.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf(":");if(s===-1)continue;let
|
|
79
|
-
[jwcode] Closing. Daemon continues running in background.`),console.log("[daemon] Stop it with: jwcode stop"))},"cleanup");process.on("SIGINT",()=>{
|
|
80
|
-
Update available: v${
|
|
81
|
-
`))}).catch(()=>{})});let
|
|
82
|
-
[daemon] Daemon process died. Attempting auto-restart...`);try{let M=
|
|
83
|
-
`).filter(d=>d.trim()).slice(0,3);for(let d of
|
|
77
|
+
`+N.trim(),N=N.trim());let Ae=Be("user",N);A(pe=>({...pe,messages:[...pe.messages,Ae]})),W.chat(N,be().getState().planMode)},[]),Co=te(C=>{c||f||dn(C)},[dn,c,f]),Mo=te(C=>{s(C),d(C.startsWith("/"));let W=oo(C);if(W>=0){let N=C.slice(W+1);if(/^[\w.\-\\\/\s]*$/.test(N)&&N.length<200){w(N),m(!0),k.current&&clearTimeout(k.current),k.current=setTimeout(async()=>{let q=b.current;if(q){let j=await q.listFiles(N.trim()||void 0);h(j)}},150);return}}m(!1),w("")},[]),vo=te(C=>{if(C){let W=oo(o);if(W>=0){let N=o.slice(0,W)+C+" ";s(N),_.current.push(C)}}m(!1),w(""),h([])},[o]),Ao=te(C=>{C?(s(C),d(!1)):(d(!1),s(""))},[]),at=te(()=>{p(C=>C.length>1?C.slice(1):[])},[]),je=te(C=>{b.current?.approveHook(C),at()},[at]),At=te(C=>{b.current?.denyHook(C),at()},[at]),un=c||f||sn,_o=te(()=>{A(C=>({...C,messages:[],currentMessage:null,scrollOffset:0,contentHeight:0,statusText:"New session started"})),b.current&&b.current.send("create_session")},[]),Ro=te(async()=>{if(b.current){let C=await b.current.listSessions();cn(C),an(!0)}},[]),Do=te(async C=>{if(an(!1),!C||!b.current)return;let N=(await b.current.getSessionMessages(C.id)).map(q=>Be(q.type==="chat"||q.type==="plan"?"user":"assistant",q.data||q.message||JSON.stringify(q)));A(q=>({...q,messages:N.length>0?N:q.messages,scrollOffset:0,contentHeight:0,statusText:`Loaded session: ${C.id} (${N.length} msgs)`}))},[]),Eo=te(async C=>{if(b.current){await b.current.deleteSession(C);let W=await b.current.listSessions();cn(W)}},[]),Po=i(()=>{y?S(!1):(S(!0),a(0))},"handleToggleHelp");to({showApproval:l!==null,showHelp:y,isGenerating:V,terminalRows:B,viewportHeight:Math.max(3,B-H),paletteOpen:un,clientRef:b,onDenyApproval:i(()=>{l&&At(l.approvalId)},"onDenyApproval"),onCloseHelp:i(()=>S(!1),"onCloseHelp"),setHelpScroll:a,onToggleHelp:Po,onNewSession:_o,onSessionHistory:Ro});let Io=te(()=>{l&&je(l.approvalId)},[l,je]),Oo=te(()=>{l&&At(l.approvalId)},[l,At]),Lo=te(()=>{l&&(x.current.add(l.toolName),je(l.approvalId))},[l,je]),Bo=te(()=>{X("app","autoMode button pressed"),A(C=>({...C,autoMode:!0})),l&&je(l.approvalId)},[l,je]);return Ce(Q,{flexDirection:"column",width:"100%",children:[ce?Ce(Q,{flexDirection:"column",children:[se===0&&!V&&!!we&&Ce(Q,{flexDirection:"column",flexShrink:0,marginBottom:1,children:[Ce(Q,{flexDirection:"column",paddingX:1,children:[O(Q,{children:O(ae,{color:u.primary,bold:!0,children:">_ JWCode v3.0.0"})}),Ce(Q,{children:[O(ae,{dimColor:!0,children:"model: "}),O(ae,{color:u.success,children:we||"connecting..."}),O(ae,{dimColor:!0,children:" /model to change"})]}),Ce(Q,{children:[O(ae,{dimColor:!0,children:"directory: "}),O(ae,{color:u.warning,children:process.cwd()})]})]}),O(Q,{paddingLeft:3,children:O(ae,{dimColor:!0,children:"Tip: Type / for commands, @ to reference files"})}),O(Q,{paddingLeft:3,children:O(ae,{dimColor:!0,children:"TUI shortcuts: F1 help | Ctrl+L clear | Ctrl+S pause | Ctrl+N new | Ctrl+R history | Tab mode | PgUp/PgDn scroll"})})]},"welcome"),O(Q,{flexGrow:un?0:1,flexDirection:"column",children:O(Nt,{terminalCols:v,terminalRows:B})}),Ce(Q,{flexDirection:"row",borderStyle:"single",borderColor:u.primary,paddingLeft:1,children:[O(ae,{color:u.success,bold:!0,children:"> "}),O(Ye,{value:o,onChange:Mo,onSubmit:Co,placeholder:"Type a message or / for commands...",disabled:l!==null})]}),Ce(Q,{flexDirection:"column",children:[c&&O(jn,{filter:o,onSelect:Ao},"command-palette"),f&&O(Gn,{query:g,files:T,onSelect:vo},"file-palette"),sn&&O(qn,{sessions:bo,onSelect:Do,onDelete:Eo},"session-picker"),y&&(()=>{let C=wt.split("\\n"),W=Math.max(5,Math.min(B-12,10)),N=Math.max(0,C.length-M),q=Math.max(0,N-W),j=C.slice(q,N);return Ce(Q,{flexDirection:"column",borderStyle:"single",borderColor:u.primary,paddingX:1,children:[C.length>W&&O(Q,{children:O(ae,{dimColor:!0,children:" "+(q+1)+"-"+N+" / "+C.length+" PgUp/PgDn scroll / Esc close"})}),j.map((Ae,pe)=>O(ae,{color:u.primary,children:Ae},pe))]},"help-box")})(),l&&O(zn,{toolName:l.toolName,payload:l.payload,onAllow:Io,onDeny:Oo,onAllowSession:Lo,onAutoMode:Bo,queuePosition:{current:1,total:r.length}},"approval-modal")]})]}):Ce(Q,{flexDirection:"column",children:[O(Q,{flexGrow:1,flexDirection:"column",children:O(Nt,{terminalCols:v,terminalRows:B})}),O(Q,{paddingLeft:1,children:O(ae,{dimColor:!0,children:"Connecting..."})})]}),O(Cn,{},Mt?"status-plan":"status-act"),!ce&&O(Q,{height:1,children:O(ae,{color:u.error,children:"Backend not connected -- WebSocket reconnecting."})}),$e&&O(Q,{height:1,children:O(ae,{color:u.warning,bold:!0,children:"Plan ready -- /confirm to execute, /cancel to discard."})})]},So)}i(Ut,"App");import{useState as Ne,useCallback as is,useEffect as cs}from"react";import{Box as He,Text as L,useInput as ls}from"ink";import{Fragment as ds,jsx as G,jsxs as ne}from"react/jsx-runtime";var Ve={openai:{name:"OpenAI",baseUrl:"https://api.openai.com/v1",apiType:"openai-completions",defaultModel:"gpt-4o"},anthropic:{name:"Anthropic",baseUrl:"https://api.anthropic.com/v1",apiType:"anthropic-messages",defaultModel:"claude-sonnet-4-6"},deepseek:{name:"DeepSeek",baseUrl:"https://api.deepseek.com/v1",apiType:"openai-completions",defaultModel:"deepseek-chat"},moonshot:{name:"Moonshot / Kimi",baseUrl:"https://api.moonshot.cn/v1",apiType:"openai-completions",defaultModel:"moonshot-v1-8k"},qwen:{name:"\u901A\u4E49\u5343\u95EE (Qwen)",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode/v1",apiType:"openai-completions",defaultModel:"qwen-plus"},zhipu:{name:"\u667A\u8C31 (GLM)",baseUrl:"https://open.bigmodel.cn/api/paas/v4",apiType:"openai-completions",defaultModel:"glm-4-plus"},baichuan:{name:"\u767E\u5DDD (Baichuan)",baseUrl:"https://api.baichuan-ai.com/v1",apiType:"openai-completions",defaultModel:"Baichuan4"},minimax:{name:"MiniMax / \u6D77\u87BA",baseUrl:"https://api.minimax.chat/v1",apiType:"openai-completions",defaultModel:"abab6.5s-chat"},doubao:{name:"\u8C46\u5305 (Doubao)",baseUrl:"https://ark.cn-beijing.volces.com/api/v3",apiType:"openai-completions",defaultModel:"doubao-pro-32k"},hunyuan:{name:"\u817E\u8BAF\u6DF7\u5143 (Hunyuan)",baseUrl:"https://api.hunyuan.cloud.tencent.com/v1",apiType:"openai-completions",defaultModel:"hunyuan-pro"},spark:{name:"\u8BAF\u98DE\u661F\u706B (Spark)",baseUrl:"https://spark-api-open.xf-yun.com/v1",apiType:"openai-completions",defaultModel:"generalv3.5"},custom:{name:"Custom (\u81EA\u5B9A\u4E49)",baseUrl:"",apiType:"openai-completions",defaultModel:""}},rt=Object.keys(Ve),ro=i(({backendUrl:t,onComplete:e,onCancel:n,mode:o="fullscreen"})=>{let[s,c]=Ne("select_provider"),[d,f]=Ne(0),[m,g]=Ne(""),[w,T]=Ne(""),[h,k]=Ne(""),[_,y]=Ne(""),[S,M]=Ne(""),a=o==="modal",r=is(async()=>{c("saving");try{let B=Ve[m],K=h||B.baseUrl,v=await fetch(`${t}/api/config/provider`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:m,baseUrl:K,apiType:B.apiType,apiKey:w,setDefault:!0,models:[{id:_,name:_,enabled:!0,priority:10}]})});if(!v.ok){let D=await v.text();throw new Error(D||`HTTP ${v.status}`)}c("done"),setTimeout(e,1200)}catch(B){M(String(B)),c("error")}},[t,m,h,w,_,e]);cs(()=>{if(s==="done")return;i(async()=>{try{(await(await fetch(`${t}/api/config/provider`)).json())?.data?.configured&&e()}catch{}},"check")()},[s,t,e]),ls((B,K)=>{if(K.escape&&a&&n){n();return}if(s==="select_provider"){if(K.upArrow||B==="k")f(v=>(v-1+rt.length)%rt.length);else if(K.downArrow||B==="j")f(v=>(v+1)%rt.length);else if(K.return){let v=rt[d];g(v);let D=Ve[v];k(D.baseUrl),y(D.defaultModel),c("enter_key")}return}if(s==="error"){if(K.escape&&a&&n){n();return}K.return&&(c("enter_key"),M(""))}});let p=i(()=>{if(w.trim().length<10){M("API key too short (min 10 characters).");return}M(""),m==="custom"?c("enter_model"):r()},"handleKeySubmit"),l=i(()=>{if(_.trim().length===0){M("Model name is required.");return}r()},"handleModelSubmit");if(s==="done")return ne(He,{flexDirection:"column",padding:1,children:[G(L,{color:u.success,children:"\u2713 Configuration saved!"}),o==="fullscreen"&&G(L,{dimColor:!0,children:"Starting JWCode..."})]});let x=a?"single":"round",b=a?u.warning:u.primary,P=a?"Add Provider":"JWCode \u2014 First Run Setup";return ne(He,{flexDirection:"column",padding:1,borderStyle:x,borderColor:b,children:[G(He,{marginBottom:1,children:G(L,{bold:!0,color:u.primary,children:P})}),o==="fullscreen"&&ne(ds,{children:[G(L,{children:"Configure your AI provider to get started."}),G(L,{children:" "})]}),a&&n&&G(L,{dimColor:!0,children:"Esc to close"}),s==="select_provider"&&ne(He,{flexDirection:"column",children:[G(L,{children:"Select provider (\u2191\u2193 to navigate, Enter to confirm):"}),rt.map((B,K)=>ne(L,{children:[K===d?"\u276F ":" ",G(L,{color:K===d?"green":void 0,bold:K===d,children:Ve[B].name}),K===d?" \u25C0":""]},B))]}),s==="enter_key"&&ne(He,{flexDirection:"column",children:[ne(L,{children:["Provider: ",G(L,{color:u.success,children:Ve[m].name})]}),ne(L,{children:["Base URL: ",G(L,{color:u.info,children:h})]}),G(L,{children:" "}),G(L,{children:"Enter API Key:"}),G(Ye,{value:w,onChange:T,onSubmit:p,placeholder:"sk-..."}),G(L,{dimColor:!0,children:"Press Enter to confirm"}),S&&ne(L,{color:u.error,children:["Error: ",S]})]}),s==="enter_model"&&ne(He,{flexDirection:"column",children:[ne(L,{children:["Provider: ",G(L,{color:u.success,children:Ve[m].name})]}),ne(L,{children:["API Key: ",G(L,{color:u.success,children:"configured"})]}),G(L,{children:" "}),ne(L,{children:["Base URL: ",G(L,{color:u.info,children:h})]}),G(L,{children:" "}),G(L,{children:"Model ID:"}),G(Ye,{value:_,onChange:y,onSubmit:l,placeholder:"model-name"}),G(L,{dimColor:!0,children:"Press Enter to confirm, type to edit model name"}),S&&ne(L,{color:u.error,children:["Error: ",S]})]}),s==="saving"&&G(L,{color:u.warning,children:"Saving configuration to ~/.jwcode/config.yaml..."}),s==="error"&&ne(He,{flexDirection:"column",children:[ne(L,{color:u.error,children:["Failed to save: ",S]}),ne(L,{children:["Press Enter to retry",a?", Esc to cancel":"","."]})]})]})},"SetupWizard");kt();import{existsSync as ho}from"node:fs";import{join as xo}from"node:path";import{readFileSync as Ss,existsSync as ys}from"node:fs";import{join as po}from"node:path";import{homedir as ks}from"node:os";var Xe={backend_url:"http://localhost:8080",ws_url:"ws://localhost:8081/ws",ws_auth_token:"default-token",workspace_dir:""};function Cs(t){let e={};for(let n of t.split(`
|
|
78
|
+
`)){let o=n.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf(":");if(s===-1)continue;let c=o.slice(0,s).trim(),d=o.slice(s+1).trim();if(typeof d=="string")if(d==="true"||d==="false")d=d==="true";else if(/^\d+$/.test(d))d=parseInt(d);else{let f=d.match(/^["'](.*)["']$/);f&&(d=f[1])}e[c]=d}return e}i(Cs,"parseYaml");function fo(){let t=po(ks(),".jwcode"),e=po(t,"config.yaml");if(!ys(e))return{...Xe};try{let n=Ss(e,"utf-8"),o=Cs(n);return{backend_url:o.backend_url||Xe.backend_url,ws_url:o.ws_url||Xe.ws_url,ws_auth_token:o.ws_auth_token||Xe.ws_auth_token,workspace_dir:o.workspace_dir||Xe.workspace_dir}}catch{return{...Xe}}}i(fo,"loadConfig");["stdout","stderr"].forEach(t=>{let e=process[t];e&&e.on("error",n=>{n.code==="EPIPE"||n.code})});process.on("uncaughtException",t=>{t.code==="EPIPE"||t.code==="ECONNRESET"||(console.error("Fatal error:",t),process.exit(1))});var Ct="3.0.0";function wo(){console.log(`JWCode CLI v${Ct}`),console.log(""),console.log("Usage:"),console.log(" jwcode [options] Start backend + interactive terminal (default)"),console.log(" jwcode start [options] Start backend + interactive terminal"),console.log(" jwcode run [options] Connect to existing backend"),console.log(" jwcode stop Stop running daemon"),console.log(" jwcode update Check for updates / update CLI"),console.log(" jwcode version Print version"),console.log(""),console.log("Options:"),console.log(" -p, --port <port> HTTP port (default: auto, first available from 8080)"),console.log(" -w, --workspace <dir> Workspace directory (default: current directory)"),console.log(" -F, --force Kill existing process on target port before starting"),console.log(" -B, --build Force rebuild backend (dev mode only)"),console.log(" -b, --backend <url> Backend URL (run mode, WS auto-derived)"),console.log(" --ws <url> Override WebSocket URL"),console.log(""),console.log("Environment:"),console.log(" JWCODE_THEME=dark|light Color theme (default: dark)"),console.log(""),console.log("Keyboard shortcuts (in TUI):"),console.log(" / Open command palette"),console.log(" Tab Toggle Plan/Act mode"),console.log(" F1 Toggle help panel"),console.log(" Ctrl+N New session"),console.log(" Ctrl+R Session history picker"),console.log(" Ctrl+L Clear screen"),console.log(" Ctrl+S Pause/resume generation"),console.log(" Ctrl+E Toggle expand all tool calls"),console.log(" Up/Down Browse input history (last 30)"),console.log(" PgUp/PgDn Scroll message history"),console.log(" Home/End Jump to oldest/newest message"),console.log(" Esc Close palette / pause gen. / deny approval")}i(wo,"printUsage");function Ns(){let t={},e=process.argv.slice(2);for(let n=0;n<e.length;n++){let o=e[n];o==="--build"||o==="-B"?t.build=!0:o==="--force"||o==="-F"?t.force=!0:o==="--port"||o==="-p"?t.port=e[++n]:o==="--workspace"||o==="-w"?t.workspace=e[++n]:o==="--backend"||o==="-b"?t.backend=e[++n]:o==="--ws"?t.ws=e[++n]:o.startsWith("-")||(t._cmd=o)}return t}i(Ns,"parseArgs");async function Hs(t){let e=!!t.force,n=!!t.build,o=String(t.workspace||process.cwd()),s=qt(),c=Qt(o);if(c){let h=c.httpPort,k=c.wsPort;console.log("[daemon] Reusing existing daemon (PID "+c.pid+") on ports "+h+"/"+k),yt(c.pid,h,k,o),await To(h,k,o,s);return}let d,f;if(t.port)d=parseInt(String(t.port),10),f=d+1,!e&&(We(d)||We(f))&&(console.error(`[launcher] Port ${d} or ${f} is already in use.`),console.error("[launcher] Use --force to replace the existing process, or omit -p for auto port selection."),process.exit(1));else{let h=Xt(8080);d=h.httpPort,f=h.wsPort}console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"),console.log("\u2551 JWCode \u2014 Java AI Coding Tool \u2551"),console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"),console.log(` Workspace: ${o}`),console.log(` HTTP API: http://localhost:${d}`),console.log(` WebSocket: ws://localhost:${f}/ws`),(n||!ve(s))&&(ho(xo(s,"pom.xml"))?St(s):ve(s)||(console.error("[launcher] Backend JAR not found and no pom.xml for build."),console.error("[launcher] Install via: npm install -g @jwcode/cli"),process.exit(1))),(n||!ve(s))&&(ho(xo(s,"pom.xml"))?St(s):ve(s)||(console.error("[launcher] Backend JAR not found. Run: npm install -g @jwcode/cli"),process.exit(1)));let m=zt({installDir:s,workspaceDir:o,port:d,wsPort:f,forceKill:e,idleTimeout:300}),g=!1,w=i(()=>{g||(g=!0,process.stdout.write("\x1B[?1049l"),console.log(`
|
|
79
|
+
[jwcode] Closing. Daemon continues running in background.`),console.log("[daemon] Stop it with: jwcode stop"))},"cleanup");process.on("SIGINT",()=>{w(),process.exit(0)}),process.on("SIGTERM",()=>{w(),process.exit(0)}),process.on("exit",w),await Yt(d),Promise.resolve().then(()=>(nn(),tn)).then(({checkForUpdates:h})=>{h(Ct).then(k=>{k?.updateAvailable&&(console.log(`
|
|
80
|
+
Update available: v${k.current} \u2192 v${k.latest}`),console.log(` Run 'jwcode update' (or '${k.url}') to upgrade.
|
|
81
|
+
`))}).catch(()=>{})});let T=setInterval(()=>{Promise.resolve().then(()=>(kt(),Zt)).then(({readDaemonInfo:h,isDaemonAlive:k,startDaemon:_,writeDaemonInfo:y})=>{let S=h();if(S&&!k(S)){console.error(`
|
|
82
|
+
[daemon] Daemon process died. Attempting auto-restart...`);try{let M=_({installDir:s,workspaceDir:o,port:d,wsPort:f,forceKill:!0,idleTimeout:300});y(M.pid,d,f,o),console.error("[daemon] Daemon restarted successfully.")}catch(M){console.error("[daemon] Auto-restart failed:",String(M))}}}).catch(()=>{})},3e4);await To(d,f,o,s),clearInterval(T)}i(Hs,"cmdStart");async function To(t,e,n,o){let s=`http://localhost:${t}`,c=`ws://localhost:${e}/ws`;process.stdout.write("\x1B[?1049h"),process.stdout.write("\x1B[2J\x1B[H");let d=!1;try{d=(await(await fetch(`${s}/api/config/provider`)).json())?.data?.configured===!0}catch{}d||await new Promise(m=>{let{unmount:g}=on(rn(ro,{backendUrl:s,onComplete:i(()=>{g(),m()},"onComplete")}))});let{unmount:f}=on(rn(Ut,{backendUrl:s,wsUrl:c,onExit:i(()=>{process.stdout.write("\x1B[?1049l"),process.exit(0)},"onExit")}));await new Promise(m=>{process.on("SIGINT",()=>m()),process.on("SIGTERM",()=>m())}),process.stdout.write("\x1B[?1049l")}i(To,"startTUI");async function Ws(t){process.stdin.isTTY||(console.error("Error: jwcode requires a real terminal (TTY)."),console.error("Please run from a terminal emulator like Windows Terminal, CMD, or PowerShell."),process.exit(1)),process.env.JWCODE_NO_BRACKETED_PASTE!=="1"&&process.stdout.write("\x1B[?2004h");let e=fo(),n=String(t.backend||e.backend_url),o=String(t.ws||n.replace(/^http/,"ws").replace(/:(\d+)/,(d,f)=>":"+(parseInt(f)+1))+"/ws"||e.ws_url);process.stdout.write("\x1B[?1049h"),process.stdout.write("\x1B[2J\x1B[H");let{unmount:s,waitUntilExit:c}=on(rn(Ut,{backendUrl:n,wsUrl:o,onExit:i(()=>{process.stdout.write("\x1B[?1049l"),process.exit(0)},"onExit")}));await c(),process.stdout.write("\x1B[?1049l")}i(Ws,"cmdRun");async function $s(){let{execSync:t}=await import("node:child_process"),{readDaemonInfo:e,clearDaemonInfo:n,isDaemonAlive:o}=await Promise.resolve().then(()=>(kt(),Zt)),s=e();if(!s){console.log("No daemon is running.");return}if(!o(s)){console.log("Daemon process is already dead. Cleaning up."),n();return}console.log("Stopping JWCode daemon (PID "+s.pid+")...");try{process.platform==="win32"?t("taskkill /F /T /PID "+s.pid,{stdio:"ignore"}):process.kill(s.pid,"SIGTERM"),n(),console.log("Daemon stopped.")}catch(c){console.error("Failed to stop daemon:",String(c))}}i($s,"cmdStop");async function js(){let{checkForUpdates:t,runNpmUpdate:e}=await Promise.resolve().then(()=>(nn(),tn));console.log("Checking for updates...");let n=await t(Ct);if(!n){console.log("Could not check for updates. Try again later or install manually:"),console.log(" npm install -g @jwcode/cli@latest");return}if(!n.updateAvailable){console.log(`JWCode CLI is up to date (v${n.current}).`);return}if(console.log(`Update available: v${n.current} \u2192 v${n.latest}`),console.log(""),n.body){let c=n.body.split(`
|
|
83
|
+
`).filter(d=>d.trim()).slice(0,3);for(let d of c)console.log(" "+d);console.log("")}let s=(await import("node:readline")).createInterface({input:process.stdin,output:process.stdout});s.question("Update now? [Y/n] ",c=>{if(s.close(),c.toLowerCase()==="n"||c.toLowerCase()==="no"){console.log('Skipped. Run "jwcode update" later or: npm install -g @jwcode/cli@latest'),process.exit(0);return}console.log("Updating...");let d=e();d.ok?console.log("Updated successfully. Restart jwcode to use the new version."):(console.error("Update failed:",d.message),console.log("Try manually: npm install -g @jwcode/cli@latest")),process.exit(d.ok?0:1)})}i(js,"cmdUpdate");async function Us(){if(process.argv.includes("--help")||process.argv.includes("-h")||process.argv.includes("help")){wo();return}if(process.argv.includes("--version")||process.argv.includes("-v")||process.argv.includes("version")){console.log(`JWCode CLI v${Ct}`);return}let t=Ns(),e=t._cmd||"start";switch(e){case"start":await Hs(t);break;case"run":await Ws(t);break;case"stop":await $s();break;case"update":await js();break;default:console.error(`Unknown command: ${e}`),wo(),process.exit(1)}}i(Us,"main");Us().catch(t=>{console.error("Fatal error:",t),process.exit(1)});
|