ccem 1.6.0 → 1.7.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 +17 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as io}from"commander";import ao from"conf";import U from"inquirer";import d from"chalk";import kt from"cli-table3";import{spawn as Et}from"child_process";import*as he from"readline";import*as Rt from"fs";import*as fe from"path";import{fileURLToPath as co}from"url";import ae from"crypto";import X from"fs";import B from"path";var De="aes-256-cbc",He=ae.scryptSync("claude-code-env-manager-secret","salt",32),$e=e=>{if(!e)return e;let t=ae.randomBytes(16),o=ae.createCipheriv(De,He,t),n=o.update(e,"utf8","hex");return n+=o.final("hex"),`enc:${t.toString("hex")}:${n}`},j=e=>{if(!e||!e.startsWith("enc:"))return e;try{let t=e.split(":");if(t.length!==3)return e;let o=Buffer.from(t[1],"hex"),n=t[2],s=ae.createDecipheriv(De,He,o),i=s.update(n,"hex","utf8");return i+=s.final("utf8"),i}catch{return e}},Ue=()=>{let e=process.cwd(),t=B.parse(e).root;for(;e!==t;){if(X.existsSync(B.join(e,".git"))||X.existsSync(B.join(e,"package.json")))return e;e=B.dirname(e)}return process.cwd()},ce=(e=!0)=>{let t=Ue(),o=B.join(t,".claude"),n=e?"settings.local.json":"settings.json";return B.join(o,n)},Fe=()=>{let e=Ue(),t=B.join(e,".claude");return X.existsSync(t)||X.mkdirSync(t,{recursive:!0}),t},_e=()=>process.env.HOME||process.env.USERPROFILE||"",Se=()=>B.join(_e(),".claude.json"),Pe=()=>B.join(_e(),".claude","settings.json"),je=()=>{let e=B.join(_e(),".claude");return X.existsSync(e)||X.mkdirSync(e,{recursive:!0}),e};var Ae={GLM:{ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",ANTHROPIC_MODEL:"glm-4.6",ANTHROPIC_SMALL_FAST_MODEL:"glm-4.5-air"},KIMI:{ANTHROPIC_BASE_URL:"https://api.moonshot.cn/anthropic",ANTHROPIC_MODEL:"kimi-k2-thinking-turbo",ANTHROPIC_SMALL_FAST_MODEL:"kimi-k2-turbo-preview"},MiniMax:{ANTHROPIC_BASE_URL:"https://api.minimaxi.com/anthropic",ANTHROPIC_MODEL:"MiniMax-M2",ANTHROPIC_SMALL_FAST_MODEL:"MiniMax-M2"},DeepSeek:{ANTHROPIC_BASE_URL:"https://api.deepseek.com/anthropic",ANTHROPIC_MODEL:"deepseek-chat",ANTHROPIC_SMALL_FAST_MODEL:"deepseek-chat"}},O={yolo:{name:"YOLO \u6A21\u5F0F",description:"\u5168\u90E8\u653E\u5F00\uFF0C\u65E0\u4EFB\u4F55\u9650\u5236",permissionMode:"bypassPermissions",permissions:{allow:["Bash(*)","Read(*)","Edit(*)","Write(*)","WebFetch(*)","WebSearch(*)","Glob(*)","Grep(*)","LSP(*)","NotebookEdit(*)"],deny:[]}},dev:{name:"\u5F00\u53D1\u6A21\u5F0F",description:"\u65E5\u5E38\u5F00\u53D1\u6743\u9650\uFF0C\u4FDD\u62A4\u654F\u611F\u6587\u4EF6",permissionMode:"acceptEdits",permissions:{allow:["Read(*)","Edit(*)","Write(*)","Glob(*)","Grep(*)","LSP(*)","NotebookEdit(*)","Bash(npm:*)","Bash(pnpm:*)","Bash(yarn:*)","Bash(bun:*)","Bash(node:*)","Bash(npx:*)","Bash(git:*)","Bash(tsc:*)","Bash(tsx:*)","Bash(eslint:*)","Bash(prettier:*)","Bash(jest:*)","Bash(vitest:*)","Bash(cargo:*)","Bash(python:*)","Bash(pip:*)","Bash(go:*)","Bash(make:*)","Bash(cmake:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)","Bash(mkdir:*)","Bash(cp:*)","Bash(mv:*)","Bash(touch:*)","WebSearch"],deny:["Read(.env)","Read(.env.*)","Read(**/secrets/**)","Read(**/*.pem)","Read(**/*.key)","Read(**/*credential*)","Bash(rm -rf:*)","Bash(sudo:*)","Bash(chmod:*)","Bash(chown:*)"]}},readonly:{name:"\u53EA\u8BFB\u6A21\u5F0F",description:"\u4EC5\u5141\u8BB8\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7981\u6B62\u4EFB\u4F55\u4FEE\u6539",permissionMode:"plan",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git status:*)","Bash(git log:*)","Bash(git diff:*)","Bash(git branch:*)","Bash(git show:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)","Bash(file:*)","WebSearch"],deny:["Edit(*)","Write(*)","NotebookEdit(*)","Bash(rm:*)","Bash(mv:*)","Bash(cp:*)","Bash(mkdir:*)","Bash(touch:*)","Bash(git add:*)","Bash(git commit:*)","Bash(git push:*)","Bash(git checkout:*)","Bash(git reset:*)","Bash(npm install:*)","Bash(pnpm install:*)","Bash(yarn add:*)"]}},safe:{name:"\u5B89\u5168\u6A21\u5F0F",description:"\u4FDD\u5B88\u6743\u9650\uFF0C\u9002\u5408\u4E0D\u719F\u6089\u7684\u4EE3\u7801\u5E93",permissionMode:"default",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git status:*)","Bash(git log:*)","Bash(git diff:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)"],deny:["Read(.env)","Read(.env.*)","Read(**/secrets/**)","Read(**/*.pem)","Read(**/*.key)","Read(**/*credential*)","Read(**/*password*)","Edit(*)","Write(*)","NotebookEdit(*)","Bash(curl:*)","Bash(wget:*)","Bash(ssh:*)","Bash(scp:*)","Bash(rm:*)","Bash(mv:*)","WebFetch(*)"]}},ci:{name:"CI/CD \u6A21\u5F0F",description:"\u9002\u5408\u81EA\u52A8\u5316\u6D41\u6C34\u7EBF\u7684\u6743\u9650",permissionMode:"default",permissions:{allow:["Read(*)","Edit(*)","Write(*)","Glob(*)","Grep(*)","LSP(*)","Bash(npm:*)","Bash(pnpm:*)","Bash(yarn:*)","Bash(node:*)","Bash(git:*)","Bash(docker:*)","Bash(make:*)","Bash(cargo:*)","Bash(go:*)","Bash(python:*)","Bash(pip:*)","Bash(pytest:*)","Bash(jest:*)","Bash(vitest:*)"],deny:["Read(.env.local)","Read(**/secrets/**)","Bash(sudo:*)","Bash(ssh:*)","Bash(scp:*)","WebFetch(*)","WebSearch"]}},audit:{name:"\u5BA1\u8BA1\u6A21\u5F0F",description:"\u4EC5\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7528\u4E8E\u5B89\u5168\u5BA1\u8BA1",permissionMode:"plan",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git log:*)","Bash(git blame:*)","Bash(git show:*)","Bash(git diff:*)","Bash(ls:*)","Bash(find:*)","Bash(wc:*)","Bash(file:*)","Bash(stat:*)"],deny:["Edit(*)","Write(*)","NotebookEdit(*)","Bash(rm:*)","Bash(mv:*)","Bash(cp:*)","Bash(curl:*)","Bash(wget:*)","Bash(ssh:*)","WebFetch(*)"]}}},Ce=()=>Object.keys(O);import N from"chalk";import Je from"cli-table3";import*as Y from"fs";import*as I from"fs/promises";import*as G from"path";import*as ke from"os";import*as Ge from"readline";var Te=G.join(ke.homedir(),".claude","projects"),le=G.join(ke.homedir(),".ccem"),Ee=1,Re=()=>G.join(le,"usage-cache.json"),xt=()=>G.join(le,"model-prices.json");async function Ke(){try{await I.access(le)}catch{await I.mkdir(le,{recursive:!0})}}var Lt="https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",bt=()=>G.join(__dirname,"..","model-prices.json"),Z={"claude-opus-4-5":{input_cost_per_token:5e-6,output_cost_per_token:25e-6,cache_read_input_token_cost:5e-7,cache_creation_input_token_cost:625e-8},"claude-sonnet-4-5":{input_cost_per_token:3e-6,output_cost_per_token:15e-6,cache_read_input_token_cost:3e-7,cache_creation_input_token_cost:375e-8},"claude-haiku-4-5":{input_cost_per_token:1e-6,output_cost_per_token:5e-6,cache_read_input_token_cost:1e-7,cache_creation_input_token_cost:125e-8}};function de(e){return e.replace(/-20\d{6}.*$/,"").replace(/-v\d+:\d+$/,"").replace(/^anthropic\./,"").replace(/^vertex_ai\//,"").replace(/@.*$/,"")}var Q=null;async function Nt(){if(Q)return Q;await Ke();let e=xt();try{let t=await fetch(Lt,{signal:AbortSignal.timeout(1e3)});if(t.ok){let o=await t.json(),n={};for(let[s,i]of Object.entries(o))i.input_cost_per_token&&i.output_cost_per_token&&(n[s]={input_cost_per_token:i.input_cost_per_token,output_cost_per_token:i.output_cost_per_token,cache_read_input_token_cost:i.cache_read_input_token_cost,cache_creation_input_token_cost:i.cache_creation_input_token_cost});return await I.writeFile(e,JSON.stringify(n,null,2)),Q=n,n}}catch{}try{let t=await I.readFile(e,"utf-8"),o=JSON.parse(t);return Q=o,o}catch{}try{let t=bt(),o=await I.readFile(t,"utf-8"),n=JSON.parse(o);return Q=n,n}catch{}return Q=Z,Z}function Bt(e,t){if(t[e])return t[e];let o=de(e);if(t[o])return t[o];for(let[n,s]of Object.entries(t))if(n.includes(o)||o.includes(de(n)))return s;return e.includes("opus")?Z["claude-opus-4-5"]:e.includes("sonnet")?Z["claude-sonnet-4-5"]:e.includes("haiku")?Z["claude-haiku-4-5"]:Z["claude-sonnet-4-5"]}function vt(e,t){return e.inputTokens*t.input_cost_per_token+e.outputTokens*t.output_cost_per_token+e.cacheReadTokens*(t.cache_read_input_token_cost||0)+e.cacheCreationTokens*(t.cache_creation_input_token_cost||0)}function v(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,cost:0}}function D(e,t){return{inputTokens:e.inputTokens+t.inputTokens,outputTokens:e.outputTokens+t.outputTokens,cacheReadTokens:e.cacheReadTokens+t.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens+t.cacheCreationTokens,cost:e.cost+t.cost}}async function Dt(e){try{let t=await I.stat(e);return{mtime:t.mtimeMs,size:t.size}}catch{return null}}function Ht(){try{let e=Re();if(!Y.existsSync(e))return null;let t=JSON.parse(Y.readFileSync(e,"utf-8"));return t.version!==Ee?null:t}catch{return null}}async function $t(){try{let e=Re(),t=await I.readFile(e,"utf-8"),o=JSON.parse(t);return o.version!==Ee?null:o}catch{return null}}function We(){let e=Ht();if(!e)return null;let t=new Date,o=new Date(t.getFullYear(),t.getMonth(),t.getDate()),n=new Date(o);n.setDate(n.getDate()-n.getDay());let s={today:v(),week:v(),total:v(),dailyHistory:{},byModel:{},lastUpdated:t.toISOString()};for(let i of Object.values(e.files))for(let a of i.stats.entries){let c=new Date(a.timestamp),l=a.timestamp.split("T")[0];s.total=D(s.total,a.usage),s.dailyHistory[l]||(s.dailyHistory[l]=v()),s.dailyHistory[l]=D(s.dailyHistory[l],a.usage);let m=de(a.model);s.byModel[m]||(s.byModel[m]=v()),s.byModel[m]=D(s.byModel[m],a.usage),c>=o&&(s.today=D(s.today,a.usage)),c>=n&&(s.week=D(s.week,a.usage))}return s}async function Ut(e){try{await Ke(),await I.writeFile(Re(),JSON.stringify(e,null,2))}catch{}}async function Ft(e,t,o){let n=[];try{let s=Y.createReadStream(e,{encoding:"utf-8"}),i=Ge.createInterface({input:s,crlfDelay:1/0}),a=0;for await(let c of i){if(a++,a%100===0){if(o?.aborted)throw i.close(),s.destroy(),new Error("Aborted");a%1e3===0&&await new Promise(l=>setTimeout(l,0))}if(c.trim())try{let l=JSON.parse(c);if(l.type!=="assistant"||!l.message?.usage)continue;let m=l.message.model||"unknown",f=l.message.usage,y={inputTokens:f.input_tokens||0,outputTokens:f.output_tokens||0,cacheReadTokens:f.cache_read_input_tokens||0,cacheCreationTokens:f.cache_creation_input_tokens||0},p=Bt(m,t),_=vt(y,p);n.push({timestamp:l.timestamp||new Date().toISOString(),model:m,usage:{...y,cost:_}})}catch{}}}catch(s){if(s.message==="Aborted")throw s}return{entries:n}}async function jt(){let e=[];try{if(!await I.access(Te).then(()=>!0).catch(()=>!1))return e;let o=await I.readdir(Te);for(let n of o){let s=G.join(Te,n);try{if((await I.stat(s)).isDirectory()){let a=await I.readdir(s);for(let c of a)c.endsWith(".jsonl")&&e.push(G.join(s,c))}}catch{}}}catch{}return e}async function Ye(e){if(e?.aborted)throw new Error("Aborted");let t=await Nt();if(e?.aborted)throw new Error("Aborted");let o=await jt();if(e?.aborted)throw new Error("Aborted");let n=await $t(),s={version:Ee,files:{},lastUpdated:new Date().toISOString()},i=[],a=5,c=[];for(let p=0;p<o.length;p+=a)c.push(o.slice(p,p+a));for(let p of c){if(e?.aborted)throw new Error("Aborted");let _=p.map(async g=>{let S=await Dt(g);if(!S)return null;let R=n?.files[g],k=R&&R.meta.mtime===S.mtime&&R.meta.size===S.size,E;return k?E=R.stats:(E=await Ft(g,t,e),await new Promise(C=>setTimeout(C,0))),{file:g,meta:S,stats:E}}),u=await Promise.all(_);for(let g of u)g&&(s.files[g.file]={meta:g.meta,stats:g.stats},i.push(...g.stats.entries))}e?.aborted||Ut(s).catch(()=>{});let l=new Date,m=new Date(l.getFullYear(),l.getMonth(),l.getDate()),f=new Date(m);f.setDate(f.getDate()-f.getDay());let y={today:v(),week:v(),total:v(),dailyHistory:{},byModel:{},lastUpdated:l.toISOString()};for(let p of i){let _=new Date(p.timestamp),u=p.timestamp.split("T")[0];y.total=D(y.total,p.usage),y.dailyHistory[u]||(y.dailyHistory[u]=v()),y.dailyHistory[u]=D(y.dailyHistory[u],p.usage);let g=de(p.model);y.byModel[g]||(y.byModel[g]=v()),y.byModel[g]=D(y.byModel[g],p.usage),_>=m&&(y.today=D(y.today,p.usage)),_>=f&&(y.week=D(y.week,p.usage))}return y}function b(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e.toString()}function ee(e){return e>=1||e>=.01?"$"+e.toFixed(2):"$"+e.toFixed(4)}function J(e){return e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens}var r={primary:N.hex("#89B4FA"),accent:N.hex("#CBA6F7"),success:N.hex("#A6E3A1"),warning:N.hex("#F9E2AF"),danger:N.hex("#F38BA8"),text:N.white,muted:N.hex("#6C7086"),dim:N.hex("#45475A")},ze=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],we=0,se=null,Gt=()=>r.primary(ze[we]),Ve=e=>{se||(se=setInterval(()=>{we=(we+1)%ze.length,e()},80))},pe=()=>{se&&(clearInterval(se),se=null)};var qe=()=>process.stdout.columns||80,Xe=(e,t,o)=>{let n=N.hex("#89B4FA"),s=N.hex("#45475A"),i=N.hex("#6C7086"),a=qe(),c=a<60,l=a<45,m=r.primary("CCEM")+" "+r.muted("Claude Code Env Manager"),f=r.primary("CCEM"),y=r.muted("Env: ")+r.primary(e),p=t.ANTHROPIC_BASE_URL||"-",_=t.ANTHROPIC_MODEL||"-",u=t.ANTHROPIC_SMALL_FAST_MODEL||"-",g=t.ANTHROPIC_API_KEY?t.ANTHROPIC_API_KEY.slice(0,2)+"\u2022\u2022\u2022\u2022"+t.ANTHROPIC_API_KEY.slice(-4):"-",S=(w,F)=>w.length>F?w.slice(0,F-3)+"...":w,R=(w,F)=>{if(w.length<=F)return w;try{let $=new URL(w),wt=$.protocol+"//",ve=$.host,ye=$.pathname+$.search,Ot=ve.slice(0,8),Mt=ve.slice(-4),It=ye.length>10?ye.slice(0,7)+"...":ye;return`${wt}${Ot}...${Mt}${It}`}catch{return S(w,F)}},k=7,E;c?E=[y,r.muted("Model:".padEnd(k))+r.dim(S(_,25)),r.muted("Key:".padEnd(k))+r.dim(g)]:E=[y+(o&&O[o]?" "+r.accent(`[${O[o].name}]`):""),r.muted("URL:".padEnd(k))+r.dim(R(p,40)),r.muted("Model:".padEnd(k))+r.dim(S(_,15))+" "+r.muted("Fast:".padEnd(k))+r.dim(S(u,15)),r.muted("Key:".padEnd(k))+r.dim(g)];let C=[];if(l)C.push(` ${i("*")} ${s("\u2584\u2588\u2584")} ${i("*")}`),C.push(` ${i("*")} ${n("\u2590\u259B\u2588\u2588\u2588\u2588\u2588\u259C\u258C")} ${i("*")}`),C.push(` ${i("*")} ${n("\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u259B\u2598")} ${i("*")}`),C.push(` ${i("*")} ${n("\u2598\u2598 \u259D\u259D")} ${i("*")}`),C.push(""),C.push(f),C.push(""),E.forEach(w=>C.push(w));else{let w=c?" ":" ";C.push(""),C.push(` ${s("\u2584\u2588\u2588\u2584")} ${w}${c?f:m}`),C.push(` ${i("*")} ${n("\u2590\u259B\u2588\u2588\u2588\u2588\u2588\u259C\u258C")} ${i("*")} ${w}${E[0]||""}`),C.push(` ${i("*")} ${n("\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u259B\u2598")} ${i("*")} ${w}${E[1]||""}`),C.push(` ${i("*")} ${n("\u2598\u2598 \u259D\u259D")} ${i("*")} ${w}${E[2]||""}`),E[3]&&C.push(` ${w}${E[3]}`)}return C.join(`
|
|
3
|
-
`)},
|
|
4
|
-
`)},
|
|
5
|
-
`)};import
|
|
6
|
-
`)},
|
|
2
|
+
import{Command as go}from"commander";import fo from"conf";import F from"inquirer";import d from"chalk";import Ot from"cli-table3";import{spawn as Mt}from"child_process";import*as ye from"readline";import*as It from"fs";import*as _e from"path";import{fileURLToPath as ho}from"url";import ce from"crypto";import Q from"fs";import B from"path";var $e="aes-256-cbc",Ue=ce.scryptSync("claude-code-env-manager-secret","salt",32),le=e=>{if(!e)return e;let t=ce.randomBytes(16),o=ce.createCipheriv($e,Ue,t),n=o.update(e,"utf8","hex");return n+=o.final("hex"),`enc:${t.toString("hex")}:${n}`},K=e=>{if(!e||!e.startsWith("enc:"))return e;try{let t=e.split(":");if(t.length!==3)return e;let o=Buffer.from(t[1],"hex"),n=t[2],s=ce.createDecipheriv($e,Ue,o),i=s.update(n,"hex","utf8");return i+=s.final("utf8"),i}catch{return e}},Fe=()=>{let e=process.cwd(),t=B.parse(e).root;for(;e!==t;){if(Q.existsSync(B.join(e,".git"))||Q.existsSync(B.join(e,"package.json")))return e;e=B.dirname(e)}return process.cwd()},de=(e=!0)=>{let t=Fe(),o=B.join(t,".claude"),n=e?"settings.local.json":"settings.json";return B.join(o,n)},je=()=>{let e=Fe(),t=B.join(e,".claude");return Q.existsSync(t)||Q.mkdirSync(t,{recursive:!0}),t},Pe=()=>process.env.HOME||process.env.USERPROFILE||"",Ae=()=>B.join(Pe(),".claude.json"),Ee=()=>B.join(Pe(),".claude","settings.json"),Ke=()=>{let e=B.join(Pe(),".claude");return Q.existsSync(e)||Q.mkdirSync(e,{recursive:!0}),e};var Ce={GLM:{ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",ANTHROPIC_MODEL:"glm-4.6",ANTHROPIC_SMALL_FAST_MODEL:"glm-4.5-air"},KIMI:{ANTHROPIC_BASE_URL:"https://api.moonshot.cn/anthropic",ANTHROPIC_MODEL:"kimi-k2-thinking-turbo",ANTHROPIC_SMALL_FAST_MODEL:"kimi-k2-turbo-preview"},MiniMax:{ANTHROPIC_BASE_URL:"https://api.minimaxi.com/anthropic",ANTHROPIC_MODEL:"MiniMax-M2",ANTHROPIC_SMALL_FAST_MODEL:"MiniMax-M2"},DeepSeek:{ANTHROPIC_BASE_URL:"https://api.deepseek.com/anthropic",ANTHROPIC_MODEL:"deepseek-chat",ANTHROPIC_SMALL_FAST_MODEL:"deepseek-chat"}},O={yolo:{name:"YOLO \u6A21\u5F0F",description:"\u5168\u90E8\u653E\u5F00\uFF0C\u65E0\u4EFB\u4F55\u9650\u5236",permissionMode:"bypassPermissions",permissions:{allow:["Bash(*)","Read(*)","Edit(*)","Write(*)","WebFetch(*)","WebSearch(*)","Glob(*)","Grep(*)","LSP(*)","NotebookEdit(*)"],deny:[]}},dev:{name:"\u5F00\u53D1\u6A21\u5F0F",description:"\u65E5\u5E38\u5F00\u53D1\u6743\u9650\uFF0C\u4FDD\u62A4\u654F\u611F\u6587\u4EF6",permissionMode:"acceptEdits",permissions:{allow:["Read(*)","Edit(*)","Write(*)","Glob(*)","Grep(*)","LSP(*)","NotebookEdit(*)","Bash(npm:*)","Bash(pnpm:*)","Bash(yarn:*)","Bash(bun:*)","Bash(node:*)","Bash(npx:*)","Bash(git:*)","Bash(tsc:*)","Bash(tsx:*)","Bash(eslint:*)","Bash(prettier:*)","Bash(jest:*)","Bash(vitest:*)","Bash(cargo:*)","Bash(python:*)","Bash(pip:*)","Bash(go:*)","Bash(make:*)","Bash(cmake:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)","Bash(mkdir:*)","Bash(cp:*)","Bash(mv:*)","Bash(touch:*)","WebSearch"],deny:["Read(.env)","Read(.env.*)","Read(**/secrets/**)","Read(**/*.pem)","Read(**/*.key)","Read(**/*credential*)","Bash(rm -rf:*)","Bash(sudo:*)","Bash(chmod:*)","Bash(chown:*)"]}},readonly:{name:"\u53EA\u8BFB\u6A21\u5F0F",description:"\u4EC5\u5141\u8BB8\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7981\u6B62\u4EFB\u4F55\u4FEE\u6539",permissionMode:"plan",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git status:*)","Bash(git log:*)","Bash(git diff:*)","Bash(git branch:*)","Bash(git show:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)","Bash(file:*)","WebSearch"],deny:["Edit(*)","Write(*)","NotebookEdit(*)","Bash(rm:*)","Bash(mv:*)","Bash(cp:*)","Bash(mkdir:*)","Bash(touch:*)","Bash(git add:*)","Bash(git commit:*)","Bash(git push:*)","Bash(git checkout:*)","Bash(git reset:*)","Bash(npm install:*)","Bash(pnpm install:*)","Bash(yarn add:*)"]}},safe:{name:"\u5B89\u5168\u6A21\u5F0F",description:"\u4FDD\u5B88\u6743\u9650\uFF0C\u9002\u5408\u4E0D\u719F\u6089\u7684\u4EE3\u7801\u5E93",permissionMode:"default",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git status:*)","Bash(git log:*)","Bash(git diff:*)","Bash(ls:*)","Bash(cat:*)","Bash(head:*)","Bash(tail:*)","Bash(find:*)","Bash(wc:*)"],deny:["Read(.env)","Read(.env.*)","Read(**/secrets/**)","Read(**/*.pem)","Read(**/*.key)","Read(**/*credential*)","Read(**/*password*)","Edit(*)","Write(*)","NotebookEdit(*)","Bash(curl:*)","Bash(wget:*)","Bash(ssh:*)","Bash(scp:*)","Bash(rm:*)","Bash(mv:*)","WebFetch(*)"]}},ci:{name:"CI/CD \u6A21\u5F0F",description:"\u9002\u5408\u81EA\u52A8\u5316\u6D41\u6C34\u7EBF\u7684\u6743\u9650",permissionMode:"default",permissions:{allow:["Read(*)","Edit(*)","Write(*)","Glob(*)","Grep(*)","LSP(*)","Bash(npm:*)","Bash(pnpm:*)","Bash(yarn:*)","Bash(node:*)","Bash(git:*)","Bash(docker:*)","Bash(make:*)","Bash(cargo:*)","Bash(go:*)","Bash(python:*)","Bash(pip:*)","Bash(pytest:*)","Bash(jest:*)","Bash(vitest:*)"],deny:["Read(.env.local)","Read(**/secrets/**)","Bash(sudo:*)","Bash(ssh:*)","Bash(scp:*)","WebFetch(*)","WebSearch"]}},audit:{name:"\u5BA1\u8BA1\u6A21\u5F0F",description:"\u4EC5\u8BFB\u53D6\u548C\u641C\u7D22\uFF0C\u7528\u4E8E\u5B89\u5168\u5BA1\u8BA1",permissionMode:"plan",permissions:{allow:["Read(*)","Glob(*)","Grep(*)","LSP(*)","Bash(git log:*)","Bash(git blame:*)","Bash(git show:*)","Bash(git diff:*)","Bash(ls:*)","Bash(find:*)","Bash(wc:*)","Bash(file:*)","Bash(stat:*)"],deny:["Edit(*)","Write(*)","NotebookEdit(*)","Bash(rm:*)","Bash(mv:*)","Bash(cp:*)","Bash(curl:*)","Bash(wget:*)","Bash(ssh:*)","WebFetch(*)"]}}},Re=()=>Object.keys(O);import v from"chalk";import ze from"cli-table3";import*as J from"fs";import*as I from"fs/promises";import*as G from"path";import*as ke from"os";import*as Ge from"readline";var Te=G.join(ke.homedir(),".claude","projects"),pe=G.join(ke.homedir(),".ccem"),we=1,Oe=()=>G.join(pe,"usage-cache.json"),vt=()=>G.join(pe,"model-prices.json");async function Ye(){try{await I.access(pe)}catch{await I.mkdir(pe,{recursive:!0})}}var Bt="https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",Dt=()=>G.join(__dirname,"..","model-prices.json"),ee={"claude-opus-4-5":{input_cost_per_token:5e-6,output_cost_per_token:25e-6,cache_read_input_token_cost:5e-7,cache_creation_input_token_cost:625e-8},"claude-sonnet-4-5":{input_cost_per_token:3e-6,output_cost_per_token:15e-6,cache_read_input_token_cost:3e-7,cache_creation_input_token_cost:375e-8},"claude-haiku-4-5":{input_cost_per_token:1e-6,output_cost_per_token:5e-6,cache_read_input_token_cost:1e-7,cache_creation_input_token_cost:125e-8}};function ue(e){return e.replace(/-20\d{6}.*$/,"").replace(/-v\d+:\d+$/,"").replace(/^anthropic\./,"").replace(/^vertex_ai\//,"").replace(/@.*$/,"")}var Z=null;async function Ht(){if(Z)return Z;await Ye();let e=vt();try{let t=await fetch(Bt,{signal:AbortSignal.timeout(1e3)});if(t.ok){let o=await t.json(),n={};for(let[s,i]of Object.entries(o))i.input_cost_per_token&&i.output_cost_per_token&&(n[s]={input_cost_per_token:i.input_cost_per_token,output_cost_per_token:i.output_cost_per_token,cache_read_input_token_cost:i.cache_read_input_token_cost,cache_creation_input_token_cost:i.cache_creation_input_token_cost});return await I.writeFile(e,JSON.stringify(n,null,2)),Z=n,n}}catch{}try{let t=await I.readFile(e,"utf-8"),o=JSON.parse(t);return Z=o,o}catch{}try{let t=Dt(),o=await I.readFile(t,"utf-8"),n=JSON.parse(o);return Z=n,n}catch{}return Z=ee,ee}function $t(e,t){if(t[e])return t[e];let o=ue(e);if(t[o])return t[o];for(let[n,s]of Object.entries(t))if(n.includes(o)||o.includes(ue(n)))return s;return e.includes("opus")?ee["claude-opus-4-5"]:e.includes("sonnet")?ee["claude-sonnet-4-5"]:e.includes("haiku")?ee["claude-haiku-4-5"]:ee["claude-sonnet-4-5"]}function Ut(e,t){return e.inputTokens*t.input_cost_per_token+e.outputTokens*t.output_cost_per_token+e.cacheReadTokens*(t.cache_read_input_token_cost||0)+e.cacheCreationTokens*(t.cache_creation_input_token_cost||0)}function D(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,cost:0}}function H(e,t){return{inputTokens:e.inputTokens+t.inputTokens,outputTokens:e.outputTokens+t.outputTokens,cacheReadTokens:e.cacheReadTokens+t.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens+t.cacheCreationTokens,cost:e.cost+t.cost}}async function Ft(e){try{let t=await I.stat(e);return{mtime:t.mtimeMs,size:t.size}}catch{return null}}function jt(){try{let e=Oe();if(!J.existsSync(e))return null;let t=JSON.parse(J.readFileSync(e,"utf-8"));return t.version!==we?null:t}catch{return null}}async function Kt(){try{let e=Oe(),t=await I.readFile(e,"utf-8"),o=JSON.parse(t);return o.version!==we?null:o}catch{return null}}function We(){let e=jt();if(!e)return null;let t=new Date,o=new Date(t.getFullYear(),t.getMonth(),t.getDate()),n=new Date(o);n.setDate(n.getDate()-n.getDay());let s={today:D(),week:D(),total:D(),dailyHistory:{},byModel:{},lastUpdated:t.toISOString()};for(let i of Object.values(e.files))for(let a of i.stats.entries){let c=new Date(a.timestamp),l=a.timestamp.split("T")[0];s.total=H(s.total,a.usage),s.dailyHistory[l]||(s.dailyHistory[l]=D()),s.dailyHistory[l]=H(s.dailyHistory[l],a.usage);let u=ue(a.model);s.byModel[u]||(s.byModel[u]=D()),s.byModel[u]=H(s.byModel[u],a.usage),c>=o&&(s.today=H(s.today,a.usage)),c>=n&&(s.week=H(s.week,a.usage))}return s}async function Gt(e){try{await Ye(),await I.writeFile(Oe(),JSON.stringify(e,null,2))}catch{}}async function Yt(e,t,o){let n=[];try{let s=J.createReadStream(e,{encoding:"utf-8"}),i=Ge.createInterface({input:s,crlfDelay:1/0}),a=0;for await(let c of i){if(a++,a%100===0){if(o?.aborted)throw i.close(),s.destroy(),new Error("Aborted");a%1e3===0&&await new Promise(l=>setTimeout(l,0))}if(c.trim())try{let l=JSON.parse(c);if(l.type!=="assistant"||!l.message?.usage)continue;let u=l.message.model||"unknown",m=l.message.usage,y={inputTokens:m.input_tokens||0,outputTokens:m.output_tokens||0,cacheReadTokens:m.cache_read_input_tokens||0,cacheCreationTokens:m.cache_creation_input_tokens||0},p=$t(u,t),_=Ut(y,p);n.push({timestamp:l.timestamp||new Date().toISOString(),model:u,usage:{...y,cost:_}})}catch{}}}catch(s){if(s.message==="Aborted")throw s}return{entries:n}}async function Wt(){let e=[];try{if(!await I.access(Te).then(()=>!0).catch(()=>!1))return e;let o=await I.readdir(Te);for(let n of o){let s=G.join(Te,n);try{if((await I.stat(s)).isDirectory()){let a=await I.readdir(s);for(let c of a)c.endsWith(".jsonl")&&e.push(G.join(s,c))}}catch{}}}catch{}return e}async function Je(e){if(e?.aborted)throw new Error("Aborted");let t=await Ht();if(e?.aborted)throw new Error("Aborted");let o=await Wt();if(e?.aborted)throw new Error("Aborted");let n=await Kt(),s={version:we,files:{},lastUpdated:new Date().toISOString()},i=[],a=5,c=[];for(let p=0;p<o.length;p+=a)c.push(o.slice(p,p+a));for(let p of c){if(e?.aborted)throw new Error("Aborted");let _=p.map(async f=>{let S=await Ft(f);if(!S)return null;let k=n?.files[f],R=k&&k.meta.mtime===S.mtime&&k.meta.size===S.size,T;return R?T=k.stats:(T=await Yt(f,t,e),await new Promise(E=>setTimeout(E,0))),{file:f,meta:S,stats:T}}),g=await Promise.all(_);for(let f of g)f&&(s.files[f.file]={meta:f.meta,stats:f.stats},i.push(...f.stats.entries))}e?.aborted||Gt(s).catch(()=>{});let l=new Date,u=new Date(l.getFullYear(),l.getMonth(),l.getDate()),m=new Date(u);m.setDate(m.getDate()-m.getDay());let y={today:D(),week:D(),total:D(),dailyHistory:{},byModel:{},lastUpdated:l.toISOString()};for(let p of i){let _=new Date(p.timestamp),g=p.timestamp.split("T")[0];y.total=H(y.total,p.usage),y.dailyHistory[g]||(y.dailyHistory[g]=D()),y.dailyHistory[g]=H(y.dailyHistory[g],p.usage);let f=ue(p.model);y.byModel[f]||(y.byModel[f]=D()),y.byModel[f]=H(y.byModel[f],p.usage),_>=u&&(y.today=H(y.today,p.usage)),_>=m&&(y.week=H(y.week,p.usage))}return y}function N(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e.toString()}function te(e){return e>=1||e>=.01?"$"+e.toFixed(2):"$"+e.toFixed(4)}function z(e){return e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens}var r={primary:v.hex("#89B4FA"),accent:v.hex("#CBA6F7"),success:v.hex("#A6E3A1"),warning:v.hex("#F9E2AF"),danger:v.hex("#F38BA8"),text:v.white,muted:v.hex("#6C7086"),dim:v.hex("#45475A")},qe=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Me=0,ne=null,Jt=()=>r.primary(qe[Me]),Ve=e=>{ne||(ne=setInterval(()=>{Me=(Me+1)%qe.length,e()},80))},me=()=>{ne&&(clearInterval(ne),ne=null)};var Xe=()=>process.stdout.columns||80,Qe=(e,t,o)=>{let n=v.hex("#89B4FA"),s=v.hex("#45475A"),i=v.hex("#6C7086"),a=Xe(),c=a<60,l=a<45,u=r.primary("CCEM")+" "+r.muted("Claude Code Env Manager"),m=r.primary("CCEM"),y=r.muted("Env: ")+r.primary(e),p=t.ANTHROPIC_BASE_URL||"-",_=t.ANTHROPIC_MODEL||"-",g=t.ANTHROPIC_SMALL_FAST_MODEL||"-",f=t.ANTHROPIC_API_KEY?t.ANTHROPIC_API_KEY.slice(0,2)+"\u2022\u2022\u2022\u2022"+t.ANTHROPIC_API_KEY.slice(-4):"-",S=(w,j)=>w.length>j?w.slice(0,j-3)+"...":w,k=(w,j)=>{if(w.length<=j)return w;try{let U=new URL(w),xt=U.protocol+"//",He=U.host,Se=U.pathname+U.search,bt=He.slice(0,8),Lt=He.slice(-4),Nt=Se.length>10?Se.slice(0,7)+"...":Se;return`${xt}${bt}...${Lt}${Nt}`}catch{return S(w,j)}},R=7,T;c?T=[y,r.muted("Model:".padEnd(R))+r.dim(S(_,25)),r.muted("Key:".padEnd(R))+r.dim(f)]:T=[y+(o&&O[o]?" "+r.accent(`[${O[o].name}]`):""),r.muted("URL:".padEnd(R))+r.dim(k(p,40)),r.muted("Model:".padEnd(R))+r.dim(S(_,15))+" "+r.muted("Fast:".padEnd(R))+r.dim(S(g,15)),r.muted("Key:".padEnd(R))+r.dim(f)];let E=[];if(l)E.push(` ${i("*")} ${s("\u2584\u2588\u2584")} ${i("*")}`),E.push(` ${i("*")} ${n("\u2590\u259B\u2588\u2588\u2588\u2588\u2588\u259C\u258C")} ${i("*")}`),E.push(` ${i("*")} ${n("\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u259B\u2598")} ${i("*")}`),E.push(` ${i("*")} ${n("\u2598\u2598 \u259D\u259D")} ${i("*")}`),E.push(""),E.push(m),E.push(""),T.forEach(w=>E.push(w));else{let w=c?" ":" ";E.push(""),E.push(` ${s("\u2584\u2588\u2588\u2584")} ${w}${c?m:u}`),E.push(` ${i("*")} ${n("\u2590\u259B\u2588\u2588\u2588\u2588\u2588\u259C\u258C")} ${i("*")} ${w}${T[0]||""}`),E.push(` ${i("*")} ${n("\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u259B\u2598")} ${i("*")} ${w}${T[1]||""}`),E.push(` ${i("*")} ${n("\u2598\u2598 \u259D\u259D")} ${i("*")} ${w}${T[2]||""}`),T[3]&&E.push(` ${w}${T[3]}`)}return E.join(`
|
|
3
|
+
`)},Ze=(e,t)=>{if(t)return r.muted(" Usage: ")+Jt()+r.dim(" Loading...");if(!e)return r.muted(" Usage: ")+r.dim("No data");let n=Xe()<70,s=z(e.today),i=z(e.week),a=z(e.total);return n?r.muted(" Usage: ")+r.text("Today ")+r.primary(N(s))+r.dim(" | ")+r.text("Week ")+r.primary(N(i))+r.dim(" | ")+r.text("Total ")+r.primary(N(a)):r.muted(" Usage: ")+r.text("Today ")+r.primary(N(s).padStart(6))+r.dim(` (${te(e.today.cost)})`)+r.dim(" | ")+r.text("Week ")+r.primary(N(i).padStart(6))+r.dim(` (${te(e.week.cost)})`)+r.dim(" | ")+r.text("Total ")+r.primary(N(a).padStart(6))+r.dim(` (${te(e.total.cost)})`)},et=()=>{let e=process.stdout.columns||80;return r.dim("\u2500".repeat(e))};var Ie=e=>{let t="Start Claude Code";return e&&O[e]&&(t=`Start Claude Code ${r.muted(`(${O[e].name})`)}`),[{name:r.success(t),value:"start",short:"Start"},{name:r.primary("Switch Environment"),value:"switch",short:"Switch"},{name:r.primary("Permission Mode"),value:"perm",short:"Permission"},{name:r.accent("View Usage"),value:"usage",short:"Usage"},{name:r.text("Set Default Mode"),value:"setDefault",short:"Default"},{name:r.muted("Exit"),value:"exit",short:"Exit"}]},zt={yolo:r.danger,dev:r.success,readonly:r.primary,safe:r.warning,ci:r.accent,audit:r.primary},xe=(e,t=!1)=>{let n=["yolo","dev","readonly","safe","ci","audit"].map(s=>{let i=O[s],a=zt[s],l=t&&s===e?r.success(" *"):"";return{name:a(i.name.padEnd(12))+r.muted(i.description)+l,value:s,short:i.name}});return t&&n.push({name:r.muted("Clear default"),value:"clear",short:"Clear"}),n.push({name:r.muted("Back"),value:"back",short:"Back"}),n},tt=(e,t)=>Object.keys(e).map(o=>{let n=o===t,s=n?r.success(" *"):"";return{name:(n?r.primary(o):r.text(o))+s,value:o,short:o}}),re={success:e=>console.log(r.success("\u2713 ")+r.text(e)),error:e=>console.log(r.danger("\u2717 ")+r.text(e)),warning:e=>console.log(r.warning("! ")+r.text(e)),info:e=>console.log(r.primary("\u203A ")+r.text(e))},ot=()=>r.muted("Starting Claude Code...");var qt=(e,t=6)=>{let o=[],n=new Date,s=new Date(n);s.setMonth(s.getMonth()-t);let i=s.getDay(),a=s.getDate()-i+(i===0?-6:1);s.setDate(a),s.setHours(0,0,0,0);let c=[],l=new Date(s);for(;(l<=n||l.getDay()!==1)&&(c.push(l.toISOString().split("T")[0]),l.setDate(l.getDate()+1),!(l>n&&l.getDay()===1)););let u=0;for(let S of c){let k=e.dailyHistory[S];if(k){let R=z(k);R>u&&(u=R)}}let m=" ",y=-1,p=Math.ceil(c.length/7);for(let S=0;S<p;S++){let k=S*7;if(k<c.length){let R=new Date(c[k]),T=R.getMonth();if(T!==y&&S<p-1){let E=R.toLocaleString("default",{month:"short"});m+=r.muted(E),y=T}}}m=" ";let _=-1;for(let S=0;S<p;S++){let k=S*7;if(k>=c.length)break;let R=new Date(c[k]),T=R.getMonth();if(T!==_){let E=R.toLocaleString("default",{month:"short"});m+=r.muted(E.padEnd(4)),S++,_=T}else m+=" "}o.push(m);let g=["Mon","","Wed","","Fri","","Sun"],f=[" ","\u2591","\u2592","\u2593","\u2588"];for(let S=0;S<7;S++){let k=r.muted((g[S]||"").padEnd(4)+" ");for(let R=0;R<p;R++){let T=R*7+S;if(T<c.length){let E=c[T];if(new Date(E)>n)k+=" ";else{let w=e.dailyHistory[E],j=w?z(w):0,U=0;j>0&&(u===0?U=0:U=Math.ceil(j/u*4)),k+=(U===0?r.dim("\xB7"):r.primary(f[U]))+" "}}}o.push(k)}return o.push(""),o.push(" "+r.dim("Less ")+r.dim("\xB7")+" "+r.primary(f[1])+" "+r.primary(f[2])+" "+r.primary(f[3])+" "+r.primary(f[4])+" "+r.dim(" More")),o.join(`
|
|
4
|
+
`)},st=e=>{let t=[];t.push(""),t.push(r.primary(" Token Usage Statistics")),t.push(r.dim("\u2500".repeat(60))),t.push(""),t.push(qt(e)),t.push(""),t.push(r.dim("\u2500".repeat(60)));let o=new ze({head:[r.muted("Period"),r.muted("Input"),r.muted("Output"),r.muted("Cache Read"),r.muted("Cost")],style:{head:[],border:[]},chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:" ","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:" "}}),n=(i,a)=>[r.text(i),r.primary(N(a.inputTokens)),r.primary(N(a.outputTokens)),r.primary(N(a.cacheReadTokens)),r.success(te(a.cost))];o.push(n("Today",e.today)),o.push(n("This Week",e.week)),o.push(n("All Time",e.total)),t.push(o.toString());let s=Object.entries(e.byModel).sort((i,a)=>a[1].cost-i[1].cost);if(s.length>0){t.push(""),t.push(r.dim("\u2500".repeat(60))),t.push(r.muted(" By Model")),t.push("");let i=new ze({head:[r.muted("Model"),r.muted("Tokens"),r.muted("Cost")],style:{head:[],border:[]},chars:{top:"","top-mid":"","top-left":"","top-right":"",bottom:"","bottom-mid":"","bottom-left":"","bottom-right":"",left:" ","left-mid":"",mid:"","mid-mid":"",right:"","right-mid":"",middle:" "}});for(let[a,c]of s){let l=z(c);i.push([r.text(a),r.primary(N(l)),r.success(te(c.cost))])}t.push(i.toString())}return t.push(""),t.push(r.dim("\u2500".repeat(60))),t.push(r.muted(` Last updated: ${new Date(e.lastUpdated).toLocaleString()}`)),t.join(`
|
|
5
|
+
`)};import q from"fs";import A from"chalk";import nt from"cli-table3";import{spawn as Vt}from"child_process";var be=e=>{if(q.existsSync(e))try{let t=q.readFileSync(e,"utf-8");return JSON.parse(t)}catch{console.warn(A.yellow(`\u8B66\u544A: \u65E0\u6CD5\u89E3\u6790 ${e}\uFF0C\u5C06\u521B\u5EFA\u5907\u4EFD`));let t=e+".error."+Date.now();return q.copyFileSync(e,t),console.log(A.gray(`\u5907\u4EFD\u5DF2\u4FDD\u5B58\u5230: ${t}`)),{}}return{}},rt=(e,t)=>{je(),q.writeFileSync(e,JSON.stringify(t,null,2)+`
|
|
6
|
+
`)},Xt=(e,t)=>{let o=e.permissions?.allow||[],n=e.permissions?.deny||[],s=[...new Set([...t.allow,...o])],i=[...new Set([...t.deny,...n])];return{...e,permissions:{allow:s,deny:i}}},it=e=>{let t=O[e];t||(console.error(A.red(`\u672A\u77E5\u7684\u6743\u9650\u6A21\u5F0F: ${e}`)),console.log(A.yellow("\u53EF\u7528\u6A21\u5F0F: "+Re().join(", "))),process.exit(1));let o=de(!0),n=be(o),s=Xt(n,t.permissions);rt(o,s),console.log(A.green(`\u5DF2\u5E94\u7528 ${t.name}`)),console.log(A.gray(`\u914D\u7F6E\u5DF2\u5199\u5165: ${o}`)),console.log(A.gray(`\u8BF4\u660E: ${t.description}`))},at=()=>{let e=de(!0);if(!q.existsSync(e)){console.log(A.yellow("\u6CA1\u6709\u81EA\u5B9A\u4E49\u6743\u9650\u914D\u7F6E\u9700\u8981\u91CD\u7F6E"));return}let t=be(e);delete t.permissions,Object.keys(t).length===0?(q.unlinkSync(e),console.log(A.green("\u5DF2\u5220\u9664\u914D\u7F6E\u6587\u4EF6\uFF08\u6587\u4EF6\u4E3A\u7A7A\uFF09"))):(rt(e,t),console.log(A.green("\u6743\u9650\u914D\u7F6E\u5DF2\u91CD\u7F6E"))),console.log(A.gray(`\u6587\u4EF6: ${e}`))},ct=()=>{let e=de(!0);if(!q.existsSync(e)){console.log(A.yellow("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49\u6743\u9650")),console.log(A.gray(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`));return}let t=be(e);if(!t.permissions){console.log(A.yellow("\u672A\u914D\u7F6E\u81EA\u5B9A\u4E49\u6743\u9650"));return}let o=Object.entries(O).find(([a,c])=>{let l=new Set(t.permissions?.allow||[]),u=new Set(t.permissions?.deny||[]),m=new Set(c.permissions.allow),y=new Set(c.permissions.deny),p=c.permissions.allow.every(g=>l.has(g)),_=c.permissions.deny.every(g=>u.has(g));return p&&_});console.log(o?A.green(`\u5F53\u524D\u6A21\u5F0F: ${o[0]} (${o[1].name})`):A.yellow("\u5F53\u524D\u6A21\u5F0F: \u81EA\u5B9A\u4E49")),console.log(A.gray(`\u914D\u7F6E\u6587\u4EF6: ${e}`));let n=new nt({head:["\u7C7B\u578B","\u89C4\u5219"],style:{head:["cyan"]},colWidths:[10,70]}),s=t.permissions.allow||[],i=t.permissions.deny||[];n.push(["Allow",s.length>0?s.join(`
|
|
7
7
|
`):"(\u65E0)"]),n.push(["Deny",i.length>0?i.join(`
|
|
8
|
-
`):"(\u65E0)"]),console.log(n.toString())},
|
|
8
|
+
`):"(\u65E0)"]),console.log(n.toString())},lt=()=>{let e=new nt({head:["\u6A21\u5F0F","\u6807\u5FD7","\u8BF4\u660E"],style:{head:["cyan"]},colWidths:[15,15,50]});Object.entries(O).forEach(([t,o])=>{e.push([o.name,`--${t}`,o.description])}),console.log(A.bold(`\u53EF\u7528\u6743\u9650\u6A21\u5F0F:
|
|
9
9
|
`)),console.log(e.toString()),console.log(A.gray(`
|
|
10
|
-
\u4E34\u65F6\u6A21\u5F0F: ccem <mode>`)),console.log(A.gray("\u6C38\u4E45\u6A21\u5F0F: ccem setup perms --<mode>"))},
|
|
11
|
-
`)},
|
|
10
|
+
\u4E34\u65F6\u6A21\u5F0F: ccem <mode>`)),console.log(A.gray("\u6C38\u4E45\u6A21\u5F0F: ccem setup perms --<mode>"))},ge=async(e,t)=>{let o=O[e];o||(console.error(A.red(`\u672A\u77E5\u7684\u6743\u9650\u6A21\u5F0F: ${e}`)),console.log(A.yellow("\u53EF\u7528\u6A21\u5F0F: "+Re().join(", "))),process.exit(1));let n=[];if(n.push("--permission-mode",o.permissionMode),o.permissions.allow.length>0){let i=o.permissions.allow.map(a=>`"${a}"`).join(" ");n.push("--allowedTools",i)}if(o.permissions.deny.length>0){let i=o.permissions.deny.map(a=>`"${a}"`).join(" ");n.push("--disallowedTools",i)}console.log(A.green(`\u5DF2\u5E94\u7528 ${o.name}\uFF08\u4E34\u65F6\uFF09`)),console.log(A.gray(`\u8BF4\u660E: ${o.description}`)),console.log("");let s={...process.env};return t&&(t.ANTHROPIC_BASE_URL&&(s.ANTHROPIC_BASE_URL=t.ANTHROPIC_BASE_URL),t.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=K(t.ANTHROPIC_API_KEY)),t.ANTHROPIC_MODEL&&(s.ANTHROPIC_MODEL=t.ANTHROPIC_MODEL),t.ANTHROPIC_SMALL_FAST_MODEL&&(s.ANTHROPIC_SMALL_FAST_MODEL=t.ANTHROPIC_SMALL_FAST_MODEL)),new Promise(i=>{let a=Vt("claude",n,{stdio:"inherit",shell:!0,env:s});a.on("exit",c=>{process.exit(c??0)}),a.on("error",c=>{console.error(A.red(`\u542F\u52A8 Claude Code \u5931\u8D25: ${c.message}`)),process.exit(1)})})};import Le from"fs";import P from"chalk";import{spawn as Qt}from"child_process";var dt=e=>{if(Le.existsSync(e))try{let t=Le.readFileSync(e,"utf-8");return JSON.parse(t)}catch{return console.warn(P.yellow(`\u8B66\u544A: \u65E0\u6CD5\u89E3\u6790 ${e}`)),{}}return{}},pt=(e,t)=>{Le.writeFileSync(e,JSON.stringify(t,null,2)+`
|
|
11
|
+
`)},Zt=()=>{let e=Ae();try{let t=dt(e);return t.hasCompletedOnboarding===!0?(console.log(P.gray(" \u2713 hasCompletedOnboarding \u5DF2\u8BBE\u7F6E")),!0):(t.hasCompletedOnboarding=!0,pt(e,t),console.log(P.green(" \u2713 \u5DF2\u8BBE\u7F6E hasCompletedOnboarding: true")),!0)}catch(t){return console.error(P.red(` \u2717 \u8BBE\u7F6E hasCompletedOnboarding \u5931\u8D25: ${t}`)),!1}},eo=()=>{let e=Ee();try{Ke();let t=dt(e);(!t.env||typeof t.env!="object")&&(t.env={});let o=t.env,n={DISABLE_BUG_COMMAND:"1",DISABLE_ERROR_REPORTING:"1",DISABLE_TELEMETRY:"1"},s=!1;for(let[i,a]of Object.entries(n))o[i]!==a&&(o[i]=a,s=!0);return s?(pt(e,t),console.log(P.green(" \u2713 \u5DF2\u914D\u7F6E\u73AF\u5883\u53D8\u91CF:")),console.log(P.gray(" DISABLE_BUG_COMMAND=1")),console.log(P.gray(" DISABLE_ERROR_REPORTING=1")),console.log(P.gray(" DISABLE_TELEMETRY=1")),!0):(console.log(P.gray(" \u2713 \u73AF\u5883\u53D8\u91CF\u5DF2\u914D\u7F6E")),!0)}catch(t){return console.error(P.red(` \u2717 \u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF\u5931\u8D25: ${t}`)),!1}},to=()=>new Promise(e=>{console.log(P.cyan(" \u2192 \u6B63\u5728\u6DFB\u52A0 chrome-devtools MCP \u5DE5\u5177..."));let t=Qt("claude",["mcp","add","chrome-devtools","npx","chrome-devtools-mcp@latest","--scope","user"],{stdio:"pipe",shell:!0}),o="",n="";t.stdout?.on("data",s=>{o+=s.toString()}),t.stderr?.on("data",s=>{n+=s.toString()}),t.on("exit",s=>{s===0?(console.log(P.green(" \u2713 \u5DF2\u6DFB\u52A0 chrome-devtools MCP \u5DE5\u5177")),e(!0)):n.includes("already exists")||o.includes("already exists")?(console.log(P.gray(" \u2713 chrome-devtools MCP \u5DE5\u5177\u5DF2\u5B58\u5728")),e(!0)):(console.error(P.red(` \u2717 \u6DFB\u52A0 MCP \u5DE5\u5177\u5931\u8D25 (code: ${s})`)),n&&console.error(P.gray(` ${n.trim()}`)),e(!1))}),t.on("error",s=>{console.error(P.red(` \u2717 \u6267\u884C claude \u547D\u4EE4\u5931\u8D25: ${s.message}`)),console.log(P.yellow(" \u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 Claude Code CLI")),e(!1)})}),ut=async()=>{console.log(P.bold(`
|
|
12
12
|
\u{1F527} Claude Code \u521D\u59CB\u5316\u8BBE\u7F6E
|
|
13
|
-
`)),console.log(P.cyan("1. \u8BBE\u7F6E onboarding \u72B6\u6001"));let e=
|
|
14
|
-
2. \u914D\u7F6E\u9690\u79C1\u8BBE\u7F6E`));let t=
|
|
15
|
-
3. \u5B89\u88C5 MCP \u5DE5\u5177`));let o=await
|
|
16
|
-
\u914D\u7F6E\u6587\u4EF6\u4F4D\u7F6E:`)),console.log(P.gray(` - ${
|
|
13
|
+
`)),console.log(P.cyan("1. \u8BBE\u7F6E onboarding \u72B6\u6001"));let e=Zt();console.log(P.cyan(`
|
|
14
|
+
2. \u914D\u7F6E\u9690\u79C1\u8BBE\u7F6E`));let t=eo();console.log(P.cyan(`
|
|
15
|
+
3. \u5B89\u88C5 MCP \u5DE5\u5177`));let o=await to();console.log(""),console.log(e&&t&&o?P.green.bold("\u2705 \u521D\u59CB\u5316\u5B8C\u6210\uFF01"):P.yellow.bold("\u26A0\uFE0F \u90E8\u5206\u6B65\u9AA4\u672A\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u4E0A\u8FF0\u9519\u8BEF")),console.log(P.gray(`
|
|
16
|
+
\u914D\u7F6E\u6587\u4EF6\u4F4D\u7F6E:`)),console.log(P.gray(` - ${Ae()}`)),console.log(P.gray(` - ${Ee()}`)),console.log("")};import{execSync as oe}from"child_process";import*as C from"fs";import*as L from"path";import M from"chalk";var gt={official:{label:"\u5B98\u65B9",icon:"\u{1F3E2}"},featured:{label:"\u7CBE\u9009",icon:"\u2B50"},others:{label:"\u5176\u4ED6",icon:"\u{1F4E6}"}},ft=[{name:"frontend-design",description:"\u521B\u5EFA\u9AD8\u8D28\u91CF\u524D\u7AEF\u754C\u9762\u8BBE\u8BA1",group:"official",install:{type:"preset",name:"frontend-design"}},{name:"skill-creator",description:"\u521B\u5EFA\u65B0\u7684 Claude Code skills",group:"official",install:{type:"preset",name:"skill-creator"}},{name:"web-artifacts-builder",description:"\u6784\u5EFA\u53EF\u4EA4\u4E92\u7684 Web \u7EC4\u4EF6",group:"official",install:{type:"preset",name:"web-artifacts-builder"}},{name:"canvas-design",description:"Canvas \u7ED8\u56FE\u8BBE\u8BA1",group:"official",install:{type:"preset",name:"canvas-design"}},{name:"algorithmic-art",description:"\u7B97\u6CD5\u827A\u672F\u751F\u6210",group:"official",install:{type:"preset",name:"algorithmic-art"}},{name:"theme-factory",description:"\u4E3B\u9898\u5DE5\u5382 - \u521B\u5EFA UI \u4E3B\u9898",group:"official",install:{type:"preset",name:"theme-factory"}},{name:"mcp-builder",description:"\u6784\u5EFA MCP \u670D\u52A1\u5668",group:"official",install:{type:"preset",name:"mcp-builder"}},{name:"webapp-testing",description:"Web \u5E94\u7528\u6D4B\u8BD5",group:"official",install:{type:"preset",name:"webapp-testing"}},{name:"pdf",description:"PDF \u6587\u6863\u5904\u7406",group:"official",install:{type:"preset",name:"pdf"}},{name:"docx",description:"Word \u6587\u6863\u5904\u7406",group:"official",install:{type:"preset",name:"docx"}},{name:"pptx",description:"PowerPoint \u6F14\u793A\u6587\u7A3F\u5904\u7406",group:"official",install:{type:"preset",name:"pptx"}},{name:"xlsx",description:"Excel \u8868\u683C\u5904\u7406",group:"official",install:{type:"preset",name:"xlsx"}},{name:"brand-guidelines",description:"\u54C1\u724C\u6307\u5357\u751F\u6210",group:"official",install:{type:"preset",name:"brand-guidelines"}},{name:"doc-coauthoring",description:"\u6587\u6863\u534F\u4F5C\u7F16\u5199",group:"official",install:{type:"preset",name:"doc-coauthoring"}},{name:"internal-comms",description:"\u5185\u90E8\u901A\u4FE1\u6587\u6863",group:"official",install:{type:"preset",name:"internal-comms"}},{name:"slack-gif-creator",description:"Slack GIF \u521B\u5EFA\u5668",group:"official",install:{type:"preset",name:"slack-gif-creator"}},{name:"superpowers",description:"Claude Code Plan\u6A21\u5F0F\u5347\u7EA7\u7248\uFF0C\u8FDE\u7EED\u8FFD\u95EE\u8BA8\u8BBA\u786E\u5B9A\u5F00\u53D1\u65B9\u6848",group:"featured",install:{type:"plugin",marketplace:"obra/superpowers-marketplace",package:"superpowers@superpowers-marketplace"}},{name:"ui-ux-pro-max",description:"\u4E13\u4E1A UI/UX \u8BBE\u8BA1",group:"featured",install:{type:"github",url:"https://github.com/nextlevelbuilder/ui-ux-pro-max-skill/tree/main/.claude/skills/ui-ux-pro-max"}},{name:"Humanizer-zh",description:"\u53BB\u9664\u6587\u672C\u4E2D AI \u751F\u6210\u75D5\u8FF9\uFF0C\u6539\u5199\u5F97\u66F4\u81EA\u7136\u3001\u66F4\u50CF\u4EBA\u7C7B\u4E66\u5199",group:"featured",install:{type:"github",url:"https://github.com/op7418/Humanizer-zh"}},{name:"skill-writer",description:"\u6307\u5BFC\u7528\u6237\u4E3A Claude Code \u521B\u5EFA\u4EE3\u7406\u6280\u80FD",group:"others",install:{type:"github",url:"https://github.com/pytorch/pytorch/tree/main/.claude/skills/skill-writer"}}];function ht(e){return ft.filter(t=>t.group===e)}function yt(){return["official","featured","others"]}function mt(e){if(/^[\w-]+\/[\w-]+$/.test(e)){let[a,c]=e.split("/");return{owner:a,repo:c,branch:"main",path:""}}let t=e.match(/github\.com\/([^/]+)\/([^/]+)(?:\/tree\/([^/]+)(?:\/(.*))?)?/);if(!t)return null;let[,o,n,s="main",i=""]=t;return{owner:o,repo:n.replace(/\.git$/,""),branch:s,path:i}}function Ne(){return L.join(process.cwd(),".claude","skills")}function oo(){let e=Ne();return C.existsSync(e)?so(e):C.mkdirSync(e,{recursive:!0}),e}function so(e){try{let t=C.readdirSync(e,{withFileTypes:!0});for(let o of t)if(o.isDirectory()&&o.name.startsWith(".tmp-")){let n=L.join(e,o.name);C.rmSync(n,{recursive:!0})}}catch{}}function fe(e,t,o,n,s){let i=oo(),a=L.join(i,s);C.existsSync(a)&&(console.log(M.yellow(`Skill "${s}" already exists. Updating...`)),C.rmSync(a,{recursive:!0}));let c=`https://github.com/${e}/${t}.git`,l=L.join(i,`.tmp-${Date.now()}`);try{C.mkdirSync(l,{recursive:!0}),oe("git init",{cwd:l,stdio:"pipe"}),oe(`git remote add origin ${c}`,{cwd:l,stdio:"pipe"}),oe("git config core.sparseCheckout true",{cwd:l,stdio:"pipe"});let u=L.join(l,".git","info","sparse-checkout");C.writeFileSync(u,n?`${n}/
|
|
17
17
|
`:`*
|
|
18
|
-
`),
|
|
18
|
+
`),oe(`git pull --depth=1 origin ${o}`,{cwd:l,stdio:"pipe"});let m=n?L.join(l,n):l;if(!C.existsSync(m))throw new Error(`Path "${n}" not found in repository`);return _t(m,a),console.log(M.green(`Successfully installed skill "${s}"`)),!0}catch(u){let m=u instanceof Error?u.message:String(u);return console.error(M.red(`Failed to download skill: ${m}`)),!1}finally{C.existsSync(l)&&C.rmSync(l,{recursive:!0})}}function _t(e,t){C.mkdirSync(t,{recursive:!0});let o=C.readdirSync(e,{withFileTypes:!0});for(let n of o){if(n.name===".git")continue;let s=L.join(e,n.name),i=L.join(t,n.name);n.isDirectory()?_t(s,i):C.copyFileSync(s,i)}}function he(e){let t=ft.find(s=>s.name===e);if(t){if(t.install.type==="preset")return fe("anthropics","skills","main",`skills/${t.install.name}`,t.name);if(t.install.type==="github"){let s=mt(t.install.url);return s?fe(s.owner,s.repo,s.branch,s.path,t.name):(console.error(M.red(`Invalid GitHub URL in preset: ${t.install.url}`)),!1)}else if(t.install.type==="plugin")return console.error(M.yellow(`Plugin installation not yet supported for "${t.name}"`)),console.log(M.gray(`Marketplace: ${t.install.marketplace}`)),console.log(M.gray(`Package: ${t.install.package}`)),!1}let o=mt(e);if(!o)return console.error(M.red("Invalid GitHub URL or preset name")),console.log(M.gray("Examples:")),console.log(M.gray(" ccem skill add frontend-design")),console.log(M.gray(" ccem skill add https://github.com/owner/repo")),console.log(M.gray(" ccem skill add https://github.com/owner/repo/tree/main/path")),!1;let n;return o.path?n=L.basename(o.path):n=o.repo,fe(o.owner,o.repo,o.branch,o.path,n)}function St(){let e=Ne();return C.existsSync(e)?C.readdirSync(e,{withFileTypes:!0}).filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>({name:o.name,path:L.join(e,o.name)})):[]}function Pt(e){let t=Ne(),o=L.join(t,e);return C.existsSync(o)?(C.rmSync(o,{recursive:!0}),console.log(M.green(`Removed skill "${e}"`)),!0):(console.error(M.red(`Skill "${e}" not found`)),!1)}function no(e,t){try{return console.log(M.cyan(`Adding marketplace: ${e}...`)),oe(`claude plugin marketplace add ${e}`,{stdio:"inherit"}),console.log(M.cyan(`Installing package: ${t}...`)),oe(`claude plugin install ${t}`,{stdio:"inherit"}),console.log(M.green(`Successfully installed ${t}`)),!0}catch(o){let n=o instanceof Error?o.message:String(o);return console.error(M.red(`Failed to install from marketplace: ${n}`)),!1}}function At(e){switch(console.log(M.cyan(`Installing ${e.name}...`)),e.install.type){case"preset":let t={repo:"anthropics/skills",path:`skills/${e.install.name}`,branch:"main"},[o,n]=t.repo.split("/");return fe(o,n,t.branch,t.path,e.name);case"github":return he(e.install.url);case"plugin":return no(e.install.marketplace,e.install.package)}}import{render as co}from"ink";import{useState as Et,useEffect as ro}from"react";import{Box as Y,Text as V,useInput as io,useApp as ao}from"ink";import{jsx as $,jsxs as ie}from"react/jsx-runtime";function Ct({onSelect:e,onCancel:t}){let{exit:o}=ao(),n=yt(),[s,i]=Et(0),[a,c]=Et(0),l=n[s],m=[...ht(l),null],y=m.length-1;return ro(()=>{c(0)},[s]),io((p,_)=>{if(_.tab&&!_.shift){i(g=>(g+1)%n.length);return}if(_.tab&&_.shift){i(g=>(g-1+n.length)%n.length);return}if(_.upArrow){c(g=>Math.max(0,g-1));return}if(_.downArrow){c(g=>Math.min(y,g+1));return}if(_.return){let g=m[a];e(g===null?"custom":g);return}if(_.escape||p==="q"){t(),o();return}}),ie(Y,{flexDirection:"column",children:[$(Y,{marginBottom:1,children:n.map((p,_)=>{let g=gt[p],f=_===s;return $(Y,{marginRight:2,children:ie(V,{bold:f,color:f?"cyan":"gray",inverse:f,children:[" ",g.icon," ",g.label," "]})},p)})}),$(Y,{marginBottom:1,children:$(V,{color:"gray",children:"\u2500".repeat(50)})}),$(Y,{flexDirection:"column",children:m.map((p,_)=>{let g=_===a,f=g?"\u276F ":" ";return p===null?$(Y,{children:ie(V,{color:g?"yellow":"gray",children:[f,"\u8F93\u5165\u81EA\u5B9A\u4E49 GitHub URL"]})},"custom"):$(Y,{children:ie(V,{color:g?"cyan":void 0,children:[f,$(V,{bold:g,children:p.name}),ie(V,{color:"gray",children:[" - ",p.description]})]})},p.name)})}),$(Y,{marginTop:1,children:$(V,{color:"gray",children:"Tab \u5207\u6362\u5206\u7EC4 | \u2191\u2193 \u9009\u62E9 | Enter \u786E\u8BA4 | Esc \u53D6\u6D88"})})]})}import{jsx as lo}from"react/jsx-runtime";async function Rt(){return new Promise(e=>{let t=!1,{unmount:o,waitUntilExit:n}=co(lo(Ct,{onSelect:s=>{t||(t=!0,o(),e(s==="custom"?{type:"custom"}:{type:"skill",skill:s}))},onCancel:()=>{t||(t=!0,o(),e({type:"cancelled"}))}}));n().then(()=>{t||e({type:"cancelled"})})})}import Tt from"crypto";import x from"chalk";import po from"conf";var kt=new po({projectName:"claude-code-env-manager"}),uo=(e,t)=>{let o=Tt.scryptSync(t,"ccem-salt",32),n=Buffer.from(e,"base64"),s=n.subarray(0,16),i=n.subarray(16).toString("hex"),a=Tt.createDecipheriv("aes-256-cbc",o,s),c=a.update(i,"hex","utf8");return c+=a.final("utf8"),c},mo=(e,t)=>{if(!t.has(e))return e;let o=1,n=`${e}-remote`;for(;t.has(n);)o++,n=`${e}-remote-${o}`;return n},wt=async(e,t)=>{console.log(x.gray("Fetching from remote..."));let o;try{o=await fetch(e)}catch(l){console.error(x.red("Error: Failed to connect to server")),console.error(x.gray(l.message)),process.exit(1)}o.status===401&&(console.error(x.red("Error: Invalid key (HTTP 401)")),process.exit(1)),o.status===429&&(console.error(x.red("Error: Too many requests, please try again later")),process.exit(1)),o.ok||(console.error(x.red(`Error: Server returned HTTP ${o.status}`)),process.exit(1));let n;try{n=await o.json()}catch{console.error(x.red("Error: Invalid response format from server")),process.exit(1)}n.encrypted||(console.error(x.red("Error: Invalid response format from server")),process.exit(1));let s;try{let l=uo(n.encrypted,t);s=JSON.parse(l)}catch{console.error(x.red("Error: Decryption failed, check your --secret")),process.exit(1)}(!s.environments||typeof s.environments!="object")&&(console.error(x.red("Error: Invalid response format from server")),process.exit(1));let i=kt.get("registries"),a=new Set(Object.keys(i)),c=[];for(let[l,u]of Object.entries(s.environments)){let m=mo(l,a),y=m!==l,p={...u};p.ANTHROPIC_API_KEY&&(p.ANTHROPIC_API_KEY=le(p.ANTHROPIC_API_KEY)),i[m]=p,a.add(m),c.push({name:m,originalName:l,renamed:y})}kt.set("registries",i),console.log(x.green(`
|
|
19
|
+
Loaded ${c.length} environment(s) from remote:`));for(let l of c)l.renamed?console.log(x.yellow(` + ${l.originalName} \u2192 ${l.name} (renamed, local exists)`)):console.log(x.green(` + ${l.name} (new)`));console.log(x.gray(`
|
|
20
|
+
Run 'ccem ls' to see all environments.`))};var yo=ho(import.meta.url),_o=_e.dirname(yo),So=_e.resolve(_o,"..","package.json"),Po=JSON.parse(It.readFileSync(So,"utf-8")),b=new go,h=new fo({projectName:"claude-code-env-manager",defaults:{registries:{official:{ANTHROPIC_BASE_URL:"https://api.anthropic.com",ANTHROPIC_MODEL:"claude-sonnet-4-5-20250929",ANTHROPIC_SMALL_FAST_MODEL:"claude-haiku-4-5-20251001"}},current:"official",defaultMode:null}}),ae=["yolo","dev","readonly","safe","ci","audit"],W=null,se=!0;var X=null,Ao=e=>{let t=We();t?(W=t,se=!1):e&&Ve(e),X&&X.abort(),X=new AbortController;let o=X.signal;Je(o).then(n=>{if(o.aborted)return;let s=se||W&&n&&W.lastUpdated!==n.lastUpdated;W=n,se=!1,me(),s&&e&&e()}).catch(n=>{n.message!=="Aborted"&&(se=!1,me())})};b.name("ccem").description("Claude Code Environment Manager - \u7BA1\u7406 Claude Code \u73AF\u5883\u53D8\u91CF\u548C\u6743\u9650").version(Po.version).option("--mode","\u67E5\u770B\u5F53\u524D\u6743\u9650\u6A21\u5F0F").option("--list-modes","\u5217\u51FA\u6240\u6709\u53EF\u7528\u6743\u9650\u6A21\u5F0F");ae.forEach(e=>{let t=O[e];b.command(e).description(`\u4E34\u65F6\u5E94\u7528 ${t.name}\uFF0C\u9000\u51FA\u540E\u8FD8\u539F`).action(async()=>{let o=h.get("registries"),n=h.get("current"),s=o[n];await ge(e,s)})});var ve=(e,t)=>{if(!process.stdout.isTTY)return;let o=h.get("current"),s=h.get("registries")[o],i=h.get("defaultMode");s&&(console.log(Qe(o,{ANTHROPIC_BASE_URL:s.ANTHROPIC_BASE_URL,ANTHROPIC_API_KEY:s.ANTHROPIC_API_KEY?K(s.ANTHROPIC_API_KEY):void 0,ANTHROPIC_MODEL:s.ANTHROPIC_MODEL,ANTHROPIC_SMALL_FAST_MODEL:s.ANTHROPIC_SMALL_FAST_MODEL},i)),console.log(""),console.log(Ze(e,t)),console.log(et()),console.log(""))},Eo=async e=>{let t=h.get("registries");if(!t[e]){console.error(d.red(`Environment '${e}' not found.`));return}h.set("current",e),process.stdout.isTTY?console.log(d.green(`Switched to environment '${e}'`)):console.error(d.green(`Switched to environment '${e}'`)),ve(null,!1);let o=t[e],n=[];o.ANTHROPIC_BASE_URL&&n.push(`export ANTHROPIC_BASE_URL="${o.ANTHROPIC_BASE_URL}"`),o.ANTHROPIC_API_KEY&&n.push(`export ANTHROPIC_API_KEY="${K(o.ANTHROPIC_API_KEY)}"`),o.ANTHROPIC_MODEL&&n.push(`export ANTHROPIC_MODEL="${o.ANTHROPIC_MODEL}"`),o.ANTHROPIC_SMALL_FAST_MODEL&&n.push(`export ANTHROPIC_SMALL_FAST_MODEL="${o.ANTHROPIC_SMALL_FAST_MODEL}"`),process.stdout.isTTY?(console.log(d.yellow(`
|
|
19
21
|
To apply to current shell immediately, run:`)),console.log(d.cyan("eval $(ccem env)")),console.log(d.yellow(`
|
|
20
|
-
Or manually export:`)),n.forEach(s=>console.log(s))):n.forEach(s=>console.log(s))};
|
|
21
|
-
\u8BBE\u7F6E\u9ED8\u8BA4\u6A21\u5F0F: ccem setup default-mode --dev`)),console.log(d.gray("\u6E05\u9664\u9ED8\u8BA4\u6A21\u5F0F: ccem setup default-mode --reset")),console.log(d.gray("\u53EF\u7528\u6A21\u5F0F: "+
|
|
22
|
+
Or manually export:`)),n.forEach(s=>console.log(s))):n.forEach(s=>console.log(s))};b.command("ls").description("List all configured environments").action(()=>{let e=h.get("registries"),t=h.get("current"),o=new Ot({head:["Name","Base URL","Model"],style:{head:["cyan"]}});Object.keys(e).forEach(n=>{let s=e[n],i=n===t?d.green("* "):" ";o.push([i+n,s.ANTHROPIC_BASE_URL||"-",s.ANTHROPIC_MODEL||"-"])}),console.log(o.toString())});b.command("use <name>").description("Switch to a specific environment").action(async e=>{await Eo(e)});b.command("add <name>").description("Add a new environment configuration").action(async e=>{let t=h.get("registries");if(t[e]){console.log(d.red(`Environment '${e}' already exists.`));return}let{usePreset:o}=await F.prompt([{type:"confirm",name:"usePreset",message:"Do you want to use a preset configuration?",default:!0}]),n={};if(o){let{presetName:i}=await F.prompt([{type:"list",name:"presetName",message:"Select a preset:",choices:Object.keys(Ce)}]);n=Ce[i]}let s=await F.prompt([{type:"input",name:"ANTHROPIC_BASE_URL",message:"Enter ANTHROPIC_BASE_URL:",default:n.ANTHROPIC_BASE_URL||"https://api.anthropic.com"},{type:"password",name:"ANTHROPIC_API_KEY",message:"Enter ANTHROPIC_API_KEY:"},{type:"input",name:"ANTHROPIC_MODEL",message:"Enter ANTHROPIC_MODEL:",default:n.ANTHROPIC_MODEL||"claude-sonnet-4-5-20250929"},{type:"input",name:"ANTHROPIC_SMALL_FAST_MODEL",message:"Enter ANTHROPIC_SMALL_FAST_MODEL:",default:n.ANTHROPIC_SMALL_FAST_MODEL||"claude-haiku-4-5-20251001"}]);s.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=le(s.ANTHROPIC_API_KEY)),t[e]=s,h.set("registries",t),console.log(d.green(`Environment '${e}' added successfully.`))});b.command("del <name>").description("Delete an environment configuration").action(e=>{let t=h.get("registries");if(!t[e]){console.log(d.red(`Environment '${e}' not found.`));return}if(e==="official"){console.log(d.red("Cannot delete default 'official' environment."));return}delete t[e],h.set("registries",t),h.get("current")===e&&(h.set("current","official"),console.log(d.yellow("Deleted current environment. Switched back to 'official'."))),console.log(d.green(`Environment '${e}' deleted.`))});b.command("current").description("Show current environment name").action(()=>{let e=h.get("current");console.log(d.green(e))});b.command("env").description("Output environment variables for shell eval").option("--json","Output as JSON").action(e=>{let t=h.get("registries"),o=h.get("current"),n=t[o];if(!n)return;let s={...n};s.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=K(s.ANTHROPIC_API_KEY)),e.json?console.log(JSON.stringify(s,null,2)):(s.ANTHROPIC_BASE_URL&&console.log(`export ANTHROPIC_BASE_URL="${s.ANTHROPIC_BASE_URL}"`),s.ANTHROPIC_API_KEY&&console.log(`export ANTHROPIC_API_KEY="${s.ANTHROPIC_API_KEY}"`),s.ANTHROPIC_MODEL&&console.log(`export ANTHROPIC_MODEL="${s.ANTHROPIC_MODEL}"`),s.ANTHROPIC_SMALL_FAST_MODEL&&console.log(`export ANTHROPIC_SMALL_FAST_MODEL="${s.ANTHROPIC_SMALL_FAST_MODEL}"`))});b.command("run <command...>").description("Run a command with the current environment variables").action(e=>{let t=h.get("registries"),o=h.get("current"),n=t[o];n||(console.error(d.red("No environment configuration found.")),process.exit(1));let s={...process.env};n.ANTHROPIC_BASE_URL&&(s.ANTHROPIC_BASE_URL=n.ANTHROPIC_BASE_URL),n.ANTHROPIC_API_KEY&&(s.ANTHROPIC_API_KEY=K(n.ANTHROPIC_API_KEY||"")),n.ANTHROPIC_MODEL&&(s.ANTHROPIC_MODEL=n.ANTHROPIC_MODEL),n.ANTHROPIC_SMALL_FAST_MODEL&&(s.ANTHROPIC_SMALL_FAST_MODEL=n.ANTHROPIC_SMALL_FAST_MODEL);let[i,...a]=e;Mt(i,a,{env:s,stdio:"inherit",shell:!0}).on("exit",l=>{process.exit(l??0)})});var Be=b.command("setup").description("Setup commands for permanent configurations");Be.command("perms").description("\u6C38\u4E45\u914D\u7F6E\u6743\u9650\u6A21\u5F0F").option("--yolo","\u5E94\u7528 YOLO \u6A21\u5F0F\uFF08\u5168\u90E8\u653E\u5F00\uFF09").option("--dev","\u5E94\u7528\u5F00\u53D1\u6A21\u5F0F").option("--readonly","\u5E94\u7528\u53EA\u8BFB\u6A21\u5F0F").option("--safe","\u5E94\u7528\u5B89\u5168\u6A21\u5F0F").option("--ci","\u5E94\u7528 CI/CD \u6A21\u5F0F").option("--audit","\u5E94\u7528\u5BA1\u8BA1\u6A21\u5F0F").option("--reset","\u91CD\u7F6E\u6743\u9650\u914D\u7F6E").action(function(){let e=this.opts();if(e.reset){at();return}for(let t of ae)if(e[t]){it(t);return}console.log(d.yellow("\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6743\u9650\u6A21\u5F0F\uFF0C\u4F8B\u5982: ccem setup perms --dev")),console.log(d.gray("\u53EF\u7528\u6A21\u5F0F: "+ae.join(", "))),console.log(d.gray("\u91CD\u7F6E\u6743\u9650: ccem setup perms --reset"))});Be.command("default-mode").description("\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F").option("--yolo","YOLO \u6A21\u5F0F").option("--dev","\u5F00\u53D1\u6A21\u5F0F").option("--readonly","\u53EA\u8BFB\u6A21\u5F0F").option("--safe","\u5B89\u5168\u6A21\u5F0F").option("--ci","CI/CD \u6A21\u5F0F").option("--audit","\u5BA1\u8BA1\u6A21\u5F0F").option("--reset","\u6E05\u9664\u9ED8\u8BA4\u6A21\u5F0F").action(function(){let e=this.opts();if(e.reset){h.set("defaultMode",null),console.log(d.green("\u5DF2\u6E05\u9664\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F"));return}for(let o of ae)if(e[o]){h.set("defaultMode",o),console.log(d.green(`\u5DF2\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F: ${O[o].name}`)),console.log(d.gray("\u4E0B\u6B21\u542F\u52A8 ccem \u65F6\u5C06\u9ED8\u8BA4\u4F7F\u7528\u6B64\u6A21\u5F0F"));return}let t=h.get("defaultMode");t&&O[t]?console.log(d.green(`\u5F53\u524D\u9ED8\u8BA4\u6A21\u5F0F: ${O[t].name}`)):console.log(d.yellow("\u672A\u8BBE\u7F6E\u9ED8\u8BA4\u6743\u9650\u6A21\u5F0F")),console.log(d.gray(`
|
|
23
|
+
\u8BBE\u7F6E\u9ED8\u8BA4\u6A21\u5F0F: ccem setup default-mode --dev`)),console.log(d.gray("\u6E05\u9664\u9ED8\u8BA4\u6A21\u5F0F: ccem setup default-mode --reset")),console.log(d.gray("\u53EF\u7528\u6A21\u5F0F: "+ae.join(", ")))});Be.command("init").description("\u521D\u59CB\u5316 Claude Code \u5168\u5C40\u914D\u7F6E\uFF08\u8DF3\u8FC7 onboarding\u3001\u7981\u7528\u9065\u6D4B\u3001\u5B89\u88C5 MCP \u5DE5\u5177\uFF09").action(async()=>{await ut()});var De=b.command("skill").description("\u7BA1\u7406 Claude Code skills");De.command("add [url]").description("\u6DFB\u52A0 skill\uFF08\u4ECE\u5B98\u65B9\u9884\u8BBE\u6216 GitHub URL\uFF09").action(async e=>{if(e)he(e);else{let t=await Rt();if(t.type==="cancelled"){console.log(d.yellow("\u5DF2\u53D6\u6D88"));return}if(t.type==="custom"){let{customUrl:o}=await F.prompt([{type:"input",name:"customUrl",message:"\u8F93\u5165 GitHub URL:",validate:n=>n.trim()?!n.includes("github.com")&&!/^[\w-]+\/[\w-]+$/.test(n)?"\u8BF7\u8F93\u5165\u6709\u6548\u7684 GitHub URL \u6216 owner/repo \u683C\u5F0F":!0:"\u8BF7\u8F93\u5165\u6709\u6548\u7684 URL"}]);he(o)}else t.skill&&At(t.skill)}});De.command("ls").description("\u5217\u51FA\u5DF2\u5B89\u88C5\u7684 skills").action(()=>{let e=St();if(e.length===0){console.log(d.yellow("\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u5B89\u88C5\u4EFB\u4F55 skill")),console.log(d.gray("\u4F7F\u7528 ccem skill add \u6DFB\u52A0 skills"));return}let t=new Ot({head:["Name","Path"],style:{head:["cyan"]}});e.forEach(o=>{t.push([d.green(o.name),d.gray(o.path)])}),console.log(t.toString())});De.command("rm <name>").description("\u5220\u9664\u5DF2\u5B89\u88C5\u7684 skill").action(e=>{Pt(e)});b.command("load <url>").description("\u4ECE\u8FDC\u7A0B\u670D\u52A1\u5668\u52A0\u8F7D\u73AF\u5883\u914D\u7F6E").requiredOption("--secret <secret>","\u89E3\u5BC6\u5BC6\u94A5").action(async(e,t)=>{await wt(e,t.secret)});b.action(async e=>{if(e.mode){ct();return}if(e.listModes){lt();return}for(Ao(()=>{ye.cursorTo(process.stdout,0,0),ye.clearScreenDown(process.stdout),ve(W,se),console.log("");let o=h.get("defaultMode");console.log(d.gray("?")+" "+d.gray("Select action")+" "+d.cyan("(Use arrow keys)")),Ie(o).forEach((s,i)=>{let a=i===0?d.cyan("\u276F"):" ";console.log(a+" "+s.name)})});;){console.clear(),ve(W,se),console.log("");let o=h.get("defaultMode"),n=h.get("registries"),s=h.get("current"),i=n[s],{action:a}=await F.prompt([{type:"list",name:"action",message:d.gray("Select action"),choices:Ie(o),prefix:d.gray("?")}]);if(a==="start"){if(X&&(X.abort(),X=null),me(),i||(re.error("No environment configuration found."),process.exit(1)),o&&O[o])await ge(o,i);else{let c={...process.env};i.ANTHROPIC_BASE_URL&&(c.ANTHROPIC_BASE_URL=i.ANTHROPIC_BASE_URL),i.ANTHROPIC_API_KEY&&(c.ANTHROPIC_API_KEY=K(i.ANTHROPIC_API_KEY||"")),i.ANTHROPIC_MODEL&&(c.ANTHROPIC_MODEL=i.ANTHROPIC_MODEL),i.ANTHROPIC_SMALL_FAST_MODEL&&(c.ANTHROPIC_SMALL_FAST_MODEL=i.ANTHROPIC_SMALL_FAST_MODEL),console.log(ot()),Mt("claude",[],{env:c,stdio:"inherit",shell:!0}).on("exit",u=>{process.exit(u??0)})}return}else if(a==="usage")console.clear(),W?console.log(st(W)):re.warning("No usage data available"),await F.prompt([{type:"input",name:"continue",message:d.gray("Press Enter to continue..."),prefix:""}]);else if(a==="switch"){let{selected:c}=await F.prompt([{type:"list",name:"selected",message:d.gray("Select environment"),choices:tt(n,s),prefix:d.gray("?"),default:s}]);h.set("current",c)}else if(a==="perm"){let{permMode:c}=await F.prompt([{type:"list",name:"permMode",message:d.gray("Select permission mode"),choices:xe(null,!1),prefix:d.gray("?")}]);if(c!=="back"){await ge(c,i);return}}else if(a==="setDefault"){let c=h.get("defaultMode"),{selectedMode:l}=await F.prompt([{type:"list",name:"selectedMode",message:d.gray("Set default permission mode"),choices:xe(c,!0),prefix:d.gray("?")}]);l==="clear"?(h.set("defaultMode",null),re.success("Default mode cleared"),await new Promise(u=>setTimeout(u,800))):l!=="back"&&(h.set("defaultMode",l),re.success(`Default mode set: ${O[l].name}`),await new Promise(u=>setTimeout(u,800)))}else process.exit(0)}});b.parse(process.argv);
|