sk-hermes-cli 1.0.0 → 2.0.1

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/README.md CHANGED
@@ -1,147 +1,64 @@
1
1
  # sk-hermes-cli
2
2
 
3
- `sk-Hermes`(Java AI Agent)的 npm 分发壳。装完即可在任意目录敲 `hermes` `sk-hermes` 进入对话,
4
- 等价于 Claude Code 的 `claude` 命令。
3
+ `sk-Hermes`(Java AI Agent)的命令行工具。装完即可在任意目录敲 `Jhermes`,像 Claude Code 一样对话。
5
4
 
6
- > 本包只是一个 **JS → Java 的桥接 shim**:`bin/hermes.js` 用 `child_process.spawn` 启动 `java -jar hermes.jar`,
7
- > 并透传参数、stdin/stdout、退出码。npm 在这里只承担「分发 + 注册全局命令」的职责;
8
- > 181MB 的 jar 不进 npm 包,而是发布到 **GitHub Release**,安装时自动下载(esbuild 同款思路)。
5
+ > 这是一个 **JS → Java 桥接壳**:`bin/jhermes.js` 启动 `java -jar hermes.jar`。
6
+ > jar 不打进 npm 包(包仅 ~20KB),而是首次使用时从 GitHub Release 自动下载。
9
7
 
10
- ## 用户体验(安装者视角)
8
+ ---
11
9
 
12
- ```bash
13
- npm install -g sk-hermes-cli
14
- # postinstall 自动从 GitHub Release 下载 hermes.jar
15
- hermes # 任意目录直接对话,模型以当前目录为项目根
16
- ```
10
+ ## 安装
17
11
 
18
- ### 安装者前置依赖
19
- - **JDK 21+**(`java` 在 PATH 中,或设置 `JAVA_HOME`)
20
- - 首次运行前配置 `~/.skhermes/config.yaml` 的 `model.api_key`
21
- - 能访问 GitHub(下载 jar);被墙时可设 `SKHERMES_JAR_URL` 指向镜像,或 `SKHERMES_JAR` 指向本地文件
22
-
23
- ### 使用
12
+ **本包只在 npmjs 官方源发布**,直接安装即可:
24
13
 
25
14
  ```bash
26
- hermes # 在当前目录直接进入对话,模型以当前目录为项目根
27
- hermes -m fast # 指定模型别名
28
- hermes --help # 查看全部子命令(chat / sessions / resume)
29
- hermes chat -s # 显式子命令 + 流式输出
15
+ npm install -g sk-hermes-cli
30
16
  ```
31
17
 
32
- ### jar 查找优先级(运行时)
33
- 1. 环境变量 `SKHERMES_JAR`(显式指定,适合多版本共存 / 开发调试)
34
- 2. 包内 `jar/hermes.jar`(postinstall 下载的落地位置,或作者手动捆绑)
35
- 3. `~/.hermes/hermes.jar`(兼容 `tools/install-hermes.ps1` 的本地安装)
18
+ ### 前置依赖
19
+ - **JDK 21+**(`java` PATH 中,或设置 `JAVA_HOME`)
20
+ - 首次运行前,在 `~/.skhermes/config.yaml` 填入 `model.api_key`
36
21
 
37
22
  ---
38
23
 
39
- ## 作者发布教程(模式 B:GitHub Release 按需下载)
40
-
41
- > 下载地址不再依赖环境变量:**package.json 内置了默认 `hermes.jarUrl`**(本仓库发布版已指向
42
- > `https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v1.0.0/hermes.jar`),
43
- > 环境变量 `SKHERMES_JAR_URL` 仅作临时覆盖(优先于内置值)。
44
-
45
- ### 第 0 步:一次性准备(只做一次)
46
-
47
- | 检查项 | 命令 | 要求 |
48
- |---|---|---|
49
- | GitHub CLI | `gh auth status` | 已登录且 token 有 repo 权限 |
50
- | npm 账号 | `npm whoami` | 未登录则 `npm login`(浏览器注册/验证) |
51
- | 仓库可见性 | GitHub 仓库设置 | 必须 **public**(Release 资产匿名可下载,postinstall 才不用带 token) |
52
- | 包名可用性 | `npm view sk-hermes-cli` | 返回 404 = 未占用,可直接用 |
53
-
54
- ### 第 1 步:构建 jar 并发布到 GitHub Release(一键脚本,幂等)
55
-
56
- ```powershell
57
- cd <项目根>
58
- powershell -ExecutionPolicy Bypass -File tools\release.ps1
59
- # 指定版本号: -Version 1.1.0(默认取 npm-package\package.json 的 version)
60
- ```
61
-
62
- 脚本内部等价于三步(理解原理用):
63
-
64
- ```powershell
65
- mvn -f sk-hermes\pom.xml clean package -DskipTests # ① 构建 fat jar
66
- gh release create v1.0.0 --title "..." --target master # ② 建 Release(tag 须与 jarUrl 一致)
67
- Copy-Item sk-hermes\target\sk-hermes-1.0-SNAPSHOT.jar $env:TEMP\hermes.jar # ③ 先复制成 hermes.jar
68
- gh release upload v1.0.0 $env:TEMP\hermes.jar --clobber # 再上传(见下方"坑")
69
- ```
24
+ ## 🇨🇳 国内网络加速(强烈建议)
70
25
 
