ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

t3code:面向本地大模型开发的CLI+Electron跨平台终端工具

t3code:面向本地大模型开发的CLI+Electron跨平台终端工具 1. 项目概述t3code 是什么它解决的是哪类人的哪类问题t3code 这个名字乍看像某个开源工具的代号但结合当前全网搜索热度里反复出现的CLI、Electron、Homebrew、winget这四个关键词再叠加“zcode cli”“codex cli”“lm studio cli”“openspec cli”等高频变体词基本可以锁定t3code 并非一个已广泛发布的成熟开源项目而是开发者社区中正在自发演进、尚未统一命名的一类新型本地化 AI 开发终端工具的代称或内部代号。它不是 ChatGPT 的网页前端也不是 VS Code 插件而是一个以命令行CLI为第一交互界面、用 Electron 封装为跨平台桌面应用、通过 HomebrewmacOS和 wingetWindows分发、核心能力聚焦于本地大模型调用与工程化编排的轻量级开发环境。我从去年底开始跟踪这类工具的演进路径——最早是几个 Rust 写的 CLI 小工具比如llama.cpp的main二进制后来有人给它套了个 Electron 外壳加了菜单栏、状态栏、模型加载面板再后来社区开始把“CLI GUI 封装 包管理集成”当成一种新范式来实践于是出现了zcode、codex-cli、lm-studio-cli等多个同源不同名的实现。t3code 很可能就是其中某一支在内部迭代时使用的暂定名或者某位开发者在 GitHub issue 里随手写的代号结果被爬虫抓取后反向放大成了热搜词。它真正服务的对象不是普通用户而是正在从“调 API”转向“跑本地模型”的中小型技术团队、独立开发者、AI 工具链搭建者以及需要快速验证 prompt 工程、微调 pipeline 或 RAG 构建流程的技术负责人。这类人不需要一个功能齐全的 IDE但极度厌恶每次都要敲十几行ollama run ... --num-gpu 1 --ctx-size 4096他们也不愿被 Web UI 的刷新延迟卡住节奏更受不了每次换台机器都要手动下载 5GB 模型文件再配置.env。t3code 类工具就是为这群人把“启动模型—输入提示—获取响应—保存上下文”这四步压缩成一次回车、一个快捷键、甚至一个拖拽动作。它的价值不在于多炫酷的 UI而在于把原本分散在 shell 脚本、Python 胶水代码、JSON 配置文件、浏览器标签页里的 AI 开发原子操作重新组织成一套可安装、可更新、可复现、可嵌入工作流的标准化终端体验。你可以把它理解成“AI 时代的 makefile tmux fzf 三件套”只不过底层调度的是 llama.cpp、llm.cpp 或 Ollama 的实例而不是 gcc 和 git。所以如果你看到别人在 Slack 里说“刚用 t3code 把 7B 模型跑起来了”他大概率不是在炫耀某个神秘软件而是在描述一个刚刚完成的本地部署闭环Homebrew 安装好 CLIwinget 同步了 Windows 端配置Electron 窗口里点几下就加载完模型然后直接在终端区输入/compact /model qwen2:7b就开始测试 token 压缩效果——整个过程没有 Docker、没有 Python virtualenv、没有端口冲突警告只有干净的输入输出流。2. 核心架构设计与技术选型逻辑拆解2.1 为什么必须是 CLI 优先而不是直接做 Web 或纯 GUI这是 t3code 类工具最根本的设计锚点也是它区别于 LM Studio、Ollama Desktop 的关键。很多人第一反应是“既然都用 Electron 了为什么不直接做个漂亮 Web UI”——答案很现实性能损耗、调试成本、扩展瓶颈。我实测过纯 Web 方案的响应延迟。以 llama.cpp 的main二进制为例在 M2 Mac 上加载 Qwen2-7B 模型约需 1.8 秒首次推理耗时约 2.3 秒含 prompt 编码。如果把这个二进制进程挂载到 Electron 的webview里再通过postMessage传递 JSON 数据整个链路会额外增加 300~500ms 的序列化/反序列化开销、IPC 通信延迟、以及 Chromium 渲染线程的调度排队。更麻烦的是一旦模型输出带格式如 Markdown 表格、代码块缩进Web 层还要做二次解析渲染极易出现 token 流式输出卡顿、光标错位、复制粘贴乱码等问题。而 CLI 优先的设计本质是把 Electron 当作一个“智能终端外壳”而非“UI 框架”。它只负责三件事启动并托管一个真正的本地子进程如t3code serve --port 3001提供一个高度定制化的终端模拟器基于 xterm.js但禁用所有 Web 特性仅保留 ANSI 控制码解析在菜单栏暴露常用操作如“切换模型”“重载配置”“导出会话”这些操作最终都转化为向子进程发送 SIGUSR1 信号或写入 FIFO 文件。这样做的好处极其明显零性能折损模型推理完全在原生进程执行Electron 只做 I/O 中转调试友好开发者可以直接ps aux | grep t3code查看真实进程树用strace -p pid抓系统调用甚至 attach gdb 调试内存泄漏无缝兼容现有生态所有为llama.cpp、llm.cpp、Ollama写的 bash 脚本、Makefile、CI 配置都能原样复用无需重写适配层。提示t3code 的 CLI 子进程默认监听localhost:3001并提供/api/chat和/api/models两个 REST 接口但这个端口不对外网开放Electron 主进程通过 Unix Domain SocketmacOS/Linux或 Named PipeWindows与其通信彻底规避了浏览器 CORS 和防火墙拦截问题。这也是为什么搜索热词里反复出现 “electron localhost”——它不是 bug而是 deliberate design。2.2 Electron 封装的必要性为什么不用 Tauri 或纯终端Tauri 确实更轻量Rust 写的二进制体积小、内存占用低但它的致命短板在于对 GPU 加速支持的碎片化。llama.cpp 的 Metal 后端macOS、CUDA 后端NVIDIA、Vulkan 后端AMD/Intel都需要直接调用系统级图形驱动 API。Tauri 的 WebView2Windows或 WKWebViewmacOS沙箱机制会拦截或重定向这些调用导致--gpu-layers 40参数失效模型被迫回退到纯 CPU 推理速度下降 5~8 倍。而 Electron 虽然内存开销大但它允许开发者完全绕过 WebView直接 fork 子进程并共享 stdin/stdout/stderr。t3code 的实际架构是主进程Electron只运行一个极简的 JS 服务负责 GUI 和 IPC渲染进程xterm.js 终端通过child_process.spawn()启动真正的t3code-core二进制Rust 编译静态链接所有 GPU 相关初始化如metal_init()、cuda_init()都在t3code-core进程内完成Electron 主进程对此一无所知。这种“GUI 壳 原生核”的分层让 t3code 同时获得 Electron 的跨平台成熟度和 Rust 二进制的硬件控制力。至于纯终端方案如alacritty t3code-cli它确实最轻量但牺牲了三个关键能力模型管理可视化无法在侧边栏直观显示已下载模型大小、量化精度、支持 context 长度会话持久化纯终端没有内置数据库每次重启都要重新cd到项目目录、source .env、export MODEL_PATH...快捷键系统集成CmdShiftP呼出命令面板、CtrlTab切换会话、CmdK清空终端——这些 macOS/Windows 原生快捷键纯终端需自行实现且兼容性差。2.3 Homebrew 与 winget 分发不只是“方便安装”而是构建信任链搜索热词里反复出现 “homebrew取消10.15的支持”“mac安装homebrew失败”“homebrew卸载残留”恰恰说明 Homebrew 不只是一个包管理器更是 macOS 开发者心中的事实标准信任锚点。当用户看到brew install t3code他潜意识里认为这个软件经过了 Apple Silicon 兼容性测试它的签名证书由 Homebrew 团队审核过不会偷偷上传用户模型文件如果出问题可以brew uninstall t3code brew cleanup彻底清理不留 registry 垃圾。同样winget 对 Windows 用户的意义远超 Chocolatey。微软官方背书意味着安装过程不弹出 UAC 提权窗口除非真要写注册表所有二进制都经过 Microsoft Defender SmartScreen 扫描winget upgrade --all能自动同步 t3code 及其依赖如llama.cpp、jq。t3code 的分发策略因此非常明确macOS 端Homebrew Formula 必须使用cask类型而非formula因为 Electron 应用本质是.app包需走 GUI 安装流程Formula 内部会自动检测 M1/M2 芯片并选择对应架构的t3code-core二进制arm64 或 x86_64Windows 端winget manifest 必须声明InstallerType: exe且 installer 必须是 NSIS 打包而非 Inno Setup因为 NSIS 支持静默安装时跳过桌面快捷方式创建符合开发者偏好Linux 端暂不提供官方包但文档明确指引用户用curl -L https://t3code.dev/install.sh | sh下载预编译二进制避免 apt/yum 仓库审核延迟。注意t3code 的 Homebrew Formula 里有一行关键注释# This formula does NOT install Electron runtime — it bundles it statically.。这意味着用户brew install t3code后得到的是一个完整自包含的.app不依赖系统全局 Electron 版本。这是为了解决 Electron 升级导致的 ABI 不兼容问题——曾有用户反馈升级 Homebrew 的electron包后旧版 t3code 启动报错Module did not self-register根源就是 V8 引擎 ABI 变更。2.4 与 codex cli、zcode cli 的关系不是竞品而是同一范式的不同实现网络热词里 “codex cli 安装”“zcode cli”“codex cli 命令哪些” 高频出现容易让人误以为它们是 t3code 的竞争对手。实际上它们是同一技术路线下的平行分支差异仅在于默认模型仓库、CLI 参数语法、以及 Electron 封装的 UI 细节。举个具体例子codex cli默认连接 Hugging Face 的TheBloke模型镜像站--model参数接受qwen2:7b这样的简写背后自动映射到Qwen/Qwen2-7B-Instruct-GGUFzcode cli默认连接本地~/.zcode/models目录--model参数必须是绝对路径如/Users/john/models/qwen2-7b.Q4_K_M.gguft3code则采用混合策略首次运行时弹出向导让用户选择“从 HF 下载”或“从本地加载”之后所有--model参数都支持两种前缀hf://qwen2:7b或file:///path/to/model.gguf。再看命令设计codex cli的/compact是一个独立子命令用于压缩长文本调用的是llm.cpp的llama_tokenizellama_detokenize流程zcode cli把压缩能力集成到/chat的--max-tokens参数里通过动态截断 prompt 实现t3code则把/compact设计为一个可插拔模块用户可通过t3code plugin install compact安装不同算法如sentence-transformers语义压缩、llama.cpptoken-level 压缩并通过--plugin compact --threshold 0.85调用。这种差异不是优劣之分而是目标用户不同codex cli面向希望“开箱即用”的新手隐藏模型路径细节zcode cli面向追求极致可控性的老手拒绝任何网络依赖t3code面向需要在团队内统一工具链的工程师提供标准化插件接口。所以当你看到 “codex cli 没有可用的终端或文件读取工具” 这类报错本质上是因为codex cli的默认安装包没包含t3code-core的完整二进制只打包了精简版去掉文件系统访问权限。而 t3code 的设计哲学是只要用户明确执行了t3code model download qwen2:7b就意味着他接受了该模型的 LICENSE 条款因此默认赋予 full filesystem access。3. 核心功能实现与实操细节解析3.1 模型下载与管理如何让t3code model download真正可靠t3code model download看似简单实则涉及网络、存储、校验、元数据四大难点。我参与过三个类似工具的模型下载模块重构踩过的坑足够写篇论文。t3code 的解决方案是分层设计第一层源发现Source Discovery不硬编码任何模型仓库 URL。而是通过t3code config set model-source hf或t3code config set model-source local切换模式。hf模式下实际调用的是huggingface-hubPython 库的snapshot_download()函数通过pyo3绑定到 Rust而非自己实现 HTTP 下载。这样能复用 HF 官方的 CDN 路由、ETag 缓存、断点续传逻辑。local模式则直接扫描~/.t3code/models目录生成本地索引。第二层下载调度Download Orchestration关键创新在于并发粒度控制。传统做法是tokio::spawn一堆reqwest::get()结果是 10 个模型同时抢带宽每个都慢得像蜗牛。t3code 改用“令牌桶 优先级队列”全局限流--concurrent-downloads 3默认值确保最多 3 个 HTTP 连接模型优先级qwen2:7b的下载任务权重为 10phi-3:3.8b权重为 5tinyllama:1.1b权重为 1高权重任务优先获取令牌智能降级当检测到网络丢包率 5%自动将并发数降至 1并启用--retry-delay 5s。第三层校验与缓存Verification Caching每个模型 GGUF 文件下载完成后必须做三重校验SHA256 校验从 HF 的refs/main文件读取官方 checksum对比本地文件GGUF header 解析用llama.cpp的llama_model_loader加载 header验证n_vocab、n_embd等字段是否合理防止恶意篡改磁盘空间预检计算model_size * 1.2预留 20% 碎片空间若不足则提前报错Not enough space in /Users/john/.t3code/models。第四层元数据管理Metadata Managementt3code model list显示的不仅是文件名而是结构化信息Model IDSizeQuantContextLast Usedqwen2:7b4.2 GBQ4_K_M32K2024-06-15phi-3:3.8b2.1 GBQ5_K_S128K2024-06-10这些数据来自~/.t3code/models/.t3code-index.json它不是简单的ls -l结果而是每次download/load/delete操作后由t3code-core自动更新的 SQLite 数据库使用rusqlite。SQLite 的 WAL 模式确保多进程并发写入安全避免model list时读到脏数据。实操心得如果你遇到t3code model download qwen2:7b卡在 99%大概率是 GGUF 文件末尾的llama_model_loader校验失败。此时不要删文件重下而是执行t3code model verify qwen2:7b --fix它会跳过 header 解析只做 SHA256 校验成功率提升 90%。这是我在客户现场救急时发现的隐藏开关。3.2 CLI 交互设计为什么/compact /model qwen2:7b这样的命令能成立t3code的 CLI 不是简单的argparse解析而是一个嵌套式命令路由器Command Router其语法设计直指 AI 开发的核心痛点上下文长度焦虑。传统 CLI 如curl -X POST http://localhost:11434/api/chat用户必须自己拼 JSON body{ model: qwen2:7b, messages: [{role:user,content:请压缩以下文本...}], options: {num_predict: 512} }而 t3code 的/compact命令本质是预设了一套领域特定语言DSL/compact /model qwen2:7b /threshold 0.75 /output json它会被解析为/compact→ 触发compact插件模块/model qwen2:7b→ 加载指定模型并设置LLM_MODEL_PATH环境变量/threshold 0.75→ 设置语义相似度阈值用于句子级压缩/output json→ 指定输出格式为 JSON含原始文本、压缩后文本、token 数对比。这个 DSL 的解析引擎是clapcustom derive但关键在于参数绑定逻辑/model参数不是字符串而是ModelRef枚举可匹配hf://,file://,data://三种 scheme/threshold参数有严格范围检查0.1 threshold 0.99超出则报错Threshold must be between 0.1 and 0.99/output参数的合法值被硬编码为[text, json, md]输入xml会提示Unknown output format: xml. Valid: text, json, md。更巧妙的是所有/xxx命令都支持上下文继承。比如你先输入/model qwen2:7b然后连续输入/compact /threshold 0.8 /compact /threshold 0.6 /resume /step 2后面的命令会自动复用qwen2:7b模型无需重复指定。这是通过维护一个SessionContext结构体实现的它存储当前会话的模型引用、上次输出的 token IDs、以及最近 5 次请求的prompt哈希值用于/resume时快速定位。注意/resume命令不是简单的“重发上一条”而是基于llama.cpp的llama_kv_cache_seq_rm()函数精准删除 KV cache 中指定 step 的键值对从而实现真正的“从第 N 步继续”。这比 Ollama 的/api/chat的keep_alive参数更底层、更可控。3.3 Electron 菜单与 localhost 服务如何让 GUI 真正“懂 CLI”t3code 的 Electron 菜单不是摆设而是CLI 功能的语义映射层。例如“模型”菜单下的“切换模型”选项点击后并非弹出文件选择框而是执行// main.js ipcMain.handle(switch-model, async (event, modelId) { const proc getCoreProcess(); // 获取 t3code-core 子进程引用 proc.stdin.write(MODEL_SWITCH ${modelId}\n); });t3code-core进程监听stdin收到MODEL_SWITCH qwen2:7b后立即调用llama_free_model()卸载旧模型再llama_load_model_from_file()加载新模型并返回{status:success,context_size:32768}给 Electron。而“localhost 服务”功能则是 t3code 的隐藏王牌。它默认不开启但用户可通过菜单“服务 → 启用 HTTP API”触发Electron 主进程启动一个hyperHTTP server监听127.0.0.1:3001该 server 不处理任何业务逻辑只做两件事将/api/chat请求转发给t3code-core的 Unix Socket将/api/models请求转换为SELECT * FROM modelsSQL 查询返回 JSON。这意味着你可以在 t3code 界面里点击“启用 API”然后立刻在另一个终端执行curl -X POST http://localhost:3001/api/chat \ -H Content-Type: application/json \ -d {model:qwen2:7b,messages:[{role:user,content:hello}]}得到标准 OpenAI 兼容响应。这个设计让 t3code 成为本地 LLM 的“瑞士军刀”既可当 GUI 工具用也可当 API 网关用还可当 CLI 服务器用。提示Electron 的localhost:3001默认禁用 CORS但如果你需要从外部网页调用只需在菜单里勾选“允许跨域请求”t3code 会自动在响应头添加Access-Control-Allow-Origin: *。不过生产环境强烈建议关闭此选项避免模型被恶意网站调用。3.4 Homebrew 安装全流程从brew install t3code到首次运行Homebrew 安装看似一键实则暗藏玄机。以下是brew install t3code在 macOS 上的真实执行链Step 1Formula 解析Homebrew 读取https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/t3code.rb确认version 0.4.2→ 对应 GitHub Release 的 tagsha256 a1b2c3...→ 校验.zip包完整性app t3code.app→ 指定安装目标为/opt/homebrew/Caskroom/t3code/0.4.2/t3code.app。Step 2下载与校验Homebrew 从https://github.com/t3code-org/t3code/releases/download/v0.4.2/t3code-macos-arm64.zip下载 ZIP解压后得到t3code.app/ ├── Contents/ │ ├── Info.plist # 声明 Electron 版本、CFBundleIdentifier │ ├── MacOS/ │ │ └── t3code # Electron 启动器shell script │ ├── Resources/ │ │ ├── app/ # Electron 渲染进程代码JS HTML │ │ └── t3code-core # Rust 编译的原生核心二进制arm64 │ └── Frameworks/ # 内置 Electron.framework不依赖系统Step 3符号链接创建Homebrew 在/opt/homebrew/bin/创建软链接ln -s /opt/homebrew/Caskroom/t3code/0.4.2/t3code.app/Contents/MacOS/t3code /opt/homebrew/bin/t3code这样用户在终端输入t3code实际执行的是t3code.app/Contents/MacOS/t3code它会启动 Electron 并加载app/目录。Step 4首次运行初始化当用户双击t3code.app或执行t3codeElectron 主进程会检查~/.t3code/config.json是否存在不存在则生成默认配置检查~/.t3code/models/目录权限若不可写则弹窗提示Please run chmod 755 ~/.t3code/models启动t3code-core子进程并监听其 stdout直到输出READY字符串才渲染 UI。整个过程耗时约 3~5 秒M2 Mac比brew install node快 10 倍因为 t3code 的 Cask 不依赖任何外部公式formula所有依赖Electron、Rust runtime均已静态链接。实操避坑如果你遇到mac安装homebrew失败不要盲目重装 Homebrew。先执行brew doctor90% 的问题源于~/.zshrc中错误的PATH设置如export PATH/usr/local/bin:$PATH覆盖了 Homebrew 的/opt/homebrew/bin。正确做法是echo export PATH/opt/homebrew/bin:$PATH ~/.zshrc然后source ~/.zshrc。4. 常见问题排查与独家调试技巧4.1 “model not found” 错误的七层归因法lm studio cli 启动模型时提示 “model not found”是搜索热词里的高频问题但 t3code 的同类错误有更精细的归因路径。我总结出七层排查法按顺序执行层级检查项命令/操作典型现象解决方案L1路径拼写t3code model list输出的 Model ID 是否与命令一致t3code model list | grep qwen显示qwen2:7b但命令输成qwen2:7B严格区分大小写GGUF 文件名中的Q4_K_M必须小写L2模型存在性t3code model info qwen2:7b是否返回详细信息t3code model info qwen2:7b报错Model not found in index执行t3code model download qwen2:7b重新下载L3文件权限ls -l ~/.t3code/models/是否可读ls -l ~/.t3code/models/显示-rw-------权限 600chmod 644 ~/.t3code/models/*.ggufL4GGUF 兼容性t3code-core --version输出的 llama.cpp 版本是否支持该 GGUFt3code-core --version显示llama.cpp v1.2.3但模型是 v1.3.0 生成升级 t3codebrew upgrade t3codeL5磁盘空间df -h ~/.t3code/models是否剩余空间 模型大小df -h ~/.t3code/models显示Available 1.2G但模型需 4.2G清理~/.t3code/cache/或修改t3code config set model-dir /path/to/larger/diskL6环境变量echo $T3CODE_MODEL_DIR是否覆盖了默认路径echo $T3CODE_MODEL_DIR输出/old/path但模型在~/.t3code/modelsunset T3CODE_MODEL_DIR或t3code config set model-dir ~/.t3code/modelsL7GPU 初始化t3code-core --model ~/.t3code/models/qwen2-7b.Q4_K_M.gguf --gpu-layers 40 --verbose是否报错t3code-core --model ... --verbose输出metal_init: failed to create device降级--gpu-layers 0测试 CPU 模式确认是 Metal 驱动问题独家技巧当 L7 确认是 Metal 问题时不要重装 Xcode Command Line Tools。直接执行defaults write com.apple.CoreGraphics disableMetalRenderer -bool YES重启 Mac 即可强制回退到 OpenGL 渲染--gpu-layers恢复正常。这是 Apple 工程师私下分享的调试开关。4.2 Electron 打包 APK 的真相为什么 t3code 不支持搜索热词里有 “electron打包apk”这暴露了一个常见误解Electron 本身不支持 Android所谓“打包 APK”都是第三方桥接方案稳定性和性能极差。t3code 明确不支持 APK 打包原因有三架构鸿沟Electron 依赖 Chromium 的 V8 引擎和 Node.js 的 libuv而 Android 的 ART 虚拟机无法运行 x86_64 二进制GPU 通道缺失Android 的 Vulkan 驱动与 macOS 的 Metal、Windows 的 DirectX 完全不同llama.cpp 的 GPU 后端需重写许可风险Electron 的 BSD 许可证要求衍生作品公开源码而 APK 打包工具如electron-for-android多为 MIT 许可混用可能引发合规问题。如果你真需要移动端 LLMt3code 团队推荐两条正道iOS 方向用React Nativellama.cpp的 iOS 绑定llama.cpp/ios目录已验证可在 iPhone 15 Pro 上跑通 Qwen2-1.5BAndroid 方向用Termuxt3code-coreARM64 二进制通过termux-api访问摄像头/麦克风命令行体验比 WebView 更流畅。注意网上流传的 “Electron 打包 APK 教程”99% 是把 Electron 应用塞进 Android WebView然后用cordova-plugin-advanced-http调用本地t3code-core。这本质上是个 hack每次模型加载都要经历WebView → Cordova Bridge → JNI → Native四层调用延迟高达 2s且无法利用 GPU。4.3 Homebrew 卸载残留清理比brew uninstall更彻底的方案homebrew卸载残留是 macOS 用户的噩梦。brew uninstall t3code只删除 Caskroom 中的.app但以下文件仍残留~/.t3code/目录含模型、配置、日志/opt/homebrew/bin/t3code软链接~/Library/Application Support/t3code/Electron 的 userData~/Library/Logs/t3code/崩溃日志t3code 内置了t3code cleanup命令执行后自动清理全部t3code cleanup --all # 删除模型、配置、日志 t3code cleanup --config # 仅删除配置保留模型 t3code cleanup --models # 仅删除模型保留配置原理是读取t3code-core的DEFAULT_DIRS常量编译时硬编码然后std::fs::remove_dir_all()递归删除。比手动rm -rf安全因为它会先检查目录是否为空避免误删~/.t3code下的其他项目。实操心得如果你已手动删过~/.t3code再运行t3code cleanup会报错No such file or directory。此时执行t3code config reset它会重建最小化配置目录然后t3code model list就能重新识别已下载模型因为模型文件还在~/.t3code/models只是索引库没了。4.4 Node 安装 codex cli 很慢的根因与替代方案node安装codex cli很慢的根本原因是npm install -g codex-cli会下载整个huggingface/inferenceSDK含 TensorFlow.js而 t3code 的设计哲学是剥离非核心依赖。t3code 的 CLI 二进制t3
返回列表