huhaa-myskills 0.3.4 → 0.3.5

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.
@@ -385,6 +385,23 @@ async function cmdStart() {
385
385
  await ensureConfigOrInit();
386
386
  const isForeground = process.argv.includes('--foreground') || process.argv.includes('-f');
387
387
  const preferred = parseInt(process.env.PORT || '11520', 10);
388
+
389
+ // 后台模式下先做幂等检查:已有实例在运行则直接返回,
390
+ // 避免 pickPort 误判端口被占用而打印"改用其它端口"的误导信息。
391
+ if (!isForeground) {
392
+ try {
393
+ const stateData = JSON.parse(fs.readFileSync(stateFile(), 'utf8'));
394
+ if (stateData.pid && isProcessRunning(stateData.pid)) {
395
+ const logFile = path.join(homeDir(), 'huhaa.log');
396
+ console.log(`✓ HuHaa-MySkills 已在运行: http://localhost:${stateData.port}`);
397
+ console.log(`📝 日志: ${logFile}`);
398
+ return;
399
+ }
400
+ } catch {
401
+ // 状态文件不存在或无效,继续正常启动流程
402
+ }
403
+ }
404
+
388
405
  const port = await pickPort(preferred, 10);
389
406
  if (!port) {
390
407
  console.error(`[start] ${preferred}..${preferred + 10} 范围内无空闲端口,已中止。`);
@@ -1134,6 +1134,53 @@ HuHaa-MySkills/
1134
1134
 
1135
1135
  ---
1136
1136
 
1137
+ ## VI.7 发布流程(npm 发布,唯一权威方式)
1138
+
1139
+ **发布完全由 GitHub Actions 自动完成,本地不执行 `npm publish`。**
1140
+
1141
+ ### 触发方式
1142
+
1143
+ ```bash
1144
+ # 1. 在 main 分支 bump 版本号并推送(脚本已封装)
1145
+ npm run release # = npm version patch && git push
1146
+
1147
+ # 2. 推送到 main 后,.github/workflows/release.yml 自动:
1148
+ # 读 package.json 版本 → 若远程无对应 tag → 构建 → npm publish → 打 tag → 建 GitHub Release
1149
+ ```
1150
+
1151
+ ### 关键设计(release.yml)
1152
+
1153
+ - **触发条件**:`push` 到 `main` 分支(不是 tag 触发)
1154
+ - **幂等**:先检查远程是否已存在 `v<version>` tag,存在则整体跳过,重复推送 main 不会重复发布
1155
+ - **顺序**:`npm publish` 成功 **之后** 才创建 tag。publish 失败不会遗留僵尸 tag,修复后重推即可重试
1156
+ - **发布说明**:`generate_release_notes: true` 自动生成,不依赖 CHANGELOG.md
1157
+
1158
+ ### 凭证配置(NPM_TOKEN,一次性)
1159
+
1160
+ 发布身份由 GitHub 仓库 Secret `NPM_TOKEN` 提供,对应 npm 账号 `huhaaonline`(包 owner)。
1161
+
1162
+ ```bash
1163
+ # token 失效/轮换时,用有 publish 权限的 Automation token 更新 secret:
1164
+ gh secret set NPM_TOKEN --body '<npm token>'
1165
+
1166
+ # 验证 token 有效且身份正确:
1167
+ printf '//registry.npmjs.org/:_authToken=%s\n' '<token>' > /tmp/v.npmrc
1168
+ npm whoami --userconfig /tmp/v.npmrc # 应输出 huhaaonline
1169
+ rm -f /tmp/v.npmrc
1170
+ ```
1171
+
1172
+ **故障对照**:CI 中 `npm publish` 报 `E404 PUT .../huhaa-myskills` = token 已注入但身份无该包写权限(npm 用 404 伪装 403),即 `NPM_TOKEN` 失效或非 owner,需按上面重配。
1173
+
1174
+ ### 发布后验证
1175
+
1176
+ ```bash
1177
+ gh run watch # CI 全绿
1178
+ npm view huhaa-myskills version # 应为新版本
1179
+ npm install -g huhaa-myskills@latest && huhaa-myskills -v
1180
+ ```
1181
+
1182
+ ---
1183
+
1137
1184
  # 七、相关资源
1138
1185
 
1139
1186
  - **[Vite 官方文档](https://vite.dev)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huhaa-myskills",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "private": false,
5
5
  "description": "Local skill / plugin / MCP aggregation hub. Browse all your AI agent skills at http://localhost:11520.",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "init": "node bin/huhaa-myskills.mjs init",
40
40
  "purge": "node bin/huhaa-myskills.mjs purge",
41
41
  "uninstall": "node bin/huhaa-myskills.mjs uninstall",
42
- "dev": "cd packages/web && npm run dev",
42
+ "dev": "node bin/huhaa-myskills.mjs start && cd packages/web && npm run dev",
43
43
  "dev-bg": "bash scripts/start-dev.sh",
44
44
  "sync": "node bin/huhaa-myskills.mjs sync",
45
45
  "build:web": "node build/build-web.mjs",
@@ -6,6 +6,11 @@ import test from 'node:test';
6
6
 
7
7
  import { startServer } from '../src/index.mjs';
8
8
 
9
+ // 动态读取根 package.json 的版本号,避免每次升版本导致断言失效
10
+ const PKG_VERSION = JSON.parse(
11
+ fs.readFileSync(new URL('../../../package.json', import.meta.url), 'utf8')
12
+ ).version;
13
+
9
14
  function makeTempHome() {
10
15
  const root = fs.mkdtempSync(path.join(os.tmpdir(), 'huhaa-server-test-'));
11
16
  const home = path.join(root, 'home');
@@ -54,7 +59,7 @@ test('server exposes health, list, detail, stats, and reload state without raw i
54
59
  ok: true,
55
60
  port: 0,
56
61
  items: 1,
57
- version: '0.3.2',
62
+ version: PKG_VERSION,
58
63
  phase: 'P6',
59
64
  });
60
65