71
- > ⚠️ **gh `path#name` 重命名语法不可靠**(gh 2.97 实测 `#name` 只是 Web UI 显示标签,
72
- > 资产真实名始终 = 源文件 basename)。而 postinstall 下载 URL 尾段必须是 `hermes.jar`,
73
- > 所以**必须先把 jar 复制成物理文件名 `hermes.jar` 再上传**,否则用户安装时 404。
74
- > release.ps1 已内置这个复制步骤 + 上传后资产核验(大文件上传可能静默失败)。
26
+ jar 托管在 GitHub Release,**直连实测仅 ~95 KB/s**(45 MB 8 分钟,还常断流);走镜像可达 **~1.5 MB/s**。
75
27
 
76
- **验证下载地址可用**(期望 HTTP/2 200):
28
+ **安装前**设一次环境变量即可(postinstall 与首次运行都会读它):
77
29
 
78
30
  ```powershell
79
- curl.exe -sIL "https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v1.0.0/hermes.jar" | Select-Object -First 1
31
+ # PowerShell
32
+ $env:SKHERMES_JAR_URL = "https://gh-proxy.com/https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v2.0.1/hermes.jar"
33
+ npm install -g sk-hermes-cli
80
34
  ```
81
35
 
82
- ### 第 2 步:核对 package.json 内置地址
83
-
84
- ```json
85
- "hermes": { "jarUrl": "https://github.com/<owner>/<repo>/releases/download/v1.0.0/hermes.jar" }
36
+ ```bat
37
+ :: CMD
38
+ set SKHERMES_JAR_URL=https://gh-proxy.com/https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v2.0.1/hermes.jar
39
+ npm install -g sk-hermes-cli
86
40
  ```
87
41
 
88
- 发新版本时 tag 变了,两种策略二选一:
89
- - **URL 带具体 tag**(当前方案):每次发版改一行;地址永久有效、支持版本回滚
90
- - **`/releases/latest/download/hermes.jar`**:永远指向最新 Release,发版不用改;但用户无法锁旧版
91
-
92
- ### 第 3 步:发布前本地全链路验证(隔离,不污染全局)
93
-
94
- ```powershell
95
- cd npm-package
96
- npm pack --dry-run # 包内应只有 3~4 个小文件(无 jar),体积 ~3.5KB
97
-
98
- $pfx = "$env:TEMP\hermes_test"; New-Item -ItemType Directory -Force -Path $pfx | Out-Null
99
- npm install -g .\npm-package --prefix $pfx
100
- # 期望输出: [sk-hermes] 正在从 https://github.com/... 下载 hermes.jar ...
101
- # [sk-hermes] jar 已下载到 ...\jar\hermes.jar(181.x MB)
102
- & "$pfx\hermes.cmd" --version # 期望 1.0.0,退出码 0
103
- Remove-Item -Recurse -Force $pfx
42
+ ```bash
43
+ # bash / zsh
44
+ export SKHERMES_JAR_URL="https://gh-proxy.com/https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v2.0.1/hermes.jar"
45
+ npm i -g sk-hermes-cli
104
46
  ```
105
47
 
