@yhotamos/enja-cli 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +15 -33
  2. package/dist/index.js +71 -68
  3. package/package.json +6 -6
package/README.md CHANGED
@@ -8,13 +8,13 @@
8
8
 
9
9
  ## 特徴
10
10
 
11
- - インストール後すぐ使える(セットアップ不要)
11
+ - セットアップ不要で,インストール後すぐに利用可能
12
12
  - Google Apps Script の LanguageApp を使用した軽量な翻訳
13
- - 引数,パイプ,ファイルから翻訳可能
14
- - HTML タグ除去機能で Web ページも翻訳可能
15
- - OpenAI API Gemini API を使用して高品質な翻訳も可能
16
- - 翻訳履歴の保存・参照機能
17
- - 複数の翻訳API設定をプロファイルとして管理・切り替え可能
13
+ - 引数,標準入力(パイプ),ファイル入力に幅広く対応
14
+ - HTML タグを除去して Web コンテンツもそのまま翻訳
15
+ - OpenAI, Gemini, LM Studio などの各種 API による高品質な翻訳
16
+ - 英日・日英の翻訳方向の切り替えが可能
17
+ - 翻訳履歴の保存やプロファイル機能による複数 API の切り替えが可能
18
18
 
19
19
  ## インストール
20
20
 
@@ -39,7 +39,7 @@ enja -f input.txt -o output.txt
39
39
  # 翻訳方向を逆にする (日本語 → 英語)
40
40
  enja "こんにちは" -F
41
41
 
42
- # OpenAI API を使用して翻訳
42
+ # OpenAI API を一時的に使用して翻訳
43
43
  enja "Hello, world!" --provider openai --api-key YOUR_OPENAI_API_KEY
