@yhotamos/enja-cli 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,40 +1,90 @@
1
1
  #!/usr/bin/env node
2
- import*as d from'fs';import {readFileSync,promises}from'fs';import {Command}from'commander';import ie from'ora';import*as y from'path';import*as K from'os';import J from'openai';import {GoogleGenAI,ApiError}from'@google/genai';import {randomUUID,createHash}from'crypto';import p from'kleur';var I=class{apiUrl;apiKey;constructor(e,r){this.apiUrl=e,this.apiKey=r;}getModel(){return null}async translate(e,r,i){let o={"Content-Type":"application/json"};this.apiKey&&(o.Authorization=`Bearer ${this.apiKey}`);let a=await fetch(this.apiUrl,{method:"POST",headers:o,body:JSON.stringify({text:e,sourceLang:r,targetLang:i})});if(!a.ok)throw new Error(`HTTP ${a.status} ${a.statusText}`);let l=await a.json();if(l.code!==200||!l.translatedText)throw new Error(`${l.error||"\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F"}`);return {text:l.translatedText,detectedSourceLang:l.detectedSourceLang}}};function P(){if(process.platform==="win32"){let r=process.env.APPDATA||y.join(K.homedir(),"AppData","Roaming");if(!r)throw new Error("APPDATA \u74B0\u5883\u5909\u6570\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u304A\u3089\u305A\uFF0C\u4EE3\u66FF\u30D1\u30B9\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return y.join(r,"enja-cli")}let e=K.homedir();return y.join(e,".config","enja-cli")}function F(){return y.join(P(),"history.json")}function G(){return y.join(P(),"config.json")}var h={gas:{provider:"gas",endpoint:"https://script.google.com/macros/s/AKfycbxOSbKD0aBTaQqIzHv00BMzp6WwrtWHBU3gJY0vhB2HblgUO-cgesfT1l-rrfttnWZzew/exec"},openai:{provider:"openai",model:"gpt-4o-mini"},gemini:{provider:"gemini",model:"gemini-2.5-flash-lite"},custom:{provider:"custom"}},N={version:"1.1",activeProfile:"default",profiles:{default:{...h.gas}}},m=class{filePath;constructor(){this.filePath=G();}ensureConfigDir(){let e=P();d.existsSync(e)||d.mkdirSync(e,{recursive:true});}async readAppConfig(){try{if(!d.existsSync(this.filePath))return {...N};let e=d.readFileSync(this.filePath,"utf-8");return JSON.parse(e)}catch{return console.warn("\u8A2D\u5B9A\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF0E\u898F\u5B9A\u5024\u3092\u4F7F\u7528\u3057\u307E\u3059"),{...N}}}async writeAppConfig(e){try{this.ensureConfigDir(),d.writeFileSync(this.filePath,JSON.stringify(e,null,2),"utf-8");}catch{throw new Error("\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}}async readConfig(){let e=await this.readAppConfig();return e.profiles[e.activeProfile]||{...h.gas}}async writeConfig(e){let r=await this.readAppConfig();r.profiles[r.activeProfile]=e,await this.writeAppConfig(r);}async get(){return await this.readConfig()}async set(e,r){let i=await this.readConfig();switch(e){case "endpoint":i.endpoint=r;break;case "api-key":i.apiKey=r;break;case "provider":if(!["gas","custom","openai","gemini"].includes(r))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${r}): 'gas', 'custom', 'openai', 'gemini' \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);i.provider=r;break;case "model":i.model=r;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${e})`)}await this.writeConfig(i);}async unset(e){let r=await this.readConfig(),i=r.provider||"gas",o=h[i];switch(e){case "endpoint":r.endpoint=o.endpoint;break;case "api-key":r.apiKey=o.apiKey;break;case "provider":r.provider=o.provider;break;case "model":r.model=o.model;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${e})`)}await this.writeConfig(r);}async reset(){await this.writeConfig({...h.gas});}async getActiveProfileName(){return (await this.readAppConfig()).activeProfile}async getProfile(e){let i=(await this.readAppConfig()).profiles[e];if(!i)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);return i}async listProfiles(){let e=await this.readAppConfig();return Object.keys(e.profiles)}async createProfile(e,r){if(["ls","list","use","rm","delete","add","provider","endpoint","api-key","model"].includes(e.toLowerCase()))throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D '${e}' \u306F\u4E88\u7D04\u8A9E\u306E\u305F\u3081\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`);if(!e.match(/^[a-zA-Z0-9_-]+$/))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D (${e}): \u82F1\u6570\u5B57\uFF0C\u30CF\u30A4\u30D5\u30F3\uFF0C\u30A2\u30F3\u30C0\u30FC\u30B9\u30B3\u30A2\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059`);if(r?.provider&&!["gas","custom","openai","gemini"].includes(r.provider))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC '${r.provider}': gas, custom, openai, gemini \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);let o=await this.readAppConfig();if(o.profiles[e])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);let a=r?.provider||"gas",n={...h[a],...r};o.profiles[e]=n,await this.writeAppConfig(o);}async deleteProfile(e){if(e==="default")throw new Error("'default' \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306F\u524A\u9664\u3067\u304D\u307E\u305B\u3093");let r=await this.readAppConfig();if(!r.profiles[e])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);delete r.profiles[e],r.activeProfile===e&&(r.activeProfile="default"),await this.writeAppConfig(r);}async useProfile(e){let r=await this.readAppConfig();if(!r.profiles[e]){let i=Object.keys(r.profiles).join(", ");throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
3
- \u5229\u7528\u53EF\u80FD\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${i}`)}r.activeProfile=e,await this.writeAppConfig(r);}async setProfileConfig(e,r,i){let o=await this.readAppConfig();if(!o.profiles[e])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF0E'enja config add ${e}' \u3067\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044`);let a=o.profiles[e];switch(r){case "endpoint":a.endpoint=i;break;case "api-key":a.apiKey=i;break;case "provider":if(!["gas","custom","openai","gemini"].includes(i))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${i}): 'gas', 'custom', 'openai', 'gemini' \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);a.provider=i;break;case "model":a.model=i;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${r})`)}await this.writeAppConfig(o);}async unsetProfileConfig(e,r){let i=await this.readAppConfig();if(!i.profiles[e])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);let o=i.profiles[e],a=o.provider||"gas",l=h[a];switch(r){case "provider":o.provider=l.provider;break;case "endpoint":o.endpoint=l.endpoint;break;case "api-key":o.apiKey=l.apiKey;break;case "model":o.model=l.model;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${r})`)}await this.writeAppConfig(i);}async resetProfile(e){let r=await this.readAppConfig();if(!r.profiles[e])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);let i=h.gas;r.profiles[e]={...i},await this.writeAppConfig(r);}};async function U(t){let e=new m,r;if(t?.profile)try{r=await e.getProfile(t.profile);}catch{let s=await e.listProfiles();throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t.profile}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
4
- \u5229\u7528\u53EF\u80FD\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${s.join(", ")}`)}else r=await e.get();let i=t?.provider||r.provider||"gas",o=t?.endpoint||r.endpoint,a=t?.apiKey||r.apiKey,l=t?.model||r.model;return {endpoint:o,provider:i,apiKey:a,model:l}}var k=class{client;model;constructor(e,r="gpt-4o-mini"){this.client=new J({apiKey:e}),this.model=r;}getModel(){return this.model}async translate(e,r,i){try{let o=this.mapLanguageCode(r),a=this.mapLanguageCode(i),l=`You are a professional translator. Translate the following text from ${o} to ${a}. Only return the translated text without any additional explanation or comments.`,s=(await this.client.chat.completions.create({model:this.model,messages:[{role:"system",content:l},{role:"user",content:e}],temperature:.3})).choices[0]?.message?.content;if(!s)throw new Error("\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return {text:s.trim(),detectedSourceLang:r}}catch(o){throw o instanceof J.APIError?new Error(`OpenAI\u7FFB\u8A33API\u30A8\u30E9\u30FC: ${o.message}`):o instanceof Error?new Error(`OpenAI\u7FFB\u8A33\u30A8\u30E9\u30FC: ${o.message}`):o}}mapLanguageCode(e){return {en:"English",ja:"Japanese"}[e.toLowerCase()]||e}};var j=class{client;model;constructor(e,r="gemini-2.5-flash-lite"){this.client=new GoogleGenAI({apiKey:e}),this.model=r;}getModel(){return this.model}async translate(e,r,i){try{let o=this.mapLanguageCode(r),a=this.mapLanguageCode(i),l=`You are a professional translator. Translate the following text from ${o} to ${a}. Only return the translated text without any additional explanation or comments.`,s=(await this.client.models.generateContent({model:this.model,contents:e,config:{systemInstruction:l}})).text;if(!s)throw new Error("\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return {text:s.trim(),detectedSourceLang:r}}catch(o){if(o instanceof ApiError){let a=JSON.parse(o.message).error.message;throw new Error(`Gemini\u7FFB\u8A33API\u30A8\u30E9\u30FC: ${a}`)}else if(o instanceof Error)throw new Error(`Gemini\u7FFB\u8A33\u30A8\u30E9\u30FC: ${o.message}`);throw o}}mapLanguageCode(e){return {en:"English",ja:"Japanese"}[e.toLowerCase()]||e}};async function _(t){let e=new m,r=await U(t),i;switch(t?.profile?i=t.profile:i=await e.getActiveProfileName(),r.provider){case "gas":case "custom":{let{endpoint:o,apiKey:a}=r;if(!o)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8URL\u304C\u5FC5\u8981\u3067\u3059");return {translator:new I(o,a),config:r,activeProfile:i}}case "openai":{let{apiKey:o,model:a}=r;if(!o)throw new Error("OpenAI\u3092\u4F7F\u7528\u3059\u308B\u306B\u306FAPI\u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new k(o,a),config:r,activeProfile:i}}case "gemini":{let{apiKey:o,model:a}=r;if(!o)throw new Error("Gemini\u3092\u4F7F\u7528\u3059\u308B\u306B\u306FAPI\u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new j(o,a),config:r,activeProfile:i}}default:throw new Error(`\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${r.provider})`)}}var Y=100,$=class{filePath;constructor(){this.filePath=F();}ensureConfigDir(){let e=P();d.existsSync(e)||d.mkdirSync(e,{recursive:true});}async readHistory(){try{let e=await promises.readFile(this.filePath,"utf-8");return JSON.parse(e)}catch(e){return e&&e.code==="ENOENT"?[]:(console.warn("\u5C65\u6B74\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF0E\u7A7A\u914D\u5217\u3092\u8FD4\u3057\u307E\u3059"),[])}}async writeHistory(e){try{this.ensureConfigDir();let r=`${this.filePath}.tmp`,i=JSON.stringify(e,null,2);await promises.writeFile(r,i,"utf-8"),await promises.rename(r,this.filePath);}catch{throw new Error("\u5C65\u6B74\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}}async add(e){let r=await this.readHistory(),i={...e,id:randomUUID(),timestamp:new Date().toISOString()};r.unshift(i),r.length>Y&&r.splice(Y),await this.writeHistory(r);}async getAll(){return await this.readHistory()}async getRecent(e){return (await this.readHistory()).slice(0,e)}async deleteById(e){let r=await this.readHistory(),i=r.filter(o=>o.id!==e);return i.length===r.length?false:(await this.writeHistory(i),true)}async clear(){await this.writeHistory([]);}async findById(e){return (await this.readHistory()).find(i=>i.id===e)||null}async findByShortId(e){return (await this.readHistory()).filter(i=>i.id.startsWith(e))}async findByHash(e,r,i){return (await this.readHistory()).find(a=>a.sourceHash===e&&a.sourceLang===r&&a.targetLang===i)||null}};function W(t){return createHash("sha256").update(t).digest("hex")}async function z(t,e){try{if(!t&&!e.file&&!process.stdin.isTTY){let r=await se();await R(r,e,"stdin");return}if(e.file){if(!d.existsSync(e.file))throw new Error(`\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${e.file})`);let r=d.readFileSync(e.file,"utf-8");await R(r,e,"file");return}if(t){await R(t,e,"arg");return}console.error("error: \u5165\u529B\u304C\u63D0\u4F9B\u3055\u308C\u3066\u3044\u307E\u305B\u3093"),console.error("\u4F7F\u3044\u65B9: enja <\u30C6\u30AD\u30B9\u30C8> \u307E\u305F\u306F enja -f <\u30D5\u30A1\u30A4\u30EB> \u307E\u305F\u306F \u30D1\u30A4\u30D7\u5165\u529B"),process.exit(1);}catch(r){console.error(`error: ${ne(r)}`),process.exit(1);}}async function R(t,e,r){if(!t||t.trim().length===0)throw new Error("\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u3067\u3059");let i=t;if(e.stripHtml&&(i=ae(t),!i||i.trim().length===0))throw new Error("HTML\u30BF\u30B0\u3092\u9664\u53BB\u3057\u305F\u7D50\u679C\uFF0C\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u306B\u306A\u308A\u307E\u3057\u305F");let{translator:o,config:a,activeProfile:l}=await _(e),n=new $,s=e.flip?"ja":"en",c=e.flip?"en":"ja",g=W(i),A=await n.findByHash(g,s,c);if(A&&e.cache!==false){console.log(`${p.green("\u2714")} \u30AD\u30E3\u30C3\u30B7\u30E5\u304B\u3089\u7FFB\u8A33\u7D50\u679C\u3092\u53D6\u5F97\u3057\u307E\u3057\u305F`);let C=A.translatedText;if(e.output)try{d.writeFileSync(e.output,C,"utf-8"),console.log(`${p.green("\u2714")} ${e.output} \u306B\u7FFB\u8A33\u7D50\u679C\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F`);}catch{throw new Error(`\u30D5\u30A1\u30A4\u30EB\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${e.output})`)}else console.log(C);return}let u=`(${s} \u2192 ${c})`,v=o.getModel()||a.model,H=l||"unknown",L=`[${H} | ${a.provider}${v?` | ${v}`:""}]`,B=ie(`\u7FFB\u8A33\u4E2D... ${u} ${L}`).start();try{let x=(await o.translate(i,s,c)).text;if(B.succeed(`\u7FFB\u8A33\u5B8C\u4E86 ${u} ${L}`),await n.add({sourceText:i,translatedText:x,sourceLang:s,targetLang:c,textLength:i.length,sourceHash:g,profile:H,provider:a.provider,model:v,options:{stripHtml:e.stripHtml,file:e.file,inputMethod:r}}),e.output)try{d.writeFileSync(e.output,x,"utf-8"),console.log(`${p.green("\u2714")} ${e.output} \u306B\u7FFB\u8A33\u7D50\u679C\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F`);}catch{throw new Error(`\u30D5\u30A1\u30A4\u30EB\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${e.output})`)}else console.log(x);}catch(C){throw B.fail(`\u7FFB\u8A33\u5931\u6557 ${u} ${L}`),C}}function ne(t){if(t instanceof Error)return t.message;try{return String(t)}catch{return "Unknown error"}}function se(){return new Promise((t,e)=>{let r="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",i=>{r+=i;}),process.stdin.on("end",()=>{t(r);}),process.stdin.on("error",i=>{e(i);});})}function ae(t){return t.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,"").replace(/<[^>]+>/g,"").replace(/&nbsp;/g," ").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/\n\s*\n/g,`
5
- `).trim()}function E(t,e=false){return t.length===0?"\u5C65\u6B74\u306F\u3042\u308A\u307E\u305B\u3093":e?pe(t):le(t)}function le(t){let e=[`\u5168 ${t.length} \u4EF6\u306E\u5C65\u6B74
6
- `];return t.forEach((r,i)=>{let o=Z(r.timestamp),a=ce(r),l=q(r.sourceText,20),n=q(r.translatedText||"",20),s=[p.cyan(`[${i+1}]`),r.id.substring(0,8),o,a||null].filter(Boolean).join(" | ");e.push(s),e.push(` ${r.sourceLang} \u2192 ${r.targetLang} | ${l} \u2192 ${n}`),e.push("");}),e.join(`
7
- `)}function pe(t){let e=[`\u5168 ${t.length} \u4EF6\u306E\u5C65\u6B74\u306E\u8A73\u7D30
8
- `];return t.forEach((r,i)=>{i>0&&e.push("\u2500".repeat(60));let o=14;if(e.push(`${p.cyan("ID:".padEnd(o))} ${r.id}`),e.push(`${p.cyan("Date:".padEnd(o))} ${Z(r.timestamp)}`),e.push(`${p.cyan("Direction:".padEnd(o))} ${r.sourceLang} \u2192 ${r.targetLang}`),e.push(`${p.cyan("InputLength:".padEnd(o))} ${r.textLength} characters`),e.push(`${p.cyan("OutputLength:".padEnd(o))} ${r.translatedText.length} characters`),r.profile&&e.push(`${p.cyan("Profile:".padEnd(o))} ${r.profile}`),r.provider&&e.push(`${p.cyan("Provider:".padEnd(o))} ${r.provider}`),r.model&&e.push(`${p.cyan("Model:".padEnd(o))} ${r.model}`),r.options){let a=[r.options.inputMethod&&`input=${r.options.inputMethod}`,r.options.stripHtml&&"stripHtml=true",r.options.file&&`file=${r.options.file}`].filter(Boolean).join(", ");a&&e.push(`${p.cyan("Options:".padEnd(o))} ${a}`);}e.push("",`${p.cyan("Input:")}`,r.sourceText),e.push("",`${p.cyan("Output:")}`,r.translatedText||"","");}),e.join(`
9
- `)}function Z(t){return new Date(t).toLocaleString("ja-JP")}function q(t,e){let r=t.replace(/[\r\n]+/g," ");return r.length>e?r.substring(0,e)+"...":r}function ce(t){return [t.profile,t.provider,t.model].filter(e=>!!e).map(e=>p.magenta(e)).join(p.dim("\u30FB"))}async function Q(t,e){try{let r=new $;if(t){let l=t.trim();if(!l)throw new Error("\u7A7A\u306EID\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F");if(l.length>=36){let c=await r.findById(l);if(!c)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t})`);console.log(E([c],e.detail));return}if(l.length<8)throw new Error(`\u77ED\u7E2EID\u306F\u5C11\u306A\u304F\u3068\u30828\u6587\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 (${l.length})`);let n=await r.findByShortId(l);if(n.length===0)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t})`);let s=E(n,e.detail);console.log(s);return}if(e.delete){let l=e.delete.trim();if(!l)throw new Error("\u7A7A\u306EID\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F");if(l.length>=36){if(await r.deleteById(l))console.log(`${p.green("\u2714")} \u5C65\u6B74ID ${l} \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);else throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${l})`);return}if(l.length<8)throw new Error(`\u77ED\u7E2EID\u3067\u524A\u9664\u3059\u308B\u5834\u5408\u306F\u5C11\u306A\u304F\u3068\u30828\u6587\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 (${l.length})`);let n=await r.findByShortId(l);if(n.length===0)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${l})`);if(n.length>1){console.error("error: \u6307\u5B9A\u3055\u308C\u305F\u77ED\u7E2EID\u306F\u8907\u6570\u306E\u5C65\u6B74\u306B\u4E00\u81F4\u3057\u307E\u3057\u305F\uFF0E\u5B8C\u5168\u306AID\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF0E");let g=E(n,!1);console.error(g),process.exit(1);}let s=n[0].id;if(await r.deleteById(s))console.log(`${p.green("\u2714")} \u5C65\u6B74ID ${s} \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);else throw new Error(`\u524A\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${s})`);return}if(e.clear){await r.clear(),console.log(`${p.green("\u2714")} \u5C65\u6B74\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3057\u305F`);return}let i=Number(e.number)||10,o=await r.getRecent(i),a=E(o,e.detail);console.log(a);}catch(r){console.error(r instanceof Error?`error: ${r.message}`:r),process.exit(1);}}async function X(t,e,r,i){let o=new m,a=i?.opts()||{},n={...i?.parent?.opts()||{},...a};try{if(t==="ls"||t==="list"){let s=await o.listProfiles(),c=await o.getActiveProfileName();console.log(p.bold("Profiles:"));for(let g of s){let A=g===c,u=await o.getProfile(g),v=A?p.green("*"):" ",H=u.model?` - ${u.model}`:"";console.log(` ${v} ${g} (${u.provider})${H}`);}return}if(t==="use"&&e){await o.useProfile(e),console.log(`${p.green("\u2714")} \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092 '${e}' \u306B\u8A2D\u5B9A\u3057\u307E\u3057\u305F`);return}if((t==="rm"||t==="delete")&&e){await o.deleteProfile(e),console.log(`${p.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);return}if(t==="add"&&e){let s={};n?.provider&&(s.provider=n.provider),n?.endpoint&&(s.endpoint=n.endpoint),n?.apiKey&&(s.apiKey=n.apiKey),n?.model&&(s.model=n.model),await o.createProfile(e,s),console.log(`${p.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u3092\u4F5C\u6210\u3057\u307E\u3057\u305F`);return}if(!t){(n?.provider||n?.endpoint||n?.apiKey||n?.model||n?.reset||n?.unset)&&(console.error("error: \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"),console.log(`
10
- \u4F7F\u7528\u4F8B:`),console.log(" enja config work --provider openai \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4"),console.log(" enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210"),process.exit(1));let s=await o.getActiveProfileName(),c=await o.get();console.log(`${p.bold("Active Profile:")} ${s}`),console.log(`${p.blue("provider:")} ${c.provider}`),console.log(`${p.blue("endpoint:")} ${c.endpoint||"(not set)"}`),console.log(`${p.blue("apiKey:")} ${c.apiKey?V(c.apiKey):"(not set)"}`),console.log(`${p.blue("model:")} ${c.model||"(not set)"}`);return}if(t&&!e&&(n?.provider||n?.endpoint||n?.apiKey||n?.model)){let s=!1;n.provider&&(await o.setProfileConfig(t,"provider",n.provider),s=!0),n.endpoint&&(await o.setProfileConfig(t,"endpoint",n.endpoint),s=!0),n.apiKey&&(await o.setProfileConfig(t,"api-key",n.apiKey),s=!0),n.model&&(await o.setProfileConfig(t,"model",n.model),s=!0),s&&console.log(`${p.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u306E\u8A2D\u5B9A\u3092\u66F4\u65B0\u3057\u307E\u3057\u305F`);return}if(t&&!e&&!n?.reset&&!n?.unset&&!n?.provider&&!n?.endpoint&&!n?.apiKey&&!n?.model){let s=await o.getProfile(t);console.log(`${p.bold("Profile:")} ${t}`),console.log(`${p.blue("provider:")} ${s.provider}`),console.log(`${p.blue("endpoint:")} ${s.endpoint||"(not set)"}`),console.log(`${p.blue("apiKey:")} ${s.apiKey?V(s.apiKey):"(not set)"}`),console.log(`${p.blue("model:")} ${s.model||"(not set)"}`);return}if(t&&n?.reset){await o.resetProfile(t),console.log(`${p.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F`);return}if(t&&n?.unset){await o.unsetProfileConfig(t,n.unset),console.log(`${p.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u306E ${n.unset} \u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F`);return}console.error("error: \u7121\u52B9\u306A\u30B3\u30DE\u30F3\u30C9\u5F62\u5F0F\u3067\u3059"),console.log(`
11
- \u4F7F\u7528\u4F8B:`),console.log(" enja config \u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u8868\u793A"),console.log(" enja config ls \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4E00\u89A7"),console.log(" enja config work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u8868\u793A"),console.log(" enja config use work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u5207\u308A\u66FF\u3048"),console.log(" enja config work --provider openai \u8A2D\u5B9A\u5909\u66F4"),console.log(" enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4F5C\u6210"),process.exit(1);}catch(s){console.error(s instanceof Error?`error: ${s.message}`:s),process.exit(1);}}function V(t){if(t.length<=8)return "*".repeat(t.length);let e=4,r=t.slice(0,e),i=t.slice(-e),o="*".repeat(t.length-e*2);return `${r}${o}${i}`}var M=JSON.parse(readFileSync(new URL("../package.json",import.meta.url),"utf-8")),T=new Command;T.name("enja").usage("[arguments] [options]").description(`Description: ${M.description}`).version(M.version,"-v, --version","output the current version");T.argument("[text]","\u30C6\u30AD\u30B9\u30C8\u3092\u7FFB\u8A33\u3059\u308B").option("-f, --file <path>","\u30D5\u30A1\u30A4\u30EB\u3092\u7FFB\u8A33\u3059\u308B").option("-o, --output <path>","\u30D5\u30A1\u30A4\u30EB\u306B\u51FA\u529B\u3059\u308B (\u30C7\u30D5\u30A9\u30EB\u30C8: \u6A19\u6E96\u51FA\u529B)").option("-s, --strip-html","HTML\u30BF\u30B0\u3092\u9664\u53BB\u3057\u3066\u304B\u3089\u7FFB\u8A33\u3059\u308B").option("-N, --no-cache","\u30AD\u30E3\u30C3\u30B7\u30E5\u3092\u4F7F\u7528\u305B\u305A\u306B\u518D\u7FFB\u8A33\u3059\u308B").option("-F, --flip","\u7FFB\u8A33\u65B9\u5411\u3092\u9006\u306B\u3059\u308B (default: \u82F1\u8A9E\u2192\u65E5\u672C\u8A9E)").option("-p, --profile <name>","\u4F7F\u7528\u3059\u308B\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A").option("--endpoint <url>","\u30AB\u30B9\u30BF\u30E0\u7FFB\u8A33\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A").option("--api-key <key>","API \u30AD\u30FC\u3092\u6307\u5B9A").option("--provider <name>","\u7FFB\u8A33\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3092\u6307\u5B9A (gas, custom, openai, gemini)").option("--model <name>","\u4F7F\u7528\u3059\u308B\u30E2\u30C7\u30EB\u540D\u3092\u6307\u5B9A (\u4F8B: gpt-4o-mini, gemini-2.5-flash-lite)").showHelpAfterError().addHelpText("after",`
2
+ import*as w from'fs';import {readFileSync,promises}from'fs';import {Command}from'commander';import yt from'ora';import*as L from'path';import*as M from'os';import J from'openai';import {GoogleGenAI,ApiError}from'@google/genai';import {randomUUID,createHash}from'crypto';import c from'kleur';var C=class o{static DEFAULT_ENDPOINT="https://script.google.com/macros/s/AKfycbxOSbKD0aBTaQqIzHv00BMzp6WwrtWHBU3gJY0vhB2HblgUO-cgesfT1l-rrfttnWZzew/exec";static ENDPOINT_URL_PATTERN=/^https:\/\/script\.google\.com\/macros\/s\/[a-zA-Z0-9_-]+\/(exec|dev)(\?.*)?$/;apiUrl;apiKey;constructor(t=o.DEFAULT_ENDPOINT,e){if(!o.ENDPOINT_URL_PATTERN.test(t))throw new Error("\u7121\u52B9\u306A GAS \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u3067\u3059");this.apiUrl=t,this.apiKey=e;}getModel(){return null}async translate(t,e,r){let i={"Content-Type":"application/json"};this.apiKey&&(i.Authorization=`Bearer ${this.apiKey}`);let a=await fetch(this.apiUrl,{method:"POST",headers:i,body:JSON.stringify({text:t,sourceLang:e,targetLang:r})});if(!a.ok)throw new Error(`HTTP ${a.status} ${a.statusText}`);let n=await a.json();if(n.code!==200||!n.translatedText)throw new Error(`${n.error||"\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F"}`);return {text:n.translatedText,detectedSourceLang:n.detectedSourceLang}}};function A(){if(process.platform==="win32"){let e=process.env.APPDATA||L.join(M.homedir(),"AppData","Roaming");if(!e)throw new Error("APPDATA \u74B0\u5883\u5909\u6570\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u304A\u3089\u305A\uFF0C\u4EE3\u66FF\u30D1\u30B9\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return L.join(e,"enja-cli")}let t=M.homedir();return L.join(t,".config","enja-cli")}function B(){return L.join(A(),"history.json")}function G(){return L.join(A(),"config.json")}var E=class o{static DEFAULT_ENDPOINT="http://localhost:1234/api/v1/chat";baseUrl;model;apiKey;constructor(t=o.DEFAULT_ENDPOINT,e,r){this.baseUrl=t,this.model=e,this.apiKey=r;}getModel(){return this.model||null}async translate(t,e,r){let i=`You are a professional translator. Translate the following text from ${e} to ${r}. Only return the translated text without any additional explanation.`,a=this.resolveEndpoint(this.baseUrl),n={"Content-Type":"application/json",Accept:"application/json",...this.apiKey?{Authorization:`Bearer ${this.apiKey}`}:{}},l=JSON.stringify({model:this.model,system_prompt:i,input:t}),s=await fetch(a.toString(),{method:"POST",headers:n,body:l}),p=await s.text(),d=this.parseJsonSafe(p,s);if(!s.ok){if(d?.error){if(typeof d.error=="string")throw new Error(`LMStudio: ${d.error}`);let{message:g,code:m}=d.error;if(m==="model_not_found")throw new Error(`LMStudio: \u30E2\u30C7\u30EB "${this.model}" \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u30E2\u30C7\u30EB\u540D\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);if(m==="invalid_api_key")throw new Error("LMStudio: API\u30AD\u30FC\u304C\u7121\u52B9\u3067\u3059\u3002API \u30AD\u30FC\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002");let T=g||"LMStudio: \u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F";throw new Error(T)}throw new Error(`LMStudio: HTTP ${s.status} ${s.statusText}`)}let f=this.extractTranslatedFromOutput(d);if(f)return {text:f.trim(),detectedSourceLang:e};throw d?.error?new Error(`LMStudio: ${d.error||"\u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"}`):new Error("LMStudio: \u51FA\u529B\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093")}resolveEndpoint(t){let e;try{e=new URL(t);}catch{throw new Error("LMStudio: \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306E URL \u304C\u4E0D\u6B63\u3067\u3059\uFF08\u4F8B: http://localhost:1234/\uFF09")}let r=e.pathname.replace(/\/+$/,"");if(r===""||r==="/")e.pathname="/api/v1/chat";else if(r!=="/api/v1/chat")throw new Error('LMStudio: \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u306F "/api/v1/chat" \u3092\u542B\u3081\u308B\u304B\uFF0C\u30D1\u30B9\u3092\u7A7A\u306B\u3057\u3066\u304F\u3060\u3055\u3044');return e}parseJsonSafe(t,e){if(t)try{return JSON.parse(t)}catch{if(!e.ok){let r=t?`${t.slice(0,200)}...`:"";throw new Error(`LMStudio: \u975EJSON\u30EC\u30B9\u30DD\u30F3\u30B9 (HTTP ${e.status} ${e.statusText}) ${r}`)}throw new Error("LMStudio: \u30EC\u30B9\u30DD\u30F3\u30B9\u306E JSON \u89E3\u6790\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}}extractTranslatedFromOutput(t){if(!t||!Array.isArray(t.output)||t.output.length===0)return null;for(let e of t.output)if(e&&typeof e=="object"&&e.type==="message"){let r=this.extractFromItem(e);if(r)return r}for(let e of t.output){let r=this.extractFromItem(e);if(r)return r}return null}extractFromItem(t){if(!t&&t!=="")return null;if(typeof t=="string")return t;if(Array.isArray(t)){for(let e of t){let r=this.extractFromItem(e);if(r)return r}return null}if(typeof t=="object"){if(typeof t=="object"&&typeof t.text=="string")return t.text;if(typeof t=="object"&&typeof t.response=="string")return t.response;if(typeof t.content=="string")return t.content;if(t.content&&typeof t.content=="object"){let e=t.content;if(typeof e.text=="string")return e.text;if(typeof e.content=="string")return e.content;let r=this.extractFromItem(e);if(r)return r}if(Array.isArray(t.content))for(let e of t.content){let r=this.extractFromItem(e);if(r)return r}if(Array.isArray(t.output)){let e=this.extractTranslatedFromOutput({output:t.output});if(e)return e}}return null}};var x=class o{static DEFAULT_MODEL="gpt-4o-mini";client;model;constructor(t,e=o.DEFAULT_MODEL){this.client=new J({apiKey:t}),this.model=e;}getModel(){return this.model}async translate(t,e,r){try{let i=this.mapLanguageCode(e),a=this.mapLanguageCode(r),n=`You are a professional translator. Translate the following text from ${i} to ${a}. Only return the translated text without any additional explanation or comments.`,s=(await this.client.chat.completions.create({model:this.model,messages:[{role:"system",content:n},{role:"user",content:t}],temperature:.3})).choices[0]?.message?.content;if(!s)throw new Error("\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return {text:s.trim(),detectedSourceLang:e}}catch(i){throw i instanceof J.APIError?new Error(`OpenAI\u7FFB\u8A33API\u30A8\u30E9\u30FC: ${i.message}`):i instanceof Error?new Error(`OpenAI\u7FFB\u8A33\u30A8\u30E9\u30FC: ${i.message}`):i}}mapLanguageCode(t){return {en:"English",ja:"Japanese"}[t.toLowerCase()]||t}};var I=class o{static DEFAULT_MODEL="gemini-2.5-flash-lite";client;model;constructor(t,e=o.DEFAULT_MODEL){this.client=new GoogleGenAI({apiKey:t}),this.model=e;}getModel(){return this.model}async translate(t,e,r){try{let i=this.mapLanguageCode(e),a=this.mapLanguageCode(r),n=`You are a professional translator. Translate the following text from ${i} to ${a}. Only return the translated text without any additional explanation or comments.`,s=(await this.client.models.generateContent({model:this.model,contents:t,config:{systemInstruction:n}})).text;if(!s)throw new Error("\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return {text:s.trim(),detectedSourceLang:e}}catch(i){if(i instanceof ApiError){let a=JSON.parse(i.message).error.message;throw new Error(`Gemini\u7FFB\u8A33API\u30A8\u30E9\u30FC: ${a}`)}else if(i instanceof Error)throw new Error(`Gemini\u7FFB\u8A33\u30A8\u30E9\u30FC: ${i.message}`);throw i}}mapLanguageCode(t){return {en:"English",ja:"Japanese"}[t.toLowerCase()]||t}};var v={gas:{provider:"gas",endpoint:C.DEFAULT_ENDPOINT},openai:{provider:"openai",model:x.DEFAULT_MODEL},gemini:{provider:"gemini",model:I.DEFAULT_MODEL},lmstudio:{provider:"lmstudio",endpoint:E.DEFAULT_ENDPOINT},custom:{provider:"custom"}},V={version:"1.1",activeProfile:"default",profiles:{default:{...v.gas}}},j=["gas","custom","openai","gemini","lmstudio"],Y=["ls","list","use","rm","delete","add","rename","provider","endpoint","api-key","model","default"],h=class{filePath;constructor(){this.filePath=G();}ensureConfigDir(){let t=A();w.existsSync(t)||w.mkdirSync(t,{recursive:true});}async readAppConfig(){try{if(!w.existsSync(this.filePath))return {...V};let t=w.readFileSync(this.filePath,"utf-8");return JSON.parse(t)}catch{return console.warn("\u8A2D\u5B9A\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF0E\u898F\u5B9A\u5024\u3092\u4F7F\u7528\u3057\u307E\u3059"),{...V}}}async writeAppConfig(t){try{this.ensureConfigDir(),w.writeFileSync(this.filePath,JSON.stringify(t,null,2),"utf-8");}catch{throw new Error("\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}}async readConfig(){let t=await this.readAppConfig();return t.profiles[t.activeProfile]||{...v.gas}}async writeConfig(t){let e=await this.readAppConfig();e.profiles[e.activeProfile]=t,await this.writeAppConfig(e);}async get(){return await this.readConfig()}async set(t,e){let r=await this.readConfig();switch(t){case "endpoint":r.endpoint=e;break;case "api-key":r.apiKey=e;break;case "provider":if(!j.includes(e))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${e}): ${j.join(", ")} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);r.provider=e;break;case "model":r.model=e;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${t})`)}await this.writeConfig(r);}async unset(t){let e=await this.readConfig(),r=e.provider||"gas",i=v[r];switch(t){case "endpoint":e.endpoint=i.endpoint;break;case "api-key":e.apiKey=i.apiKey;break;case "provider":e.provider=i.provider;break;case "model":e.model=i.model;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${t})`)}await this.writeConfig(e);}async reset(){await this.writeConfig({...v.gas});}async getActiveProfileName(){return (await this.readAppConfig()).activeProfile}async getProfile(t){let r=(await this.readAppConfig()).profiles[t];if(!r)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);return r}async listProfiles(){let t=await this.readAppConfig();return Object.keys(t.profiles)}async createProfile(t,e){if(Y.includes(t.toLowerCase()))throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D '${t}' \u306F\u4E88\u7D04\u8A9E\u306E\u305F\u3081\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`);if(!t.match(/^[a-zA-Z0-9_-]+$/))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D (${t}): \u82F1\u6570\u5B57\uFF0C\u30CF\u30A4\u30D5\u30F3\uFF0C\u30A2\u30F3\u30C0\u30FC\u30B9\u30B3\u30A2\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059`);if(e?.provider&&!j.includes(e.provider))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC '${e.provider}': ${j.join(", ")} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);let r=await this.readAppConfig();if(r.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);let i=e?.provider||"gas",n={...v[i],...e};r.profiles[t]=n,await this.writeAppConfig(r);}async deleteProfile(t){if(t==="default")throw new Error("'default' \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306F\u524A\u9664\u3067\u304D\u307E\u305B\u3093");let e=await this.readAppConfig();if(!e.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);delete e.profiles[t],e.activeProfile===t&&(e.activeProfile="default"),await this.writeAppConfig(e);}async useProfile(t){let e=await this.readAppConfig();if(!e.profiles[t]){let r=Object.keys(e.profiles).join(", ");throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
3
+ \u5229\u7528\u53EF\u80FD\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${r}`)}e.activeProfile=t,await this.writeAppConfig(e);}async setProfileConfig(t,e,r){let i=await this.readAppConfig();if(!i.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF0E'enja config add ${t}' \u3067\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044`);let a=i.profiles[t];switch(e){case "endpoint":a.endpoint=r;break;case "api-key":a.apiKey=r;break;case "provider":if(!j.includes(r))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${r}): ${j.join(", ")} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`);a.provider=r;break;case "model":a.model=r;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${e})`)}await this.writeAppConfig(i);}async unsetProfileConfig(t,e){let r=await this.readAppConfig();if(!r.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);let i=r.profiles[t],a=i.provider||"gas",n=v[a];switch(e){case "provider":i.provider=n.provider;break;case "endpoint":i.endpoint=n.endpoint;break;case "api-key":i.apiKey=n.apiKey;break;case "model":i.model=n.model;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${e})`)}await this.writeAppConfig(r);}async resetProfile(t){let e=await this.readAppConfig();if(!e.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);let r=v.gas;e.profiles[t]={...r},await this.writeAppConfig(e);}async renameProfile(t,e){if(t==="default")throw new Error("'default' \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306F\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093");if(t===e)return;if(Y.includes(e.toLowerCase()))throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D '${e}' \u306F\u4E88\u7D04\u8A9E\u306E\u305F\u3081\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`);if(!e.match(/^[a-zA-Z0-9_-]+$/))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D (${e}): \u82F1\u6570\u5B57\uFF0C\u30CF\u30A4\u30D5\u30F3\uFF0C\u30A2\u30F3\u30C0\u30FC\u30B9\u30B3\u30A2\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059`);let r=await this.readAppConfig();if(!r.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);if(r.profiles[e])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${e}' \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);r.profiles[e]=r.profiles[t],delete r.profiles[t],r.activeProfile===t&&(r.activeProfile=e),await this.writeAppConfig(r);}};async function z(o){let t=new h,e;if(o?.profile)try{e=await t.getProfile(o.profile);}catch{let l=await t.listProfiles();throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o.profile}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
4
+ \u5229\u7528\u53EF\u80FD\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${l.join(", ")}`)}else e=await t.get();let r=o?.provider||e.provider||"gas",i=o?.endpoint||e.endpoint,a=o?.apiKey||e.apiKey,n=o?.model||e.model;return {endpoint:i,provider:r,apiKey:a,model:n}}var st=new Set(["169.254.169.254"]);function at(o){let t=o.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);if(!t)return null;let e=t.slice(1).map(r=>Number(r));return e.some(r=>!Number.isInteger(r)||r<0||r>255)?null:e}function lt(o,t,e){return o[0]===t&&o[1]===e}function pt(o){let[t,e]=o;return t===10||t===192&&e===168||t===172&&e>=16&&e<=31}function ft(o){return o[0]===127}function ct(o){return lt(o,169,254)}function dt(o){return o==="::1"||o==="0:0:0:0:0:0:0:1"}function gt(o){return o.toLowerCase().startsWith("fe80:")}var ut=new Set(["localhost","127.0.0.1","::1"]),mt=new Set(["10.","192.168."]);function H(o,t={}){let{allowLocalEndpoint:e=false,allowPrivateEndpoint:r=false,allowHttp:i=false}=t,a;try{a=new URL(o);}catch{throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u4E0D\u6B63\u3067\u3059")}let n=a.protocol,l=a.hostname;if(st.has(l))throw new Error("\u6307\u5B9A\u3055\u308C\u305F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306F\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u4E0A\u306E\u7406\u7531\u306B\u3088\u308A\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093");if(n!=="https:"&&n!=="http:")throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u306F http:// \u307E\u305F\u306F https:// \u3067\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");let s=at(l),p=s!==null,d=ut.has(l)||(p?ft(s):false)||dt(l);if((p?ct(s):false)||gt(l))throw new Error("\u6307\u5B9A\u3055\u308C\u305F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306F\u30EA\u30F3\u30AF\u30ED\u30FC\u30AB\u30EB\u30A2\u30C9\u30EC\u30B9\u306E\u305F\u3081\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093");let g=p?pt(s):Array.from(mt).some(m=>l.startsWith(m));if(n==="http:"&&!(i||e&&d))throw new Error(`\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u306F https:// \u3067\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
5
+ HTTP \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\u5834\u5408\u306F\uFF0C--allow-http \u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
6
+ \u30ED\u30FC\u30AB\u30EB\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3067\u3042\u308C\u3070 --allow-local-endpoint \u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3082\u8A31\u53EF\u3055\u308C\u307E\u3059`);if(d&&!e)throw new Error(`\u30ED\u30FC\u30AB\u30EB\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306E\u4F7F\u7528\u306F\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u30EA\u30B9\u30AF\u304C\u3042\u308B\u305F\u3081\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093
7
+ \u30ED\u30FC\u30AB\u30EB\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\u5834\u5408\u306F\uFF0C--allow-local-endpoint \u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044`);if(g&&!r)throw new Error(`\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8 IP \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306E\u4F7F\u7528\u306F\u65E2\u5B9A\u3067\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093
8
+ \u4F7F\u7528\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\u5834\u5408\u306F\uFF0C--allow-private-endpoint \u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044`);return true}async function W(o){let t=new h,e=await z(o),r;o?.profile?r=o.profile:r=await t.getActiveProfileName();let i=o?.allowLocalEndpoint??false,a=o?.allowPrivateEndpoint??false,n=o?.allowHttp??false,l={allowLocalEndpoint:i,allowPrivateEndpoint:a,allowHttp:n};switch(e.provider){case "gas":case "custom":{let{endpoint:s,apiKey:p}=e;if(!s)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u5FC5\u8981\u3067\u3059");return H(s,l),{translator:new C(s,p),config:e,activeProfile:r}}case "openai":{let{apiKey:s,model:p}=e;if(!s)throw new Error("OpenAI \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F API \u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new x(s,p),config:e,activeProfile:r}}case "gemini":{let{apiKey:s,model:p}=e;if(!s)throw new Error("Gemini \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F API \u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new I(s,p),config:e,activeProfile:r}}case "lmstudio":{let{endpoint:s}=e;if(o?.endpoint?(H(o.endpoint,l),s=o.endpoint):s?H(s,l):(s=E.DEFAULT_ENDPOINT,H(s,{allowLocalEndpoint:true,allowPrivateEndpoint:true,allowHttp:true})),!e.model)throw new Error("LM Studio \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F\u30E2\u30C7\u30EB\u540D\u304C\u5FC5\u8981\u3067\u3059");return {translator:new E(s,e.model,e.apiKey),config:e,activeProfile:r}}default:throw new Error(`\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${e.provider})`)}}var Z=100,D=class{filePath;constructor(){this.filePath=B();}ensureConfigDir(){let t=A();w.existsSync(t)||w.mkdirSync(t,{recursive:true});}async readHistory(){try{let t=await promises.readFile(this.filePath,"utf-8");return JSON.parse(t)}catch(t){return t instanceof Error&&"code"in t&&t.code==="ENOENT"?[]:(console.warn("\u5C65\u6B74\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF0E\u7A7A\u914D\u5217\u3092\u8FD4\u3057\u307E\u3059"),[])}}async writeHistory(t){try{this.ensureConfigDir();let e=`${this.filePath}.tmp`,r=JSON.stringify(t,null,2);await promises.writeFile(e,r,"utf-8"),await promises.rename(e,this.filePath);}catch{throw new Error("\u5C65\u6B74\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}}async add(t){let e=await this.readHistory(),r={...t,id:randomUUID(),timestamp:new Date().toISOString()};e.unshift(r),e.length>Z&&e.splice(Z),await this.writeHistory(e);}async getAll(){return await this.readHistory()}async getRecent(t){return (await this.readHistory()).slice(0,t)}async deleteById(t){let e=await this.readHistory(),r=e.filter(i=>i.id!==t);return r.length===e.length?false:(await this.writeHistory(r),true)}async clear(){await this.writeHistory([]);}async findById(t){return (await this.readHistory()).find(r=>r.id===t)||null}async findByShortId(t){return (await this.readHistory()).filter(r=>r.id.startsWith(t))}async findByHash(t,e,r){return (await this.readHistory()).find(a=>a.sourceHash===t&&a.sourceLang===e&&a.targetLang===r)||null}};function X(o){return createHash("sha256").update(o).digest("hex")}async function q(o,t){try{if(!o&&!t.file&&!process.stdin.isTTY){let e=await Et();await N(e,t,"stdin");return}if(t.file){if(!w.existsSync(t.file))throw new Error(`\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t.file})`);let e=w.readFileSync(t.file,"utf-8");await N(e,t,"file");return}if(o){await N(o,t,"arg");return}throw new Error(`\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\u304C\u63D0\u4F9B\u3055\u308C\u3066\u3044\u307E\u305B\u3093
9
+
10
+ \u4F7F\u7528\u4F8B:
11
+ enja "Hello, world!" # \u5F15\u6570\u3067\u6E21\u3055\u308C\u305F\u6587\u5B57\u5217\u3092\u7FFB\u8A33
12
+ enja -f input.txt # \u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30C6\u30AD\u30B9\u30C8\u3092\u8AAD\u307F\u8FBC\u3093\u3067\u7FFB\u8A33
13
+ cat README.md | enja # \u30D1\u30A4\u30D7(\u6A19\u6E96\u5165\u529B)\u3067\u6E21\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u7FFB\u8A33`)}catch(e){console.error(`error: ${Pt(e)}`),process.exit(1);}}async function N(o,t,e){if(!o||o.trim().length===0)throw new Error("\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u3067\u3059");let r=o;if(t.stripHtml&&(r=vt(o),!r||r.trim().length===0))throw new Error("HTML\u30BF\u30B0\u3092\u9664\u53BB\u3057\u305F\u7D50\u679C\uFF0C\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u306B\u306A\u308A\u307E\u3057\u305F");let{translator:i,config:a,activeProfile:n}=await W(t),l=new D,s=t.flip?"ja":"en",p=t.flip?"en":"ja",d=X(r),f=await l.findByHash(d,s,p);if(f&&t.cache!==false){console.log(`${c.green("\u2714")} \u30AD\u30E3\u30C3\u30B7\u30E5\u304B\u3089\u7FFB\u8A33\u7D50\u679C\u3092\u53D6\u5F97\u3057\u307E\u3057\u305F`);let P=f.translatedText;if(t.output)try{w.writeFileSync(t.output,P,"utf-8"),console.log(`${c.green("\u2714")} ${t.output} \u306B\u7FFB\u8A33\u7D50\u679C\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F`);}catch{throw new Error(`\u30D5\u30A1\u30A4\u30EB\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${t.output})`)}else console.log(P);return}let g=`(${s} \u2192 ${p})`,m=i.getModel()||a.model,T=n||"unknown",y=`[${T} | ${a.provider}${m?` | ${m}`:""}]`,b=yt(`\u7FFB\u8A33\u4E2D... ${g} ${y}`).start();try{let R=(await i.translate(r,s,p)).text;if(b.succeed(`\u7FFB\u8A33\u5B8C\u4E86 ${g} ${y}`),await l.add({sourceText:r,translatedText:R,sourceLang:s,targetLang:p,textLength:r.length,sourceHash:d,profile:T,provider:a.provider,model:m,options:{stripHtml:t.stripHtml,file:t.file,inputMethod:e}}),t.output)try{w.writeFileSync(t.output,R,"utf-8"),console.log(`${c.green("\u2714")} ${t.output} \u306B\u7FFB\u8A33\u7D50\u679C\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F`);}catch{throw new Error(`\u30D5\u30A1\u30A4\u30EB\u3078\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${t.output})`)}else console.log(R);}catch(P){throw b.fail(`\u7FFB\u8A33\u5931\u6557 ${g} ${y}`),P}}function Pt(o){if(o instanceof Error)return o.message;try{return String(o)}catch{return "Unknown error"}}function Et(){return new Promise((o,t)=>{let e="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",r=>{e+=r;}),process.stdin.on("end",()=>{o(e);}),process.stdin.on("error",r=>{t(r);});})}function vt(o){return o.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,"").replace(/<[^>]+>/g,"").replace(/&nbsp;/g," ").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/\n\s*\n/g,`
14
+ `).trim()}function k(o,t=false){return o.length===0?"\u5C65\u6B74\u306F\u3042\u308A\u307E\u305B\u3093":t?Tt(o):$t(o)}function $t(o){let t=[`\u5168 ${o.length} \u4EF6\u306E\u5C65\u6B74
15
+ `];return o.forEach((e,r)=>{let i=tt(e.timestamp),a=Ct(e),n=Q(e.sourceText,20),l=Q(e.translatedText||"",20),s=[c.cyan(`[${r+1}]`),e.id.substring(0,8),i,a||null].filter(Boolean).join(" | ");t.push(s),t.push(` ${e.sourceLang} \u2192 ${e.targetLang} | ${n} \u2192 ${l}`),t.push("");}),t.join(`
16
+ `)}function Tt(o){let t=[`\u5168 ${o.length} \u4EF6\u306E\u5C65\u6B74\u306E\u8A73\u7D30
17
+ `];return o.forEach((e,r)=>{r>0&&t.push("\u2500".repeat(60));let i=14;if(t.push(`${c.cyan("ID:".padEnd(i))} ${e.id}`),t.push(`${c.cyan("Date:".padEnd(i))} ${tt(e.timestamp)}`),t.push(`${c.cyan("Direction:".padEnd(i))} ${e.sourceLang} \u2192 ${e.targetLang}`),t.push(`${c.cyan("InputLength:".padEnd(i))} ${e.textLength} characters`),t.push(`${c.cyan("OutputLength:".padEnd(i))} ${e.translatedText.length} characters`),e.profile&&t.push(`${c.cyan("Profile:".padEnd(i))} ${e.profile}`),e.provider&&t.push(`${c.cyan("Provider:".padEnd(i))} ${e.provider}`),e.model&&t.push(`${c.cyan("Model:".padEnd(i))} ${e.model}`),e.options){let a=[e.options.inputMethod&&`input=${e.options.inputMethod}`,e.options.stripHtml&&"stripHtml=true",e.options.file&&`file=${e.options.file}`].filter(Boolean).join(", ");a&&t.push(`${c.cyan("Options:".padEnd(i))} ${a}`);}t.push("",`${c.cyan("Input:")}`,e.sourceText),t.push("",`${c.cyan("Output:")}`,e.translatedText||"","");}),t.join(`
18
+ `)}function tt(o){return new Date(o).toLocaleString("ja-JP")}function Q(o,t){let e=o.replace(/[\r\n]+/g," ");return e.length>t?e.substring(0,t)+"...":e}function Ct(o){return [o.profile,o.provider,o.model].filter(t=>!!t).map(t=>c.magenta(t)).join(c.dim("\u30FB"))}async function et(o,t){try{let e=new D;if(o){let n=o.trim();if(!n)throw new Error("\u7A7A\u306EID\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F");if(n.length>=36){let p=await e.findById(n);if(!p)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${o})`);console.log(k([p],t.detail));return}if(n.length<8)throw new Error(`\u77ED\u7E2EID\u306F\u5C11\u306A\u304F\u3068\u30828\u6587\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 (${n.length})`);let l=await e.findByShortId(n);if(l.length===0)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${o})`);let s=k(l,t.detail);console.log(s);return}if(t.delete){let n=t.delete.trim();if(!n)throw new Error("\u7A7A\u306EID\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F");if(n.length>=36){if(await e.deleteById(n))console.log(`${c.green("\u2714")} \u5C65\u6B74ID ${n} \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);else throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${n})`);return}if(n.length<8)throw new Error(`\u77ED\u7E2EID\u3067\u524A\u9664\u3059\u308B\u5834\u5408\u306F\u5C11\u306A\u304F\u3068\u30828\u6587\u5B57\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 (${n.length})`);let l=await e.findByShortId(n);if(l.length===0)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${n})`);if(l.length>1)throw new Error(`\u6307\u5B9A\u3055\u308C\u305F\u77ED\u7E2EID\u306F\u8907\u6570\u306E\u5C65\u6B74\u306B\u4E00\u81F4\u3057\u307E\u3057\u305F\uFF0E\u5B8C\u5168\u306AID\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF0E
19
+ ${k(l,!1)}`);let s=l[0].id;if(await e.deleteById(s))console.log(`${c.green("\u2714")} \u5C65\u6B74ID ${s} \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);else throw new Error(`\u524A\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${s})`);return}if(t.clear){await e.clear(),console.log(`${c.green("\u2714")} \u5C65\u6B74\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3057\u305F`);return}let r=Number(t.number)||10,i=await e.getRecent(r),a=k(i,t.detail);console.log(a);}catch(e){console.error(e instanceof Error?`error: ${e.message}`:e),process.exit(1);}}async function ot(o,t,e){let r=new h,i=e?.opts()||{},n={...e?.parent?.opts()||{},...i};try{let l=e?.args??[],s=l.length,[,p,d]=l;if(o==="ls"||o==="list"){if(s>1)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
20
+
21
+ \u4F7F\u7528\u4F8B:
22
+ enja config ls`);let f=await r.listProfiles(),g=await r.getActiveProfileName();console.log(c.bold("Profiles:"));for(let m of f){let T=m===g,y=await r.getProfile(m),b=T?c.green("*"):" ",P=y.model?` - ${y.model}`:"";console.log(` ${b} ${m} (${y.provider})${P}`);}return}if(o==="use"){if(!p)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
23
+
24
+ \u4F7F\u7528\u4F8B:
25
+ enja config use <profile>`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
26
+
27
+ \u4F7F\u7528\u4F8B:
28
+ enja config use <profile>`);await r.useProfile(p),console.log(`${c.green("\u2714")} \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092 '${p}' \u306B\u8A2D\u5B9A\u3057\u307E\u3057\u305F`);return}if(o==="rm"||o==="delete"){if(!p)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
29
+
30
+ \u4F7F\u7528\u4F8B:
31
+ enja config rm <profile>`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
32
+
33
+ \u4F7F\u7528\u4F8B:
34
+ enja config rm <profile>`);await r.deleteProfile(p),console.log(`${c.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${p}' \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);return}if(o==="add"){if(!p)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
35
+
36
+ \u4F7F\u7528\u4F8B:
37
+ enja config add <profile> [options]`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
38
+
39
+ \u4F7F\u7528\u4F8B:
40
+ enja config add <profile> [options]`);let f={};n?.provider&&(f.provider=n.provider),n?.endpoint&&(f.endpoint=n.endpoint),n?.apiKey&&(f.apiKey=n.apiKey),n?.model&&(f.model=n.model),await r.createProfile(p,f),console.log(`${c.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${p}' \u3092\u4F5C\u6210\u3057\u307E\u3057\u305F`);return}if(o==="rename"){if(!p)throw new Error(`\u5909\u66F4\u524D\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
41
+
42
+ \u4F7F\u7528\u4F8B:
43
+ enja config rename <oldProfile> <newProfile>`);if(!d)throw new Error(`\u65B0\u3057\u3044\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
44
+
45
+ \u4F7F\u7528\u4F8B:
46
+ enja config rename <oldProfile> <newProfile>`);if(s>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
47
+
48
+ \u4F7F\u7528\u4F8B:
49
+ enja config rename <oldProfile> <newProfile>`);await r.renameProfile(p,d),console.log(`${c.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${p}' \u3092 '${d}' \u306B\u5909\u66F4\u3057\u307E\u3057\u305F`);return}if(!o){if(n?.provider||n?.endpoint||n?.apiKey||n?.model||n?.reset||n?.unset)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
50
+
51
+ \u4F7F\u7528\u4F8B:
52
+ enja config work --provider openai \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4
53
+ enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210`);let f=await r.getActiveProfileName(),g=await r.get();console.log(`${c.bold("Active Profile:")} ${f}`),console.log(`${c.blue("provider:")} ${g.provider}`),console.log(`${c.blue("endpoint:")} ${g.endpoint||"(not set)"}`),console.log(`${c.blue("apiKey:")} ${g.apiKey?rt(g.apiKey):"(not set)"}`),console.log(`${c.blue("model:")} ${g.model||"(not set)"}`);return}if(o&&!p&&(n?.provider||n?.endpoint||n?.apiKey||n?.model)){let f=!1;n.provider&&(await r.setProfileConfig(o,"provider",n.provider),f=!0),n.endpoint&&(await r.setProfileConfig(o,"endpoint",n.endpoint),f=!0),n.apiKey&&(await r.setProfileConfig(o,"api-key",n.apiKey),f=!0),n.model&&(await r.setProfileConfig(o,"model",n.model),f=!0),f&&console.log(`${c.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o}' \u306E\u8A2D\u5B9A\u3092\u66F4\u65B0\u3057\u307E\u3057\u305F`);return}if(o&&!p&&!n?.reset&&!n?.unset&&!n?.provider&&!n?.endpoint&&!n?.apiKey&&!n?.model){let f=await r.getProfile(o);console.log(`${c.bold("Profile:")} ${o}`),console.log(`${c.blue("provider:")} ${f.provider}`),console.log(`${c.blue("endpoint:")} ${f.endpoint||"(not set)"}`),console.log(`${c.blue("apiKey:")} ${f.apiKey?rt(f.apiKey):"(not set)"}`),console.log(`${c.blue("model:")} ${f.model||"(not set)"}`);return}if(o&&n?.reset){await r.resetProfile(o),console.log(`${c.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o}' \u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F`);return}if(o&&n?.unset){await r.unsetProfileConfig(o,n.unset),console.log(`${c.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o}' \u306E ${n.unset} \u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F`);return}throw new Error(`\u7121\u52B9\u306A\u30B3\u30DE\u30F3\u30C9\u5F62\u5F0F\u3067\u3059\uFF0E
54
+
55
+ \u4F7F\u7528\u4F8B:
56
+ enja config \u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u8868\u793A
57
+ enja config ls \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4E00\u89A7
58
+ enja config work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u8868\u793A
59
+ enja config use work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u5207\u308A\u66FF\u3048
60
+ enja config work --provider openai \u8A2D\u5B9A\u5909\u66F4
61
+ enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4F5C\u6210
62
+ enja config rename oldProfile newProfile \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u5909\u66F4
63
+ `)}catch(l){l instanceof Error?console.error(`error: ${l.message}`):console.error(l),process.exit(1);}}function rt(o){if(o.length<=8)return "*".repeat(o.length);let t=4,e=o.slice(0,t),r=o.slice(-t),i="*".repeat(o.length-t*2);return `${e}${i}${r}`}var K=JSON.parse(readFileSync(new URL("../package.json",import.meta.url),"utf-8")),S=new Command;S.name("enja").usage("[arguments] [options]").description(K.description).version(K.version,"-v, --version","output the current version");S.argument("[text]","\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\uFF08\u7701\u7565\u3057\u305F\u5834\u5408\u306F\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u6A19\u6E96\u5165\u529B\u304B\u3089\u8AAD\u307F\u8FBC\u3080\uFF09").option("-f, --file <path>","\u30D5\u30A1\u30A4\u30EB\u3092\u7FFB\u8A33\u3059\u308B").option("-o, --output <path>","\u30D5\u30A1\u30A4\u30EB\u306B\u51FA\u529B\u3059\u308B (\u30C7\u30D5\u30A9\u30EB\u30C8: \u6A19\u6E96\u51FA\u529B)").option("-s, --strip-html","HTML\u30BF\u30B0\u3092\u9664\u53BB\u3057\u3066\u304B\u3089\u7FFB\u8A33\u3059\u308B").option("-N, --no-cache","\u30AD\u30E3\u30C3\u30B7\u30E5\u3092\u4F7F\u7528\u305B\u305A\u306B\u518D\u7FFB\u8A33\u3059\u308B").option("-F, --flip","\u7FFB\u8A33\u65B9\u5411\u3092\u9006\u306B\u3059\u308B (default: \u82F1\u8A9E\u2192\u65E5\u672C\u8A9E)").option("-p, --profile <name>","\u4F7F\u7528\u3059\u308B\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A").option("--endpoint <url>","\u4E00\u6642\u7684\u306B\u30AB\u30B9\u30BF\u30E0\u7FFB\u8A33\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\uFF08\u73FE\u5728\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u9069\u7528\uFF09").option("--api-key <key>","\u4E00\u6642\u7684\u306B API \u30AD\u30FC\u3092\u6307\u5B9A\uFF08\u73FE\u5728\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u9069\u7528\uFF09").option("--provider <name>","\u4E00\u6642\u7684\u306B\u7FFB\u8A33\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3092\u6307\u5B9A (\u4F8B: gas, openai, gemini, lmstudio; \u73FE\u5728\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u9069\u7528)").option("--model <name>","\u4E00\u6642\u7684\u306B\u4F7F\u7528\u3059\u308B\u30E2\u30C7\u30EB\u540D\u3092\u6307\u5B9A (\u4F8B: gpt-4o-mini, gemini-2.5-flash-lite; \u73FE\u5728\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u9069\u7528)").option("--allow-local-endpoint","localhost\uFF08127.0.0.1\uFF09\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u8A31\u53EF\u3059\u308B").option("--allow-private-endpoint","\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\uFF08\u4F8B: 192.168.x.x\uFF09\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u8A31\u53EF\u3059\u308B").option("--allow-http","HTTP\uFF08\u975E TLS\uFF09\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u8A31\u53EF\u3059\u308B").addHelpText("after",`
12
64
  Examples:
13
65
  $ enja "Hello, world!" # \u5F15\u6570\u3067\u6E21\u3055\u308C\u305F\u6587\u5B57\u5217\u3092\u7FFB\u8A33
14
- $ git --help | enja # \u30D1\u30A4\u30D7(\u6A19\u6E96\u5165\u529B)\u3067\u6E21\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u7FFB\u8A33
66
+ $ docker --help | enja # \u30D1\u30A4\u30D7(\u6A19\u6E96\u5165\u529B)\u3067\u6E21\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u7FFB\u8A33
15
67
  $ enja -f input.txt # \u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30C6\u30AD\u30B9\u30C8\u3092\u8AAD\u307F\u8FBC\u3093\u3067\u7FFB\u8A33
16
68
  $ enja -f input.txt -o output.txt # \u30D5\u30A1\u30A4\u30EB\u304B\u3089\u8AAD\u307F\u8FBC\u307F\uFF0C\u7FFB\u8A33\u7D50\u679C\u3092\u30D5\u30A1\u30A4\u30EB\u306B\u4FDD\u5B58
17
69
  $ cat README.md | enja -o japanese.md # \u30D1\u30A4\u30D7\u3068\u30D5\u30A1\u30A4\u30EB\u51FA\u529B\u306E\u7D44\u307F\u5408\u308F\u305B
18
70
  $ curl -s https://example.com | enja -s # HTML\u30BF\u30B0\u3092\u9664\u53BB\u3057\u3066\u7FFB\u8A33
19
71
  $ enja "Hello" -p work # work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F7F\u7528\u3057\u3066\u7FFB\u8A33
20
72
  $ enja "Hello, world!" --provider openai --api-key YOUR_OPENAI_API_KEY # OpenAI API \u3092\u4F7F\u7528\u3057\u3066\u7FFB\u8A33`).addHelpText("afterAll",`
21
- Enja CLI v${M.version}`).addHelpText("afterAll","Copyright (c) 2025-2026 yhotta240").addHelpText("afterAll","GitHub: https://github.com/yhotamos/enja-cli").action(z);T.command("history").description("Description: \u7FFB\u8A33\u5C65\u6B74\u3092\u8868\u793A\u3059\u308B").argument("[id]","ID \u3067\u5C65\u6B74\u3092\u8868\u793A\u3059\u308B\uFF08\u5B8C\u5168 ID \u307E\u305F\u306F\u77ED\u7E2E ID\uFF09").option("-d, --detail","\u8A73\u7D30\u8868\u793A").option("-n, --number <number>","\u8868\u793A\u4EF6\u6570","10").option("--delete <id>","\u7279\u5B9A\u306E\u5C65\u6B74\u3092\u524A\u9664\u3059\u308B").option("--clear","\u5C65\u6B74\u3092\u30AF\u30EA\u30A2").action(Q);T.command("config").usage("[profile|subcommand] [subcommandArg] [options]").description("Description: \u8A2D\u5B9A\u3068\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u7BA1\u7406\u3059\u308B").argument("[profile|subcommand]",`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u307E\u305F\u306F\u30B5\u30D6\u30B3\u30DE\u30F3\u30C9
73
+ Enja CLI v${K.version}`).addHelpText("afterAll","Copyright (c) 2025-2026 yhotta240").addHelpText("afterAll","GitHub: https://github.com/yhotamos/enja-cli").action(q);S.command("history").description("\u7FFB\u8A33\u5C65\u6B74\u3092\u8868\u793A\u3059\u308B").argument("[id]","ID \u3067\u5C65\u6B74\u3092\u8868\u793A\u3059\u308B\uFF08\u5B8C\u5168 ID \u307E\u305F\u306F\u77ED\u7E2E ID\uFF09").option("-d, --detail","\u8A73\u7D30\u8868\u793A").option("-n, --number <number>","\u8868\u793A\u4EF6\u6570","10").option("--delete <id>","\u7279\u5B9A\u306E\u5C65\u6B74\u3092\u524A\u9664\u3059\u308B").option("--clear","\u5C65\u6B74\u3092\u30AF\u30EA\u30A2").action(et);S.command("config").usage("[profile|subcommand] [options]").description("\u8A2D\u5B9A\u3068\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u7BA1\u7406\u3059\u308B").allowExcessArguments(true).argument("[profile|subcommand]",`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u307E\u305F\u306F\u30B5\u30D6\u30B3\u30DE\u30F3\u30C9
22
74
 
23
75
  Profiles:
24
76
  <profile> \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A73\u7D30\u3092\u8868\u793A
25
77
  <profile> [options] \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4
26
78
 
27
79
  Subcommands:
28
- ls, list \u5168\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4E00\u89A7\u8868\u793A
29
- use <profile> \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u5909\u66F4
30
- rm <profile>, delete <profile> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664
31
- add <profile> [options] \u65B0\u3057\u3044\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
32
- `).argument("[subcommandArg]","\u30B5\u30D6\u30B3\u30DE\u30F3\u30C9 (use, rm, delete, add) \u306E\u5F15\u6570\u3068\u3057\u3066\u6307\u5B9A\u3059\u308B\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D").option("--provider <name>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3092\u8A2D\u5B9A (gas, custom, openai, gemini)").option("--endpoint <url>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u5B9A").option("--api-key <api-key>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E API \u30AD\u30FC\u3092\u8A2D\u5B9A").option("--model <name>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u30E2\u30C7\u30EB\u3092\u8A2D\u5B9A").option("--unset <key>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u3057\u305F\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8").option("--reset","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u5168\u4F53\u3092\u30EA\u30BB\u30C3\u30C8").addHelpText("after",`
80
+ ls, list \u5168\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4E00\u89A7\u8868\u793A
81
+ use <profile> \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u5909\u66F4
82
+ rm <profile>, delete <profile> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664
83
+ rename <oldProfile> <newProfile> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u5909\u66F4
84
+ add <profile> [options] \u65B0\u3057\u3044\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
85
+ `).option("--provider <name>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3092\u8A2D\u5B9A (\u4F8B: gas, openai, gemini, lmstudio)").option("--endpoint <url>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u5B9A").option("--api-key <api-key>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E API \u30AD\u30FC\u3092\u8A2D\u5B9A").option("--model <name>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u30E2\u30C7\u30EB\u3092\u8A2D\u5B9A").option("--unset <key>","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u3057\u305F\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8").option("--reset","\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u5168\u4F53\u3092\u30EA\u30BB\u30C3\u30C8").addHelpText("after",`
33
86
  --provider Names:
34
- gas Google Apps Script \u306E LanguageApp \u3092\u4F7F\u7528\u3057\u305F\u7FFB\u8A33\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\uFF09
35
- custom \u30AB\u30B9\u30BF\u30E0\u7FFB\u8A33\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528
36
- openai OpenAI API \u3092\u4F7F\u7528\u3057\u305F\u7FFB\u8A33
37
- gemini Gemini API \u3092\u4F7F\u7528\u3057\u305F\u7FFB\u8A33
87
+ gas, custom, openai, gemini, lmstudio
38
88
 
39
89
  --unset Keys:
40
90
  provider, endpoint, api-key, model
@@ -51,4 +101,4 @@ Examples:
51
101
  $ enja config work --provider openai work \u306E provider \u3092\u8A2D\u5B9A
52
102
  $ enja config work --provider openai --model gpt-4o \u8907\u6570\u8A2D\u5B9A\u3092\u540C\u6642\u5909\u66F4
53
103
  $ enja config add personal --provider gemini personal \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
54
- $ enja "Hello" -p work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3067\u7FFB\u8A33`).action(X);T.parse();
104
+ $ enja "Hello" -p work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3067\u7FFB\u8A33`).action(ot);S.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yhotamos/enja-cli",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "英語を日本語に翻訳するシンプルなコマンドラインツール",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,30 +11,13 @@
11
11
  "enja": "dist/index.js"
12
12
  },
13
13
  "scripts": {
14
- "build": "tsup --no-sourcemap",
15
- "build:dev": "tsup",
16
- "watch": "tsup --watch"
17
- },
18
- "tsup": {
19
- "entry": [
20
- "src/index.ts"
21
- ],
22
- "format": [
23
- "esm"
24
- ],
25
- "bundle": true,
26
- "minify": true,
27
- "treeshake": true,
28
- "external": [
29
- "commander",
30
- "kleur",
31
- "ora"
32
- ],
33
- "dts": true,
34
- "outDir": "dist",
35
- "clean": true,
36
- "sourcemap": true,
37
- "target": "node18"
14
+ "lint": "eslint src",
15
+ "lint:fix": "eslint src --fix",
16
+ "typecheck": "tsc --noEmit",
17
+ "build": "npm run lint && npm run typecheck && tsup",
18
+ "build:dev": "tsup --sourcemap",
19
+ "watch": "tsup --watch",
20
+ "test": "vitest"
38
21
  },
39
22
  "keywords": [
40
23
  "translation",
@@ -68,8 +51,12 @@
68
51
  },
69
52
  "devDependencies": {
70
53
  "@types/node": "^24.10.1",
54
+ "dotenv": "^17.3.1",
55
+ "eslint": "^10.0.2",
71
56
  "tsup": "^8.5.1",
72
57
  "tsx": "^4.20.6",
73
- "typescript": "^5.9.3"
58
+ "typescript": "^5.9.3",
59
+ "typescript-eslint": "^8.56.1",
60
+ "vitest": "^4.0.18"
74
61
  }
75
62
  }
package/dist/index.d.ts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node