106
- > ⚠️ npm 开启了 install-scripts 安全策略(提示 `allow-scripts`),postinstall 会被拦截,
107
- > 执行 `npm approve-scripts sk-hermes-cli` 放行后重装。
108
-
109
- ### 第 4 步:发布
48
+ > 装完 jar 没下下来?不必重装——直接敲 `Jhermes` 会自动补下载(带 5 次重试)。
110
49
 
111
- ```powershell
112
- cd npm-package
113
- npm publish --access public
114
- ```
50
+ ---
115
51
 
116
- ### 第 5 步:日常迭代发版循环
52
+ ## 使用
117
53
 
118
- ```powershell
119
- mvn -f sk-hermes\pom.xml clean package -DskipTests # 1) 构建
120
- cd npm-package; npm version 1.1.0 --no-git-tag-version; cd .. # 2) 升版本号(npm 禁止同版本重复发布)
121
- powershell -ExecutionPolicy Bypass -File tools\release.ps1 # 3) 传新 tag 的 Release
122
- # 4) 同步修改 package.json hermes.jarUrl → v1.1.0
123
- npm pack --dry-run; 3 步验证; npm publish # 5) 验证后发布
54
+ ```bash
55
+ Jhermes # 在当前目录直接进入对话,模型以当前目录为项目根
56
+ Jhermes -m fast # 指定模型别名
57
+ Jhermes -s # 开启流式输出
58
+ Jhermes --help # 查看全部子命令(chat / sessions / resume)
59
+ Jhermes chat # 显式使用 chat 子命令
124
60
  ```
125
61
 
126
- ## 常见坑(全部实测踩过)
62
+ 首次运行会自动下载 hermes.jar(约 45 MB),之后直接启动。
127
63
 
128
- | 坑 | 现象 | 解法 |
129
- |---|---|---|
130
- | Release 资产名不对 | postinstall 下载 404 | 资产真名必须叫 `hermes.jar`;gh 的 `#重命名`不生效,须先 `Copy-Item` 成 hermes.jar 再 upload |
131
- | 大文件上传静默失败 | 资产列表为空/不全 | `gh release view v1.0.0 --json assets` 核验;失败重跑 release.ps1(幂等,含上传后自动核验) |
132
- | 仓库是 private | 匿名下载 404 | 仓库设 public;或 postinstall 带 token(复杂度高,不推荐) |
133
- | npm 拦截 postinstall | 装完没 jar,运行时提示找不到 | `npm approve-scripts sk-hermes-cli` 或 `npm rebuild` |
134
- | 包名被占用 | `npm publish` 403 | `npm view <名字>` 先探测;占用则换名或用 scoped 包 `@你/sk-hermes-cli` |
135
- | 含中文 .ps1 报语法错 | "字符串缺少终止符"、输出乱码 | 必须存**带 BOM 的 UTF-8**(PS 5.1 无 BOM 按 GBK 解析) |
136
- | gh stderr 触发 PS 终止 | `$ErrorActionPreference='Stop'` 时探测命令被误杀 | 探测类 gh 调用临时切回 Continue(见 release.ps1 的 Invoke-GhProbe) |
137
-
138
- ## 项目结构
139
-
140
- ```
141
- npm-package/
142
- ├── package.json # bin 声明(hermes + sk-hermes)+ hermes.jarUrl 内置下载地址
143
- ├── bin/hermes.js # shim:定位 jar → 定位 java → spawn 透传(stdio inherit + 退出码)
144
- ├── scripts/postinstall.js # 安装钩子:env > jarUrl 两级取值下载;任何失败都 exit 0 不阻断安装
145
- └── README.md
146
- ```
147
64
 
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
  /**
4
- * hermes CLI 入口(npm bin shim)。
4
+ * Jhermes CLI 入口(npm bin shim)。
5
5
  *
6
6
  * 职责链:定位 hermes.jar(找不到则懒加载下载兜底)→ 定位 java → spawn 子进程
7
7
  *
8
8
  * 关键点:
9
9
  * - jar 懒下载:不依赖 postinstall(npm 新版本可能拦截安装脚本),首次运行发现无 jar
10
10
  * 时现场下载(复用 scripts/download-jar.js 的重试逻辑),成功后才 spawn Java
11
+ * - 命令名 Jhermes 由 package.json 的 bin 字段注册(npm 据此生成 shim)
11
12
  * - stdio:'inherit' 让 Java 进程直接接管终端(交互式对话、Ctrl+C 都正常)
12
13
  * - 透传退出码,保证脚本化调用(if errorlevel 1)语义不被破坏
13
14
  */
