ai-project-manage-cli 6.0.48 → 6.0.51
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 +80 -21
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -81,10 +81,17 @@ function buildAgentWsUrl(httpBase, apiKey) {
|
|
|
81
81
|
|
|
82
82
|
// src/commands/init.ts
|
|
83
83
|
import { join as join4 } from "path";
|
|
84
|
-
import { readFileSync as
|
|
84
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
85
85
|
|
|
86
86
|
// src/command-utils.ts
|
|
87
|
-
import {
|
|
87
|
+
import {
|
|
88
|
+
copyFileSync,
|
|
89
|
+
existsSync,
|
|
90
|
+
mkdirSync as mkdirSync2,
|
|
91
|
+
readFileSync as readFileSync2,
|
|
92
|
+
readdirSync,
|
|
93
|
+
statSync
|
|
94
|
+
} from "fs";
|
|
88
95
|
import { basename, dirname, extname, join as join2, resolve as resolve2 } from "path";
|
|
89
96
|
import { fileURLToPath } from "url";
|
|
90
97
|
|
|
@@ -141,6 +148,56 @@ var CLI_TEMPLATE_DIR = resolve2(__dirname, "../template");
|
|
|
141
148
|
function workspaceApmDir(cwd = resolveWorkdirPath()) {
|
|
142
149
|
return resolve2(resolve2(cwd), ".apm");
|
|
143
150
|
}
|
|
151
|
+
function assertWorkspaceApmDirExists(workdir) {
|
|
152
|
+
const apmDir = workspaceApmDir(workdir);
|
|
153
|
+
const fsApmDir = toFsPath(apmDir);
|
|
154
|
+
if (!existsSync(fsApmDir)) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`\u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u4E0B\u672A\u68C0\u6D4B\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5728\u8BE5\u4ED3\u5E93\u6839\u76EE\u5F55\u6267\u884C apm init \u5B8C\u6210\u63A5\u5165\u3002`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const st = statSync(fsApmDir);
|
|
160
|
+
if (!st.isDirectory()) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`\u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u4E0B\u7684 .apm \u4E0D\u662F\u76EE\u5F55\uFF0C\u8BF7\u68C0\u67E5\u672C\u5730\u63A5\u5165\u72B6\u6001\u3002`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
var APM_GITIGNORE_PATTERNS = [
|
|
167
|
+
/^\.apm\/?$/,
|
|
168
|
+
/^\.apm\/\*\*$/,
|
|
169
|
+
/^\*\*\/\.apm\/?$/,
|
|
170
|
+
/^\*\*\/\.apm\/\*\*$/,
|
|
171
|
+
/^\/\.apm\/?$/,
|
|
172
|
+
/^\/\.apm\/\*\*$/
|
|
173
|
+
];
|
|
174
|
+
function normalizeGitignorePattern(line) {
|
|
175
|
+
const trimmed = line.trim();
|
|
176
|
+
if (!trimmed || trimmed.startsWith("#")) return "";
|
|
177
|
+
if (trimmed.startsWith("!")) return "";
|
|
178
|
+
const hashIndex = trimmed.indexOf("#");
|
|
179
|
+
return (hashIndex >= 0 ? trimmed.slice(0, hashIndex) : trimmed).trim();
|
|
180
|
+
}
|
|
181
|
+
function gitignoreIgnoresApm(line) {
|
|
182
|
+
const pattern = normalizeGitignorePattern(line);
|
|
183
|
+
if (!pattern) return false;
|
|
184
|
+
return APM_GITIGNORE_PATTERNS.some((re) => re.test(pattern));
|
|
185
|
+
}
|
|
186
|
+
function assertApmGitignoredInRepo(workdir) {
|
|
187
|
+
const gitignorePath = join2(workdir, ".gitignore");
|
|
188
|
+
const fsGitignorePath = toFsPath(gitignorePath);
|
|
189
|
+
if (!existsSync(fsGitignorePath)) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`\u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u7F3A\u5C11 .gitignore \u6587\u4EF6\uFF0C\u8BF7\u6DFB\u52A0\u5BF9 .apm \u7684\u5FFD\u7565\u89C4\u5219\uFF08\u4F8B\u5982 **/.apm/**\uFF09\uFF0C\u907F\u514D\u672C\u5730\u4F1A\u8BDD\u4E0E\u90E8\u7F72\u51ED\u636E\u88AB\u63D0\u4EA4\u3002`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
const content = readFileSync2(fsGitignorePath, "utf8");
|
|
195
|
+
if (!content.split(/\r?\n/).some(gitignoreIgnoresApm)) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`\u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u7684 .gitignore \u672A\u5FFD\u7565 .apm\uFF0C\u8BF7\u6DFB\u52A0 **/.apm/** \u6216 .apm/\uFF0C\u907F\u514D\u672C\u5730\u4F1A\u8BDD\u4E0E\u90E8\u7F72\u51ED\u636E\u88AB\u63D0\u4EA4\u3002`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
144
201
|
var SESSIONS_SUBDIR = "sessions";
|
|
145
202
|
var SESSION_DOCS_SUBDIR = "docs";
|
|
146
203
|
var SESSION_ATTACHMENTS_SUBDIR = "attachments";
|
|
@@ -492,7 +549,7 @@ async function runInit(name) {
|
|
|
492
549
|
const trimmedName = name?.trim();
|
|
493
550
|
if (trimmedName) {
|
|
494
551
|
const apmConfigPath = toFsPath(join4(apmDir, "apm.config.json"));
|
|
495
|
-
const config =
|
|
552
|
+
const config = readFileSync3(apmConfigPath, "utf8");
|
|
496
553
|
const configJson = JSON.parse(config);
|
|
497
554
|
configJson.name = trimmedName;
|
|
498
555
|
writeFileSync3(
|
|
@@ -775,7 +832,7 @@ function formatSessionMessagesXml(sessionId, messages) {
|
|
|
775
832
|
}
|
|
776
833
|
|
|
777
834
|
// src/commands/sync-session-attachments.ts
|
|
778
|
-
import { existsSync as existsSync3, readFileSync as
|
|
835
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
779
836
|
import { join as join5 } from "path";
|
|
780
837
|
var MANIFEST_FILE = ".sync-manifest.json";
|
|
781
838
|
async function downloadAttachment(cfg, attachmentId) {
|
|
@@ -796,7 +853,7 @@ function loadManifest(dir) {
|
|
|
796
853
|
}
|
|
797
854
|
try {
|
|
798
855
|
const parsed = JSON.parse(
|
|
799
|
-
|
|
856
|
+
readFileSync4(path10, "utf8")
|
|
800
857
|
);
|
|
801
858
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
802
859
|
return parsed;
|
|
@@ -852,7 +909,7 @@ async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
|
|
|
852
909
|
|
|
853
910
|
// src/rules-sync.ts
|
|
854
911
|
import { basename as basename2, extname as extname2, join as join7 } from "path";
|
|
855
|
-
import { existsSync as existsSync5, readFileSync as
|
|
912
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
856
913
|
|
|
857
914
|
// src/skills-sync.ts
|
|
858
915
|
import {
|
|
@@ -960,7 +1017,7 @@ function loadManifest2(rulesDir) {
|
|
|
960
1017
|
}
|
|
961
1018
|
try {
|
|
962
1019
|
const parsed = JSON.parse(
|
|
963
|
-
|
|
1020
|
+
readFileSync5(toFsPath(path10), "utf8")
|
|
964
1021
|
);
|
|
965
1022
|
if (parsed?.version === 1 && parsed.rules && typeof parsed.rules === "object") {
|
|
966
1023
|
return parsed;
|
|
@@ -985,7 +1042,7 @@ function isRuleUpToDate(entry, rule, dest) {
|
|
|
985
1042
|
if (entry.fileName !== ruleLocalFileName(rule.name)) return false;
|
|
986
1043
|
const updatedAt = rule.updatedAt ?? "";
|
|
987
1044
|
if (entry.updatedAt !== updatedAt) return false;
|
|
988
|
-
const localContent =
|
|
1045
|
+
const localContent = readFileSync5(toFsPath(dest), "utf8");
|
|
989
1046
|
return localContent === (rule.content ?? "");
|
|
990
1047
|
}
|
|
991
1048
|
async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
@@ -1112,7 +1169,7 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
1112
1169
|
import { spawnSync } from "child_process";
|
|
1113
1170
|
|
|
1114
1171
|
// src/version.ts
|
|
1115
|
-
import { readFileSync as
|
|
1172
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
1116
1173
|
import { dirname as dirname2, join as join9 } from "path";
|
|
1117
1174
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1118
1175
|
var CLI_PACKAGE_NAME = "ai-project-manage-cli";
|
|
@@ -1120,7 +1177,7 @@ function readCliVersion() {
|
|
|
1120
1177
|
try {
|
|
1121
1178
|
const dir = dirname2(fileURLToPath2(import.meta.url));
|
|
1122
1179
|
const pkgPath = join9(dir, "..", "package.json");
|
|
1123
|
-
const pkg = JSON.parse(
|
|
1180
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf8"));
|
|
1124
1181
|
return pkg.version ?? "0.0.0";
|
|
1125
1182
|
} catch {
|
|
1126
1183
|
return "0.0.0";
|
|
@@ -1266,7 +1323,7 @@ import { existsSync as existsSync9 } from "fs";
|
|
|
1266
1323
|
import { basename as basename3 } from "path";
|
|
1267
1324
|
|
|
1268
1325
|
// src/commands/sync-session-documents.ts
|
|
1269
|
-
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as
|
|
1326
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
1270
1327
|
import { join as join11 } from "path";
|
|
1271
1328
|
function listLocalMarkdownFiles(docsDir) {
|
|
1272
1329
|
if (!existsSync8(docsDir)) {
|
|
@@ -1285,7 +1342,7 @@ function remoteDocumentByLocalName(remoteDocuments, localFileName) {
|
|
|
1285
1342
|
}
|
|
1286
1343
|
async function upsertLocalDocumentFile(api, sessionId, docsDir, fileName) {
|
|
1287
1344
|
const absPath = join11(docsDir, fileName);
|
|
1288
|
-
const content =
|
|
1345
|
+
const content = readFileSync7(absPath, "utf8");
|
|
1289
1346
|
const name = documentPlatformName(absPath);
|
|
1290
1347
|
return api.cli.upsertDocument({
|
|
1291
1348
|
sessionId,
|
|
@@ -1308,7 +1365,7 @@ async function syncSessionDocuments(cfg, sessionId, apmRoot, options) {
|
|
|
1308
1365
|
let synced = 0;
|
|
1309
1366
|
for (const fileName of localFiles) {
|
|
1310
1367
|
const absPath = join11(docsDir, fileName);
|
|
1311
|
-
const content =
|
|
1368
|
+
const content = readFileSync7(absPath, "utf8");
|
|
1312
1369
|
const remote = remoteDocumentByLocalName(remoteDocuments, fileName);
|
|
1313
1370
|
if (remote && remote.content === content) {
|
|
1314
1371
|
continue;
|
|
@@ -1741,7 +1798,7 @@ ${JSON.stringify(event, null, 2)}
|
|
|
1741
1798
|
}
|
|
1742
1799
|
|
|
1743
1800
|
// src/commands/connect/agent-session-registry.ts
|
|
1744
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as
|
|
1801
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "node:fs";
|
|
1745
1802
|
import { dirname as dirname3, resolve as resolve3 } from "node:path";
|
|
1746
1803
|
function registryPath(workdir, sessionId) {
|
|
1747
1804
|
return resolve3(workdir, ".apm", "sessions", sessionId, "cursor-agents.json");
|
|
@@ -1751,7 +1808,7 @@ function readRegistry(path10) {
|
|
|
1751
1808
|
return {};
|
|
1752
1809
|
}
|
|
1753
1810
|
try {
|
|
1754
|
-
const parsed = JSON.parse(
|
|
1811
|
+
const parsed = JSON.parse(readFileSync8(path10, "utf8"));
|
|
1755
1812
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
1756
1813
|
const result = {};
|
|
1757
1814
|
for (const [key, value] of Object.entries(
|
|
@@ -2159,6 +2216,8 @@ async function handleInboundMessage(cfg, msg, signal, ctx) {
|
|
|
2159
2216
|
};
|
|
2160
2217
|
try {
|
|
2161
2218
|
if (signal.aborted) return;
|
|
2219
|
+
assertWorkspaceApmDirExists(workdir);
|
|
2220
|
+
assertApmGitignoredInRepo(workdir);
|
|
2162
2221
|
await runStep(
|
|
2163
2222
|
"status-typing",
|
|
2164
2223
|
() => updateMessageStatus(cfg, messageId, "TYPING")
|
|
@@ -2411,7 +2470,7 @@ async function runCreatePr(options) {
|
|
|
2411
2470
|
import path5 from "node:path";
|
|
2412
2471
|
|
|
2413
2472
|
// src/commands/deploy/internal/apm-config.ts
|
|
2414
|
-
import { existsSync as existsSync11, readFileSync as
|
|
2473
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
|
|
2415
2474
|
import { resolve as resolve4 } from "node:path";
|
|
2416
2475
|
function loadApmConfig(options) {
|
|
2417
2476
|
const p = resolve4(
|
|
@@ -2423,7 +2482,7 @@ function loadApmConfig(options) {
|
|
|
2423
2482
|
process.exit(1);
|
|
2424
2483
|
}
|
|
2425
2484
|
try {
|
|
2426
|
-
const raw =
|
|
2485
|
+
const raw = readFileSync9(p, "utf8");
|
|
2427
2486
|
return JSON.parse(raw);
|
|
2428
2487
|
} catch (e) {
|
|
2429
2488
|
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
@@ -2545,7 +2604,7 @@ import path4 from "node:path";
|
|
|
2545
2604
|
import Docker from "dockerode";
|
|
2546
2605
|
|
|
2547
2606
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
2548
|
-
import { existsSync as existsSync12, readFileSync as
|
|
2607
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
2549
2608
|
import path from "node:path";
|
|
2550
2609
|
function asOptionalTlsBuffer(value) {
|
|
2551
2610
|
if (typeof value !== "string") {
|
|
@@ -2558,7 +2617,7 @@ function asOptionalTlsBuffer(value) {
|
|
|
2558
2617
|
return void 0;
|
|
2559
2618
|
}
|
|
2560
2619
|
if (existsSync12(normalized)) {
|
|
2561
|
-
return
|
|
2620
|
+
return readFileSync10(normalized);
|
|
2562
2621
|
}
|
|
2563
2622
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
2564
2623
|
if (looksLikePath) {
|
|
@@ -2768,7 +2827,7 @@ var DockerodeClient = class {
|
|
|
2768
2827
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
2769
2828
|
|
|
2770
2829
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
2771
|
-
import { existsSync as existsSync13, readFileSync as
|
|
2830
|
+
import { existsSync as existsSync13, readFileSync as readFileSync11, statSync as statSync5 } from "node:fs";
|
|
2772
2831
|
import path2 from "node:path";
|
|
2773
2832
|
function stripSurroundingQuotes(value) {
|
|
2774
2833
|
const t = value.trim();
|
|
@@ -2788,7 +2847,7 @@ function loadEnvFromFile(envFilePath) {
|
|
|
2788
2847
|
if (!existsSync13(targetPath) || !statSync5(targetPath).isFile()) {
|
|
2789
2848
|
return {};
|
|
2790
2849
|
}
|
|
2791
|
-
const raw =
|
|
2850
|
+
const raw = readFileSync11(targetPath, "utf-8");
|
|
2792
2851
|
const result = {};
|
|
2793
2852
|
for (const line of raw.split(/\r?\n/)) {
|
|
2794
2853
|
const normalized = line.trim();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-project-manage-cli",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.51",
|
|
4
4
|
"description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -27,9 +27,12 @@
|
|
|
27
27
|
"@types/ssh2-sftp-client": "~9.0.6"
|
|
28
28
|
},
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
30
|
+
"node": ">=22.13.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@bufbuild/protobuf": "1.10.0",
|
|
34
|
+
"@connectrpc/connect": "~1.7.0",
|
|
35
|
+
"@connectrpc/connect-node": "~1.7.0",
|
|
33
36
|
"@cursor/sdk": "~1.0.18",
|
|
34
37
|
"ws": "~8.18.0",
|
|
35
38
|
"listpage-http": "~0.0.318",
|