ai-project-manage-cli 8.0.14 → 8.0.15
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.
|
@@ -205,8 +205,8 @@ function toFsPath(inputPath) {
|
|
|
205
205
|
}
|
|
206
206
|
return `\\\\?\\${normalized}`;
|
|
207
207
|
}
|
|
208
|
-
function normalizeWorkdirPath(
|
|
209
|
-
let normalized =
|
|
208
|
+
function normalizeWorkdirPath(path3) {
|
|
209
|
+
let normalized = path3.trim().replace(/\\/g, "/").normalize("NFC");
|
|
210
210
|
if (normalized.startsWith("//?/")) {
|
|
211
211
|
normalized = normalized.slice(4);
|
|
212
212
|
}
|
|
@@ -328,9 +328,9 @@ function listWebIdeRuleFileNames(rulesDir) {
|
|
|
328
328
|
function assertWebIdeTemplateCopiedToApm(apmDir, workdir) {
|
|
329
329
|
const required = ["AGENTS.md", "rules"];
|
|
330
330
|
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: ${
|
|
331
|
+
const path3 = join2(apmDir, item);
|
|
332
|
+
if (!existsSync(toFsPath(path3))) {
|
|
333
|
+
throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path3}`);
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
336
|
const rulesDir = join2(apmDir, "rules");
|
|
@@ -614,13 +614,13 @@ function normalizeRepoEntry(raw) {
|
|
|
614
614
|
return entry;
|
|
615
615
|
}
|
|
616
616
|
function readManifest(workdir) {
|
|
617
|
-
const
|
|
618
|
-
if (!existsSync2(
|
|
617
|
+
const path3 = toFsPath(manifestPath(workdir));
|
|
618
|
+
if (!existsSync2(path3)) {
|
|
619
619
|
return null;
|
|
620
620
|
}
|
|
621
621
|
try {
|
|
622
622
|
const raw = JSON.parse(
|
|
623
|
-
readFileSync2(
|
|
623
|
+
readFileSync2(path3, "utf8")
|
|
624
624
|
);
|
|
625
625
|
if (raw?.version !== WORKSPACE_REPOS_VERSION) {
|
|
626
626
|
return null;
|
|
@@ -652,8 +652,8 @@ function readManifest(workdir) {
|
|
|
652
652
|
function writeManifest(workdir, manifest) {
|
|
653
653
|
const apmDir = toFsPath(workspaceApmDir(workdir));
|
|
654
654
|
mkdirSync3(apmDir, { recursive: true });
|
|
655
|
-
const
|
|
656
|
-
writeFileSync2(
|
|
655
|
+
const path3 = toFsPath(manifestPath(workdir));
|
|
656
|
+
writeFileSync2(path3, `${JSON.stringify(manifest, null, 2)}
|
|
657
657
|
`, "utf8");
|
|
658
658
|
}
|
|
659
659
|
function manifestStillValid(workdir, manifest) {
|
|
@@ -2226,12 +2226,12 @@ import { dirname as dirname3, resolve as resolve5 } from "node:path";
|
|
|
2226
2226
|
function registryPath(workdir, taskId) {
|
|
2227
2227
|
return resolve5(workdir, ".apm", "webide", taskId, "cursor-agent.json");
|
|
2228
2228
|
}
|
|
2229
|
-
function readRegistry(
|
|
2230
|
-
if (!existsSync4(
|
|
2229
|
+
function readRegistry(path3) {
|
|
2230
|
+
if (!existsSync4(path3)) {
|
|
2231
2231
|
return {};
|
|
2232
2232
|
}
|
|
2233
2233
|
try {
|
|
2234
|
-
const parsed = JSON.parse(readFileSync4(
|
|
2234
|
+
const parsed = JSON.parse(readFileSync4(path3, "utf8"));
|
|
2235
2235
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2236
2236
|
const raw = parsed;
|
|
2237
2237
|
const state = {};
|
|
@@ -2259,16 +2259,16 @@ function readRegistry(path2) {
|
|
|
2259
2259
|
}
|
|
2260
2260
|
return {};
|
|
2261
2261
|
}
|
|
2262
|
-
function writeRegistry(
|
|
2263
|
-
mkdirSync4(dirname3(
|
|
2264
|
-
writeFileSync3(
|
|
2262
|
+
function writeRegistry(path3, registry) {
|
|
2263
|
+
mkdirSync4(dirname3(path3), { recursive: true });
|
|
2264
|
+
writeFileSync3(path3, `${JSON.stringify(registry, null, 2)}
|
|
2265
2265
|
`, "utf8");
|
|
2266
2266
|
}
|
|
2267
2267
|
function syncWebIdeTaskState(workdir, taskId, patch) {
|
|
2268
2268
|
const trimmedTaskId = taskId.trim();
|
|
2269
2269
|
if (!trimmedTaskId) return;
|
|
2270
|
-
const
|
|
2271
|
-
const current = readRegistry(
|
|
2270
|
+
const path3 = registryPath(workdir, trimmedTaskId);
|
|
2271
|
+
const current = readRegistry(path3);
|
|
2272
2272
|
const next = {
|
|
2273
2273
|
...current,
|
|
2274
2274
|
taskId: trimmedTaskId,
|
|
@@ -2292,7 +2292,7 @@ function syncWebIdeTaskState(workdir, taskId, patch) {
|
|
|
2292
2292
|
if (patch.status !== void 0) {
|
|
2293
2293
|
next.status = patch.status;
|
|
2294
2294
|
}
|
|
2295
|
-
writeRegistry(
|
|
2295
|
+
writeRegistry(path3, next);
|
|
2296
2296
|
}
|
|
2297
2297
|
function loadWebIdeAgentId(workdir, taskId) {
|
|
2298
2298
|
return readRegistry(registryPath(workdir, taskId)).agentId;
|
|
@@ -2301,8 +2301,8 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
|
|
|
2301
2301
|
syncWebIdeTaskState(workdir, taskId, { agentId });
|
|
2302
2302
|
}
|
|
2303
2303
|
function clearWebIdeAgentId(workdir, taskId) {
|
|
2304
|
-
const
|
|
2305
|
-
if (!existsSync4(
|
|
2304
|
+
const path3 = registryPath(workdir, taskId);
|
|
2305
|
+
if (!existsSync4(path3)) return;
|
|
2306
2306
|
syncWebIdeTaskState(workdir, taskId, { agentId: "" });
|
|
2307
2307
|
}
|
|
2308
2308
|
|
|
@@ -2506,6 +2506,34 @@ var MinioClient = class {
|
|
|
2506
2506
|
async fPutObject(bucket, objectKey, filePath, meta) {
|
|
2507
2507
|
await this.inner.fPutObject(bucket, objectKey, filePath, meta);
|
|
2508
2508
|
}
|
|
2509
|
+
async listObjects(bucket, prefix) {
|
|
2510
|
+
const objects = [];
|
|
2511
|
+
const stream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
2512
|
+
await new Promise((resolve7, reject) => {
|
|
2513
|
+
stream.on("data", (obj) => {
|
|
2514
|
+
if (!obj.name) return;
|
|
2515
|
+
objects.push({
|
|
2516
|
+
name: obj.name,
|
|
2517
|
+
size: typeof obj.size === "number" ? obj.size : 0,
|
|
2518
|
+
lastModified: obj.lastModified ?? null,
|
|
2519
|
+
...typeof obj.etag === "string" ? { etag: obj.etag } : {}
|
|
2520
|
+
});
|
|
2521
|
+
});
|
|
2522
|
+
stream.on("error", reject);
|
|
2523
|
+
stream.on("end", () => resolve7());
|
|
2524
|
+
});
|
|
2525
|
+
return objects;
|
|
2526
|
+
}
|
|
2527
|
+
async statObject(bucket, objectKey) {
|
|
2528
|
+
const stat = await this.inner.statObject(bucket, objectKey);
|
|
2529
|
+
return {
|
|
2530
|
+
size: typeof stat.size === "number" ? stat.size : 0,
|
|
2531
|
+
metaData: stat.metaData
|
|
2532
|
+
};
|
|
2533
|
+
}
|
|
2534
|
+
async removeObject(bucket, objectKey) {
|
|
2535
|
+
await this.inner.removeObject(bucket, objectKey);
|
|
2536
|
+
}
|
|
2509
2537
|
};
|
|
2510
2538
|
|
|
2511
2539
|
// src/commands/connect/apm-log-minio.ts
|
|
@@ -2954,13 +2982,13 @@ async function downloadAttachment(cfg, attachmentId) {
|
|
|
2954
2982
|
return Buffer.from(await res.arrayBuffer());
|
|
2955
2983
|
}
|
|
2956
2984
|
function loadManifest(dir) {
|
|
2957
|
-
const
|
|
2958
|
-
if (!existsSync6(
|
|
2985
|
+
const path3 = join5(dir, MANIFEST_FILE);
|
|
2986
|
+
if (!existsSync6(path3)) {
|
|
2959
2987
|
return { version: 1, attachments: {} };
|
|
2960
2988
|
}
|
|
2961
2989
|
try {
|
|
2962
2990
|
const parsed = JSON.parse(
|
|
2963
|
-
readFileSync6(
|
|
2991
|
+
readFileSync6(path3, "utf8")
|
|
2964
2992
|
);
|
|
2965
2993
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
2966
2994
|
return parsed;
|
|
@@ -3055,14 +3083,14 @@ function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
|
3055
3083
|
...normalized.split("/")
|
|
3056
3084
|
);
|
|
3057
3085
|
}
|
|
3058
|
-
function normalizeLocalDocumentPath(
|
|
3059
|
-
const trimmed =
|
|
3086
|
+
function normalizeLocalDocumentPath(path3) {
|
|
3087
|
+
const trimmed = path3.trim().replace(/\\/g, "/");
|
|
3060
3088
|
if (!trimmed || trimmed.startsWith("/") || /^[a-zA-Z]:/.test(trimmed)) {
|
|
3061
|
-
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${
|
|
3089
|
+
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path3}`);
|
|
3062
3090
|
}
|
|
3063
3091
|
const segments = trimmed.split("/").filter(Boolean);
|
|
3064
3092
|
if (segments.some((segment) => segment === ".." || segment === ".")) {
|
|
3065
|
-
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${
|
|
3093
|
+
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path3}`);
|
|
3066
3094
|
}
|
|
3067
3095
|
return segments.join("/");
|
|
3068
3096
|
}
|
|
@@ -3116,15 +3144,15 @@ function diffManifestPaths(remote, local) {
|
|
|
3116
3144
|
(local?.documents ?? []).map((doc) => [doc.path, doc.contentHash])
|
|
3117
3145
|
);
|
|
3118
3146
|
const download = [];
|
|
3119
|
-
for (const [
|
|
3120
|
-
if (localMap.get(
|
|
3121
|
-
download.push(
|
|
3147
|
+
for (const [path3, hash] of remoteMap) {
|
|
3148
|
+
if (localMap.get(path3) !== hash) {
|
|
3149
|
+
download.push(path3);
|
|
3122
3150
|
}
|
|
3123
3151
|
}
|
|
3124
3152
|
const deleteLocal = [];
|
|
3125
|
-
for (const
|
|
3126
|
-
if (!remoteMap.has(
|
|
3127
|
-
deleteLocal.push(
|
|
3153
|
+
for (const path3 of localMap.keys()) {
|
|
3154
|
+
if (!remoteMap.has(path3)) {
|
|
3155
|
+
deleteLocal.push(path3);
|
|
3128
3156
|
}
|
|
3129
3157
|
}
|
|
3130
3158
|
return { download, deleteLocal };
|
|
@@ -3218,9 +3246,9 @@ ${diagnostic ?? ""}`);
|
|
|
3218
3246
|
}
|
|
3219
3247
|
}
|
|
3220
3248
|
let deleted = 0;
|
|
3221
|
-
for (const
|
|
3249
|
+
for (const path3 of deleteLocal) {
|
|
3222
3250
|
const absPath = toFsPath(
|
|
3223
|
-
projectDocumentLocalPath(targetApmDir, projectId,
|
|
3251
|
+
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3224
3252
|
);
|
|
3225
3253
|
if (existsSync7(absPath)) {
|
|
3226
3254
|
rmSync2(absPath, { force: true });
|
|
@@ -3267,23 +3295,23 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
|
|
|
3267
3295
|
(remoteManifest?.documents ?? []).map((doc) => [doc.path, doc.description])
|
|
3268
3296
|
);
|
|
3269
3297
|
let synced = 0;
|
|
3270
|
-
for (const
|
|
3298
|
+
for (const path3 of localPaths) {
|
|
3271
3299
|
const absPath = toFsPath(
|
|
3272
|
-
projectDocumentLocalPath(targetApmDir, projectId,
|
|
3300
|
+
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3273
3301
|
);
|
|
3274
3302
|
const content = readFileSync7(absPath, "utf8");
|
|
3275
3303
|
const contentHash = hashLocalFileContent(content);
|
|
3276
|
-
if (remoteHashByPath.get(
|
|
3304
|
+
if (remoteHashByPath.get(path3) === contentHash) {
|
|
3277
3305
|
continue;
|
|
3278
3306
|
}
|
|
3279
3307
|
await api.cli.upsertProjectDocument({
|
|
3280
3308
|
projectId,
|
|
3281
|
-
path:
|
|
3309
|
+
path: path3,
|
|
3282
3310
|
content,
|
|
3283
|
-
description: remoteDescriptionByPath.get(
|
|
3311
|
+
description: remoteDescriptionByPath.get(path3) ?? void 0
|
|
3284
3312
|
});
|
|
3285
3313
|
synced += 1;
|
|
3286
|
-
console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${
|
|
3314
|
+
console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${path3}`);
|
|
3287
3315
|
}
|
|
3288
3316
|
if (synced === 0) {
|
|
3289
3317
|
console.log("[apm] \u9879\u76EE\u6587\u6863\u65E0\u53D8\u5316\uFF0C\u8DF3\u8FC7\u63A8\u9001");
|
|
@@ -3299,13 +3327,13 @@ function manifestPath2(apmDir) {
|
|
|
3299
3327
|
return join7(apmDir, CLI_VERSION_FILE);
|
|
3300
3328
|
}
|
|
3301
3329
|
function loadManifest2(apmDir) {
|
|
3302
|
-
const
|
|
3303
|
-
if (!existsSync8(
|
|
3330
|
+
const path3 = toFsPath(manifestPath2(apmDir));
|
|
3331
|
+
if (!existsSync8(path3)) {
|
|
3304
3332
|
return null;
|
|
3305
3333
|
}
|
|
3306
3334
|
try {
|
|
3307
3335
|
const parsed = JSON.parse(
|
|
3308
|
-
readFileSync8(
|
|
3336
|
+
readFileSync8(path3, "utf8")
|
|
3309
3337
|
);
|
|
3310
3338
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
3311
3339
|
return parsed;
|
|
@@ -4034,6 +4062,151 @@ async function uploadPackageArtifact(cfg, target, packageId, projectId) {
|
|
|
4034
4062
|
return { artifactPath: objectKey, artifactUrl };
|
|
4035
4063
|
}
|
|
4036
4064
|
|
|
4065
|
+
// src/commands/connect/sync-package-sql.ts
|
|
4066
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
4067
|
+
import fs2 from "node:fs";
|
|
4068
|
+
import path2 from "node:path";
|
|
4069
|
+
var SKIP_DIR_NAMES2 = /* @__PURE__ */ new Set([
|
|
4070
|
+
".apm",
|
|
4071
|
+
".git",
|
|
4072
|
+
".idea",
|
|
4073
|
+
".vscode",
|
|
4074
|
+
"node_modules",
|
|
4075
|
+
"target",
|
|
4076
|
+
"dist",
|
|
4077
|
+
"build",
|
|
4078
|
+
"out",
|
|
4079
|
+
"coverage",
|
|
4080
|
+
"__pycache__"
|
|
4081
|
+
]);
|
|
4082
|
+
var MIGRATION_MARKER = "/db/migration/";
|
|
4083
|
+
function isSqlFileName(name) {
|
|
4084
|
+
return name.toLowerCase().endsWith(".sql");
|
|
4085
|
+
}
|
|
4086
|
+
function sha256File(absPath) {
|
|
4087
|
+
const hash = createHash2("sha256");
|
|
4088
|
+
hash.update(fs2.readFileSync(absPath));
|
|
4089
|
+
return hash.digest("hex");
|
|
4090
|
+
}
|
|
4091
|
+
function scanLocalMigrationSqlFiles(workdir) {
|
|
4092
|
+
const root = path2.resolve(workdir);
|
|
4093
|
+
const byRelative = /* @__PURE__ */ new Map();
|
|
4094
|
+
const walk = (dir) => {
|
|
4095
|
+
let entries;
|
|
4096
|
+
try {
|
|
4097
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
4098
|
+
} catch {
|
|
4099
|
+
return;
|
|
4100
|
+
}
|
|
4101
|
+
for (const entry of entries) {
|
|
4102
|
+
const name = entry.name;
|
|
4103
|
+
if (entry.isDirectory()) {
|
|
4104
|
+
if (SKIP_DIR_NAMES2.has(name) || name.startsWith(".")) continue;
|
|
4105
|
+
walk(path2.join(dir, name));
|
|
4106
|
+
continue;
|
|
4107
|
+
}
|
|
4108
|
+
if (!entry.isFile() || !isSqlFileName(name)) continue;
|
|
4109
|
+
const absPath = path2.join(dir, name);
|
|
4110
|
+
const normalized = absPath.replace(/\\/g, "/");
|
|
4111
|
+
const idx = normalized.toLowerCase().lastIndexOf(MIGRATION_MARKER);
|
|
4112
|
+
if (idx < 0) continue;
|
|
4113
|
+
const relativePath = normalized.slice(idx + MIGRATION_MARKER.length);
|
|
4114
|
+
if (!relativePath || relativePath.includes("..")) continue;
|
|
4115
|
+
const stat = fs2.statSync(absPath);
|
|
4116
|
+
if (!stat.isFile() || stat.size <= 0) continue;
|
|
4117
|
+
const item = {
|
|
4118
|
+
absPath,
|
|
4119
|
+
relativePath,
|
|
4120
|
+
size: stat.size,
|
|
4121
|
+
sha256: sha256File(absPath)
|
|
4122
|
+
};
|
|
4123
|
+
const prev = byRelative.get(relativePath);
|
|
4124
|
+
if (prev) {
|
|
4125
|
+
console.warn(
|
|
4126
|
+
`[apm] SQL relative path conflict, overwrite: ${relativePath}
|
|
4127
|
+
old: ${prev.absPath}
|
|
4128
|
+
new: ${absPath}`
|
|
4129
|
+
);
|
|
4130
|
+
}
|
|
4131
|
+
byRelative.set(relativePath, item);
|
|
4132
|
+
}
|
|
4133
|
+
};
|
|
4134
|
+
walk(root);
|
|
4135
|
+
return [...byRelative.values()].sort(
|
|
4136
|
+
(a, b) => a.relativePath.localeCompare(b.relativePath)
|
|
4137
|
+
);
|
|
4138
|
+
}
|
|
4139
|
+
function packageSqlObjectKey(projectId, relativePath) {
|
|
4140
|
+
return `packages/${projectId}/sql/${relativePath}`;
|
|
4141
|
+
}
|
|
4142
|
+
function packageSqlPrefix(projectId) {
|
|
4143
|
+
return `packages/${projectId}/sql/`;
|
|
4144
|
+
}
|
|
4145
|
+
async function syncPackageSqlToMinio(cfg, workdir, projectId) {
|
|
4146
|
+
const id = projectId.trim();
|
|
4147
|
+
if (!id) {
|
|
4148
|
+
throw new Error("projectId \u4E0D\u80FD\u4E3A\u7A7A");
|
|
4149
|
+
}
|
|
4150
|
+
const localFiles = scanLocalMigrationSqlFiles(workdir);
|
|
4151
|
+
const { client, bucket } = await createApmLogMinioClient(cfg);
|
|
4152
|
+
await client.ensureBucket(bucket);
|
|
4153
|
+
const prefix = packageSqlPrefix(id);
|
|
4154
|
+
const remoteObjects = await client.listObjects(bucket, prefix);
|
|
4155
|
+
const remoteByRelative = /* @__PURE__ */ new Map();
|
|
4156
|
+
for (const obj of remoteObjects) {
|
|
4157
|
+
if (!obj.name.startsWith(prefix) || obj.name.endsWith("/")) continue;
|
|
4158
|
+
if (!obj.name.toLowerCase().endsWith(".sql")) continue;
|
|
4159
|
+
const relativePath = obj.name.slice(prefix.length);
|
|
4160
|
+
if (!relativePath) continue;
|
|
4161
|
+
remoteByRelative.set(relativePath, {
|
|
4162
|
+
objectKey: obj.name,
|
|
4163
|
+
size: obj.size
|
|
4164
|
+
});
|
|
4165
|
+
}
|
|
4166
|
+
for (const [relativePath, remote] of remoteByRelative) {
|
|
4167
|
+
const local = localFiles.find((f) => f.relativePath === relativePath);
|
|
4168
|
+
if (!local) continue;
|
|
4169
|
+
if (local.size !== remote.size) continue;
|
|
4170
|
+
try {
|
|
4171
|
+
const stat = await client.statObject(bucket, remote.objectKey);
|
|
4172
|
+
const meta = stat.metaData ?? {};
|
|
4173
|
+
const sha = meta["sha256"] || meta["x-amz-meta-sha256"] || meta["Sha256"] || void 0;
|
|
4174
|
+
if (typeof sha === "string" && sha.trim()) {
|
|
4175
|
+
remote.sha256 = sha.trim().toLowerCase();
|
|
4176
|
+
}
|
|
4177
|
+
} catch {
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
let uploaded = 0;
|
|
4181
|
+
let skipped = 0;
|
|
4182
|
+
const localRelativeSet = new Set(localFiles.map((f) => f.relativePath));
|
|
4183
|
+
for (const file of localFiles) {
|
|
4184
|
+
const objectKey = packageSqlObjectKey(id, file.relativePath);
|
|
4185
|
+
const remote = remoteByRelative.get(file.relativePath);
|
|
4186
|
+
if (remote?.sha256 && remote.sha256 === file.sha256) {
|
|
4187
|
+
skipped += 1;
|
|
4188
|
+
continue;
|
|
4189
|
+
}
|
|
4190
|
+
await client.fPutObject(bucket, objectKey, file.absPath, {
|
|
4191
|
+
"Content-Type": "application/sql",
|
|
4192
|
+
sha256: file.sha256
|
|
4193
|
+
});
|
|
4194
|
+
uploaded += 1;
|
|
4195
|
+
}
|
|
4196
|
+
let deleted = 0;
|
|
4197
|
+
for (const [relativePath, remote] of remoteByRelative) {
|
|
4198
|
+
if (localRelativeSet.has(relativePath)) continue;
|
|
4199
|
+
await client.removeObject(bucket, remote.objectKey);
|
|
4200
|
+
deleted += 1;
|
|
4201
|
+
}
|
|
4202
|
+
return {
|
|
4203
|
+
scanned: localFiles.length,
|
|
4204
|
+
uploaded,
|
|
4205
|
+
skipped,
|
|
4206
|
+
deleted
|
|
4207
|
+
};
|
|
4208
|
+
}
|
|
4209
|
+
|
|
4037
4210
|
// src/commands/connect/handle-package.ts
|
|
4038
4211
|
async function updatePackageStatus(cfg, packageId, status, extra) {
|
|
4039
4212
|
const api = createApmApiClient(cfg);
|
|
@@ -4164,6 +4337,21 @@ async function handleWebIdePackage(cfg, msg, signal) {
|
|
|
4164
4337
|
return `downloaded=${result.downloaded} deleted=${result.deleted}`;
|
|
4165
4338
|
}
|
|
4166
4339
|
);
|
|
4340
|
+
if (msg.target === "backend") {
|
|
4341
|
+
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
4342
|
+
try {
|
|
4343
|
+
await runPrepStep(
|
|
4344
|
+
"\u540C\u6B65 SQL \u5230 MinIO",
|
|
4345
|
+
() => syncPackageSqlToMinio(cfg, workdir, projectId),
|
|
4346
|
+
(result) => `scanned=${result.scanned} uploaded=${result.uploaded} skipped=${result.skipped} deleted=${result.deleted}`
|
|
4347
|
+
);
|
|
4348
|
+
} catch (err) {
|
|
4349
|
+
console.warn(
|
|
4350
|
+
`[apm] \u540C\u6B65 SQL \u5230 MinIO \u5931\u8D25\uFF08\u4E0D\u963B\u65AD\u6253\u5305\uFF09:`,
|
|
4351
|
+
err instanceof Error ? err.message : err
|
|
4352
|
+
);
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4167
4355
|
eventSession.addCliStep("\u542F\u52A8\u6253\u5305 Agent", "\u51C6\u5907 create\u2026", "running");
|
|
4168
4356
|
await syncPrepLog();
|
|
4169
4357
|
let failedByTool = false;
|
package/package.json
CHANGED
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
### target=backend(SpringBoot)
|
|
41
41
|
|
|
42
42
|
1. 按 deploy 文档进入后端目录,执行文档写明的构建命令(通常 `mvn clean package`)。
|
|
43
|
-
2. **只**收集 deploy 文档标明的交付 jar(路径/文件名/glob 以文档为准)。**禁止**全量收集 `target/lib
|
|
43
|
+
2. **只**收集 deploy 文档标明的交付 jar(路径/文件名/glob 以文档为准)。**禁止**全量收集 `target/lib`、**禁止**把 SQL 打进 jars.zip、**禁止**在规则或命令里写死具体 jar 名。SQL 镜像由 CLI 自动扫描本地 `db/migration` 下的 `.sql` 同步到 MinIO,Agent **不要**上传 SQL。
|
|
44
44
|
3. 确认文档列出的每个 jar 均已生成;缺任一文件 → SetPackageFailed。
|
|
45
45
|
4. 在临时目录将上述 jar **打成一个 zip**(勿在工作区生成交付 zip),落到:
|
|
46
46
|
|