@yhotamos/enja-cli 1.4.3 → 1.5.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 (4) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +102 -102
  3. package/dist/index.js +29 -29
  4. package/package.json +62 -62
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 yhotta240
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 yhotta240
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,102 +1,102 @@
1
- # Enja CLI
2
-
3
- ![NPM Version](https://img.shields.io/npm/v/%40yhotamos%2Fenja-cli)
4
- ![NPM Downloads](https://img.shields.io/npm/dm/%40yhotamos%2Fenja-cli)
5
- ![NPM License](https://img.shields.io/npm/l/%40yhotamos%2Fenja-cli)
6
-
7
- 英語を日本語に翻訳するシンプルなコマンドラインツール
8
-
9
- ## 特徴
10
-
11
- - セットアップ不要で,インストール後すぐに利用可能
12
- - Google Apps Script の LanguageApp を使用した軽量な翻訳
13
- - 引数,標準入力(パイプ),ファイル入力に幅広く対応
14
- - HTML タグを除去して Web コンテンツもそのまま翻訳
15
- - OpenAI, Gemini, LM Studio などの各種 API による高品質な翻訳
16
- - 英日・日英の翻訳方向の切り替えが可能
17
- - 翻訳履歴の保存やプロファイル機能による複数 API の切り替えが可能
18
-
19
- ## インストール
20
-
21
- ```bash
22
- npm install -g @yhotamos/enja-cli
23
- ```
24
-
25
- ## 使い方
26
-
27
- ### 基本的な使い方
28
-
29
- ```bash
30
- # 引数で渡された文字列を翻訳
31
- enja "Hello, world!"
32
-
33
- # パイプで翻訳
34
- echo "Hello, world!" | enja
35
-
36
- # ファイルから読み込み
37
- enja -f input.txt -o output.txt
38
-
39
- # 翻訳方向を逆にする (日本語 → 英語)
40
- enja "こんにちは" -F
41
-
42
- # OpenAI API を一時的に使用して翻訳
43
- enja "Hello, world!" --provider openai --api-key YOUR_OPENAI_API_KEY
44
- ```
45
-
46
- ### 履歴と設定
47
-
48
- ```bash
49
- # 翻訳履歴を表示
50
- enja history
51
-
52
- # 設定を表示/追加/アクティブ化
53
- enja config
54
- enja config add work --provider gemini --api-key YOUR_GEMINI_API_KEY --model gemini-2.5-flash
55
- enja config use work
56
- ```
57
-
58
- ### 実用例
59
-
60
- ```bash
61
- # エラーメッセージの翻訳
62
- npm install nonexistent-package 2>&1 | enja
63
-
64
- # コマンドのヘルプを日本語化
65
- docker --help | enja
66
-
67
- # 英語で書かれたドキュメントを日本語に翻訳
68
- enja -f README.md -o README.ja.md
69
-
70
- # Webページの本文を翻訳(HTMLタグ除去)
71
- curl -s https://example.com | enja -s
72
-
73
- # APIドキュメントなどテキストコンテンツの翻訳
74
- curl -s https://example.com/api/docs | enja
75
- ```
76
-
77
- ## コマンド
78
-
79
- [COMMANDS.md](docs/COMMANDS.md) を参照してください.
80
-
81
- ## セキュリティとプライバシー
82
-
83
- ### デフォルトプロバイダー(GAS)使用時
84
-
85
- - 翻訳データは保存されません(その場で処理され,すぐに結果が返ります)
86
- - 公開エンドポイントを使用しているため,機密情報の翻訳は避けてください
87
-
88
- ### その他のプロバイダー使用時
89
-
90
- OpenAI,Gemini,LM Studio などを使用する場合は,各サービスのプライバシーポリシーに従います.
91
- プロバイダーによっては,入力データが保存されたり,学習に利用されることがありますので,注意してください.
92
-
93
- ## 貢献
94
-
95
- バグ報告や機能リクエストは [GitHub Issues](https://github.com/yhotamos/enja-cli/issues) へお願いします.
96
-
97
- ## 作者
98
-
99
- yhotta240
100
-
101
- - Email: yhotta240@gmail.com
102
- - GitHub: [@yhotta240](https://github.com/yhotta240)
1
+ # Enja CLI
2
+
3
+ ![NPM Version](https://img.shields.io/npm/v/%40yhotamos%2Fenja-cli)
4
+ ![NPM Downloads](https://img.shields.io/npm/dm/%40yhotamos%2Fenja-cli)
5
+ ![NPM License](https://img.shields.io/npm/l/%40yhotamos%2Fenja-cli)
6
+
7
+ 英語を日本語に翻訳するシンプルなコマンドラインツール
8
+
9
+ ## 特徴
10
+
11
+ - セットアップ不要で,インストール後すぐに利用可能
12
+ - Google Apps Script の LanguageApp を使用した軽量な翻訳
13
+ - 引数,標準入力(パイプ),ファイル入力に幅広く対応
14
+ - HTML タグを除去して Web コンテンツもそのまま翻訳
15
+ - OpenAI, Gemini, LM Studio などの各種 API による高品質な翻訳
16
+ - 英日・日英の翻訳方向の切り替えが可能
17
+ - 翻訳履歴の保存やプロファイル機能による複数 API の切り替えが可能
18
+
19
+ ## インストール
20
+
21
+ ```bash
22
+ npm install -g @yhotamos/enja-cli
23
+ ```
24
+
25
+ ## 使い方
26
+
27
+ ### 基本的な使い方
28
+
29
+ ```bash
30
+ # 引数で渡された文字列を翻訳
31
+ enja "Hello, world!"
32
+
33
+ # パイプで翻訳
34
+ echo "Hello, world!" | enja
35
+
36
+ # ファイルから読み込み
37
+ enja -f input.txt -o output.txt
38
+
39
+ # 翻訳方向を逆にする (日本語 → 英語)
40
+ enja "こんにちは" -F
41
+
42
+ # OpenAI API を一時的に使用して翻訳
43
+ enja "Hello, world!" --provider openai --api-key YOUR_OPENAI_API_KEY
44
+ ```
45
+
46
+ ### 履歴と設定
47
+
48
+ ```bash
49
+ # 翻訳履歴を表示
50
+ enja history
51
+
52
+ # 設定を表示/追加/アクティブ化
53
+ enja config
54
+ enja config add work --provider gemini --api-key YOUR_GEMINI_API_KEY --model gemini-2.5-flash
55
+ enja config use work
56
+ ```
57
+
58
+ ### 実用例
59
+
60
+ ```bash
61
+ # エラーメッセージの翻訳
62
+ npm install nonexistent-package 2>&1 | enja
63
+
64
+ # コマンドのヘルプを日本語化
65
+ docker --help | enja
66
+
67
+ # 英語で書かれたドキュメントを日本語に翻訳
68
+ enja -f README.md -o README.ja.md
69
+
70
+ # Webページの本文を翻訳(HTMLタグ除去)
71
+ curl -s https://example.com | enja -s
72
+
73
+ # APIドキュメントなどテキストコンテンツの翻訳
74
+ curl -s https://example.com/api/docs | enja
75
+ ```
76
+
77
+ ## コマンド
78
+
79
+ [COMMANDS.md](docs/COMMANDS.md) を参照してください.
80
+
81
+ ## セキュリティとプライバシー
82
+
83
+ ### デフォルトプロバイダー(GAS)使用時
84
+
85
+ - 翻訳データは保存されません(その場で処理され,すぐに結果が返ります)
86
+ - 公開エンドポイントを使用しているため,機密情報の翻訳は避けてください
87
+
88
+ ### その他のプロバイダー使用時
89
+
90
+ OpenAI,Gemini,LM Studio などを使用する場合は,各サービスのプライバシーポリシーに従います.
91
+ プロバイダーによっては,入力データが保存されたり,学習に利用されることがありますので,注意してください.
92
+
93
+ ## 貢献
94
+
95
+ バグ報告や機能リクエストは [GitHub Issues](https://github.com/yhotamos/enja-cli/issues) へお願いします.
96
+
97
+ ## 作者
98
+
99
+ yhotta240
100
+
101
+ - Email: yhotta240@gmail.com
102
+ - GitHub: [@yhotta240](https://github.com/yhotta240)
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
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
2
+ import*as v from'fs';import {readFileSync,promises}from'fs';import {Command}from'commander';import d from'kleur';import {select,confirm}from'@inquirer/prompts';import*as K from'os';import*as T from'path';import {GoogleGenAI,ApiError}from'@google/genai';import X from'openai';import {randomUUID,createHash}from'crypto';import Ot from'ora';async function N(o,t){let r=o.map(e=>({name:e===t?d.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 _(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 C(){if(process.platform==="win32"){let r=process.env.APPDATA||T.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 T.join(r,"enja-cli")}let t=K.homedir();return T.join(t,".config","enja-cli")}function z(){return T.join(C(),"history.json")}function W(){return T.join(C(),"config.json")}var x=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 s=await fetch(this.apiUrl,{method:"POST",headers:i,body:JSON.stringify({text:t,sourceLang:r,targetLang:e,...this.model?{model:this.model}:{}})}),n=await s.text();if(!s.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 ${s.status} ${s.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 a=this.extractText(p);if(a)return {text:a.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 A=class o{static DEFAULT_ENDPOINT="https://script.google.com/macros/s/YOUR_SCRIPT_ID/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 s=await fetch(this.apiUrl,{method:"POST",headers:i,body:JSON.stringify({text:t,sourceLang:r,targetLang:e})});if(!s.ok)throw new Error(`HTTP ${s.status} ${s.statusText}`);let n=await s.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 L=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),s=this.mapLanguageCode(e),n=`You are a professional translator. Translate the following text from ${i} to ${s}. Only return the translated text without any additional explanation or comments.`,a=(await this.client.models.generateContent({model:this.model,contents:t,config:{systemInstruction:n}})).text;if(!a)throw new Error("\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return {text:a.trim(),detectedSourceLang:r}}catch(i){if(i instanceof ApiError){let s=JSON.parse(i.message).error.message;throw new Error(`Gemini\u7FFB\u8A33API\u30A8\u30E9\u30FC: ${s}`)}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.`,s=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}),a=await fetch(s.toString(),{method:"POST",headers:n,body:p}),l=await a.text(),c=this.parseJsonSafe(l,a);if(!a.ok){if(c?.error){if(typeof c.error=="string")throw new Error(`LMStudio: ${c.error}`);let{message:g,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 $=g||"LMStudio: \u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F";throw new Error($)}throw new Error(`LMStudio: HTTP ${a.status} ${a.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 E=class o{static PROVIDER_NAME="ollama";static DEFAULT_ENDPOINT="http://localhost:11434";static DEFAULT_MODEL="gpt-oss:120b-cloud";static getDefaultProfile(){return {provider:o.PROVIDER_NAME,endpoint:o.DEFAULT_ENDPOINT,model:o.DEFAULT_MODEL}}baseUrl;model;apiKey;constructor(t,r,e){this.baseUrl=t||o.DEFAULT_ENDPOINT,this.model=r||o.DEFAULT_MODEL,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 or comments.`,s=this.baseUrl.endsWith("/api/generate")?this.baseUrl:`${this.baseUrl}/api/generate`,n={"Content-Type":"application/json",Accept:"application/json",...this.apiKey?{Authorization:`Bearer ${this.apiKey}`}:{}},p=JSON.stringify({model:this.model,prompt:t,system:i,stream:false}),a=await fetch(s,{method:"POST",headers:n,body:p});if(!a.ok){let f=await a.json();throw new Error(`Ollama HTTP ${a.status} ${a.statusText}: ${f.error}`)}let c=(await a.json()).response;if(!c)throw new Error("Ollama: \u5FDC\u7B54\u304B\u3089\u7FFB\u8A33\u30C6\u30AD\u30B9\u30C8\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F");return {text:String(c).trim(),detectedSourceLang:r}}};var D=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 X({apiKey:t}),this.model=r;}getModel(){return this.model}async translate(t,r,e){try{let i=this.mapLanguageCode(r),s=this.mapLanguageCode(e),n=`You are a professional translator. Translate the following text from ${i} to ${s}. Only return the translated text without any additional explanation or comments.`,a=(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(!a)throw new Error("\u7FFB\u8A33\u306B\u5931\u6557\u3057\u307E\u3057\u305F");return {text:a.trim(),detectedSourceLang:r}}catch(i){throw i instanceof X.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 Z=["ls","list","use","rm","delete","add","rename","copy","provider","endpoint","api-key","model","default"];function k(o){if(Z.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 U="gas",I={gas:A.getDefaultProfile,openai:D.getDefaultProfile,gemini:L.getDefaultProfile,lmstudio:P.getDefaultProfile,ollama:E.getDefaultProfile,custom:x.getDefaultProfile},q={version:"1.1",activeProfile:"default",profiles:{default:I[U]()}},h=class o{filePath;constructor(){this.filePath=W();}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(k(t),r?.provider&&!this.isTranslatorProvider(r.provider)){let p=Object.keys(I).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||U,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;k(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");k(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 s=i.profiles[t];switch(r){case "endpoint":s.endpoint=e;break;case "api-key":s.apiKey=e;break;case "provider":if(!this.isTranslatorProvider(e)){let n=Object.keys(I).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`)}s.provider=e;break;case "model":s.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],s=i.provider||U,n=this.getDefaultProfileByProvider(s);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 I[U]()}getDefaultProfileByProvider(t){return I[t]()}isTranslatorProvider(t){return t in I}async ensureConfigDir(){let t=C();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:{...q}}catch{return {...q}}}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 tt(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
4
 
5
- Profiles:
5
+ Profile:
6
6
  <profile> \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A73\u7D30\u3092\u8868\u793A
7
7
  <profile> [options] \u6307\u5B9A\u3057\u305F\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4
8
8
 
@@ -12,9 +12,9 @@ Subcommands:
12
12
  add <profile> [options] \u65B0\u3057\u3044\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
13
13
  rename <old> <new> \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u5909\u66F4
14
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",`
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").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
16
  --provider Names:
17
- gas, custom, openai, gemini, lmstudio
17
+ gas, openai, gemini, lmstudio, ollama, custom
18
18
 
19
19
  --unset Keys:
20
20
  provider, endpoint, api-key, model
@@ -30,44 +30,44 @@ Examples:
30
30
  $ enja config use work work \u3092\u30A2\u30AF\u30C6\u30A3\u30D6\u306B\u8A2D\u5B9A
31
31
  $ enja config add personal personal \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
32
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
33
+ $ enja "Hello" -p work work \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3067\u7FFB\u8A33`).action(mt);}async function mt(o,t,r){let e=new h,i=r?.opts()||{},n={...r?.parent?.opts()||{},...i};try{let p=r?.args??[],a=p.length,[,l,c]=p;if(o==="ls"||o==="list"){if(a>1)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
34
34
 
35
35
  \u4F7F\u7528\u4F8B:
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
36
+ enja config ls`);let f=await e.listProfiles(),g=await e.getActiveProfileName();console.log(d.bold("Profiles:"));for(let u of f){let $=u===g,w=await e.getProfile(u),H=$?d.green("*"):" ",y=w.model?` - ${w.model}`:"";console.log(` ${H} ${u} (${w.provider})${y}`);}return}if(o==="use"){if(!l){let f=await e.listProfiles(),g=await e.getActiveProfileName(),u=await N(f,g);await e.useProfile(u),console.log(`${d.green("\u2714")} \u30A2\u30AF\u30C6\u30A3\u30D6\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092 '${u}' \u306B\u8A2D\u5B9A\u3057\u307E\u3057\u305F`);return}if(a>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
37
37
 
38
38
  \u4F7F\u7528\u4F8B:
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
39
+ enja config use <profile>`);await e.useProfile(l),console.log(`${d.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(),g=await e.getActiveProfileName(),u=await N(f,g);if(!await _(u))return;await e.deleteProfile(u),console.log(`${d.green("\u2714")} \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB '${u}' \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);return}if(a>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
40
40
 
41
41
  \u4F7F\u7528\u4F8B:
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
42
+ enja config rm <profile>`);if(!await _(l))return;await e.deleteProfile(l),console.log(`${d.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
43
43
 
44
44
  \u4F7F\u7528\u4F8B:
45
- enja config add <profile> [options]`);if(s>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
45
+ enja config add <profile> [options]`);if(a>2)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
46
46
 
47
47
  \u4F7F\u7528\u4F8B:
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
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(`${d.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
49
49
 
50
50
  \u4F7F\u7528\u4F8B:
51
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
52
52
 
53
53
  \u4F7F\u7528\u4F8B:
54
- enja config rename <oldProfile> <newProfile>`);if(s>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
54
+ enja config rename <oldProfile> <newProfile>`);if(a>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
55
55
 
56
56
  \u4F7F\u7528\u4F8B:
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
57
+ enja config rename <oldProfile> <newProfile>`);await e.renameProfile(l,c),console.log(`${d.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
58
58
 
59
59
  \u4F7F\u7528\u4F8B:
60
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
61
61
 
62
62
  \u4F7F\u7528\u4F8B:
63
- enja config copy <sourceProfile> <targetProfile>`);if(s>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
63
+ enja config copy <sourceProfile> <targetProfile>`);if(a>3)throw new Error(`\u5F15\u6570\u304C\u591A\u3059\u304E\u307E\u3059
64
64
 
65
65
  \u4F7F\u7528\u4F8B:
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
66
+ enja config copy <sourceProfile> <targetProfile>`);await e.copyProfile(l,c),console.log(`${d.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
67
67
 
68
68
  \u4F7F\u7528\u4F8B:
69
69
  enja config work --provider openai \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306E\u8A2D\u5B9A\u3092\u5909\u66F4
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
70
+ enja config add personal --provider gemini \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210`);let f=await e.getActiveProfileName(),g=await e.get();console.log(`${d.bold("Active Profile:")} ${f}`),console.log(`${d.blue("provider:")} ${g.provider}`),console.log(`${d.blue("endpoint:")} ${g.endpoint||"(not set)"}`),console.log(`${d.blue("apiKey:")} ${g.apiKey?Q(g.apiKey):"(not set)"}`),console.log(`${d.blue("model:")} ${g.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(`${d.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(`${d.bold("Profile:")} ${o}`),console.log(`${d.blue("provider:")} ${f.provider}`),console.log(`${d.blue("endpoint:")} ${f.endpoint||"(not set)"}`),console.log(`${d.blue("apiKey:")} ${f.apiKey?Q(f.apiKey):"(not set)"}`),console.log(`${d.blue("model:")} ${f.model||"(not set)"}`);return}if(o&&n?.reset){await e.resetProfileConfig(o),console.log(`${d.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(`${d.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
71
71
 
72
72
  \u4F7F\u7528\u4F8B:
73
73
  enja config \u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u8868\u793A
@@ -81,27 +81,27 @@ Examples:
81
81
  enja config rm profileName \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u524A\u9664
82
82
  enja config work --reset \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30EA\u30BB\u30C3\u30C8
83
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
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 O(o,t=false){return o.length===0?"\u5C65\u6B74\u306F\u3042\u308A\u307E\u305B\u3093":t?wt(o):ht(o)}function ht(o){let t=[`\u5168 ${o.length} \u4EF6\u306E\u5C65\u6B74
85
+ `];return o.forEach((r,e)=>{let i=et(r.timestamp),s=yt(r),n=rt(r.sourceText,20),p=rt(r.translatedText||"",20),a=[d.cyan(`[${e+1}]`),r.id.substring(0,8),i,s||null].filter(Boolean).join(" | ");t.push(a),t.push(` ${r.sourceLang} \u2192 ${r.targetLang} | ${n} \u2192 ${p}`),t.push("");}),t.join(`
86
+ `)}function wt(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(`${d.cyan("ID:".padEnd(i))} ${r.id}`),t.push(`${d.cyan("Date:".padEnd(i))} ${et(r.timestamp)}`),t.push(`${d.cyan("Direction:".padEnd(i))} ${r.sourceLang} \u2192 ${r.targetLang}`),t.push(`${d.cyan("InputLength:".padEnd(i))} ${r.textLength} characters`),t.push(`${d.cyan("OutputLength:".padEnd(i))} ${r.translatedText.length} characters`),r.profile&&t.push(`${d.cyan("Profile:".padEnd(i))} ${r.profile}`),r.provider&&t.push(`${d.cyan("Provider:".padEnd(i))} ${r.provider}`),r.model&&t.push(`${d.cyan("Model:".padEnd(i))} ${r.model}`),r.options){let s=[r.options.inputMethod&&`input=${r.options.inputMethod}`,r.options.stripHtml&&"stripHtml=true",r.options.file&&`file=${r.options.file}`].filter(Boolean).join(", ");s&&t.push(`${d.cyan("Options:".padEnd(i))} ${s}`);}t.push("",`${d.cyan("Input:")}`,r.sourceText),t.push("",`${d.cyan("Output:")}`,r.translatedText||"","");}),t.join(`
88
+ `)}function et(o){return new Date(o).toLocaleString("ja-JP")}function rt(o,t){let r=o.replace(/[\r\n]+/g," ");return r.length>t?`${r.substring(0,t)}...`:r}function yt(o){return [o.profile,o.provider,o.model].filter(t=>!!t).map(t=>d.magenta(t)).join(d.dim("\u30FB"))}var ot=100,j=class{filePath;constructor(){this.filePath=z();}ensureConfigDir(){let t=C();v.existsSync(t)||v.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>ot&&r.splice(ot),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(s=>s.sourceHash===t&&s.sourceLang===r&&s.targetLang===e)||null}};function nt(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(Et);}async function Et(o,t){try{let r=new j;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(O([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 a=O(p,t.detail);console.log(a);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(`${d.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
+ ${O(p,!1)}`);let a=p[0].id;if(await r.deleteById(a))console.log(`${d.green("\u2714")} \u5C65\u6B74ID ${a} \u3092\u524A\u9664\u3057\u307E\u3057\u305F`);else throw new Error(`\u524A\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F (${a})`);return}if(t.clear){await r.clear(),console.log(`${d.green("\u2714")} \u5C65\u6B74\u3092\u30AF\u30EA\u30A2\u3057\u307E\u3057\u305F`);return}let e=Number(t.number)||10,i=await r.getRecent(e),s=O(i,t.detail);console.log(s);}catch(r){console.error(r instanceof Error?`error: ${r.message}`:r),process.exit(1);}}async function it(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,s=o?.apiKey||r.apiKey,n=o?.model||r.model;return {endpoint:i,provider:e,apiKey:s,model:n}}var vt=new Set(["169.254.169.254"]);function $t(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 Tt(o,t,r){return o[0]===t&&o[1]===r}function Ct(o){let[t,r]=o;return t===10||t===192&&r===168||t===172&&r>=16&&r<=31}function xt(o){return o[0]===127}function At(o){return Tt(o,169,254)}function Lt(o){return o==="::1"||o==="0:0:0:0:0:0:0:1"}function Dt(o){return o.toLowerCase().startsWith("fe80:")}var It=new Set(["localhost","127.0.0.1","::1"]),jt=new Set(["10.","192.168."]);function S(o,t={}){let{allowLocalEndpoint:r=false,allowPrivateEndpoint:e=false,allowHttp:i=false}=t,s;try{s=new URL(o);}catch{throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u4E0D\u6B63\u3067\u3059")}let n=s.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(s.username||s.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=s.hostname;if(vt.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 a=$t(p),l=a!==null,c=It.has(p)||(l?xt(a):false)||Lt(p);if((l?At(a):false)||Dt(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 g=l?Ct(a):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
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
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",`
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(g&&!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}function st({defaultUrl:o,configUrl:t,optionUrl:r,validateOpts:e}){return r?(S(r,e),r):t?(S(t,e),t):(S(o,{allowLocalEndpoint:true,allowPrivateEndpoint:true,allowHttp:true}),o)}async function at(o){let t=new h,r=await it(o),e;o?.profile?e=o.profile:e=await t.getActiveProfileName();let i=o?.allowLocalEndpoint??false,s=o?.allowPrivateEndpoint??false,n=o?.allowHttp??false,p={allowLocalEndpoint:i,allowPrivateEndpoint:s,allowHttp:n},{provider:a,endpoint:l,apiKey:c,model:f}=r;switch(a){case "custom":{if(!l)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u5FC5\u8981\u3067\u3059");return S(l,p),{translator:new x(l,c,f),config:r,activeProfile:e}}case "gas":{if(!l)throw new Error("\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 URL \u304C\u5FC5\u8981\u3067\u3059");return S(l,p),{translator:new A(l,c),config:r,activeProfile:e}}case "openai":{if(!c)throw new Error("OpenAI \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F API \u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new D(c,f),config:r,activeProfile:e}}case "gemini":{if(!c)throw new Error("Gemini \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F API \u30AD\u30FC\u304C\u5FC5\u8981\u3067\u3059");return {translator:new L(c,f),config:r,activeProfile:e}}case "lmstudio":{if(!f)throw new Error("LM Studio \u3092\u4F7F\u7528\u3059\u308B\u306B\u306F\u30E2\u30C7\u30EB\u540D\u304C\u5FC5\u8981\u3067\u3059");let g=st({defaultUrl:P.DEFAULT_ENDPOINT,configUrl:l,optionUrl:o?.endpoint,validateOpts:p});return {translator:new P(g,f,c),config:r,activeProfile:e}}case "ollama":{let g=st({defaultUrl:E.DEFAULT_ENDPOINT,configUrl:l,optionUrl:o?.endpoint,validateOpts:p});return {translator:new E(g,f,c),config:r,activeProfile:e}}default:throw new Error(`\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC (${a}) \u3067\u3059`)}}function lt(o){return createHash("sha256").update(o).digest("hex")}function pt(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\uFF08\u73FE\u5728\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u9069\u7528\uFF09").option("--model <name>","\u4E00\u6642\u7684\u306B\u4F7F\u7528\u3059\u308B\u30E2\u30C7\u30EB\u540D\u3092\u6307\u5B9A\uFF08\u73FE\u5728\u306E\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u306B\u9069\u7528\uFF09").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",`
95
95
  Examples:
96
96
  $ enja "Hello, world!" # \u6587\u5B57\u5217\u3092\u7FFB\u8A33
97
97
  $ docker --help | enja # \u6A19\u6E96\u5165\u529B\u3092\u7FFB\u8A33
98
98
  $ enja -f input.txt -o output.txt # \u30D5\u30A1\u30A4\u30EB\u5165\u51FA\u529B
99
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
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(Rt);}async function Rt(o,t){try{if(!o&&!t.file&&!process.stdin.isTTY){let r=await kt();await V(r,t,"stdin");return}if(t.file){if(!v.existsSync(t.file))throw new Error(`\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 (${t.file})`);let r=v.readFileSync(t.file,"utf-8");await V(r,t,"file");return}if(o){await V(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
101
101
 
102
102
  \u4F7F\u7528\u4F8B:
103
103
  enja "Hello, world!" # \u5F15\u6570\u3067\u6E21\u3055\u308C\u305F\u6587\u5B57\u5217\u3092\u7FFB\u8A33
104
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();
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 V(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=bt(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:s,activeProfile:n}=await at(t),p=new j,a=t.flip?"ja":"en",l=t.flip?"en":"ja",c=lt(e),f=await p.findByHash(c,a,l);if(f&&t.cache!==false){console.log(`${d.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{v.writeFileSync(t.output,y,"utf-8"),console.log(`${d.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 g=`(${a} \u2192 ${l})`,u=i.getModel()||s.model,$=n||"unknown",w=`[${$} | ${s.provider}${u?` | ${u}`:""}]`,H=Ot(`\u7FFB\u8A33\u4E2D... ${g} ${w}`).start();try{let F=(await i.translate(e,a,l)).text;if(H.succeed(`\u7FFB\u8A33\u5B8C\u4E86 ${g} ${w}`),await p.add({sourceText:e,translatedText:F,sourceLang:a,targetLang:l,textLength:e.length,sourceHash:c,profile:$,provider:s.provider,model:u,options:{stripHtml:t.stripHtml,file:t.file,inputMethod:r}}),t.output)try{v.writeFileSync(t.output,F,"utf-8"),console.log(`${d.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(F);}catch(y){throw H.fail(`\u7FFB\u8A33\u5931\u6557 ${g} ${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 bt(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 Y=JSON.parse(readFileSync(new URL("../package.json",import.meta.url),"utf-8")),R=new Command;R.name("enja").usage("[arguments] [options]").description(Y.description).version(Y.version,"-v, --version","output the current version").addHelpText("afterAll",`
107
+ Enja CLI v${Y.version}`).addHelpText("afterAll","Copyright (c) 2025-2026 yhotta240").addHelpText("afterAll","GitHub: https://github.com/yhotamos/enja-cli");pt(R);nt(R);tt(R);R.parse();
package/package.json CHANGED
@@ -1,62 +1,62 @@
1
- {
2
- "name": "@yhotamos/enja-cli",
3
- "version": "1.4.3",
4
- "description": "英語を日本語に翻訳するシンプルなコマンドラインツール",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "files": [
8
- "dist"
9
- ],
10
- "bin": {
11
- "enja": "dist/index.js"
12
- },
13
- "scripts": {
14
- "check": "biome check src",
15
- "check:fix": "biome check --write --unsafe src",
16
- "typecheck": "tsc --noEmit",
17
- "build": "npm run check && npm run typecheck && tsup",
18
- "build:dev": "tsup --sourcemap",
19
- "watch": "tsup --watch",
20
- "test": "vitest"
21
- },
22
- "keywords": [
23
- "translation",
24
- "cli",
25
- "english",
26
- "japanese",
27
- "enja"
28
- ],
29
- "publishConfig": {
30
- "access": "public"
31
- },
32
- "author": "yhotta240 <yhotta240@gmail.com> (https://github.com/yhotta240)",
33
- "engines": {
34
- "node": ">=18"
35
- },
36
- "license": "MIT",
37
- "repository": {
38
- "type": "git",
39
- "url": "git+https://github.com/yhotamos/enja-cli.git"
40
- },
41
- "bugs": {
42
- "url": "https://github.com/yhotamos/enja-cli/issues"
43
- },
44
- "homepage": "https://github.com/yhotamos/enja-cli#readme",
45
- "dependencies": {
46
- "@google/genai": "^1.33.0",
47
- "@inquirer/prompts": "^8.3.2",
48
- "commander": "^14.0.2",
49
- "kleur": "^4.1.5",
50
- "openai": "^6.9.1",
51
- "ora": "^9.0.0"
52
- },
53
- "devDependencies": {
54
- "@biomejs/biome": "^2.4.10",
55
- "@types/node": "^24.10.1",
56
- "dotenv": "^17.3.1",
57
- "tsup": "^8.5.1",
58
- "tsx": "^4.20.6",
59
- "typescript": "^5.9.3",
60
- "vitest": "^4.0.18"
61
- }
62
- }
1
+ {
2
+ "name": "@yhotamos/enja-cli",
3
+ "version": "1.5.3",
4
+ "description": "英語を日本語に翻訳するシンプルなコマンドラインツール",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "bin": {
11
+ "enja": "dist/index.js"
12
+ },
13
+ "scripts": {
14
+ "check": "biome check src",
15
+ "check:fix": "biome check --write --unsafe src",
16
+ "typecheck": "tsc --noEmit",
17
+ "build": "npm run check && npm run typecheck && tsup",
18
+ "build:dev": "tsup --sourcemap",
19
+ "watch": "tsup --watch",
20
+ "test": "vitest"
21
+ },
22
+ "keywords": [
23
+ "translation",
24
+ "cli",
25
+ "english",
26
+ "japanese",
27
+ "enja"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "author": "yhotta240 <yhotta240@gmail.com> (https://github.com/yhotta240)",
33
+ "engines": {
34
+ "node": ">=18"
35
+ },
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/yhotamos/enja-cli.git"
40
+ },
41
+ "bugs": {
42
+ "url": "https://github.com/yhotamos/enja-cli/issues"
43
+ },
44
+ "homepage": "https://github.com/yhotamos/enja-cli#readme",
45
+ "dependencies": {
46
+ "@google/genai": "^1.33.0",
47
+ "@inquirer/prompts": "^8.3.2",
48
+ "commander": "^14.0.2",
49
+ "kleur": "^4.1.5",
50
+ "openai": "^6.9.1",
51
+ "ora": "^9.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@biomejs/biome": "^2.4.10",
55
+ "@types/node": "^24.10.1",
56
+ "dotenv": "^17.3.1",
57
+ "tsup": "^8.5.1",
58
+ "tsx": "^4.20.6",
59
+ "typescript": "^5.9.3",
60
+ "vitest": "^4.0.18"
61
+ }
62
+ }