@fullkkk/codiq 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +9 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Le}from"commander";import{render as ve}from"ink";import je from"react";import"dotenv/config";async function M(t,e,n){let s=[...n,{role:"user",content:t}];return e.stream?await te({apiKey:e.apiKey,baseUrl:e.baseUrl,model:e.model,messages:s,onToken:e.onToken}):await ee({apiKey:e.apiKey,baseUrl:e.baseUrl,model:e.model,messages:s})}async function ee(t){let e=await fetch(t.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`},body:JSON.stringify({model:t.model,messages:t.messages,stream:!1})});if(!e.ok)throw new Error(`HTTP ${e.status}: ${await e.text()}`);return(await e.json()).message?.content??""}async function te(t){let e=await fetch(t.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`},body:JSON.stringify({model:t.model,messages:t.messages,stream:!0})});if(!e.ok)throw new Error(`HTTP ${e.status}: ${await e.text()}`);if(!e.body)throw new Error("\uC751\uB2F5 \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");let n=new TextDecoder,s="",r="";for await(let a of e.body){s+=n.decode(a,{stream:!0});let m=s.split(`
3
- `);s=m.pop()??"";for(let P of m){let p=P.trim();if(!p)continue;let y;try{y=JSON.parse(p)}catch{throw new Error(`\uC2A4\uD2B8\uB9BC \uD30C\uC2F1 \uC2E4\uD328: ${p}`)}let w=y.message?.content??"";w&&(r+=w,t.onToken?.(w))}}s+=n.decode();let o=s.trim();if(!o)return r;let l=JSON.parse(o).message?.content??"";return l&&(r+=l,t.onToken?.(l)),r}import{mkdir as se,readFile as oe,rm as ne,writeFile as re}from"node:fs/promises";import ie from"node:os";import L from"node:path";var v=L.join(ie.homedir(),".codiq"),F=L.join(v,"config.json");async function j(){try{return await ne(F,{force:!0}),!0}catch{return!1}}async function k(){let t=process.env.OLLAMA_API_KEY?.trim();if(t)return t;let e=await ae();if(e)return e;let n=await le();return await ce(n),console.log("Ollama Cloud API Key \uC124\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."),n}async function ae(){try{let t=await oe(F,"utf8");return JSON.parse(t).ollamaApiKey?.trim()||null}catch{return null}}async function ce(t){await se(v,{recursive:!0}),await re(F,JSON.stringify({ollamaApiKey:t},null,2),"utf8")}async function le(){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Ollama Cloud API Key\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uACE0 \uC785\uB825\uC744 \uBC1B\uC744 \uC218 \uC788\uB294 \uD130\uBBF8\uB110\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");console.log("Ollama Cloud API Key\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."),console.log("\uCD5C\uCD08 1\uD68C\uB9CC \uC785\uB825\uD558\uBA74 \uC0AC\uC6A9\uC790 \uC124\uC815\uC5D0 \uC800\uC7A5\uD574 \uC7AC\uC0AC\uC6A9\uD569\uB2C8\uB2E4.");let t=await me("Ollama Cloud API Key: ");if(!t.trim())throw new Error("Ollama Cloud API Key\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.");return t.trim()}async function me(t){return await new Promise((e,n)=>{let s=process.stdin,r=process.stdout,o=s.isRaw,c="",l=()=>{s.off("data",a),s.isTTY&&s.setRawMode(o??!1),s.pause(),r.write(`
4
- `)},a=m=>{if(m===""){l(),n(new Error("\uC785\uB825\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));return}if(m==="\r"||m===`
5
- `){l(),e(c);return}if(m==="\x7F"){c.length>0&&(c=c.slice(0,-1),r.write("\b \b"));return}c+=m,r.write("*")};r.write(t),s.setEncoding("utf8"),s.isTTY&&s.setRawMode(!0),s.resume(),s.on("data",a)})}import{readdir as X,readFile as pe,stat as ue}from"node:fs/promises";import _ from"node:path";var de=new Set([".git","node_modules","dist","build",".next",".turbo","coverage",".idea",".vscode"]),fe=[".env"],$=new Set(["package.json","package-lock.json","tsconfig.json","README.md","README","pyproject.toml","requirements.txt","Cargo.toml","go.mod","Dockerfile","docker-compose.yml"]),ge=3,U=60,ye=32e3,he=8,we=1200,D=`\uC544\uB798\uB294 \uD604\uC7AC \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uC218\uC9D1\uD55C \uD504\uB85C\uC81D\uD2B8 \uCEE8\uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4.
6
- `,H=`\uC751\uB2F5 \uD615\uC2DD \uC9C0\uCE68:
7
- `;async function O(t,e,n){let s=t.filter(o=>o.role!=="system"||!o.content.startsWith(D)&&!o.content.startsWith(H));if(s.push({role:"system",content:H+xe(e)}),!Ce(e))return{history:s,projectContextUsed:!1};let r=await Ee(n);return s.push({role:"system",content:D+r}),{history:s,projectContextUsed:!0}}function T(t,e){return[{role:"system",content:t},{role:"system",content:`\uD604\uC7AC \uC0AC\uC6A9\uC790\uAC00 CLI\uB97C \uC2E4\uD589\uD55C \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB294 ${e} \uC785\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8, \uD30C\uC77C \uAD6C\uC870, \uCF54\uB4DC \uC218\uC815, \uB9AC\uD329\uD1A0\uB9C1, \uD2B9\uC815 \uD30C\uC77C \uB3D9\uC791\uC744 \uBB3B\uB294 \uACBD\uC6B0 \uC774 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uB2F5\uBCC0\uD558\uC138\uC694.`}]}function Ce(t){let e=t.toLowerCase();return[/프로젝트/,/코드베이스/,/저장소/,/리포지토리/,/구조/,/분석/,/설명/,/파악/,/파일/,/수정/,/리팩토링/,/어디/,/엔트리/,/architecture/,/project/,/codebase/,/repository/,/repo/,/file/,/refactor/,/edit/,/fix/].some(s=>s.test(e))}function xe(t){return Pe(t)?"\uC0AC\uC6A9\uC790\uAC00 README.md, \uBB38\uC11C, markdown \uD30C\uC77C, md \uBB38\uC11C \uC791\uC131\uC744 \uC694\uCCAD\uD55C \uC0C1\uD669\uC785\uB2C8\uB2E4. \uC774 \uACBD\uC6B0\uC5D0\uB294 Markdown \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD574\uB3C4 \uB429\uB2C8\uB2E4. \uB300\uC2E0 \uBB38\uC11C \uBCF8\uBB38 \uC790\uCCB4\uB97C \uBC14\uB85C \uC4F8 \uC218 \uC788\uB294 \uD615\uD0DC\uB85C \uCD9C\uB825\uD558\uC138\uC694.":"\uC0AC\uC6A9\uC790\uB294 shell\uC5D0\uC11C \uC751\uB2F5\uC744 \uC77D\uC2B5\uB2C8\uB2E4. Markdown\uC73C\uB85C \uB2F5\uBCC0\uD558\uC9C0 \uB9C8\uC138\uC694. \uCF54\uB4DC \uD39C\uC2A4(```), \uC81C\uBAA9(#), \uAD75\uAC8C(**), \uBAA9\uB85D \uB9C8\uCEE4(-, *, 1.)\uB97C \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694. \uD56D\uC0C1 plain text\uB85C\uB9CC \uB2F5\uBCC0\uD558\uACE0, \uC9E7\uC740 \uBB38\uB2E8\uC774\uB098 \uC904\uBC14\uAFC8\uB41C \uC77C\uBC18 \uD14D\uC2A4\uD2B8\uB85C \uC124\uBA85\uD558\uC138\uC694."}function Pe(t){let e=t.toLowerCase();return[/readme/,/markdown/,/\bmd\b/,/문서/,/README\.md/i,/사용법/,/guide/,/docs?/].some(s=>s.test(e))}async function Ee(t){let e=await B(t,0,[]),n=await Te(t),s=[];return s.push(`root: ${t}`),s.push(`top-level entries: ${n.slice(0,20).join(", ")||"(empty)"}`),e.keyFiles.length>0&&s.push(`key files: ${e.keyFiles.join(", ")}`),e.sourceFiles.length>0&&s.push(`source files(sample): ${e.sourceFiles.slice(0,20).join(", ")}`),e.fileSnippets.length>0&&(s.push("file snippets:"),s.push(...e.fileSnippets.map(r=>`- ${r}`))),s.join(`
8
- `)}async function B(t,e,n){let s={keyFiles:[],sourceFiles:[],fileSnippets:[]};if(e>ge||n.length>=U)return s;let r=await X(t,{withFileTypes:!0});for(let o of r){if(n.length>=U)break;if(o.isDirectory()){if(de.has(o.name))continue;let a=await B(_.join(t,o.name),e+1,n);s.keyFiles.push(...a.keyFiles),s.sourceFiles.push(...a.sourceFiles),s.fileSnippets.push(...a.fileSnippets);continue}if(!o.isFile()||fe.some(a=>o.name.startsWith(a)))continue;let c=_.join(t,o.name),l=_.relative(process.cwd(),c)||o.name;if(n.push(l),$.has(o.name)&&s.keyFiles.push(l),N(o.name)&&s.sourceFiles.push(l),s.fileSnippets.length<he&&($.has(o.name)||N(o.name))){let a=await Ae(c,l);a&&s.fileSnippets.push(a)}}return s}async function Ae(t,e){try{if((await ue(t)).size>ye)return`${e}: skipped, too large`;let r=(await pe(t,"utf8")).replace(/\s+/g," ").trim().slice(0,we);return r?`${e}: ${r}`:null}catch{return null}}function N(t){return/\.(ts|tsx|js|jsx|json|md|py|rs|go|java|kt|rb|php|toml|yaml|yml|sh)$/.test(t)}async function Te(t){try{return(await X(t)).sort()}catch{return[]}}import{useEffect as q,useRef as be,useState as C}from"react";import{Box as x,Text as f,useApp as Se,useInput as Me}from"ink";import Oe from"ink-text-input";import{jsx as h,jsxs as g}from"react/jsx-runtime";var Re="Enter \uC804\uC1A1 | Ctrl+C \uC885\uB8CC | Ctrl+L \uCD08\uAE30\uD654",z="v0.0.4";function Y({apiKey:t,options:e}){let{exit:n}=Se(),[s,r]=C([{role:"assistant",content:"\uC9C8\uBB38\uC744 \uC785\uB825\uD558\uC138\uC694."}]),[o,c]=C([...T(e.system,process.cwd())]),l=be(o),[a,m]=C(""),[P,p]=C("Ready"),[y,w]=C(!1),[J,W]=C(process.stdout.columns??80);q(()=>{l.current=o},[o]),q(()=>{let i=()=>{W(process.stdout.columns??80)};return process.stdout.on("resize",i),()=>{process.stdout.off("resize",i)}},[]),Me((i,u)=>{if(u.ctrl&&i==="c"){n();return}if(u.ctrl&&i==="l"&&!y){r([{role:"assistant",content:"\uB300\uD654 \uAE30\uB85D\uC744 \uCD08\uAE30\uD654\uD588\uC2B5\uB2C8\uB2E4."}]),c(T(e.system,process.cwd())),p("Cleared");return}});let G=async()=>{let i=a.trim();if(!i||y)return;m(""),w(!0),p("Streaming...");let u=-1;r(d=>(u=d.length+1,[...d,{role:"user",content:i},{role:"assistant",content:""}]));try{p("Inspecting project...");let{history:d,projectContextUsed:R}=await O(l.current,i,process.cwd()),I=[...d,{role:"user",content:i}];p(R?"Streaming with project context...":"Streaming...");let b=await M(i,{apiKey:t,model:e.model,baseUrl:e.baseUrl,system:e.system,stream:e.stream,onToken:E=>{r(S=>S.map((A,Z)=>Z===u?{...A,content:A.content+E}:A))}},d);r(E=>E.map((S,A)=>A===u?{...S,content:b}:S)),c([...I,{role:"assistant",content:b}]),p("Ready")}catch(d){let R=d instanceof Error?d.message:String(d);r(I=>I.map((b,E)=>E===u?{role:"assistant",content:`\uC694\uCCAD \uC2E4\uD328: ${R}`}:b)),p("Error")}finally{w(!1)}},V=Math.max(J-4,20),Q=Ie(s,V,y);return g(x,{flexDirection:"column",children:[g(x,{borderStyle:"round",borderColor:"cyan",paddingX:1,children:[h(f,{color:"cyan",children:"Codiq"}),g(f,{dimColor:!0,children:[" ",`(${z})`]})]}),h(x,{flexDirection:"column",paddingX:1,children:Q.map((i,u)=>g(f,{children:[h(f,{color:Ke(i.role),children:i.prefix}),i.text]},`${u}-${i.role}-${i.prefix}-${i.text}`))}),g(x,{borderStyle:"round",borderColor:"green",paddingX:1,children:[h(f,{color:"green",children:"> "}),h(Oe,{value:a,onChange:m,onSubmit:()=>{G()},placeholder:y?"\uC751\uB2F5 \uC0DD\uC131 \uC911...":"\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694",showCursor:!0})]}),g(x,{justifyContent:"space-between",children:[g(f,{dimColor:!0,children:["Codiq (",z,") | model=",e.model," | status=",P]}),g(f,{dimColor:!0,children:["messages=",s.length]})]}),h(x,{children:h(f,{dimColor:!0,children:Re})})]})}function Ie(t,e,n){return t.flatMap((s,r)=>{let o=`${_e(s.role)}: `,c=" ".repeat(o.length),l=s.content||(n&&r===t.length-1?"...":"");return Fe(l,Math.max(e-o.length,8)).map((m,P)=>({role:s.role,prefix:P===0?o:c,text:m}))})}function Fe(t,e){let n=t.split(`
9
- `),s=[];for(let r of n){if(r.length===0){s.push("");continue}let o=r;for(;o.length>e;)s.push(o.slice(0,e)),o=o.slice(e);s.push(o)}return s.length>0?s:[""]}function _e(t){switch(t){case"user":return"You";case"assistant":return"AI";default:return"System"}}function Ke(t){switch(t){case"user":return"yellow";case"assistant":return"green";default:return"cyan"}}var K=new Le,ke="https://ollama.com/api/chat",$e="gpt-oss:20b",Ue="\uB2F9\uC2E0\uC740 shell\uC5D0\uC11C \uB3D9\uC791\uD558\uB294 \uD504\uB85C\uC81D\uD2B8 \uBD84\uC11D\uAC00 \uBC0F \uCF54\uB529 \uB3C4\uC6B0\uBBF8\uC785\uB2C8\uB2E4. \uD604\uC7AC \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uC0AC\uC6A9\uC790\uC758 \uC9C8\uBB38\uC5D0 \uB9DE\uAC8C \uC124\uBA85, \uBD84\uC11D, \uC218\uC815 \uC81C\uC548\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4.";K.command("clear-key").description("\uC800\uC7A5\uB41C Ollama Cloud API Key\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4.").action(async()=>{if(await j()){console.log("\uC800\uC7A5\uB41C Ollama Cloud API Key\uB97C \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4.");return}console.log("\uC0AD\uC81C\uD560 \uC800\uC7A5\uB41C Ollama Cloud API Key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.")});K.name("codiq").description("A simple Ollama Cloud CLI tool").version("1.0.0").argument("[prompt...]","\uC9C8\uBB38 \uB0B4\uC6A9").option("-m, --model <model>","\uBAA8\uB378\uBA85",$e).option("-u, --base-url <url>","API URL",ke).option("-s, --system <text>","System \uD504\uB86C\uD504\uD2B8",Ue).option("--stream","\uC2A4\uD2B8\uB9AC\uBC0D \uCD9C\uB825",!0).action(async(t,e)=>{let n=t.join(" ").trim(),s=await k();if(n){let r=T(e.system,process.cwd()),{history:o}=await O(r,n,process.cwd());await M(n,{...e,apiKey:s,onToken:c=>{process.stdout.write(c)}},o),process.stdout.write(`
10
- `);return}De(s,e)});await K.parseAsync();function De(t,e){ve(je.createElement(Y,{apiKey:t,options:e}),{exitOnCtrlC:!0})}
2
+ import{Command as Be}from"commander";import{render as Xe}from"ink";import qe from"react";import"dotenv/config";async function R(s,e,r){let t=[...r,{role:"user",content:s}];return e.stream?await ue({apiKey:e.apiKey,baseUrl:e.baseUrl,model:e.model,messages:t,onToken:e.onToken}):await le({apiKey:e.apiKey,baseUrl:e.baseUrl,model:e.model,messages:t})}async function le(s){let e=await fetch(s.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.apiKey}`},body:JSON.stringify({model:s.model,messages:s.messages,stream:!1})});if(!e.ok)throw new Error(`HTTP ${e.status}: ${await e.text()}`);return(await e.json()).message?.content??""}async function ue(s){let e=await fetch(s.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.apiKey}`},body:JSON.stringify({model:s.model,messages:s.messages,stream:!0})});if(!e.ok)throw new Error(`HTTP ${e.status}: ${await e.text()}`);if(!e.body)throw new Error("\uC751\uB2F5 \uC2A4\uD2B8\uB9BC\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");let r=new TextDecoder,t="",i="";for await(let u of e.body){t+=r.decode(u,{stream:!0});let m=t.split(`
3
+ `);t=m.pop()??"";for(let I of m){let d=I.trim();if(!d)continue;let w;try{w=JSON.parse(d)}catch{throw new Error(`\uC2A4\uD2B8\uB9BC \uD30C\uC2F1 \uC2E4\uD328: ${d}`)}let x=w.message?.content??"";x&&(i+=x,s.onToken?.(x))}}t+=r.decode();let n=t.trim();if(!n)return i;let l=JSON.parse(n).message?.content??"";return l&&(i+=l,s.onToken?.(l)),i}import{mkdir as me,readFile as pe,rm as de,writeFile as fe}from"node:fs/promises";import ge from"node:os";import D from"node:path";var H=D.join(ge.homedir(),".codiq"),L=D.join(H,"config.json");async function N(){try{return await de(L,{force:!0}),!0}catch{return!1}}async function B(){let s=process.env.OLLAMA_API_KEY?.trim();if(s)return s;let e=await ye();if(e)return e;let r=await we();return await he(r),console.log("Ollama Cloud API Key \uC124\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."),r}async function ye(){try{let s=await pe(L,"utf8");return JSON.parse(s).ollamaApiKey?.trim()||null}catch{return null}}async function he(s){await me(H,{recursive:!0}),await fe(L,JSON.stringify({ollamaApiKey:s},null,2),"utf8")}async function we(){if(!process.stdin.isTTY||!process.stdout.isTTY)throw new Error("Ollama Cloud API Key\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uACE0 \uC785\uB825\uC744 \uBC1B\uC744 \uC218 \uC788\uB294 \uD130\uBBF8\uB110\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");console.log("Ollama Cloud API Key\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."),console.log("\uCD5C\uCD08 1\uD68C\uB9CC \uC785\uB825\uD558\uBA74 \uC0AC\uC6A9\uC790 \uC124\uC815\uC5D0 \uC800\uC7A5\uD574 \uC7AC\uC0AC\uC6A9\uD569\uB2C8\uB2E4.");let s=await Ce("Ollama Cloud API Key: ");if(!s.trim())throw new Error("Ollama Cloud API Key\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.");return s.trim()}async function Ce(s){return await new Promise((e,r)=>{let t=process.stdin,i=process.stdout,n=t.isRaw,c="",l=()=>{t.off("data",u),t.isTTY&&t.setRawMode(n??!1),t.pause(),i.write(`
4
+ `)},u=m=>{if(m===""){l(),r(new Error("\uC785\uB825\uC774 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));return}if(m==="\r"||m===`
5
+ `){l(),e(c);return}if(m==="\x7F"){c.length>0&&(c=c.slice(0,-1),i.write("\b \b"));return}c+=m,i.write("*")};i.write(s),t.setEncoding("utf8"),t.isTTY&&t.setRawMode(!0),t.resume(),t.on("data",u)})}import{readdir as W,readFile as xe,stat as Te}from"node:fs/promises";import v from"node:path";var Pe=new Set([".git","node_modules","dist","build",".next",".turbo","coverage",".idea",".vscode"]),Ae=[".env"],X=new Set(["package.json","package-lock.json","tsconfig.json","README.md","README","pyproject.toml","requirements.txt","Cargo.toml","go.mod","Dockerfile","docker-compose.yml"]),Ee=3,q=60,Se=32e3,be=8,Me=1200,z=`\uC544\uB798\uB294 \uD604\uC7AC \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uC218\uC9D1\uD55C \uD504\uB85C\uC81D\uD2B8 \uCEE8\uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4.
6
+ `,J=`\uC751\uB2F5 \uD615\uC2DD \uC9C0\uCE68:
7
+ `;async function O(s,e,r){let t=s.filter(n=>n.role!=="system"||!n.content.startsWith(z)&&!n.content.startsWith(J));if(t.push({role:"system",content:J+Oe(e)}),!Re(e))return{history:t,projectContextUsed:!1};let i=await _e(r);return t.push({role:"system",content:z+i}),{history:t,projectContextUsed:!0}}function E(s,e){return[{role:"system",content:s},{role:"system",content:`\uD604\uC7AC \uC0AC\uC6A9\uC790\uAC00 CLI\uB97C \uC2E4\uD589\uD55C \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB294 ${e} \uC785\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8, \uD30C\uC77C \uAD6C\uC870, \uCF54\uB4DC \uC218\uC815, \uB9AC\uD329\uD1A0\uB9C1, \uD2B9\uC815 \uD30C\uC77C \uB3D9\uC791\uC744 \uBB3B\uB294 \uACBD\uC6B0 \uC774 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uB2F5\uBCC0\uD558\uC138\uC694.`}]}function Re(s){let e=s.toLowerCase();return[/프로젝트/,/코드베이스/,/저장소/,/리포지토리/,/구조/,/분석/,/설명/,/파악/,/파일/,/수정/,/리팩토링/,/어디/,/엔트리/,/architecture/,/project/,/codebase/,/repository/,/repo/,/file/,/refactor/,/edit/,/fix/].some(t=>t.test(e))}function Oe(s){return Ie(s)?"\uC0AC\uC6A9\uC790\uAC00 README.md, \uBB38\uC11C, markdown \uD30C\uC77C, md \uBB38\uC11C \uC791\uC131\uC744 \uC694\uCCAD\uD55C \uC0C1\uD669\uC785\uB2C8\uB2E4. \uC774 \uACBD\uC6B0\uC5D0\uB294 Markdown \uD615\uC2DD\uC744 \uC0AC\uC6A9\uD574\uB3C4 \uB429\uB2C8\uB2E4. \uB300\uC2E0 \uBB38\uC11C \uBCF8\uBB38 \uC790\uCCB4\uB97C \uBC14\uB85C \uC4F8 \uC218 \uC788\uB294 \uD615\uD0DC\uB85C \uCD9C\uB825\uD558\uC138\uC694.":"\uC0AC\uC6A9\uC790\uB294 shell\uC5D0\uC11C \uC751\uB2F5\uC744 \uC77D\uC2B5\uB2C8\uB2E4. Markdown\uC73C\uB85C \uB2F5\uBCC0\uD558\uC9C0 \uB9C8\uC138\uC694. \uCF54\uB4DC \uD39C\uC2A4(```), \uC81C\uBAA9(#), \uAD75\uAC8C(**), \uBAA9\uB85D \uB9C8\uCEE4(-, *, 1.)\uB97C \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694. \uD56D\uC0C1 plain text\uB85C\uB9CC \uB2F5\uBCC0\uD558\uACE0, \uC9E7\uC740 \uBB38\uB2E8\uC774\uB098 \uC904\uBC14\uAFC8\uB41C \uC77C\uBC18 \uD14D\uC2A4\uD2B8\uB85C \uC124\uBA85\uD558\uC138\uC694."}function Ie(s){let e=s.toLowerCase();return[/readme/,/markdown/,/\bmd\b/,/문서/,/README\.md/i,/사용법/,/guide/,/docs?/].some(t=>t.test(e))}async function _e(s){let e=await G(s,0,[]),r=await Le(s),t=[];return t.push(`root: ${s}`),t.push(`top-level entries: ${r.slice(0,20).join(", ")||"(empty)"}`),e.keyFiles.length>0&&t.push(`key files: ${e.keyFiles.join(", ")}`),e.sourceFiles.length>0&&t.push(`source files(sample): ${e.sourceFiles.slice(0,20).join(", ")}`),e.fileSnippets.length>0&&(t.push("file snippets:"),t.push(...e.fileSnippets.map(i=>`- ${i}`))),t.join(`
8
+ `)}async function G(s,e,r){let t={keyFiles:[],sourceFiles:[],fileSnippets:[]};if(e>Ee||r.length>=q)return t;let i=await W(s,{withFileTypes:!0});for(let n of i){if(r.length>=q)break;if(n.isDirectory()){if(Pe.has(n.name))continue;let u=await G(v.join(s,n.name),e+1,r);t.keyFiles.push(...u.keyFiles),t.sourceFiles.push(...u.sourceFiles),t.fileSnippets.push(...u.fileSnippets);continue}if(!n.isFile()||Ae.some(u=>n.name.startsWith(u)))continue;let c=v.join(s,n.name),l=v.relative(process.cwd(),c)||n.name;if(r.push(l),X.has(n.name)&&t.keyFiles.push(l),Y(n.name)&&t.sourceFiles.push(l),t.fileSnippets.length<be&&(X.has(n.name)||Y(n.name))){let u=await Fe(c,l);u&&t.fileSnippets.push(u)}}return t}async function Fe(s,e){try{if((await Te(s)).size>Se)return`${e}: skipped, too large`;let i=(await xe(s,"utf8")).replace(/\s+/g," ").trim().slice(0,Me);return i?`${e}: ${i}`:null}catch{return null}}function Y(s){return/\.(ts|tsx|js|jsx|json|md|py|rs|go|java|kt|rb|php|toml|yaml|yml|sh)$/.test(s)}async function Le(s){try{return(await W(s)).sort()}catch{return[]}}import{useEffect as K,useRef as k,useState as y}from"react";import{Box as P,Text as p,useApp as ve,useInput as Ke}from"ink";import ke from"ink-text-input";import{jsx as f,jsxs as h}from"react/jsx-runtime";var je="Enter \uC804\uC1A1 | Ctrl+C \uC885\uB8CC | Ctrl+L \uCD08\uAE30\uD654",V="v0.0.5",$e=40,Ue=[" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557","\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551\u2584\u2584 \u2588\u2588\u2551","\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D"," \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2580\u2580\u2550\u255D"];function ee({apiKey:s,options:e}){let{exit:r}=ve(),[t,i]=y([]),[n,c]=y([...E(e.system,process.cwd())]),l=k(n),[u,m]=y(""),[I,d]=y("Ready"),[w,x]=y(!1),[te,se]=y(process.stdout.columns??80),[re,S]=y(""),[ne,C]=y(""),T=k(""),g=k(null);K(()=>{l.current=n},[n]),K(()=>{let o=()=>{se(process.stdout.columns??80)};return process.stdout.on("resize",o),()=>{process.stdout.off("resize",o)}},[]),K(()=>()=>{g.current&&clearTimeout(g.current)},[]),Ke((o,a)=>{if(a.ctrl&&o==="c"){r();return}if(a.ctrl&&o==="l"&&!w){i([]),S(""),C(""),c(E(e.system,process.cwd())),d("Cleared");return}});let oe=async()=>{let o=u.trim();if(!(!o||w)){m(""),x(!0),d("Streaming..."),S(o),C(""),T.current="",i(a=>[...a,{role:"user",content:o}]);try{d("Inspecting project...");let{history:a,projectContextUsed:U}=await O(l.current,o,process.cwd()),M=[...a,{role:"user",content:o}];d(U?"Streaming with project context...":"Streaming...");let A=await R(o,{apiKey:s,model:e.model,baseUrl:e.baseUrl,system:e.system,stream:e.stream,onToken:F=>{T.current+=F,ie()}},a);_(),C(A),i(F=>[...F,{role:"assistant",content:A}]),c([...M,{role:"assistant",content:A}]),S(""),C(""),d("Ready")}catch(a){_();let M=`\uC694\uCCAD \uC2E4\uD328: ${a instanceof Error?a.message:String(a)}`;C(M),i(A=>[...A,{role:"assistant",content:M}]),S(""),C(""),d("Error")}finally{g.current&&(clearTimeout(g.current),g.current=null),T.current="",x(!1)}}},ie=()=>{g.current||(g.current=setTimeout(()=>{g.current=null,_()},$e))},_=()=>{if(!T.current)return;let o=T.current;T.current="",C(a=>a+o)},$=Math.max(te-4,20),ae=Q(t,$),b=Q(De(re,ne,w),$),ce=t.length===0&&b.length===0;return h(P,{flexDirection:"column",children:[h(P,{flexDirection:"column",children:[Ue.map((o,a)=>f(p,{color:"cyan",children:o},`${a}-${o}`)),f(p,{dimColor:!0,children:V}),ce?f(p,{color:"green",children:"AI: \uC9C8\uBB38\uC744 \uC785\uB825\uD558\uC138\uC694."}):null,ae.map((o,a)=>h(p,{children:[f(p,{color:Z(o.role),children:o.prefix}),o.text]},`${a}-${o.role}-${o.prefix}-${o.text}`))]}),f(P,{flexDirection:"column",paddingX:1,minHeight:1,children:b.length>0?b.map((o,a)=>h(p,{children:[f(p,{color:Z(o.role),children:o.prefix}),o.text]},`${a}-${o.role}-${o.prefix}-${o.text}`)):null}),h(P,{borderStyle:"round",borderColor:"green",paddingX:1,children:[f(p,{color:"green",children:"> "}),f(ke,{value:u,onChange:m,onSubmit:()=>{oe()},placeholder:w?"\uC751\uB2F5 \uC0DD\uC131 \uC911...":"\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694",showCursor:!0})]}),h(P,{justifyContent:"space-between",children:[h(p,{dimColor:!0,children:["Codiq (",V,") | model=",e.model," | status=",I]}),h(p,{dimColor:!0,children:["messages=",t.length+b.length]})]}),f(P,{children:f(p,{dimColor:!0,children:je})})]})}function De(s,e,r){let t=[];return(e||r)&&t.push({role:"assistant",content:e||"..."}),t}function Q(s,e){return s.flatMap(r=>{let t=`${Ne(r.role)}: `,i=" ".repeat(t.length);return He(r.content,Math.max(e-t.length,8)).map((c,l)=>({role:r.role,prefix:l===0?t:i,text:c}))})}function He(s,e){let r=s.split(`
9
+ `),t=[];for(let i of r){if(i.length===0){t.push("");continue}let n=i;for(;n.length>e;)t.push(n.slice(0,e)),n=n.slice(e);t.push(n)}return t.length>0?t:[""]}function Ne(s){switch(s){case"user":return"You";case"assistant":return"AI";default:return"System"}}function Z(s){switch(s){case"user":return"yellow";case"assistant":return"green";default:return"cyan"}}var j=new Be,ze="https://ollama.com/api/chat",Je="gpt-oss:20b",Ye="\uB2F9\uC2E0\uC740 shell\uC5D0\uC11C \uB3D9\uC791\uD558\uB294 \uD504\uB85C\uC81D\uD2B8 \uBD84\uC11D\uAC00 \uBC0F \uCF54\uB529 \uB3C4\uC6B0\uBBF8\uC785\uB2C8\uB2E4. \uD604\uC7AC \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uC0AC\uC6A9\uC790\uC758 \uC9C8\uBB38\uC5D0 \uB9DE\uAC8C \uC124\uBA85, \uBD84\uC11D, \uC218\uC815 \uC81C\uC548\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4.";j.command("clear-key").description("\uC800\uC7A5\uB41C Ollama Cloud API Key\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4.").action(async()=>{if(await N()){console.log("\uC800\uC7A5\uB41C Ollama Cloud API Key\uB97C \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4.");return}console.log("\uC0AD\uC81C\uD560 \uC800\uC7A5\uB41C Ollama Cloud API Key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.")});j.name("codiq").description("A simple Ollama Cloud CLI tool").version("1.0.0").argument("[prompt...]","\uC9C8\uBB38 \uB0B4\uC6A9").option("-m, --model <model>","\uBAA8\uB378\uBA85",Je).option("-u, --base-url <url>","API URL",ze).option("-s, --system <text>","System \uD504\uB86C\uD504\uD2B8",Ye).option("--stream","\uC2A4\uD2B8\uB9AC\uBC0D \uCD9C\uB825",!0).action(async(s,e)=>{let r=s.join(" ").trim(),t=await B();if(r){let i=E(e.system,process.cwd()),{history:n}=await O(i,r,process.cwd());await R(r,{...e,apiKey:t,onToken:c=>{process.stdout.write(c)}},n),process.stdout.write(`
10
+ `);return}We(t,e)});await j.parseAsync();function We(s,e){Xe(qe.createElement(ee,{apiKey:s,options:e}),{exitOnCtrlC:!0})}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullkkk/codiq",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {