ai-project-manage-cli 8.0.12 → 8.0.13

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/dist/index.js CHANGED
@@ -196,6 +196,10 @@ var init_request_config = __esm({
196
196
  method: "GET",
197
197
  path: "/cli/apm-log-storage"
198
198
  }),
199
+ getDeployArtifactStorage: defineEndpoint({
200
+ method: "GET",
201
+ path: "/cli/deploy-artifact-storage"
202
+ }),
199
203
  projectPackageUpdateStatus: defineEndpoint({
200
204
  method: "PUT",
201
205
  path: "/cli/project-packages/status"
@@ -100,6 +100,10 @@ var requestConfig = {
100
100
  method: "GET",
101
101
  path: "/cli/apm-log-storage"
102
102
  }),
103
+ getDeployArtifactStorage: defineEndpoint({
104
+ method: "GET",
105
+ path: "/cli/deploy-artifact-storage"
106
+ }),
103
107
  projectPackageUpdateStatus: defineEndpoint({
104
108
  method: "PUT",
105
109
  path: "/cli/project-packages/status"
@@ -205,8 +209,8 @@ function toFsPath(inputPath) {
205
209
  }
206
210
  return `\\\\?\\${normalized}`;
207
211
  }
208
- function normalizeWorkdirPath(path) {
209
- let normalized = path.trim().replace(/\\/g, "/").normalize("NFC");
212
+ function normalizeWorkdirPath(path2) {
213
+ let normalized = path2.trim().replace(/\\/g, "/").normalize("NFC");
210
214
  if (normalized.startsWith("//?/")) {
211
215
  normalized = normalized.slice(4);
212
216
  }
@@ -328,9 +332,9 @@ function listWebIdeRuleFileNames(rulesDir) {
328
332
  function assertWebIdeTemplateCopiedToApm(apmDir, workdir) {
329
333
  const required = ["AGENTS.md", "rules"];
330
334
  for (const item of required) {
331
- const path = join2(apmDir, item);
332
- if (!existsSync(toFsPath(path))) {
333
- throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path}`);
335
+ const path2 = join2(apmDir, item);
336
+ if (!existsSync(toFsPath(path2))) {
337
+ throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path2}`);
334
338
  }
335
339
  }
336
340
  const rulesDir = join2(apmDir, "rules");
@@ -614,13 +618,13 @@ function normalizeRepoEntry(raw) {
614
618
  return entry;
615
619
  }
616
620
  function readManifest(workdir) {
617
- const path = toFsPath(manifestPath(workdir));
618
- if (!existsSync2(path)) {
621
+ const path2 = toFsPath(manifestPath(workdir));
622
+ if (!existsSync2(path2)) {
619
623
  return null;
620
624
  }
621
625
  try {
622
626
  const raw = JSON.parse(
623
- readFileSync2(path, "utf8")
627
+ readFileSync2(path2, "utf8")
624
628
  );
625
629
  if (raw?.version !== WORKSPACE_REPOS_VERSION) {
626
630
  return null;
@@ -652,8 +656,8 @@ function readManifest(workdir) {
652
656
  function writeManifest(workdir, manifest) {
653
657
  const apmDir = toFsPath(workspaceApmDir(workdir));
654
658
  mkdirSync3(apmDir, { recursive: true });
655
- const path = toFsPath(manifestPath(workdir));
656
- writeFileSync2(path, `${JSON.stringify(manifest, null, 2)}
659
+ const path2 = toFsPath(manifestPath(workdir));
660
+ writeFileSync2(path2, `${JSON.stringify(manifest, null, 2)}
657
661
  `, "utf8");
658
662
  }
659
663
  function manifestStillValid(workdir, manifest) {
@@ -2226,12 +2230,12 @@ import { dirname as dirname3, resolve as resolve5 } from "node:path";
2226
2230
  function registryPath(workdir, taskId) {
2227
2231
  return resolve5(workdir, ".apm", "webide", taskId, "cursor-agent.json");
2228
2232
  }
2229
- function readRegistry(path) {
2230
- if (!existsSync4(path)) {
2233
+ function readRegistry(path2) {
2234
+ if (!existsSync4(path2)) {
2231
2235
  return {};
2232
2236
  }
2233
2237
  try {
2234
- const parsed = JSON.parse(readFileSync4(path, "utf8"));
2238
+ const parsed = JSON.parse(readFileSync4(path2, "utf8"));
2235
2239
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2236
2240
  const raw = parsed;
2237
2241
  const state = {};
@@ -2259,16 +2263,16 @@ function readRegistry(path) {
2259
2263
  }
2260
2264
  return {};
2261
2265
  }
2262
- function writeRegistry(path, registry) {
2263
- mkdirSync4(dirname3(path), { recursive: true });
2264
- writeFileSync3(path, `${JSON.stringify(registry, null, 2)}
2266
+ function writeRegistry(path2, registry) {
2267
+ mkdirSync4(dirname3(path2), { recursive: true });
2268
+ writeFileSync3(path2, `${JSON.stringify(registry, null, 2)}
2265
2269
  `, "utf8");
2266
2270
  }
2267
2271
  function syncWebIdeTaskState(workdir, taskId, patch) {
2268
2272
  const trimmedTaskId = taskId.trim();
2269
2273
  if (!trimmedTaskId) return;
2270
- const path = registryPath(workdir, trimmedTaskId);
2271
- const current = readRegistry(path);
2274
+ const path2 = registryPath(workdir, trimmedTaskId);
2275
+ const current = readRegistry(path2);
2272
2276
  const next = {
2273
2277
  ...current,
2274
2278
  taskId: trimmedTaskId,
@@ -2292,7 +2296,7 @@ function syncWebIdeTaskState(workdir, taskId, patch) {
2292
2296
  if (patch.status !== void 0) {
2293
2297
  next.status = patch.status;
2294
2298
  }
2295
- writeRegistry(path, next);
2299
+ writeRegistry(path2, next);
2296
2300
  }
2297
2301
  function loadWebIdeAgentId(workdir, taskId) {
2298
2302
  return readRegistry(registryPath(workdir, taskId)).agentId;
@@ -2301,8 +2305,8 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
2301
2305
  syncWebIdeTaskState(workdir, taskId, { agentId });
2302
2306
  }
2303
2307
  function clearWebIdeAgentId(workdir, taskId) {
2304
- const path = registryPath(workdir, taskId);
2305
- if (!existsSync4(path)) return;
2308
+ const path2 = registryPath(workdir, taskId);
2309
+ if (!existsSync4(path2)) return;
2306
2310
  syncWebIdeTaskState(workdir, taskId, { agentId: "" });
2307
2311
  }
2308
2312
 
@@ -2502,6 +2506,10 @@ var MinioClient = class {
2502
2506
  async putObject(bucket, objectKey, body, meta) {
2503
2507
  await this.inner.putObject(bucket, objectKey, body, body.length, meta);
2504
2508
  }
2509
+ /** 大文件:从本地路径流式上传,避免整包读入内存 */
2510
+ async fPutObject(bucket, objectKey, filePath, meta) {
2511
+ await this.inner.fPutObject(bucket, objectKey, filePath, meta);
2512
+ }
2505
2513
  };
2506
2514
 
2507
2515
  // src/commands/connect/apm-log-minio.ts
@@ -2949,13 +2957,13 @@ async function downloadAttachment(cfg, attachmentId) {
2949
2957
  return Buffer.from(await res.arrayBuffer());
2950
2958
  }
2951
2959
  function loadManifest(dir) {
2952
- const path = join5(dir, MANIFEST_FILE);
2953
- if (!existsSync6(path)) {
2960
+ const path2 = join5(dir, MANIFEST_FILE);
2961
+ if (!existsSync6(path2)) {
2954
2962
  return { version: 1, attachments: {} };
2955
2963
  }
2956
2964
  try {
2957
2965
  const parsed = JSON.parse(
2958
- readFileSync6(path, "utf8")
2966
+ readFileSync6(path2, "utf8")
2959
2967
  );
2960
2968
  if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
2961
2969
  return parsed;
@@ -3050,14 +3058,14 @@ function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
3050
3058
  ...normalized.split("/")
3051
3059
  );
3052
3060
  }
3053
- function normalizeLocalDocumentPath(path) {
3054
- const trimmed = path.trim().replace(/\\/g, "/");
3061
+ function normalizeLocalDocumentPath(path2) {
3062
+ const trimmed = path2.trim().replace(/\\/g, "/");
3055
3063
  if (!trimmed || trimmed.startsWith("/") || /^[a-zA-Z]:/.test(trimmed)) {
3056
- throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path}`);
3064
+ throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path2}`);
3057
3065
  }
3058
3066
  const segments = trimmed.split("/").filter(Boolean);
3059
3067
  if (segments.some((segment) => segment === ".." || segment === ".")) {
3060
- throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path}`);
3068
+ throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path2}`);
3061
3069
  }
3062
3070
  return segments.join("/");
3063
3071
  }
@@ -3111,15 +3119,15 @@ function diffManifestPaths(remote, local) {
3111
3119
  (local?.documents ?? []).map((doc) => [doc.path, doc.contentHash])
3112
3120
  );
3113
3121
  const download = [];
3114
- for (const [path, hash] of remoteMap) {
3115
- if (localMap.get(path) !== hash) {
3116
- download.push(path);
3122
+ for (const [path2, hash] of remoteMap) {
3123
+ if (localMap.get(path2) !== hash) {
3124
+ download.push(path2);
3117
3125
  }
3118
3126
  }
3119
3127
  const deleteLocal = [];
3120
- for (const path of localMap.keys()) {
3121
- if (!remoteMap.has(path)) {
3122
- deleteLocal.push(path);
3128
+ for (const path2 of localMap.keys()) {
3129
+ if (!remoteMap.has(path2)) {
3130
+ deleteLocal.push(path2);
3123
3131
  }
3124
3132
  }
3125
3133
  return { download, deleteLocal };
@@ -3213,9 +3221,9 @@ ${diagnostic ?? ""}`);
3213
3221
  }
3214
3222
  }
3215
3223
  let deleted = 0;
3216
- for (const path of deleteLocal) {
3224
+ for (const path2 of deleteLocal) {
3217
3225
  const absPath = toFsPath(
3218
- projectDocumentLocalPath(targetApmDir, projectId, path)
3226
+ projectDocumentLocalPath(targetApmDir, projectId, path2)
3219
3227
  );
3220
3228
  if (existsSync7(absPath)) {
3221
3229
  rmSync2(absPath, { force: true });
@@ -3262,23 +3270,23 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
3262
3270
  (remoteManifest?.documents ?? []).map((doc) => [doc.path, doc.description])
3263
3271
  );
3264
3272
  let synced = 0;
3265
- for (const path of localPaths) {
3273
+ for (const path2 of localPaths) {
3266
3274
  const absPath = toFsPath(
3267
- projectDocumentLocalPath(targetApmDir, projectId, path)
3275
+ projectDocumentLocalPath(targetApmDir, projectId, path2)
3268
3276
  );
3269
3277
  const content = readFileSync7(absPath, "utf8");
3270
3278
  const contentHash = hashLocalFileContent(content);
3271
- if (remoteHashByPath.get(path) === contentHash) {
3279
+ if (remoteHashByPath.get(path2) === contentHash) {
3272
3280
  continue;
3273
3281
  }
3274
3282
  await api.cli.upsertProjectDocument({
3275
3283
  projectId,
3276
- path,
3284
+ path: path2,
3277
3285
  content,
3278
- description: remoteDescriptionByPath.get(path) ?? void 0
3286
+ description: remoteDescriptionByPath.get(path2) ?? void 0
3279
3287
  });
3280
3288
  synced += 1;
3281
- console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${path}`);
3289
+ console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${path2}`);
3282
3290
  }
3283
3291
  if (synced === 0) {
3284
3292
  console.log("[apm] \u9879\u76EE\u6587\u6863\u65E0\u53D8\u5316\uFF0C\u8DF3\u8FC7\u63A8\u9001");
@@ -3294,13 +3302,13 @@ function manifestPath2(apmDir) {
3294
3302
  return join7(apmDir, CLI_VERSION_FILE);
3295
3303
  }
3296
3304
  function loadManifest2(apmDir) {
3297
- const path = toFsPath(manifestPath2(apmDir));
3298
- if (!existsSync8(path)) {
3305
+ const path2 = toFsPath(manifestPath2(apmDir));
3306
+ if (!existsSync8(path2)) {
3299
3307
  return null;
3300
3308
  }
3301
3309
  try {
3302
3310
  const parsed = JSON.parse(
3303
- readFileSync8(path, "utf8")
3311
+ readFileSync8(path2, "utf8")
3304
3312
  );
3305
3313
  if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
3306
3314
  return parsed;
@@ -3982,6 +3990,74 @@ async function handleStartProject(cfg, msg, signal) {
3982
3990
  }
3983
3991
  }
3984
3992
 
3993
+ // src/commands/connect/upload-package-artifact.ts
3994
+ import fs from "node:fs";
3995
+ import path from "node:path";
3996
+
3997
+ // src/commands/connect/deploy-artifact-minio.ts
3998
+ async function fetchDeployArtifactStorage(cfg) {
3999
+ const api = createApmApiClient(cfg);
4000
+ return api.cli.getDeployArtifactStorage(void 0);
4001
+ }
4002
+ async function createDeployArtifactMinioClient(cfg) {
4003
+ const storage = await fetchDeployArtifactStorage(cfg);
4004
+ return {
4005
+ client: new MinioClient({
4006
+ endPoint: storage.endpoint,
4007
+ port: storage.port,
4008
+ useSSL: storage.useSsl,
4009
+ accessKey: storage.accessKey,
4010
+ secretKey: storage.secretKey
4011
+ }),
4012
+ bucket: storage.bucket,
4013
+ ...storage.publicEndpoint ? { publicEndpoint: storage.publicEndpoint } : {}
4014
+ };
4015
+ }
4016
+
4017
+ // src/commands/connect/upload-package-artifact.ts
4018
+ function packageTmpDir(packageId) {
4019
+ return `/data/package-tmp/${packageId}`;
4020
+ }
4021
+ function expectedLocalArtifactPath(target, packageId) {
4022
+ const fileName = target === "frontend" ? "dist.zip" : "jars.zip";
4023
+ return path.join(packageTmpDir(packageId), fileName);
4024
+ }
4025
+ function packageArtifactObjectKey(target, packageId) {
4026
+ const fileName = target === "frontend" ? "dist.zip" : "jars.zip";
4027
+ return `packages/${target}/${packageId}/${fileName}`;
4028
+ }
4029
+ function removePackageTmpDir(packageId) {
4030
+ const dir = packageTmpDir(packageId);
4031
+ try {
4032
+ fs.rmSync(dir, { recursive: true, force: true });
4033
+ } catch (err) {
4034
+ console.warn(
4035
+ `[apm] \u6E05\u7406\u6253\u5305\u4E34\u65F6\u76EE\u5F55\u5931\u8D25 ${dir}:`,
4036
+ err instanceof Error ? err.message : err
4037
+ );
4038
+ }
4039
+ }
4040
+ async function uploadPackageArtifact(cfg, target, packageId) {
4041
+ const localPath = expectedLocalArtifactPath(target, packageId);
4042
+ if (!fs.existsSync(localPath)) {
4043
+ throw new Error(`\u6253\u5305\u4EA7\u7269\u4E0D\u5B58\u5728: ${localPath}`);
4044
+ }
4045
+ const stat = fs.statSync(localPath);
4046
+ if (!stat.isFile() || stat.size <= 0) {
4047
+ throw new Error(`\u6253\u5305\u4EA7\u7269\u65E0\u6548\u6216\u4E3A\u7A7A: ${localPath}`);
4048
+ }
4049
+ const objectKey = packageArtifactObjectKey(target, packageId);
4050
+ const { client, bucket, publicEndpoint } = await createDeployArtifactMinioClient(cfg);
4051
+ await client.ensureBucket(bucket);
4052
+ await client.fPutObject(bucket, objectKey, localPath, {
4053
+ "Content-Type": "application/zip"
4054
+ });
4055
+ removePackageTmpDir(packageId);
4056
+ const base = publicEndpoint?.replace(/\/$/, "") ?? "";
4057
+ const artifactUrl = base ? `${base}/${bucket}/${objectKey}` : null;
4058
+ return { artifactPath: objectKey, artifactUrl };
4059
+ }
4060
+
3985
4061
  // src/commands/connect/handle-package.ts
3986
4062
  async function updatePackageStatus(cfg, packageId, status, extra) {
3987
4063
  const api = createApmApiClient(cfg);
@@ -3990,15 +4066,10 @@ async function updatePackageStatus(cfg, packageId, status, extra) {
3990
4066
  status,
3991
4067
  ...extra?.error != null ? { error: extra.error } : {},
3992
4068
  ...extra?.content != null ? { content: extra.content } : {},
3993
- ...extra?.artifactPath != null ? { artifactPath: extra.artifactPath } : {}
4069
+ ...extra?.artifactPath != null ? { artifactPath: extra.artifactPath } : {},
4070
+ ...extra?.artifactUrl != null ? { artifactUrl: extra.artifactUrl } : {}
3994
4071
  });
3995
4072
  }
3996
- function expectedArtifactPath(target, packageId) {
3997
- if (target === "frontend") {
3998
- return `/data/artifacts/vue/${packageId}/dist.zip`;
3999
- }
4000
- return `/data/artifacts/springboot/${packageId}/jars.zip`;
4001
- }
4002
4073
  async function handleWebIdePackage(cfg, msg, signal) {
4003
4074
  const workdir = requireRemoteWorkdir(msg.workdir);
4004
4075
  const messageId = msg.messageId;
@@ -4119,7 +4190,6 @@ async function handleWebIdePackage(cfg, msg, signal) {
4119
4190
  );
4120
4191
  eventSession.addCliStep("\u542F\u52A8\u6253\u5305 Agent", "\u51C6\u5907 create\u2026", "running");
4121
4192
  await syncPrepLog();
4122
- const artifactHint = expectedArtifactPath(msg.target, packageId);
4123
4193
  let failedByTool = false;
4124
4194
  const outcome = await runCursorAgent(
4125
4195
  cfg,
@@ -4226,11 +4296,17 @@ async function handleWebIdePackage(cfg, msg, signal) {
4226
4296
  );
4227
4297
  return;
4228
4298
  }
4299
+ const uploaded = await runPrepStep(
4300
+ "\u4E0A\u4F20\u6253\u5305\u4EA7\u7269\u5230 MinIO",
4301
+ () => uploadPackageArtifact(cfg, msg.target, packageId),
4302
+ (result) => `objectKey=${result.artifactPath}${result.artifactUrl ? ` url=${result.artifactUrl}` : ""}`
4303
+ );
4229
4304
  await updatePackageStatus(cfg, packageId, "SUCCESS", {
4230
- artifactPath: artifactHint
4305
+ artifactPath: uploaded.artifactPath,
4306
+ ...uploaded.artifactUrl ? { artifactUrl: uploaded.artifactUrl } : {}
4231
4307
  });
4232
4308
  console.log(
4233
- `[apm] webide-package \u5B8C\u6210 target=${msg.target} packageId=${packageId} agentId=${outcome.agentId}`
4309
+ `[apm] webide-package \u5B8C\u6210 target=${msg.target} packageId=${packageId} agentId=${outcome.agentId} artifact=${uploaded.artifactPath}`
4234
4310
  );
4235
4311
  } catch (err) {
4236
4312
  const detail = err instanceof Error ? err.message : String(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "8.0.12",
3
+ "version": "8.0.13",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,
@@ -2,6 +2,8 @@
2
2
 
3
3
  适用:独立打包 Agent(不 resume 任务对话)。只打 payload 指定的 **一个** target(`frontend` / `backend`)。
4
4
 
5
+ 产物最终由 CLI 上传 MinIO;本地**只**使用临时目录,不要写 `/data/artifacts/` 持久路径。
6
+
5
7
  ### 开始前
6
8
 
7
9
  1. Read 本规则全文。
@@ -12,8 +14,8 @@
12
14
 
13
15
  - **禁止**修改业务代码、提交 Git、创建 PR。
14
16
  - **禁止**为修依赖或修编译错误而改代码 / 装依赖 / 改 lockfile;构建失败 → 以错误结束。
15
- - **禁止**在仓库工作区内留下交付用 zip;临时文件只用 `/data/` 下目录(如 `/data/artifacts/.tmp/<packageId>/`),成功后可删临时目录。
16
- - 临时目录与最终产物均在 `/data` 下,不要用 `/tmp`。
17
+ - **禁止**在仓库工作区内留下交付用 zip
18
+ - 临时目录统一用:`/data/package-tmp/<packageId>/`(不要用 `/tmp`,不要用 `/data/artifacts/`)。
17
19
  - 后端交付 jar 的路径与文件名**只**来自 deploy 文档;禁止在本规则中写死具体项目的 jar 清单。
18
20
 
19
21
  ### target=frontend(Vue)
@@ -22,14 +24,14 @@
22
24
  2. **不要**执行 `npm i` / `pnpm i` 等;分支切换后依赖已就绪。
23
25
  3. 执行文档中的打包命令(通常 `npm run build`)。
24
26
  4. 确认产出 `dist/`(或文档写明的目录)。
25
- 5. `/data` 下压缩(勿在工作区生成 `dist.zip`),落到:
27
+ 5. 在临时目录压缩(勿在工作区生成 `dist.zip`),落到:
26
28
 
27
- `/data/artifacts/vue/<packageId>/dist.zip`
29
+ `/data/package-tmp/<packageId>/dist.zip`
28
30
 
29
31
  **压缩结构(必须)**:zip 内顶层就是名为 `dist` 的目录,解压后得到 `dist/…`,**禁止**出现 `dist/dist/…`。
30
32
 
31
33
  - 正确:在**含有 `dist` 的父目录**执行,例如
32
- `zip -r /data/artifacts/vue/<packageId>/dist.zip dist`
34
+ `mkdir -p /data/package-tmp/<packageId> && zip -r /data/package-tmp/<packageId>/dist.zip dist`
33
35
  (把目录名 `dist` 打进包,不要先 `cd dist` 再压当前目录)。
34
36
  - 错误:`cd dist && zip -r … .`(解压后没有顶层 `dist`);或把整个前端仓/多套一层 `dist` 再压(解压成 `dist/dist`)。
35
37
 
@@ -40,25 +42,25 @@
40
42
  1. 按 deploy 文档进入后端目录,执行文档写明的构建命令(通常 `mvn clean package`)。
41
43
  2. **只**收集 deploy 文档标明的交付 jar(路径/文件名/glob 以文档为准)。**禁止**全量收集 `target/lib`、**禁止**打包 SQL、**禁止**在规则或命令里写死具体 jar 名。
42
44
  3. 确认文档列出的每个 jar 均已生成;缺任一文件 → SetPackageFailed。
43
- 4. `/data` 下将上述 jar **打成一个 zip**(勿在工作区生成交付 zip),落到:
45
+ 4. 在临时目录将上述 jar **打成一个 zip**(勿在工作区生成交付 zip),落到:
44
46
 
45
- `/data/artifacts/springboot/<packageId>/jars.zip`
47
+ `/data/package-tmp/<packageId>/jars.zip`
46
48
 
47
49
  **压缩结构(必须)**:zip 内顶层直接是各个 `.jar` 文件(解压后同级列出 jar),**禁止**多套一层无意义目录,也禁止把整个 `lib` 目录原样打进包。
48
50
 
49
51
  示例(路径与文件列表须来自 deploy,勿照抄本例文件名):
50
52
 
51
53
  ```bash
52
- mkdir -p /data/artifacts/springboot/<packageId> /data/artifacts/.tmp/<packageId>
54
+ mkdir -p /data/package-tmp/<packageId>/jars
53
55
  # 按 deploy 文档把待交付 jar 拷到临时目录后:
54
- cd /data/artifacts/.tmp/<packageId>
55
- zip /data/artifacts/springboot/<packageId>/jars.zip ./*.jar
56
+ cd /data/package-tmp/<packageId>/jars
57
+ zip /data/package-tmp/<packageId>/jars.zip ./*.jar
56
58
  ```
57
59
 
58
- 5. 可选:同目录写 `commitId.txt`(后端仓 `git rev-parse HEAD` 一行),非必须。
60
+ 5. 可选:同临时目录写 `commitId.txt`(后端仓 `git rev-parse HEAD` 一行),非必须。
59
61
  6. 构建或落盘失败 → 调用 **SetPackageFailed**(传入失败原因)后结束。
60
62
 
61
63
  ### 结束
62
64
 
63
- - 成功:确认产物已落到约定路径后正常结束(不要调用 SetPackageFailed)。
65
+ - 成功:确认 zip 已落到 `/data/package-tmp/<packageId>/` 约定文件名后正常结束(不要调用 SetPackageFailed)。CLI 会上传 MinIO 并清理该临时目录。
64
66
  - 失败:先调用 SetPackageFailed 写入原因,再结束。