@tosh99/navi-cli 0.1.1 → 0.1.3
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/README.md +52 -5
- package/dist/cli.js +14 -14
- package/package.json +38 -37
package/README.md
CHANGED
|
@@ -1,15 +1,62 @@
|
|
|
1
1
|
# navi-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A terminal AI chat CLI with multi-provider support. Ask questions, work with files, run code, and switch between AI models — all from your terminal.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
[Bun](https://bun.sh) (v1.3.11 or higher)
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @tosh99/navi-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
Create a `navi.jsonc` file in your project directory:
|
|
18
|
+
|
|
19
|
+
```jsonc
|
|
20
|
+
{
|
|
21
|
+
"DEFAULT_MODEL_PROVIDER": "minimax",
|
|
22
|
+
"DEFAULT_MODEL": "MiniMax-M2.5",
|
|
23
|
+
"API_KEY_MINIMAX": "your-api-key"
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Available Providers
|
|
28
|
+
|
|
29
|
+
| Provider | Models |
|
|
30
|
+
|----------------|------------------------------------------|
|
|
31
|
+
| **OpenRouter** | Kimi K2.5, GPT-4o Mini, Claude 3.5 Haiku |
|
|
32
|
+
| **ZhipuAI** | GLM-4.5, GLM-4.5 Flash, GLM Z1 Flash |
|
|
33
|
+
| **MiniMax** | M2.7, M2.5 |
|
|
34
|
+
|
|
35
|
+
### Environment Variables
|
|
36
|
+
|
|
37
|
+
You can also set API keys via environment variables instead of the config file:
|
|
4
38
|
|
|
5
39
|
```bash
|
|
6
|
-
|
|
40
|
+
export OPENROUTER_API_KEY="your-key"
|
|
41
|
+
export ZHIPU_API_KEY="your-key"
|
|
42
|
+
export MINIMAX_API_KEY="your-key"
|
|
7
43
|
```
|
|
8
44
|
|
|
9
|
-
|
|
45
|
+
## Usage
|
|
10
46
|
|
|
11
47
|
```bash
|
|
12
|
-
|
|
48
|
+
navi
|
|
13
49
|
```
|
|
14
50
|
|
|
15
|
-
|
|
51
|
+
- Type your message and press **Enter** to send
|
|
52
|
+
- Type `/models` to switch AI models
|
|
53
|
+
- Use **↑/↓** arrows to navigate suggestions
|
|
54
|
+
- Press **Esc** to quit
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install -g @tosh99/navi-cli
|
|
60
|
+
echo '{"DEFAULT_MODEL_PROVIDER": "minimax", "DEFAULT_MODEL": "MiniMax-M2.5", "API_KEY_MINIMAX": "your-key"}' > navi.jsonc
|
|
61
|
+
navi
|
|
62
|
+
```
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
import{useEffect as
|
|
3
|
-
${
|
|
4
|
-
${
|
|
5
|
-
`).slice(0,8000)}catch(
|
|
6
|
-
`);for(let
|
|
7
|
-
`).length>7800)return
|
|
8
|
-
`)}}catch{}}return
|
|
9
|
-
`):"No matches found."}catch(
|
|
10
|
-
`),
|
|
11
|
-
`).slice(0,8000)}catch(
|
|
12
|
-
`),$=[],J=0;while(J<Y.length){let U=Y[J],K=U.match(/^(`{3,}|~{3,})\s*(\S*)/);if(K){let G=K[1],P=K[2]??"",R=[];J++;while(J<Y.length&&!Y[J].startsWith(G.slice(0,3)))R.push(Y[J]),J++;$.push({k:"code",lang:P,lines:R}),J++;continue}let H=U.match(/^(#{1,6})\s+(.+)/);if(H){$.push({k:"h",level:H[1].length,segs:g(H[2])}),J++;continue}if(/^[-*_]{3,}\s*$/.test(U)){$.push({k:"hr"}),J++;continue}if(U.startsWith("|")){let G=[];while(J<Y.length&&Y[J].trimEnd().startsWith("|"))G.push(Y[J]),J++;let P=G.findIndex((R)=>/^\|[\s|:\-]+\|?\s*$/.test(R));if(P>=1&&G[0]){let R=UJ(G[0]),k=dJ(G[P]),j=G.slice(P+1).map(UJ);$.push({k:"table",headers:R,rows:j,aligns:k})}else for(let R of G)$.push({k:"p",segs:g(R)});continue}let O=U.match(/^(\s*)[*\-+]\s+(.+)/);if(O){let G=Math.floor(O[1].length/2);$.push({k:"li",ordered:!1,n:0,depth:G,segs:g(O[2])}),J++;continue}let _=U.match(/^(\s*)(\d+)\.\s+(.+)/);if(_){let G=Math.floor(_[1].length/2);$.push({k:"li",ordered:!0,n:parseInt(_[2],10),depth:G,segs:g(_[3])}),J++;continue}let w=U.match(/^>\s?(.*)/);if(w){$.push({k:"bq",segs:g(w[1])}),J++;continue}if(U.trim()===""){J++;continue}let Q=[];while(J<Y.length){let G=Y[J];if(G.trim()===""||/^#{1,6}\s/.test(G)||/^(`{3,}|~{3,})/.test(G)||/^[-*_]{3,}\s*$/.test(G)||/^\s*[*\-+]\s/.test(G)||/^\s*\d+\.\s/.test(G)||/^>\s/.test(G)||G.startsWith("|"))break;Q.push(G),J++}if(Q.length)$.push({k:"p",segs:g(Q.join(" "))})}return $}var cJ=["#ffcc77","#ffb347","#e8a020","#cc8800","#aa6600","#886600"],lJ=({lang:X,lines:Y})=>q(S,{flexDirection:"column",marginY:1,paddingX:1,borderStyle:"single",borderColor:"#3a3a3a",children:[X?q(z,{color:"#555555",dimColor:!0,children:X},void 0,!1,void 0,this):null,Y.map(($,J)=>q(z,{color:"#d4c5a9",children:$},J,!1,void 0,this))]},void 0,!0,void 0,this),oJ=({headers:X,rows:Y,aligns:$})=>{let J=X.length,U=Array.from({length:J},(Q,G)=>{let P=e(c(X[G]??[])),R=Y.reduce((k,j)=>Math.max(k,e(c(j[G]??[]))),0);return Math.max(P,R,3)});function K(Q,G,P){let R=G-e(Q);if(P==="right")return" "+" ".repeat(R)+Q+" ";if(P==="center"){let k=Math.floor(R/2),j=R-k;return" "+" ".repeat(k)+Q+" ".repeat(j)+" "}return" "+Q+" ".repeat(R)+" "}let H="#3a3a3a",O="┌"+U.map((Q)=>"─".repeat(Q+2)).join("┬")+"┐",_="├"+U.map((Q)=>"─".repeat(Q+2)).join("┼")+"┤",w="└"+U.map((Q)=>"─".repeat(Q+2)).join("┴")+"┘";return q(S,{flexDirection:"column",marginY:1,children:[q(z,{color:H,children:O},void 0,!1,void 0,this),q(S,{children:[q(z,{color:H,children:"│"},void 0,!1,void 0,this),U.map((Q,G)=>q(HJ.Fragment,{children:[q(z,{bold:!0,color:"#ffb347",children:K(c(X[G]??[]),Q,$[G]??null)},void 0,!1,void 0,this),q(z,{color:H,children:"│"},void 0,!1,void 0,this)]},G,!0,void 0,this))]},void 0,!0,void 0,this),q(z,{color:H,children:_},void 0,!1,void 0,this),Y.map((Q,G)=>q(S,{children:[q(z,{color:H,children:"│"},void 0,!1,void 0,this),U.map((P,R)=>q(HJ.Fragment,{children:[q(z,{color:"#aaaaaa",children:K(c(Q[R]??[]),P,$[R]??null)},void 0,!1,void 0,this),q(z,{color:H,children:"│"},void 0,!1,void 0,this)]},R,!0,void 0,this))]},G,!0,void 0,this)),q(z,{color:H,children:w},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},ZJ=({content:X})=>{let Y=xJ(X);return q(S,{flexDirection:"column",children:Y.map(($,J)=>{let U=Y[J+1],K=$.k==="li"&&U?.k!=="li";if($.k==="code")return q(lJ,{lang:$.lang,lines:$.lines},J,!1,void 0,this);if($.k==="table")return q(oJ,{headers:$.headers,rows:$.rows,aligns:$.aligns},J,!1,void 0,this);if($.k==="hr")return q(S,{marginBottom:1,children:q(z,{color:"#3a3a3a",children:"─".repeat(40)},void 0,!1,void 0,this)},J,!1,void 0,this);if($.k==="h")return q(S,{marginBottom:1,children:q(z,{color:cJ[$.level-1],bold:!0,children:q(x,{segs:$.segs},void 0,!1,void 0,this)},void 0,!1,void 0,this)},J,!1,void 0,this);if($.k==="li")return q(S,{marginBottom:K?1:0,children:[q(z,{color:"#555555",children:[" ".repeat($.depth),$.ordered?`${$.n}. `:"• "]},void 0,!0,void 0,this),q(S,{flexGrow:1,children:q(z,{color:"#aaaaaa",children:q(x,{segs:$.segs},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},J,!0,void 0,this);if($.k==="bq")return q(S,{marginBottom:1,borderStyle:"single",borderLeft:!0,borderRight:!1,borderTop:!1,borderBottom:!1,borderColor:"#555555",paddingLeft:1,children:q(z,{color:"#777777",italic:!0,children:q(x,{segs:$.segs,dim:!0},void 0,!1,void 0,this)},void 0,!1,void 0,this)},J,!1,void 0,this);return q(S,{marginBottom:1,children:q(z,{color:"#aaaaaa",wrap:"wrap",children:q(x,{segs:$.segs},void 0,!1,void 0,this)},void 0,!1,void 0,this)},J,!1,void 0,this)})},void 0,!1,void 0,this)};import{mkdirSync as aJ,writeFileSync as nJ}from"fs";import{join as GJ}from"path";var KJ=GJ(process.cwd(),".navi","sessions");function qJ(){let X=new Date().toISOString();return{id:X.replace(/:/g,"-").replace(/\./g,"-"),createdAt:X}}function QJ(X){aJ(KJ,{recursive:!0});let Y=GJ(KJ,`${X.id}.json`);nJ(Y,JSON.stringify(X,null,2))}import{jsxDEV as Z}from"react/jsx-dev-runtime";var W={border:"#3a3a3a",label:"#555555",text:"#aaaaaa",textDim:"#444444",amber:"#ffb347",amberGlow:"#ffcc77",amberDim:"#7a4f00",meta:"#3d3d3d"},WJ=[{cmd:"/models",description:"switch model"}],eJ=["███╗ ██╗ █████╗ ██╗ ██╗██╗","████╗ ██║██╔══██╗██║ ██║██║","██╔██╗ ██║███████║██║ ██║██║","██║╚██╗██║██╔══██║╚██╗ ██╔╝██║","██║ ╚████║██║ ██║ ╚████╔╝ ██║","╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═══╝ ╚═╝"],JX=YJ();function XX(X){let Y=s.find((J)=>J.id===X.providerId),$=Y?.models.find((J)=>J.id===X.modelId);return $?`${Y.label} / ${$.label}`:X.modelId}var YX=({selectionLabel:X})=>Z(L,{flexDirection:"column",marginBottom:1,children:[eJ.map((Y,$)=>{let J=$===0?W.amberGlow:$<3?W.amber:$<5?W.amberDim:W.meta;return Z(A,{color:J,children:Y},$,!1,void 0,this)}),Z(A,{color:W.textDim,children:["v0.1.0 · ",Z(A,{color:W.label,children:X},void 0,!1,void 0,this),Z(A,{color:W.textDim,children:" · esc to quit"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$X=({content:X})=>Z(L,{flexDirection:"column",marginBottom:1,children:Z(A,{color:W.amber,children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),HX=({stats:X})=>Z(A,{color:W.meta,dimColor:!0,children:[(X.elapsedMs/1000).toFixed(1),"s · ",X.tokensPerSec," tok/s · ↑",X.inputTokens," ↓",X.outputTokens]},void 0,!0,void 0,this),UX=({entry:X})=>Z(L,{flexDirection:"column",marginBottom:1,children:[Z(A,{color:W.amber,children:["⚙ ",Z(A,{bold:!0,children:X.toolName},void 0,!1,void 0,this),Z(A,{color:W.label,children:" "+JSON.stringify(X.args)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.result!==void 0&&Z(A,{color:W.textDim,dimColor:!0,children:X.result.slice(0,400)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),ZX=({content:X,reasoning:Y,toolCalls:$,isLast:J,streaming:U,stats:K})=>Z(L,{flexDirection:"column",marginBottom:1,children:[Y&&Z(L,{marginBottom:1,children:Z(A,{color:W.textDim,dimColor:!0,children:Y?.trim()},void 0,!1,void 0,this)},void 0,!1,void 0,this),$?.map((H,O)=>Z(UX,{entry:H},O,!1,void 0,this)),X?.trim()?J&&U?Z(A,{color:W.text,children:[X.trim(),Z(A,{color:W.amber,children:"▌"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):Z(ZJ,{content:X.trim()},void 0,!1,void 0,this):J&&U?Z(A,{color:W.amber,children:"▌"},void 0,!1,void 0,this):null,!U&&K&&Z(HX,{stats:K},void 0,!1,void 0,this)]},void 0,!0,void 0,this),NJ=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function KX(){let X=[];for(let Y of s){X.push({providerId:Y.id,providerLabel:Y.label,modelId:"",modelLabel:"",isHeader:!0});for(let $ of Y.models)X.push({providerId:Y.id,providerLabel:Y.label,modelId:$.id,modelLabel:$.label,isHeader:!1})}return X}var OJ=KX(),m=OJ.filter((X)=>!X.isHeader),GX=({current:X,onSelect:Y})=>{let $=m.findIndex((H)=>H.providerId===X.providerId&&H.modelId===X.modelId),[J,U]=h(Math.max(0,$));FJ((H,O)=>{if(O.upArrow)U((_)=>(_-1+m.length)%m.length);if(O.downArrow)U((_)=>(_+1)%m.length);if(O.return){let _=m[J];Y({providerId:_.providerId,modelId:_.modelId})}});let K=m[J];return Z(L,{flexDirection:"column",marginBottom:1,children:OJ.map((H,O)=>H.isHeader?Z(A,{color:W.label,children:" "+H.providerLabel},O,!1,void 0,this):Z(L,{children:Z(A,{color:H.providerId===K.providerId&&H.modelId===K.modelId?W.amber:W.textDim,children:[H.providerId===K.providerId&&H.modelId===K.modelId?" ❯ ":" ",H.modelLabel,H.providerId===X.providerId&&H.modelId===X.modelId?Z(A,{color:W.label,children:" (active)"},void 0,!1,void 0,this):""]},void 0,!0,void 0,this)},O,!1,void 0,this))},void 0,!1,void 0,this)},qX=()=>{let[X,Y]=h(""),[$,J]=h([]),[U,K]=h(!1),[H,O]=h(JX),[_,w]=h(!1),[Q,G]=h(0),[P,R]=h(null),k=JJ(null),[j,_J]=h(0);iJ(()=>{if(!U)return;let N=setInterval(()=>_J((B)=>(B+1)%NJ.length),80);return()=>clearInterval(N)},[U]);let l=JJ(null),XJ=JJ([]),d=(N)=>{J((B)=>{let I=N(B);return XJ.current=I,I})},o=X.startsWith("/"),T=o?WJ.filter((N)=>N.cmd.startsWith(X)):[],AJ=Math.max(...WJ.map((N)=>N.cmd.length));FJ((N,B)=>{if(B.escape){if(_){w(!1);return}process.exit(0)}if(T.length>0){if(B.upArrow){G((I)=>(I-1+T.length)%T.length);return}if(B.downArrow){G((I)=>(I+1)%T.length);return}if(B.return){let I=T[Q]?.cmd;if(I)r(I);return}}});let r=(N)=>{if(Y(""),G(0),N==="/models")w(!0)},RJ=async(N)=>{if(U)return;if(P!==null)R(null),k.current=null;if(T.length>0){let b=T[Q]?.cmd;if(b)r(b);return}if(o){r(N.trim());return}if(!N.trim())return;if(Y(""),!l.current)l.current=qJ();let B={role:"user",content:N},I=[...$,B];d(()=>[...I,{role:"assistant",content:""}]),K(!0);try{let{stream:b,stats:a}=$J(I,H);for await(let M of b)if(d((C)=>{let f=[...C],y=f[f.length-1];if(!y||y.role!=="assistant")return C;if(M.type==="text")return[...f.slice(0,-1),{...y,content:y.content+M.delta}];if(M.type==="reasoning")return[...f.slice(0,-1),{...y,reasoning:(y.reasoning??"")+M.delta}];if(M.type==="tool-call")return[...f.slice(0,-1),{...y,toolCalls:[...y.toolCalls??[],{toolName:M.toolName,args:M.args}]}];if(M.type==="tool-result"){let v=[...y.toolCalls??[]],E=-1;for(let p=v.length-1;p>=0;p--)if(v[p].toolName===M.toolName&&v[p].result===void 0){E=p;break}if(E>=0)v[E]={...v[E],result:M.result};return[...f.slice(0,-1),{...y,toolCalls:v}]}if(M.type==="ask-user"){let v=M.question;k.current=v,R(v);let E={...y,content:y.content+(y.content.trim()?`
|
|
13
|
-
|
|
14
|
-
`:"")+v};return[...f.slice(0,-1),E]}return C}),M.type==="ask-user")break;let u=await a;d((M)=>{let C=[...M],f=C[C.length-1];if(f?.role==="assistant")C[C.length-1]={...f,stats:u};return C})}catch(b){d((a)=>{let u=[...a];return u[u.length-1]={role:"assistant",content:`ERR: ${b instanceof Error?b.message:String(b)}`},u})}finally{K(!1),QJ({...l.current,model:H,messages:XJ.current})}},zJ=(N)=>{Y(N),G(0)};return Z(L,{flexDirection:"column",paddingX:1,paddingTop:1,children:[Z(YX,{selectionLabel:XX(H)},void 0,!1,void 0,this),$.map((N,B)=>N.role==="user"?Z($X,{content:N.content},B,!1,void 0,this):Z(ZX,{content:N.content,reasoning:N.reasoning,toolCalls:N.toolCalls,isLast:B===$.length-1,streaming:U,stats:N.stats},B,!1,void 0,this)),_&&Z(GX,{current:H,onSelect:(N)=>{O(N),w(!1)}},void 0,!1,void 0,this),T.length>0&&Z(L,{flexDirection:"column",marginBottom:1,children:T.map((N,B)=>Z(L,{children:Z(A,{color:B===Q?W.amber:W.textDim,children:[B===Q?" ❯ ":" ",Z(A,{bold:B===Q,children:N.cmd.padEnd(AJ)},void 0,!1,void 0,this)," ",Z(A,{color:W.label,children:N.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},N.cmd,!1,void 0,this))},void 0,!1,void 0,this),Z(L,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:W.border},void 0,!1,void 0,this),P!==null&&Z(L,{marginBottom:1,children:[Z(A,{color:W.amber,children:"? "},void 0,!1,void 0,this),Z(A,{color:W.amberGlow,children:P},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z(L,{children:[Z(A,{color:P!==null?W.amberGlow:W.amber,children:"❯ "},void 0,!1,void 0,this),Z(L,{flexGrow:1,children:Z(A,{color:o?W.amber:void 0,children:Z(sJ,{value:X,onChange:zJ,onSubmit:RJ,placeholder:_?"↑↓ navigate enter select esc cancel":U?NJ[j]??"⠋":P!==null?"type your answer...":"type here..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Z(L,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:W.border},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};tJ(Z(qX,{},void 0,!1,void 0,this));
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import{render as It}from"ink";import{useEffect as Bt,useRef as we,useState as H}from"react";import{Box as L,Text as Y,useInput as $t}from"ink";import vt from"ink-text-input";import{mkdirSync as Ue}from"fs";import{homedir as Ze}from"os";import{dirname as ze,join as D}from"path";var v={OpenRouter:"openrouter",Zhipu:"zhipu",MiniMax:"minimax"},$={KimiK2_5:"moonshotai/kimi-k2.5",Gpt4oMini:"openai/gpt-4o-mini",Claude35Haiku:"anthropic/claude-3.5-haiku",Glm45:"glm-4.5",Glm47:"glm-4.7",Glm5:"glm-5",Glm5Turbo:"glm-5-turbo",MinimaxM27:"MiniMax-M2.7",MinimaxM27HighSpeed:"MiniMax-M2.7-High-Speed",MinimaxM25:"MiniMax-M2.5"},U=[{id:v.OpenRouter,label:"OpenRouter",models:[{id:$.KimiK2_5,label:"Kimi K2.5",maxContext:128000},{id:$.Gpt4oMini,label:"GPT-4o Mini",maxContext:128000},{id:$.Claude35Haiku,label:"Claude 3.5 Haiku",maxContext:200000}]},{id:v.Zhipu,label:"ZhipuAI",models:[{id:$.Glm5,label:"GLM-5",maxContext:200000},{id:$.Glm5Turbo,label:"GLM-5 Turbo",maxContext:200000},{id:$.Glm47,label:"GLM-4.7",maxContext:200000},{id:$.Glm45,label:"GLM-4.5",maxContext:128000}]},{id:v.MiniMax,label:"MiniMax",models:[{id:$.MinimaxM27HighSpeed,label:"M2.7 High Speed",maxContext:200000},{id:$.MinimaxM27,label:"M2.7",maxContext:200000},{id:$.MinimaxM25,label:"M2.5",maxContext:200000}]}];function ue(e,r){return U.find((n)=>n.id===e)?.models.find((n)=>n.id===r)?.maxContext??128000}var Ke={providerId:v.MiniMax,modelId:$.MinimaxM25};function qe(e){return e.replace(/("(?:[^"\\]|\\.)*")|\/\/[^\n]*/g,(r,o)=>o??"").replace(/("(?:[^"\\]|\\.)*")|\/\*[\s\S]*?\*\//g,(r,o)=>o??"")}var Xe=[process.cwd(),D(process.cwd(),".navi"),D(Ze(),".navi")],fe=null;async function Qe(){for(let e of Xe)for(let r of["navi.jsonc","navi.json"]){let o=D(e,r),t=Bun.file(o);if(await t.exists())return fe=o,JSON.parse(qe(await t.text()))}return{}}var X=await Qe();function ae(e){return X[e]||process.env[e]||void 0}var Ye=[["API_KEY_OPENROUTER","OPENROUTER_API_KEY"],["API_KEY_ZHIPU","ZHIPU_API_KEY"],["API_KEY_MINIMAX","MINIMAX_API_KEY"]];for(let[e,r]of Ye){let o=ae(e);if(o)process.env[r]??=o}function pe(){let e=ae("DEFAULT_MODEL_PROVIDER"),r=ae("DEFAULT_MODEL");if(e&&r)return{providerId:e,modelId:r};return Ke}function ge(e){return X.PROVIDER_CONFIG?.[e]}function he(e,r){X.DEFAULT_MODEL_PROVIDER=e,X.DEFAULT_MODEL=r;let o=fe??D(process.cwd(),"navi.jsonc");Ue(ze(o),{recursive:!0}),Bun.write(o,JSON.stringify(X,null,4))}import{stepCountIs as lt,streamText as mt}from"ai";import{tool as w}from"ai";import{exec as We}from"child_process";import{mkdirSync as le,renameSync as Ee,rmSync as De}from"fs";import{dirname as me,resolve as T}from"path";import{promisify as Ve}from"util";import{z as p}from"zod";var je=Ve(We),be={bash:w({description:"Run a bash/shell command and return stdout/stderr. Use for file operations, running scripts, checking system info, etc.",inputSchema:p.object({command:p.string().describe("The shell command to execute")}),execute:async({command:e})=>{try{let{stdout:r,stderr:o}=await je(e,{timeout:30000});return(r||o||"(no output)").slice(0,8000)}catch(r){return`Error: ${r.message}
|
|
3
|
+
${r.stdout??""}
|
|
4
|
+
${r.stderr??""}`.trim().slice(0,8000)}}}),glob:w({description:"Find files matching a glob pattern. Returns matching file paths.",inputSchema:p.object({pattern:p.string().describe("Glob pattern, e.g. 'src/**/*.ts'"),cwd:p.string().optional().describe("Base directory to search from (defaults to current working directory)")}),execute:async({pattern:e,cwd:r})=>{try{let o=r?T(r):process.cwd(),t=new Bun.Glob(e),n=[];for await(let i of t.scan({cwd:o,onlyFiles:!0}))n.push(i);if(n.length===0)return"No files found.";return n.join(`
|
|
5
|
+
`).slice(0,8000)}catch(o){return`Error: ${o.message}`}}}),grep:w({description:"Search file contents for a regex pattern. Returns matching lines with file:line format.",inputSchema:p.object({pattern:p.string().describe("Regex pattern to search for"),path:p.string().optional().describe("Directory or file to search in (defaults to cwd)"),fileGlob:p.string().optional().describe("Glob to filter files, e.g. '**/*.ts' (defaults to all files)")}),execute:async({pattern:e,path:r,fileGlob:o})=>{try{let t=r?T(r):process.cwd(),n=new Bun.Glob(o??"**/*"),i=new RegExp(e),a=[];for await(let d of n.scan({cwd:t,onlyFiles:!0})){let f=`${t}/${d}`;try{let C=(await Bun.file(f).text()).split(`
|
|
6
|
+
`);for(let c=0;c<C.length;c++)if(i.test(C[c])){if(a.push(`${d}:${c+1}: ${C[c]}`),a.join(`
|
|
7
|
+
`).length>7800)return a.push("... (truncated)"),a.join(`
|
|
8
|
+
`)}}catch{}}return a.length?a.join(`
|
|
9
|
+
`):"No matches found."}catch(t){return`Error: ${t.message}`}}}),read_file:w({description:"Read the contents of a file. Optionally limit to a range of lines.",inputSchema:p.object({path:p.string().describe("Path to the file"),offset:p.number().int().optional().describe("Line number to start reading from (1-based)"),limit:p.number().int().optional().describe("Maximum number of lines to read")}),execute:async({path:e,offset:r,limit:o})=>{try{let t=T(e),n=(await Bun.file(t).text()).split(`
|
|
10
|
+
`),i=r?r-1:0;return(o!==void 0?n.slice(i,i+o):n.slice(i)).map((d,f)=>`${i+f+1} ${d}`).join(`
|
|
11
|
+
`).slice(0,8000)}catch(t){return`Error: ${t.message}`}}}),sync_file:w({description:"Write, append to, or delete a file. Creates missing parent directories as needed.",inputSchema:p.object({path:p.string().describe("Path to the file"),content:p.string().optional().describe("Content to write or append (not required for delete)"),mode:p.enum(["replace","append","delete"]).optional().describe("'replace' (default) overwrites, 'append' adds to end, 'delete' removes the file")}),execute:async({path:e,content:r="",mode:o="replace"})=>{try{let t=T(e);if(o==="delete")return De(t,{force:!0}),`Deleted ${e}`;if(le(me(t),{recursive:!0}),o==="append"){let n=await Bun.file(t).exists()?await Bun.file(t).text():"";return await Bun.write(t,n+r),`Appended ${r.length} chars to ${e}`}return await Bun.write(t,r),`Written ${r.length} chars to ${e}`}catch(t){return`Error: ${t.message}`}}}),copy_file:w({description:"Copy a file from source to destination, creating missing parent directories.",inputSchema:p.object({src:p.string().describe("Source file path"),dest:p.string().describe("Destination file path")}),execute:async({src:e,dest:r})=>{try{let o=T(r);return le(me(o),{recursive:!0}),await Bun.write(o,Bun.file(T(e))),`Copied ${e} → ${r}`}catch(o){return`Error: ${o.message}`}}}),move_file:w({description:"Move (rename) a file, creating missing parent directories at the destination.",inputSchema:p.object({src:p.string().describe("Source file path"),dest:p.string().describe("Destination file path")}),execute:async({src:e,dest:r})=>{try{let o=T(r);return le(me(o),{recursive:!0}),Ee(T(e),o),`Moved ${e} → ${r}`}catch(o){return`Error: ${o.message}`}}}),patch_file:w({description:"Replace an exact string in a file with new content. Fails if old_str is not found or appears more than once.",inputSchema:p.object({path:p.string().describe("Path to the file"),old_str:p.string().describe("Exact string to find and replace (must be unique in the file)"),new_str:p.string().describe("Replacement string")}),execute:async({path:e,old_str:r,new_str:o})=>{try{let t=T(e),n=await Bun.file(t).text(),i=n.split(r).length-1;if(i===0)return`Error: old_str not found in ${e}`;if(i>1)return`Error: old_str found ${i} times — provide more context to make it unique`;return await Bun.write(t,n.replace(r,o)),`Patched ${e}`}catch(t){return`Error: ${t.message}`}}})};import{openrouter as et}from"@openrouter/ai-sdk-provider";import{createZhipu as tt}from"zhipu-ai-provider";import{createMinimax as rt}from"vercel-minimax-ai-provider";var ot=tt({baseURL:"https://api.z.ai/api/coding/paas/v4"}),nt=rt();function ye(e,r){switch(e){case v.OpenRouter:return et(r);case v.Zhipu:return ot(r,{thinking:{type:"enabled"}});case v.MiniMax:return nt(r);default:throw Error(`Unknown provider: ${e}`)}}var it={[v.OpenRouter]:{reasoning:{effort:"high"},provider:{order:["BaseTen","ModelRun","Fireworks"]}},[v.Zhipu]:{thinking:{type:"enabled"}}};function Me(e,r){let o=it[e]??{},t=r?{...o,...r}:o;if(Object.keys(t).length===0)return{};return{[e]:t}}var Ce=`- If the user asks to make a change, always PLAN first, then confirm the PLAN, then on explicit approval, proceed with the changes.
|
|
12
|
+
- If there is even the slightest doubt, ask for clarification from the user.
|
|
13
|
+
- For generating a commit message, use the tools provided to get diffs from git.`;function Se(e,r){let o=Date.now(),t=ge(r.providerId),n=mt({model:ye(r.providerId,r.modelId),system:Ce,messages:e,tools:be,stopWhen:lt(50),providerOptions:Me(r.providerId,t)}),i=Promise.resolve(n.usage).then((d)=>{let f=Date.now()-o,C=d.outputTokens??0,c=d.inputTokens??0,l=d.totalTokens??0;return{elapsedMs:f,tokensPerSec:f>0?Math.round(C/f*1000):0,inputTokens:c,outputTokens:C,totalTokens:l,maxContext:ue(r.providerId,r.modelId)}});async function*a(){for await(let d of n.fullStream)if(d.type==="text-delta")yield{type:"text",delta:d.text};else if(d.type==="reasoning-delta")yield{type:"reasoning",delta:d.text};else if(d.type==="tool-call")yield{type:"tool-call",toolName:d.toolName,args:d.input};else if(d.type==="tool-result")yield{type:"tool-result",toolName:d.toolName,result:String(d.output)}}return{stream:a(),stats:i}}import{mkdirSync as dt}from"fs";import{join as Be}from"path";var xe=Be(process.cwd(),".navi","sessions");function $e(){let e=new Date().toISOString();return{id:e.replace(/:/g,"-").replace(/\./g,"-"),createdAt:e}}function ve(e){dt(xe,{recursive:!0});let r=Be(xe,`${e.id}.json`);Bun.write(r,JSON.stringify(e,null,2))}var u={border:"#3a3a3a",label:"#555555",text:"#aaaaaa",textDim:"#444444",amber:"#ffb347",amberGlow:"#ffcc77",amberDim:"#7a4f00",meta:"#3d3d3d"},de=[{cmd:"/models",description:"switch model"}],Re=["███╗ ██╗ █████╗ ██╗ ██╗██╗","████╗ ██║██╔══██╗██║ ██║██║","██╔██╗ ██║███████║██║ ██║██║","██║╚██╗██║██╔══██║╚██╗ ██╔╝██║","██║ ╚████║██║ ██║ ╚████╔╝ ██║","╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═══╝ ╚═╝"],ce=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];import{Box as ct,Text as V}from"ink";import{jsxDEV as Q}from"react/jsx-dev-runtime";var Oe=({selectionLabel:e})=>Q(ct,{flexDirection:"column",marginBottom:1,children:[Re.map((r,o)=>{let t=o===0?u.amberGlow:o<3?u.amber:o<5?u.amberDim:u.meta;return Q(V,{color:t,children:r},o,!1,void 0,this)}),Q(V,{color:u.textDim,children:["v0.1.0 · ",Q(V,{color:u.label,children:e},void 0,!1,void 0,this),Q(V,{color:u.textDim,children:" · esc to quit"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);import{Box as te,Text as O}from"ink";import Ie from"react";import{Box as R,Text as h}from"ink";import{jsxDEV as m,Fragment as ht}from"react/jsx-dev-runtime";function A(e){let r=[],o=/(~~[^~]+~~|`[^`]+`|\*\*[^*]+\*\*|\*[^*\n]+\*|_[^_\n]+_)/g,t=0;for(let n of e.matchAll(o)){if(n.index>t)r.push({t:e.slice(t,n.index)});let i=n[0];if(i.startsWith("~~"))r.push({t:i.slice(2,-2),strike:!0});else if(i.startsWith("`"))r.push({t:i.slice(1,-1),code:!0});else if(i.startsWith("**"))r.push({t:i.slice(2,-2),bold:!0});else r.push({t:i.slice(1,-1),italic:!0});t=n.index+i.length}if(t<e.length)r.push({t:e.slice(t)});return r.filter((n)=>n.t)}var j=({segs:e,dim:r})=>m(ht,{children:e.map((o,t)=>o.code?m(h,{color:"#e8b86d",backgroundColor:"#2a2a2a",children:[" ",o.t," "]},t,!0,void 0,this):m(h,{bold:o.bold,italic:o.italic,strikethrough:o.strike,dimColor:r,children:o.t},t,!1,void 0,this))},void 0,!1,void 0,this);function ee(e){return e.map((r)=>r.t).join("")}function se(e){let r=0;for(let o of e){let t=o.codePointAt(0)??0;if(t>=4352&&t<=4447||t>=9001&&t<=9002||t>=9728&&t<=10175||t>=11904&&t<=13311||t>=13312&&t<=19903||t>=19968&&t<=40959||t>=40960&&t<=42191||t>=44032&&t<=55215||t>=63744&&t<=64255||t>=65040&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=126980&&t<=129791||t>=131072&&t<=262141)r+=2;else r+=1}return r}function Ge(e){return e.split("|").slice(1,-1).map((r)=>A(r.trim()))}function st(e){return e.split("|").slice(1,-1).map((r)=>{let o=r.trim();if(o.startsWith(":")&&o.endsWith(":"))return"center";if(o.endsWith(":"))return"right";if(o.startsWith(":"))return"left";return null})}function ut(e){let r=e.split(`
|
|
14
|
+
`),o=[],t=0;while(t<r.length){let n=r[t],i=n.match(/^(`{3,}|~{3,})\s*(\S*)/);if(i){let l=i[1],S=i[2]??"",g=[];t++;while(t<r.length&&!r[t].startsWith(l.slice(0,3)))g.push(r[t]),t++;o.push({k:"code",lang:S,lines:g}),t++;continue}let a=n.match(/^(#{1,6})\s+(.+)/);if(a){o.push({k:"h",level:a[1].length,segs:A(a[2])}),t++;continue}if(/^[-*_]{3,}\s*$/.test(n)){o.push({k:"hr"}),t++;continue}if(n.startsWith("|")){let l=[];while(t<r.length&&r[t].trimEnd().startsWith("|"))l.push(r[t]),t++;let S=l.findIndex((g)=>/^\|[\s|:\-]+\|?\s*$/.test(g));if(S>=1&&l[0]){let g=Ge(l[0]),I=st(l[S]),F=l.slice(S+1).map(Ge);o.push({k:"table",headers:g,rows:F,aligns:I})}else for(let g of l)o.push({k:"p",segs:A(g)});continue}let d=n.match(/^(\s*)[*\-+]\s+(.+)/);if(d){let l=Math.floor(d[1].length/2);o.push({k:"li",ordered:!1,n:0,depth:l,segs:A(d[2])}),t++;continue}let f=n.match(/^(\s*)(\d+)\.\s+(.+)/);if(f){let l=Math.floor(f[1].length/2);o.push({k:"li",ordered:!0,n:parseInt(f[2],10),depth:l,segs:A(f[3])}),t++;continue}let C=n.match(/^>\s?(.*)/);if(C){o.push({k:"bq",segs:A(C[1])}),t++;continue}if(n.trim()===""){t++;continue}let c=[];while(t<r.length){let l=r[t];if(l.trim()===""||/^#{1,6}\s/.test(l)||/^(`{3,}|~{3,})/.test(l)||/^[-*_]{3,}\s*$/.test(l)||/^\s*[*\-+]\s/.test(l)||/^\s*\d+\.\s/.test(l)||/^>\s/.test(l)||l.startsWith("|"))break;c.push(l),t++}if(c.length)o.push({k:"p",segs:A(c.join(" "))})}return o}var ft=["#ffcc77","#ffb347","#e8a020","#cc8800","#aa6600","#886600"],pt=({lang:e,lines:r})=>m(R,{flexDirection:"column",marginY:1,paddingX:1,borderStyle:"single",borderColor:"#3a3a3a",children:[e?m(h,{color:"#555555",dimColor:!0,children:e},void 0,!1,void 0,this):null,r.map((o,t)=>m(h,{color:"#d4c5a9",children:o},t,!1,void 0,this))]},void 0,!0,void 0,this),gt=({headers:e,rows:r,aligns:o})=>{let t=e.length,n=Array.from({length:t},(c,l)=>{let S=se(ee(e[l]??[])),g=r.reduce((I,F)=>Math.max(I,se(ee(F[l]??[]))),0);return Math.max(S,g,3)});function i(c,l,S){let g=l-se(c);if(S==="right")return" "+" ".repeat(g)+c+" ";if(S==="center"){let I=Math.floor(g/2),F=g-I;return" "+" ".repeat(I)+c+" ".repeat(F)+" "}return" "+c+" ".repeat(g)+" "}let a="#3a3a3a",d="┌"+n.map((c)=>"─".repeat(c+2)).join("┬")+"┐",f="├"+n.map((c)=>"─".repeat(c+2)).join("┼")+"┤",C="└"+n.map((c)=>"─".repeat(c+2)).join("┴")+"┘";return m(R,{flexDirection:"column",marginY:1,children:[m(h,{color:a,children:d},void 0,!1,void 0,this),m(R,{children:[m(h,{color:a,children:"│"},void 0,!1,void 0,this),n.map((c,l)=>m(Ie.Fragment,{children:[m(h,{bold:!0,color:"#ffb347",children:i(ee(e[l]??[]),c,o[l]??null)},void 0,!1,void 0,this),m(h,{color:a,children:"│"},void 0,!1,void 0,this)]},l,!0,void 0,this))]},void 0,!0,void 0,this),m(h,{color:a,children:f},void 0,!1,void 0,this),r.map((c,l)=>m(R,{children:[m(h,{color:a,children:"│"},void 0,!1,void 0,this),n.map((S,g)=>m(Ie.Fragment,{children:[m(h,{color:"#aaaaaa",children:i(ee(c[g]??[]),S,o[g]??null)},void 0,!1,void 0,this),m(h,{color:a,children:"│"},void 0,!1,void 0,this)]},g,!0,void 0,this))]},l,!0,void 0,this)),m(h,{color:a,children:C},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Pe=({content:e})=>{let r=ut(e);return m(R,{flexDirection:"column",children:r.map((o,t)=>{let n=r[t+1],i=o.k==="li"&&n?.k!=="li";if(o.k==="code")return m(pt,{lang:o.lang,lines:o.lines},t,!1,void 0,this);if(o.k==="table")return m(gt,{headers:o.headers,rows:o.rows,aligns:o.aligns},t,!1,void 0,this);if(o.k==="hr")return m(R,{marginBottom:1,children:m(h,{color:"#3a3a3a",children:"─".repeat(40)},void 0,!1,void 0,this)},t,!1,void 0,this);if(o.k==="h")return m(R,{marginBottom:1,children:m(h,{color:ft[o.level-1],bold:!0,children:m(j,{segs:o.segs},void 0,!1,void 0,this)},void 0,!1,void 0,this)},t,!1,void 0,this);if(o.k==="li")return m(R,{marginBottom:i?1:0,children:[m(h,{color:"#555555",children:[" ".repeat(o.depth),o.ordered?`${o.n}. `:"• "]},void 0,!0,void 0,this),m(R,{flexGrow:1,children:m(h,{color:"#aaaaaa",children:m(j,{segs:o.segs},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},t,!0,void 0,this);if(o.k==="bq")return m(R,{marginBottom:1,borderStyle:"single",borderLeft:!0,borderRight:!1,borderTop:!1,borderBottom:!1,borderColor:"#555555",paddingLeft:1,children:m(h,{color:"#777777",italic:!0,children:m(j,{segs:o.segs,dim:!0},void 0,!1,void 0,this)},void 0,!1,void 0,this)},t,!1,void 0,this);return m(R,{marginBottom:1,children:m(h,{color:"#aaaaaa",wrap:"wrap",children:m(j,{segs:o.segs},void 0,!1,void 0,this)},void 0,!1,void 0,this)},t,!1,void 0,this)})},void 0,!1,void 0,this)};import{jsxDEV as y}from"react/jsx-dev-runtime";var _e=({content:e})=>y(te,{flexDirection:"column",marginBottom:1,children:y(O,{color:u.amber,children:e},void 0,!1,void 0,this)},void 0,!1,void 0,this),bt=({stats:e})=>{let r=e.maxContext>0?(e.totalTokens/e.maxContext*100).toFixed(1):"?";return y(O,{color:u.meta,dimColor:!0,children:[(e.elapsedMs/1000).toFixed(1),"s · ",e.tokensPerSec," tok/s · ↑",e.inputTokens," ↓",e.outputTokens," ⬡ ",e.totalTokens,"/",Math.round(e.maxContext/1000)+"k"," (",r,"%)"]},void 0,!0,void 0,this)},yt=({entry:e})=>y(te,{flexDirection:"column",marginBottom:1,children:[y(O,{color:u.amber,children:["⚙ ",y(O,{bold:!0,children:e.toolName},void 0,!1,void 0,this),y(O,{color:u.label,children:" "+JSON.stringify(e.args)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e.result!==void 0&&y(O,{color:u.textDim,dimColor:!0,children:e.result.slice(0,400)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Ne=({content:e,reasoning:r,toolCalls:o,isLast:t,streaming:n,stats:i,error:a})=>y(te,{flexDirection:"column",marginBottom:1,children:[r&&y(te,{marginBottom:1,children:y(O,{color:u.textDim,dimColor:!0,children:r?.trim()},void 0,!1,void 0,this)},void 0,!1,void 0,this),o?.map((d,f)=>y(yt,{entry:d},f,!1,void 0,this)),e?.trim()?a?y(O,{color:"red",children:e.trim()},void 0,!1,void 0,this):t&&n?y(O,{color:u.text,children:[e.trim(),y(O,{color:u.amber,children:"▌"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):y(Pe,{content:e.trim()},void 0,!1,void 0,this):t&&n?y(O,{color:u.amber,children:"▌"},void 0,!1,void 0,this):null,!n&&i&&y(bt,{stats:i},void 0,!1,void 0,this)]},void 0,!0,void 0,this);import{useState as Mt}from"react";import{Box as Te,Text as re,useInput as Ct}from"ink";import{jsxDEV as z}from"react/jsx-dev-runtime";function St(e){return Math.round(e/1000)+"k"}function xt(){let e=[];for(let r of U){e.push({providerId:r.id,providerLabel:r.label,modelId:"",modelLabel:"",maxContext:0,isHeader:!0});for(let o of r.models)e.push({providerId:r.id,providerLabel:r.label,modelId:o.id,modelLabel:o.label,maxContext:o.maxContext,isHeader:!1})}return e}var Fe=xt(),Z=Fe.filter((e)=>!e.isHeader),ke=({current:e,onSelect:r})=>{let o=Z.findIndex((a)=>a.providerId===e.providerId&&a.modelId===e.modelId),[t,n]=Mt(Math.max(0,o));Ct((a,d)=>{if(d.upArrow)n((f)=>(f-1+Z.length)%Z.length);if(d.downArrow)n((f)=>(f+1)%Z.length);if(d.return){let f=Z[t];r({providerId:f.providerId,modelId:f.modelId})}});let i=Z[t];return z(Te,{flexDirection:"column",marginBottom:1,children:Fe.map((a,d)=>a.isHeader?z(re,{color:u.label,children:" "+a.providerLabel},d,!1,void 0,this):z(Te,{children:z(re,{color:a.providerId===i.providerId&&a.modelId===i.modelId?u.amber:u.textDim,children:[a.providerId===i.providerId&&a.modelId===i.modelId?" ❯ ":" ",a.modelLabel,z(re,{color:u.label,children:" "+St(a.maxContext)},void 0,!1,void 0,this),a.providerId===e.providerId&&a.modelId===e.modelId?z(re,{color:u.label,children:" (active)"},void 0,!1,void 0,this):""]},void 0,!0,void 0,this)},d,!1,void 0,this))},void 0,!1,void 0,this)};import{jsxDEV as M}from"react/jsx-dev-runtime";var Rt=pe();function Ot(e){let r=U.find((t)=>t.id===e.providerId),o=r?.models.find((t)=>t.id===e.modelId);return o?`${r.label} / ${o.label}`:e.modelId}var Ae=()=>{let[e,r]=H(""),[o,t]=H([]),[n,i]=H(!1),[a,d]=H(Rt),[f,C]=H(!1),[c,l]=H(0),[S,g]=H(0);Bt(()=>{if(!n)return;let s=setInterval(()=>g((b)=>(b+1)%ce.length),80);return()=>clearInterval(s)},[n]);let I=we(null),F=we([]),W=(s)=>{t((b)=>{let x=s(b);return F.current=x,x})},oe=e.startsWith("/"),P=oe?de.filter((s)=>s.cmd.startsWith(e)):[],He=Math.max(...de.map((s)=>s.cmd.length));$t((s,b)=>{if(b.escape){if(f){C(!1);return}process.exit(0)}if(P.length>0){if(b.upArrow){l((x)=>(x-1+P.length)%P.length);return}if(b.downArrow){l((x)=>(x+1)%P.length);return}if(b.return){let x=P[c]?.cmd;if(x)ne(x);return}}});let ne=(s)=>{if(r(""),l(0),s==="/models")C(!0)},Le=async(s)=>{if(n)return;if(P.length>0){let k=P[c]?.cmd;if(k)ne(k);return}if(oe){ne(s.trim());return}if(!s.trim())return;if(r(""),!I.current)I.current=$e();let b={role:"user",content:s},x=[...o,b];W(()=>[...x,{role:"assistant",content:""}]),i(!0);try{let{stream:k,stats:ie}=Se(x,a);for await(let B of k)W((_)=>{let N=[..._],G=N[N.length-1];if(!G||G.role!=="assistant")return _;if(B.type==="text")return[...N.slice(0,-1),{...G,content:G.content+B.delta}];if(B.type==="reasoning")return[...N.slice(0,-1),{...G,reasoning:(G.reasoning??"")+B.delta}];if(B.type==="tool-call")return[...N.slice(0,-1),{...G,toolCalls:[...G.toolCalls??[],{toolName:B.toolName,args:B.args}]}];if(B.type==="tool-result"){let J=[...G.toolCalls??[]],E=-1;for(let q=J.length-1;q>=0;q--)if(J[q].toolName===B.toolName&&J[q].result===void 0){E=q;break}if(E>=0)J[E]={...J[E],result:B.result};return[...N.slice(0,-1),{...G,toolCalls:J}]}return _});let K=await ie;W((B)=>{let _=[...B],N=_[_.length-1];if(N?.role==="assistant")_[_.length-1]={...N,stats:K};return _})}catch(k){W((ie)=>{let K=[...ie];return K[K.length-1]={role:"assistant",content:k instanceof Error?k.message:String(k),error:!0},K})}finally{i(!1),ve({...I.current,model:a,messages:F.current})}},Je=(s)=>{r(s),l(0)};return M(L,{flexDirection:"column",paddingX:1,paddingTop:1,children:[M(Oe,{selectionLabel:Ot(a)},void 0,!1,void 0,this),o.map((s,b)=>s.role==="user"?M(_e,{content:s.content},b,!1,void 0,this):M(Ne,{content:s.content,reasoning:s.reasoning,toolCalls:s.toolCalls,isLast:b===o.length-1,streaming:n,stats:s.stats,error:s.error},b,!1,void 0,this)),f&&M(ke,{current:a,onSelect:(s)=>{d(s),C(!1),he(s.providerId,s.modelId)}},void 0,!1,void 0,this),P.length>0&&M(L,{flexDirection:"column",marginBottom:1,children:P.map((s,b)=>M(L,{children:M(Y,{color:b===c?u.amber:u.textDim,children:[b===c?" ❯ ":" ",M(Y,{bold:b===c,children:s.cmd.padEnd(He)},void 0,!1,void 0,this)," ",M(Y,{color:u.label,children:s.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},s.cmd,!1,void 0,this))},void 0,!1,void 0,this),M(L,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:u.border},void 0,!1,void 0,this),M(L,{children:[M(Y,{color:u.amber,children:"❯ "},void 0,!1,void 0,this),M(L,{flexGrow:1,children:M(Y,{color:oe?u.amber:void 0,children:M(vt,{value:e,onChange:Je,onSubmit:Le,placeholder:f?"↑↓ navigate enter select esc cancel":n?ce[S]??"⠋":"type here..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M(L,{borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderColor:u.border},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as Gt}from"react/jsx-dev-runtime";It(Gt(Ae,{},void 0,!1,void 0,this));
|
package/package.json
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@tosh99/navi-cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A terminal AI chat CLI with multi-provider support",
|
|
5
|
-
"author": "Anutosh Chaudhuri <anutosh.chaudhuri@gmail.com>",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"module": "src/cli.tsx",
|
|
8
|
-
"type": "module",
|
|
9
|
-
"bin": {
|
|
10
|
-
"navi": "dist/cli.js"
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
"dist"
|
|
14
|
-
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"@types/
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"@
|
|
30
|
-
"ai": "
|
|
31
|
-
"
|
|
32
|
-
"ink
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@tosh99/navi-cli",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "A terminal AI chat CLI with multi-provider support",
|
|
5
|
+
"author": "Anutosh Chaudhuri <anutosh.chaudhuri@gmail.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"module": "src/cli/index.tsx",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"bin": {
|
|
10
|
+
"navi": "dist/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"dev": "bun run --watch src/cli/index.tsx",
|
|
17
|
+
"build": "bun scripts/build.ts",
|
|
18
|
+
"prepublishOnly": "bun run build"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/bun": "latest",
|
|
22
|
+
"@types/react": "^19.2.14",
|
|
23
|
+
"prettier": "^3.8.1"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"typescript": "^5"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@ai-sdk/openai": "^3.0.50",
|
|
30
|
+
"@openrouter/ai-sdk-provider": "^2.3.3",
|
|
31
|
+
"ai": "6",
|
|
32
|
+
"ink": "^6.8.0",
|
|
33
|
+
"ink-text-input": "^6.0.0",
|
|
34
|
+
"react": "^19.2.4",
|
|
35
|
+
"vercel-minimax-ai-provider": "^0.0.2",
|
|
36
|
+
"zhipu-ai-provider": "^0.3.0"
|
|
37
|
+
}
|
|
38
|
+
}
|