ai-project-manage-cli 8.0.10 → 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 +4 -0
- package/dist/webide-message-worker.js +131 -55
- package/package.json +1 -1
- package/template/rules/webide_package.md +33 -42
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(
|
|
209
|
-
let normalized =
|
|
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
|
|
332
|
-
if (!existsSync(toFsPath(
|
|
333
|
-
throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${
|
|
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
|
|
618
|
-
if (!existsSync2(
|
|
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(
|
|
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
|
|
656
|
-
writeFileSync2(
|
|
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(
|
|
2230
|
-
if (!existsSync4(
|
|
2233
|
+
function readRegistry(path2) {
|
|
2234
|
+
if (!existsSync4(path2)) {
|
|
2231
2235
|
return {};
|
|
2232
2236
|
}
|
|
2233
2237
|
try {
|
|
2234
|
-
const parsed = JSON.parse(readFileSync4(
|
|
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(
|
|
2263
|
-
mkdirSync4(dirname3(
|
|
2264
|
-
writeFileSync3(
|
|
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
|
|
2271
|
-
const current = readRegistry(
|
|
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(
|
|
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
|
|
2305
|
-
if (!existsSync4(
|
|
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
|
|
2953
|
-
if (!existsSync6(
|
|
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(
|
|
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(
|
|
3054
|
-
const trimmed =
|
|
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: ${
|
|
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: ${
|
|
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 [
|
|
3115
|
-
if (localMap.get(
|
|
3116
|
-
download.push(
|
|
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
|
|
3121
|
-
if (!remoteMap.has(
|
|
3122
|
-
deleteLocal.push(
|
|
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
|
|
3224
|
+
for (const path2 of deleteLocal) {
|
|
3217
3225
|
const absPath = toFsPath(
|
|
3218
|
-
projectDocumentLocalPath(targetApmDir, projectId,
|
|
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
|
|
3273
|
+
for (const path2 of localPaths) {
|
|
3266
3274
|
const absPath = toFsPath(
|
|
3267
|
-
projectDocumentLocalPath(targetApmDir, projectId,
|
|
3275
|
+
projectDocumentLocalPath(targetApmDir, projectId, path2)
|
|
3268
3276
|
);
|
|
3269
3277
|
const content = readFileSync7(absPath, "utf8");
|
|
3270
3278
|
const contentHash = hashLocalFileContent(content);
|
|
3271
|
-
if (remoteHashByPath.get(
|
|
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(
|
|
3286
|
+
description: remoteDescriptionByPath.get(path2) ?? void 0
|
|
3279
3287
|
});
|
|
3280
3288
|
synced += 1;
|
|
3281
|
-
console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${
|
|
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
|
|
3298
|
-
if (!existsSync8(
|
|
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(
|
|
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}/manifest.json`;
|
|
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:
|
|
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
|
@@ -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,9 @@
|
|
|
12
14
|
|
|
13
15
|
- **禁止**修改业务代码、提交 Git、创建 PR。
|
|
14
16
|
- **禁止**为修依赖或修编译错误而改代码 / 装依赖 / 改 lockfile;构建失败 → 以错误结束。
|
|
15
|
-
- **禁止**在仓库工作区内留下交付用 zip
|
|
16
|
-
-
|
|
17
|
+
- **禁止**在仓库工作区内留下交付用 zip。
|
|
18
|
+
- 临时目录统一用:`/data/package-tmp/<packageId>/`(不要用 `/tmp`,不要用 `/data/artifacts/`)。
|
|
19
|
+
- 后端交付 jar 的路径与文件名**只**来自 deploy 文档;禁止在本规则中写死具体项目的 jar 清单。
|
|
17
20
|
|
|
18
21
|
### target=frontend(Vue)
|
|
19
22
|
|
|
@@ -21,55 +24,43 @@
|
|
|
21
24
|
2. **不要**执行 `npm i` / `pnpm i` 等;分支切换后依赖已就绪。
|
|
22
25
|
3. 执行文档中的打包命令(通常 `npm run build`)。
|
|
23
26
|
4. 确认产出 `dist/`(或文档写明的目录)。
|
|
24
|
-
5.
|
|
27
|
+
5. 在临时目录压缩(勿在工作区生成 `dist.zip`),落到:
|
|
28
|
+
|
|
29
|
+
`/data/package-tmp/<packageId>/dist.zip`
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
**压缩结构(必须)**:zip 内顶层就是名为 `dist` 的目录,解压后得到 `dist/…`,**禁止**出现 `dist/dist/…`。
|
|
32
|
+
|
|
33
|
+
- 正确:在**含有 `dist` 的父目录**执行,例如
|
|
34
|
+
`mkdir -p /data/package-tmp/<packageId> && zip -r /data/package-tmp/<packageId>/dist.zip dist`
|
|
35
|
+
(把目录名 `dist` 打进包,不要先 `cd dist` 再压当前目录)。
|
|
36
|
+
- 错误:`cd dist && zip -r … .`(解压后没有顶层 `dist`);或把整个前端仓/多套一层 `dist` 再压(解压成 `dist/dist`)。
|
|
27
37
|
|
|
28
38
|
6. 缺产物或构建失败 → 调用 **SetPackageFailed**(传入失败原因)后结束。
|
|
29
39
|
|
|
30
40
|
### target=backend(SpringBoot)
|
|
31
41
|
|
|
32
|
-
1. 按 deploy
|
|
33
|
-
2.
|
|
34
|
-
3.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"target": "backend",
|
|
50
|
-
"baseBranch": "release/1.0",
|
|
51
|
-
"createdAt": "2026-09-02T07:00:00.000Z",
|
|
52
|
-
"commitId": "a1b2c3d4…",
|
|
53
|
-
"jars": [
|
|
54
|
-
{
|
|
55
|
-
"name": "app-1.2.3.jar",
|
|
56
|
-
"hash": "e3b0…b855",
|
|
57
|
-
"path": "/data/artifacts/springboot/jars/e3b0…b855.jar"
|
|
58
|
-
}
|
|
59
|
-
],
|
|
60
|
-
"sqls": [
|
|
61
|
-
{
|
|
62
|
-
"name": "20260301_add_col.sql",
|
|
63
|
-
"hash": "2c26…e7ae",
|
|
64
|
-
"path": "/data/artifacts/springboot/sqls/2c26…e7ae.sql"
|
|
65
|
-
}
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
```
|
|
42
|
+
1. 按 deploy 文档进入后端目录,执行文档写明的构建命令(通常 `mvn clean package`)。
|
|
43
|
+
2. **只**收集 deploy 文档标明的交付 jar(路径/文件名/glob 以文档为准)。**禁止**全量收集 `target/lib`、**禁止**打包 SQL、**禁止**在规则或命令里写死具体 jar 名。
|
|
44
|
+
3. 确认文档列出的每个 jar 均已生成;缺任一文件 → SetPackageFailed。
|
|
45
|
+
4. 在临时目录将上述 jar **打成一个 zip**(勿在工作区生成交付 zip),落到:
|
|
46
|
+
|
|
47
|
+
`/data/package-tmp/<packageId>/jars.zip`
|
|
48
|
+
|
|
49
|
+
**压缩结构(必须)**:zip 内顶层直接是各个 `.jar` 文件(解压后同级列出 jar),**禁止**多套一层无意义目录,也禁止把整个 `lib` 目录原样打进包。
|
|
50
|
+
|
|
51
|
+
示例(路径与文件列表须来自 deploy,勿照抄本例文件名):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mkdir -p /data/package-tmp/<packageId>/jars
|
|
55
|
+
# 按 deploy 文档把待交付 jar 拷到临时目录后:
|
|
56
|
+
cd /data/package-tmp/<packageId>/jars
|
|
57
|
+
zip /data/package-tmp/<packageId>/jars.zip ./*.jar
|
|
58
|
+
```
|
|
69
59
|
|
|
60
|
+
5. 可选:同临时目录写 `commitId.txt`(后端仓 `git rev-parse HEAD` 一行),非必须。
|
|
70
61
|
6. 构建或落盘失败 → 调用 **SetPackageFailed**(传入失败原因)后结束。
|
|
71
62
|
|
|
72
63
|
### 结束
|
|
73
64
|
|
|
74
|
-
-
|
|
65
|
+
- 成功:确认 zip 已落到 `/data/package-tmp/<packageId>/` 约定文件名后正常结束(不要调用 SetPackageFailed)。CLI 会上传 MinIO 并清理该临时目录。
|
|
75
66
|
- 失败:先调用 SetPackageFailed 写入原因,再结束。
|