# ideam-cli **Repository Path**: cc123hh/ideam-cli ## Basic Information - **Project Name**: ideam-cli - **Description**: IDEA Java 项目命令行管理器:启动、停止、重启、日志,一条命令,零依赖 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-11-14 - **Last Updated**: 2026-11-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

ideam

ideam banner

python 3.10+ platform dependencies commands license

在终端里把 IDEA 的 Java 项目管起来:启动、停止、重启、看日志,一条命令。
零依赖 · 单文件脚本 · 只杀自己启动的进程,绝不误伤 IDEA

--- ## 📑 目录 - [快速开始](#-快速开始) - [它解决什么问题](#-它解决什么问题) - [安装](#-安装) - [命令一览](#-命令一览) - [设计要点](#-设计要点) ## 🚀 快速开始 ```console $ ideam add my-app --dir ~/Projects/my-app --port 8080 \ --jdk 21 --profile dev --from-log 已注册 my-app $ ideam start my-app [my-app] 增量编译中(--no-build 可跳过)… [my-app] 启动中 PID 68446,日志 ~/.local/state/ideam/logs/my-app.log [my-app] 就绪(第 2 轮探测,端口 8080 可达) $ ideam list 名称 状态 PID 端口 主类 my-app managed 68446 8080 com.example.MyApplication ``` `--from-log` 填 IDEA 控制台第一行启动命令所在的日志文件,classpath 与主类自动提取,一次注册永久使用。 ## 🤔 它解决什么问题 IDEA 管理的 Spring Boot 项目,服务生命周期被锁在图形界面里:agent / CI / 远程终端想重启一下后端,要么打开 IDEA 点按钮,要么手拼一长串 `java -classpath` 命令。`ideam` 把这件事翻译成四条命令: - **classpath 自动提取**:IDEA 启动命令里的 classpath(含全部依赖与模块产物)从运行日志一次性提取,持久存入 `~/.config/ideam/projects.json`; - **构建环境对齐**:按项目注册的 JDK 版本编译(规避系统 JDK 过新导致 Lombok 失效等环境坑),启动前自动增量编译(`--no-build` 可跳过); - **就绪轮询**:启动后按端口探测直到服务可达,失败时自动回放日志尾部定位原因; - **进程归属保护**:只管理本工具启动的进程(pidfile 记录);端口被 IDEA 或其他途径占用时标注 `external` 并拒绝操作,绝不误杀。 ## 📦 安装 ```bash git clone https://gitee.com/cc123hh/ideam-cli.git ln -sf $(pwd)/ideam-cli/ideam.py ~/.local/bin/ideam ``` 要求:Python 3.10+(纯标准库,无第三方依赖)、macOS/Linux。 ## ⌨️ 命令一览 | 命令 | 作用 | |------|------| | `ideam list` | 所有注册项目与运行状态(managed / external / stopped) | | `ideam add <名> --dir <目录> [选项]` | 注册项目,`--from-log` 提取 classpath | | `ideam start <名> [--no-build]` | 启动(默认先增量编译) | | `ideam stop <名>` | 优雅停止(SIGTERM → 超时 SIGKILL) | | `ideam restart <名> [--no-build]` | 重启 | | `ideam status [名]` | 状态详情:PID、HTTP 探测、日志路径 | | `ideam logs <名> [-f] [-n 行数]` | 查看 / 跟踪启动日志 | | `ideam update-classpath <名> --from-log <日志>` | 依赖大变动后刷新 classpath | | `ideam set <名> --port/--jdk/--profile/...` | 修改注册项 | | `ideam outdated <名>` | 依赖体检:扫描全部 pom,对比 Maven Central | | `ideam doctor <名>` | 环境体检:JDK 实测 / Maven / 资源过滤残留 / classpath 时效 | | `ideam remove <名>` | 移除注册(不影响运行中进程) | ### 🔍 断点调试(JDWP) 注册调试端口后,启动的 JVM 自动挂上 JDWP agent,IDEA「Remote Debug」、VSCode 或 `jdb` 直接 attach,`suspend=n` 不阻塞启动: ```console $ ideam set my-app --debug-port 5005 $ ideam restart my-app $ ideam status my-app JDWP 调试: 5005(可 attach)—— jdb -attach 5005 或 IDE Remote Debug ``` 下次 restart 生效;不注册 debug_port 则行为与之前完全一致。 ### 🛠️ 断点抓值(debug) 一行命令完成「设断点 → 触发 → 抓变量 → 放行」,全程无需打开 IDEA: ```console $ ideam debug my-app --break "com.example.Foo.handleThing" \ --trigger "curl -s http://localhost:8080/api/thing" \ -p "request.getId()" -p "principal.getName()" | 断点命中: "线程=http-nio-8080-exec-1", Foo.handleThing(), 行=42 | 方法参数: | request = instance of com.example.ThingRequest | principal = instance of UsernamePasswordAuthenticationToken | principal.getName() = "1" ``` - `--break`:jdb 语法断点(类全限定名.方法);`--trigger`:断点就绪后自动执行的命令(curl / 脚本均可),不带则等待外部触发 - `-p`:命中后求值的表达式,可重复;默认输出 `where` 调用栈 + `locals` 全部变量 - 实现驱动 JDK 自带的 jdb,经 **pty** 交互(jdb 输出接管道是全缓冲,pty 才能实时逐行读);放行用 `cont`,调试会话结束服务无感继续 - 前置:`ideam set <名> --debug-port <端口>` + restart(挂 JDWP),`ideam status` 可确认「可 attach」 ### 🩺 依赖与环境体检 ```console $ ideam outdated my-app # 扫描全部 pom(含多模块),对比 Maven Central ❗ org.example:some-lib 当前 1.2.0 落后 → 1.3.0 org.example:another-lib 当前 2.4.1 本地更新(索引滞后,标记 2.3.9) $ ideam doctor my-app # 起不来 / 行为异常时先跑它 ✓ JDK 21: 位于 /Library/Java/...(实际 21) # java -version 实测,不信注册值 ✓ 资源过滤: target 下无 @xx@ 残留 # 占位符残留会导致启动即死 全部 7 项通过,环境健康 ``` 版本比对内置三层防误报:**预发布版**(alpha/beta/rc)不算落后、**Central 历史垃圾版本号**(如 commons-io 的 `20030203.000550`)标人工确认、**索引滞后**(本地比「最新」还新)不告警——search.maven.org 的 `latestVersion` 字段滞后严重,以本地实测为准。 ## 🧭 设计要点 - **配置**:`~/.config/ideam/projects.json`(XDG) - **运行状态**:`~/.local/state/ideam/`(pidfile 与日志,日志每次启动自动轮转) - **双栈探测**:Java 进程可能只监听 IPv6 环回,端口与 HTTP 探测同时尝试 `::1` 与 `127.0.0.1` - **优雅退出**:SIGTERM 等 5 秒不退再 SIGKILL - **Maven profile 感知**:注册时记下 profile,编译时自动带上(`application.yml` 的 `@xx@` 占位符依赖资源过滤,漏了会启动即死)