@@ -62,7 +63,7 @@ async function main() {
62
63
  }
63
64
 
64
65
  // Windows 控制台默认代码页是 GBK,Java 侧用 -Dstdout.encoding=UTF-8 写出 UTF-8 字节,
65
- // 必须把控制台代码页也切到 UTF-8,两边编码对齐才不乱码(与 hermes.cmd 的 chcp 65001 同理)。
66
+ // 必须把控制台代码页也切到 UTF-8,两边编码对齐才不乱码(与 Jhermes.cmd 的 chcp 65001 同理)。
66
67
  // chcp 是 chcp.com 这个真实可执行文件,spawnSync 不带 shell 时必须写全名。
67
68
  if (process.platform === 'win32') {
68
69
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sk-hermes-cli",
3
- "version": "1.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "sk-Hermes:可自我进化的 AI Agent 命令行工具(Java fat-jar 的 npm 分发壳)",
5
5
  "keywords": [
6
6
  "cli",
@@ -13,8 +13,7 @@
13
13
  ],
14
14
  "license": "MIT",
15
15
  "bin": {
16
- "hermes": "bin/hermes.js",
17
- "sk-hermes": "bin/hermes.js"
16
+ "Jhermes": "bin/jhermes.js"
18
17
  },
19
18
  "files": [
20
19
  "bin/",
@@ -25,7 +24,11 @@
25
24
  "postinstall": "node scripts/postinstall.js"
26
25
  },
27
26
  "hermes": {
28
- "jarUrl": "https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v1.0.0/hermes.jar"
27
+ "jarUrl": "https://github.com/chen-2024-cn/Hermes-agent-Java-/releases/download/v2.0.1/hermes.jar"
28
+ },
29
+ "publishConfig": {
30
+ "registry": "https://registry.npmjs.org/",
31
+ "access": "public"
29
32
  },
30
33
  "engines": {
31
34
  "node": ">=18"
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * 被两处调用:
6
6
  * - scripts/postinstall.js:安装时 best-effort 预下载(可能被 npm allow-scripts 策略拦截)
7
- * - bin/hermes.js:首次运行时懒加载兜底(不依赖任何安装脚本,最可靠)
7
+ * - bin/jhermes.js:首次运行时懒加载兜底(不依赖任何安装脚本,最可靠)
8
8
  *
9
9
  * 设计要点(针对不稳定网络,尤其国内访问 GitHub Release CDN 易被 Connection reset):
10
10
  * - 整包重试 + 递增退避(重试窗口内大概率能撞上一次通畅)
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * postinstall 钩子:安装后 best-effort 预下载 hermes.jar。
4
4
  *
5
- * 定位是「加分项」而非「必需项」——下载逻辑同时内置于 bin/hermes.js(首次运行懒加载兜底),
5
+ * 定位是「加分项」而非「必需项」——下载逻辑同时内置于 bin/jhermes.js(首次运行懒加载兜底),
6
6
  * 因此即使本脚本被 npm 的 allow-scripts / ignore-scripts 策略拦截(npm 新版本默认可能拦),
7
- * 或下载因网络失败,用户敲 hermes 时依然会自动补下载,不影响可用性。
7
+ * 或下载因网络失败,用户敲 Jhermes 时依然会自动补下载,不影响可用性。
8
8
  *
9
9
  * 铁律:任何情况下都 exit 0,绝不阻断 npm install。
10
10
  * 真正的下载实现见 ./download-jar.js(bin 与此处共用同一份,避免逻辑漂移)。
@@ -20,7 +20,7 @@ process.on('uncaughtException', (err) => {
20
20
  const PKG_ROOT = path.join(__dirname, '..');
21
21
 
22
22
  (async () => {
23
- // 安装阶段少试几次(maxAttempts=3);失败无所谓,首次运行 hermes 时还会带 5 次重试再下
23
+ // 安装阶段少试几次(maxAttempts=3);失败无所谓,首次运行 Jhermes 时还会带 5 次重试再下
24
24
  await ensureJar({
25
25
  dest: path.join(PKG_ROOT, 'jar', 'hermes.jar'),
26
26
  url: resolveJarUrl(PKG_ROOT),