44
44
  ```
45
45
 
@@ -64,8 +64,8 @@ npm install nonexistent-package 2>&1 | enja
64
64
  # コマンドのヘルプを日本語化
65
65
  docker --help | enja
66
66
 
67
- # 英語のドキュメントを日本語に変換
68
- enja -f CONTRIBUTING.md -o CONTRIBUTING.ja.md
67
+ # 英語で書かれたドキュメントを日本語に翻訳
68
+ enja -f README.md -o README.ja.md
69
69
 
70
70
  # Webページの本文を翻訳(HTMLタグ除去)
71
71
  curl -s https://example.com | enja -s
@@ -80,33 +80,15 @@ curl -s https://example.com/api/docs | enja
80
80
 
81
81
  ## セキュリティとプライバシー
82
82
 
83
- ### デフォルトプロバイダー (GAS) 使用時
83
+ ### デフォルトプロバイダー(GAS)使用時
84
84
 
85
- - 翻訳データは保存されません(リクエストごとに処理し,即座にレスポンス)
86
- - 他のユーザーの翻訳内容は見えません(完全にステートレス)
87
- - 機密情報の翻訳は避けてください(公開エンドポイントを使用しているため)
85
+ - 翻訳データは保存されません(その場で処理され,すぐに結果が返ります)
86
+ - 公開エンドポイントを使用しているため,機密情報の翻訳は避けてください
88
87
 
89
- ### カスタムプロバイダー使用時
88
+ ### その他のプロバイダー使用時
90
89
 
91
- OpenAI Gemini などのカスタムプロバイダーを使用する場合は,各サービスのプライバシーポリシーに従います.
92
-
93
- ## 制限事項
94
-
95
- ### デフォルトプロバイダー (GAS) 使用時
96
-
97
- - 1 日あたりのリクエスト数: すべてのユーザーで共有で約 5,000 リクエスト
98
- - 文字数制限: 1 リクエストあたり最大 100,000 文字
99
-
100
- 制限に達した場合はエラーメッセージが表示されます.
101
-
102
- ### カスタムプロバイダー使用時
103
-
104
- 各サービスの制限に従います(OpenAI,Gemini など).
105
-
106
- ## 今後の予定
107
-
108
- - [ ] より多くの翻訳プロバイダー対応(DeepL など)
109
- - [ ] API キーの暗号化保存
90
+ OpenAI,Gemini,LM Studio などを使用する場合は,各サービスのプライバシーポリシーに従います.
91
+ プロバイダーによっては,入力データが保存されたり,学習に利用されることがありますので,注意してください.
110
92
 
111
93
  ## 貢献
112
94
 
package/dist/index.js CHANGED
@@ -1,104 +1,107 @@
1
1
  #!/usr/bin/env node
2
- import*as h 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 T=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 P=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 $=g||"LMStudio: \u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F";throw new Error($)}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 C=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 x=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 j={gas:{provider:"gas",endpoint:T.DEFAULT_ENDPOINT},openai:{provider:"openai",model:C.DEFAULT_MODEL},gemini:{provider:"gemini",model:x.DEFAULT_MODEL},lmstudio:{provider:"lmstudio",endpoint:P.DEFAULT_ENDPOINT},custom:{provider:"custom"}},V={version:"1.1",activeProfile:"default",profiles:{default:{...j.gas}}},k=["gas","custom","openai","gemini","lmstudio"],Y=["ls","list","use","rm","delete","add","rename","provider","endpoint","api-key","model","default"],w=class{filePath;constructor(){this.filePath=G();}ensureConfigDir(){let t=A();h.existsSync(t)||h.mkdirSync(t,{recursive:true});}async readAppConfig(){try{if(!h.existsSync(this.filePath))return {...V};let t=h.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(),h.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]||{...j.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 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&&!k.includes(e.provider))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC '${e.provider}': ${k.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={...j[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(!k.includes(r))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${r}): ${k.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=j[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=j.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 w,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 D(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 w,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 D(s,l),{translator:new T(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 C(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 x(s,p),config:e,activeProfile:r}}case "lmstudio":{let{endpoint:s}=e;if(o?.endpoint?(D(o.endpoint,l),s=o.endpoint):s?D(s,l):(s=P.DEFAULT_ENDPOINT,D(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 P(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,I=class{filePath;constructor(){this.filePath=B();}ensureConfigDir(){let t=A();h.existsSync(t)||h.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 Pt();await U(e,t,"stdin");return}if(t.file){if(!h.existsSync(t.file))throw new Error(`\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t.file})`);let e=h.readFileSync(t.file,"utf-8");await U(e,t,"file");return}if(o){await U(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
2
+ import*as E from'fs';import {readFileSync,promises}from'fs';import {Command}from'commander';import g from'kleur';import {select,confirm}from'@inquirer/prompts';import*as _ from'os';import*as $ from'path';import {GoogleGenAI,ApiError}from'@google/genai';import W from'openai';import {randomUUID,createHash}from'crypto';import Dt from'ora';async function F(o,t){let r=o.map(e=>({name:e===t?g.green(`${e} (active)`):e,value:e}));try{return await select({message:"\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044",choices:r})}catch{throw new Error("\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u9078\u629E\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F")}}async function K(o){try{if(!await confirm({message:`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o}' \u3092\u524A\u9664\u3057\u3066\u3082\u3088\u308D\u3057\u3044\u3067\u3059\u304B\uFF1F`}))return console.log("\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u524A\u9664\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F"),!1}catch{throw new Error("\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u524A\u9664\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F")}return true}function T(){if(process.platform==="win32"){let r=process.env.APPDATA||$.join(_.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 $.join(r,"enja-cli")}let t=_.homedir();return $.join(t,".config","enja-cli")}function Y(){return $.join(T(),"history.json")}function z(){return $.join(T(),"config.json")}var C=class{static getDefaultProfile(){return {provider:"custom"}}apiUrl;apiKey;model;constructor(t,r,e){this.apiUrl=t,this.apiKey=r,this.model=e;}getModel(){return this.model||null}async translate(t,r,e){let i={"Content-Type":"application/json",Accept:"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:r,targetLang:e,...this.model?{model:this.model}:{}})}),n=await a.text();if(!a.ok){let l;try{let c=JSON.parse(n);if(this.isRecord(c)){let f=this.asString(c.error)??(this.isRecord(c.error)?this.asString(c.error.message):null)??this.asString(c.message);f&&(l=f);}}catch{}throw new Error(`Custom: HTTP ${a.status} ${a.statusText}${l?` - ${l}`:""}`)}let p;try{p=JSON.parse(n);}catch{if(n.trim())return {text:n.trim(),detectedSourceLang:r};throw new Error("Custom: \u30EC\u30B9\u30DD\u30F3\u30B9\u306E JSON \u89E3\u6790\u306B\u5931\u6557\u3057\u307E\u3057\u305F")}let s=this.extractText(p);if(s)return {text:s.trim(),detectedSourceLang:r};throw new Error("Custom: \u30EC\u30B9\u30DD\u30F3\u30B9\u304B\u3089\u7FFB\u8A33\u30C6\u30AD\u30B9\u30C8\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F")}extractText(t){if(!this.isRecord(t))return null;if(Array.isArray(t.choices)&&t.choices.length>0){let r=t.choices[0];if(this.isRecord(r)){let e=(this.isRecord(r.message)?this.asString(r.message.content):null)??this.asString(r.text);if(e)return e}}if(Array.isArray(t.output))for(let r of t.output){let e=this.extractFromItem(r);if(e)return e}if(Array.isArray(t.results)&&t.results.length>0){let r=t.results[0];if(this.isRecord(r)){let e=this.asString(r.content)??this.asString(r.text);if(e)return e}}return this.asString(t.translation)??this.asString(t.translated_text)??this.asString(t.translatedText)??this.asString(t.result)??this.asString(t.text)??this.asString(t.content)??this.asString(t.response)??this.asString(t.output)??null}extractFromItem(t){if(typeof t=="string")return t||null;if(!this.isRecord(t))return null;if(t.type==="message"||t.type==="text"){let r=this.asString(t.content)??this.asString(t.text);if(r)return r}return this.asString(t.content)??this.asString(t.text)??this.asString(t.response)??null}isRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}asString(t){return typeof t=="string"&&t.length>0?t:null}};var x=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)(\?.*)?$/;static getDefaultProfile(){return {provider:"gas",endpoint:o.DEFAULT_ENDPOINT}}apiUrl;apiKey;constructor(t=o.DEFAULT_ENDPOINT,r){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=r;}getModel(){return null}async translate(t,r,e){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:r,targetLang:e})});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}}};var A=class o{static DEFAULT_MODEL="gemini-2.5-flash-lite";static getDefaultProfile(){return {provider:"gemini",model:o.DEFAULT_MODEL}}client;model;constructor(t,r=o.DEFAULT_MODEL){this.client=new GoogleGenAI({apiKey:t}),this.model=r;}getModel(){return this.model}async translate(t,r,e){try{let i=this.mapLanguageCode(r),a=this.mapLanguageCode(e),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:r}}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 P=class o{static DEFAULT_ENDPOINT="http://localhost:1234/api/v1/chat";static getDefaultProfile(){return {provider:"lmstudio",endpoint:o.DEFAULT_ENDPOINT}}baseUrl;model;apiKey;constructor(t=o.DEFAULT_ENDPOINT,r,e){this.baseUrl=t,this.model=r,this.apiKey=e;}getModel(){return this.model||null}async translate(t,r,e){let i=`You are a professional translator. Translate the following text from ${r} to ${e}. 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}`}:{}},p=JSON.stringify({model:this.model,system_prompt:i,input:t}),s=await fetch(a.toString(),{method:"POST",headers:n,body:p}),l=await s.text(),c=this.parseJsonSafe(l,s);if(!s.ok){if(c?.error){if(typeof c.error=="string")throw new Error(`LMStudio: ${c.error}`);let{message:d,code:u}=c.error;if(u==="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(u==="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 v=d||"LMStudio: \u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F";throw new Error(v)}throw new Error(`LMStudio: HTTP ${s.status} ${s.statusText}`)}let f=this.extractTranslatedFromOutput(c);if(f)return {text:f.trim(),detectedSourceLang:r};throw c?.error?new Error(`LMStudio: ${c.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 r;try{r=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 e=r.pathname.replace(/\/+$/,"");if(e===""||e==="/")r.pathname="/api/v1/chat";else if(e!=="/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 r}parseJsonSafe(t,r){if(t)try{return JSON.parse(t)}catch{if(!r.ok){let e=t?`${t.slice(0,200)}...`:"";throw new Error(`LMStudio: \u975EJSON\u30EC\u30B9\u30DD\u30F3\u30B9 (HTTP ${r.status} ${r.statusText}) ${e}`)}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 r of t.output)if(r&&typeof r=="object"&&r.type==="message"){let e=this.extractFromItem(r);if(e)return e}for(let r of t.output){let e=this.extractFromItem(r);if(e)return e}return null}extractFromItem(t){if(!t&&t!=="")return null;if(typeof t=="string")return t;if(Array.isArray(t)){for(let r of t){let e=this.extractFromItem(r);if(e)return e}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 r=t.content;if(typeof r.text=="string")return r.text;if(typeof r.content=="string")return r.content;let e=this.extractFromItem(r);if(e)return e}if(Array.isArray(t.content))for(let r of t.content){let e=this.extractFromItem(r);if(e)return e}if(Array.isArray(t.output)){let r=this.extractTranslatedFromOutput({output:t.output});if(r)return r}}return null}};var L=class o{static DEFAULT_MODEL="gpt-4o-mini";static getDefaultProfile(){return {provider:"openai",model:o.DEFAULT_MODEL}}client;model;constructor(t,r=o.DEFAULT_MODEL){this.client=new W({apiKey:t}),this.model=r;}getModel(){return this.model}async translate(t,r,e){try{let i=this.mapLanguageCode(r),a=this.mapLanguageCode(e),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:r}}catch(i){throw i instanceof W.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 X=["ls","list","use","rm","delete","add","rename","copy","provider","endpoint","api-key","model","default"];function R(o){if(X.includes(o.toLowerCase()))throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D '${o}' \u306F\u4E88\u7D04\u8A9E\u306E\u305F\u3081\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`);if(!o.match(/^[a-zA-Z0-9_-]+$/))throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D (${o}): \u82F1\u6570\u5B57\uFF0C\u30CF\u30A4\u30D5\u30F3\uFF0C\u30A2\u30F3\u30C0\u30FC\u30B9\u30B3\u30A2\u306E\u307F\u4F7F\u7528\u3067\u304D\u307E\u3059`)}var b="gas",j={gas:x.getDefaultProfile,openai:L.getDefaultProfile,gemini:A.getDefaultProfile,lmstudio:P.getDefaultProfile,custom:C.getDefaultProfile},Z={version:"1.1",activeProfile:"default",profiles:{default:j[b]()}},h=class o{filePath;constructor(){this.filePath=z();}async get(){return await this.readConfig()}async getActiveProfileName(){return (await this.readAppConfig()).activeProfile}async getProfile(t){let e=(await this.readAppConfig()).profiles[t];if(!e)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093`);return e}async listProfiles(){let t=await this.readAppConfig();return Object.keys(t.profiles)}async useProfile(t){let r=await this.readAppConfig();if(!r.profiles[t]){let e=Object.keys(r.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: ${e}`)}r.activeProfile=t,await this.writeAppConfig(r);}async addProfile(t,r){if(R(t),r?.provider&&!this.isTranslatorProvider(r.provider)){let p=Object.keys(j).join(", ");throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC '${r.provider}': ${p} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`)}let e=await this.readAppConfig();if(e.profiles[t])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${t}' \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);let i=r?.provider||b,n={...this.getDefaultProfileByProvider(i),...r};e.profiles[t]=n,await this.writeAppConfig(e);}async renameProfile(t,r){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===r)return;R(r);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`);if(e.profiles[r])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${r}' \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);e.profiles[r]=e.profiles[t],delete e.profiles[t],e.activeProfile===t&&(e.activeProfile=r),await this.writeAppConfig(e);}async copyProfile(t,r){if(t===r)throw new Error("\u30B3\u30D4\u30FC\u5143\u3068\u30B3\u30D4\u30FC\u5148\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u304C\u540C\u3058\u3067\u3059");R(r);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`);if(e.profiles[r])throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${r}' \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059`);e.profiles[r]={...e.profiles[t]},await this.writeAppConfig(e);}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 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`);delete r.profiles[t],r.activeProfile===t&&(r.activeProfile="default"),await this.writeAppConfig(r);}async setProfileConfig(t,r,e){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(r){case "endpoint":a.endpoint=e;break;case "api-key":a.apiKey=e;break;case "provider":if(!this.isTranslatorProvider(e)){let n=Object.keys(j).join(", ");throw new Error(`\u7121\u52B9\u306A\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${e}): ${n} \u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`)}a.provider=e;break;case "model":a.model=e;break;default:throw new Error(`\u7121\u52B9\u306A\u8A2D\u5B9A\u30AD\u30FC (${r})`)}await this.writeAppConfig(i);}async unsetProfileConfig(t,r){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 i=e.profiles[t],a=i.provider||b,n=this.getDefaultProfileByProvider(a);switch(r){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 (${r})`)}await this.writeAppConfig(e);}async resetProfileConfig(t){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 e=this.getDefaultProfile();r.profiles[t]={...e},await this.writeAppConfig(r);}static isAppConfig(t){return !(!t||typeof t!="object"||!("profiles"in t)||!("activeProfile"in t)||typeof t.activeProfile!="string"||typeof t.profiles!="object"||t.profiles===null)}getDefaultProfile(){return j[b]()}getDefaultProfileByProvider(t){return j[t]()}isTranslatorProvider(t){return t in j}async ensureConfigDir(){let t=T();await promises.mkdir(t,{recursive:true});}async readAppConfig(){try{let t=await promises.readFile(this.filePath,"utf-8"),r=JSON.parse(t);return o.isAppConfig(r)?r:(console.warn("\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306E\u5F62\u5F0F\u304C\u4E0D\u6B63\u3067\u3059\uFF0E\u898F\u5B9A\u5024\u3092\u4F7F\u7528\u3057\u307E\u3059"),{...Z})}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"),{...Z}}}async writeAppConfig(t){try{await this.ensureConfigDir();let r=`${this.filePath}.${Date.now()}.tmp`,e=JSON.stringify(t,null,2);await promises.writeFile(r,e,"utf-8"),await promises.rename(r,this.filePath);}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]||this.getDefaultProfile()}};function Q(o){o.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
4
+
5
+ Profiles:
6
+ <profile> \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A73\u7D30\u3092\u8868\u793A
7
+ <profile> [options] \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4
8
+
9
+ Subcommands:
10
+ list, ls \u5168\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4E00\u89A7\u8868\u793A
11
+ use <profile> \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u5909\u66F4
12
+ add <profile> [options] \u65B0\u3057\u3044\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
13
+ rename <old> <new> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u5909\u66F4
14
+ copy <source> <target> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u30B3\u30D4\u30FC
15
+ delete, rm <profile> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664`).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",`
16
+ --provider Names:
17
+ gas, custom, openai, gemini, lmstudio
18
+
19
+ --unset Keys:
20
+ provider, endpoint, api-key, model
21
+
22
+ \u6CE8\u610F: --provider, --endpoint, --api-key, --model \u30AA\u30D7\u30B7\u30E7\u30F3\u306F
23
+ \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u307E\u305F\u306F 'add' \u30B5\u30D6\u30B3\u30DE\u30F3\u30C9\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
24
+ --unset, --reset \u306F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
25
+
26
+ Examples:
27
+ $ enja config \u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u8868\u793A
28
+ $ enja config ls \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4E00\u89A7
29
+ $ enja config work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u8868\u793A
30
+ $ enja config use work work \u3092\u30A2\u30AF\u30C6\u30A3\u30D6\u306B\u8A2D\u5B9A
31
+ $ enja config add personal personal \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
32
+ $ enja config rm personal \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664
33
+ $ enja "Hello" -p work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3067\u7FFB\u8A33`).action(dt);}async function dt(o,t,r){let e=new h,i=r?.opts()||{},n={...r?.parent?.opts()||{},...i};try{let p=r?.args??[],s=p.length,[,l,c]=p;if(o==="ls"||o==="list"){if(s>1)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
9
34
 
10
35
  \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: ${Et(e)}`),process.exit(1);}}async function U(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 I,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 E=f.translatedText;if(t.output)try{h.writeFileSync(t.output,E,"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(E);return}let g=`(${s} \u2192 ${p})`,m=i.getModel()||a.model,$=n||"unknown",y=`[${$} | ${a.provider}${m?` | ${m}`:""}]`,O=yt(`\u7FFB\u8A33\u4E2D... ${g} ${y}`).start();try{let R=(await i.translate(r,s,p)).text;if(O.succeed(`\u7FFB\u8A33\u5B8C\u4E86 ${g} ${y}`),await l.add({sourceText:r,translatedText:R,sourceLang:s,targetLang:p,textLength:r.length,sourceHash:d,profile:$,provider:a.provider,model:m,options:{stripHtml:t.stripHtml,file:t.file,inputMethod:e}}),t.output)try{h.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(E){throw O.fail(`\u7FFB\u8A33\u5931\u6557 ${g} ${y}`),E}}function Et(o){if(o instanceof Error)return o.message;try{return String(o)}catch{return "Unknown error"}}function Pt(){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 H(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=Lt(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 Lt(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 I;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(H([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=H(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
- ${H(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=H(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 w,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
36
+ enja config ls`);let f=await e.listProfiles(),d=await e.getActiveProfileName();console.log(g.bold("Profiles:"));for(let u of f){let v=u===d,w=await e.getProfile(u),k=v?g.green("*"):" ",y=w.model?` - ${w.model}`:"";console.log(` ${k} ${u} (${w.provider})${y}`);}return}if(o==="use"){if(!l){let f=await e.listProfiles(),d=await e.getActiveProfileName(),u=await F(f,d);await e.useProfile(u),console.log(`${g.green("\u2714")} \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092 '${u}' \u306B\u8A2D\u5B9A\u3057\u307E\u3057\u305F`);return}if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
20
37
 
21
38
  \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 $=m===g,y=await r.getProfile(m),O=$?c.green("*"):" ",E=y.model?` - ${y.model}`:"";console.log(` ${O} ${m} (${y.provider})${E}`);}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
39
+ enja config use <profile>`);await e.useProfile(l),console.log(`${g.green("\u2714")} \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092 '${l}' \u306B\u8A2D\u5B9A\u3057\u307E\u3057\u305F`);return}if(o==="rm"||o==="delete"){if(!l){let f=await e.listProfiles(),d=await e.getActiveProfileName(),u=await F(f,d);if(!await K(u))return;await e.deleteProfile(u),console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${u}' \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);return}if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
23
40
 
24
41
  \u4F7F\u7528\u4F8B:
25
- enja config use <profile>`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
42
+ enja config rm <profile>`);if(!await K(l))return;await e.deleteProfile(l),console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${l}' \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);return}if(o==="add"){if(!l)throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
26
43
 
27
44
  \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
45
+ enja config add <profile> [options]`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
29
46
 
30
47
  \u4F7F\u7528\u4F8B:
31
- enja config rm <profile>`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
48
+ 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 e.addProfile(l,f),console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${l}' \u3092\u4F5C\u6210\u3057\u307E\u3057\u305F`);return}if(o==="rename"){if(!l)throw new Error(`\u5909\u66F4\u524D\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
32
49
 
33
50
  \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
51
+ enja config rename <oldProfile> <newProfile>`);if(!c)throw new Error(`\u65B0\u3057\u3044\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
35
52
 
36
53
  \u4F7F\u7528\u4F8B:
37
- enja config add <profile> [options]`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
54
+ enja config rename <oldProfile> <newProfile>`);if(s>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
38
55
 
39
56
  \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
57
+ enja config rename <oldProfile> <newProfile>`);await e.renameProfile(l,c),console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${l}' \u3092 '${c}' \u306B\u5909\u66F4\u3057\u307E\u3057\u305F`);return}if(o==="copy"){if(!l)throw new Error(`\u30B3\u30D4\u30FC\u5143\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
41
58
 
42
59
  \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
60
+ enja config copy <sourceProfile> <targetProfile>`);if(!c)throw new Error(`\u30B3\u30D4\u30FC\u5148\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044
44
61
 
45
62
  \u4F7F\u7528\u4F8B:
46
- enja config rename <oldProfile> <newProfile>`);if(s>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
63
+ enja config copy <sourceProfile> <targetProfile>`);if(s>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
47
64
 
48
65
  \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
66
+ enja config copy <sourceProfile> <targetProfile>`);await e.copyProfile(l,c),console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${l}' \u3092 '${c}' \u306B\u30B3\u30D4\u30FC\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
67
 
51
68
  \u4F7F\u7528\u4F8B:
52
69
  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
70
+ enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210`);let f=await e.getActiveProfileName(),d=await e.get();console.log(`${g.bold("Active Profile:")} ${f}`),console.log(`${g.blue("provider:")} ${d.provider}`),console.log(`${g.blue("endpoint:")} ${d.endpoint||"(not set)"}`),console.log(`${g.blue("apiKey:")} ${d.apiKey?q(d.apiKey):"(not set)"}`),console.log(`${g.blue("model:")} ${d.model||"(not set)"}`);return}if(o&&!l&&(n?.provider||n?.endpoint||n?.apiKey||n?.model)){let f=!1;n.provider&&(await e.setProfileConfig(o,"provider",n.provider),f=!0),n.endpoint&&(await e.setProfileConfig(o,"endpoint",n.endpoint),f=!0),n.apiKey&&(await e.setProfileConfig(o,"api-key",n.apiKey),f=!0),n.model&&(await e.setProfileConfig(o,"model",n.model),f=!0),f&&console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o}' \u306E\u8A2D\u5B9A\u3092\u66F4\u65B0\u3057\u307E\u3057\u305F`);return}if(o&&!l&&!n?.reset&&!n?.unset&&!n?.provider&&!n?.endpoint&&!n?.apiKey&&!n?.model){let f=await e.getProfile(o);console.log(`${g.bold("Profile:")} ${o}`),console.log(`${g.blue("provider:")} ${f.provider}`),console.log(`${g.blue("endpoint:")} ${f.endpoint||"(not set)"}`),console.log(`${g.blue("apiKey:")} ${f.apiKey?q(f.apiKey):"(not set)"}`),console.log(`${g.blue("model:")} ${f.model||"(not set)"}`);return}if(o&&n?.reset){await e.resetProfileConfig(o),console.log(`${g.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o}' \u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F`);return}if(o&&n?.unset){await e.unsetProfileConfig(o,n.unset),console.log(`${g.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
71
 
55
72
  \u4F7F\u7528\u4F8B:
56
73
  enja config \u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u8868\u793A
57
74
  enja config ls \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4E00\u89A7
58
75
  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
76
  enja config work --provider openai \u8A2D\u5B9A\u5909\u66F4
77
+ enja config use work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u5207\u308A\u66FF\u3048
61
78
  enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4F5C\u6210
62
79
  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 N=JSON.parse(readFileSync(new URL("../package.json",import.meta.url),"utf-8")),S=new Command;S.name("enja").usage("[arguments] [options]").description(N.description).version(N.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",`
80
+ enja config copy srcProfile destProfile \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u8907\u88FD
81
+ enja config rm profileName \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u524A\u9664
82
+ enja config work --reset \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30EA\u30BB\u30C3\u30C8
83
+ enja config work --unset api-key \u8A2D\u5B9A\u30EA\u30BB\u30C3\u30C8
84
+ `)}catch(p){p instanceof Error?console.error(`error: ${p.message}`):console.error(p),process.exit(1);}}function q(o){if(o.length<=8)return "*".repeat(o.length);let t=4,r=o.slice(0,t),e=o.slice(-t),i="*".repeat(o.length-t*2);return `${r}${i}${e}`}function S(o,t=false){return o.length===0?"\u5C65\u6B74\u306F\u3042\u308A\u307E\u305B\u3093":t?mt(o):ut(o)}function ut(o){let t=[`\u5168 ${o.length} \u4EF6\u306E\u5C65\u6B74
85
+ `];return o.forEach((r,e)=>{let i=rt(r.timestamp),a=ht(r),n=tt(r.sourceText,20),p=tt(r.translatedText||"",20),s=[g.cyan(`[${e+1}]`),r.id.substring(0,8),i,a||null].filter(Boolean).join(" | ");t.push(s),t.push(` ${r.sourceLang} \u2192 ${r.targetLang} | ${n} \u2192 ${p}`),t.push("");}),t.join(`
86
+ `)}function mt(o){let t=[`\u5168 ${o.length} \u4EF6\u306E\u5C65\u6B74\u306E\u8A73\u7D30
87
+ `];return o.forEach((r,e)=>{e>0&&t.push("\u2500".repeat(60));let i=14;if(t.push(`${g.cyan("ID:".padEnd(i))} ${r.id}`),t.push(`${g.cyan("Date:".padEnd(i))} ${rt(r.timestamp)}`),t.push(`${g.cyan("Direction:".padEnd(i))} ${r.sourceLang} \u2192 ${r.targetLang}`),t.push(`${g.cyan("InputLength:".padEnd(i))} ${r.textLength} characters`),t.push(`${g.cyan("OutputLength:".padEnd(i))} ${r.translatedText.length} characters`),r.profile&&t.push(`${g.cyan("Profile:".padEnd(i))} ${r.profile}`),r.provider&&t.push(`${g.cyan("Provider:".padEnd(i))} ${r.provider}`),r.model&&t.push(`${g.cyan("Model:".padEnd(i))} ${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&&t.push(`${g.cyan("Options:".padEnd(i))} ${a}`);}t.push("",`${g.cyan("Input:")}`,r.sourceText),t.push("",`${g.cyan("Output:")}`,r.translatedText||"","");}),t.join(`
88
+ `)}function rt(o){return new Date(o).toLocaleString("ja-JP")}function tt(o,t){let r=o.replace(/[\r\n]+/g," ");return r.length>t?`${r.substring(0,t)}...`:r}function ht(o){return [o.profile,o.provider,o.model].filter(t=>!!t).map(t=>g.magenta(t)).join(g.dim("\u30FB"))}var et=100,I=class{filePath;constructor(){this.filePath=Y();}ensureConfigDir(){let t=T();E.existsSync(t)||E.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 r=`${this.filePath}.tmp`,e=JSON.stringify(t,null,2);await promises.writeFile(r,e,"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(t){let r=await this.readHistory(),e={...t,id:randomUUID(),timestamp:new Date().toISOString()};r.unshift(e),r.length>et&&r.splice(et),await this.writeHistory(r);}async getAll(){return await this.readHistory()}async getRecent(t){return (await this.readHistory()).slice(0,t)}async deleteById(t){let r=await this.readHistory(),e=r.filter(i=>i.id!==t);return e.length===r.length?false:(await this.writeHistory(e),true)}async clear(){await this.writeHistory([]);}async findById(t){return (await this.readHistory()).find(e=>e.id===t)||null}async findByShortId(t){return (await this.readHistory()).filter(e=>e.id.startsWith(t))}async findByHash(t,r,e){return (await this.readHistory()).find(a=>a.sourceHash===t&&a.sourceLang===r&&a.targetLang===e)||null}};function ot(o){o.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(yt);}async function yt(o,t){try{let r=new I;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 l=await r.findById(n);if(!l)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${o})`);console.log(S([l],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 p=await r.findByShortId(n);if(p.length===0)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${o})`);let s=S(p,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 r.deleteById(n))console.log(`${g.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 p=await r.findByShortId(n);if(p.length===0)throw new Error(`\u6307\u5B9A\u3055\u308C\u305FID\u306E\u5C65\u6B74\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${n})`);if(p.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
89
+ ${S(p,!1)}`);let s=p[0].id;if(await r.deleteById(s))console.log(`${g.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 r.clear(),console.log(`${g.green("\u2714")} \u5C65\u6B74\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3057\u305F`);return}let e=Number(t.number)||10,i=await r.getRecent(e),a=S(i,t.detail);console.log(a);}catch(r){console.error(r instanceof Error?`error: ${r.message}`:r),process.exit(1);}}async function nt(o){let t=new h,r;if(o?.profile)try{r=await t.getProfile(o.profile);}catch{let p=await t.listProfiles();throw new Error(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${o.profile}' \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
90
+ \u5229\u7528\u53EF\u80FD\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${p.join(", ")}`)}else r=await t.get();let e=o?.provider||r.provider||"gas",i=o?.endpoint||r.endpoint,a=o?.apiKey||r.apiKey,n=o?.model||r.model;return {endpoint:i,provider:e,apiKey:a,model:n}}var Pt=new Set(["169.254.169.254"]);function Et(o){let t=o.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);if(!t)return null;let r=t.slice(1).map(e=>Number(e));return r.some(e=>!Number.isInteger(e)||e<0||e>255)?null:r}function vt(o,t,r){return o[0]===t&&o[1]===r}function $t(o){let[t,r]=o;return t===10||t===192&&r===168||t===172&&r>=16&&r<=31}function Tt(o){return o[0]===127}function Ct(o){return vt(o,169,254)}function xt(o){return o==="::1"||o==="0:0:0:0:0:0:0:1"}function At(o){return o.toLowerCase().startsWith("fe80:")}var Lt=new Set(["localhost","127.0.0.1","::1"]),jt=new Set(["10.","192.168."]);function D(o,t={}){let{allowLocalEndpoint:r=false,allowPrivateEndpoint:e=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;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");if(a.username||a.password)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u306B\u8A8D\u8A3C\u60C5\u5831\u3092\u57CB\u3081\u8FBC\u3080\u3053\u3068\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093");let p=a.hostname;if(Pt.has(p))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");let s=Et(p),l=s!==null,c=Lt.has(p)||(l?Tt(s):false)||xt(p);if((l?Ct(s):false)||At(p))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 d=l?$t(s):Array.from(jt).some(u=>p.startsWith(u));if(n==="http:"&&!(i||r&&c))throw new Error(`\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u306F https:// \u3067\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
91
+ 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
92
+ \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(c&&!r)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
93
+ \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(d&&!e)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
94
+ \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 it(o){let t=new h,r=await nt(o),e;o?.profile?e=o.profile:e=await t.getActiveProfileName();let i=o?.allowLocalEndpoint??false,a=o?.allowPrivateEndpoint??false,n=o?.allowHttp??false,p={allowLocalEndpoint:i,allowPrivateEndpoint:a,allowHttp:n};switch(r.provider){case "custom":{let{endpoint:s,apiKey:l,model:c}=r;if(!s)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u5FC5\u8981\u3067\u3059");return D(s,p),{translator:new C(s,l,c),config:r,activeProfile:e}}case "gas":{let{endpoint:s,apiKey:l}=r;if(!s)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u5FC5\u8981\u3067\u3059");return D(s,p),{translator:new x(s,l),config:r,activeProfile:e}}case "openai":{let{apiKey:s,model:l}=r;if(!s)throw new Error("OpenAI \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F API \u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new L(s,l),config:r,activeProfile:e}}case "gemini":{let{apiKey:s,model:l}=r;if(!s)throw new Error("Gemini \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F API \u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new A(s,l),config:r,activeProfile:e}}case "lmstudio":{let{endpoint:s}=r;if(o?.endpoint?(D(o.endpoint,p),s=o.endpoint):s?D(s,p):(s=P.DEFAULT_ENDPOINT,D(s,{allowLocalEndpoint:true,allowPrivateEndpoint:true,allowHttp:true})),!r.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 P(s,r.model,r.apiKey),config:r,activeProfile:e}}default:throw new Error(`\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${r.provider})`)}}function st(o){return createHash("sha256").update(o).digest("hex")}function at(o){o.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",`
64
95
  Examples:
65
- $ enja "Hello, world!" # \u5F15\u6570\u3067\u6E21\u3055\u308C\u305F\u6587\u5B57\u5217\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
67
- $ enja -f input.txt # \u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30C6\u30AD\u30B9\u30C8\u3092\u8AAD\u307F\u8FBC\u3093\u3067\u7FFB\u8A33
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
69
- $ cat README.md | enja -o japanese.md # \u30D1\u30A4\u30D7\u3068\u30D5\u30A1\u30A4\u30EB\u51FA\u529B\u306E\u7D44\u307F\u5408\u308F\u305B
70
- $ curl -s https://example.com | enja -s # HTML\u30BF\u30B0\u3092\u9664\u53BB\u3057\u3066\u7FFB\u8A33
71
- $ enja "Hello" -p work # work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F7F\u7528\u3057\u3066\u7FFB\u8A33
72
- $ enja "Hello, world!" --provider openai --api-key YOUR_OPENAI_API_KEY # OpenAI API \u3092\u4F7F\u7528\u3057\u3066\u7FFB\u8A33`).addHelpText("afterAll",`
73
- Enja CLI v${N.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
74
-
75
- Profiles:
76
- <profile> \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A73\u7D30\u3092\u8868\u793A
77
- <profile> [options] \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4
78
-
79
- Subcommands:
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",`
86
- --provider Names:
87
- gas, custom, openai, gemini, lmstudio
96
+ $ enja "Hello, world!" # \u6587\u5B57\u5217\u3092\u7FFB\u8A33
97
+ $ docker --help | enja # \u6A19\u6E96\u5165\u529B\u3092\u7FFB\u8A33
98
+ $ enja -f input.txt -o output.txt # \u30D5\u30A1\u30A4\u30EB\u5165\u51FA\u529B
99
+ $ enja "Hello" -p work # \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\u3057\u3066\u7FFB\u8A33
100
+ $ enja "Hello" --provider openai --api-key YOUR_API_KEY # \u4E00\u6642\u7684\u306B\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u3092\u6307\u5B9A\u3057\u3066\u7FFB\u8A33`).action(St);}async function St(o,t){try{if(!o&&!t.file&&!process.stdin.isTTY){let r=await kt();await G(r,t,"stdin");return}if(t.file){if(!E.existsSync(t.file))throw new Error(`\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t.file})`);let r=E.readFileSync(t.file,"utf-8");await G(r,t,"file");return}if(o){await G(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
88
101
 
89
- --unset Keys:
90
- provider, endpoint, api-key, model
91
-
92
- \u6CE8\u610F: --provider, --endpoint, --api-key, --model \u30AA\u30D7\u30B7\u30E7\u30F3\u306F
93
- \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u307E\u305F\u306F 'add' \u30B5\u30D6\u30B3\u30DE\u30F3\u30C9\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
94
- --unset, --reset \u306F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
95
-
96
- Examples:
97
- $ enja config \u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u8868\u793A
98
- $ enja config ls \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u4E00\u89A7
99
- $ enja config work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u8868\u793A
100
- $ enja config use work work \u3092\u30A2\u30AF\u30C6\u30A3\u30D6\u306B\u8A2D\u5B9A
101
- $ enja config work --provider openai work \u306E provider \u3092\u8A2D\u5B9A
102
- $ enja config work --provider openai --model gpt-4o \u8907\u6570\u8A2D\u5B9A\u3092\u540C\u6642\u5909\u66F4
103
- $ enja config add personal --provider gemini personal \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
104
- $ enja "Hello" -p work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3067\u7FFB\u8A33`).action(ot);S.parse();
102
+ \u4F7F\u7528\u4F8B:
103
+ enja "Hello, world!" # \u5F15\u6570\u3067\u6E21\u3055\u308C\u305F\u6587\u5B57\u5217\u3092\u7FFB\u8A33
104
+ enja -f input.txt # \u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30C6\u30AD\u30B9\u30C8\u3092\u8AAD\u307F\u8FBC\u3093\u3067\u7FFB\u8A33
105
+ cat README.md | enja # \u30D1\u30A4\u30D7(\u6A19\u6E96\u5165\u529B)\u3067\u6E21\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u7FFB\u8A33`)}catch(r){console.error(`error: ${Ht(r)}`),process.exit(1);}}async function G(o,t,r){if(!o||o.trim().length===0)throw new Error("\u7FFB\u8A33\u3059\u308B\u30C6\u30AD\u30B9\u30C8\u304C\u7A7A\u3067\u3059");let e=o;if(t.stripHtml&&(e=Rt(o),!e||e.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 it(t),p=new I,s=t.flip?"ja":"en",l=t.flip?"en":"ja",c=st(e),f=await p.findByHash(c,s,l);if(f&&t.cache!==false){console.log(`${g.green("\u2714")} \u30AD\u30E3\u30C3\u30B7\u30E5\u304B\u3089\u7FFB\u8A33\u7D50\u679C\u3092\u53D6\u5F97\u3057\u307E\u3057\u305F`);let y=f.translatedText;if(t.output)try{E.writeFileSync(t.output,y,"utf-8"),console.log(`${g.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(y);return}let d=`(${s} \u2192 ${l})`,u=i.getModel()||a.model,v=n||"unknown",w=`[${v} | ${a.provider}${u?` | ${u}`:""}]`,k=Dt(`\u7FFB\u8A33\u4E2D... ${d} ${w}`).start();try{let U=(await i.translate(e,s,l)).text;if(k.succeed(`\u7FFB\u8A33\u5B8C\u4E86 ${d} ${w}`),await p.add({sourceText:e,translatedText:U,sourceLang:s,targetLang:l,textLength:e.length,sourceHash:c,profile:v,provider:a.provider,model:u,options:{stripHtml:t.stripHtml,file:t.file,inputMethod:r}}),t.output)try{E.writeFileSync(t.output,U,"utf-8"),console.log(`${g.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(U);}catch(y){throw k.fail(`\u7FFB\u8A33\u5931\u6557 ${d} ${w}`),y}}function Ht(o){if(o instanceof Error)return o.message;try{return String(o)}catch{return "Unknown error"}}function kt(){return new Promise((o,t)=>{let r="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",e=>{r+=e;}),process.stdin.on("end",()=>{o(r);}),process.stdin.on("error",e=>{t(e);});})}function Rt(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,`
106
+ `).trim()}var V=JSON.parse(readFileSync(new URL("../package.json",import.meta.url),"utf-8")),H=new Command;H.name("enja").usage("[arguments] [options]").description(V.description).version(V.version,"-v, --version","output the current version").addHelpText("afterAll",`
107
+ Enja CLI v${V.version}`).addHelpText("afterAll","Copyright (c) 2025-2026 yhotta240").addHelpText("afterAll","GitHub: https://github.com/yhotamos/enja-cli");at(H);ot(H);Q(H);H.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yhotamos/enja-cli",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "英語を日本語に翻訳するシンプルなコマンドラインツール",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,10 +11,10 @@
11
11
  "enja": "dist/index.js"
12
12
  },
13
13
  "scripts": {
14
- "lint": "eslint src",
15
- "lint:fix": "eslint src --fix",
14
+ "check": "biome check src",
15
+ "check:fix": "biome check --write --unsafe src",
16
16
  "typecheck": "tsc --noEmit",
17
- "build": "npm run lint && npm run typecheck && tsup",
17
+ "build": "npm run check && npm run typecheck && tsup",
18
18
  "build:dev": "tsup --sourcemap",
19
19
  "watch": "tsup --watch",
20
20
  "test": "vitest"
@@ -44,19 +44,19 @@
44
44
  "homepage": "https://github.com/yhotamos/enja-cli#readme",
45
45
  "dependencies": {
46
46
  "@google/genai": "^1.33.0",
47
+ "@inquirer/prompts": "^8.3.2",
47
48
  "commander": "^14.0.2",
48
49
  "kleur": "^4.1.5",
49
50
  "openai": "^6.9.1",
50
51
  "ora": "^9.0.0"
51
52
  },
52
53
  "devDependencies": {
54
+ "@biomejs/biome": "^2.4.10",
53
55
  "@types/node": "^24.10.1",
54
56
  "dotenv": "^17.3.1",
55
- "eslint": "^10.0.2",
56
57
  "tsup": "^8.5.1",
57
58
  "tsx": "^4.20.6",
58
59
  "typescript": "^5.9.3",
59
- "typescript-eslint": "^8.56.1",
60
60
  "vitest": "^4.0.18"
61
61
  }
62
62
  }