ai-project-manage-cli 6.0.55 → 6.0.57
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
|
@@ -999,6 +999,19 @@ function reasonForCleanup(sessionId, sessionStatusById) {
|
|
|
999
999
|
}
|
|
1000
1000
|
return "\u4FDD\u7559";
|
|
1001
1001
|
}
|
|
1002
|
+
async function isBranchMergedIntoDefault(cwd, branch, defaultBranch) {
|
|
1003
|
+
const ref = await localBranchExists2(cwd, branch) ? branch : `origin/${branch}`;
|
|
1004
|
+
try {
|
|
1005
|
+
await execGit3(
|
|
1006
|
+
cwd,
|
|
1007
|
+
["merge-base", "--is-ancestor", ref, `origin/${defaultBranch}`],
|
|
1008
|
+
true
|
|
1009
|
+
);
|
|
1010
|
+
return true;
|
|
1011
|
+
} catch {
|
|
1012
|
+
return false;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1002
1015
|
async function runCleanBranches(options = {}) {
|
|
1003
1016
|
const cwd = options.cwd ?? process.cwd();
|
|
1004
1017
|
const dryRun = options.dryRun ?? false;
|
|
@@ -1035,11 +1048,20 @@ async function runCleanBranches(options = {}) {
|
|
|
1035
1048
|
}
|
|
1036
1049
|
let currentBranch = await getCurrentBranch2(cwd);
|
|
1037
1050
|
let defaultBranch = null;
|
|
1051
|
+
if (dryRun) {
|
|
1052
|
+
defaultBranch = await resolveDefaultBranch(cwd);
|
|
1053
|
+
}
|
|
1038
1054
|
for (const item of toDelete) {
|
|
1039
1055
|
const { branch, sessionId, reason } = item;
|
|
1040
1056
|
const label = `${branch} (${sessionId}: ${reason})`;
|
|
1041
1057
|
if (dryRun) {
|
|
1042
|
-
|
|
1058
|
+
const merged = await isBranchMergedIntoDefault(
|
|
1059
|
+
cwd,
|
|
1060
|
+
branch,
|
|
1061
|
+
defaultBranch
|
|
1062
|
+
);
|
|
1063
|
+
const mergeTag = merged ? "\u5DF2\u5408\u5E76" : "\u672A\u5408\u5E76";
|
|
1064
|
+
console.log(`[apm] [dry-run] \u5C06\u5220\u9664 ${label} [${mergeTag}]`);
|
|
1043
1065
|
continue;
|
|
1044
1066
|
}
|
|
1045
1067
|
if (currentBranch === branch) {
|
|
@@ -1518,17 +1540,16 @@ async function runUpdate() {
|
|
|
1518
1540
|
// src/commands/update-skills.ts
|
|
1519
1541
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4, statSync as statSync3 } from "fs";
|
|
1520
1542
|
import { join as join10 } from "path";
|
|
1521
|
-
async function
|
|
1522
|
-
const apmDir = workspaceApmDir();
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1543
|
+
async function syncWorkspaceSkills(cfg, workdir) {
|
|
1544
|
+
const apmDir = workspaceApmDir(workdir);
|
|
1545
|
+
const fsApmDir = toFsPath(apmDir);
|
|
1546
|
+
if (!existsSync6(fsApmDir)) {
|
|
1547
|
+
throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
1526
1548
|
}
|
|
1527
|
-
const apmStat = statSync3(
|
|
1549
|
+
const apmStat = statSync3(fsApmDir);
|
|
1528
1550
|
if (!apmStat.isDirectory()) {
|
|
1529
1551
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
1530
1552
|
}
|
|
1531
|
-
const cfg = await ensureLoggedConfig();
|
|
1532
1553
|
const api = createApmApiClient(cfg);
|
|
1533
1554
|
const { list } = await api.cli.listSkills({});
|
|
1534
1555
|
if (syncAgentsGuide(apmDir)) {
|
|
@@ -1540,7 +1561,7 @@ async function runUpdateSkills() {
|
|
|
1540
1561
|
console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u89C4\u5219: rules/${name}`);
|
|
1541
1562
|
}
|
|
1542
1563
|
const skillsDir = join10(apmDir, "skills");
|
|
1543
|
-
mkdirSync4(skillsDir, { recursive: true });
|
|
1564
|
+
mkdirSync4(toFsPath(skillsDir), { recursive: true });
|
|
1544
1565
|
const baseNames = syncBaseSkills(skillsDir);
|
|
1545
1566
|
for (const name of baseNames) {
|
|
1546
1567
|
console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u6280\u80FD: skills/${name}/`);
|
|
@@ -1564,6 +1585,19 @@ async function runUpdateSkills() {
|
|
|
1564
1585
|
`[apm] \u540C\u6B65\u5B8C\u6210\uFF1A${ruleNames.length} \u4E2A\u57FA\u7840\u89C4\u5219\uFF0C${baseNames.length} \u4E2A\u57FA\u7840\u6280\u80FD\uFF0C${written.length} \u4E2A\u8865\u5145\u6280\u80FD`
|
|
1565
1586
|
);
|
|
1566
1587
|
}
|
|
1588
|
+
async function runUpdateSkills() {
|
|
1589
|
+
const apmDir = workspaceApmDir();
|
|
1590
|
+
if (!existsSync6(apmDir)) {
|
|
1591
|
+
console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
1592
|
+
process.exit(1);
|
|
1593
|
+
}
|
|
1594
|
+
const apmStat = statSync3(apmDir);
|
|
1595
|
+
if (!apmStat.isDirectory()) {
|
|
1596
|
+
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
1597
|
+
}
|
|
1598
|
+
const cfg = await ensureLoggedConfig();
|
|
1599
|
+
await syncWorkspaceSkills(cfg, resolveWorkdirPath());
|
|
1600
|
+
}
|
|
1567
1601
|
|
|
1568
1602
|
// src/commands/sync-deploy-config.ts
|
|
1569
1603
|
import { existsSync as existsSync7, statSync as statSync4 } from "fs";
|
|
@@ -2397,6 +2431,56 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
2397
2431
|
}
|
|
2398
2432
|
}
|
|
2399
2433
|
|
|
2434
|
+
// src/commands/connect/cli-version-sync.ts
|
|
2435
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
2436
|
+
import { join as join12 } from "path";
|
|
2437
|
+
var CLI_VERSION_FILE = ".cli-version.json";
|
|
2438
|
+
function manifestPath(apmDir) {
|
|
2439
|
+
return join12(apmDir, CLI_VERSION_FILE);
|
|
2440
|
+
}
|
|
2441
|
+
function loadManifest3(apmDir) {
|
|
2442
|
+
const path10 = toFsPath(manifestPath(apmDir));
|
|
2443
|
+
if (!existsSync11(path10)) {
|
|
2444
|
+
return null;
|
|
2445
|
+
}
|
|
2446
|
+
try {
|
|
2447
|
+
const parsed = JSON.parse(
|
|
2448
|
+
readFileSync9(path10, "utf8")
|
|
2449
|
+
);
|
|
2450
|
+
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
2451
|
+
return parsed;
|
|
2452
|
+
}
|
|
2453
|
+
} catch {
|
|
2454
|
+
}
|
|
2455
|
+
return null;
|
|
2456
|
+
}
|
|
2457
|
+
function saveManifest3(apmDir, cliVersion) {
|
|
2458
|
+
const manifest = { version: 1, cliVersion };
|
|
2459
|
+
writeFileSync10(
|
|
2460
|
+
toFsPath(manifestPath(apmDir)),
|
|
2461
|
+
`${JSON.stringify(manifest, null, 2)}
|
|
2462
|
+
`,
|
|
2463
|
+
"utf8"
|
|
2464
|
+
);
|
|
2465
|
+
}
|
|
2466
|
+
var syncedInSession = /* @__PURE__ */ new Map();
|
|
2467
|
+
function shouldSyncSkillsForCliVersion(workdir, currentVersion) {
|
|
2468
|
+
const cached = syncedInSession.get(workdir);
|
|
2469
|
+
if (cached === currentVersion) {
|
|
2470
|
+
return false;
|
|
2471
|
+
}
|
|
2472
|
+
const stored = loadManifest3(workspaceApmDir(workdir));
|
|
2473
|
+
if (stored?.cliVersion === currentVersion) {
|
|
2474
|
+
syncedInSession.set(workdir, currentVersion);
|
|
2475
|
+
return false;
|
|
2476
|
+
}
|
|
2477
|
+
return true;
|
|
2478
|
+
}
|
|
2479
|
+
function markSkillsSyncedForCliVersion(workdir, cliVersion) {
|
|
2480
|
+
saveManifest3(workspaceApmDir(workdir), cliVersion);
|
|
2481
|
+
syncedInSession.set(workdir, cliVersion);
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2400
2484
|
// src/commands/connect/pre-step-cache.ts
|
|
2401
2485
|
var PULL_TTL_MS = 3e4;
|
|
2402
2486
|
function sessionWorkdirKey(sessionId, workdir) {
|
|
@@ -2515,6 +2599,19 @@ async function handleInboundMessage(cfg, msg, signal, ctx) {
|
|
|
2515
2599
|
} else {
|
|
2516
2600
|
console.log(`[apm] step=commit-pull skipped sessionId=${msg.sessionId}`);
|
|
2517
2601
|
}
|
|
2602
|
+
const cliVersion = readCliVersion();
|
|
2603
|
+
if (shouldSyncSkillsForCliVersion(workdir, cliVersion)) {
|
|
2604
|
+
if (signal.aborted) return;
|
|
2605
|
+
console.log(
|
|
2606
|
+
`[apm] CLI \u7248\u672C ${cliVersion} \u4E0E\u5DE5\u4F5C\u533A\u8BB0\u5F55\u4E0D\u4E00\u81F4\uFF0C\u6267\u884C update-skills`
|
|
2607
|
+
);
|
|
2608
|
+
await runStep("update-skills", async () => {
|
|
2609
|
+
await syncWorkspaceSkills(cfg, workdir);
|
|
2610
|
+
markSkillsSyncedForCliVersion(workdir, cliVersion);
|
|
2611
|
+
});
|
|
2612
|
+
} else {
|
|
2613
|
+
console.log(`[apm] step=update-skills skipped workdir=${workdir}`);
|
|
2614
|
+
}
|
|
2518
2615
|
if (signal.aborted) return;
|
|
2519
2616
|
await runStep(
|
|
2520
2617
|
"cursor-agent",
|
|
@@ -2755,19 +2852,19 @@ async function runCreatePr(options) {
|
|
|
2755
2852
|
import path5 from "node:path";
|
|
2756
2853
|
|
|
2757
2854
|
// src/commands/deploy/internal/apm-config.ts
|
|
2758
|
-
import { existsSync as
|
|
2855
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
2759
2856
|
import { resolve as resolve4 } from "node:path";
|
|
2760
2857
|
function loadApmConfig(options) {
|
|
2761
2858
|
const p = resolve4(
|
|
2762
2859
|
process.cwd(),
|
|
2763
2860
|
options?.configPath ?? resolve4(workspaceApmDir(), "apm.config.json")
|
|
2764
2861
|
);
|
|
2765
|
-
if (!
|
|
2862
|
+
if (!existsSync12(p)) {
|
|
2766
2863
|
console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
|
|
2767
2864
|
process.exit(1);
|
|
2768
2865
|
}
|
|
2769
2866
|
try {
|
|
2770
|
-
const raw =
|
|
2867
|
+
const raw = readFileSync10(p, "utf8");
|
|
2771
2868
|
return JSON.parse(raw);
|
|
2772
2869
|
} catch (e) {
|
|
2773
2870
|
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
@@ -2889,7 +2986,7 @@ import path4 from "node:path";
|
|
|
2889
2986
|
import Docker from "dockerode";
|
|
2890
2987
|
|
|
2891
2988
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
2892
|
-
import { existsSync as
|
|
2989
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
|
|
2893
2990
|
import path from "node:path";
|
|
2894
2991
|
function asOptionalTlsBuffer(value) {
|
|
2895
2992
|
if (typeof value !== "string") {
|
|
@@ -2901,8 +2998,8 @@ function asOptionalTlsBuffer(value) {
|
|
|
2901
2998
|
if (normalized === "") {
|
|
2902
2999
|
return void 0;
|
|
2903
3000
|
}
|
|
2904
|
-
if (
|
|
2905
|
-
return
|
|
3001
|
+
if (existsSync13(normalized)) {
|
|
3002
|
+
return readFileSync11(normalized);
|
|
2906
3003
|
}
|
|
2907
3004
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
2908
3005
|
if (looksLikePath) {
|
|
@@ -3112,7 +3209,7 @@ var DockerodeClient = class {
|
|
|
3112
3209
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
3113
3210
|
|
|
3114
3211
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
3115
|
-
import { existsSync as
|
|
3212
|
+
import { existsSync as existsSync14, readFileSync as readFileSync12, statSync as statSync5 } from "node:fs";
|
|
3116
3213
|
import path2 from "node:path";
|
|
3117
3214
|
function stripSurroundingQuotes(value) {
|
|
3118
3215
|
const t = value.trim();
|
|
@@ -3129,10 +3226,10 @@ function loadEnvFromFile(envFilePath) {
|
|
|
3129
3226
|
return {};
|
|
3130
3227
|
}
|
|
3131
3228
|
const targetPath = path2.resolve(envFilePath);
|
|
3132
|
-
if (!
|
|
3229
|
+
if (!existsSync14(targetPath) || !statSync5(targetPath).isFile()) {
|
|
3133
3230
|
return {};
|
|
3134
3231
|
}
|
|
3135
|
-
const raw =
|
|
3232
|
+
const raw = readFileSync12(targetPath, "utf-8");
|
|
3136
3233
|
const result = {};
|
|
3137
3234
|
for (const line of raw.split(/\r?\n/)) {
|
|
3138
3235
|
const normalized = line.trim();
|
|
@@ -3303,12 +3400,12 @@ function dockerPushImage(params, cwd) {
|
|
|
3303
3400
|
}
|
|
3304
3401
|
|
|
3305
3402
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
3306
|
-
import { existsSync as
|
|
3403
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
3307
3404
|
import path3 from "node:path";
|
|
3308
3405
|
function resolveDockerBuildPaths(cwd) {
|
|
3309
3406
|
const dockerfilePath = path3.join(cwd, "Dockerfile");
|
|
3310
3407
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
3311
|
-
if (!
|
|
3408
|
+
if (!existsSync15(dockerfilePath)) {
|
|
3312
3409
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
3313
3410
|
}
|
|
3314
3411
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|
package/package.json
CHANGED
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
|
|
53
53
|
- **目标数据库**(库名/实例名、类型如 MySQL;同一变更涉及多库时分别标注)
|
|
54
54
|
- 变更摘要(改了什么表/数据、为什么)
|
|
55
|
-
- 完整 SQL 语句(按执行顺序排列;**每条须放在 ` ```sql `
|
|
55
|
+
- 完整 SQL 语句(按执行顺序排列;**每条须放在 ` ```sql ` 代码块中**,便于复制执行;**禁止**用 `...` 或「省略」占位代替任何片段)
|
|
56
56
|
- 执行环境说明(测试/生产是否一致、是否需人工执行)
|
|
57
|
-
- 回滚方案(如适用;回滚 SQL 同样用 ` ```sql `
|
|
57
|
+
- 回滚方案(如适用;回滚 SQL 同样用 ` ```sql ` 代码块,须完整可执行,禁止省略)
|
|
58
58
|
|
|
59
59
|
示例:
|
|
60
60
|
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
|
|
19
19
|
### 步骤 2:四项检查
|
|
20
20
|
|
|
21
|
-
| 检查项 | 判定
|
|
22
|
-
| -------------- |
|
|
23
|
-
| **白名单对账** | diff 中出现白名单之外的文件,且计划未更新说明 → **不通过**
|
|
24
|
-
| **需求相关性** | 存在与本需求无关的改动(顺手重构、改格式、动了无关逻辑)→ **不通过**
|
|
25
|
-
| **计划落实** | 计划「实现步骤」中的关键点在 diff 中找不到对应实现 → **不通过**
|
|
26
|
-
| **SQL 文档** | **仅后端**:diff 涉及 SQL 改动(DDL/DML、表结构、Mapper/XML 中 SQL 等),但 `docs/SQL.md`
|
|
21
|
+
| 检查项 | 判定 |
|
|
22
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| **白名单对账** | diff 中出现白名单之外的文件,且计划未更新说明 → **不通过** |
|
|
24
|
+
| **需求相关性** | 存在与本需求无关的改动(顺手重构、改格式、动了无关逻辑)→ **不通过** |
|
|
25
|
+
| **计划落实** | 计划「实现步骤」中的关键点在 diff 中找不到对应实现 → **不通过** |
|
|
26
|
+
| **SQL 文档** | **仅后端**:diff 涉及 SQL 改动(DDL/DML、表结构、Mapper/XML 中 SQL 等),但 `docs/SQL.md` 缺失、未标注目标数据库、与改动不一致、或 SQL 代码块含 `...`/「省略」占位 → **不通过** |
|
|
27
27
|
|
|
28
28
|
注意事项:
|
|
29
29
|
|