注意:本项目已停止更新。 因已有 opencode 等成熟的同类产品,jclaude 不再继续开发。代码保留在 v0.1.7 版本供参考。
jclaude 是一个使用 Java 21 实现的 Claude Code 风格 CLI,命令名对标 claude。当前版本:0.1.7。当前通过 Java HttpClient 直连 provider 的 HTTP/SSE 接口,支持两种 API 格式:
anthropic:Anthropic Messages API 格式,调用/v1/messages,支持 SSE 流式输出和 tool use。openai:OpenAI-compatible Chat Completions 格式,调用/v1/chat/completions,可用于 DeepSeek 等兼容 OpenAI API 的服务,支持 SSE 流式输出和 function tools。
- Java 21+
- Maven 3.9+
print模式和交互模式都支持远程模型 SSE 流式输出。- provider 使用 ReAct 型 agent loop:模型流式输出文本,遇到工具调用就执行本地工具,再把结果送回模型继续下一轮。
- 支持
Read/Bash/Write/Edit/Delete工具,其中Delete必须确认后才会真正删除。 Bash可执行编译、测试、启动服务等非交互命令,并返回 exit code、stdout 和 stderr。- 支持可选 Plan Mode:复杂或高风险任务可以先只读分析和制定计划,用户批准后再允许修改。
- OpenAI-compatible provider 会保留并续传 DeepSeek 等模型返回的
reasoning_content,兼容 thinking mode 多轮工具调用。 - 交互模式会显示
思考中...、工具开始和工具结果状态,避免多轮工具调用时文本挤在同一行。 - 交互模式中,单轮 provider/SSE 异常只会结束当前轮并保留 REPL,不会因为一次
closed/断流直接退出整个 CLI。 - 在多轮工具调用请求过大时,会先对单轮工具结果应用预算控制,再根据模型上下文窗口做更保守的请求压缩,降低长任务触发上游断流的概率。
- 支持按模型名匹配
modelProfiles,可分别控制contextWindowTokens、maxOutputTokens和supportsVision。 /status和doctor会显示当前生效的 context window tokens 与 max output tokens,便于排查 profile 命中结果。- 当 provider 因输出长度提前截断响应时,
jclaude会自动追加一轮恢复提示,让模型从中断处继续,而不是静默结束任务。 - 如果 provider 返回空白 assistant 结束轮次,
jclaude会显式报错并保留会话,避免看起来“执行成功但什么都没生成”。 -p非交互模式支持--max-turns <N>限制 agentic turns;交互模式默认不限制。- 交互输入支持
/命令补全、@文件补全、光标左右移动、输入历史和长行横向滚动。 - 支持本地 skills、图片输入、配置文件和 Anthropic/OpenAI-compatible provider。
- skill 调用展开后的 prompt 会再次按普通输入解析,因此 skill 里内联的本地图片路径也能作为真实图片输入发送给支持视觉能力的模型。
mvn package构建完成后会生成:
target/jclaude-0.1.7.jarbin/jclaude 会从 pom.xml 读取当前项目版本,并启动对应的 target/jclaude-<version>.jar。这样即使 target/ 目录里残留了旧版本 jar,也不会误启动到别的版本。
./bin/jclaude --help如果提示没有 jar 文件,先运行:
mvn packagejava -jar target/jclaude-0.1.7.jar --help./bin/jclaude --version./bin/jclaude doctor未配置 API key 时,命令不会请求远程模型,会返回本地占位响应:
./bin/jclaude -p "你好"./bin/jclaude交互模式会在当前进程内维护一份会话历史,实现多轮对话记忆。每次输入普通文本时,jclaude 会把当前会话中的 user / assistant 历史消息一起发送给模型,因此模型可以理解前文。
示例:
jclaude> 请记住一个词:蓝鲸
已记住:蓝鲸
jclaude> 我刚才让你记住的词是什么?
你刚才让我记住的词是:蓝鲸
交互模式支持的 slash commands:
/help 查看交互模式帮助
/status 查看当前工作目录、配置目录、provider、model、context window 和 max output tokens
/config 查看配置文件路径
/model 查看当前模型
/skills 查看已加载的 skills
/plan 进入只读 Plan Mode;/plan status 查看状态;/plan off 手动退出
/clear 清空当前会话历史
/reset 清空当前会话历史
/exit 退出交互模式
注意:当前多轮记忆只保存在本次 ./bin/jclaude 进程内;退出后不会持久化历史。/clear 和 /reset 会立即清空当前会话历史。
如果某一轮流式请求被 provider 或代理中途关闭,jclaude 会保留当前交互会话并输出错误,用户可以直接继续下一条命令,而不需要重新启动 CLI。
如果 provider 因输出上限截断了当前轮回复,jclaude 会自动发出一条恢复提示,让模型直接从中断位置继续;如果对端返回空白结束轮次,则会明确提示错误而不是静默回到提示符。
交互模式支持类似 Claude Code 的输入提示:
- 输入
/会自动显示内置 slash commands 和已加载 skills - 继续输入命令前缀会过滤列表,例如
/sk - 输入
@会自动显示当前目录下的目录和文件 - 补全目录后会继续显示该目录下的目录和文件,例如
@src/ - 使用
↑/↓选择候选项,使用Tab接受当前候选项 - 候选项未显示时,
↑/↓可浏览本次进程内输入历史 - 使用
←/→可移动光标在中间修改;长输入会横向滚动,避免终端自动换行导致光标错位
jclaude 会向模型提供类似 Claude Code 的本地文件工具:
Read:读取文本文件或列出目录;文本读取默认最多返回 2000 行,支持offset/limit按行读取Bash:在当前工作目录执行非交互 shell 命令,返回exit_code、stdout和stderr;默认超时 60 秒,最长 600 秒,输出会截断保护Write:创建或完整覆盖文件Edit:对已读文件做精确字符串替换Delete:删除文件或目录,执行前必须由用户显式确认EnterPlanMode/ExitPlanMode:可选计划模式;计划模式中禁止Bash、写入、编辑和删除,提交计划并获用户批准后才退出
这些工具由模型在 ReAct 循环中调用,不是用户直接输入的 shell 命令。只有工具结果明确成功时,模型才应该告知用户“已读取/写入/编辑/删除”;如果工具失败或用户拒绝确认,操作不会执行。
为减少长链路任务在多轮工具调用后的上下文膨胀,jclaude 在发送下一轮流式请求前,会先对单轮工具结果应用聚合预算控制,再根据当前模型的估算上下文窗口决定是否进一步压缩较早的工具结果和中间 assistant 说明;如果模型确实还需要完整内容,应再次调用相应工具重新读取。
Bash 适合让模型查看命令结果,例如:
jclaude> 执行 mvn -q test,查看失败原因并修复
jclaude> 启动 Spring Boot 项目,若端口冲突请修复并验证接口
长期运行的服务建议让模型使用后台命令并把日志写入文件,例如 mvn spring-boot:run > /tmp/app.log 2>&1 &,再用 curl 或读取日志验证结果。
写入保护规则:
Write/Edit修改已有文件前必须先对该文件做完整Read。- 如果
Read只读取了部分内容,或者文件在读取后被外部修改,Write/Edit会拒绝执行。 Edit默认要求old_string唯一匹配;需要替换多处时必须设置replace_all=true。- 文本读取会拒绝过大的文件和明显的二进制文件。
输入中的 @path 会被解析为本地文件引用,支持相对路径、绝对路径和行范围:
jclaude> @README.md 前3行内容
jclaude> @src/main/java/com/jclaude/cli/JClaude.java#L1-20 总结这段代码
为降低误写/误删风险,Write / Edit / Delete 默认只允许操作当前工作目录下的文件;如确需操作工作目录外路径,可设置:
export JCLAUDE_ALLOW_WRITE_OUTSIDE_CWD=trueDelete 属于破坏性操作:交互模式中会提示输入 yes 或 确认 后才会真正删除;-p 非交互模式默认不会执行删除。自动化场景如确需跳过确认,可显式设置:
export JCLAUDE_AUTO_CONFIRM_DESTRUCTIVE=truePlan Mode 是可选的只读计划模式,适合复杂或高风险任务:
- 交互模式输入
/plan可手动进入;/plan status查看状态;/plan off或/plan exit手动退出。 - 模型也可以调用
EnterPlanMode进入计划模式。 - Plan Mode 中
Bash/Write/Edit/Delete会被拒绝,只允许读取、分析和制定计划。 - 模型调用
ExitPlanMode时必须提交plan,交互模式会展示计划并要求用户输入yes或确认。 -p非交互模式默认不会自动批准计划;自动化场景可设置JCLAUDE_AUTO_APPROVE_PLAN=true。
jclaude 支持在 prompt 中直接传入本地图片路径,路径会作为图片内容发送给支持视觉能力的模型。
支持格式:.png、.jpg、.jpeg、.gif、.webp。
当 provider 为 openai 时,.webp 图片会先在本地临时转换为 PNG,再按 OpenAI-compatible image_url 格式发送。这样可以兼容部分 OpenAI-compatible 服务(例如 LM Studio)对 WebP data URL 支持不完整的问题。
示例:
./bin/jclaude -p "/Users/huanglei/Pictures/example.webp 描述一下这张图片的内容"
./bin/jclaude -p "@./screenshots/app.png 这张图里有什么问题?"交互模式中也可以直接输入:
jclaude> /Users/huanglei/Pictures/example.webp 描述一下这张图片的内容
如果路径中包含空格,可以使用引号:
jclaude> "@/Users/huanglei/Pictures/my image.png" 描述一下这张图片
jclaude 支持类似 Claude Code 的本地 skills:每个 skill 是一个目录,目录内包含 SKILL.md。
支持的目录:
- 当前项目向上查找最近的:
.jclaude/skills/<skill-name>/SKILL.md - 如果找到了至少一个有效项目 skill,则只加载该项目技能目录
- 如果当前项目没有有效 skill,则回退到用户级:
~/.jclaude/skills/<skill-name>/SKILL.md
查看配置路径时,/config 会额外显示当前实际生效的 skills 来源目录。
示例:
mkdir -p .jclaude/skills/commit
cat > .jclaude/skills/commit/SKILL.md <<'MD'
---
description: Generate a concise git commit message
when_to_use: Use when the user asks to prepare or review a commit
argument-hint: "<scope>"
arguments: scope
---
# Commit Skill
Review the current change summary and write a concise commit message for $scope.
MD查看已加载 skills:
./bin/jclaude
jclaude> /skills直接调用 skill:
./bin/jclaude -p "/commit auth"交互模式也可以直接输入:
jclaude> /commit auth
SKILL.md 支持的常用 frontmatter:
description:skill 描述,用于列表和系统提示when_to_use:什么时候使用该 skillargument-hint:调用参数提示arguments:命名参数,例如scope topicuser-invocable:设为false时禁止用户直接/skill调用disable-model-invocation:设为true时禁用该 skill 调用
正文中支持以下占位符:
$ARGUMENTS:完整参数字符串$ARGUMENTS[0]/$0:第 1 个参数$name:arguments中定义的命名参数${CLAUDE_SKILL_DIR}/${JCLAUDE_SKILL_DIR}:当前 skill 目录${CLAUDE_SESSION_ID}/${JCLAUDE_SESSION_ID}:当前会话 ID
export ANTHROPIC_API_KEY="你的 Anthropic API Key"
export ANTHROPIC_MODEL="claude-opus-4-7"
./bin/jclaude -p --provider anthropic "你好"也可以用统一变量:
export JCLAUDE_PROVIDER="anthropic"
export JCLAUDE_MODEL="claude-opus-4-7"
export JCLAUDE_API_KEY="你的 API Key"
./bin/jclaude -p "你好"./bin/jclaude -p --provider anthropic --model claude-sonnet-4-6 "你好"如果某个服务提供 Anthropic Messages API 兼容格式,可以通过 --base-url 指向它:
JCLAUDE_API_KEY="你的 API Key" \
./bin/jclaude -p \
--provider anthropic \
--base-url https://example.com \
--model claude-opus-4-7 \
"你好"--base-url 可以是 base URL,也可以是完整 endpoint:
--base-url https://example.com
--base-url https://example.com/v1
--base-url https://example.com/v1/messagesopenai provider 使用 /v1/chat/completions 格式。
export OPENAI_API_KEY="你的 API Key"
export OPENAI_MODEL="gpt-4.1"
./bin/jclaude -p --provider openai "你好"也可以使用统一变量:
export JCLAUDE_PROVIDER="openai"
export JCLAUDE_MODEL="gpt-4.1"
export JCLAUDE_API_KEY="你的 API Key"
./bin/jclaude -p "你好"DeepSeek 可以按你使用的网关协议接到不同 provider:
- OpenAI-compatible endpoint:配置到
openaiprovider - Anthropic-compatible endpoint:配置到
anthropicprovider
OpenAI-compatible 示例:
OPENAI_API_KEY="你的 DeepSeek API Key" \
./bin/jclaude -p \
--provider openai \
--base-url https://api.deepseek.com \
--model deepseek-chat \
"你好"也可以用环境变量:
export JCLAUDE_PROVIDER="openai"
export JCLAUDE_BASE_URL="https://api.deepseek.com"
export JCLAUDE_MODEL="deepseek-chat"
export OPENAI_API_KEY="你的 DeepSeek API Key"
./bin/jclaude -p "你好"如果你使用的是 Anthropic-compatible 网关,则改为 anthropic provider 并填写对应 baseUrl 即可:
ANTHROPIC_API_KEY="你的 DeepSeek API Key" \
./bin/jclaude -p \
--provider anthropic \
--base-url https://你的-anthropic-compatible-gateway \
--model deepseek-v4-pro \
"你好"jclaude 支持类似 Claude Code 的配置文件层级。推荐把非敏感配置写入 JSON 文件,把 API key 继续放在环境变量中。
配置文件读取顺序从低到高:
~/.jclaude/settings.json~/.jclaude/settings.local.json- 当前项目
.jclaude/settings.json - 当前项目
.jclaude/settings.local.json
示例:
{
"provider": "openai",
"model": "deepseek-v4-pro",
"baseUrl": "https://api.deepseek.com",
"outputFormat": "text",
"apiKeyEnv": "OPENAI_API_KEY",
"modelProfiles": {
"default": {
"contextWindowTokens": 256000,
"maxOutputTokens": 32000
},
"claude-*": {
"contextWindowTokens": 256000,
"maxOutputTokens": 32000
},
"deepseek-v4-*": {
"contextWindowTokens": 1000000,
"maxOutputTokens": 64000
},
"cc-gpt-5.4": {
"contextWindowTokens": 1000000,
"maxOutputTokens": 64000
}
}
}modelProfiles 会按当前模型名匹配 profile,用来控制:
contextWindowTokens:上下文窗口估计值,影响自动压缩阈值maxOutputTokens:请求里的输出上限;Anthropic 和 OpenAI-compatible 两条 provider 路径都会使用supportsVision:可选,手动覆盖视觉能力判断
匹配规则:
default或*:兜底 profile- 精确模型名:例如
cc-gpt-5.4 *通配:例如claude-*、deepseek-v4-*
如果多个 profile 同时匹配,会优先选择更具体的规则;同样具体度下,后定义的覆盖前定义的。
如果没有命中自定义 profile,jclaude 会使用内置默认值:
- 默认模型:
contextWindowTokens=256000,maxOutputTokens=32000 claude-*:默认按256000 / 32000处理gpt-5*、cc-gpt-5*、gemini*、deepseek-v4*:默认按1000000 / 32000处理supportsVision会基于模型名做启发式判断,也可以在modelProfiles里显式覆盖
你可以通过 ./bin/jclaude doctor 或交互模式里的 /status 查看当前模型最终命中的 profile 值。
如果要更新版本号并创建新的 git tag,至少需要同步这些位置:
pom.xml:Maven 项目版本,也是bin/jclaude选择目标 jar 的单一版本源src/main/java/com/jclaude/cli/JClaude.java:--version和 banner 显示的 CLI 版本README.md:文档里的“当前版本”和示例 jar 文件名
发版步骤建议如下:
- 先同步修改上面 3 个位置的版本号。
- 运行
mvn package,确认产物是target/jclaude-<version>.jar。 - 用
./bin/jclaude --version验证脚本和 CLI 显示的版本一致。 - 提交代码后创建对应 tag,例如
v0.1.7。 - 推送分支和 tag 到远程仓库。
注意:bin/jclaude 不需要在每次发版时手动改 jar 文件名;它会自动按 pom.xml 里的版本寻找对应产物。
apiKeyEnv 写的是“环境变量名”,不是 API key 本身。jclaude 会读取这个环境变量的值作为 API key。
项目级配置示例:
mkdir -p .jclaude
cat > .jclaude/settings.json <<'JSON'
{
"provider": "openai",
"model": "deepseek-v4-pro",
"baseUrl": "https://api.deepseek.com",
"outputFormat": "text",
"apiKeyEnv": "OPENAI_API_KEY",
"modelProfiles": {
"deepseek-v4-*": {
"contextWindowTokens": 1000000,
"maxOutputTokens": 64000
}
}
}
JSON
OPENAI_API_KEY="你的 DeepSeek API Key" ./bin/jclaude -p "你好"常见错误:不要把真实 key 写到 apiKeyEnv 里。
{
"apiKeyEnv": "sk-xxxx"
}上面表示读取名为 sk-xxxx 的环境变量,不会把 sk-xxxx 当作 key 使用。
如果你希望不额外设置环境变量,也可以直接在配置文件中写 apiKey:
{
"provider": "anthropic",
"model": "cc-gpt-5.5",
"baseUrl": "https://api.codexzh.com",
"outputFormat": "text",
"apiKey": "你的 API Key"
}这种方式启动最方便:
./bin/jclaude
./bin/jclaude -p "你好"注意:apiKey 会以明文形式保存在配置文件中。只建议用于个人本机配置,不建议提交到 git。
用户级配置示例:
mkdir -p ~/.jclaude
cat > ~/.jclaude/settings.json <<'JSON'
{
"provider": "anthropic",
"model": "claude-opus-4-7",
"outputFormat": "text"
}
JSON支持字段:
provider:anthropic或openaimodel:模型名baseUrl/base_url:provider base URL 或完整 endpointoutputFormat/output_format:text、json或stream-jsonapiKey/api_key:直接写入 API key,适合个人本机快速启动,但会明文保存apiKeyEnv/api_key_env:写环境变量名,jclaude会从该环境变量读取 API key,推荐使用modelProfiles/model_profiles:按模型名配置contextWindowTokens、maxOutputTokens、supportsVision
| 环境变量 | 作用 |
|---|---|
JCLAUDE_CONFIG_DIR / CLAUDE_CONFIG_DIR |
覆盖用户级配置目录,默认是 ~/.jclaude |
JCLAUDE_PROVIDER |
默认 provider:anthropic 或 openai |
JCLAUDE_MODEL |
统一模型名覆盖 |
ANTHROPIC_MODEL / OPENAI_MODEL |
provider 专属模型名 |
JCLAUDE_API_KEY |
统一 API key 兜底变量 |
ANTHROPIC_API_KEY / OPENAI_API_KEY |
provider 专属 API key,优先级高于 JCLAUDE_API_KEY |
JCLAUDE_BASE_URL |
统一 base URL 覆盖 |
ANTHROPIC_BASE_URL / OPENAI_BASE_URL |
provider 专属 base URL |
JCLAUDE_OUTPUT_FORMAT |
默认输出格式:text、json 或 stream-json |
JCLAUDE_ALLOW_WRITE_OUTSIDE_CWD |
设为 true 或 1 后允许写入/编辑/删除当前工作目录外路径 |
JCLAUDE_AUTO_CONFIRM_DESTRUCTIVE |
设为 true 或 1 后跳过 Delete 确认,仅建议自动化场景使用 |
JCLAUDE_AUTO_APPROVE_PLAN |
设为 true 或 1 后允许非交互模式自动批准 ExitPlanMode |
远程 provider 都走同一类 ReAct 型 agent loop:
- 构造包含系统提示、会话历史和工具定义的请求,并设置
stream=true。 - 通过 SSE 逐条读取
data:JSON 事件,文本 delta 会立即输出给终端或 JSONL。 - 如果模型发起工具调用,
jclaude执行对应本地工具,并把工具结果追加回对话。 - 继续下一轮流式请求,直到模型不再调用工具;如果在
-p非交互模式下显式设置了--max-turns,达到上限后会停止并返回错误。
这不是固定的 PAE(Plan-Act-Execute)流水线;默认是 ReAct 循环。Plan Mode 是额外的可选权限模式,用于在行动前先提交计划并等待用户批准。
交互模式会把模型思考和工具调用转换成简短状态行:
- 收到 Anthropic
thinking_delta或 OpenAI-compatiblereasoning_content时显示思考中...,但不会打印思考内容。 - 工具开始执行时显示
→ 工具名: 摘要,例如→ Bash: mvn spring-boot:run。 - 工具结束后显示结果摘要,例如
✓ Bash exit 0或✗ Bash exit 1。
OpenAI-compatible provider 的 thinking mode 会保留 reasoning_content 并在后续工具轮次回传给 API;这对 DeepSeek 等要求续传 reasoning 的模型是必需的。
支持三种输出格式:
./bin/jclaude -p --output-format text "你好"
./bin/jclaude -p --output-format json "你好"
./bin/jclaude -p --output-format stream-json "你好"说明:
text:默认格式,连接远程模型时会流式输出文本json:仍使用同一套 SSE/ReAct 循环,但 CLI 会缓冲完整响应后输出单个 JSON 对象stream-json:通过 SSE 按真实增量输出 JSONL 事件;如果模型调用工具,会在工具结果返回后继续下一轮增量输出--max-turns <N>:只在--print非交互模式下生效,用于限制 agentic turns;默认不限制- 交互模式默认不限制 turns,这一点与 Claude Code 的源码行为保持一致
- 当
--max-turns触发上限时,text会输出Error: Reached max turns (N)并以退出码1结束;json和stream-json会输出type=result、subtype=error_max_turns的错误对象
优先级从高到低:
--providerJCLAUDE_PROVIDER- 配置文件中的
provider - 默认值:
anthropic
可选值:
anthropicopenai
优先级从高到低:
--modelJCLAUDE_MODEL- provider 专属环境变量:
ANTHROPIC_MODEL或OPENAI_MODEL - 配置文件中的
model - 默认值:
anthropic:claude-opus-4-7openai:gpt-4.1
anthropic provider:
ANTHROPIC_API_KEYJCLAUDE_API_KEY
openai provider:
OPENAI_API_KEYJCLAUDE_API_KEY
优先级从高到低:
--base-urlJCLAUDE_BASE_URL- provider 专属环境变量:
ANTHROPIC_BASE_URL或OPENAI_BASE_URL - 配置文件中的
baseUrl或base_url - 默认值:
anthropic:https://api.anthropic.comopenai:https://api.openai.com
- 交互模式历史只保存在当前进程内,暂不支持跨进程
/continue或/resume持久恢复。 --input-format、--allowed-tools、--disallowed-tools、--mcp-config、--permission-mode、--settings、--agents当前只完成参数解析或 help 占位,尚未真正接入对应能力。mcp、plugin、auth/login/logout、install、update仍是占位实现;completion当前只输出通用提示。- 暂未实现 MCP 工具、插件管理、工具 allowlist/denylist、权限模式矩阵和会话持久化。
Bash是非交互命令执行工具,不适合需要持续前台交互输入的程序;长时间运行的服务应后台启动并写日志。- 工具循环有最大轮次保护,超过后会中止并报错,避免模型无限调用工具。
- 图片会作为本地文件内容发送给 provider,但最终识别效果取决于所选模型是否支持视觉输入。
- OpenAI-compatible provider 的 WebP 图片会依赖本机
sips命令临时转换为 PNG;非 macOS 环境如缺少sips,请先手动转换为 PNG/JPEG。