ai-project-manage-cli 5.0.11 → 5.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 +83 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -242,7 +242,7 @@ var requestConfig = {
|
|
|
242
242
|
|
|
243
243
|
// src/api/client.ts
|
|
244
244
|
function createApmApiClient(cfg) {
|
|
245
|
-
const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api`;
|
|
245
|
+
const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api/v1`;
|
|
246
246
|
return createApiClient(requestConfig, {
|
|
247
247
|
baseURL,
|
|
248
248
|
getToken: () => cfg.token || void 0,
|
|
@@ -281,7 +281,7 @@ async function runLogin(opts) {
|
|
|
281
281
|
const token = data?.token;
|
|
282
282
|
if (!userId || !token) {
|
|
283
283
|
console.error(
|
|
284
|
-
"[apm] \u54CD\u5E94\u7F3A\u5C11 user.id / token\uFF08\u8BF7\u786E\u8BA4\u670D\u52A1\u7AEF\u4E3A /api/auth/login\uFF09"
|
|
284
|
+
"[apm] \u54CD\u5E94\u7F3A\u5C11 user.id / token\uFF08\u8BF7\u786E\u8BA4\u670D\u52A1\u7AEF\u4E3A /api/v1/auth/login\uFF09"
|
|
285
285
|
);
|
|
286
286
|
process.exit(1);
|
|
287
287
|
}
|
|
@@ -499,12 +499,13 @@ function formatSessionMessagesXml(sessionId, messages) {
|
|
|
499
499
|
}
|
|
500
500
|
|
|
501
501
|
// src/commands/sync-session-attachments.ts
|
|
502
|
-
import { writeFileSync as writeFileSync3 } from "fs";
|
|
502
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
503
503
|
import { join as join4 } from "path";
|
|
504
|
+
var MANIFEST_FILE = ".sync-manifest.json";
|
|
504
505
|
async function downloadAttachment(cfg, sessionId, attachmentId) {
|
|
505
506
|
const base = cfg.baseUrl.trim().replace(/\/+$/, "");
|
|
506
507
|
const q = new URLSearchParams({ sessionId, attachmentId });
|
|
507
|
-
const url = `${base}/api/cli/attachments/file?${q.toString()}`;
|
|
508
|
+
const url = `${base}/api/v1/cli/attachments/file?${q.toString()}`;
|
|
508
509
|
const res = await fetch(url, {
|
|
509
510
|
headers: { Authorization: `Bearer ${cfg.token}` }
|
|
510
511
|
});
|
|
@@ -515,18 +516,65 @@ async function downloadAttachment(cfg, sessionId, attachmentId) {
|
|
|
515
516
|
}
|
|
516
517
|
return Buffer.from(await res.arrayBuffer());
|
|
517
518
|
}
|
|
519
|
+
function loadManifest(dir) {
|
|
520
|
+
const path8 = join4(dir, MANIFEST_FILE);
|
|
521
|
+
if (!existsSync2(path8)) {
|
|
522
|
+
return { version: 1, attachments: {} };
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
const parsed = JSON.parse(
|
|
526
|
+
readFileSync3(path8, "utf8")
|
|
527
|
+
);
|
|
528
|
+
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
529
|
+
return parsed;
|
|
530
|
+
}
|
|
531
|
+
} catch {
|
|
532
|
+
}
|
|
533
|
+
return { version: 1, attachments: {} };
|
|
534
|
+
}
|
|
535
|
+
function saveManifest(dir, manifest) {
|
|
536
|
+
writeFileSync3(
|
|
537
|
+
join4(dir, MANIFEST_FILE),
|
|
538
|
+
`${JSON.stringify(manifest, null, 2)}
|
|
539
|
+
`,
|
|
540
|
+
"utf8"
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
function isAttachmentUpToDate(entry, item, dest) {
|
|
544
|
+
if (!entry || !existsSync2(dest)) return false;
|
|
545
|
+
if (entry.name !== item.name) return false;
|
|
546
|
+
const createdAt = item.createdAt ?? "";
|
|
547
|
+
return entry.createdAt === createdAt;
|
|
548
|
+
}
|
|
518
549
|
async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
|
|
519
|
-
if (attachments.length === 0) return;
|
|
520
550
|
const dir = join4(sessionDir(sessionId, apmRoot), SESSION_ATTACHMENTS_SUBDIR);
|
|
521
551
|
await ensureDirExists(dir);
|
|
552
|
+
if (attachments.length === 0) {
|
|
553
|
+
saveManifest(dir, { version: 1, attachments: {} });
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
const manifest = loadManifest(dir);
|
|
557
|
+
const nextManifest = { version: 1, attachments: {} };
|
|
522
558
|
for (const item of attachments) {
|
|
523
559
|
const dest = join4(dir, item.name);
|
|
560
|
+
const entry = manifest.attachments[item.id];
|
|
561
|
+
const createdAt = item.createdAt ?? "";
|
|
562
|
+
if (isAttachmentUpToDate(entry, item, dest)) {
|
|
563
|
+
nextManifest.attachments[item.id] = entry;
|
|
564
|
+
console.log(
|
|
565
|
+
`[apm] \u9644\u4EF6\u65E0\u53D8\u5316\uFF0C\u5DF2\u8DF3\u8FC7: ${SESSION_ATTACHMENTS_SUBDIR}/${item.name}`
|
|
566
|
+
);
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
524
569
|
const buffer = await downloadAttachment(cfg, sessionId, item.id);
|
|
525
570
|
writeFileSync3(dest, buffer);
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
571
|
+
nextManifest.attachments[item.id] = {
|
|
572
|
+
name: item.name,
|
|
573
|
+
createdAt
|
|
574
|
+
};
|
|
575
|
+
console.log(`[apm] \u5DF2\u4E0B\u8F7D\u9644\u4EF6: ${SESSION_ATTACHMENTS_SUBDIR}/${item.name}`);
|
|
529
576
|
}
|
|
577
|
+
saveManifest(dir, nextManifest);
|
|
530
578
|
}
|
|
531
579
|
|
|
532
580
|
// src/commands/pull.ts
|
|
@@ -594,7 +642,7 @@ async function runPull(sessionId, apmRoot) {
|
|
|
594
642
|
import { spawnSync } from "child_process";
|
|
595
643
|
|
|
596
644
|
// src/version.ts
|
|
597
|
-
import { readFileSync as
|
|
645
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
598
646
|
import { dirname as dirname2, join as join6 } from "path";
|
|
599
647
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
600
648
|
var CLI_PACKAGE_NAME = "ai-project-manage-cli";
|
|
@@ -602,7 +650,7 @@ function readCliVersion() {
|
|
|
602
650
|
try {
|
|
603
651
|
const dir = dirname2(fileURLToPath2(import.meta.url));
|
|
604
652
|
const pkgPath = join6(dir, "..", "package.json");
|
|
605
|
-
const pkg = JSON.parse(
|
|
653
|
+
const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
|
|
606
654
|
return pkg.version ?? "0.0.0";
|
|
607
655
|
} catch {
|
|
608
656
|
return "0.0.0";
|
|
@@ -669,14 +717,14 @@ async function runUpdate() {
|
|
|
669
717
|
}
|
|
670
718
|
|
|
671
719
|
// src/commands/update-skills.ts
|
|
672
|
-
import { existsSync as
|
|
720
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, statSync as statSync3 } from "fs";
|
|
673
721
|
import { join as join8 } from "path";
|
|
674
722
|
|
|
675
723
|
// src/skills-sync.ts
|
|
676
724
|
import {
|
|
677
725
|
copyFileSync,
|
|
678
726
|
cpSync as cpSync2,
|
|
679
|
-
existsSync as
|
|
727
|
+
existsSync as existsSync3,
|
|
680
728
|
mkdirSync as mkdirSync3,
|
|
681
729
|
readdirSync as readdirSync2,
|
|
682
730
|
rmSync,
|
|
@@ -692,14 +740,14 @@ function sanitizeSkillDirName(name) {
|
|
|
692
740
|
return trimmed.replace(/[/\\:*?"<>|]/g, "_");
|
|
693
741
|
}
|
|
694
742
|
function listBaseSkillDirNames() {
|
|
695
|
-
if (!
|
|
743
|
+
if (!existsSync3(BASE_SKILLS_TEMPLATE_DIR)) return [];
|
|
696
744
|
return readdirSync2(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
|
|
697
745
|
const path8 = join7(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
698
746
|
return statSync2(path8).isDirectory();
|
|
699
747
|
});
|
|
700
748
|
}
|
|
701
749
|
function syncAgentsGuide(apmDir) {
|
|
702
|
-
if (!
|
|
750
|
+
if (!existsSync3(AGENTS_TEMPLATE_PATH)) return false;
|
|
703
751
|
mkdirSync3(apmDir, { recursive: true });
|
|
704
752
|
copyFileSync(AGENTS_TEMPLATE_PATH, join7(apmDir, "AGENTS.md"));
|
|
705
753
|
return true;
|
|
@@ -732,7 +780,7 @@ function syncSupplementarySkills(skillsDir, list) {
|
|
|
732
780
|
written.push(dirName);
|
|
733
781
|
}
|
|
734
782
|
const removed = [];
|
|
735
|
-
if (!
|
|
783
|
+
if (!existsSync3(skillsDir)) return { written, skipped, removed };
|
|
736
784
|
for (const entry of readdirSync2(skillsDir)) {
|
|
737
785
|
const full = join7(skillsDir, entry);
|
|
738
786
|
if (!statSync2(full).isDirectory()) continue;
|
|
@@ -747,7 +795,7 @@ function syncSupplementarySkills(skillsDir, list) {
|
|
|
747
795
|
// src/commands/update-skills.ts
|
|
748
796
|
async function runUpdateSkills() {
|
|
749
797
|
const apmDir = workspaceApmDir();
|
|
750
|
-
if (!
|
|
798
|
+
if (!existsSync4(apmDir)) {
|
|
751
799
|
console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
752
800
|
process.exit(1);
|
|
753
801
|
}
|
|
@@ -788,7 +836,7 @@ async function runUpdateSkills() {
|
|
|
788
836
|
}
|
|
789
837
|
|
|
790
838
|
// src/commands/sync-document.ts
|
|
791
|
-
import { existsSync as
|
|
839
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
792
840
|
async function runSyncDocument(sessionId, options) {
|
|
793
841
|
const trimmedSessionId = sessionId.trim();
|
|
794
842
|
if (!trimmedSessionId) {
|
|
@@ -801,7 +849,7 @@ async function runSyncDocument(sessionId, options) {
|
|
|
801
849
|
process.exit(1);
|
|
802
850
|
}
|
|
803
851
|
const absPath = resolveSessionDocumentPath(trimmedSessionId, fileArg);
|
|
804
|
-
if (!
|
|
852
|
+
if (!existsSync5(absPath)) {
|
|
805
853
|
const docsDir = sessionDocsDir(trimmedSessionId);
|
|
806
854
|
console.error(
|
|
807
855
|
`[apm] \u6587\u6863\u4E0D\u5B58\u5728: ${absPath}
|
|
@@ -809,7 +857,7 @@ async function runSyncDocument(sessionId, options) {
|
|
|
809
857
|
);
|
|
810
858
|
process.exit(1);
|
|
811
859
|
}
|
|
812
|
-
const content =
|
|
860
|
+
const content = readFileSync5(absPath, "utf8");
|
|
813
861
|
const name = documentPlatformName(absPath);
|
|
814
862
|
const cfg = await ensureLoggedConfig();
|
|
815
863
|
const api = createApmApiClient(cfg);
|
|
@@ -1158,19 +1206,19 @@ async function runConnect(options) {
|
|
|
1158
1206
|
import path5 from "node:path";
|
|
1159
1207
|
|
|
1160
1208
|
// src/commands/deploy/internal/apm-config.ts
|
|
1161
|
-
import { existsSync as
|
|
1209
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
|
|
1162
1210
|
import { resolve as resolve4 } from "node:path";
|
|
1163
1211
|
function loadApmConfig(options) {
|
|
1164
1212
|
const p = resolve4(
|
|
1165
1213
|
process.cwd(),
|
|
1166
1214
|
options?.configPath ?? resolve4(workspaceApmDir(), "apm.config.json")
|
|
1167
1215
|
);
|
|
1168
|
-
if (!
|
|
1216
|
+
if (!existsSync6(p)) {
|
|
1169
1217
|
console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
|
|
1170
1218
|
process.exit(1);
|
|
1171
1219
|
}
|
|
1172
1220
|
try {
|
|
1173
|
-
const raw =
|
|
1221
|
+
const raw = readFileSync6(p, "utf8");
|
|
1174
1222
|
return JSON.parse(raw);
|
|
1175
1223
|
} catch (e) {
|
|
1176
1224
|
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
@@ -1267,7 +1315,7 @@ import path4 from "node:path";
|
|
|
1267
1315
|
import Docker from "dockerode";
|
|
1268
1316
|
|
|
1269
1317
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
1270
|
-
import { existsSync as
|
|
1318
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
1271
1319
|
import path from "node:path";
|
|
1272
1320
|
function asOptionalTlsBuffer(value) {
|
|
1273
1321
|
if (typeof value !== "string") {
|
|
@@ -1279,8 +1327,8 @@ function asOptionalTlsBuffer(value) {
|
|
|
1279
1327
|
if (normalized === "") {
|
|
1280
1328
|
return void 0;
|
|
1281
1329
|
}
|
|
1282
|
-
if (
|
|
1283
|
-
return
|
|
1330
|
+
if (existsSync7(normalized)) {
|
|
1331
|
+
return readFileSync7(normalized);
|
|
1284
1332
|
}
|
|
1285
1333
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
1286
1334
|
if (looksLikePath) {
|
|
@@ -1490,7 +1538,7 @@ var DockerodeClient = class {
|
|
|
1490
1538
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
1491
1539
|
|
|
1492
1540
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
1493
|
-
import { existsSync as
|
|
1541
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync4 } from "node:fs";
|
|
1494
1542
|
import path2 from "node:path";
|
|
1495
1543
|
function stripSurroundingQuotes(value) {
|
|
1496
1544
|
const t = value.trim();
|
|
@@ -1507,10 +1555,10 @@ function loadEnvFromFile(envFilePath) {
|
|
|
1507
1555
|
return {};
|
|
1508
1556
|
}
|
|
1509
1557
|
const targetPath = path2.resolve(envFilePath);
|
|
1510
|
-
if (!
|
|
1558
|
+
if (!existsSync8(targetPath) || !statSync4(targetPath).isFile()) {
|
|
1511
1559
|
return {};
|
|
1512
1560
|
}
|
|
1513
|
-
const raw =
|
|
1561
|
+
const raw = readFileSync8(targetPath, "utf-8");
|
|
1514
1562
|
const result = {};
|
|
1515
1563
|
for (const line of raw.split(/\r?\n/)) {
|
|
1516
1564
|
const normalized = line.trim();
|
|
@@ -1681,12 +1729,12 @@ function dockerPushImage(params, cwd) {
|
|
|
1681
1729
|
}
|
|
1682
1730
|
|
|
1683
1731
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
1684
|
-
import { existsSync as
|
|
1732
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
1685
1733
|
import path3 from "node:path";
|
|
1686
1734
|
function resolveDockerBuildPaths(cwd) {
|
|
1687
1735
|
const dockerfilePath = path3.join(cwd, "Dockerfile");
|
|
1688
1736
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
1689
|
-
if (!
|
|
1737
|
+
if (!existsSync9(dockerfilePath)) {
|
|
1690
1738
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
1691
1739
|
}
|
|
1692
1740
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|
|
@@ -1815,16 +1863,16 @@ import { copyFile, readdir as readdir2, stat } from "node:fs/promises";
|
|
|
1815
1863
|
import path7 from "node:path";
|
|
1816
1864
|
|
|
1817
1865
|
// src/commands/deploy/internal/load-apm-dotenv.ts
|
|
1818
|
-
import { existsSync as
|
|
1866
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "node:fs";
|
|
1819
1867
|
import { join as join9 } from "node:path";
|
|
1820
1868
|
function loadApmDotEnvIfPresent() {
|
|
1821
1869
|
const p = join9(workspaceApmDir(), ".env");
|
|
1822
|
-
if (!
|
|
1870
|
+
if (!existsSync10(p)) {
|
|
1823
1871
|
return;
|
|
1824
1872
|
}
|
|
1825
1873
|
let text;
|
|
1826
1874
|
try {
|
|
1827
|
-
text =
|
|
1875
|
+
text = readFileSync9(p, "utf8");
|
|
1828
1876
|
} catch {
|
|
1829
1877
|
return;
|
|
1830
1878
|
}
|
|
@@ -2186,7 +2234,7 @@ function buildProgram() {
|
|
|
2186
2234
|
\u672A\u4F20 --server \u65F6\u4F18\u5148\u4F7F\u7528\u73AF\u5883\u53D8\u91CF AI_PM_SERVER\uFF0C\u5426\u5219\u9ED8\u8BA4 ${DEFAULT_BASE_URL}\u3002`
|
|
2187
2235
|
).version(readCliVersion(), "-V, --version", "\u663E\u793A\u7248\u672C\u53F7").helpOption("-h, --help", "\u663E\u793A\u5E2E\u52A9").showHelpAfterError(true);
|
|
2188
2236
|
program.command("login").description(
|
|
2189
|
-
"\u8C03\u7528 POST /api/auth/login\uFF0C\u5C06 token \u5199\u5165 ~/.config/apm/config.json"
|
|
2237
|
+
"\u8C03\u7528 POST /api/v1/auth/login\uFF0C\u5C06 token \u5199\u5165 ~/.config/apm/config.json"
|
|
2190
2238
|
).requiredOption("--email <\u90AE\u7BB1>", "\u767B\u5F55\u90AE\u7BB1").requiredOption("--password <\u5BC6\u7801>", "\u767B\u5F55\u5BC6\u7801").option("--server <url>", "API \u6839\u5730\u5740\uFF0C\u4F8B\u5982 http://127.0.0.1:3000").action(
|
|
2191
2239
|
async (opts) => {
|
|
2192
2240
|
await runLogin(opts);
|
|
@@ -2216,7 +2264,7 @@ function buildProgram() {
|
|
|
2216
2264
|
).action(async (sessionId, opts) => {
|
|
2217
2265
|
await runSyncDocument(sessionId, { file: opts.file });
|
|
2218
2266
|
});
|
|
2219
|
-
program.command("append-message").description("\u5411\u5E73\u53F0\u4F1A\u8BDD\u6D88\u606F\u8FFD\u52A0\u5185\u5BB9\uFF08PUT /api/cli/messages/content\uFF09").requiredOption("--id <messageId>", "\u6D88\u606F ID").requiredOption("--content <content>", "\u8981\u8FFD\u52A0\u7684\u6D88\u606F\u5185\u5BB9").action(async (opts) => {
|
|
2267
|
+
program.command("append-message").description("\u5411\u5E73\u53F0\u4F1A\u8BDD\u6D88\u606F\u8FFD\u52A0\u5185\u5BB9\uFF08PUT /api/v1/cli/messages/content\uFF09").requiredOption("--id <messageId>", "\u6D88\u606F ID").requiredOption("--content <content>", "\u8981\u8FFD\u52A0\u7684\u6D88\u606F\u5185\u5BB9").action(async (opts) => {
|
|
2220
2268
|
await runAppendMessage(opts);
|
|
2221
2269
|
});
|
|
2222
2270
|
program.command("update-message-status").description("\u66F4\u65B0\u5E73\u53F0\u4F1A\u8BDD\u6D88\u606F\u72B6\u6001").requiredOption("--id <messageId>", "\u6D88\u606F ID").requiredOption("--status <status>", "CREATED | TYPING | SUCCESS | FAILED").action(async (opts) => {
|