ai-yuca 1.6.4 → 1.6.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,7 @@
5
5
  ### Added
6
6
  - 新增 `pm2-release` 命令,可读取项目 `package.json` 的 `ai-yuca.pm2Release` 配置,统一执行 PM2 远程 `setup` / `deploy`。
7
7
  - `pm2-release` 支持运行时生成临时 PM2 ecosystem 配置,项目侧只需维护 `package.json` 的发布差异配置。
8
+ - `pm2-release` 在 pnpm 项目缺少 `pnpm-lock.yaml` 时会发布前询问;远端分支没有 lockfile 时自动降级为 `pnpm install --no-frozen-lockfile`。
8
9
  - `pm2-release` 支持 SSH alias 预检、SSH ControlMaster 复用、发布 ref 覆盖、PM2 命令覆盖,以及 test/prod/all 目标。
9
10
 
10
11
  ## [1.6.3] - 2026-06-05
package/README.md CHANGED
@@ -219,6 +219,7 @@ ai-yuca pm2-release deploy prod --ref origin/main
219
219
  "repo": "git@github.com:HEchooo/project.git",
220
220
  "packageManager": "pnpm",
221
221
  "pm2Command": "pnpm exec pm2",
222
+ "allowNoPnpmLockfile": false,
222
223
  "deployName": "server",
