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