ai-project-manage-cli 6.0.86 → 6.0.88

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.
Files changed (2) hide show
  1. package/dist/index.js +233 -50
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2281,7 +2281,8 @@ function validateDeployPush(o) {
2281
2281
  type: "deploy",
2282
2282
  deploymentRunId: o.deploymentRunId.trim(),
2283
2283
  workdir: o.workdir.trim(),
2284
- environment
2284
+ environment,
2285
+ ...o.packOnly === true ? { packOnly: true } : {}
2285
2286
  }
2286
2287
  };
2287
2288
  }
@@ -2483,7 +2484,7 @@ async function fetchDeployArtifactStorage(api) {
2483
2484
  }
2484
2485
  async function uploadDeployArtifactZip(options) {
2485
2486
  const deploymentRunId = options.deploymentRunId ?? resolveDeploymentRunIdFromEnv();
2486
- if (!deploymentRunId) {
2487
+ if (!deploymentRunId && !options.uploadWithoutRunId) {
2487
2488
  return null;
2488
2489
  }
2489
2490
  const cfg = await tryReadApmConfig();
@@ -2536,19 +2537,21 @@ async function uploadDeployArtifactZip(options) {
2536
2537
  console.warn(`[apm] MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863\u5931\u8D25: ${detail}`);
2537
2538
  return null;
2538
2539
  }
2539
- try {
2540
- await api.cli.attachTaskDeploymentArtifact({
2541
- id: deploymentRunId,
2542
- artifactObjectKey: objectKey,
2543
- artifactFileName: fileName
2544
- });
2545
- console.error(
2546
- `[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
2547
- );
2548
- } catch (error) {
2549
- const detail = error instanceof Error ? error.message : String(error);
2550
- console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
2551
- return null;
2540
+ if (deploymentRunId) {
2541
+ try {
2542
+ await api.cli.attachTaskDeploymentArtifact({
2543
+ id: deploymentRunId,
2544
+ artifactObjectKey: objectKey,
2545
+ artifactFileName: fileName
2546
+ });
2547
+ console.error(
2548
+ `[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
2549
+ );
2550
+ } catch (error) {
2551
+ const detail = error instanceof Error ? error.message : String(error);
2552
+ console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
2553
+ return null;
2554
+ }
2552
2555
  }
2553
2556
  return {
2554
2557
  objectKey,
@@ -2559,8 +2562,8 @@ async function uploadDeployArtifactZip(options) {
2559
2562
 
2560
2563
  // src/commands/connect/deploy-run.ts
2561
2564
  var DEPLOY_LOG_SYNC_INTERVAL_MS = 3e4;
2562
- function resolveDeployCommand(environment) {
2563
- return `apm deploy ${environment}`;
2565
+ function resolveDeployCommand(environment, packOnly) {
2566
+ return packOnly ? `apm deploy ${environment} --pack-only` : `apm deploy ${environment}`;
2564
2567
  }
2565
2568
  function buildDeployLog(stdout, stderr) {
2566
2569
  return [stdout, stderr].filter(Boolean).join("\n");
@@ -2656,7 +2659,7 @@ async function handleInboundDeploy(cfg, msg, signal) {
2656
2659
  status: "DEPLOYING"
2657
2660
  });
2658
2661
  const workdir = requireRemoteWorkdir(msg.workdir);
2659
- const command = resolveDeployCommand(msg.environment);
2662
+ const command = resolveDeployCommand(msg.environment, msg.packOnly);
2660
2663
  console.log(
2661
2664
  `[apm] deploy start id=${deploymentRunId} env=${msg.environment} cwd=${workdir}`
2662
2665
  );
@@ -4673,6 +4676,12 @@ function formatDeployNotConfiguredLines(env, deployCommands) {
4673
4676
  "[apm] \u90E8\u5206\u9879\u76EE\u4E0D\u652F\u6301\u6216\u672A\u542F\u7528\u81EA\u52A8\u5316\u90E8\u7F72\uFF0C\u5C5E\u6B63\u5E38\u60C5\u51B5\uFF0C\u53EF\u8DF3\u8FC7\u90E8\u7F72"
4674
4677
  ];
4675
4678
  }
4679
+ function formatWisdomFrontendBuildNotConfiguredLines(env, packageJsonPath) {
4680
+ return [
4681
+ `[apm] \u65E0\u6CD5\u6267\u884C\u4EC5\u6253\u5305\uFF1A${packageJsonPath} \u4E2D\u672A\u627E\u5230 build:${env} \u811A\u672C`,
4682
+ "[apm] \u8BF7\u914D\u7F6E npm run build:test / build:online \u540E\u518D\u8BD5"
4683
+ ];
4684
+ }
4676
4685
  function formatWisdomFrontendDeployNotConfiguredLines(env, packageJsonPath) {
4677
4686
  return [
4678
4687
  `[apm] \u65E0\u6CD5\u6267\u884C\u90E8\u7F72\uFF1A${packageJsonPath} \u4E2D\u672A\u627E\u5230 deploy:${env} \u811A\u672C`,
@@ -4693,7 +4702,7 @@ var DeployExecutionError = class extends Error {
4693
4702
  };
4694
4703
 
4695
4704
  // src/commands/deploy/internal/wisdom-auto-deploy.ts
4696
- import { existsSync as existsSync17, readFileSync as readFileSync14 } from "node:fs";
4705
+ import { existsSync as existsSync17, readFileSync as readFileSync14, statSync as statSync7 } from "node:fs";
4697
4706
  import path4 from "node:path";
4698
4707
  import { spawnSync as spawnSync4 } from "node:child_process";
4699
4708
 
@@ -4837,19 +4846,30 @@ async function uploadAndMaybeExtract(settings, localZip, extract) {
4837
4846
  async function runWisdomSftpDeploy(params) {
4838
4847
  const zipPath = path2.join(params.localDir, "..", ".deploy-sftp-dist.zip");
4839
4848
  const resolvedZipPath = path2.resolve(zipPath);
4849
+ const packOnly = Boolean(params.packOnly);
4840
4850
  let zipSizeBytes = 0;
4851
+ let artifactUploaded = false;
4841
4852
  try {
4842
4853
  zipSizeBytes = await zipDirectory(params.localDir, resolvedZipPath);
4843
- await uploadAndMaybeExtract(
4844
- params.settings,
4845
- resolvedZipPath,
4846
- params.extract
4847
- );
4848
- await uploadDeployArtifactZip({
4854
+ if (!packOnly) {
4855
+ await uploadAndMaybeExtract(
4856
+ params.settings,
4857
+ resolvedZipPath,
4858
+ params.extract
4859
+ );
4860
+ } else {
4861
+ console.error("[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7 SFTP \u8FDC\u7A0B\u4E0A\u4F20");
4862
+ }
4863
+ const artifact = await uploadDeployArtifactZip({
4849
4864
  zipPath: resolvedZipPath,
4850
4865
  projectName: params.projectName,
4851
- kind: "frontend"
4866
+ kind: "frontend",
4867
+ uploadWithoutRunId: packOnly && !resolveDeploymentRunIdFromEnv()
4852
4868
  });
4869
+ artifactUploaded = artifact !== null;
4870
+ if (packOnly && artifactUploaded) {
4871
+ console.error("\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09");
4872
+ }
4853
4873
  } finally {
4854
4874
  try {
4855
4875
  await unlink(resolvedZipPath);
@@ -4863,7 +4883,9 @@ async function runWisdomSftpDeploy(params) {
4863
4883
  host: params.settings.host,
4864
4884
  remotePath: params.settings.remotePath,
4865
4885
  zipSizeBytes,
4866
- extracted: params.extract
4886
+ extracted: packOnly ? false : params.extract,
4887
+ packOnly,
4888
+ artifactUploaded
4867
4889
  };
4868
4890
  }
4869
4891
 
@@ -5387,19 +5409,64 @@ async function restartRemoteService(client, config) {
5387
5409
  const script = buildRemoteRestartScript(config.remoteAppDir);
5388
5410
  await runRemoteServiceScript(client, script, "restart");
5389
5411
  }
5412
+ function listAllLibFilesForArchive(libDir) {
5413
+ return readdirSync5(libDir).filter((name) => name.endsWith(".jar")).sort().map((jarName) => ({
5414
+ path: path3.join(libDir, jarName),
5415
+ arcname: jarName,
5416
+ reason: "\u4EC5\u6253\u5305\u5F52\u6863"
5417
+ }));
5418
+ }
5390
5419
  async function runWisdomBackendDeploy(options) {
5391
5420
  const projectRoot = path3.resolve(options.projectRoot ?? process.cwd());
5392
5421
  const config = options.config;
5422
+ const packOnly = Boolean(options.packOnly);
5393
5423
  log(`=== \u81EA\u52A8\u90E8\u7F72: ${config.projectName} ===`);
5394
5424
  log(`\u914D\u7F6E\u6587\u4EF6: ${path3.join(workspaceApmDir(), "apm.config.json")}`);
5395
5425
  log(`\u9879\u76EE\u6839\u76EE\u5F55: ${projectRoot}`);
5396
5426
  log(
5397
- `\u90E8\u7F72\u6A21\u5F0F: ${config.mode}${config.mode === "full" ? "\uFF08\u5168\u91CF JAR\uFF0C\u8DF3\u8FC7 lib \u68C0\u67E5\uFF09" : "\uFF08\u589E\u91CF lib \u66F4\u65B0\uFF09"}`
5427
+ `\u90E8\u7F72\u6A21\u5F0F: ${config.mode}${config.mode === "full" ? "\uFF08\u5168\u91CF JAR\uFF0C\u8DF3\u8FC7 lib \u68C0\u67E5\uFF09" : "\uFF08\u589E\u91CF lib \u66F4\u65B0\uFF09"}${packOnly ? "\uFF1B\u4EC5\u6253\u5305\uFF08\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\uFF09" : ""}`
5398
5428
  );
5399
5429
  runMavenBuild(projectRoot, config.mavenLocalRepo, {
5400
5430
  source: config.mavenLocalRepoSource,
5401
5431
  sourceDetail: config.mavenLocalRepoSourceDetail
5402
5432
  });
5433
+ if (packOnly) {
5434
+ const uploadWithoutRunId = !resolveDeploymentRunIdFromEnv();
5435
+ if (config.mode === "full") {
5436
+ const mainJar = locateMainJar(projectRoot);
5437
+ const archiveZipPath = await createUpdatePackage(
5438
+ [
5439
+ {
5440
+ path: mainJar,
5441
+ arcname: path3.basename(mainJar),
5442
+ reason: "\u5168\u91CF JAR \u5F52\u6863"
5443
+ }
5444
+ ],
5445
+ `.deploy-archive-${config.projectName}.jar.zip`
5446
+ );
5447
+ await uploadDeployArtifactZip({
5448
+ zipPath: archiveZipPath,
5449
+ projectName: config.projectName,
5450
+ kind: "backend",
5451
+ uploadWithoutRunId
5452
+ });
5453
+ } else {
5454
+ const libDir = locateLibDir(projectRoot);
5455
+ const entries = listAllLibFilesForArchive(libDir);
5456
+ if (entries.length === 0) {
5457
+ fail("lib \u76EE\u5F55\u4E0B\u6CA1\u6709\u53EF\u5F52\u6863\u7684 JAR");
5458
+ }
5459
+ const zipPath = await createUpdatePackage(entries, config.packageName);
5460
+ await uploadDeployArtifactZip({
5461
+ zipPath,
5462
+ projectName: config.projectName,
5463
+ kind: "backend",
5464
+ uploadWithoutRunId
5465
+ });
5466
+ }
5467
+ log("\u4EC5\u6253\u5305\u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09");
5468
+ return;
5469
+ }
5403
5470
  const conn = await connectSsh(config);
5404
5471
  try {
5405
5472
  if (config.mode === "full") {
@@ -5521,6 +5588,14 @@ function resolveFrontendDeployCommand(env, cwd) {
5521
5588
  }
5522
5589
  return null;
5523
5590
  }
5591
+ function resolveFrontendBuildCommand(env, cwd) {
5592
+ const scripts = readPackageScripts(cwd);
5593
+ const buildKey = `build:${env}`;
5594
+ if (scripts[buildKey]?.trim()) {
5595
+ return `npm run build:${env}`;
5596
+ }
5597
+ return null;
5598
+ }
5524
5599
  function runShellCommand2(command, cwd, captureOutput) {
5525
5600
  const result = spawnSync4(command, {
5526
5601
  cwd,
@@ -5545,14 +5620,58 @@ function runShellCommand2(command, cwd, captureOutput) {
5545
5620
  }
5546
5621
  return output;
5547
5622
  }
5623
+ function resolveFrontendDistDir(cwd) {
5624
+ const candidates = ["dist", "apps/web/dist"];
5625
+ for (const rel of candidates) {
5626
+ const full = path4.join(cwd, rel);
5627
+ try {
5628
+ if (existsSync17(full) && statSync7(full).isDirectory()) {
5629
+ return full;
5630
+ }
5631
+ } catch {
5632
+ }
5633
+ }
5634
+ return path4.join(cwd, "dist");
5635
+ }
5548
5636
  async function runWisdomAutoDeploy(options) {
5549
5637
  const cwd = path4.resolve(options.cwd ?? process.cwd());
5550
5638
  const captureOutput = options.captureOutput ?? false;
5639
+ const packOnly = Boolean(options.packOnly);
5551
5640
  const projectType = detectWisdomProjectType(cwd);
5641
+ const configPath = options.configPath ?? path4.join(workspaceApmDir(cwd), "apm.config.json");
5642
+ const cfg = loadApmConfig({ configPath });
5552
5643
  console.error(
5553
- `[apm] \u533B\u52A1\u5B58\u91CF\u9879\u76EE\u81EA\u52A8\u8BC6\u522B: ${projectType === "frontend" ? "\u524D\u7AEF Vue" : "\u540E\u7AEF Java"}`
5644
+ `[apm] \u533B\u52A1\u5B58\u91CF\u9879\u76EE\u81EA\u52A8\u8BC6\u522B: ${projectType === "frontend" ? "\u524D\u7AEF Vue" : "\u540E\u7AEF Java"}${packOnly ? "\uFF08\u4EC5\u6253\u5305\u6A21\u5F0F\uFF09" : ""}`
5554
5645
  );
5555
5646
  if (projectType === "frontend") {
5647
+ if (packOnly) {
5648
+ const buildCmd = resolveFrontendBuildCommand(options.env, cwd);
5649
+ if (!buildCmd) {
5650
+ const lines = formatWisdomFrontendBuildNotConfiguredLines(
5651
+ options.env,
5652
+ path4.join(cwd, "package.json")
5653
+ );
5654
+ throw new DeployExecutionError(lines.join("\n"), 1, lines.join("\n"));
5655
+ }
5656
+ console.error(`[apm] \u524D\u7AEF\u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u6267\u884C ${buildCmd}`);
5657
+ runShellCommand2(buildCmd, cwd, captureOutput);
5658
+ const projectName = (cfg.name ?? "").trim();
5659
+ if (!projectName) {
5660
+ throw new DeployExecutionError(
5661
+ "\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09",
5662
+ 1
5663
+ );
5664
+ }
5665
+ const settings2 = resolveWisdomDeployFromApmConfig(cfg);
5666
+ await runWisdomSftpDeploy({
5667
+ localDir: resolveFrontendDistDir(cwd),
5668
+ settings: settings2,
5669
+ extract: false,
5670
+ projectName,
5671
+ packOnly: true
5672
+ });
5673
+ return { projectType };
5674
+ }
5556
5675
  const deployCmd = resolveFrontendDeployCommand(options.env, cwd);
5557
5676
  if (!deployCmd) {
5558
5677
  const lines = formatWisdomFrontendDeployNotConfiguredLines(
@@ -5564,15 +5683,18 @@ async function runWisdomAutoDeploy(options) {
5564
5683
  runShellCommand2(deployCmd, cwd, captureOutput);
5565
5684
  return { projectType };
5566
5685
  }
5567
- const configPath = options.configPath ?? path4.join(workspaceApmDir(cwd), "apm.config.json");
5568
- const cfg = loadApmConfig({ configPath });
5569
5686
  const settings = resolveWisdomBackendDeployFromApmConfig(cfg);
5570
- console.error(
5571
- `[apm] \u540E\u7AEF\u90E8\u7F72\u4E0D\u533A\u5206 test/online\uFF0C\u5FFD\u7565\u73AF\u5883\u53C2\u6570: ${options.env}`
5572
- );
5687
+ if (packOnly) {
5688
+ console.error(`[apm] \u540E\u7AEF\u4EC5\u6253\u5305\u6A21\u5F0F\uFF0C\u5FFD\u7565\u73AF\u5883\u53C2\u6570: ${options.env}`);
5689
+ } else {
5690
+ console.error(
5691
+ `[apm] \u540E\u7AEF\u90E8\u7F72\u4E0D\u533A\u5206 test/online\uFF0C\u5FFD\u7565\u73AF\u5883\u53C2\u6570: ${options.env}`
5692
+ );
5693
+ }
5573
5694
  await runWisdomBackendDeploy({
5574
5695
  config: settings,
5575
- projectRoot: cwd
5696
+ projectRoot: cwd,
5697
+ packOnly
5576
5698
  });
5577
5699
  return { projectType };
5578
5700
  }
@@ -5779,7 +5901,8 @@ async function executeDeploy(options) {
5779
5901
  env: options.env,
5780
5902
  cwd,
5781
5903
  configPath: options.configPath,
5782
- captureOutput
5904
+ captureOutput,
5905
+ packOnly: options.packOnly
5783
5906
  });
5784
5907
  return outputParts.join("\n");
5785
5908
  } catch (error) {
@@ -5934,21 +6057,26 @@ function registerDeployMainCommand(program) {
5934
6057
  ).option(
5935
6058
  "--session <sessionId>",
5936
6059
  "\u6C9F\u901A\u7FA4 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7"
6060
+ ).option(
6061
+ "--pack-only",
6062
+ "\u4EC5\u6784\u5EFA/\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF08\u524D\u7AEF build:<env>\uFF0C\u540E\u7AEF Maven \u6784\u5EFA\uFF09"
5937
6063
  ).action(
5938
6064
  async (env, opts) => {
5939
6065
  const cwd = process.cwd();
5940
6066
  const sessionId = opts.session?.trim();
6067
+ const packOnly = Boolean(opts.packOnly);
5941
6068
  try {
5942
6069
  if (sessionId) {
5943
6070
  await runDeployWithBackendTracking({
5944
6071
  env,
5945
6072
  cwd,
5946
6073
  configPath: opts.config,
5947
- sessionId
6074
+ sessionId,
6075
+ packOnly
5948
6076
  });
5949
6077
  return;
5950
6078
  }
5951
- await executeDeploy({ env, cwd, configPath: opts.config });
6079
+ await executeDeploy({ env, cwd, configPath: opts.config, packOnly });
5952
6080
  } catch (error) {
5953
6081
  if (error instanceof DeployExecutionError) {
5954
6082
  printDeployExecutionError(error);
@@ -6193,7 +6321,7 @@ var DockerodeClient = class {
6193
6321
  var createDockerodeClient = (config) => new DockerodeClient(config);
6194
6322
 
6195
6323
  // src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
6196
- import { existsSync as existsSync19, readFileSync as readFileSync16, statSync as statSync7 } from "node:fs";
6324
+ import { existsSync as existsSync19, readFileSync as readFileSync16, statSync as statSync8 } from "node:fs";
6197
6325
  import path7 from "node:path";
6198
6326
  function stripSurroundingQuotes(value) {
6199
6327
  const t = value.trim();
@@ -6210,7 +6338,7 @@ function loadEnvFromFile(envFilePath) {
6210
6338
  return {};
6211
6339
  }
6212
6340
  const targetPath = path7.resolve(envFilePath);
6213
- if (!existsSync19(targetPath) || !statSync7(targetPath).isFile()) {
6341
+ if (!existsSync19(targetPath) || !statSync8(targetPath).isFile()) {
6214
6342
  return {};
6215
6343
  }
6216
6344
  const raw = readFileSync16(targetPath, "utf-8");
@@ -6514,7 +6642,7 @@ function registerDeployBackendCommands(program) {
6514
6642
  }
6515
6643
 
6516
6644
  // src/commands/deploy/frontend.ts
6517
- import { copyFile, readdir as readdir3, stat } from "node:fs/promises";
6645
+ import { copyFile, readdir as readdir3, stat, unlink as unlink2 } from "node:fs/promises";
6518
6646
  import path11 from "node:path";
6519
6647
  function resolveArtifactNamePrefix(cfg) {
6520
6648
  const nameRaw = (cfg.name ?? "").trim();
@@ -6578,6 +6706,44 @@ async function ensureArtifactRootIndexHtml(root) {
6578
6706
  );
6579
6707
  process.exit(1);
6580
6708
  }
6709
+ async function runFrontendPackOnlyDeploy(root, namePrefix) {
6710
+ const zipPath = path11.resolve(root, "..", ".deploy-frontend-dist.zip");
6711
+ let zipSizeBytes = 0;
6712
+ let artifactUploaded = false;
6713
+ try {
6714
+ zipSizeBytes = await zipDirectory(root, zipPath);
6715
+ console.error("[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7\u524D\u7AEF\u8BBF\u95EE\u6876\u4E0A\u4F20");
6716
+ const artifact = await uploadDeployArtifactZip({
6717
+ zipPath,
6718
+ projectName: namePrefix,
6719
+ kind: "frontend",
6720
+ uploadWithoutRunId: true
6721
+ });
6722
+ artifactUploaded = artifact !== null;
6723
+ if (artifactUploaded) {
6724
+ console.error("\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u81F3\u524D\u7AEF\u8BBF\u95EE\u6876\uFF09");
6725
+ }
6726
+ console.log(
6727
+ JSON.stringify(
6728
+ {
6729
+ ok: true,
6730
+ packOnly: true,
6731
+ namePrefix,
6732
+ zipSizeBytes,
6733
+ artifactUploaded
6734
+ },
6735
+ null,
6736
+ 2
6737
+ )
6738
+ );
6739
+ } finally {
6740
+ try {
6741
+ await unlink2(zipPath);
6742
+ console.error(`\u5DF2\u6E05\u7406\u672C\u5730\u4E34\u65F6\u6587\u4EF6: ${zipPath}`);
6743
+ } catch {
6744
+ }
6745
+ }
6746
+ }
6581
6747
  function registerDeployFrontendCommands(program) {
6582
6748
  program.command("deploy-frontend").description(
6583
6749
  "\u9012\u5F52\u4E0A\u4F20\u524D\u7AEF\u4EA7\u7269\u76EE\u5F55\u5230 MinIO\uFF0C\u5E76\u5728\u6210\u529F\u540E\u4E3A\u8BE5\u6876\u8BBE\u7F6E\u533F\u540D\u53EF\u8BFB\u7B56\u7565\uFF08MinIO \u8FDE\u63A5\u4FE1\u606F\u4EC5\u6765\u81EA apm.config.json frontendDeploy\uFF09"
@@ -6592,10 +6758,23 @@ function registerDeployFrontendCommands(program) {
6592
6758
  "--max-file-size-mb <mb>",
6593
6759
  `\u5355\u6587\u4EF6\u5927\u5C0F\u4E0A\u9650\uFF0C\u9ED8\u8BA4 ${DEFAULT_MAX_FILE_SIZE_MB}`,
6594
6760
  (v) => Number.parseInt(String(v), 10)
6761
+ ).option(
6762
+ "--pack-only",
6763
+ "\u4EC5\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u81F3\u524D\u7AEF\u8BBF\u95EE\u6876\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09"
6595
6764
  ).action(
6596
6765
  async (name, opts) => {
6597
6766
  const cfg = loadApmConfig({ configPath: opts.config });
6598
6767
  const namePrefix = resolveArtifactNamePrefix(cfg);
6768
+ const root = path11.resolve(process.cwd(), opts.dir || "apps/web/dist");
6769
+ if (!await isDirectoryPath(root)) {
6770
+ console.error(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`);
6771
+ process.exit(1);
6772
+ }
6773
+ await ensureArtifactRootIndexHtml(root);
6774
+ if (opts.packOnly) {
6775
+ await runFrontendPackOnlyDeploy(root, namePrefix);
6776
+ return;
6777
+ }
6599
6778
  const settings = resolveFrontendDeployFromApmConfig(cfg);
6600
6779
  const minio = new MinioClient({
6601
6780
  endPoint: settings.endpoint,
@@ -6605,12 +6784,6 @@ function registerDeployFrontendCommands(program) {
6605
6784
  secretKey: settings.secretKey
6606
6785
  });
6607
6786
  const bucket = settings.bucket;
6608
- const root = path11.resolve(process.cwd(), opts.dir || "apps/web/dist");
6609
- if (!await isDirectoryPath(root)) {
6610
- console.error(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`);
6611
- process.exit(1);
6612
- }
6613
- await ensureArtifactRootIndexHtml(root);
6614
6787
  const maxBytes = Math.max(
6615
6788
  1,
6616
6789
  Number.isFinite(opts.maxFileSizeMb) ? Math.floor(
@@ -6685,7 +6858,10 @@ function registerDeploySftpCommands(program) {
6685
6858
  ).option(
6686
6859
  "--config <path>",
6687
6860
  "apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
6688
- ).option("--extract", "\u4E0A\u4F20\u540E\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u89E3\u538B zip \u5230 remotePath").action(
6861
+ ).option("--extract", "\u4E0A\u4F20\u540E\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u89E3\u538B zip \u5230 remotePath").option(
6862
+ "--pack-only",
6863
+ "\u4EC5\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF08\u4E0E --extract \u4E92\u65A5\uFF09"
6864
+ ).action(
6689
6865
  async (opts) => {
6690
6866
  const cfg = loadApmConfig({ configPath: opts.config });
6691
6867
  const settings = resolveWisdomDeployFromApmConfig(cfg);
@@ -6702,16 +6878,23 @@ function registerDeploySftpCommands(program) {
6702
6878
  process.exit(1);
6703
6879
  }
6704
6880
  try {
6881
+ const packOnly = Boolean(opts.packOnly);
6882
+ if (packOnly && opts.extract) {
6883
+ console.error("--pack-only \u4E0E --extract \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
6884
+ process.exit(1);
6885
+ }
6705
6886
  const result = await runWisdomSftpDeploy({
6706
6887
  localDir: root,
6707
6888
  settings,
6708
6889
  extract: Boolean(opts.extract),
6709
- projectName
6890
+ projectName,
6891
+ packOnly
6710
6892
  });
6711
6893
  console.log(JSON.stringify(result, null, 2));
6712
6894
  } catch (err) {
6713
6895
  const message = err instanceof Error ? err.message : String(err);
6714
- console.error(`${opts.extract ? "\u90E8\u7F72" : "\u4E0A\u4F20"}\u5931\u8D25:`, message);
6896
+ const action = opts.packOnly ? "\u6253\u5305" : opts.extract ? "\u90E8\u7F72" : "\u4E0A\u4F20";
6897
+ console.error(`${action}\u5931\u8D25:`, message);
6715
6898
  process.exit(1);
6716
6899
  }
6717
6900
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "6.0.86",
3
+ "version": "6.0.88",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,