Files
claude-code/src/commands/env/index.ts
claude-code-best fdddb6dbe8 feat: 添加工具类命令(teleport、recap、break-cache、env、tui 等)
- /teleport: 从 claude.ai 恢复会话
- /recap: 生成会话摘要
- /break-cache: 提示缓存管理(once/always/off/status)
- /env: 环境信息展示(含密钥脱敏)
- /tui: 无闪烁 TUI 模式管理
- /onboarding: 引导流程
- /perf-issue: 性能问题诊断
- /debug-tool-call: 工具调用调试
- /usage: 用量统计(合并 /cost 和 /stats 别名)

Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
2026-05-09 23:04:31 +08:00

103 lines
2.7 KiB
TypeScript

import type { Command, LocalCommandResult } from '../../types/command.js'
import { getSessionId } from '../../bootstrap/state.js'
/**
* /env — show the user a snapshot of the current environment, claude config,
* feature flags, and version info. All secrets are masked.
*
* Pure-local command: no Anthropic backend dependency. Restored from stub
* 2026-04-29 (was Anthropic-internal in upstream; safe to expose to fork
* users since output is local-only).
*/
const SECRET_KEY_PATTERNS = [
/token/i,
/secret/i,
/password/i,
/api[_-]?key/i,
/auth/i,
/private/i,
/credential/i,
/jwt/i,
/session[_-]?id$/i,
]
function isSecretKey(key: string): boolean {
return SECRET_KEY_PATTERNS.some(rx => rx.test(key))
}
function maskValue(value: string): string {
if (value.length <= 8) return '***'
return `${value.slice(0, 4)}${value.slice(-2)} (${value.length} chars)`
}
const ENV_PREFIX_ALLOWLIST = [
'CLAUDE_',
'FEATURE_',
'ANTHROPIC_',
'BUN_',
'NODE_',
'GEMINI_',
'OPENAI_',
'GROK_',
'CCR_',
'KAIROS_',
'BUGHUNTER_',
]
function shouldShowEnv(key: string): boolean {
return ENV_PREFIX_ALLOWLIST.some(prefix => key.startsWith(prefix))
}
function formatEnvVars(): string {
const entries = Object.entries(process.env)
.filter(([k]) => shouldShowEnv(k))
.map(([k, v]): [string, string] => {
const display = isSecretKey(k) && v ? maskValue(v) : (v ?? '')
return [k, display]
})
.sort(([a], [b]) => a.localeCompare(b))
if (entries.length === 0) {
return ' (no recognized env vars set)'
}
return entries.map(([k, v]) => ` ${k}=${v}`).join('\n')
}
function formatRuntime(): string {
const lines = [
` platform: ${process.platform} ${process.arch}`,
` cwd: ${process.cwd()}`,
` pid: ${process.pid}`,
` bun: ${typeof Bun !== 'undefined' ? Bun.version : 'n/a'}`,
` node: ${process.version}`,
` session: ${getSessionId()}`,
]
return lines.join('\n')
}
const env: Command = {
type: 'local',
name: 'env',
description: 'Show current environment, runtime, and feature flags',
isHidden: false,
isEnabled: () => true,
supportsNonInteractive: true,
load: async () => ({
call: async (): Promise<LocalCommandResult> => {
const text = [
'## Runtime',
formatRuntime(),
'',
'## Environment Variables (allowlisted prefixes)',
formatEnvVars(),
'',
'_Secrets matching token/password/auth/api_key are masked. Set additional `CLAUDE_*` / `FEATURE_*` env vars to see them here._',
].join('\n')
return { type: 'text', value: text }
},
}),
}
export default env