223
224
  "environments": {
224
225
  "test": {
@@ -239,6 +240,8 @@ ai-yuca pm2-release deploy prod --ref origin/main
239
240
  }
240
241
  ```
241
242
 
243
+ pnpm 项目默认优先使用 `pnpm install --frozen-lockfile`。如果本地没有 `pnpm-lock.yaml`,`pm2-release deploy` 会先询问是否继续;如果远端目标分支没有 lockfile,会自动降级为 `pnpm install --no-frozen-lockfile`。如果项目明确不提交 lockfile,可设置 `"allowNoPnpmLockfile": true`。
244
+
242
245
  ## 资源处理
243
246
 
244
247
  ### sharp 本地压缩
package/dist/bin/cli.js CHANGED
@@ -242,7 +242,7 @@ program
242
242
  .option('--env-name <name>', '覆盖注入到 PM2_DEPLOY_ENV 的环境名')
243
243
  .option('--package-manager <name>', '覆盖 PM2 执行器推断,支持 npm 或 pnpm')
244
244
  .option('--pm2-command <command>', '自定义 PM2 命令,例如 "pnpm exec pm2" 或 "npx pm2"')
245
- .action((action, target, options) => {
245
+ .action(async (action, target, options) => {
246
246
  try {
247
247
  if (action !== 'setup' && action !== 'deploy') {
248
248
  throw new Error('action 只能是 setup 或 deploy。');
@@ -251,7 +251,7 @@ program
251
251
  if (resolvedTarget !== 'test' && resolvedTarget !== 'prod' && resolvedTarget !== 'all') {
252
252
  throw new Error('target 只能是 test、prod 或 all。');
253
253
  }
254
- (0, pm2Release_1.pm2Release)(action, resolvedTarget, options);
254
+ await (0, pm2Release_1.pm2Release)(action, resolvedTarget, options);
255
255
  }
256
256
  catch (err) {
257
257
  console.error(`PM2 发布错误: ${err instanceof Error ? err.message : String(err)}`);
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-yuca",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "一个用AI生成的开发辅助工具",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -1,2 +1,2 @@
1
1
  import { Pm2ReleaseAction, Pm2ReleaseCommandOptions, Pm2ReleaseTarget } from './types/pm2Release';
2
- export declare function pm2Release(action: Pm2ReleaseAction, target: Pm2ReleaseTarget | 'all', options?: Pm2ReleaseCommandOptions): void;
2
+ export declare function pm2Release(action: Pm2ReleaseAction, target: Pm2ReleaseTarget | 'all', options?: Pm2ReleaseCommandOptions): Promise<void>;
@@ -38,6 +38,7 @@ const fs = __importStar(require("fs"));
38
38
  const os = __importStar(require("os"));
39
39
  const path = __importStar(require("path"));
40
40
  const child_process_1 = require("child_process");
41
+ const readline = __importStar(require("readline"));
41
42
  function readJson(filePath) {
42
43
  return JSON.parse(fs.readFileSync(filePath, 'utf8'));
43
44
  }
@@ -184,7 +185,10 @@ function getInstallCommand(config) {
184
185
  if (config.installCommand) {
185
186
  return config.installCommand;
186
187
  }
187
- return config.packageManager === 'pnpm' ? 'pnpm install --frozen-lockfile' : 'npm ci';
188
+ if (config.packageManager === 'pnpm') {
189
+ return 'if test -f pnpm-lock.yaml; then pnpm install --frozen-lockfile; else echo pnpm_lock_missing_use_no_frozen_lockfile; pnpm install --no-frozen-lockfile; fi';
190
+ }
191
+ return 'npm ci';
188
192
  }
189
193
  function getRunCommand(config) {
190
194
  if (config.runCommand) {
@@ -260,6 +264,37 @@ function getEnvConfig(config, target) {
260
264
  }
261
265
  return envConfig;
262
266
  }
267
+ function confirm(question) {
268
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
269
+ return Promise.resolve(false);
270
+ }
271
+ const rl = readline.createInterface({
272
+ input: process.stdin,
273
+ output: process.stdout,
274
+ });
275
+ return new Promise((resolve) => {
276
+ rl.question(`${question} (y/N) `, (answer) => {
277
+ rl.close();
278
+ resolve(['y', 'yes'].includes(answer.trim().toLowerCase()));
279
+ });
280
+ });
281
+ }
282
+ async function ensurePnpmLockfile(packageRoot, config, action) {
283
+ if (action !== 'deploy' || config.installCommand || config.packageManager !== 'pnpm') {
284
+ return;
285
+ }
286
+ if (fs.existsSync(path.join(packageRoot, 'pnpm-lock.yaml'))) {
287
+ return;
288
+ }
289
+ if (config.allowNoPnpmLockfile) {
290
+ console.warn('未找到 pnpm-lock.yaml,将允许远端使用 pnpm install --no-frozen-lockfile。');
291
+ return;
292
+ }
293
+ const shouldContinue = await confirm('未找到 pnpm-lock.yaml。是否继续发布,并在远端使用 pnpm install --no-frozen-lockfile?');
294
+ if (!shouldContinue) {
295
+ throw new Error('已取消发布:pnpm 项目缺少 pnpm-lock.yaml。');
296
+ }
297
+ }
263
298
  function runPm2(packageRoot, packageJson, config, action, target, options) {
264
299
  const envConfig = getEnvConfig(config, target);
265
300
  const hosts = normalizeHosts(envConfig.hosts);
@@ -315,7 +350,10 @@ function pm2Release(action, target, options = {}) {
315
350
  throw new Error('package.json 缺少 ai-yuca.pm2Release 配置。');
316
351
  }
317
352
  const targets = target === 'all' ? ['test', 'prod'] : [target];
318
- for (const releaseTarget of targets) {
319
- runPm2(packageRoot, packageJson, config, action, releaseTarget, options);
320
- }
353
+ return (async () => {
354
+ await ensurePnpmLockfile(packageRoot, config, action);
355
+ for (const releaseTarget of targets) {
356
+ runPm2(packageRoot, packageJson, config, action, releaseTarget, options);
357
+ }
358
+ })();
321
359
  }
@@ -24,6 +24,7 @@ export interface Pm2ReleaseConfig {
24
24
  pm2Command?: string;
25
25
  installCommand?: string;
26
26
  runCommand?: string;
27
+ allowNoPnpmLockfile?: boolean;
27
28
  environments: {
28
29
  test: Pm2ReleaseEnvConfig;
29
30
  prod: Pm2ReleaseEnvConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-yuca",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "一个用AI生成的开发辅助工具",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",