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