ai-project-manage-cli 7.1.17 → 7.1.19
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 +706 -317
- package/dist/webide-message-worker.js +164 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -333,13 +333,13 @@ var init_client = __esm({
|
|
|
333
333
|
});
|
|
334
334
|
|
|
335
335
|
// src/commands/deploy/internal/minio.ts
|
|
336
|
-
import { statSync as
|
|
336
|
+
import { statSync as statSync6 } from "node:fs";
|
|
337
337
|
import { readdir, readFile } from "node:fs/promises";
|
|
338
338
|
import path from "node:path";
|
|
339
339
|
import * as Minio from "minio";
|
|
340
340
|
async function isDirectoryPath(dir) {
|
|
341
341
|
try {
|
|
342
|
-
const st =
|
|
342
|
+
const st = statSync6(dir);
|
|
343
343
|
return st.isDirectory();
|
|
344
344
|
} catch {
|
|
345
345
|
return false;
|
|
@@ -369,7 +369,7 @@ async function collectFiles(root) {
|
|
|
369
369
|
if (e.isDirectory()) {
|
|
370
370
|
await walk(abs, rel);
|
|
371
371
|
} else if (e.isFile()) {
|
|
372
|
-
const st =
|
|
372
|
+
const st = statSync6(abs);
|
|
373
373
|
out.push({
|
|
374
374
|
absPath: abs,
|
|
375
375
|
relativePath: rel.replace(/\\/g, "/"),
|
|
@@ -436,14 +436,14 @@ var init_minio = __esm({
|
|
|
436
436
|
async deleteObjectsByPrefix(bucket, prefix) {
|
|
437
437
|
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
438
438
|
const keys = [];
|
|
439
|
-
await new Promise((
|
|
439
|
+
await new Promise((resolve8, reject) => {
|
|
440
440
|
objectsStream.on("data", (obj) => {
|
|
441
441
|
if (obj.name) {
|
|
442
442
|
keys.push(obj.name);
|
|
443
443
|
}
|
|
444
444
|
});
|
|
445
445
|
objectsStream.on("error", reject);
|
|
446
|
-
objectsStream.on("end",
|
|
446
|
+
objectsStream.on("end", resolve8);
|
|
447
447
|
});
|
|
448
448
|
const chunkSize = 500;
|
|
449
449
|
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
@@ -1099,8 +1099,8 @@ import { Command } from "commander";
|
|
|
1099
1099
|
init_config();
|
|
1100
1100
|
|
|
1101
1101
|
// src/commands/init.ts
|
|
1102
|
-
import { join as
|
|
1103
|
-
import { readFileSync as
|
|
1102
|
+
import { join as join6 } from "path";
|
|
1103
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
1104
1104
|
|
|
1105
1105
|
// src/command-utils.ts
|
|
1106
1106
|
init_config();
|
|
@@ -1388,13 +1388,43 @@ async function copyTemplateFiles(targetDir, workdir = resolveWorkdirPath()) {
|
|
|
1388
1388
|
|
|
1389
1389
|
// src/deployment-config-sync.ts
|
|
1390
1390
|
init_client();
|
|
1391
|
-
import { join as
|
|
1392
|
-
import { writeFileSync as
|
|
1391
|
+
import { join as join4 } from "path";
|
|
1392
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1393
1393
|
|
|
1394
1394
|
// src/git-remote.ts
|
|
1395
1395
|
import { execFile } from "child_process";
|
|
1396
1396
|
import { promisify } from "util";
|
|
1397
1397
|
var execFileAsync = promisify(execFile);
|
|
1398
|
+
function toHttpsGitRemoteUrl(raw) {
|
|
1399
|
+
let s = raw.trim();
|
|
1400
|
+
if (!s) return null;
|
|
1401
|
+
const sshScp = /^git@([^:]+):(.+)$/.exec(s);
|
|
1402
|
+
if (sshScp) {
|
|
1403
|
+
s = `https://${sshScp[1]}/${sshScp[2]}`;
|
|
1404
|
+
} else {
|
|
1405
|
+
const sshUri = /^ssh:\/\/(?:git@)?([^/]+)\/(.+)$/i.exec(s);
|
|
1406
|
+
if (sshUri) {
|
|
1407
|
+
s = `https://${sshUri[1]}/${sshUri[2]}`;
|
|
1408
|
+
} else if (/^http:\/\//i.test(s)) {
|
|
1409
|
+
s = `https://${s.slice("http://".length)}`;
|
|
1410
|
+
} else if (!/^https:\/\//i.test(s)) {
|
|
1411
|
+
const scpLike = /^([^/:]+):(.+)$/.exec(s);
|
|
1412
|
+
if (scpLike && !scpLike[1].includes(".")) {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
if (scpLike) {
|
|
1416
|
+
s = `https://${scpLike[1]}/${scpLike[2]}`;
|
|
1417
|
+
} else if (s.includes("/")) {
|
|
1418
|
+
s = `https://${s}`;
|
|
1419
|
+
} else {
|
|
1420
|
+
return null;
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
s = s.replace(/\/+$/, "");
|
|
1425
|
+
if (!/^https:\/\//i.test(s)) return null;
|
|
1426
|
+
return s;
|
|
1427
|
+
}
|
|
1398
1428
|
async function tryReadGitOriginUrl(cwd) {
|
|
1399
1429
|
try {
|
|
1400
1430
|
const { stdout } = await execFileAsync(
|
|
@@ -1408,6 +1438,11 @@ async function tryReadGitOriginUrl(cwd) {
|
|
|
1408
1438
|
return null;
|
|
1409
1439
|
}
|
|
1410
1440
|
}
|
|
1441
|
+
async function tryReadHttpsGitOriginUrl(cwd) {
|
|
1442
|
+
const raw = await tryReadGitOriginUrl(cwd);
|
|
1443
|
+
if (!raw) return null;
|
|
1444
|
+
return toHttpsGitRemoteUrl(raw);
|
|
1445
|
+
}
|
|
1411
1446
|
|
|
1412
1447
|
// src/git-utils.ts
|
|
1413
1448
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -1470,6 +1505,24 @@ async function ensureRemoteBaselineBranch(cwd, baselineBranch) {
|
|
|
1470
1505
|
`[apm] \u8FDC\u7A0B\u4E0D\u5B58\u5728\u57FA\u7EBF\u5206\u652F origin/${baselineBranch}\uFF0C\u8BF7\u786E\u8BA4\u4ED3\u5E93\u9ED8\u8BA4\u5206\u652F\u5DF2\u63A8\u9001\u5230 origin`
|
|
1471
1506
|
);
|
|
1472
1507
|
}
|
|
1508
|
+
async function resolveDefaultRemoteBranch(cwd) {
|
|
1509
|
+
try {
|
|
1510
|
+
const ref = (await execGit(cwd, ["symbolic-ref", "refs/remotes/origin/HEAD"], true)).trim();
|
|
1511
|
+
const match = ref.match(/^refs\/remotes\/origin\/(.+)$/);
|
|
1512
|
+
if (match?.[1]) {
|
|
1513
|
+
return match[1];
|
|
1514
|
+
}
|
|
1515
|
+
} catch {
|
|
1516
|
+
}
|
|
1517
|
+
for (const candidate of ["main", "master"]) {
|
|
1518
|
+
if (await remoteBranchExists(cwd, candidate)) {
|
|
1519
|
+
return candidate;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
throw new Error(
|
|
1523
|
+
"[apm] \u65E0\u6CD5\u786E\u5B9A\u8FDC\u7A0B\u9ED8\u8BA4\u5206\u652F\uFF08origin/HEAD\u3001main\u3001master \u5747\u4E0D\u53EF\u7528\uFF09"
|
|
1524
|
+
);
|
|
1525
|
+
}
|
|
1473
1526
|
async function hasUpstream(cwd) {
|
|
1474
1527
|
try {
|
|
1475
1528
|
await execGit(cwd, ["rev-parse", "--abbrev-ref", "@{upstream}"], true);
|
|
@@ -1596,6 +1649,162 @@ async function resolveBranchBaseline(api, sessionId, workdirPath) {
|
|
|
1596
1649
|
|
|
1597
1650
|
// src/deployment-config-sync.ts
|
|
1598
1651
|
init_config();
|
|
1652
|
+
|
|
1653
|
+
// src/workspace-repos.ts
|
|
1654
|
+
import {
|
|
1655
|
+
existsSync as existsSync2,
|
|
1656
|
+
mkdirSync as mkdirSync3,
|
|
1657
|
+
readFileSync as readFileSync3,
|
|
1658
|
+
readdirSync as readdirSync2,
|
|
1659
|
+
statSync as statSync2,
|
|
1660
|
+
writeFileSync as writeFileSync3
|
|
1661
|
+
} from "fs";
|
|
1662
|
+
import { basename as basename2, dirname as dirname2, join as join3, relative, resolve as resolve3 } from "path";
|
|
1663
|
+
var WORKSPACE_REPOS_MANIFEST = "workspace-repos.json";
|
|
1664
|
+
var WORKSPACE_REPOS_VERSION = 1;
|
|
1665
|
+
function manifestPath(workdir) {
|
|
1666
|
+
return join3(workspaceApmDir(workdir), WORKSPACE_REPOS_MANIFEST);
|
|
1667
|
+
}
|
|
1668
|
+
function absoluteRepoPath(workdir, entry) {
|
|
1669
|
+
if (entry.path === "." || entry.path === "") {
|
|
1670
|
+
return workdir;
|
|
1671
|
+
}
|
|
1672
|
+
return resolve3(workdir, entry.path);
|
|
1673
|
+
}
|
|
1674
|
+
function normalizeRepoEntry(raw) {
|
|
1675
|
+
if (!raw || typeof raw !== "object") return null;
|
|
1676
|
+
const o = raw;
|
|
1677
|
+
if (typeof o.path !== "string" || !o.path.trim()) return null;
|
|
1678
|
+
const entry = {
|
|
1679
|
+
path: o.path.trim().replace(/\\/g, "/")
|
|
1680
|
+
};
|
|
1681
|
+
if (typeof o.remoteUrl === "string" && o.remoteUrl.trim()) {
|
|
1682
|
+
entry.remoteUrl = o.remoteUrl.trim();
|
|
1683
|
+
} else if (o.remoteUrl === null) {
|
|
1684
|
+
entry.remoteUrl = null;
|
|
1685
|
+
}
|
|
1686
|
+
return entry;
|
|
1687
|
+
}
|
|
1688
|
+
function readManifest(workdir) {
|
|
1689
|
+
const path19 = toFsPath(manifestPath(workdir));
|
|
1690
|
+
if (!existsSync2(path19)) {
|
|
1691
|
+
return null;
|
|
1692
|
+
}
|
|
1693
|
+
try {
|
|
1694
|
+
const raw = JSON.parse(
|
|
1695
|
+
readFileSync3(path19, "utf8")
|
|
1696
|
+
);
|
|
1697
|
+
if (raw?.version !== WORKSPACE_REPOS_VERSION) {
|
|
1698
|
+
return null;
|
|
1699
|
+
}
|
|
1700
|
+
if (raw.kind !== "single" && raw.kind !== "multi") {
|
|
1701
|
+
return null;
|
|
1702
|
+
}
|
|
1703
|
+
if (!Array.isArray(raw.repos) || raw.repos.length === 0) {
|
|
1704
|
+
return null;
|
|
1705
|
+
}
|
|
1706
|
+
if (typeof raw.workdir !== "string" || !raw.workdir.trim()) {
|
|
1707
|
+
return null;
|
|
1708
|
+
}
|
|
1709
|
+
const repos = raw.repos.map((item) => normalizeRepoEntry(item)).filter((item) => item != null);
|
|
1710
|
+
if (repos.length === 0) {
|
|
1711
|
+
return null;
|
|
1712
|
+
}
|
|
1713
|
+
return {
|
|
1714
|
+
version: WORKSPACE_REPOS_VERSION,
|
|
1715
|
+
kind: raw.kind,
|
|
1716
|
+
workdir: raw.workdir,
|
|
1717
|
+
repos,
|
|
1718
|
+
scannedAt: typeof raw.scannedAt === "string" && raw.scannedAt.trim() ? raw.scannedAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
1719
|
+
};
|
|
1720
|
+
} catch {
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
function writeManifest(workdir, manifest) {
|
|
1725
|
+
const apmDir = toFsPath(workspaceApmDir(workdir));
|
|
1726
|
+
mkdirSync3(apmDir, { recursive: true });
|
|
1727
|
+
const path19 = toFsPath(manifestPath(workdir));
|
|
1728
|
+
writeFileSync3(path19, `${JSON.stringify(manifest, null, 2)}
|
|
1729
|
+
`, "utf8");
|
|
1730
|
+
}
|
|
1731
|
+
function isPathInsideOrEqual(parentAbs, childAbs) {
|
|
1732
|
+
const parent = normalizeWorkdirPath(parentAbs);
|
|
1733
|
+
const child = normalizeWorkdirPath(childAbs);
|
|
1734
|
+
if (child === parent) return true;
|
|
1735
|
+
const prefix = parent.endsWith("/") ? parent : `${parent}/`;
|
|
1736
|
+
return child.startsWith(prefix);
|
|
1737
|
+
}
|
|
1738
|
+
function findWorkspaceReposManifestNearPath(startDirInput) {
|
|
1739
|
+
let current = resolve3(startDirInput);
|
|
1740
|
+
for (; ; ) {
|
|
1741
|
+
const candidates = /* @__PURE__ */ new Set([normalizeWorkdirPath(current)]);
|
|
1742
|
+
try {
|
|
1743
|
+
if (existsSync2(toFsPath(current))) {
|
|
1744
|
+
candidates.add(resolveWorkdirPath(current));
|
|
1745
|
+
}
|
|
1746
|
+
} catch {
|
|
1747
|
+
}
|
|
1748
|
+
for (const candidate of candidates) {
|
|
1749
|
+
const cached = readManifest(candidate);
|
|
1750
|
+
if (!cached) continue;
|
|
1751
|
+
const cachedWorkdir = resolveWorkdirPath(cached.workdir);
|
|
1752
|
+
const candidateNorm = resolveWorkdirPath(candidate);
|
|
1753
|
+
if (cachedWorkdir === candidateNorm) {
|
|
1754
|
+
return { ...cached, workdir: cachedWorkdir };
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
const parent = dirname2(current);
|
|
1758
|
+
if (parent === current) {
|
|
1759
|
+
return null;
|
|
1760
|
+
}
|
|
1761
|
+
current = parent;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
function matchWorkspaceRepoEntryForPath(manifest, pathInput) {
|
|
1765
|
+
const target = resolveWorkdirPath(pathInput);
|
|
1766
|
+
const workdir = resolveWorkdirPath(manifest.workdir);
|
|
1767
|
+
let best = null;
|
|
1768
|
+
let bestLen = -1;
|
|
1769
|
+
for (const entry of manifest.repos) {
|
|
1770
|
+
const abs = resolveWorkdirPath(absoluteRepoPath(workdir, entry));
|
|
1771
|
+
if (!isPathInsideOrEqual(abs, target)) {
|
|
1772
|
+
continue;
|
|
1773
|
+
}
|
|
1774
|
+
if (abs.length > bestLen) {
|
|
1775
|
+
best = entry;
|
|
1776
|
+
bestLen = abs.length;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
return best;
|
|
1780
|
+
}
|
|
1781
|
+
async function enrichWorkspaceReposRemoteUrls(manifest) {
|
|
1782
|
+
let changed = false;
|
|
1783
|
+
const repos = [];
|
|
1784
|
+
for (const entry of manifest.repos) {
|
|
1785
|
+
const abs = absoluteRepoPath(manifest.workdir, entry);
|
|
1786
|
+
const remoteUrl = await tryReadHttpsGitOriginUrl(abs);
|
|
1787
|
+
const next = {
|
|
1788
|
+
path: entry.path,
|
|
1789
|
+
remoteUrl: remoteUrl || null
|
|
1790
|
+
};
|
|
1791
|
+
if ((entry.remoteUrl ?? null) !== next.remoteUrl) {
|
|
1792
|
+
changed = true;
|
|
1793
|
+
}
|
|
1794
|
+
repos.push(next);
|
|
1795
|
+
}
|
|
1796
|
+
const nextManifest = {
|
|
1797
|
+
...manifest,
|
|
1798
|
+
repos,
|
|
1799
|
+
scannedAt: changed ? (/* @__PURE__ */ new Date()).toISOString() : manifest.scannedAt
|
|
1800
|
+
};
|
|
1801
|
+
if (changed) {
|
|
1802
|
+
writeManifest(manifest.workdir, nextManifest);
|
|
1803
|
+
}
|
|
1804
|
+
return nextManifest;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
// src/deployment-config-sync.ts
|
|
1599
1808
|
var TEMPLATE_HINT = "\u4FDD\u7559\u6A21\u677F .apm/apm.config.json";
|
|
1600
1809
|
var SYNC_HINT = "\u767B\u8BB0\u5DE5\u4F5C\u7A7A\u95F4\u8DEF\u5F84\u3001\u7ED1\u5B9A\u4ED3\u5E93\u540E\uFF0C\u53EF\u6267\u884C: apm sync-deploy-config";
|
|
1601
1810
|
async function resolveRepositoryIdForSync(api, workdirPath) {
|
|
@@ -1610,7 +1819,73 @@ async function resolveRepositoryIdForSync(api, workdirPath) {
|
|
|
1610
1819
|
};
|
|
1611
1820
|
}
|
|
1612
1821
|
}
|
|
1613
|
-
async function
|
|
1822
|
+
async function resolveDeployCwdForRepository(workspaceRoot, repositoryId, api) {
|
|
1823
|
+
const start = resolveWorkdirPath(workspaceRoot);
|
|
1824
|
+
let manifest = findWorkspaceReposManifestNearPath(start);
|
|
1825
|
+
if (!manifest) {
|
|
1826
|
+
return null;
|
|
1827
|
+
}
|
|
1828
|
+
try {
|
|
1829
|
+
manifest = await enrichWorkspaceReposRemoteUrls(manifest);
|
|
1830
|
+
} catch {
|
|
1831
|
+
return null;
|
|
1832
|
+
}
|
|
1833
|
+
let client = api;
|
|
1834
|
+
if (!client) {
|
|
1835
|
+
const cfg = await tryReadApmConfig();
|
|
1836
|
+
if (!cfg || !resolveApiKey(cfg)) {
|
|
1837
|
+
return null;
|
|
1838
|
+
}
|
|
1839
|
+
client = createApmApiClient(cfg);
|
|
1840
|
+
}
|
|
1841
|
+
for (const entry of manifest.repos) {
|
|
1842
|
+
const abs = absoluteRepoPath(manifest.workdir, entry);
|
|
1843
|
+
const remoteUrl = toHttpsGitRemoteUrl(entry.remoteUrl ?? "");
|
|
1844
|
+
if (!remoteUrl) {
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1847
|
+
let baseBranch = "";
|
|
1848
|
+
try {
|
|
1849
|
+
const gitRoot = await resolveGitRepoRoot(abs);
|
|
1850
|
+
baseBranch = (await resolveDefaultRemoteBranch(gitRoot)).trim();
|
|
1851
|
+
} catch {
|
|
1852
|
+
continue;
|
|
1853
|
+
}
|
|
1854
|
+
if (!baseBranch) {
|
|
1855
|
+
continue;
|
|
1856
|
+
}
|
|
1857
|
+
try {
|
|
1858
|
+
const matched = await client.cli.matchRepository({
|
|
1859
|
+
url: remoteUrl,
|
|
1860
|
+
baseBranch
|
|
1861
|
+
});
|
|
1862
|
+
if (matched.repositoryId?.trim() === repositoryId) {
|
|
1863
|
+
return abs;
|
|
1864
|
+
}
|
|
1865
|
+
} catch {
|
|
1866
|
+
continue;
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
return null;
|
|
1870
|
+
}
|
|
1871
|
+
async function writeDeploymentConfigContent(apmDir, content, configName) {
|
|
1872
|
+
let parsed;
|
|
1873
|
+
try {
|
|
1874
|
+
parsed = JSON.parse(content);
|
|
1875
|
+
} catch {
|
|
1876
|
+
console.warn(
|
|
1877
|
+
`[apm] \u8FDC\u7A0B\u90E8\u7F72\u914D\u7F6E\u300C${configName}\u300DJSON \u65E0\u6548\uFF08${TEMPLATE_HINT}\uFF09`
|
|
1878
|
+
);
|
|
1879
|
+
return false;
|
|
1880
|
+
}
|
|
1881
|
+
const apmConfigPath = toFsPath(join4(apmDir, "apm.config.json"));
|
|
1882
|
+
writeFileSync4(apmConfigPath, `${JSON.stringify(parsed, null, 2)}
|
|
1883
|
+
`, "utf8");
|
|
1884
|
+
console.log(`[apm] \u5DF2\u540C\u6B65\u5E73\u53F0\u90E8\u7F72\u914D\u7F6E: ${configName}`);
|
|
1885
|
+
console.log("[apm] \u5DF2\u5199\u5165 .apm/apm.config.json");
|
|
1886
|
+
return true;
|
|
1887
|
+
}
|
|
1888
|
+
async function syncRemoteDeploymentConfig(workdirPath, apmDir, options) {
|
|
1614
1889
|
const cfg = await tryReadApmConfig();
|
|
1615
1890
|
if (!cfg || !resolveApiKey(cfg)) {
|
|
1616
1891
|
console.log(
|
|
@@ -1620,10 +1895,14 @@ async function syncRemoteDeploymentConfig(workdirPath, apmDir) {
|
|
|
1620
1895
|
return { synced: false, repositoryId: null };
|
|
1621
1896
|
}
|
|
1622
1897
|
const api = createApmApiClient(cfg);
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
)
|
|
1898
|
+
const preferredId = options?.repositoryId?.trim() || "";
|
|
1899
|
+
let repositoryId = preferredId || null;
|
|
1900
|
+
let diagnostic = null;
|
|
1901
|
+
if (!repositoryId) {
|
|
1902
|
+
const resolved = await resolveRepositoryIdForSync(api, workdirPath);
|
|
1903
|
+
repositoryId = resolved.repositoryId;
|
|
1904
|
+
diagnostic = resolved.diagnostic;
|
|
1905
|
+
}
|
|
1627
1906
|
if (!repositoryId) {
|
|
1628
1907
|
console.log(
|
|
1629
1908
|
`[apm] \u672A\u80FD\u540C\u6B65\u5E73\u53F0\u90E8\u7F72\u914D\u7F6E\uFF08${TEMPLATE_HINT}\uFF09\u3002
|
|
@@ -1640,21 +1919,15 @@ ${diagnostic ?? ""}
|
|
|
1640
1919
|
);
|
|
1641
1920
|
return { synced: false, repositoryId };
|
|
1642
1921
|
}
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1922
|
+
const targetApmDir = apmDir ?? workspaceApmDir(workdirPath);
|
|
1923
|
+
const wrote = await writeDeploymentConfigContent(
|
|
1924
|
+
targetApmDir,
|
|
1925
|
+
config.content,
|
|
1926
|
+
config.name
|
|
1927
|
+
);
|
|
1928
|
+
if (!wrote) {
|
|
1650
1929
|
return { synced: false, repositoryId };
|
|
1651
1930
|
}
|
|
1652
|
-
const targetApmDir = apmDir ?? workspaceApmDir(workdirPath);
|
|
1653
|
-
const apmConfigPath = toFsPath(join3(targetApmDir, "apm.config.json"));
|
|
1654
|
-
writeFileSync3(apmConfigPath, `${JSON.stringify(parsed, null, 2)}
|
|
1655
|
-
`, "utf8");
|
|
1656
|
-
console.log(`[apm] \u5DF2\u540C\u6B65\u5E73\u53F0\u90E8\u7F72\u914D\u7F6E: ${config.name}`);
|
|
1657
|
-
console.log("[apm] \u5DF2\u5199\u5165 .apm/apm.config.json");
|
|
1658
1931
|
return { synced: true, repositoryId, configName: config.name };
|
|
1659
1932
|
}
|
|
1660
1933
|
|
|
@@ -1662,14 +1935,14 @@ ${diagnostic ?? ""}
|
|
|
1662
1935
|
init_client();
|
|
1663
1936
|
init_config();
|
|
1664
1937
|
import {
|
|
1665
|
-
existsSync as
|
|
1666
|
-
readdirSync as
|
|
1667
|
-
readFileSync as
|
|
1938
|
+
existsSync as existsSync3,
|
|
1939
|
+
readdirSync as readdirSync3,
|
|
1940
|
+
readFileSync as readFileSync4,
|
|
1668
1941
|
rmSync,
|
|
1669
|
-
writeFileSync as
|
|
1942
|
+
writeFileSync as writeFileSync5
|
|
1670
1943
|
} from "fs";
|
|
1671
1944
|
import { createHash } from "crypto";
|
|
1672
|
-
import { dirname as
|
|
1945
|
+
import { dirname as dirname3, join as join5, relative as relative2, sep } from "path";
|
|
1673
1946
|
var MANIFEST_FILE = "manifest.json";
|
|
1674
1947
|
function normalizeProjectIdForPath(projectId) {
|
|
1675
1948
|
const id = projectId.trim();
|
|
@@ -1683,11 +1956,11 @@ function normalizeProjectIdForPath(projectId) {
|
|
|
1683
1956
|
}
|
|
1684
1957
|
function projectDocumentsDir(apmRoot, projectId) {
|
|
1685
1958
|
const id = normalizeProjectIdForPath(projectId);
|
|
1686
|
-
return
|
|
1959
|
+
return join5(apmRoot ?? workspaceApmDir(), "project", id);
|
|
1687
1960
|
}
|
|
1688
1961
|
function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
1689
1962
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
1690
|
-
return
|
|
1963
|
+
return join5(
|
|
1691
1964
|
projectDocumentsDir(apmRoot, projectId),
|
|
1692
1965
|
...normalized.split("/")
|
|
1693
1966
|
);
|
|
@@ -1707,16 +1980,16 @@ function hashLocalFileContent(content) {
|
|
|
1707
1980
|
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
1708
1981
|
}
|
|
1709
1982
|
function readLocalManifest(apmRoot, projectId) {
|
|
1710
|
-
const
|
|
1983
|
+
const manifestPath3 = join5(
|
|
1711
1984
|
projectDocumentsDir(apmRoot, projectId),
|
|
1712
1985
|
MANIFEST_FILE
|
|
1713
1986
|
);
|
|
1714
|
-
if (!
|
|
1987
|
+
if (!existsSync3(manifestPath3)) {
|
|
1715
1988
|
return null;
|
|
1716
1989
|
}
|
|
1717
1990
|
try {
|
|
1718
1991
|
return JSON.parse(
|
|
1719
|
-
|
|
1992
|
+
readFileSync4(manifestPath3, "utf8")
|
|
1720
1993
|
);
|
|
1721
1994
|
} catch {
|
|
1722
1995
|
return null;
|
|
@@ -1724,13 +1997,13 @@ function readLocalManifest(apmRoot, projectId) {
|
|
|
1724
1997
|
}
|
|
1725
1998
|
function listLocalDocumentPaths(apmRoot, projectId) {
|
|
1726
1999
|
const root = projectDocumentsDir(apmRoot, projectId);
|
|
1727
|
-
if (!
|
|
2000
|
+
if (!existsSync3(root)) {
|
|
1728
2001
|
return [];
|
|
1729
2002
|
}
|
|
1730
2003
|
const paths = [];
|
|
1731
2004
|
const walk = (dir) => {
|
|
1732
|
-
for (const entry of
|
|
1733
|
-
const abs =
|
|
2005
|
+
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
2006
|
+
const abs = join5(dir, entry.name);
|
|
1734
2007
|
if (entry.isDirectory()) {
|
|
1735
2008
|
walk(abs);
|
|
1736
2009
|
continue;
|
|
@@ -1738,7 +2011,7 @@ function listLocalDocumentPaths(apmRoot, projectId) {
|
|
|
1738
2011
|
if (entry.isFile() && entry.name === MANIFEST_FILE) {
|
|
1739
2012
|
continue;
|
|
1740
2013
|
}
|
|
1741
|
-
const rel =
|
|
2014
|
+
const rel = relative2(root, abs).split(sep).join("/");
|
|
1742
2015
|
paths.push(rel);
|
|
1743
2016
|
}
|
|
1744
2017
|
};
|
|
@@ -1848,8 +2121,8 @@ ${diagnostic ?? ""}`);
|
|
|
1848
2121
|
const absPath = toFsPath(
|
|
1849
2122
|
projectDocumentLocalPath(targetApmDir, projectId, doc.path)
|
|
1850
2123
|
);
|
|
1851
|
-
await ensureDirExists(
|
|
1852
|
-
|
|
2124
|
+
await ensureDirExists(dirname3(absPath));
|
|
2125
|
+
writeFileSync5(absPath, doc.content, "utf8");
|
|
1853
2126
|
downloaded += 1;
|
|
1854
2127
|
}
|
|
1855
2128
|
}
|
|
@@ -1858,13 +2131,13 @@ ${diagnostic ?? ""}`);
|
|
|
1858
2131
|
const absPath = toFsPath(
|
|
1859
2132
|
projectDocumentLocalPath(targetApmDir, projectId, path19)
|
|
1860
2133
|
);
|
|
1861
|
-
if (
|
|
2134
|
+
if (existsSync3(absPath)) {
|
|
1862
2135
|
rmSync(absPath, { force: true });
|
|
1863
2136
|
deleted += 1;
|
|
1864
2137
|
}
|
|
1865
2138
|
}
|
|
1866
|
-
|
|
1867
|
-
toFsPath(
|
|
2139
|
+
writeFileSync5(
|
|
2140
|
+
toFsPath(join5(docsDir, MANIFEST_FILE)),
|
|
1868
2141
|
`${JSON.stringify(remoteManifest, null, 2)}
|
|
1869
2142
|
`,
|
|
1870
2143
|
"utf8"
|
|
@@ -1907,7 +2180,7 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
|
|
|
1907
2180
|
const absPath = toFsPath(
|
|
1908
2181
|
projectDocumentLocalPath(targetApmDir, projectId, path19)
|
|
1909
2182
|
);
|
|
1910
|
-
const content =
|
|
2183
|
+
const content = readFileSync4(absPath, "utf8");
|
|
1911
2184
|
const contentHash = hashLocalFileContent(content);
|
|
1912
2185
|
if (remoteHashByPath.get(path19) === contentHash) {
|
|
1913
2186
|
continue;
|
|
@@ -1946,11 +2219,11 @@ async function ensureWorkspaceInitialized(workdir, options) {
|
|
|
1946
2219
|
await syncProjectDocumentsPull(workdir, apmDir);
|
|
1947
2220
|
const trimmedName = options?.name?.trim();
|
|
1948
2221
|
if (trimmedName) {
|
|
1949
|
-
const apmConfigPath = toFsPath(
|
|
1950
|
-
const config =
|
|
2222
|
+
const apmConfigPath = toFsPath(join6(apmDir, "apm.config.json"));
|
|
2223
|
+
const config = readFileSync5(apmConfigPath, "utf8");
|
|
1951
2224
|
const configJson = JSON.parse(config);
|
|
1952
2225
|
configJson.name = trimmedName;
|
|
1953
|
-
|
|
2226
|
+
writeFileSync6(
|
|
1954
2227
|
apmConfigPath,
|
|
1955
2228
|
`${JSON.stringify(configJson, null, 2)}
|
|
1956
2229
|
`,
|
|
@@ -1983,7 +2256,7 @@ async function runInit(name) {
|
|
|
1983
2256
|
// src/commands/login.ts
|
|
1984
2257
|
init_config();
|
|
1985
2258
|
init_client();
|
|
1986
|
-
import { existsSync as
|
|
2259
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1987
2260
|
import { ApiError } from "listpage-http";
|
|
1988
2261
|
async function runLogin(opts) {
|
|
1989
2262
|
const baseUrl = (opts.server?.trim() || process.env.AI_PM_SERVER?.trim() || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
@@ -2038,7 +2311,7 @@ async function runLogin(opts) {
|
|
|
2038
2311
|
);
|
|
2039
2312
|
const workdir = resolveWorkdirPath();
|
|
2040
2313
|
const apmDir = workspaceApmDir(workdir);
|
|
2041
|
-
if (
|
|
2314
|
+
if (existsSync4(apmDir)) {
|
|
2042
2315
|
await syncRemoteDeploymentConfig(workdir, apmDir);
|
|
2043
2316
|
}
|
|
2044
2317
|
}
|
|
@@ -2494,8 +2767,8 @@ async function runCleanBranches(options = {}) {
|
|
|
2494
2767
|
|
|
2495
2768
|
// src/commands/pull.ts
|
|
2496
2769
|
init_client();
|
|
2497
|
-
import { writeFileSync as
|
|
2498
|
-
import { join as
|
|
2770
|
+
import { writeFileSync as writeFileSync10 } from "fs";
|
|
2771
|
+
import { join as join10 } from "path";
|
|
2499
2772
|
import { stringify as yamlStringify } from "yaml";
|
|
2500
2773
|
|
|
2501
2774
|
// src/session-messages-xml.ts
|
|
@@ -2528,8 +2801,8 @@ function formatSessionMessagesXml(sessionId, messages) {
|
|
|
2528
2801
|
}
|
|
2529
2802
|
|
|
2530
2803
|
// src/commands/sync-session-attachments.ts
|
|
2531
|
-
import { existsSync as
|
|
2532
|
-
import { join as
|
|
2804
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
2805
|
+
import { join as join7 } from "path";
|
|
2533
2806
|
var MANIFEST_FILE2 = ".sync-manifest.json";
|
|
2534
2807
|
async function downloadAttachment(cfg, attachmentId) {
|
|
2535
2808
|
const base = cfg.baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -2545,13 +2818,13 @@ async function downloadAttachment(cfg, attachmentId) {
|
|
|
2545
2818
|
return Buffer.from(await res.arrayBuffer());
|
|
2546
2819
|
}
|
|
2547
2820
|
function loadManifest(dir) {
|
|
2548
|
-
const path19 =
|
|
2549
|
-
if (!
|
|
2821
|
+
const path19 = join7(dir, MANIFEST_FILE2);
|
|
2822
|
+
if (!existsSync5(path19)) {
|
|
2550
2823
|
return { version: 1, attachments: {} };
|
|
2551
2824
|
}
|
|
2552
2825
|
try {
|
|
2553
2826
|
const parsed = JSON.parse(
|
|
2554
|
-
|
|
2827
|
+
readFileSync6(path19, "utf8")
|
|
2555
2828
|
);
|
|
2556
2829
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
2557
2830
|
return parsed;
|
|
@@ -2561,15 +2834,15 @@ function loadManifest(dir) {
|
|
|
2561
2834
|
return { version: 1, attachments: {} };
|
|
2562
2835
|
}
|
|
2563
2836
|
function saveManifest(dir, manifest) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2837
|
+
writeFileSync7(
|
|
2838
|
+
join7(dir, MANIFEST_FILE2),
|
|
2566
2839
|
`${JSON.stringify(manifest, null, 2)}
|
|
2567
2840
|
`,
|
|
2568
2841
|
"utf8"
|
|
2569
2842
|
);
|
|
2570
2843
|
}
|
|
2571
2844
|
function isAttachmentUpToDate(entry, item, dest) {
|
|
2572
|
-
if (!entry || !
|
|
2845
|
+
if (!entry || !existsSync5(dest)) return false;
|
|
2573
2846
|
if (entry.name !== item.name) return false;
|
|
2574
2847
|
const createdAt = item.createdAt ?? "";
|
|
2575
2848
|
return entry.createdAt === createdAt;
|
|
@@ -2584,7 +2857,7 @@ async function syncAttachmentsToDirectory(cfg, attachments, dir, logLabel) {
|
|
|
2584
2857
|
const nextManifest = { version: 1, attachments: {} };
|
|
2585
2858
|
const names = [];
|
|
2586
2859
|
for (const item of attachments) {
|
|
2587
|
-
const dest =
|
|
2860
|
+
const dest = join7(dir, item.name);
|
|
2588
2861
|
const entry = manifest.attachments[item.id];
|
|
2589
2862
|
const createdAt = item.createdAt ?? "";
|
|
2590
2863
|
names.push(item.name);
|
|
@@ -2594,7 +2867,7 @@ async function syncAttachmentsToDirectory(cfg, attachments, dir, logLabel) {
|
|
|
2594
2867
|
continue;
|
|
2595
2868
|
}
|
|
2596
2869
|
const buffer = await downloadAttachment(cfg, item.id);
|
|
2597
|
-
|
|
2870
|
+
writeFileSync7(dest, buffer);
|
|
2598
2871
|
nextManifest.attachments[item.id] = {
|
|
2599
2872
|
name: item.name,
|
|
2600
2873
|
createdAt
|
|
@@ -2605,7 +2878,7 @@ async function syncAttachmentsToDirectory(cfg, attachments, dir, logLabel) {
|
|
|
2605
2878
|
return names;
|
|
2606
2879
|
}
|
|
2607
2880
|
async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
|
|
2608
|
-
const dir =
|
|
2881
|
+
const dir = join7(sessionDir(sessionId, apmRoot), SESSION_ATTACHMENTS_SUBDIR);
|
|
2609
2882
|
return syncAttachmentsToDirectory(
|
|
2610
2883
|
cfg,
|
|
2611
2884
|
attachments,
|
|
@@ -2616,65 +2889,65 @@ async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
|
|
|
2616
2889
|
|
|
2617
2890
|
// src/rules-sync.ts
|
|
2618
2891
|
init_client();
|
|
2619
|
-
import { basename as
|
|
2620
|
-
import { existsSync as
|
|
2892
|
+
import { basename as basename3, extname as extname2, join as join9 } from "path";
|
|
2893
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync9 } from "fs";
|
|
2621
2894
|
|
|
2622
2895
|
// src/skills-sync.ts
|
|
2623
2896
|
import {
|
|
2624
2897
|
copyFileSync as copyFileSync2,
|
|
2625
2898
|
cpSync,
|
|
2626
|
-
existsSync as
|
|
2627
|
-
mkdirSync as
|
|
2628
|
-
readdirSync as
|
|
2899
|
+
existsSync as existsSync6,
|
|
2900
|
+
mkdirSync as mkdirSync4,
|
|
2901
|
+
readdirSync as readdirSync4,
|
|
2629
2902
|
rmSync as rmSync2,
|
|
2630
|
-
statSync as
|
|
2631
|
-
writeFileSync as
|
|
2903
|
+
statSync as statSync3,
|
|
2904
|
+
writeFileSync as writeFileSync8
|
|
2632
2905
|
} from "fs";
|
|
2633
|
-
import { join as
|
|
2634
|
-
var AGENTS_TEMPLATE_PATH =
|
|
2635
|
-
var BASE_SKILLS_TEMPLATE_DIR =
|
|
2636
|
-
var BASE_RULES_TEMPLATE_DIR =
|
|
2906
|
+
import { join as join8 } from "path";
|
|
2907
|
+
var AGENTS_TEMPLATE_PATH = join8(CLI_TEMPLATE_DIR, "AGENTS.md");
|
|
2908
|
+
var BASE_SKILLS_TEMPLATE_DIR = join8(CLI_TEMPLATE_DIR, "skills");
|
|
2909
|
+
var BASE_RULES_TEMPLATE_DIR = join8(CLI_TEMPLATE_DIR, "rules");
|
|
2637
2910
|
function sanitizeSkillDirName(name) {
|
|
2638
2911
|
const trimmed = name.trim();
|
|
2639
2912
|
if (!trimmed) return "skill";
|
|
2640
2913
|
return trimmed.replace(/[/\\:*?"<>|]/g, "_");
|
|
2641
2914
|
}
|
|
2642
2915
|
function listBaseSkillDirNames() {
|
|
2643
|
-
if (!
|
|
2644
|
-
return
|
|
2645
|
-
const path19 =
|
|
2646
|
-
return
|
|
2916
|
+
if (!existsSync6(BASE_SKILLS_TEMPLATE_DIR)) return [];
|
|
2917
|
+
return readdirSync4(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
|
|
2918
|
+
const path19 = join8(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
2919
|
+
return statSync3(path19).isDirectory();
|
|
2647
2920
|
});
|
|
2648
2921
|
}
|
|
2649
2922
|
function syncAgentsGuide(apmDir) {
|
|
2650
|
-
if (!
|
|
2651
|
-
|
|
2652
|
-
copyFileSync2(AGENTS_TEMPLATE_PATH,
|
|
2923
|
+
if (!existsSync6(AGENTS_TEMPLATE_PATH)) return false;
|
|
2924
|
+
mkdirSync4(apmDir, { recursive: true });
|
|
2925
|
+
copyFileSync2(AGENTS_TEMPLATE_PATH, join8(apmDir, "AGENTS.md"));
|
|
2653
2926
|
return true;
|
|
2654
2927
|
}
|
|
2655
2928
|
function listBaseRuleFileNames() {
|
|
2656
|
-
if (!
|
|
2657
|
-
return
|
|
2658
|
-
const path19 =
|
|
2659
|
-
return
|
|
2929
|
+
if (!existsSync6(BASE_RULES_TEMPLATE_DIR)) return [];
|
|
2930
|
+
return readdirSync4(BASE_RULES_TEMPLATE_DIR).filter((name) => {
|
|
2931
|
+
const path19 = join8(BASE_RULES_TEMPLATE_DIR, name);
|
|
2932
|
+
return statSync3(path19).isFile();
|
|
2660
2933
|
});
|
|
2661
2934
|
}
|
|
2662
2935
|
function syncBaseRules(rulesDir) {
|
|
2663
|
-
|
|
2936
|
+
mkdirSync4(rulesDir, { recursive: true });
|
|
2664
2937
|
const names = listBaseRuleFileNames();
|
|
2665
2938
|
for (const name of names) {
|
|
2666
|
-
const src =
|
|
2667
|
-
const dest =
|
|
2939
|
+
const src = join8(BASE_RULES_TEMPLATE_DIR, name);
|
|
2940
|
+
const dest = join8(rulesDir, name);
|
|
2668
2941
|
copyFileSync2(src, dest);
|
|
2669
2942
|
}
|
|
2670
2943
|
return names;
|
|
2671
2944
|
}
|
|
2672
2945
|
function syncBaseSkills(skillsDir) {
|
|
2673
|
-
|
|
2946
|
+
mkdirSync4(skillsDir, { recursive: true });
|
|
2674
2947
|
const names = listBaseSkillDirNames();
|
|
2675
2948
|
for (const name of names) {
|
|
2676
|
-
const src =
|
|
2677
|
-
const dest =
|
|
2949
|
+
const src = join8(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
2950
|
+
const dest = join8(skillsDir, name);
|
|
2678
2951
|
cpSync(src, dest, { recursive: true, force: true });
|
|
2679
2952
|
}
|
|
2680
2953
|
return names;
|
|
@@ -2691,16 +2964,16 @@ function syncSupplementarySkills(skillsDir, list) {
|
|
|
2691
2964
|
skipped.push(dirName);
|
|
2692
2965
|
continue;
|
|
2693
2966
|
}
|
|
2694
|
-
const skillDir =
|
|
2695
|
-
|
|
2696
|
-
|
|
2967
|
+
const skillDir = join8(skillsDir, dirName);
|
|
2968
|
+
mkdirSync4(skillDir, { recursive: true });
|
|
2969
|
+
writeFileSync8(join8(skillDir, "SKILL.md"), skill.content ?? "", "utf8");
|
|
2697
2970
|
written.push(dirName);
|
|
2698
2971
|
}
|
|
2699
2972
|
const removed = [];
|
|
2700
|
-
if (!
|
|
2701
|
-
for (const entry of
|
|
2702
|
-
const full =
|
|
2703
|
-
if (!
|
|
2973
|
+
if (!existsSync6(skillsDir)) return { written, skipped, removed };
|
|
2974
|
+
for (const entry of readdirSync4(skillsDir)) {
|
|
2975
|
+
const full = join8(skillsDir, entry);
|
|
2976
|
+
if (!statSync3(full).isDirectory()) continue;
|
|
2704
2977
|
if (baseNames.has(entry)) continue;
|
|
2705
2978
|
if (apiDirNames.has(entry)) continue;
|
|
2706
2979
|
rmSync2(full, { recursive: true, force: true });
|
|
@@ -2719,13 +2992,13 @@ function ruleLocalFileName(ruleName) {
|
|
|
2719
2992
|
return `${sanitized}.md`;
|
|
2720
2993
|
}
|
|
2721
2994
|
function loadManifest2(rulesDir) {
|
|
2722
|
-
const path19 =
|
|
2723
|
-
if (!
|
|
2995
|
+
const path19 = join9(rulesDir, MANIFEST_FILE3);
|
|
2996
|
+
if (!existsSync7(toFsPath(path19))) {
|
|
2724
2997
|
return { version: 1, rules: {} };
|
|
2725
2998
|
}
|
|
2726
2999
|
try {
|
|
2727
3000
|
const parsed = JSON.parse(
|
|
2728
|
-
|
|
3001
|
+
readFileSync7(toFsPath(path19), "utf8")
|
|
2729
3002
|
);
|
|
2730
3003
|
if (parsed?.version === 1 && parsed.rules && typeof parsed.rules === "object") {
|
|
2731
3004
|
return parsed;
|
|
@@ -2735,29 +3008,29 @@ function loadManifest2(rulesDir) {
|
|
|
2735
3008
|
return { version: 1, rules: {} };
|
|
2736
3009
|
}
|
|
2737
3010
|
function saveManifest2(rulesDir, manifest) {
|
|
2738
|
-
|
|
2739
|
-
toFsPath(
|
|
3011
|
+
writeFileSync9(
|
|
3012
|
+
toFsPath(join9(rulesDir, MANIFEST_FILE3)),
|
|
2740
3013
|
`${JSON.stringify(manifest, null, 2)}
|
|
2741
3014
|
`,
|
|
2742
3015
|
"utf8"
|
|
2743
3016
|
);
|
|
2744
3017
|
}
|
|
2745
3018
|
function isBaseRuleFileName(fileName) {
|
|
2746
|
-
return listBaseRuleFileNames().includes(
|
|
3019
|
+
return listBaseRuleFileNames().includes(basename3(fileName));
|
|
2747
3020
|
}
|
|
2748
3021
|
function isRuleUpToDate(entry, rule, dest) {
|
|
2749
|
-
if (!entry || !
|
|
3022
|
+
if (!entry || !existsSync7(toFsPath(dest))) return false;
|
|
2750
3023
|
if (entry.fileName !== ruleLocalFileName(rule.name)) return false;
|
|
2751
3024
|
const updatedAt = rule.updatedAt ?? "";
|
|
2752
3025
|
if (entry.updatedAt !== updatedAt) return false;
|
|
2753
|
-
const localContent =
|
|
3026
|
+
const localContent = readFileSync7(toFsPath(dest), "utf8");
|
|
2754
3027
|
return localContent === (rule.content ?? "");
|
|
2755
3028
|
}
|
|
2756
3029
|
async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
2757
3030
|
const api = createApmApiClient(cfg);
|
|
2758
3031
|
const baseline = await resolveBranchBaseline(api, sessionId, workdirPath);
|
|
2759
3032
|
const repositoryId = baseline.repositoryId;
|
|
2760
|
-
const rulesDir =
|
|
3033
|
+
const rulesDir = join9(apmRoot ?? workspaceApmDir(workdirPath), "rules");
|
|
2761
3034
|
await ensureDirExists(rulesDir);
|
|
2762
3035
|
if (!repositoryId) {
|
|
2763
3036
|
console.log(
|
|
@@ -2774,7 +3047,7 @@ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
|
2774
3047
|
for (const rule of list) {
|
|
2775
3048
|
remoteIds.add(rule.id);
|
|
2776
3049
|
const fileName = ruleLocalFileName(rule.name);
|
|
2777
|
-
const dest =
|
|
3050
|
+
const dest = join9(rulesDir, fileName);
|
|
2778
3051
|
const entry = manifest.rules[rule.id];
|
|
2779
3052
|
const updatedAt = rule.updatedAt ?? "";
|
|
2780
3053
|
if (isRuleUpToDate(entry, rule, dest)) {
|
|
@@ -2783,7 +3056,7 @@ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
|
2783
3056
|
console.log(`[apm] \u89C4\u5219\u65E0\u53D8\u5316\uFF0C\u5DF2\u8DF3\u8FC7: rules/${fileName}`);
|
|
2784
3057
|
continue;
|
|
2785
3058
|
}
|
|
2786
|
-
|
|
3059
|
+
writeFileSync9(toFsPath(dest), rule.content ?? "", "utf8");
|
|
2787
3060
|
nextManifest.rules[rule.id] = { fileName, updatedAt };
|
|
2788
3061
|
written.push(fileName);
|
|
2789
3062
|
console.log(`[apm] \u5DF2\u540C\u6B65\u5E73\u53F0\u89C4\u5219: rules/${fileName}`);
|
|
@@ -2792,8 +3065,8 @@ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
|
2792
3065
|
for (const [ruleId, entry] of Object.entries(manifest.rules)) {
|
|
2793
3066
|
if (remoteIds.has(ruleId)) continue;
|
|
2794
3067
|
if (isBaseRuleFileName(entry.fileName)) continue;
|
|
2795
|
-
const dest =
|
|
2796
|
-
if (
|
|
3068
|
+
const dest = join9(rulesDir, entry.fileName);
|
|
3069
|
+
if (existsSync7(toFsPath(dest))) {
|
|
2797
3070
|
rmSync3(toFsPath(dest), { force: true });
|
|
2798
3071
|
}
|
|
2799
3072
|
removed.push(entry.fileName);
|
|
@@ -2824,20 +3097,20 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
2824
3097
|
const dir = sessionDir(trimmedId, apmRoot);
|
|
2825
3098
|
const docsDir = sessionDocsDir(trimmedId, apmRoot);
|
|
2826
3099
|
await ensureDirExists(docsDir);
|
|
2827
|
-
|
|
3100
|
+
writeFileSync10(
|
|
2828
3101
|
sessionRulePath(trimmedId, apmRoot),
|
|
2829
3102
|
detail.description ?? "",
|
|
2830
3103
|
"utf8"
|
|
2831
3104
|
);
|
|
2832
|
-
|
|
3105
|
+
writeFileSync10(
|
|
2833
3106
|
sessionTaskPath(trimmedId, apmRoot),
|
|
2834
3107
|
detail.task.description ?? "",
|
|
2835
3108
|
"utf8"
|
|
2836
3109
|
);
|
|
2837
|
-
|
|
3110
|
+
writeFileSync10(sessionTodoPath(trimmedId, apmRoot), detail.todo ?? "", "utf8");
|
|
2838
3111
|
for (const doc of documents) {
|
|
2839
3112
|
const fileName = documentLocalFileName(doc.name);
|
|
2840
|
-
|
|
3113
|
+
writeFileSync10(join10(docsDir, fileName), doc.content ?? "", "utf8");
|
|
2841
3114
|
}
|
|
2842
3115
|
const sessionYaml = yamlStringify(
|
|
2843
3116
|
{
|
|
@@ -2854,13 +3127,13 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
2854
3127
|
},
|
|
2855
3128
|
{ lineWidth: 0 }
|
|
2856
3129
|
);
|
|
2857
|
-
|
|
3130
|
+
writeFileSync10(
|
|
2858
3131
|
sessionYamlPath(trimmedId, apmRoot),
|
|
2859
3132
|
sessionYaml.endsWith("\n") ? sessionYaml : `${sessionYaml}
|
|
2860
3133
|
`,
|
|
2861
3134
|
"utf8"
|
|
2862
3135
|
);
|
|
2863
|
-
|
|
3136
|
+
writeFileSync10(
|
|
2864
3137
|
sessionMessagesXmlPath(trimmedId, apmRoot),
|
|
2865
3138
|
formatSessionMessagesXml(trimmedId, messages),
|
|
2866
3139
|
"utf8"
|
|
@@ -2877,15 +3150,15 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
2877
3150
|
import { spawnSync } from "child_process";
|
|
2878
3151
|
|
|
2879
3152
|
// src/version.ts
|
|
2880
|
-
import { readFileSync as
|
|
2881
|
-
import { dirname as
|
|
3153
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
3154
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
2882
3155
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2883
3156
|
var CLI_PACKAGE_NAME = "ai-project-manage-cli";
|
|
2884
3157
|
function readCliVersion() {
|
|
2885
3158
|
try {
|
|
2886
|
-
const dir =
|
|
2887
|
-
const pkgPath =
|
|
2888
|
-
const pkg = JSON.parse(
|
|
3159
|
+
const dir = dirname4(fileURLToPath2(import.meta.url));
|
|
3160
|
+
const pkgPath = join11(dir, "..", "package.json");
|
|
3161
|
+
const pkg = JSON.parse(readFileSync8(pkgPath, "utf8"));
|
|
2889
3162
|
return pkg.version ?? "0.0.0";
|
|
2890
3163
|
} catch {
|
|
2891
3164
|
return "0.0.0";
|
|
@@ -3039,15 +3312,15 @@ async function runUpdate(options = {}) {
|
|
|
3039
3312
|
|
|
3040
3313
|
// src/commands/update-skills.ts
|
|
3041
3314
|
init_client();
|
|
3042
|
-
import { existsSync as
|
|
3043
|
-
import { join as
|
|
3315
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, statSync as statSync4 } from "fs";
|
|
3316
|
+
import { join as join12 } from "path";
|
|
3044
3317
|
async function syncWorkspaceSkills(cfg, workdir) {
|
|
3045
3318
|
const apmDir = workspaceApmDir(workdir);
|
|
3046
3319
|
const fsApmDir = toFsPath(apmDir);
|
|
3047
|
-
if (!
|
|
3320
|
+
if (!existsSync8(fsApmDir)) {
|
|
3048
3321
|
throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3049
3322
|
}
|
|
3050
|
-
const apmStat =
|
|
3323
|
+
const apmStat = statSync4(fsApmDir);
|
|
3051
3324
|
if (!apmStat.isDirectory()) {
|
|
3052
3325
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
3053
3326
|
}
|
|
@@ -3056,13 +3329,13 @@ async function syncWorkspaceSkills(cfg, workdir) {
|
|
|
3056
3329
|
if (syncAgentsGuide(apmDir)) {
|
|
3057
3330
|
console.log("[apm] \u5DF2\u540C\u6B65 APM \u6307\u5357: .apm/AGENTS.md");
|
|
3058
3331
|
}
|
|
3059
|
-
const rulesDir =
|
|
3332
|
+
const rulesDir = join12(apmDir, "rules");
|
|
3060
3333
|
const ruleNames = syncBaseRules(rulesDir);
|
|
3061
3334
|
for (const name of ruleNames) {
|
|
3062
3335
|
console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u89C4\u5219: rules/${name}`);
|
|
3063
3336
|
}
|
|
3064
|
-
const skillsDir =
|
|
3065
|
-
|
|
3337
|
+
const skillsDir = join12(apmDir, "skills");
|
|
3338
|
+
mkdirSync5(toFsPath(skillsDir), { recursive: true });
|
|
3066
3339
|
const baseNames = syncBaseSkills(skillsDir);
|
|
3067
3340
|
for (const name of baseNames) {
|
|
3068
3341
|
console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u6280\u80FD: skills/${name}/`);
|
|
@@ -3088,11 +3361,11 @@ async function syncWorkspaceSkills(cfg, workdir) {
|
|
|
3088
3361
|
}
|
|
3089
3362
|
async function runUpdateSkills() {
|
|
3090
3363
|
const apmDir = workspaceApmDir();
|
|
3091
|
-
if (!
|
|
3364
|
+
if (!existsSync8(apmDir)) {
|
|
3092
3365
|
console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3093
3366
|
process.exit(1);
|
|
3094
3367
|
}
|
|
3095
|
-
const apmStat =
|
|
3368
|
+
const apmStat = statSync4(apmDir);
|
|
3096
3369
|
if (!apmStat.isDirectory()) {
|
|
3097
3370
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
3098
3371
|
}
|
|
@@ -3101,15 +3374,15 @@ async function runUpdateSkills() {
|
|
|
3101
3374
|
}
|
|
3102
3375
|
|
|
3103
3376
|
// src/commands/sync-deploy-config.ts
|
|
3104
|
-
import { existsSync as
|
|
3377
|
+
import { existsSync as existsSync9, statSync as statSync5 } from "fs";
|
|
3105
3378
|
async function runSyncDeployConfig() {
|
|
3106
3379
|
const workdir = resolveWorkdirPath();
|
|
3107
3380
|
const apmDir = workspaceApmDir(workdir);
|
|
3108
|
-
if (!
|
|
3381
|
+
if (!existsSync9(apmDir)) {
|
|
3109
3382
|
console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3110
3383
|
process.exit(1);
|
|
3111
3384
|
}
|
|
3112
|
-
const apmStat =
|
|
3385
|
+
const apmStat = statSync5(apmDir);
|
|
3113
3386
|
if (!apmStat.isDirectory()) {
|
|
3114
3387
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
3115
3388
|
}
|
|
@@ -3140,8 +3413,8 @@ async function runSyncProjectDocuments(options) {
|
|
|
3140
3413
|
}
|
|
3141
3414
|
|
|
3142
3415
|
// src/commands/sync-document.ts
|
|
3143
|
-
import { existsSync as
|
|
3144
|
-
import { basename as
|
|
3416
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
3417
|
+
import { basename as basename4 } from "path";
|
|
3145
3418
|
|
|
3146
3419
|
// src/assumptions/local-validate.ts
|
|
3147
3420
|
var NO_ASSUMPTIONS_RE = /无[,,]?\s*口径均有依据/;
|
|
@@ -3311,13 +3584,13 @@ init_client();
|
|
|
3311
3584
|
|
|
3312
3585
|
// src/commands/sync-session-documents.ts
|
|
3313
3586
|
init_client();
|
|
3314
|
-
import { existsSync as
|
|
3315
|
-
import { join as
|
|
3587
|
+
import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
|
|
3588
|
+
import { join as join13 } from "path";
|
|
3316
3589
|
function listLocalMarkdownFiles(docsDir) {
|
|
3317
|
-
if (!
|
|
3590
|
+
if (!existsSync10(docsDir)) {
|
|
3318
3591
|
return [];
|
|
3319
3592
|
}
|
|
3320
|
-
return
|
|
3593
|
+
return readdirSync5(docsDir).filter(
|
|
3321
3594
|
(name) => name.toLowerCase().endsWith(".md")
|
|
3322
3595
|
);
|
|
3323
3596
|
}
|
|
@@ -3329,8 +3602,8 @@ function remoteDocumentByLocalName(remoteDocuments, localFileName) {
|
|
|
3329
3602
|
});
|
|
3330
3603
|
}
|
|
3331
3604
|
async function upsertLocalDocumentFile(api, sessionId, docsDir, fileName) {
|
|
3332
|
-
const absPath =
|
|
3333
|
-
const content =
|
|
3605
|
+
const absPath = join13(docsDir, fileName);
|
|
3606
|
+
const content = readFileSync9(absPath, "utf8");
|
|
3334
3607
|
const name = documentPlatformName(absPath);
|
|
3335
3608
|
return api.cli.upsertDocument({
|
|
3336
3609
|
sessionId,
|
|
@@ -3352,8 +3625,8 @@ async function syncSessionDocuments(cfg, sessionId, apmRoot, options) {
|
|
|
3352
3625
|
const remoteDocuments = options?.remoteDocuments ?? await api.cli.listDocuments({ sessionId: trimmedSessionId });
|
|
3353
3626
|
let synced = 0;
|
|
3354
3627
|
for (const fileName of localFiles) {
|
|
3355
|
-
const absPath =
|
|
3356
|
-
const content =
|
|
3628
|
+
const absPath = join13(docsDir, fileName);
|
|
3629
|
+
const content = readFileSync9(absPath, "utf8");
|
|
3357
3630
|
const remote = remoteDocumentByLocalName(remoteDocuments, fileName);
|
|
3358
3631
|
if (remote && remote.content === content) {
|
|
3359
3632
|
continue;
|
|
@@ -3386,7 +3659,7 @@ async function runSyncDocument(sessionId, options) {
|
|
|
3386
3659
|
process.exit(1);
|
|
3387
3660
|
}
|
|
3388
3661
|
const absPath = resolveSessionDocumentPath(trimmedSessionId, fileArg);
|
|
3389
|
-
if (!
|
|
3662
|
+
if (!existsSync11(absPath)) {
|
|
3390
3663
|
const docsDir2 = sessionDocsDir(trimmedSessionId);
|
|
3391
3664
|
console.error(
|
|
3392
3665
|
`[apm] \u6587\u6863\u4E0D\u5B58\u5728: ${absPath}
|
|
@@ -3394,10 +3667,10 @@ async function runSyncDocument(sessionId, options) {
|
|
|
3394
3667
|
);
|
|
3395
3668
|
process.exit(1);
|
|
3396
3669
|
}
|
|
3397
|
-
const fileName =
|
|
3670
|
+
const fileName = basename4(absPath);
|
|
3398
3671
|
const assumptionSource = resolveAssumptionSourceFromFileName(fileName);
|
|
3399
3672
|
if (assumptionSource) {
|
|
3400
|
-
const content =
|
|
3673
|
+
const content = readFileSync10(absPath, "utf8");
|
|
3401
3674
|
const validation = validateAssumptionsMarkdown(content, assumptionSource);
|
|
3402
3675
|
if (!validation.ok) {
|
|
3403
3676
|
printAssumptionValidationResult(validation);
|
|
@@ -3414,7 +3687,7 @@ async function runSyncDocument(sessionId, options) {
|
|
|
3414
3687
|
api,
|
|
3415
3688
|
trimmedSessionId,
|
|
3416
3689
|
docsDir,
|
|
3417
|
-
|
|
3690
|
+
basename4(absPath)
|
|
3418
3691
|
);
|
|
3419
3692
|
console.log(`[apm] \u5DF2\u540C\u6B65\u6587\u6863: ${doc.name} (id=${doc.id})`);
|
|
3420
3693
|
const assumptionSync = doc.assumptionSync;
|
|
@@ -3652,6 +3925,7 @@ function validateDeployPush(o) {
|
|
|
3652
3925
|
deploymentRunId: o.deploymentRunId.trim(),
|
|
3653
3926
|
workdir: o.workdir.trim(),
|
|
3654
3927
|
environment,
|
|
3928
|
+
...typeof o.repositoryId === "string" && o.repositoryId.trim() ? { repositoryId: o.repositoryId.trim() } : {},
|
|
3655
3929
|
...o.packOnly === true ? { packOnly: true } : {}
|
|
3656
3930
|
}
|
|
3657
3931
|
};
|
|
@@ -3759,8 +4033,8 @@ init_client();
|
|
|
3759
4033
|
import path11 from "node:path";
|
|
3760
4034
|
|
|
3761
4035
|
// src/commands/deploy/internal/apm-config.ts
|
|
3762
|
-
import { existsSync as
|
|
3763
|
-
import { resolve as
|
|
4036
|
+
import { existsSync as existsSync13, readFileSync as readFileSync12 } from "node:fs";
|
|
4037
|
+
import { resolve as resolve5 } from "node:path";
|
|
3764
4038
|
|
|
3765
4039
|
// src/commands/deploy/internal/config/config-validation.ts
|
|
3766
4040
|
function req(v, field, section) {
|
|
@@ -3852,9 +4126,9 @@ function resolveFrontendDeployFromApmConfig(cfg) {
|
|
|
3852
4126
|
}
|
|
3853
4127
|
|
|
3854
4128
|
// src/commands/deploy/internal/config/maven-repo.ts
|
|
3855
|
-
import { existsSync as
|
|
4129
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "node:fs";
|
|
3856
4130
|
import { homedir as homedir2 } from "node:os";
|
|
3857
|
-
import { join as
|
|
4131
|
+
import { join as join14, resolve as resolve4 } from "node:path";
|
|
3858
4132
|
var MAVEN_REPO_ENV_KEYS = [
|
|
3859
4133
|
"MAVEN_LOCAL_REPO",
|
|
3860
4134
|
"M2_REPO",
|
|
@@ -3887,7 +4161,7 @@ function expandUserPath(pathStr, env = process.env) {
|
|
|
3887
4161
|
if (/^[a-zA-Z]:[/\\]/.test(expanded)) {
|
|
3888
4162
|
return expanded;
|
|
3889
4163
|
}
|
|
3890
|
-
return
|
|
4164
|
+
return resolve4(expanded);
|
|
3891
4165
|
}
|
|
3892
4166
|
function readMavenLocalRepoFromMavenOpts(mavenOpts, env = process.env) {
|
|
3893
4167
|
const match = mavenOpts.match(/-Dmaven\.repo\.local=(?:"([^"]+)"|(\S+))/);
|
|
@@ -3911,12 +4185,12 @@ function readMavenLocalRepoFromEnv(env = process.env) {
|
|
|
3911
4185
|
return null;
|
|
3912
4186
|
}
|
|
3913
4187
|
function readMavenLocalRepoFromSettings() {
|
|
3914
|
-
const settingsPath =
|
|
3915
|
-
if (!
|
|
4188
|
+
const settingsPath = join14(homedir2(), ".m2", "settings.xml");
|
|
4189
|
+
if (!existsSync12(settingsPath)) {
|
|
3916
4190
|
return null;
|
|
3917
4191
|
}
|
|
3918
4192
|
try {
|
|
3919
|
-
const xml =
|
|
4193
|
+
const xml = readFileSync11(settingsPath, "utf8");
|
|
3920
4194
|
const match = xml.match(
|
|
3921
4195
|
/<localRepository>\s*([^<]+?)\s*<\/localRepository>/
|
|
3922
4196
|
);
|
|
@@ -3947,7 +4221,7 @@ function resolveMavenLocalRepoWithSource() {
|
|
|
3947
4221
|
};
|
|
3948
4222
|
}
|
|
3949
4223
|
return {
|
|
3950
|
-
path:
|
|
4224
|
+
path: join14(homedir2(), ".m2", "repository"),
|
|
3951
4225
|
source: "default",
|
|
3952
4226
|
sourceDetail: "~/.m2/repository"
|
|
3953
4227
|
};
|
|
@@ -4043,16 +4317,16 @@ function resolveWisdomBackendDeployFromApmConfig(cfg) {
|
|
|
4043
4317
|
|
|
4044
4318
|
// src/commands/deploy/internal/apm-config.ts
|
|
4045
4319
|
function loadApmConfig(options) {
|
|
4046
|
-
const p =
|
|
4320
|
+
const p = resolve5(
|
|
4047
4321
|
process.cwd(),
|
|
4048
|
-
options?.configPath ??
|
|
4322
|
+
options?.configPath ?? resolve5(workspaceApmDir(), "apm.config.json")
|
|
4049
4323
|
);
|
|
4050
|
-
if (!
|
|
4324
|
+
if (!existsSync13(p)) {
|
|
4051
4325
|
console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
|
|
4052
4326
|
process.exit(1);
|
|
4053
4327
|
}
|
|
4054
4328
|
try {
|
|
4055
|
-
const raw =
|
|
4329
|
+
const raw = readFileSync12(p, "utf8");
|
|
4056
4330
|
return JSON.parse(raw);
|
|
4057
4331
|
} catch (e) {
|
|
4058
4332
|
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
@@ -4098,32 +4372,32 @@ var DeployExecutionError = class extends Error {
|
|
|
4098
4372
|
// src/commands/deploy/deploy-debug-log.ts
|
|
4099
4373
|
init_deploy_artifact_minio();
|
|
4100
4374
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
4101
|
-
import { existsSync as
|
|
4102
|
-
import { dirname as
|
|
4375
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
4376
|
+
import { dirname as dirname6, join as join18 } from "node:path";
|
|
4103
4377
|
|
|
4104
4378
|
// src/commands/deploy/internal/deploy-shell-env.ts
|
|
4105
4379
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
4106
|
-
import { existsSync as
|
|
4107
|
-
import { dirname as
|
|
4380
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
4381
|
+
import { dirname as dirname5, join as join17 } from "node:path";
|
|
4108
4382
|
|
|
4109
4383
|
// src/commands/daemon.ts
|
|
4110
4384
|
init_config();
|
|
4111
4385
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
4112
4386
|
import { setTimeout as delay } from "node:timers/promises";
|
|
4113
|
-
import { existsSync as
|
|
4114
|
-
import { join as
|
|
4387
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync12 } from "fs";
|
|
4388
|
+
import { join as join16 } from "path";
|
|
4115
4389
|
|
|
4116
4390
|
// src/commands/connect-lock.ts
|
|
4117
4391
|
init_config();
|
|
4118
4392
|
import {
|
|
4119
|
-
existsSync as
|
|
4120
|
-
mkdirSync as
|
|
4121
|
-
readFileSync as
|
|
4393
|
+
existsSync as existsSync14,
|
|
4394
|
+
mkdirSync as mkdirSync6,
|
|
4395
|
+
readFileSync as readFileSync13,
|
|
4122
4396
|
unlinkSync,
|
|
4123
|
-
writeFileSync as
|
|
4397
|
+
writeFileSync as writeFileSync11
|
|
4124
4398
|
} from "fs";
|
|
4125
|
-
import { join as
|
|
4126
|
-
var CONNECT_LOCK_PATH =
|
|
4399
|
+
import { join as join15 } from "path";
|
|
4400
|
+
var CONNECT_LOCK_PATH = join15(APM_CONFIG_DIR, "connect.lock");
|
|
4127
4401
|
function isProcessAlive(pid) {
|
|
4128
4402
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
4129
4403
|
try {
|
|
@@ -4150,9 +4424,9 @@ function waitForPm2LockHandoff(timeoutMs = 5e3) {
|
|
|
4150
4424
|
}
|
|
4151
4425
|
}
|
|
4152
4426
|
function readConnectLock() {
|
|
4153
|
-
if (!
|
|
4427
|
+
if (!existsSync14(CONNECT_LOCK_PATH)) return null;
|
|
4154
4428
|
try {
|
|
4155
|
-
const raw =
|
|
4429
|
+
const raw = readFileSync13(CONNECT_LOCK_PATH, "utf8");
|
|
4156
4430
|
const parsed = JSON.parse(raw);
|
|
4157
4431
|
if (typeof parsed.pid !== "number" || parsed.mode !== "foreground" && parsed.mode !== "pm2" || typeof parsed.startedAt !== "string") {
|
|
4158
4432
|
return null;
|
|
@@ -4187,13 +4461,13 @@ function acquireConnectLock(mode) {
|
|
|
4187
4461
|
process.exit(1);
|
|
4188
4462
|
}
|
|
4189
4463
|
}
|
|
4190
|
-
|
|
4464
|
+
mkdirSync6(APM_CONFIG_DIR, { recursive: true });
|
|
4191
4465
|
const lock = {
|
|
4192
4466
|
pid: process.pid,
|
|
4193
4467
|
mode,
|
|
4194
4468
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4195
4469
|
};
|
|
4196
|
-
|
|
4470
|
+
writeFileSync11(
|
|
4197
4471
|
CONNECT_LOCK_PATH,
|
|
4198
4472
|
JSON.stringify(lock, null, 2) + "\n",
|
|
4199
4473
|
"utf8"
|
|
@@ -4209,7 +4483,7 @@ function releaseConnectLock() {
|
|
|
4209
4483
|
}
|
|
4210
4484
|
function forceReleaseConnectLock() {
|
|
4211
4485
|
try {
|
|
4212
|
-
if (
|
|
4486
|
+
if (existsSync14(CONNECT_LOCK_PATH)) {
|
|
4213
4487
|
unlinkSync(CONNECT_LOCK_PATH);
|
|
4214
4488
|
}
|
|
4215
4489
|
} catch {
|
|
@@ -4218,16 +4492,16 @@ function forceReleaseConnectLock() {
|
|
|
4218
4492
|
|
|
4219
4493
|
// src/commands/daemon.ts
|
|
4220
4494
|
var PM2_APP_NAME = "apm-connect";
|
|
4221
|
-
var PM2_ECOSYSTEM_PATH =
|
|
4495
|
+
var PM2_ECOSYSTEM_PATH = join16(
|
|
4222
4496
|
APM_CONFIG_DIR,
|
|
4223
4497
|
"connect.ecosystem.config.cjs"
|
|
4224
4498
|
);
|
|
4225
|
-
var PM2_CONNECT_ENTRY_PATH =
|
|
4226
|
-
var PM2_CONNECT_LAUNCH_PATH =
|
|
4499
|
+
var PM2_CONNECT_ENTRY_PATH = join16(APM_CONFIG_DIR, "connect.entry.cjs");
|
|
4500
|
+
var PM2_CONNECT_LAUNCH_PATH = join16(
|
|
4227
4501
|
APM_CONFIG_DIR,
|
|
4228
4502
|
"connect.launch.json"
|
|
4229
4503
|
);
|
|
4230
|
-
var LEGACY_PM2_ECOSYSTEM_PATH =
|
|
4504
|
+
var LEGACY_PM2_ECOSYSTEM_PATH = join16(
|
|
4231
4505
|
APM_CONFIG_DIR,
|
|
4232
4506
|
"connect.ecosystem.cjs"
|
|
4233
4507
|
);
|
|
@@ -4358,8 +4632,8 @@ function resolvePm2FromNpmRoot() {
|
|
|
4358
4632
|
const root = rootResult.stdout?.toString().trim();
|
|
4359
4633
|
if (!root) return null;
|
|
4360
4634
|
for (const rel of ["pm2/bin/pm2", "pm2/bin/pm2.js"]) {
|
|
4361
|
-
const candidate =
|
|
4362
|
-
if (
|
|
4635
|
+
const candidate = join16(root, ...rel.split("/"));
|
|
4636
|
+
if (existsSync15(candidate)) {
|
|
4363
4637
|
return candidate;
|
|
4364
4638
|
}
|
|
4365
4639
|
}
|
|
@@ -4396,7 +4670,7 @@ function spawnPm2At(binPath, args, options = {}) {
|
|
|
4396
4670
|
return spawnPm2Target(buildPm2SpawnTarget(binPath), args, options);
|
|
4397
4671
|
}
|
|
4398
4672
|
function verifyPm2Bin(pm2Bin) {
|
|
4399
|
-
if (!pm2Bin.trim() || !
|
|
4673
|
+
if (!pm2Bin.trim() || !existsSync15(pm2Bin)) {
|
|
4400
4674
|
return false;
|
|
4401
4675
|
}
|
|
4402
4676
|
const result = spawnPm2At(pm2Bin, ["--version"], {
|
|
@@ -4409,10 +4683,10 @@ function collectPm2Candidates() {
|
|
|
4409
4683
|
const globalBin = resolveNpmGlobalBin();
|
|
4410
4684
|
if (globalBin) {
|
|
4411
4685
|
if (useNpmShell2) {
|
|
4412
|
-
candidates.push(
|
|
4413
|
-
candidates.push(
|
|
4686
|
+
candidates.push(join16(globalBin, "pm2.cmd"));
|
|
4687
|
+
candidates.push(join16(globalBin, "pm2"));
|
|
4414
4688
|
} else {
|
|
4415
|
-
candidates.push(
|
|
4689
|
+
candidates.push(join16(globalBin, "pm2"));
|
|
4416
4690
|
}
|
|
4417
4691
|
}
|
|
4418
4692
|
const fromRoot = resolvePm2FromNpmRoot();
|
|
@@ -4535,7 +4809,7 @@ function ensureGlobalPm2(options) {
|
|
|
4535
4809
|
}
|
|
4536
4810
|
function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
4537
4811
|
const fromArgv = entryArg?.trim();
|
|
4538
|
-
if (fromArgv &&
|
|
4812
|
+
if (fromArgv && existsSync15(fromArgv)) {
|
|
4539
4813
|
return fromArgv;
|
|
4540
4814
|
}
|
|
4541
4815
|
const npmResult = spawnSync2(useNpmShell2 ? "npm.cmd" : "npm", ["root", "-g"], {
|
|
@@ -4546,8 +4820,8 @@ function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
|
4546
4820
|
if (npmResult.status === 0) {
|
|
4547
4821
|
const globalRoot = npmResult.stdout?.toString().trim();
|
|
4548
4822
|
if (globalRoot) {
|
|
4549
|
-
const candidate =
|
|
4550
|
-
if (
|
|
4823
|
+
const candidate = join16(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
|
|
4824
|
+
if (existsSync15(candidate)) {
|
|
4551
4825
|
return candidate;
|
|
4552
4826
|
}
|
|
4553
4827
|
}
|
|
@@ -4705,8 +4979,8 @@ async function resolveBaseUrl(server) {
|
|
|
4705
4979
|
return cfg?.baseUrl;
|
|
4706
4980
|
}
|
|
4707
4981
|
function writeConnectLaunchFiles(options) {
|
|
4708
|
-
|
|
4709
|
-
|
|
4982
|
+
mkdirSync7(APM_CONFIG_DIR, { recursive: true });
|
|
4983
|
+
writeFileSync12(PM2_CONNECT_ENTRY_PATH, CONNECT_ENTRY_SCRIPT, "utf8");
|
|
4710
4984
|
const env = {
|
|
4711
4985
|
...collectPm2LaunchEnv()
|
|
4712
4986
|
};
|
|
@@ -4721,7 +4995,7 @@ function writeConnectLaunchFiles(options) {
|
|
|
4721
4995
|
cwd: options.cwd,
|
|
4722
4996
|
env
|
|
4723
4997
|
};
|
|
4724
|
-
|
|
4998
|
+
writeFileSync12(
|
|
4725
4999
|
PM2_CONNECT_LAUNCH_PATH,
|
|
4726
5000
|
JSON.stringify(launch, null, 2) + "\n",
|
|
4727
5001
|
"utf8"
|
|
@@ -4733,12 +5007,12 @@ function writeEcosystemFile(options) {
|
|
|
4733
5007
|
entryScript: PM2_CONNECT_ENTRY_PATH,
|
|
4734
5008
|
baseUrl: options.baseUrl
|
|
4735
5009
|
});
|
|
4736
|
-
|
|
5010
|
+
writeFileSync12(
|
|
4737
5011
|
PM2_ECOSYSTEM_PATH,
|
|
4738
5012
|
formatConnectPm2EcosystemFile(ecosystem),
|
|
4739
5013
|
"utf8"
|
|
4740
5014
|
);
|
|
4741
|
-
if (
|
|
5015
|
+
if (existsSync15(LEGACY_PM2_ECOSYSTEM_PATH)) {
|
|
4742
5016
|
try {
|
|
4743
5017
|
unlinkSync2(LEGACY_PM2_ECOSYSTEM_PATH);
|
|
4744
5018
|
} catch {
|
|
@@ -4897,14 +5171,14 @@ function writeEnvPath(env, value) {
|
|
|
4897
5171
|
env.PATH = value;
|
|
4898
5172
|
}
|
|
4899
5173
|
function resolveNodeInstallDir() {
|
|
4900
|
-
return
|
|
5174
|
+
return dirname5(process.execPath);
|
|
4901
5175
|
}
|
|
4902
5176
|
function resolveNpmCmdPath() {
|
|
4903
5177
|
if (process.platform !== "win32") {
|
|
4904
5178
|
return null;
|
|
4905
5179
|
}
|
|
4906
|
-
const candidate =
|
|
4907
|
-
return
|
|
5180
|
+
const candidate = join17(resolveNodeInstallDir(), "npm.cmd");
|
|
5181
|
+
return existsSync16(candidate) ? candidate : null;
|
|
4908
5182
|
}
|
|
4909
5183
|
function formatNpmRunShellCommand(scriptName) {
|
|
4910
5184
|
const trimmed = scriptName.trim();
|
|
@@ -5076,7 +5350,7 @@ function logExecuteDeployContext(input) {
|
|
|
5076
5350
|
const deploymentRunId = process.env[APM_DEPLOYMENT_RUN_ID_ENV]?.trim() || null;
|
|
5077
5351
|
const shellEnv = buildDeployShellEnv();
|
|
5078
5352
|
const npmGlobalBin = resolveNpmGlobalBin2();
|
|
5079
|
-
const packageJsonPath =
|
|
5353
|
+
const packageJsonPath = join18(input.cwd, "package.json");
|
|
5080
5354
|
logLine("========== executeDeploy \u4E0A\u4E0B\u6587 ==========");
|
|
5081
5355
|
logLine(`trigger=${trigger} deployEnv=${input.env}`);
|
|
5082
5356
|
logLine(`cwd(input)=${input.cwdInput}`);
|
|
@@ -5086,12 +5360,12 @@ function logExecuteDeployContext(input) {
|
|
|
5086
5360
|
`cwdMatchProcess=${input.cwd === input.processCwd ? "yes" : "no"} (connect \u901A\u5E38\u4E3A no)`
|
|
5087
5361
|
);
|
|
5088
5362
|
logLine(
|
|
5089
|
-
`apm.config=${input.apmConfigPath} exists=${
|
|
5363
|
+
`apm.config=${input.apmConfigPath} exists=${existsSync17(
|
|
5090
5364
|
input.apmConfigPath
|
|
5091
5365
|
)}`
|
|
5092
5366
|
);
|
|
5093
5367
|
logLine(
|
|
5094
|
-
`package.json=${packageJsonPath} exists=${
|
|
5368
|
+
`package.json=${packageJsonPath} exists=${existsSync17(packageJsonPath)}`
|
|
5095
5369
|
);
|
|
5096
5370
|
logLine(
|
|
5097
5371
|
`flags captureOutput=${input.captureOutput} packOnly=${Boolean(
|
|
@@ -5105,7 +5379,7 @@ function logExecuteDeployContext(input) {
|
|
|
5105
5379
|
);
|
|
5106
5380
|
logLine(`process argv=${process.argv.join(" ")}`);
|
|
5107
5381
|
logLine(`npmGlobalBin=${npmGlobalBin ?? "(resolve failed)"}`);
|
|
5108
|
-
logLine(`nodeDir=${
|
|
5382
|
+
logLine(`nodeDir=${dirname6(process.execPath)}`);
|
|
5109
5383
|
logLine("--- process.env\uFF08\u8282\u9009\uFF09---");
|
|
5110
5384
|
for (const [key, value] of Object.entries(
|
|
5111
5385
|
collectInterestingEnv(process.env)
|
|
@@ -5147,14 +5421,14 @@ function logWisdomFrontendDeployContext(input) {
|
|
|
5147
5421
|
logLine(
|
|
5148
5422
|
`buildKey=build:${input.env} buildCmd=${input.buildCmd ?? "(missing)"}`
|
|
5149
5423
|
);
|
|
5150
|
-
logLine(`distDir=${input.distDir} exists=${
|
|
5424
|
+
logLine(`distDir=${input.distDir} exists=${existsSync17(input.distDir)}`);
|
|
5151
5425
|
logLine(
|
|
5152
5426
|
`packOnly=${input.packOnly} archiveDeployArtifact=${input.archiveDeployArtifact}`
|
|
5153
5427
|
);
|
|
5154
5428
|
}
|
|
5155
5429
|
|
|
5156
5430
|
// src/commands/deploy/internal/wisdom-deploy.ts
|
|
5157
|
-
import { existsSync as
|
|
5431
|
+
import { existsSync as existsSync21, readFileSync as readFileSync16, statSync as statSync10 } from "node:fs";
|
|
5158
5432
|
import path10 from "node:path";
|
|
5159
5433
|
|
|
5160
5434
|
// src/commands/deploy/deploy-shell-run.ts
|
|
@@ -5253,22 +5527,22 @@ init_deploy_artifact_minio();
|
|
|
5253
5527
|
|
|
5254
5528
|
// src/commands/deploy/internal/wisdom-backend/jar-incremental.ts
|
|
5255
5529
|
import {
|
|
5256
|
-
mkdirSync as
|
|
5257
|
-
readdirSync as
|
|
5258
|
-
readFileSync as
|
|
5259
|
-
statSync as
|
|
5260
|
-
writeFileSync as
|
|
5530
|
+
mkdirSync as mkdirSync9,
|
|
5531
|
+
readdirSync as readdirSync6,
|
|
5532
|
+
readFileSync as readFileSync15,
|
|
5533
|
+
statSync as statSync8,
|
|
5534
|
+
writeFileSync as writeFileSync14
|
|
5261
5535
|
} from "node:fs";
|
|
5262
5536
|
import path6 from "node:path";
|
|
5263
5537
|
import JSZip2 from "jszip";
|
|
5264
5538
|
|
|
5265
5539
|
// src/commands/deploy/internal/wisdom-backend/manifest.ts
|
|
5266
5540
|
import {
|
|
5267
|
-
existsSync as
|
|
5268
|
-
mkdirSync as
|
|
5269
|
-
readFileSync as
|
|
5270
|
-
statSync as
|
|
5271
|
-
writeFileSync as
|
|
5541
|
+
existsSync as existsSync18,
|
|
5542
|
+
mkdirSync as mkdirSync8,
|
|
5543
|
+
readFileSync as readFileSync14,
|
|
5544
|
+
statSync as statSync7,
|
|
5545
|
+
writeFileSync as writeFileSync13
|
|
5272
5546
|
} from "node:fs";
|
|
5273
5547
|
import path2 from "node:path";
|
|
5274
5548
|
function deployCacheDir() {
|
|
@@ -5281,20 +5555,20 @@ function relativeKey(projectRoot, filePath) {
|
|
|
5281
5555
|
return path2.relative(projectRoot, filePath).split(path2.sep).join("/");
|
|
5282
5556
|
}
|
|
5283
5557
|
function fileSignature(filePath) {
|
|
5284
|
-
const stat2 =
|
|
5558
|
+
const stat2 = statSync7(filePath);
|
|
5285
5559
|
return { size: stat2.size, mtime: stat2.mtimeMs / 1e3 };
|
|
5286
5560
|
}
|
|
5287
5561
|
function loadManifest3() {
|
|
5288
|
-
const
|
|
5289
|
-
if (!
|
|
5562
|
+
const manifestPath3 = manifestFilePath();
|
|
5563
|
+
if (!existsSync18(manifestPath3)) {
|
|
5290
5564
|
return {};
|
|
5291
5565
|
}
|
|
5292
|
-
return JSON.parse(
|
|
5566
|
+
return JSON.parse(readFileSync14(manifestPath3, "utf8"));
|
|
5293
5567
|
}
|
|
5294
5568
|
function saveManifest3(manifest) {
|
|
5295
5569
|
const dir = deployCacheDir();
|
|
5296
|
-
|
|
5297
|
-
|
|
5570
|
+
mkdirSync8(dir, { recursive: true });
|
|
5571
|
+
writeFileSync13(manifestFilePath(), JSON.stringify(manifest, null, 2), "utf8");
|
|
5298
5572
|
}
|
|
5299
5573
|
function updateManifestEntries(manifest, entries, projectRoot) {
|
|
5300
5574
|
for (const entry of entries) {
|
|
@@ -5427,7 +5701,7 @@ function buildSftpConnectOptions(settings) {
|
|
|
5427
5701
|
};
|
|
5428
5702
|
}
|
|
5429
5703
|
async function sleep(ms) {
|
|
5430
|
-
await new Promise((
|
|
5704
|
+
await new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
5431
5705
|
}
|
|
5432
5706
|
async function uploadZipWithRetry(settings, localZip, remoteZipPath) {
|
|
5433
5707
|
let lastError;
|
|
@@ -5471,7 +5745,7 @@ async function ensureRemoteDir(sftp, dir) {
|
|
|
5471
5745
|
}
|
|
5472
5746
|
}
|
|
5473
5747
|
function execCommand(client, command) {
|
|
5474
|
-
return new Promise((
|
|
5748
|
+
return new Promise((resolve8, reject) => {
|
|
5475
5749
|
client.exec(command, (err, stream) => {
|
|
5476
5750
|
if (err) return reject(err);
|
|
5477
5751
|
let stdout = "";
|
|
@@ -5481,7 +5755,7 @@ function execCommand(client, command) {
|
|
|
5481
5755
|
reject(new Error(`\u8FDC\u7A0B\u547D\u4EE4\u5931\u8D25 (${code}): ${stderr || stdout}`));
|
|
5482
5756
|
return;
|
|
5483
5757
|
}
|
|
5484
|
-
|
|
5758
|
+
resolve8(stdout);
|
|
5485
5759
|
}).on("data", (data) => {
|
|
5486
5760
|
stdout += data.toString();
|
|
5487
5761
|
});
|
|
@@ -5664,7 +5938,7 @@ function shouldUploadLibFile(localPath, remoteAttr, manifest, projectRoot) {
|
|
|
5664
5938
|
if (!remoteAttr) {
|
|
5665
5939
|
return [false, "\u8FDC\u7A0B\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7"];
|
|
5666
5940
|
}
|
|
5667
|
-
const localSize =
|
|
5941
|
+
const localSize = statSync8(localPath).size;
|
|
5668
5942
|
const remoteSize = remoteAttr.size;
|
|
5669
5943
|
if (localSize !== remoteSize) {
|
|
5670
5944
|
return [true, `\u5927\u5C0F\u53D8\u5316 ${remoteSize} -> ${localSize}`];
|
|
@@ -5687,7 +5961,7 @@ function shouldUploadLibFile(localPath, remoteAttr, manifest, projectRoot) {
|
|
|
5687
5961
|
}
|
|
5688
5962
|
function listLibFilesToUpload(localLibDir, remoteStats, projectRoot, manifest = null) {
|
|
5689
5963
|
const entries = [];
|
|
5690
|
-
const jarFiles =
|
|
5964
|
+
const jarFiles = readdirSync6(localLibDir).filter((name) => name.endsWith(".jar")).sort();
|
|
5691
5965
|
for (const jarName of jarFiles) {
|
|
5692
5966
|
const jarPath = path6.join(localLibDir, jarName);
|
|
5693
5967
|
const remoteAttr = remoteStats.get(jarName);
|
|
@@ -5705,12 +5979,12 @@ function listLibFilesToUpload(localLibDir, remoteStats, projectRoot, manifest =
|
|
|
5705
5979
|
}
|
|
5706
5980
|
async function createUpdatePackage(entries, packageName) {
|
|
5707
5981
|
const dir = deployCacheDirectory();
|
|
5708
|
-
|
|
5982
|
+
mkdirSync9(dir, { recursive: true });
|
|
5709
5983
|
const zipPath = path6.join(dir, packageName);
|
|
5710
5984
|
log(`\u521B\u5EFA\u66F4\u65B0\u5305: ${path6.basename(zipPath)}\uFF08${entries.length} \u4E2A\u6587\u4EF6\uFF09`);
|
|
5711
5985
|
const zip = new JSZip2();
|
|
5712
5986
|
for (const entry of entries) {
|
|
5713
|
-
const content =
|
|
5987
|
+
const content = readFileSync15(entry.path);
|
|
5714
5988
|
zip.file(entry.arcname, content);
|
|
5715
5989
|
log(` \u6253\u5305: ${entry.arcname} (${entry.reason})`);
|
|
5716
5990
|
}
|
|
@@ -5719,11 +5993,11 @@ async function createUpdatePackage(entries, packageName) {
|
|
|
5719
5993
|
compression: "DEFLATE",
|
|
5720
5994
|
compressionOptions: { level: 6 }
|
|
5721
5995
|
});
|
|
5722
|
-
|
|
5996
|
+
writeFileSync14(zipPath, buffer);
|
|
5723
5997
|
return zipPath;
|
|
5724
5998
|
}
|
|
5725
5999
|
function listAllLibFilesForArchive(libDir) {
|
|
5726
|
-
return
|
|
6000
|
+
return readdirSync6(libDir).filter((name) => name.endsWith(".jar")).sort().map((jarName) => ({
|
|
5727
6001
|
path: path6.join(libDir, jarName),
|
|
5728
6002
|
arcname: jarName,
|
|
5729
6003
|
reason: "\u4EC5\u6253\u5305\u5F52\u6863"
|
|
@@ -5731,7 +6005,7 @@ function listAllLibFilesForArchive(libDir) {
|
|
|
5731
6005
|
}
|
|
5732
6006
|
|
|
5733
6007
|
// src/commands/deploy/internal/wisdom-backend/maven-build.ts
|
|
5734
|
-
import { existsSync as
|
|
6008
|
+
import { existsSync as existsSync20, readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
|
|
5735
6009
|
import path7 from "node:path";
|
|
5736
6010
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
5737
6011
|
function getMvnExecutable() {
|
|
@@ -5780,14 +6054,14 @@ function runMavenBuild(projectRoot, mavenLocalRepo, repoSource) {
|
|
|
5780
6054
|
}
|
|
5781
6055
|
function locateLibDir(projectRoot) {
|
|
5782
6056
|
const targetDir = getTargetDir(projectRoot);
|
|
5783
|
-
if (!
|
|
6057
|
+
if (!existsSync20(targetDir)) {
|
|
5784
6058
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
5785
6059
|
}
|
|
5786
6060
|
const libDir = path7.join(targetDir, "lib");
|
|
5787
|
-
if (!
|
|
6061
|
+
if (!existsSync20(libDir) || !statSync9(libDir).isDirectory()) {
|
|
5788
6062
|
fail(`lib \u76EE\u5F55\u4E0D\u5B58\u5728: ${libDir}`);
|
|
5789
6063
|
}
|
|
5790
|
-
const libJars =
|
|
6064
|
+
const libJars = readdirSync7(libDir).filter((name) => name.endsWith(".jar"));
|
|
5791
6065
|
if (libJars.length === 0) {
|
|
5792
6066
|
fail(`lib \u76EE\u5F55\u4E0B\u6CA1\u6709\u4F9D\u8D56 JAR: ${libDir}`);
|
|
5793
6067
|
}
|
|
@@ -5796,10 +6070,10 @@ function locateLibDir(projectRoot) {
|
|
|
5796
6070
|
}
|
|
5797
6071
|
function locateMainJar(projectRoot) {
|
|
5798
6072
|
const targetDir = getTargetDir(projectRoot);
|
|
5799
|
-
if (!
|
|
6073
|
+
if (!existsSync20(targetDir)) {
|
|
5800
6074
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
5801
6075
|
}
|
|
5802
|
-
const jarFiles =
|
|
6076
|
+
const jarFiles = readdirSync7(targetDir).filter((name) => name.endsWith(".jar") && !name.endsWith(".jar.original")).map((name) => path7.join(targetDir, name)).sort((a, b) => statSync9(b).mtimeMs - statSync9(a).mtimeMs);
|
|
5803
6077
|
if (jarFiles.length === 0) {
|
|
5804
6078
|
fail(`target \u76EE\u5F55\u4E0B\u6CA1\u6709\u4E3B JAR: ${targetDir}`);
|
|
5805
6079
|
}
|
|
@@ -5956,8 +6230,8 @@ function springbootOutputIndicatesSuccess(action, combined) {
|
|
|
5956
6230
|
async function connectSsh(config) {
|
|
5957
6231
|
const client = new Client2();
|
|
5958
6232
|
log(`\u8FDE\u63A5\u670D\u52A1\u5668 ${config.username}@${config.host}:${config.port}`);
|
|
5959
|
-
await new Promise((
|
|
5960
|
-
client.on("ready", () =>
|
|
6233
|
+
await new Promise((resolve8, reject) => {
|
|
6234
|
+
client.on("ready", () => resolve8()).on("error", (err) => reject(err)).connect({
|
|
5961
6235
|
host: config.host,
|
|
5962
6236
|
port: config.port,
|
|
5963
6237
|
username: config.username,
|
|
@@ -6025,7 +6299,7 @@ async function runRemoteCommand(client, command, options) {
|
|
|
6025
6299
|
const check = options?.check ?? true;
|
|
6026
6300
|
const stream = options?.stream ?? false;
|
|
6027
6301
|
const label = options?.label ?? "\u8FDC\u7A0B\u547D\u4EE4";
|
|
6028
|
-
return new Promise((
|
|
6302
|
+
return new Promise((resolve8, reject) => {
|
|
6029
6303
|
client.exec(command, (err, execStream) => {
|
|
6030
6304
|
if (err) {
|
|
6031
6305
|
reject(err);
|
|
@@ -6055,7 +6329,7 @@ ${errText}`.trim();
|
|
|
6055
6329
|
\u8F93\u51FA: ${combined}` : "")
|
|
6056
6330
|
);
|
|
6057
6331
|
}
|
|
6058
|
-
|
|
6332
|
+
resolve8({ exitCode: code, out: out.trim(), err: errText.trim() });
|
|
6059
6333
|
});
|
|
6060
6334
|
});
|
|
6061
6335
|
});
|
|
@@ -6285,15 +6559,15 @@ function isWisdomDeployConfigured(cfg) {
|
|
|
6285
6559
|
return Boolean(w?.host?.trim() && w?.remotePath?.trim());
|
|
6286
6560
|
}
|
|
6287
6561
|
function detectWisdomProjectType(cwd) {
|
|
6288
|
-
return
|
|
6562
|
+
return existsSync21(path10.join(cwd, "package.json")) ? "frontend" : "backend";
|
|
6289
6563
|
}
|
|
6290
6564
|
function readPackageScripts(cwd) {
|
|
6291
6565
|
const pkgPath = path10.join(cwd, "package.json");
|
|
6292
|
-
if (!
|
|
6566
|
+
if (!existsSync21(pkgPath)) {
|
|
6293
6567
|
return {};
|
|
6294
6568
|
}
|
|
6295
6569
|
try {
|
|
6296
|
-
const raw =
|
|
6570
|
+
const raw = readFileSync16(pkgPath, "utf8");
|
|
6297
6571
|
const parsed = JSON.parse(raw);
|
|
6298
6572
|
return parsed.scripts ?? {};
|
|
6299
6573
|
} catch {
|
|
@@ -6316,7 +6590,7 @@ function resolveFrontendDistDir(cwd) {
|
|
|
6316
6590
|
for (const rel of candidates) {
|
|
6317
6591
|
const full = path10.join(cwd, rel);
|
|
6318
6592
|
try {
|
|
6319
|
-
if (
|
|
6593
|
+
if (existsSync21(full) && statSync10(full).isDirectory()) {
|
|
6320
6594
|
return full;
|
|
6321
6595
|
}
|
|
6322
6596
|
} catch {
|
|
@@ -6565,7 +6839,8 @@ async function executeDeploy(options) {
|
|
|
6565
6839
|
try {
|
|
6566
6840
|
const configSyncResult = await syncRemoteDeploymentConfig(
|
|
6567
6841
|
cwd,
|
|
6568
|
-
workspaceApmDir(cwd)
|
|
6842
|
+
workspaceApmDir(cwd),
|
|
6843
|
+
options.repositoryId ? { repositoryId: options.repositoryId } : void 0
|
|
6569
6844
|
);
|
|
6570
6845
|
if (configSyncResult.synced && configSyncResult.configName) {
|
|
6571
6846
|
outputParts.push(
|
|
@@ -6840,6 +7115,7 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
6840
7115
|
if (signal.aborted) return;
|
|
6841
7116
|
const api = createApmApiClient(cfg);
|
|
6842
7117
|
const deploymentRunId = msg.deploymentRunId;
|
|
7118
|
+
const repositoryId = msg.repositoryId?.trim() || "";
|
|
6843
7119
|
await api.cli.updateTaskDeploymentStatus({
|
|
6844
7120
|
id: deploymentRunId,
|
|
6845
7121
|
status: "DEPLOYING"
|
|
@@ -6848,13 +7124,33 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
6848
7124
|
api,
|
|
6849
7125
|
deploymentRunId,
|
|
6850
7126
|
run: async (appendLog) => {
|
|
6851
|
-
const
|
|
7127
|
+
const workspaceRoot = requireRemoteWorkdir(msg.workdir);
|
|
7128
|
+
let cwd = workspaceRoot;
|
|
7129
|
+
if (repositoryId) {
|
|
7130
|
+
const resolved = await resolveDeployCwdForRepository(
|
|
7131
|
+
workspaceRoot,
|
|
7132
|
+
repositoryId,
|
|
7133
|
+
api
|
|
7134
|
+
);
|
|
7135
|
+
if (resolved) {
|
|
7136
|
+
cwd = resolved;
|
|
7137
|
+
appendLog(
|
|
7138
|
+
`[apm] \u591A\u4ED3\u90E8\u7F72\uFF1A\u6309 repositoryId=${repositoryId} \u89E3\u6790 cwd=${cwd}
|
|
7139
|
+
`
|
|
7140
|
+
);
|
|
7141
|
+
} else {
|
|
7142
|
+
appendLog(
|
|
7143
|
+
`[apm] \u672A\u5728 workspace-repos \u547D\u4E2D repositoryId=${repositoryId}\uFF0C\u4F7F\u7528\u5DE5\u4F5C\u7A7A\u95F4\u76EE\u5F55 cwd=${cwd}
|
|
7144
|
+
`
|
|
7145
|
+
);
|
|
7146
|
+
}
|
|
7147
|
+
}
|
|
6852
7148
|
const displayCommand = resolveDeployCommand(
|
|
6853
7149
|
msg.environment,
|
|
6854
7150
|
msg.packOnly
|
|
6855
7151
|
);
|
|
6856
7152
|
console.log(
|
|
6857
|
-
`[apm] deploy start id=${deploymentRunId} env=${msg.environment} cwd=${
|
|
7153
|
+
`[apm] deploy start id=${deploymentRunId} env=${msg.environment} cwd=${cwd}` + (repositoryId ? ` repositoryId=${repositoryId}` : "")
|
|
6858
7154
|
);
|
|
6859
7155
|
console.log(`[apm] deploy command: ${displayCommand}`);
|
|
6860
7156
|
if (signal.aborted) {
|
|
@@ -6862,11 +7158,12 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
6862
7158
|
}
|
|
6863
7159
|
const deployOptions = {
|
|
6864
7160
|
env: msg.environment,
|
|
6865
|
-
cwd
|
|
7161
|
+
cwd,
|
|
6866
7162
|
packOnly: msg.packOnly,
|
|
6867
7163
|
captureOutput: true,
|
|
6868
7164
|
archiveDeployArtifact: true,
|
|
6869
|
-
deployTrigger: "connect"
|
|
7165
|
+
deployTrigger: "connect",
|
|
7166
|
+
...repositoryId ? { repositoryId } : {}
|
|
6870
7167
|
};
|
|
6871
7168
|
const output = await executeDeploy(deployOptions);
|
|
6872
7169
|
if (output.trim()) {
|
|
@@ -6884,7 +7181,7 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
6884
7181
|
}
|
|
6885
7182
|
|
|
6886
7183
|
// src/commands/clean-session-cache.ts
|
|
6887
|
-
import { existsSync as
|
|
7184
|
+
import { existsSync as existsSync22, rmSync as rmSync4 } from "node:fs";
|
|
6888
7185
|
|
|
6889
7186
|
// src/commands/connect/pre-step-cache.ts
|
|
6890
7187
|
var PULL_TTL_MS = 3e4;
|
|
@@ -6926,7 +7223,7 @@ function cleanSessionWorkspaceCache(sessionId, workdir) {
|
|
|
6926
7223
|
return;
|
|
6927
7224
|
}
|
|
6928
7225
|
const dir = sessionDir(trimmedSessionId, workspaceApmDir(trimmedWorkdir));
|
|
6929
|
-
if (
|
|
7226
|
+
if (existsSync22(dir)) {
|
|
6930
7227
|
rmSync4(dir, { recursive: true, force: true });
|
|
6931
7228
|
console.log(`[apm] \u5DF2\u6E05\u7406\u4F1A\u8BDD\u7F13\u5B58 ${dir}`);
|
|
6932
7229
|
} else {
|
|
@@ -6936,16 +7233,16 @@ function cleanSessionWorkspaceCache(sessionId, workdir) {
|
|
|
6936
7233
|
}
|
|
6937
7234
|
|
|
6938
7235
|
// src/commands/clean-webide-cache.ts
|
|
6939
|
-
import { existsSync as
|
|
6940
|
-
import { resolve as
|
|
7236
|
+
import { existsSync as existsSync23, rmSync as rmSync5 } from "node:fs";
|
|
7237
|
+
import { resolve as resolve6 } from "node:path";
|
|
6941
7238
|
function cleanWebIdeWorkspaceCache(taskId, workdir) {
|
|
6942
7239
|
const trimmedTaskId = taskId.trim();
|
|
6943
7240
|
const trimmedWorkdir = workdir.trim();
|
|
6944
7241
|
if (!trimmedTaskId || !trimmedWorkdir) {
|
|
6945
7242
|
return;
|
|
6946
7243
|
}
|
|
6947
|
-
const dir =
|
|
6948
|
-
if (
|
|
7244
|
+
const dir = resolve6(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
|
|
7245
|
+
if (existsSync23(dir)) {
|
|
6949
7246
|
rmSync5(dir, { recursive: true, force: true });
|
|
6950
7247
|
console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
|
|
6951
7248
|
} else {
|
|
@@ -7296,17 +7593,17 @@ ${JSON.stringify(event, null, 2)}
|
|
|
7296
7593
|
}
|
|
7297
7594
|
|
|
7298
7595
|
// src/commands/connect/agent-session-registry.ts
|
|
7299
|
-
import { existsSync as
|
|
7300
|
-
import { dirname as
|
|
7596
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
|
|
7597
|
+
import { dirname as dirname7, resolve as resolve7 } from "node:path";
|
|
7301
7598
|
function registryPath(workdir, sessionId) {
|
|
7302
|
-
return
|
|
7599
|
+
return resolve7(workdir, ".apm", "sessions", sessionId, "cursor-agents.json");
|
|
7303
7600
|
}
|
|
7304
7601
|
function readRegistry(path19) {
|
|
7305
|
-
if (!
|
|
7602
|
+
if (!existsSync24(path19)) {
|
|
7306
7603
|
return {};
|
|
7307
7604
|
}
|
|
7308
7605
|
try {
|
|
7309
|
-
const parsed = JSON.parse(
|
|
7606
|
+
const parsed = JSON.parse(readFileSync17(path19, "utf8"));
|
|
7310
7607
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7311
7608
|
const result = {};
|
|
7312
7609
|
for (const [key, value] of Object.entries(
|
|
@@ -7323,8 +7620,8 @@ function readRegistry(path19) {
|
|
|
7323
7620
|
return {};
|
|
7324
7621
|
}
|
|
7325
7622
|
function writeRegistry(path19, registry) {
|
|
7326
|
-
|
|
7327
|
-
|
|
7623
|
+
mkdirSync10(dirname7(path19), { recursive: true });
|
|
7624
|
+
writeFileSync15(path19, `${JSON.stringify(registry, null, 2)}
|
|
7328
7625
|
`, "utf8");
|
|
7329
7626
|
}
|
|
7330
7627
|
function loadSessionAgentId(workdir, sessionId, user) {
|
|
@@ -7927,12 +8224,12 @@ ${WORKSPACE_BOUNDARY_HINT}`;
|
|
|
7927
8224
|
}
|
|
7928
8225
|
|
|
7929
8226
|
// src/commands/connect/local-agent-store.ts
|
|
7930
|
-
import { mkdirSync as
|
|
7931
|
-
import { join as
|
|
8227
|
+
import { mkdirSync as mkdirSync11 } from "node:fs";
|
|
8228
|
+
import { join as join19 } from "node:path";
|
|
7932
8229
|
import { JsonlLocalAgentStore } from "@cursor/sdk";
|
|
7933
8230
|
function createWorkspaceLocalAgentStore(workdir) {
|
|
7934
|
-
const rootDir =
|
|
7935
|
-
|
|
8231
|
+
const rootDir = join19(workdir, ".apm", "cursor-agent-store");
|
|
8232
|
+
mkdirSync11(rootDir, { recursive: true });
|
|
7936
8233
|
return new JsonlLocalAgentStore(rootDir);
|
|
7937
8234
|
}
|
|
7938
8235
|
|
|
@@ -8212,20 +8509,20 @@ async function ensureMessageHasReply(cfg, sessionId, messageId, fallback) {
|
|
|
8212
8509
|
}
|
|
8213
8510
|
|
|
8214
8511
|
// src/commands/connect/cli-version-sync.ts
|
|
8215
|
-
import { existsSync as
|
|
8216
|
-
import { join as
|
|
8512
|
+
import { existsSync as existsSync25, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
8513
|
+
import { join as join20 } from "path";
|
|
8217
8514
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
8218
|
-
function
|
|
8219
|
-
return
|
|
8515
|
+
function manifestPath2(apmDir) {
|
|
8516
|
+
return join20(apmDir, CLI_VERSION_FILE);
|
|
8220
8517
|
}
|
|
8221
8518
|
function loadManifest4(apmDir) {
|
|
8222
|
-
const path19 = toFsPath(
|
|
8223
|
-
if (!
|
|
8519
|
+
const path19 = toFsPath(manifestPath2(apmDir));
|
|
8520
|
+
if (!existsSync25(path19)) {
|
|
8224
8521
|
return null;
|
|
8225
8522
|
}
|
|
8226
8523
|
try {
|
|
8227
8524
|
const parsed = JSON.parse(
|
|
8228
|
-
|
|
8525
|
+
readFileSync18(path19, "utf8")
|
|
8229
8526
|
);
|
|
8230
8527
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
8231
8528
|
return parsed;
|
|
@@ -8236,8 +8533,8 @@ function loadManifest4(apmDir) {
|
|
|
8236
8533
|
}
|
|
8237
8534
|
function saveManifest4(apmDir, cliVersion) {
|
|
8238
8535
|
const manifest = { version: 1, cliVersion };
|
|
8239
|
-
|
|
8240
|
-
toFsPath(
|
|
8536
|
+
writeFileSync16(
|
|
8537
|
+
toFsPath(manifestPath2(apmDir)),
|
|
8241
8538
|
`${JSON.stringify(manifest, null, 2)}
|
|
8242
8539
|
`,
|
|
8243
8540
|
"utf8"
|
|
@@ -8290,7 +8587,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8290
8587
|
);
|
|
8291
8588
|
}
|
|
8292
8589
|
const queuedAt = Date.now();
|
|
8293
|
-
return new Promise((
|
|
8590
|
+
return new Promise((resolve8) => {
|
|
8294
8591
|
waiters.push(() => {
|
|
8295
8592
|
active += 1;
|
|
8296
8593
|
const waitedMs = Date.now() - queuedAt;
|
|
@@ -8301,7 +8598,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8301
8598
|
)}s\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`
|
|
8302
8599
|
);
|
|
8303
8600
|
}
|
|
8304
|
-
|
|
8601
|
+
resolve8();
|
|
8305
8602
|
});
|
|
8306
8603
|
});
|
|
8307
8604
|
};
|
|
@@ -8322,9 +8619,9 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8322
8619
|
init_webide_terminal_registry();
|
|
8323
8620
|
import { Worker } from "node:worker_threads";
|
|
8324
8621
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8325
|
-
import { dirname as
|
|
8326
|
-
var workerFile =
|
|
8327
|
-
|
|
8622
|
+
import { dirname as dirname8, join as join21 } from "node:path";
|
|
8623
|
+
var workerFile = join21(
|
|
8624
|
+
dirname8(fileURLToPath3(import.meta.url)),
|
|
8328
8625
|
"webide-message-worker.js"
|
|
8329
8626
|
);
|
|
8330
8627
|
function spawnWebIdeMessageWorker(cfg, msg) {
|
|
@@ -8333,8 +8630,8 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8333
8630
|
});
|
|
8334
8631
|
const registry = getWebIdeTerminalRegistry(cfg);
|
|
8335
8632
|
let resolveDone;
|
|
8336
|
-
const done = new Promise((
|
|
8337
|
-
resolveDone =
|
|
8633
|
+
const done = new Promise((resolve8) => {
|
|
8634
|
+
resolveDone = resolve8;
|
|
8338
8635
|
});
|
|
8339
8636
|
worker.on("message", (m) => {
|
|
8340
8637
|
if (m?.type === "terminal-rpc") {
|
|
@@ -8579,11 +8876,11 @@ async function handleInboundMessage(cfg, msg, signal, ctx) {
|
|
|
8579
8876
|
}
|
|
8580
8877
|
function interruptibleSleep(ms, signal) {
|
|
8581
8878
|
if (signal.aborted) return Promise.resolve();
|
|
8582
|
-
return new Promise((
|
|
8583
|
-
const timer = setTimeout(
|
|
8879
|
+
return new Promise((resolve8) => {
|
|
8880
|
+
const timer = setTimeout(resolve8, ms);
|
|
8584
8881
|
const onAbort = () => {
|
|
8585
8882
|
clearTimeout(timer);
|
|
8586
|
-
|
|
8883
|
+
resolve8();
|
|
8587
8884
|
};
|
|
8588
8885
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
8589
8886
|
});
|
|
@@ -8795,7 +9092,7 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
8795
9092
|
});
|
|
8796
9093
|
}
|
|
8797
9094
|
function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
8798
|
-
return new Promise((
|
|
9095
|
+
return new Promise((resolve8, reject) => {
|
|
8799
9096
|
const ws = new WebSocket(url);
|
|
8800
9097
|
let stopHeartbeat;
|
|
8801
9098
|
let settled = false;
|
|
@@ -8824,7 +9121,7 @@ function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
|
8824
9121
|
finish(() => reject(new Error("shutdown")));
|
|
8825
9122
|
return;
|
|
8826
9123
|
}
|
|
8827
|
-
finish(
|
|
9124
|
+
finish(resolve8);
|
|
8828
9125
|
});
|
|
8829
9126
|
ws.on("error", (err) => {
|
|
8830
9127
|
console.error("[apm] WebSocket \u9519\u8BEF:", err.message);
|
|
@@ -9110,38 +9407,111 @@ function normalizeDeployEnvironment(env) {
|
|
|
9110
9407
|
if (normalized === "online") return "ONLINE";
|
|
9111
9408
|
return null;
|
|
9112
9409
|
}
|
|
9410
|
+
async function resolveRepositoryIdForWebIdeDeploy(cwd, api) {
|
|
9411
|
+
const start = resolveWorkdirPath(cwd);
|
|
9412
|
+
let manifest = findWorkspaceReposManifestNearPath(start);
|
|
9413
|
+
if (!manifest) {
|
|
9414
|
+
throw new DeployExecutionError(
|
|
9415
|
+
"\u672A\u627E\u5230 .apm/workspace-repos.json\uFF0C\u65E0\u6CD5\u5339\u914D\u5E73\u53F0\u4ED3\u5E93",
|
|
9416
|
+
1
|
|
9417
|
+
);
|
|
9418
|
+
}
|
|
9419
|
+
try {
|
|
9420
|
+
manifest = await enrichWorkspaceReposRemoteUrls(manifest);
|
|
9421
|
+
} catch (err) {
|
|
9422
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9423
|
+
throw new DeployExecutionError(
|
|
9424
|
+
`\u5237\u65B0 workspace-repos remoteUrl \u5931\u8D25: ${detail}`,
|
|
9425
|
+
1
|
|
9426
|
+
);
|
|
9427
|
+
}
|
|
9428
|
+
const entry = matchWorkspaceRepoEntryForPath(manifest, start);
|
|
9429
|
+
if (!entry) {
|
|
9430
|
+
throw new DeployExecutionError(
|
|
9431
|
+
`\u5F53\u524D\u76EE\u5F55\u672A\u547D\u4E2D workspace-repos \u4E2D\u7684\u4ED3\u5E93: ${start}`,
|
|
9432
|
+
1
|
|
9433
|
+
);
|
|
9434
|
+
}
|
|
9435
|
+
const abs = absoluteRepoPath(manifest.workdir, entry);
|
|
9436
|
+
const remoteUrl = toHttpsGitRemoteUrl(entry.remoteUrl ?? "") || await tryReadHttpsGitOriginUrl(abs);
|
|
9437
|
+
if (!remoteUrl) {
|
|
9438
|
+
throw new DeployExecutionError(
|
|
9439
|
+
`\u4ED3 ${entry.path} \u65E0\u53EF\u7528\u7684 https remote\uFF0C\u65E0\u6CD5\u5339\u914D\u5E73\u53F0\u4ED3\u5E93`,
|
|
9440
|
+
1
|
|
9441
|
+
);
|
|
9442
|
+
}
|
|
9443
|
+
let baseBranch = "";
|
|
9444
|
+
try {
|
|
9445
|
+
const gitRoot = await resolveGitRepoRoot(abs);
|
|
9446
|
+
baseBranch = (await resolveDefaultRemoteBranch(gitRoot)).trim();
|
|
9447
|
+
} catch (err) {
|
|
9448
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9449
|
+
throw new DeployExecutionError(`\u89E3\u6790\u5F53\u524D\u4ED3\u57FA\u7EBF\u5206\u652F\u5931\u8D25: ${detail}`, 1);
|
|
9450
|
+
}
|
|
9451
|
+
if (!baseBranch) {
|
|
9452
|
+
throw new DeployExecutionError(
|
|
9453
|
+
"\u65E0\u6CD5\u786E\u5B9A\u5F53\u524D\u4ED3\u57FA\u7EBF\u5206\u652F\uFF0C\u65E0\u6CD5\u5339\u914D\u5E73\u53F0\u4ED3\u5E93",
|
|
9454
|
+
1
|
|
9455
|
+
);
|
|
9456
|
+
}
|
|
9457
|
+
let matched;
|
|
9458
|
+
try {
|
|
9459
|
+
matched = await api.cli.matchRepository({
|
|
9460
|
+
url: remoteUrl,
|
|
9461
|
+
baseBranch
|
|
9462
|
+
});
|
|
9463
|
+
} catch (err) {
|
|
9464
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9465
|
+
throw new DeployExecutionError(
|
|
9466
|
+
`\u6309 https remote + \u57FA\u7EBF\u5206\u652F\u5339\u914D\u5E73\u53F0\u4ED3\u5E93\u5931\u8D25: ${detail}`,
|
|
9467
|
+
1
|
|
9468
|
+
);
|
|
9469
|
+
}
|
|
9470
|
+
const repositoryId = matched.repositoryId?.trim() || "";
|
|
9471
|
+
if (!repositoryId) {
|
|
9472
|
+
throw new DeployExecutionError(
|
|
9473
|
+
`\u672A\u5339\u914D\u5230\u5E73\u53F0\u4ED3\u5E93 path=${entry.path} url=${remoteUrl} baseBranch=${baseBranch}`,
|
|
9474
|
+
1
|
|
9475
|
+
);
|
|
9476
|
+
}
|
|
9477
|
+
console.log(
|
|
9478
|
+
`[apm] \u90E8\u7F72\u8BB0\u5F55\u4ED3\u5E93 path=${entry.path} https+baseBranch=${baseBranch} \u2192 repositoryId=${repositoryId}`
|
|
9479
|
+
);
|
|
9480
|
+
return repositoryId;
|
|
9481
|
+
}
|
|
9113
9482
|
async function runDeployWithBackendTracking(options) {
|
|
9483
|
+
const { tracking, ...deployOptions } = options;
|
|
9114
9484
|
const cfg = await tryReadApmConfig();
|
|
9115
9485
|
if (!cfg || !resolveApiKey(cfg)) {
|
|
9116
|
-
|
|
9117
|
-
await executeDeploy(options);
|
|
9118
|
-
return;
|
|
9486
|
+
throw new DeployExecutionError("\u672A\u767B\u5F55\uFF0C\u65E0\u6CD5\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55", 1);
|
|
9119
9487
|
}
|
|
9120
|
-
const environment = normalizeDeployEnvironment(
|
|
9488
|
+
const environment = normalizeDeployEnvironment(deployOptions.env);
|
|
9121
9489
|
if (!environment) {
|
|
9122
|
-
|
|
9123
|
-
|
|
9490
|
+
throw new DeployExecutionError(
|
|
9491
|
+
`\u672A\u77E5\u90E8\u7F72\u73AF\u5883 ${deployOptions.env}\uFF0C\u4EC5\u652F\u6301 test/online`,
|
|
9492
|
+
1
|
|
9124
9493
|
);
|
|
9125
|
-
await executeDeploy(options);
|
|
9126
|
-
return;
|
|
9127
9494
|
}
|
|
9128
9495
|
const api = createApmApiClient(cfg);
|
|
9496
|
+
const repositoryId = tracking.kind === "task" ? await resolveRepositoryIdForWebIdeDeploy(deployOptions.cwd, api) : void 0;
|
|
9129
9497
|
let deploymentRunId;
|
|
9130
9498
|
try {
|
|
9131
9499
|
const run = await api.cli.createTaskDeployment({
|
|
9132
|
-
sessionId:
|
|
9500
|
+
...tracking.kind === "session" ? { sessionId: tracking.sessionId } : { taskId: tracking.taskId },
|
|
9133
9501
|
environment,
|
|
9134
|
-
workdirPath: resolveWorkdirPath(
|
|
9502
|
+
workdirPath: resolveWorkdirPath(deployOptions.cwd),
|
|
9503
|
+
...repositoryId ? { repositoryId } : {}
|
|
9135
9504
|
});
|
|
9136
9505
|
deploymentRunId = run.id;
|
|
9137
9506
|
console.log(
|
|
9138
9507
|
`[apm] \u5DF2\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55 id=${deploymentRunId} env=${environment}`
|
|
9139
9508
|
);
|
|
9140
9509
|
} catch (error) {
|
|
9510
|
+
if (error instanceof DeployExecutionError) {
|
|
9511
|
+
throw error;
|
|
9512
|
+
}
|
|
9141
9513
|
const detail = error instanceof Error ? error.message : String(error);
|
|
9142
|
-
|
|
9143
|
-
await executeDeploy(options);
|
|
9144
|
-
return;
|
|
9514
|
+
throw new DeployExecutionError(`\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5931\u8D25: ${detail}`, 1);
|
|
9145
9515
|
}
|
|
9146
9516
|
await api.cli.updateTaskDeploymentStatus({
|
|
9147
9517
|
id: deploymentRunId,
|
|
@@ -9152,7 +9522,7 @@ async function runDeployWithBackendTracking(options) {
|
|
|
9152
9522
|
deploymentRunId,
|
|
9153
9523
|
run: async (appendLog) => {
|
|
9154
9524
|
const output = await executeDeploy({
|
|
9155
|
-
...
|
|
9525
|
+
...deployOptions,
|
|
9156
9526
|
captureOutput: true,
|
|
9157
9527
|
archiveDeployArtifact: true
|
|
9158
9528
|
});
|
|
@@ -9178,7 +9548,10 @@ function registerDeployMainCommand(program) {
|
|
|
9178
9548
|
"apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
|
|
9179
9549
|
).option(
|
|
9180
9550
|
"--session <sessionId>",
|
|
9181
|
-
"\u6C9F\u901A\u7FA4 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7"
|
|
9551
|
+
"\u6C9F\u901A\u7FA4 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7\uFF08\u4E0E --task \u4E8C\u9009\u4E00\uFF09"
|
|
9552
|
+
).option(
|
|
9553
|
+
"--task <taskId>",
|
|
9554
|
+
"WebIDE \u4EFB\u52A1 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7\uFF08\u4E0E --session \u4E8C\u9009\u4E00\uFF09"
|
|
9182
9555
|
).option(
|
|
9183
9556
|
"--pack-only",
|
|
9184
9557
|
"\u4EC5\u6784\u5EFA/\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B SFTP/SSH\uFF08\u65E0\u9700 wisdomDeploy\uFF09"
|
|
@@ -9186,14 +9559,30 @@ function registerDeployMainCommand(program) {
|
|
|
9186
9559
|
async (env, opts) => {
|
|
9187
9560
|
const cwd = process.cwd();
|
|
9188
9561
|
const sessionId = opts.session?.trim();
|
|
9562
|
+
const taskId = opts.task?.trim();
|
|
9189
9563
|
const packOnly = Boolean(opts.packOnly);
|
|
9564
|
+
if (sessionId && taskId) {
|
|
9565
|
+
console.error("[apm] --session \u4E0E --task \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
9566
|
+
process.exit(1);
|
|
9567
|
+
}
|
|
9190
9568
|
try {
|
|
9191
9569
|
if (sessionId) {
|
|
9192
9570
|
await runDeployWithBackendTracking({
|
|
9193
9571
|
env,
|
|
9194
9572
|
cwd,
|
|
9195
9573
|
configPath: opts.config,
|
|
9196
|
-
sessionId,
|
|
9574
|
+
tracking: { kind: "session", sessionId },
|
|
9575
|
+
packOnly,
|
|
9576
|
+
deployTrigger: "session"
|
|
9577
|
+
});
|
|
9578
|
+
return;
|
|
9579
|
+
}
|
|
9580
|
+
if (taskId) {
|
|
9581
|
+
await runDeployWithBackendTracking({
|
|
9582
|
+
env,
|
|
9583
|
+
cwd,
|
|
9584
|
+
configPath: opts.config,
|
|
9585
|
+
tracking: { kind: "task", taskId },
|
|
9197
9586
|
packOnly,
|
|
9198
9587
|
deployTrigger: "session"
|
|
9199
9588
|
});
|
|
@@ -9227,7 +9616,7 @@ import path15 from "node:path";
|
|
|
9227
9616
|
import Docker from "dockerode";
|
|
9228
9617
|
|
|
9229
9618
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
9230
|
-
import { existsSync as
|
|
9619
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19 } from "node:fs";
|
|
9231
9620
|
import path12 from "node:path";
|
|
9232
9621
|
function asOptionalTlsBuffer(value) {
|
|
9233
9622
|
if (typeof value !== "string") {
|
|
@@ -9239,8 +9628,8 @@ function asOptionalTlsBuffer(value) {
|
|
|
9239
9628
|
if (normalized === "") {
|
|
9240
9629
|
return void 0;
|
|
9241
9630
|
}
|
|
9242
|
-
if (
|
|
9243
|
-
return
|
|
9631
|
+
if (existsSync26(normalized)) {
|
|
9632
|
+
return readFileSync19(normalized);
|
|
9244
9633
|
}
|
|
9245
9634
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
9246
9635
|
if (looksLikePath) {
|
|
@@ -9365,17 +9754,17 @@ var DockerodeClient = class {
|
|
|
9365
9754
|
await this.client.getImage(image).remove({ force: true });
|
|
9366
9755
|
}
|
|
9367
9756
|
async pullImage(image, auth) {
|
|
9368
|
-
const stream = await new Promise((
|
|
9757
|
+
const stream = await new Promise((resolve8, reject) => {
|
|
9369
9758
|
const pullOptions = auth ? { authconfig: auth } : void 0;
|
|
9370
9759
|
this.client.pull(image, pullOptions, (err, output) => {
|
|
9371
9760
|
if (err || !output) {
|
|
9372
9761
|
reject(err ?? new Error("docker pull \u8FD4\u56DE\u7A7A\u8F93\u51FA"));
|
|
9373
9762
|
return;
|
|
9374
9763
|
}
|
|
9375
|
-
|
|
9764
|
+
resolve8(output);
|
|
9376
9765
|
});
|
|
9377
9766
|
});
|
|
9378
|
-
await new Promise((
|
|
9767
|
+
await new Promise((resolve8, reject) => {
|
|
9379
9768
|
this.client.modem.followProgress(
|
|
9380
9769
|
stream,
|
|
9381
9770
|
(err) => {
|
|
@@ -9383,7 +9772,7 @@ var DockerodeClient = class {
|
|
|
9383
9772
|
reject(err);
|
|
9384
9773
|
return;
|
|
9385
9774
|
}
|
|
9386
|
-
|
|
9775
|
+
resolve8();
|
|
9387
9776
|
},
|
|
9388
9777
|
() => void 0
|
|
9389
9778
|
);
|
|
@@ -9450,7 +9839,7 @@ var DockerodeClient = class {
|
|
|
9450
9839
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
9451
9840
|
|
|
9452
9841
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
9453
|
-
import { existsSync as
|
|
9842
|
+
import { existsSync as existsSync27, readFileSync as readFileSync20, statSync as statSync11 } from "node:fs";
|
|
9454
9843
|
import path13 from "node:path";
|
|
9455
9844
|
function stripSurroundingQuotes(value) {
|
|
9456
9845
|
const t = value.trim();
|
|
@@ -9467,10 +9856,10 @@ function loadEnvFromFile(envFilePath) {
|
|
|
9467
9856
|
return {};
|
|
9468
9857
|
}
|
|
9469
9858
|
const targetPath = path13.resolve(envFilePath);
|
|
9470
|
-
if (!
|
|
9859
|
+
if (!existsSync27(targetPath) || !statSync11(targetPath).isFile()) {
|
|
9471
9860
|
return {};
|
|
9472
9861
|
}
|
|
9473
|
-
const raw =
|
|
9862
|
+
const raw = readFileSync20(targetPath, "utf-8");
|
|
9474
9863
|
const result = {};
|
|
9475
9864
|
for (const line of raw.split(/\r?\n/)) {
|
|
9476
9865
|
const normalized = line.trim();
|
|
@@ -9641,12 +10030,12 @@ function dockerPushImage(params, cwd) {
|
|
|
9641
10030
|
}
|
|
9642
10031
|
|
|
9643
10032
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
9644
|
-
import { existsSync as
|
|
10033
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
9645
10034
|
import path14 from "node:path";
|
|
9646
10035
|
function resolveDockerBuildPaths(cwd) {
|
|
9647
10036
|
const dockerfilePath = path14.join(cwd, "Dockerfile");
|
|
9648
10037
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
9649
|
-
if (!
|
|
10038
|
+
if (!existsSync28(dockerfilePath)) {
|
|
9650
10039
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
9651
10040
|
}
|
|
9652
10041
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|