ai-project-manage-cli 7.1.16 → 7.1.18
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/README.md +1 -1
- package/dist/index.js +625 -295
- package/dist/webide-message-worker.js +261 -26
- package/package.json +1 -1
- package/template/AGENTS.md +4 -3
- package/template/rules/webide_terminal.md +3 -3
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) {
|
|
@@ -1395,6 +1395,36 @@ import { writeFileSync as writeFileSync3 } from "fs";
|
|
|
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);
|
|
@@ -1671,12 +1724,26 @@ import {
|
|
|
1671
1724
|
import { createHash } from "crypto";
|
|
1672
1725
|
import { dirname as dirname2, join as join4, relative, sep } from "path";
|
|
1673
1726
|
var MANIFEST_FILE = "manifest.json";
|
|
1674
|
-
function
|
|
1675
|
-
|
|
1727
|
+
function normalizeProjectIdForPath(projectId) {
|
|
1728
|
+
const id = projectId.trim();
|
|
1729
|
+
if (!id) {
|
|
1730
|
+
throw new Error("projectId \u4E0D\u80FD\u4E3A\u7A7A");
|
|
1731
|
+
}
|
|
1732
|
+
if (id.includes("..") || id.includes("/") || id.includes("\\") || id.includes("\0")) {
|
|
1733
|
+
throw new Error(`\u975E\u6CD5 projectId: ${projectId}`);
|
|
1734
|
+
}
|
|
1735
|
+
return id;
|
|
1676
1736
|
}
|
|
1677
|
-
function
|
|
1737
|
+
function projectDocumentsDir(apmRoot, projectId) {
|
|
1738
|
+
const id = normalizeProjectIdForPath(projectId);
|
|
1739
|
+
return join4(apmRoot ?? workspaceApmDir(), "project", id);
|
|
1740
|
+
}
|
|
1741
|
+
function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
1678
1742
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
1679
|
-
return join4(
|
|
1743
|
+
return join4(
|
|
1744
|
+
projectDocumentsDir(apmRoot, projectId),
|
|
1745
|
+
...normalized.split("/")
|
|
1746
|
+
);
|
|
1680
1747
|
}
|
|
1681
1748
|
function normalizeLocalDocumentPath(path19) {
|
|
1682
1749
|
const trimmed = path19.trim().replace(/\\/g, "/");
|
|
@@ -1692,21 +1759,24 @@ function normalizeLocalDocumentPath(path19) {
|
|
|
1692
1759
|
function hashLocalFileContent(content) {
|
|
1693
1760
|
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
1694
1761
|
}
|
|
1695
|
-
function readLocalManifest(apmRoot) {
|
|
1696
|
-
const
|
|
1697
|
-
|
|
1762
|
+
function readLocalManifest(apmRoot, projectId) {
|
|
1763
|
+
const manifestPath3 = join4(
|
|
1764
|
+
projectDocumentsDir(apmRoot, projectId),
|
|
1765
|
+
MANIFEST_FILE
|
|
1766
|
+
);
|
|
1767
|
+
if (!existsSync2(manifestPath3)) {
|
|
1698
1768
|
return null;
|
|
1699
1769
|
}
|
|
1700
1770
|
try {
|
|
1701
1771
|
return JSON.parse(
|
|
1702
|
-
readFileSync3(
|
|
1772
|
+
readFileSync3(manifestPath3, "utf8")
|
|
1703
1773
|
);
|
|
1704
1774
|
} catch {
|
|
1705
1775
|
return null;
|
|
1706
1776
|
}
|
|
1707
1777
|
}
|
|
1708
|
-
function listLocalDocumentPaths(apmRoot) {
|
|
1709
|
-
const root = projectDocumentsDir(apmRoot);
|
|
1778
|
+
function listLocalDocumentPaths(apmRoot, projectId) {
|
|
1779
|
+
const root = projectDocumentsDir(apmRoot, projectId);
|
|
1710
1780
|
if (!existsSync2(root)) {
|
|
1711
1781
|
return [];
|
|
1712
1782
|
}
|
|
@@ -1749,7 +1819,11 @@ function diffManifestPaths(remote, local) {
|
|
|
1749
1819
|
}
|
|
1750
1820
|
return { download, deleteLocal };
|
|
1751
1821
|
}
|
|
1752
|
-
async function resolveProjectIdForSync(api, workdirPath) {
|
|
1822
|
+
async function resolveProjectIdForSync(api, workdirPath, options) {
|
|
1823
|
+
const explicit = options?.projectId?.trim();
|
|
1824
|
+
if (explicit) {
|
|
1825
|
+
return { projectId: explicit, diagnostic: null };
|
|
1826
|
+
}
|
|
1753
1827
|
try {
|
|
1754
1828
|
const baseline = await api.cli.workspaceBaseline({ workdirPath });
|
|
1755
1829
|
const projectId = baseline.projectId?.trim() || null;
|
|
@@ -1777,7 +1851,7 @@ async function resolveProjectIdForSync(api, workdirPath) {
|
|
|
1777
1851
|
};
|
|
1778
1852
|
}
|
|
1779
1853
|
}
|
|
1780
|
-
async function syncProjectDocumentsPull(workdirPath, apmDir) {
|
|
1854
|
+
async function syncProjectDocumentsPull(workdirPath, apmDir, options) {
|
|
1781
1855
|
const empty = {
|
|
1782
1856
|
synced: false,
|
|
1783
1857
|
projectId: null,
|
|
@@ -1794,7 +1868,8 @@ async function syncProjectDocumentsPull(workdirPath, apmDir) {
|
|
|
1794
1868
|
const api = createApmApiClient(cfg);
|
|
1795
1869
|
const { projectId, diagnostic } = await resolveProjectIdForSync(
|
|
1796
1870
|
api,
|
|
1797
|
-
workdirPath
|
|
1871
|
+
workdirPath,
|
|
1872
|
+
options
|
|
1798
1873
|
);
|
|
1799
1874
|
if (!projectId) {
|
|
1800
1875
|
console.log(`[apm] \u672A\u80FD\u540C\u6B65\u9879\u76EE\u6587\u6863\u3002
|
|
@@ -1802,14 +1877,16 @@ ${diagnostic ?? ""}`);
|
|
|
1802
1877
|
return empty;
|
|
1803
1878
|
}
|
|
1804
1879
|
const targetApmDir = apmDir ?? workspaceApmDir(workdirPath);
|
|
1805
|
-
const docsDir = projectDocumentsDir(targetApmDir);
|
|
1880
|
+
const docsDir = projectDocumentsDir(targetApmDir, projectId);
|
|
1806
1881
|
await ensureDirExists(docsDir);
|
|
1807
|
-
const { manifest: remoteManifest } = await api.cli.getProjectDocumentManifest(
|
|
1882
|
+
const { manifest: remoteManifest } = await api.cli.getProjectDocumentManifest(
|
|
1883
|
+
{ projectId }
|
|
1884
|
+
);
|
|
1808
1885
|
if (!remoteManifest) {
|
|
1809
1886
|
console.log(`[apm] \u9879\u76EE ${projectId} \u65E0\u9879\u76EE\u6587\u6863 manifest\uFF0C\u8DF3\u8FC7\u540C\u6B65\u3002`);
|
|
1810
1887
|
return { ...empty, projectId };
|
|
1811
1888
|
}
|
|
1812
|
-
const localManifest = readLocalManifest(targetApmDir);
|
|
1889
|
+
const localManifest = readLocalManifest(targetApmDir, projectId);
|
|
1813
1890
|
const { download, deleteLocal } = diffManifestPaths(
|
|
1814
1891
|
remoteManifest,
|
|
1815
1892
|
localManifest
|
|
@@ -1822,7 +1899,7 @@ ${diagnostic ?? ""}`);
|
|
|
1822
1899
|
});
|
|
1823
1900
|
for (const doc of list) {
|
|
1824
1901
|
const absPath = toFsPath(
|
|
1825
|
-
projectDocumentLocalPath(targetApmDir, doc.path)
|
|
1902
|
+
projectDocumentLocalPath(targetApmDir, projectId, doc.path)
|
|
1826
1903
|
);
|
|
1827
1904
|
await ensureDirExists(dirname2(absPath));
|
|
1828
1905
|
writeFileSync4(absPath, doc.content, "utf8");
|
|
@@ -1831,7 +1908,9 @@ ${diagnostic ?? ""}`);
|
|
|
1831
1908
|
}
|
|
1832
1909
|
let deleted = 0;
|
|
1833
1910
|
for (const path19 of deleteLocal) {
|
|
1834
|
-
const absPath = toFsPath(
|
|
1911
|
+
const absPath = toFsPath(
|
|
1912
|
+
projectDocumentLocalPath(targetApmDir, projectId, path19)
|
|
1913
|
+
);
|
|
1835
1914
|
if (existsSync2(absPath)) {
|
|
1836
1915
|
rmSync(absPath, { force: true });
|
|
1837
1916
|
deleted += 1;
|
|
@@ -1844,7 +1923,7 @@ ${diagnostic ?? ""}`);
|
|
|
1844
1923
|
"utf8"
|
|
1845
1924
|
);
|
|
1846
1925
|
console.log(
|
|
1847
|
-
`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: \u4E0B\u8F7D ${downloaded}\uFF0C\u5220\u9664\u672C\u5730 ${deleted}
|
|
1926
|
+
`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: projectId=${projectId} \u4E0B\u8F7D ${downloaded}\uFF0C\u5220\u9664\u672C\u5730 ${deleted} \u2192 .apm/project/${projectId}/`
|
|
1848
1927
|
);
|
|
1849
1928
|
return {
|
|
1850
1929
|
synced: true,
|
|
@@ -1853,14 +1932,18 @@ ${diagnostic ?? ""}`);
|
|
|
1853
1932
|
deleted
|
|
1854
1933
|
};
|
|
1855
1934
|
}
|
|
1856
|
-
async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot) {
|
|
1935
|
+
async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
|
|
1857
1936
|
const api = createApmApiClient(cfg);
|
|
1858
|
-
const { projectId } = await resolveProjectIdForSync(
|
|
1937
|
+
const { projectId } = await resolveProjectIdForSync(
|
|
1938
|
+
api,
|
|
1939
|
+
workdirPath,
|
|
1940
|
+
options
|
|
1941
|
+
);
|
|
1859
1942
|
if (!projectId) {
|
|
1860
1943
|
return 0;
|
|
1861
1944
|
}
|
|
1862
1945
|
const targetApmDir = apmRoot ?? workspaceApmDir(workdirPath);
|
|
1863
|
-
const localPaths = listLocalDocumentPaths(targetApmDir);
|
|
1946
|
+
const localPaths = listLocalDocumentPaths(targetApmDir, projectId);
|
|
1864
1947
|
if (localPaths.length === 0) {
|
|
1865
1948
|
console.log("[apm] \u9879\u76EE\u6587\u6863\u65E0\u672C\u5730\u6587\u4EF6\uFF0C\u8DF3\u8FC7\u63A8\u9001");
|
|
1866
1949
|
return 0;
|
|
@@ -1870,14 +1953,13 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot) {
|
|
|
1870
1953
|
(remoteManifest?.documents ?? []).map((doc) => [doc.path, doc.contentHash])
|
|
1871
1954
|
);
|
|
1872
1955
|
const remoteDescriptionByPath = new Map(
|
|
1873
|
-
(remoteManifest?.documents ?? []).map((doc) => [
|
|
1874
|
-
doc.path,
|
|
1875
|
-
doc.description
|
|
1876
|
-
])
|
|
1956
|
+
(remoteManifest?.documents ?? []).map((doc) => [doc.path, doc.description])
|
|
1877
1957
|
);
|
|
1878
1958
|
let synced = 0;
|
|
1879
1959
|
for (const path19 of localPaths) {
|
|
1880
|
-
const absPath = toFsPath(
|
|
1960
|
+
const absPath = toFsPath(
|
|
1961
|
+
projectDocumentLocalPath(targetApmDir, projectId, path19)
|
|
1962
|
+
);
|
|
1881
1963
|
const content = readFileSync3(absPath, "utf8");
|
|
1882
1964
|
const contentHash = hashLocalFileContent(content);
|
|
1883
1965
|
if (remoteHashByPath.get(path19) === contentHash) {
|
|
@@ -2016,6 +2098,162 @@ async function runLogin(opts) {
|
|
|
2016
2098
|
|
|
2017
2099
|
// src/commands/branch.ts
|
|
2018
2100
|
init_client();
|
|
2101
|
+
|
|
2102
|
+
// src/workspace-repos.ts
|
|
2103
|
+
import {
|
|
2104
|
+
existsSync as existsSync4,
|
|
2105
|
+
mkdirSync as mkdirSync3,
|
|
2106
|
+
readFileSync as readFileSync5,
|
|
2107
|
+
readdirSync as readdirSync3,
|
|
2108
|
+
statSync as statSync2,
|
|
2109
|
+
writeFileSync as writeFileSync6
|
|
2110
|
+
} from "fs";
|
|
2111
|
+
import { basename as basename2, dirname as dirname3, join as join6, relative as relative2, resolve as resolve3 } from "path";
|
|
2112
|
+
var WORKSPACE_REPOS_MANIFEST = "workspace-repos.json";
|
|
2113
|
+
var WORKSPACE_REPOS_VERSION = 1;
|
|
2114
|
+
function manifestPath(workdir) {
|
|
2115
|
+
return join6(workspaceApmDir(workdir), WORKSPACE_REPOS_MANIFEST);
|
|
2116
|
+
}
|
|
2117
|
+
function absoluteRepoPath(workdir, entry) {
|
|
2118
|
+
if (entry.path === "." || entry.path === "") {
|
|
2119
|
+
return workdir;
|
|
2120
|
+
}
|
|
2121
|
+
return resolve3(workdir, entry.path);
|
|
2122
|
+
}
|
|
2123
|
+
function normalizeRepoEntry(raw) {
|
|
2124
|
+
if (!raw || typeof raw !== "object") return null;
|
|
2125
|
+
const o = raw;
|
|
2126
|
+
if (typeof o.path !== "string" || !o.path.trim()) return null;
|
|
2127
|
+
const entry = {
|
|
2128
|
+
path: o.path.trim().replace(/\\/g, "/")
|
|
2129
|
+
};
|
|
2130
|
+
if (typeof o.remoteUrl === "string" && o.remoteUrl.trim()) {
|
|
2131
|
+
entry.remoteUrl = o.remoteUrl.trim();
|
|
2132
|
+
} else if (o.remoteUrl === null) {
|
|
2133
|
+
entry.remoteUrl = null;
|
|
2134
|
+
}
|
|
2135
|
+
return entry;
|
|
2136
|
+
}
|
|
2137
|
+
function readManifest(workdir) {
|
|
2138
|
+
const path19 = toFsPath(manifestPath(workdir));
|
|
2139
|
+
if (!existsSync4(path19)) {
|
|
2140
|
+
return null;
|
|
2141
|
+
}
|
|
2142
|
+
try {
|
|
2143
|
+
const raw = JSON.parse(
|
|
2144
|
+
readFileSync5(path19, "utf8")
|
|
2145
|
+
);
|
|
2146
|
+
if (raw?.version !== WORKSPACE_REPOS_VERSION) {
|
|
2147
|
+
return null;
|
|
2148
|
+
}
|
|
2149
|
+
if (raw.kind !== "single" && raw.kind !== "multi") {
|
|
2150
|
+
return null;
|
|
2151
|
+
}
|
|
2152
|
+
if (!Array.isArray(raw.repos) || raw.repos.length === 0) {
|
|
2153
|
+
return null;
|
|
2154
|
+
}
|
|
2155
|
+
if (typeof raw.workdir !== "string" || !raw.workdir.trim()) {
|
|
2156
|
+
return null;
|
|
2157
|
+
}
|
|
2158
|
+
const repos = raw.repos.map((item) => normalizeRepoEntry(item)).filter((item) => item != null);
|
|
2159
|
+
if (repos.length === 0) {
|
|
2160
|
+
return null;
|
|
2161
|
+
}
|
|
2162
|
+
return {
|
|
2163
|
+
version: WORKSPACE_REPOS_VERSION,
|
|
2164
|
+
kind: raw.kind,
|
|
2165
|
+
workdir: raw.workdir,
|
|
2166
|
+
repos,
|
|
2167
|
+
scannedAt: typeof raw.scannedAt === "string" && raw.scannedAt.trim() ? raw.scannedAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
2168
|
+
};
|
|
2169
|
+
} catch {
|
|
2170
|
+
return null;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
function writeManifest(workdir, manifest) {
|
|
2174
|
+
const apmDir = toFsPath(workspaceApmDir(workdir));
|
|
2175
|
+
mkdirSync3(apmDir, { recursive: true });
|
|
2176
|
+
const path19 = toFsPath(manifestPath(workdir));
|
|
2177
|
+
writeFileSync6(path19, `${JSON.stringify(manifest, null, 2)}
|
|
2178
|
+
`, "utf8");
|
|
2179
|
+
}
|
|
2180
|
+
function isPathInsideOrEqual(parentAbs, childAbs) {
|
|
2181
|
+
const parent = normalizeWorkdirPath(parentAbs);
|
|
2182
|
+
const child = normalizeWorkdirPath(childAbs);
|
|
2183
|
+
if (child === parent) return true;
|
|
2184
|
+
const prefix = parent.endsWith("/") ? parent : `${parent}/`;
|
|
2185
|
+
return child.startsWith(prefix);
|
|
2186
|
+
}
|
|
2187
|
+
function findWorkspaceReposManifestNearPath(startDirInput) {
|
|
2188
|
+
let current = resolve3(startDirInput);
|
|
2189
|
+
for (; ; ) {
|
|
2190
|
+
const candidates = /* @__PURE__ */ new Set([normalizeWorkdirPath(current)]);
|
|
2191
|
+
try {
|
|
2192
|
+
if (existsSync4(toFsPath(current))) {
|
|
2193
|
+
candidates.add(resolveWorkdirPath(current));
|
|
2194
|
+
}
|
|
2195
|
+
} catch {
|
|
2196
|
+
}
|
|
2197
|
+
for (const candidate of candidates) {
|
|
2198
|
+
const cached = readManifest(candidate);
|
|
2199
|
+
if (!cached) continue;
|
|
2200
|
+
const cachedWorkdir = resolveWorkdirPath(cached.workdir);
|
|
2201
|
+
const candidateNorm = resolveWorkdirPath(candidate);
|
|
2202
|
+
if (cachedWorkdir === candidateNorm) {
|
|
2203
|
+
return { ...cached, workdir: cachedWorkdir };
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
const parent = dirname3(current);
|
|
2207
|
+
if (parent === current) {
|
|
2208
|
+
return null;
|
|
2209
|
+
}
|
|
2210
|
+
current = parent;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
function matchWorkspaceRepoEntryForPath(manifest, pathInput) {
|
|
2214
|
+
const target = resolveWorkdirPath(pathInput);
|
|
2215
|
+
const workdir = resolveWorkdirPath(manifest.workdir);
|
|
2216
|
+
let best = null;
|
|
2217
|
+
let bestLen = -1;
|
|
2218
|
+
for (const entry of manifest.repos) {
|
|
2219
|
+
const abs = resolveWorkdirPath(absoluteRepoPath(workdir, entry));
|
|
2220
|
+
if (!isPathInsideOrEqual(abs, target)) {
|
|
2221
|
+
continue;
|
|
2222
|
+
}
|
|
2223
|
+
if (abs.length > bestLen) {
|
|
2224
|
+
best = entry;
|
|
2225
|
+
bestLen = abs.length;
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
return best;
|
|
2229
|
+
}
|
|
2230
|
+
async function enrichWorkspaceReposRemoteUrls(manifest) {
|
|
2231
|
+
let changed = false;
|
|
2232
|
+
const repos = [];
|
|
2233
|
+
for (const entry of manifest.repos) {
|
|
2234
|
+
const abs = absoluteRepoPath(manifest.workdir, entry);
|
|
2235
|
+
const remoteUrl = await tryReadHttpsGitOriginUrl(abs);
|
|
2236
|
+
const next = {
|
|
2237
|
+
path: entry.path,
|
|
2238
|
+
remoteUrl: remoteUrl || null
|
|
2239
|
+
};
|
|
2240
|
+
if ((entry.remoteUrl ?? null) !== next.remoteUrl) {
|
|
2241
|
+
changed = true;
|
|
2242
|
+
}
|
|
2243
|
+
repos.push(next);
|
|
2244
|
+
}
|
|
2245
|
+
const nextManifest = {
|
|
2246
|
+
...manifest,
|
|
2247
|
+
repos,
|
|
2248
|
+
scannedAt: changed ? (/* @__PURE__ */ new Date()).toISOString() : manifest.scannedAt
|
|
2249
|
+
};
|
|
2250
|
+
if (changed) {
|
|
2251
|
+
writeManifest(manifest.workdir, nextManifest);
|
|
2252
|
+
}
|
|
2253
|
+
return nextManifest;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// src/commands/branch.ts
|
|
2019
2257
|
var SESSION_BRANCH_PREFIX = "feat/session-";
|
|
2020
2258
|
function branchNameForSession(sessionId) {
|
|
2021
2259
|
const id = sessionId.trim();
|
|
@@ -2465,8 +2703,8 @@ async function runCleanBranches(options = {}) {
|
|
|
2465
2703
|
|
|
2466
2704
|
// src/commands/pull.ts
|
|
2467
2705
|
init_client();
|
|
2468
|
-
import { writeFileSync as
|
|
2469
|
-
import { join as
|
|
2706
|
+
import { writeFileSync as writeFileSync10 } from "fs";
|
|
2707
|
+
import { join as join10 } from "path";
|
|
2470
2708
|
import { stringify as yamlStringify } from "yaml";
|
|
2471
2709
|
|
|
2472
2710
|
// src/session-messages-xml.ts
|
|
@@ -2499,8 +2737,8 @@ function formatSessionMessagesXml(sessionId, messages) {
|
|
|
2499
2737
|
}
|
|
2500
2738
|
|
|
2501
2739
|
// src/commands/sync-session-attachments.ts
|
|
2502
|
-
import { existsSync as
|
|
2503
|
-
import { join as
|
|
2740
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
2741
|
+
import { join as join7 } from "path";
|
|
2504
2742
|
var MANIFEST_FILE2 = ".sync-manifest.json";
|
|
2505
2743
|
async function downloadAttachment(cfg, attachmentId) {
|
|
2506
2744
|
const base = cfg.baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -2516,13 +2754,13 @@ async function downloadAttachment(cfg, attachmentId) {
|
|
|
2516
2754
|
return Buffer.from(await res.arrayBuffer());
|
|
2517
2755
|
}
|
|
2518
2756
|
function loadManifest(dir) {
|
|
2519
|
-
const path19 =
|
|
2520
|
-
if (!
|
|
2757
|
+
const path19 = join7(dir, MANIFEST_FILE2);
|
|
2758
|
+
if (!existsSync5(path19)) {
|
|
2521
2759
|
return { version: 1, attachments: {} };
|
|
2522
2760
|
}
|
|
2523
2761
|
try {
|
|
2524
2762
|
const parsed = JSON.parse(
|
|
2525
|
-
|
|
2763
|
+
readFileSync6(path19, "utf8")
|
|
2526
2764
|
);
|
|
2527
2765
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
2528
2766
|
return parsed;
|
|
@@ -2532,15 +2770,15 @@ function loadManifest(dir) {
|
|
|
2532
2770
|
return { version: 1, attachments: {} };
|
|
2533
2771
|
}
|
|
2534
2772
|
function saveManifest(dir, manifest) {
|
|
2535
|
-
|
|
2536
|
-
|
|
2773
|
+
writeFileSync7(
|
|
2774
|
+
join7(dir, MANIFEST_FILE2),
|
|
2537
2775
|
`${JSON.stringify(manifest, null, 2)}
|
|
2538
2776
|
`,
|
|
2539
2777
|
"utf8"
|
|
2540
2778
|
);
|
|
2541
2779
|
}
|
|
2542
2780
|
function isAttachmentUpToDate(entry, item, dest) {
|
|
2543
|
-
if (!entry || !
|
|
2781
|
+
if (!entry || !existsSync5(dest)) return false;
|
|
2544
2782
|
if (entry.name !== item.name) return false;
|
|
2545
2783
|
const createdAt = item.createdAt ?? "";
|
|
2546
2784
|
return entry.createdAt === createdAt;
|
|
@@ -2555,7 +2793,7 @@ async function syncAttachmentsToDirectory(cfg, attachments, dir, logLabel) {
|
|
|
2555
2793
|
const nextManifest = { version: 1, attachments: {} };
|
|
2556
2794
|
const names = [];
|
|
2557
2795
|
for (const item of attachments) {
|
|
2558
|
-
const dest =
|
|
2796
|
+
const dest = join7(dir, item.name);
|
|
2559
2797
|
const entry = manifest.attachments[item.id];
|
|
2560
2798
|
const createdAt = item.createdAt ?? "";
|
|
2561
2799
|
names.push(item.name);
|
|
@@ -2565,7 +2803,7 @@ async function syncAttachmentsToDirectory(cfg, attachments, dir, logLabel) {
|
|
|
2565
2803
|
continue;
|
|
2566
2804
|
}
|
|
2567
2805
|
const buffer = await downloadAttachment(cfg, item.id);
|
|
2568
|
-
|
|
2806
|
+
writeFileSync7(dest, buffer);
|
|
2569
2807
|
nextManifest.attachments[item.id] = {
|
|
2570
2808
|
name: item.name,
|
|
2571
2809
|
createdAt
|
|
@@ -2576,7 +2814,7 @@ async function syncAttachmentsToDirectory(cfg, attachments, dir, logLabel) {
|
|
|
2576
2814
|
return names;
|
|
2577
2815
|
}
|
|
2578
2816
|
async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
|
|
2579
|
-
const dir =
|
|
2817
|
+
const dir = join7(sessionDir(sessionId, apmRoot), SESSION_ATTACHMENTS_SUBDIR);
|
|
2580
2818
|
return syncAttachmentsToDirectory(
|
|
2581
2819
|
cfg,
|
|
2582
2820
|
attachments,
|
|
@@ -2587,65 +2825,65 @@ async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
|
|
|
2587
2825
|
|
|
2588
2826
|
// src/rules-sync.ts
|
|
2589
2827
|
init_client();
|
|
2590
|
-
import { basename as
|
|
2591
|
-
import { existsSync as
|
|
2828
|
+
import { basename as basename3, extname as extname2, join as join9 } from "path";
|
|
2829
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync9 } from "fs";
|
|
2592
2830
|
|
|
2593
2831
|
// src/skills-sync.ts
|
|
2594
2832
|
import {
|
|
2595
2833
|
copyFileSync as copyFileSync2,
|
|
2596
2834
|
cpSync,
|
|
2597
|
-
existsSync as
|
|
2598
|
-
mkdirSync as
|
|
2599
|
-
readdirSync as
|
|
2835
|
+
existsSync as existsSync6,
|
|
2836
|
+
mkdirSync as mkdirSync4,
|
|
2837
|
+
readdirSync as readdirSync4,
|
|
2600
2838
|
rmSync as rmSync2,
|
|
2601
|
-
statSync as
|
|
2602
|
-
writeFileSync as
|
|
2839
|
+
statSync as statSync3,
|
|
2840
|
+
writeFileSync as writeFileSync8
|
|
2603
2841
|
} from "fs";
|
|
2604
|
-
import { join as
|
|
2605
|
-
var AGENTS_TEMPLATE_PATH =
|
|
2606
|
-
var BASE_SKILLS_TEMPLATE_DIR =
|
|
2607
|
-
var BASE_RULES_TEMPLATE_DIR =
|
|
2842
|
+
import { join as join8 } from "path";
|
|
2843
|
+
var AGENTS_TEMPLATE_PATH = join8(CLI_TEMPLATE_DIR, "AGENTS.md");
|
|
2844
|
+
var BASE_SKILLS_TEMPLATE_DIR = join8(CLI_TEMPLATE_DIR, "skills");
|
|
2845
|
+
var BASE_RULES_TEMPLATE_DIR = join8(CLI_TEMPLATE_DIR, "rules");
|
|
2608
2846
|
function sanitizeSkillDirName(name) {
|
|
2609
2847
|
const trimmed = name.trim();
|
|
2610
2848
|
if (!trimmed) return "skill";
|
|
2611
2849
|
return trimmed.replace(/[/\\:*?"<>|]/g, "_");
|
|
2612
2850
|
}
|
|
2613
2851
|
function listBaseSkillDirNames() {
|
|
2614
|
-
if (!
|
|
2615
|
-
return
|
|
2616
|
-
const path19 =
|
|
2617
|
-
return
|
|
2852
|
+
if (!existsSync6(BASE_SKILLS_TEMPLATE_DIR)) return [];
|
|
2853
|
+
return readdirSync4(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
|
|
2854
|
+
const path19 = join8(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
2855
|
+
return statSync3(path19).isDirectory();
|
|
2618
2856
|
});
|
|
2619
2857
|
}
|
|
2620
2858
|
function syncAgentsGuide(apmDir) {
|
|
2621
|
-
if (!
|
|
2622
|
-
|
|
2623
|
-
copyFileSync2(AGENTS_TEMPLATE_PATH,
|
|
2859
|
+
if (!existsSync6(AGENTS_TEMPLATE_PATH)) return false;
|
|
2860
|
+
mkdirSync4(apmDir, { recursive: true });
|
|
2861
|
+
copyFileSync2(AGENTS_TEMPLATE_PATH, join8(apmDir, "AGENTS.md"));
|
|
2624
2862
|
return true;
|
|
2625
2863
|
}
|
|
2626
2864
|
function listBaseRuleFileNames() {
|
|
2627
|
-
if (!
|
|
2628
|
-
return
|
|
2629
|
-
const path19 =
|
|
2630
|
-
return
|
|
2865
|
+
if (!existsSync6(BASE_RULES_TEMPLATE_DIR)) return [];
|
|
2866
|
+
return readdirSync4(BASE_RULES_TEMPLATE_DIR).filter((name) => {
|
|
2867
|
+
const path19 = join8(BASE_RULES_TEMPLATE_DIR, name);
|
|
2868
|
+
return statSync3(path19).isFile();
|
|
2631
2869
|
});
|
|
2632
2870
|
}
|
|
2633
2871
|
function syncBaseRules(rulesDir) {
|
|
2634
|
-
|
|
2872
|
+
mkdirSync4(rulesDir, { recursive: true });
|
|
2635
2873
|
const names = listBaseRuleFileNames();
|
|
2636
2874
|
for (const name of names) {
|
|
2637
|
-
const src =
|
|
2638
|
-
const dest =
|
|
2875
|
+
const src = join8(BASE_RULES_TEMPLATE_DIR, name);
|
|
2876
|
+
const dest = join8(rulesDir, name);
|
|
2639
2877
|
copyFileSync2(src, dest);
|
|
2640
2878
|
}
|
|
2641
2879
|
return names;
|
|
2642
2880
|
}
|
|
2643
2881
|
function syncBaseSkills(skillsDir) {
|
|
2644
|
-
|
|
2882
|
+
mkdirSync4(skillsDir, { recursive: true });
|
|
2645
2883
|
const names = listBaseSkillDirNames();
|
|
2646
2884
|
for (const name of names) {
|
|
2647
|
-
const src =
|
|
2648
|
-
const dest =
|
|
2885
|
+
const src = join8(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
2886
|
+
const dest = join8(skillsDir, name);
|
|
2649
2887
|
cpSync(src, dest, { recursive: true, force: true });
|
|
2650
2888
|
}
|
|
2651
2889
|
return names;
|
|
@@ -2662,16 +2900,16 @@ function syncSupplementarySkills(skillsDir, list) {
|
|
|
2662
2900
|
skipped.push(dirName);
|
|
2663
2901
|
continue;
|
|
2664
2902
|
}
|
|
2665
|
-
const skillDir =
|
|
2666
|
-
|
|
2667
|
-
|
|
2903
|
+
const skillDir = join8(skillsDir, dirName);
|
|
2904
|
+
mkdirSync4(skillDir, { recursive: true });
|
|
2905
|
+
writeFileSync8(join8(skillDir, "SKILL.md"), skill.content ?? "", "utf8");
|
|
2668
2906
|
written.push(dirName);
|
|
2669
2907
|
}
|
|
2670
2908
|
const removed = [];
|
|
2671
|
-
if (!
|
|
2672
|
-
for (const entry of
|
|
2673
|
-
const full =
|
|
2674
|
-
if (!
|
|
2909
|
+
if (!existsSync6(skillsDir)) return { written, skipped, removed };
|
|
2910
|
+
for (const entry of readdirSync4(skillsDir)) {
|
|
2911
|
+
const full = join8(skillsDir, entry);
|
|
2912
|
+
if (!statSync3(full).isDirectory()) continue;
|
|
2675
2913
|
if (baseNames.has(entry)) continue;
|
|
2676
2914
|
if (apiDirNames.has(entry)) continue;
|
|
2677
2915
|
rmSync2(full, { recursive: true, force: true });
|
|
@@ -2690,13 +2928,13 @@ function ruleLocalFileName(ruleName) {
|
|
|
2690
2928
|
return `${sanitized}.md`;
|
|
2691
2929
|
}
|
|
2692
2930
|
function loadManifest2(rulesDir) {
|
|
2693
|
-
const path19 =
|
|
2694
|
-
if (!
|
|
2931
|
+
const path19 = join9(rulesDir, MANIFEST_FILE3);
|
|
2932
|
+
if (!existsSync7(toFsPath(path19))) {
|
|
2695
2933
|
return { version: 1, rules: {} };
|
|
2696
2934
|
}
|
|
2697
2935
|
try {
|
|
2698
2936
|
const parsed = JSON.parse(
|
|
2699
|
-
|
|
2937
|
+
readFileSync7(toFsPath(path19), "utf8")
|
|
2700
2938
|
);
|
|
2701
2939
|
if (parsed?.version === 1 && parsed.rules && typeof parsed.rules === "object") {
|
|
2702
2940
|
return parsed;
|
|
@@ -2706,29 +2944,29 @@ function loadManifest2(rulesDir) {
|
|
|
2706
2944
|
return { version: 1, rules: {} };
|
|
2707
2945
|
}
|
|
2708
2946
|
function saveManifest2(rulesDir, manifest) {
|
|
2709
|
-
|
|
2710
|
-
toFsPath(
|
|
2947
|
+
writeFileSync9(
|
|
2948
|
+
toFsPath(join9(rulesDir, MANIFEST_FILE3)),
|
|
2711
2949
|
`${JSON.stringify(manifest, null, 2)}
|
|
2712
2950
|
`,
|
|
2713
2951
|
"utf8"
|
|
2714
2952
|
);
|
|
2715
2953
|
}
|
|
2716
2954
|
function isBaseRuleFileName(fileName) {
|
|
2717
|
-
return listBaseRuleFileNames().includes(
|
|
2955
|
+
return listBaseRuleFileNames().includes(basename3(fileName));
|
|
2718
2956
|
}
|
|
2719
2957
|
function isRuleUpToDate(entry, rule, dest) {
|
|
2720
|
-
if (!entry || !
|
|
2958
|
+
if (!entry || !existsSync7(toFsPath(dest))) return false;
|
|
2721
2959
|
if (entry.fileName !== ruleLocalFileName(rule.name)) return false;
|
|
2722
2960
|
const updatedAt = rule.updatedAt ?? "";
|
|
2723
2961
|
if (entry.updatedAt !== updatedAt) return false;
|
|
2724
|
-
const localContent =
|
|
2962
|
+
const localContent = readFileSync7(toFsPath(dest), "utf8");
|
|
2725
2963
|
return localContent === (rule.content ?? "");
|
|
2726
2964
|
}
|
|
2727
2965
|
async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
2728
2966
|
const api = createApmApiClient(cfg);
|
|
2729
2967
|
const baseline = await resolveBranchBaseline(api, sessionId, workdirPath);
|
|
2730
2968
|
const repositoryId = baseline.repositoryId;
|
|
2731
|
-
const rulesDir =
|
|
2969
|
+
const rulesDir = join9(apmRoot ?? workspaceApmDir(workdirPath), "rules");
|
|
2732
2970
|
await ensureDirExists(rulesDir);
|
|
2733
2971
|
if (!repositoryId) {
|
|
2734
2972
|
console.log(
|
|
@@ -2745,7 +2983,7 @@ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
|
2745
2983
|
for (const rule of list) {
|
|
2746
2984
|
remoteIds.add(rule.id);
|
|
2747
2985
|
const fileName = ruleLocalFileName(rule.name);
|
|
2748
|
-
const dest =
|
|
2986
|
+
const dest = join9(rulesDir, fileName);
|
|
2749
2987
|
const entry = manifest.rules[rule.id];
|
|
2750
2988
|
const updatedAt = rule.updatedAt ?? "";
|
|
2751
2989
|
if (isRuleUpToDate(entry, rule, dest)) {
|
|
@@ -2754,7 +2992,7 @@ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
|
2754
2992
|
console.log(`[apm] \u89C4\u5219\u65E0\u53D8\u5316\uFF0C\u5DF2\u8DF3\u8FC7: rules/${fileName}`);
|
|
2755
2993
|
continue;
|
|
2756
2994
|
}
|
|
2757
|
-
|
|
2995
|
+
writeFileSync9(toFsPath(dest), rule.content ?? "", "utf8");
|
|
2758
2996
|
nextManifest.rules[rule.id] = { fileName, updatedAt };
|
|
2759
2997
|
written.push(fileName);
|
|
2760
2998
|
console.log(`[apm] \u5DF2\u540C\u6B65\u5E73\u53F0\u89C4\u5219: rules/${fileName}`);
|
|
@@ -2763,8 +3001,8 @@ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
|
|
|
2763
3001
|
for (const [ruleId, entry] of Object.entries(manifest.rules)) {
|
|
2764
3002
|
if (remoteIds.has(ruleId)) continue;
|
|
2765
3003
|
if (isBaseRuleFileName(entry.fileName)) continue;
|
|
2766
|
-
const dest =
|
|
2767
|
-
if (
|
|
3004
|
+
const dest = join9(rulesDir, entry.fileName);
|
|
3005
|
+
if (existsSync7(toFsPath(dest))) {
|
|
2768
3006
|
rmSync3(toFsPath(dest), { force: true });
|
|
2769
3007
|
}
|
|
2770
3008
|
removed.push(entry.fileName);
|
|
@@ -2795,20 +3033,20 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
2795
3033
|
const dir = sessionDir(trimmedId, apmRoot);
|
|
2796
3034
|
const docsDir = sessionDocsDir(trimmedId, apmRoot);
|
|
2797
3035
|
await ensureDirExists(docsDir);
|
|
2798
|
-
|
|
3036
|
+
writeFileSync10(
|
|
2799
3037
|
sessionRulePath(trimmedId, apmRoot),
|
|
2800
3038
|
detail.description ?? "",
|
|
2801
3039
|
"utf8"
|
|
2802
3040
|
);
|
|
2803
|
-
|
|
3041
|
+
writeFileSync10(
|
|
2804
3042
|
sessionTaskPath(trimmedId, apmRoot),
|
|
2805
3043
|
detail.task.description ?? "",
|
|
2806
3044
|
"utf8"
|
|
2807
3045
|
);
|
|
2808
|
-
|
|
3046
|
+
writeFileSync10(sessionTodoPath(trimmedId, apmRoot), detail.todo ?? "", "utf8");
|
|
2809
3047
|
for (const doc of documents) {
|
|
2810
3048
|
const fileName = documentLocalFileName(doc.name);
|
|
2811
|
-
|
|
3049
|
+
writeFileSync10(join10(docsDir, fileName), doc.content ?? "", "utf8");
|
|
2812
3050
|
}
|
|
2813
3051
|
const sessionYaml = yamlStringify(
|
|
2814
3052
|
{
|
|
@@ -2825,13 +3063,13 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
2825
3063
|
},
|
|
2826
3064
|
{ lineWidth: 0 }
|
|
2827
3065
|
);
|
|
2828
|
-
|
|
3066
|
+
writeFileSync10(
|
|
2829
3067
|
sessionYamlPath(trimmedId, apmRoot),
|
|
2830
3068
|
sessionYaml.endsWith("\n") ? sessionYaml : `${sessionYaml}
|
|
2831
3069
|
`,
|
|
2832
3070
|
"utf8"
|
|
2833
3071
|
);
|
|
2834
|
-
|
|
3072
|
+
writeFileSync10(
|
|
2835
3073
|
sessionMessagesXmlPath(trimmedId, apmRoot),
|
|
2836
3074
|
formatSessionMessagesXml(trimmedId, messages),
|
|
2837
3075
|
"utf8"
|
|
@@ -2848,15 +3086,15 @@ async function runPull(sessionId, remoteWorkdir) {
|
|
|
2848
3086
|
import { spawnSync } from "child_process";
|
|
2849
3087
|
|
|
2850
3088
|
// src/version.ts
|
|
2851
|
-
import { readFileSync as
|
|
2852
|
-
import { dirname as
|
|
3089
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
3090
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
2853
3091
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2854
3092
|
var CLI_PACKAGE_NAME = "ai-project-manage-cli";
|
|
2855
3093
|
function readCliVersion() {
|
|
2856
3094
|
try {
|
|
2857
|
-
const dir =
|
|
2858
|
-
const pkgPath =
|
|
2859
|
-
const pkg = JSON.parse(
|
|
3095
|
+
const dir = dirname4(fileURLToPath2(import.meta.url));
|
|
3096
|
+
const pkgPath = join11(dir, "..", "package.json");
|
|
3097
|
+
const pkg = JSON.parse(readFileSync8(pkgPath, "utf8"));
|
|
2860
3098
|
return pkg.version ?? "0.0.0";
|
|
2861
3099
|
} catch {
|
|
2862
3100
|
return "0.0.0";
|
|
@@ -3010,15 +3248,15 @@ async function runUpdate(options = {}) {
|
|
|
3010
3248
|
|
|
3011
3249
|
// src/commands/update-skills.ts
|
|
3012
3250
|
init_client();
|
|
3013
|
-
import { existsSync as
|
|
3014
|
-
import { join as
|
|
3251
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, statSync as statSync4 } from "fs";
|
|
3252
|
+
import { join as join12 } from "path";
|
|
3015
3253
|
async function syncWorkspaceSkills(cfg, workdir) {
|
|
3016
3254
|
const apmDir = workspaceApmDir(workdir);
|
|
3017
3255
|
const fsApmDir = toFsPath(apmDir);
|
|
3018
|
-
if (!
|
|
3256
|
+
if (!existsSync8(fsApmDir)) {
|
|
3019
3257
|
throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3020
3258
|
}
|
|
3021
|
-
const apmStat =
|
|
3259
|
+
const apmStat = statSync4(fsApmDir);
|
|
3022
3260
|
if (!apmStat.isDirectory()) {
|
|
3023
3261
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
3024
3262
|
}
|
|
@@ -3027,13 +3265,13 @@ async function syncWorkspaceSkills(cfg, workdir) {
|
|
|
3027
3265
|
if (syncAgentsGuide(apmDir)) {
|
|
3028
3266
|
console.log("[apm] \u5DF2\u540C\u6B65 APM \u6307\u5357: .apm/AGENTS.md");
|
|
3029
3267
|
}
|
|
3030
|
-
const rulesDir =
|
|
3268
|
+
const rulesDir = join12(apmDir, "rules");
|
|
3031
3269
|
const ruleNames = syncBaseRules(rulesDir);
|
|
3032
3270
|
for (const name of ruleNames) {
|
|
3033
3271
|
console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u89C4\u5219: rules/${name}`);
|
|
3034
3272
|
}
|
|
3035
|
-
const skillsDir =
|
|
3036
|
-
|
|
3273
|
+
const skillsDir = join12(apmDir, "skills");
|
|
3274
|
+
mkdirSync5(toFsPath(skillsDir), { recursive: true });
|
|
3037
3275
|
const baseNames = syncBaseSkills(skillsDir);
|
|
3038
3276
|
for (const name of baseNames) {
|
|
3039
3277
|
console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u6280\u80FD: skills/${name}/`);
|
|
@@ -3059,11 +3297,11 @@ async function syncWorkspaceSkills(cfg, workdir) {
|
|
|
3059
3297
|
}
|
|
3060
3298
|
async function runUpdateSkills() {
|
|
3061
3299
|
const apmDir = workspaceApmDir();
|
|
3062
|
-
if (!
|
|
3300
|
+
if (!existsSync8(apmDir)) {
|
|
3063
3301
|
console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3064
3302
|
process.exit(1);
|
|
3065
3303
|
}
|
|
3066
|
-
const apmStat =
|
|
3304
|
+
const apmStat = statSync4(apmDir);
|
|
3067
3305
|
if (!apmStat.isDirectory()) {
|
|
3068
3306
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
3069
3307
|
}
|
|
@@ -3072,15 +3310,15 @@ async function runUpdateSkills() {
|
|
|
3072
3310
|
}
|
|
3073
3311
|
|
|
3074
3312
|
// src/commands/sync-deploy-config.ts
|
|
3075
|
-
import { existsSync as
|
|
3313
|
+
import { existsSync as existsSync9, statSync as statSync5 } from "fs";
|
|
3076
3314
|
async function runSyncDeployConfig() {
|
|
3077
3315
|
const workdir = resolveWorkdirPath();
|
|
3078
3316
|
const apmDir = workspaceApmDir(workdir);
|
|
3079
|
-
if (!
|
|
3317
|
+
if (!existsSync9(apmDir)) {
|
|
3080
3318
|
console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3081
3319
|
process.exit(1);
|
|
3082
3320
|
}
|
|
3083
|
-
const apmStat =
|
|
3321
|
+
const apmStat = statSync5(apmDir);
|
|
3084
3322
|
if (!apmStat.isDirectory()) {
|
|
3085
3323
|
throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
|
|
3086
3324
|
}
|
|
@@ -3111,8 +3349,8 @@ async function runSyncProjectDocuments(options) {
|
|
|
3111
3349
|
}
|
|
3112
3350
|
|
|
3113
3351
|
// src/commands/sync-document.ts
|
|
3114
|
-
import { existsSync as
|
|
3115
|
-
import { basename as
|
|
3352
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
|
|
3353
|
+
import { basename as basename4 } from "path";
|
|
3116
3354
|
|
|
3117
3355
|
// src/assumptions/local-validate.ts
|
|
3118
3356
|
var NO_ASSUMPTIONS_RE = /无[,,]?\s*口径均有依据/;
|
|
@@ -3282,13 +3520,13 @@ init_client();
|
|
|
3282
3520
|
|
|
3283
3521
|
// src/commands/sync-session-documents.ts
|
|
3284
3522
|
init_client();
|
|
3285
|
-
import { existsSync as
|
|
3286
|
-
import { join as
|
|
3523
|
+
import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
|
|
3524
|
+
import { join as join13 } from "path";
|
|
3287
3525
|
function listLocalMarkdownFiles(docsDir) {
|
|
3288
|
-
if (!
|
|
3526
|
+
if (!existsSync10(docsDir)) {
|
|
3289
3527
|
return [];
|
|
3290
3528
|
}
|
|
3291
|
-
return
|
|
3529
|
+
return readdirSync5(docsDir).filter(
|
|
3292
3530
|
(name) => name.toLowerCase().endsWith(".md")
|
|
3293
3531
|
);
|
|
3294
3532
|
}
|
|
@@ -3300,8 +3538,8 @@ function remoteDocumentByLocalName(remoteDocuments, localFileName) {
|
|
|
3300
3538
|
});
|
|
3301
3539
|
}
|
|
3302
3540
|
async function upsertLocalDocumentFile(api, sessionId, docsDir, fileName) {
|
|
3303
|
-
const absPath =
|
|
3304
|
-
const content =
|
|
3541
|
+
const absPath = join13(docsDir, fileName);
|
|
3542
|
+
const content = readFileSync9(absPath, "utf8");
|
|
3305
3543
|
const name = documentPlatformName(absPath);
|
|
3306
3544
|
return api.cli.upsertDocument({
|
|
3307
3545
|
sessionId,
|
|
@@ -3323,8 +3561,8 @@ async function syncSessionDocuments(cfg, sessionId, apmRoot, options) {
|
|
|
3323
3561
|
const remoteDocuments = options?.remoteDocuments ?? await api.cli.listDocuments({ sessionId: trimmedSessionId });
|
|
3324
3562
|
let synced = 0;
|
|
3325
3563
|
for (const fileName of localFiles) {
|
|
3326
|
-
const absPath =
|
|
3327
|
-
const content =
|
|
3564
|
+
const absPath = join13(docsDir, fileName);
|
|
3565
|
+
const content = readFileSync9(absPath, "utf8");
|
|
3328
3566
|
const remote = remoteDocumentByLocalName(remoteDocuments, fileName);
|
|
3329
3567
|
if (remote && remote.content === content) {
|
|
3330
3568
|
continue;
|
|
@@ -3357,7 +3595,7 @@ async function runSyncDocument(sessionId, options) {
|
|
|
3357
3595
|
process.exit(1);
|
|
3358
3596
|
}
|
|
3359
3597
|
const absPath = resolveSessionDocumentPath(trimmedSessionId, fileArg);
|
|
3360
|
-
if (!
|
|
3598
|
+
if (!existsSync11(absPath)) {
|
|
3361
3599
|
const docsDir2 = sessionDocsDir(trimmedSessionId);
|
|
3362
3600
|
console.error(
|
|
3363
3601
|
`[apm] \u6587\u6863\u4E0D\u5B58\u5728: ${absPath}
|
|
@@ -3365,10 +3603,10 @@ async function runSyncDocument(sessionId, options) {
|
|
|
3365
3603
|
);
|
|
3366
3604
|
process.exit(1);
|
|
3367
3605
|
}
|
|
3368
|
-
const fileName =
|
|
3606
|
+
const fileName = basename4(absPath);
|
|
3369
3607
|
const assumptionSource = resolveAssumptionSourceFromFileName(fileName);
|
|
3370
3608
|
if (assumptionSource) {
|
|
3371
|
-
const content =
|
|
3609
|
+
const content = readFileSync10(absPath, "utf8");
|
|
3372
3610
|
const validation = validateAssumptionsMarkdown(content, assumptionSource);
|
|
3373
3611
|
if (!validation.ok) {
|
|
3374
3612
|
printAssumptionValidationResult(validation);
|
|
@@ -3385,7 +3623,7 @@ async function runSyncDocument(sessionId, options) {
|
|
|
3385
3623
|
api,
|
|
3386
3624
|
trimmedSessionId,
|
|
3387
3625
|
docsDir,
|
|
3388
|
-
|
|
3626
|
+
basename4(absPath)
|
|
3389
3627
|
);
|
|
3390
3628
|
console.log(`[apm] \u5DF2\u540C\u6B65\u6587\u6863: ${doc.name} (id=${doc.id})`);
|
|
3391
3629
|
const assumptionSync = doc.assumptionSync;
|
|
@@ -3730,8 +3968,8 @@ init_client();
|
|
|
3730
3968
|
import path11 from "node:path";
|
|
3731
3969
|
|
|
3732
3970
|
// src/commands/deploy/internal/apm-config.ts
|
|
3733
|
-
import { existsSync as
|
|
3734
|
-
import { resolve as
|
|
3971
|
+
import { existsSync as existsSync13, readFileSync as readFileSync12 } from "node:fs";
|
|
3972
|
+
import { resolve as resolve5 } from "node:path";
|
|
3735
3973
|
|
|
3736
3974
|
// src/commands/deploy/internal/config/config-validation.ts
|
|
3737
3975
|
function req(v, field, section) {
|
|
@@ -3823,9 +4061,9 @@ function resolveFrontendDeployFromApmConfig(cfg) {
|
|
|
3823
4061
|
}
|
|
3824
4062
|
|
|
3825
4063
|
// src/commands/deploy/internal/config/maven-repo.ts
|
|
3826
|
-
import { existsSync as
|
|
4064
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "node:fs";
|
|
3827
4065
|
import { homedir as homedir2 } from "node:os";
|
|
3828
|
-
import { join as
|
|
4066
|
+
import { join as join14, resolve as resolve4 } from "node:path";
|
|
3829
4067
|
var MAVEN_REPO_ENV_KEYS = [
|
|
3830
4068
|
"MAVEN_LOCAL_REPO",
|
|
3831
4069
|
"M2_REPO",
|
|
@@ -3858,7 +4096,7 @@ function expandUserPath(pathStr, env = process.env) {
|
|
|
3858
4096
|
if (/^[a-zA-Z]:[/\\]/.test(expanded)) {
|
|
3859
4097
|
return expanded;
|
|
3860
4098
|
}
|
|
3861
|
-
return
|
|
4099
|
+
return resolve4(expanded);
|
|
3862
4100
|
}
|
|
3863
4101
|
function readMavenLocalRepoFromMavenOpts(mavenOpts, env = process.env) {
|
|
3864
4102
|
const match = mavenOpts.match(/-Dmaven\.repo\.local=(?:"([^"]+)"|(\S+))/);
|
|
@@ -3882,12 +4120,12 @@ function readMavenLocalRepoFromEnv(env = process.env) {
|
|
|
3882
4120
|
return null;
|
|
3883
4121
|
}
|
|
3884
4122
|
function readMavenLocalRepoFromSettings() {
|
|
3885
|
-
const settingsPath =
|
|
3886
|
-
if (!
|
|
4123
|
+
const settingsPath = join14(homedir2(), ".m2", "settings.xml");
|
|
4124
|
+
if (!existsSync12(settingsPath)) {
|
|
3887
4125
|
return null;
|
|
3888
4126
|
}
|
|
3889
4127
|
try {
|
|
3890
|
-
const xml =
|
|
4128
|
+
const xml = readFileSync11(settingsPath, "utf8");
|
|
3891
4129
|
const match = xml.match(
|
|
3892
4130
|
/<localRepository>\s*([^<]+?)\s*<\/localRepository>/
|
|
3893
4131
|
);
|
|
@@ -3918,7 +4156,7 @@ function resolveMavenLocalRepoWithSource() {
|
|
|
3918
4156
|
};
|
|
3919
4157
|
}
|
|
3920
4158
|
return {
|
|
3921
|
-
path:
|
|
4159
|
+
path: join14(homedir2(), ".m2", "repository"),
|
|
3922
4160
|
source: "default",
|
|
3923
4161
|
sourceDetail: "~/.m2/repository"
|
|
3924
4162
|
};
|
|
@@ -4014,16 +4252,16 @@ function resolveWisdomBackendDeployFromApmConfig(cfg) {
|
|
|
4014
4252
|
|
|
4015
4253
|
// src/commands/deploy/internal/apm-config.ts
|
|
4016
4254
|
function loadApmConfig(options) {
|
|
4017
|
-
const p =
|
|
4255
|
+
const p = resolve5(
|
|
4018
4256
|
process.cwd(),
|
|
4019
|
-
options?.configPath ??
|
|
4257
|
+
options?.configPath ?? resolve5(workspaceApmDir(), "apm.config.json")
|
|
4020
4258
|
);
|
|
4021
|
-
if (!
|
|
4259
|
+
if (!existsSync13(p)) {
|
|
4022
4260
|
console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
|
|
4023
4261
|
process.exit(1);
|
|
4024
4262
|
}
|
|
4025
4263
|
try {
|
|
4026
|
-
const raw =
|
|
4264
|
+
const raw = readFileSync12(p, "utf8");
|
|
4027
4265
|
return JSON.parse(raw);
|
|
4028
4266
|
} catch (e) {
|
|
4029
4267
|
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
@@ -4069,32 +4307,32 @@ var DeployExecutionError = class extends Error {
|
|
|
4069
4307
|
// src/commands/deploy/deploy-debug-log.ts
|
|
4070
4308
|
init_deploy_artifact_minio();
|
|
4071
4309
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
4072
|
-
import { existsSync as
|
|
4073
|
-
import { dirname as
|
|
4310
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
4311
|
+
import { dirname as dirname6, join as join18 } from "node:path";
|
|
4074
4312
|
|
|
4075
4313
|
// src/commands/deploy/internal/deploy-shell-env.ts
|
|
4076
4314
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
4077
|
-
import { existsSync as
|
|
4078
|
-
import { dirname as
|
|
4315
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
4316
|
+
import { dirname as dirname5, join as join17 } from "node:path";
|
|
4079
4317
|
|
|
4080
4318
|
// src/commands/daemon.ts
|
|
4081
4319
|
init_config();
|
|
4082
4320
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
4083
4321
|
import { setTimeout as delay } from "node:timers/promises";
|
|
4084
|
-
import { existsSync as
|
|
4085
|
-
import { join as
|
|
4322
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync12 } from "fs";
|
|
4323
|
+
import { join as join16 } from "path";
|
|
4086
4324
|
|
|
4087
4325
|
// src/commands/connect-lock.ts
|
|
4088
4326
|
init_config();
|
|
4089
4327
|
import {
|
|
4090
|
-
existsSync as
|
|
4091
|
-
mkdirSync as
|
|
4092
|
-
readFileSync as
|
|
4328
|
+
existsSync as existsSync14,
|
|
4329
|
+
mkdirSync as mkdirSync6,
|
|
4330
|
+
readFileSync as readFileSync13,
|
|
4093
4331
|
unlinkSync,
|
|
4094
|
-
writeFileSync as
|
|
4332
|
+
writeFileSync as writeFileSync11
|
|
4095
4333
|
} from "fs";
|
|
4096
|
-
import { join as
|
|
4097
|
-
var CONNECT_LOCK_PATH =
|
|
4334
|
+
import { join as join15 } from "path";
|
|
4335
|
+
var CONNECT_LOCK_PATH = join15(APM_CONFIG_DIR, "connect.lock");
|
|
4098
4336
|
function isProcessAlive(pid) {
|
|
4099
4337
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
4100
4338
|
try {
|
|
@@ -4121,9 +4359,9 @@ function waitForPm2LockHandoff(timeoutMs = 5e3) {
|
|
|
4121
4359
|
}
|
|
4122
4360
|
}
|
|
4123
4361
|
function readConnectLock() {
|
|
4124
|
-
if (!
|
|
4362
|
+
if (!existsSync14(CONNECT_LOCK_PATH)) return null;
|
|
4125
4363
|
try {
|
|
4126
|
-
const raw =
|
|
4364
|
+
const raw = readFileSync13(CONNECT_LOCK_PATH, "utf8");
|
|
4127
4365
|
const parsed = JSON.parse(raw);
|
|
4128
4366
|
if (typeof parsed.pid !== "number" || parsed.mode !== "foreground" && parsed.mode !== "pm2" || typeof parsed.startedAt !== "string") {
|
|
4129
4367
|
return null;
|
|
@@ -4158,13 +4396,13 @@ function acquireConnectLock(mode) {
|
|
|
4158
4396
|
process.exit(1);
|
|
4159
4397
|
}
|
|
4160
4398
|
}
|
|
4161
|
-
|
|
4399
|
+
mkdirSync6(APM_CONFIG_DIR, { recursive: true });
|
|
4162
4400
|
const lock = {
|
|
4163
4401
|
pid: process.pid,
|
|
4164
4402
|
mode,
|
|
4165
4403
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4166
4404
|
};
|
|
4167
|
-
|
|
4405
|
+
writeFileSync11(
|
|
4168
4406
|
CONNECT_LOCK_PATH,
|
|
4169
4407
|
JSON.stringify(lock, null, 2) + "\n",
|
|
4170
4408
|
"utf8"
|
|
@@ -4180,7 +4418,7 @@ function releaseConnectLock() {
|
|
|
4180
4418
|
}
|
|
4181
4419
|
function forceReleaseConnectLock() {
|
|
4182
4420
|
try {
|
|
4183
|
-
if (
|
|
4421
|
+
if (existsSync14(CONNECT_LOCK_PATH)) {
|
|
4184
4422
|
unlinkSync(CONNECT_LOCK_PATH);
|
|
4185
4423
|
}
|
|
4186
4424
|
} catch {
|
|
@@ -4189,16 +4427,16 @@ function forceReleaseConnectLock() {
|
|
|
4189
4427
|
|
|
4190
4428
|
// src/commands/daemon.ts
|
|
4191
4429
|
var PM2_APP_NAME = "apm-connect";
|
|
4192
|
-
var PM2_ECOSYSTEM_PATH =
|
|
4430
|
+
var PM2_ECOSYSTEM_PATH = join16(
|
|
4193
4431
|
APM_CONFIG_DIR,
|
|
4194
4432
|
"connect.ecosystem.config.cjs"
|
|
4195
4433
|
);
|
|
4196
|
-
var PM2_CONNECT_ENTRY_PATH =
|
|
4197
|
-
var PM2_CONNECT_LAUNCH_PATH =
|
|
4434
|
+
var PM2_CONNECT_ENTRY_PATH = join16(APM_CONFIG_DIR, "connect.entry.cjs");
|
|
4435
|
+
var PM2_CONNECT_LAUNCH_PATH = join16(
|
|
4198
4436
|
APM_CONFIG_DIR,
|
|
4199
4437
|
"connect.launch.json"
|
|
4200
4438
|
);
|
|
4201
|
-
var LEGACY_PM2_ECOSYSTEM_PATH =
|
|
4439
|
+
var LEGACY_PM2_ECOSYSTEM_PATH = join16(
|
|
4202
4440
|
APM_CONFIG_DIR,
|
|
4203
4441
|
"connect.ecosystem.cjs"
|
|
4204
4442
|
);
|
|
@@ -4329,8 +4567,8 @@ function resolvePm2FromNpmRoot() {
|
|
|
4329
4567
|
const root = rootResult.stdout?.toString().trim();
|
|
4330
4568
|
if (!root) return null;
|
|
4331
4569
|
for (const rel of ["pm2/bin/pm2", "pm2/bin/pm2.js"]) {
|
|
4332
|
-
const candidate =
|
|
4333
|
-
if (
|
|
4570
|
+
const candidate = join16(root, ...rel.split("/"));
|
|
4571
|
+
if (existsSync15(candidate)) {
|
|
4334
4572
|
return candidate;
|
|
4335
4573
|
}
|
|
4336
4574
|
}
|
|
@@ -4367,7 +4605,7 @@ function spawnPm2At(binPath, args, options = {}) {
|
|
|
4367
4605
|
return spawnPm2Target(buildPm2SpawnTarget(binPath), args, options);
|
|
4368
4606
|
}
|
|
4369
4607
|
function verifyPm2Bin(pm2Bin) {
|
|
4370
|
-
if (!pm2Bin.trim() || !
|
|
4608
|
+
if (!pm2Bin.trim() || !existsSync15(pm2Bin)) {
|
|
4371
4609
|
return false;
|
|
4372
4610
|
}
|
|
4373
4611
|
const result = spawnPm2At(pm2Bin, ["--version"], {
|
|
@@ -4380,10 +4618,10 @@ function collectPm2Candidates() {
|
|
|
4380
4618
|
const globalBin = resolveNpmGlobalBin();
|
|
4381
4619
|
if (globalBin) {
|
|
4382
4620
|
if (useNpmShell2) {
|
|
4383
|
-
candidates.push(
|
|
4384
|
-
candidates.push(
|
|
4621
|
+
candidates.push(join16(globalBin, "pm2.cmd"));
|
|
4622
|
+
candidates.push(join16(globalBin, "pm2"));
|
|
4385
4623
|
} else {
|
|
4386
|
-
candidates.push(
|
|
4624
|
+
candidates.push(join16(globalBin, "pm2"));
|
|
4387
4625
|
}
|
|
4388
4626
|
}
|
|
4389
4627
|
const fromRoot = resolvePm2FromNpmRoot();
|
|
@@ -4506,7 +4744,7 @@ function ensureGlobalPm2(options) {
|
|
|
4506
4744
|
}
|
|
4507
4745
|
function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
4508
4746
|
const fromArgv = entryArg?.trim();
|
|
4509
|
-
if (fromArgv &&
|
|
4747
|
+
if (fromArgv && existsSync15(fromArgv)) {
|
|
4510
4748
|
return fromArgv;
|
|
4511
4749
|
}
|
|
4512
4750
|
const npmResult = spawnSync2(useNpmShell2 ? "npm.cmd" : "npm", ["root", "-g"], {
|
|
@@ -4517,8 +4755,8 @@ function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
|
4517
4755
|
if (npmResult.status === 0) {
|
|
4518
4756
|
const globalRoot = npmResult.stdout?.toString().trim();
|
|
4519
4757
|
if (globalRoot) {
|
|
4520
|
-
const candidate =
|
|
4521
|
-
if (
|
|
4758
|
+
const candidate = join16(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
|
|
4759
|
+
if (existsSync15(candidate)) {
|
|
4522
4760
|
return candidate;
|
|
4523
4761
|
}
|
|
4524
4762
|
}
|
|
@@ -4676,8 +4914,8 @@ async function resolveBaseUrl(server) {
|
|
|
4676
4914
|
return cfg?.baseUrl;
|
|
4677
4915
|
}
|
|
4678
4916
|
function writeConnectLaunchFiles(options) {
|
|
4679
|
-
|
|
4680
|
-
|
|
4917
|
+
mkdirSync7(APM_CONFIG_DIR, { recursive: true });
|
|
4918
|
+
writeFileSync12(PM2_CONNECT_ENTRY_PATH, CONNECT_ENTRY_SCRIPT, "utf8");
|
|
4681
4919
|
const env = {
|
|
4682
4920
|
...collectPm2LaunchEnv()
|
|
4683
4921
|
};
|
|
@@ -4692,7 +4930,7 @@ function writeConnectLaunchFiles(options) {
|
|
|
4692
4930
|
cwd: options.cwd,
|
|
4693
4931
|
env
|
|
4694
4932
|
};
|
|
4695
|
-
|
|
4933
|
+
writeFileSync12(
|
|
4696
4934
|
PM2_CONNECT_LAUNCH_PATH,
|
|
4697
4935
|
JSON.stringify(launch, null, 2) + "\n",
|
|
4698
4936
|
"utf8"
|
|
@@ -4704,12 +4942,12 @@ function writeEcosystemFile(options) {
|
|
|
4704
4942
|
entryScript: PM2_CONNECT_ENTRY_PATH,
|
|
4705
4943
|
baseUrl: options.baseUrl
|
|
4706
4944
|
});
|
|
4707
|
-
|
|
4945
|
+
writeFileSync12(
|
|
4708
4946
|
PM2_ECOSYSTEM_PATH,
|
|
4709
4947
|
formatConnectPm2EcosystemFile(ecosystem),
|
|
4710
4948
|
"utf8"
|
|
4711
4949
|
);
|
|
4712
|
-
if (
|
|
4950
|
+
if (existsSync15(LEGACY_PM2_ECOSYSTEM_PATH)) {
|
|
4713
4951
|
try {
|
|
4714
4952
|
unlinkSync2(LEGACY_PM2_ECOSYSTEM_PATH);
|
|
4715
4953
|
} catch {
|
|
@@ -4868,14 +5106,14 @@ function writeEnvPath(env, value) {
|
|
|
4868
5106
|
env.PATH = value;
|
|
4869
5107
|
}
|
|
4870
5108
|
function resolveNodeInstallDir() {
|
|
4871
|
-
return
|
|
5109
|
+
return dirname5(process.execPath);
|
|
4872
5110
|
}
|
|
4873
5111
|
function resolveNpmCmdPath() {
|
|
4874
5112
|
if (process.platform !== "win32") {
|
|
4875
5113
|
return null;
|
|
4876
5114
|
}
|
|
4877
|
-
const candidate =
|
|
4878
|
-
return
|
|
5115
|
+
const candidate = join17(resolveNodeInstallDir(), "npm.cmd");
|
|
5116
|
+
return existsSync16(candidate) ? candidate : null;
|
|
4879
5117
|
}
|
|
4880
5118
|
function formatNpmRunShellCommand(scriptName) {
|
|
4881
5119
|
const trimmed = scriptName.trim();
|
|
@@ -5047,7 +5285,7 @@ function logExecuteDeployContext(input) {
|
|
|
5047
5285
|
const deploymentRunId = process.env[APM_DEPLOYMENT_RUN_ID_ENV]?.trim() || null;
|
|
5048
5286
|
const shellEnv = buildDeployShellEnv();
|
|
5049
5287
|
const npmGlobalBin = resolveNpmGlobalBin2();
|
|
5050
|
-
const packageJsonPath =
|
|
5288
|
+
const packageJsonPath = join18(input.cwd, "package.json");
|
|
5051
5289
|
logLine("========== executeDeploy \u4E0A\u4E0B\u6587 ==========");
|
|
5052
5290
|
logLine(`trigger=${trigger} deployEnv=${input.env}`);
|
|
5053
5291
|
logLine(`cwd(input)=${input.cwdInput}`);
|
|
@@ -5057,12 +5295,12 @@ function logExecuteDeployContext(input) {
|
|
|
5057
5295
|
`cwdMatchProcess=${input.cwd === input.processCwd ? "yes" : "no"} (connect \u901A\u5E38\u4E3A no)`
|
|
5058
5296
|
);
|
|
5059
5297
|
logLine(
|
|
5060
|
-
`apm.config=${input.apmConfigPath} exists=${
|
|
5298
|
+
`apm.config=${input.apmConfigPath} exists=${existsSync17(
|
|
5061
5299
|
input.apmConfigPath
|
|
5062
5300
|
)}`
|
|
5063
5301
|
);
|
|
5064
5302
|
logLine(
|
|
5065
|
-
`package.json=${packageJsonPath} exists=${
|
|
5303
|
+
`package.json=${packageJsonPath} exists=${existsSync17(packageJsonPath)}`
|
|
5066
5304
|
);
|
|
5067
5305
|
logLine(
|
|
5068
5306
|
`flags captureOutput=${input.captureOutput} packOnly=${Boolean(
|
|
@@ -5076,7 +5314,7 @@ function logExecuteDeployContext(input) {
|
|
|
5076
5314
|
);
|
|
5077
5315
|
logLine(`process argv=${process.argv.join(" ")}`);
|
|
5078
5316
|
logLine(`npmGlobalBin=${npmGlobalBin ?? "(resolve failed)"}`);
|
|
5079
|
-
logLine(`nodeDir=${
|
|
5317
|
+
logLine(`nodeDir=${dirname6(process.execPath)}`);
|
|
5080
5318
|
logLine("--- process.env\uFF08\u8282\u9009\uFF09---");
|
|
5081
5319
|
for (const [key, value] of Object.entries(
|
|
5082
5320
|
collectInterestingEnv(process.env)
|
|
@@ -5118,14 +5356,14 @@ function logWisdomFrontendDeployContext(input) {
|
|
|
5118
5356
|
logLine(
|
|
5119
5357
|
`buildKey=build:${input.env} buildCmd=${input.buildCmd ?? "(missing)"}`
|
|
5120
5358
|
);
|
|
5121
|
-
logLine(`distDir=${input.distDir} exists=${
|
|
5359
|
+
logLine(`distDir=${input.distDir} exists=${existsSync17(input.distDir)}`);
|
|
5122
5360
|
logLine(
|
|
5123
5361
|
`packOnly=${input.packOnly} archiveDeployArtifact=${input.archiveDeployArtifact}`
|
|
5124
5362
|
);
|
|
5125
5363
|
}
|
|
5126
5364
|
|
|
5127
5365
|
// src/commands/deploy/internal/wisdom-deploy.ts
|
|
5128
|
-
import { existsSync as
|
|
5366
|
+
import { existsSync as existsSync21, readFileSync as readFileSync16, statSync as statSync10 } from "node:fs";
|
|
5129
5367
|
import path10 from "node:path";
|
|
5130
5368
|
|
|
5131
5369
|
// src/commands/deploy/deploy-shell-run.ts
|
|
@@ -5224,22 +5462,22 @@ init_deploy_artifact_minio();
|
|
|
5224
5462
|
|
|
5225
5463
|
// src/commands/deploy/internal/wisdom-backend/jar-incremental.ts
|
|
5226
5464
|
import {
|
|
5227
|
-
mkdirSync as
|
|
5228
|
-
readdirSync as
|
|
5229
|
-
readFileSync as
|
|
5230
|
-
statSync as
|
|
5231
|
-
writeFileSync as
|
|
5465
|
+
mkdirSync as mkdirSync9,
|
|
5466
|
+
readdirSync as readdirSync6,
|
|
5467
|
+
readFileSync as readFileSync15,
|
|
5468
|
+
statSync as statSync8,
|
|
5469
|
+
writeFileSync as writeFileSync14
|
|
5232
5470
|
} from "node:fs";
|
|
5233
5471
|
import path6 from "node:path";
|
|
5234
5472
|
import JSZip2 from "jszip";
|
|
5235
5473
|
|
|
5236
5474
|
// src/commands/deploy/internal/wisdom-backend/manifest.ts
|
|
5237
5475
|
import {
|
|
5238
|
-
existsSync as
|
|
5239
|
-
mkdirSync as
|
|
5240
|
-
readFileSync as
|
|
5241
|
-
statSync as
|
|
5242
|
-
writeFileSync as
|
|
5476
|
+
existsSync as existsSync18,
|
|
5477
|
+
mkdirSync as mkdirSync8,
|
|
5478
|
+
readFileSync as readFileSync14,
|
|
5479
|
+
statSync as statSync7,
|
|
5480
|
+
writeFileSync as writeFileSync13
|
|
5243
5481
|
} from "node:fs";
|
|
5244
5482
|
import path2 from "node:path";
|
|
5245
5483
|
function deployCacheDir() {
|
|
@@ -5252,20 +5490,20 @@ function relativeKey(projectRoot, filePath) {
|
|
|
5252
5490
|
return path2.relative(projectRoot, filePath).split(path2.sep).join("/");
|
|
5253
5491
|
}
|
|
5254
5492
|
function fileSignature(filePath) {
|
|
5255
|
-
const stat2 =
|
|
5493
|
+
const stat2 = statSync7(filePath);
|
|
5256
5494
|
return { size: stat2.size, mtime: stat2.mtimeMs / 1e3 };
|
|
5257
5495
|
}
|
|
5258
5496
|
function loadManifest3() {
|
|
5259
|
-
const
|
|
5260
|
-
if (!
|
|
5497
|
+
const manifestPath3 = manifestFilePath();
|
|
5498
|
+
if (!existsSync18(manifestPath3)) {
|
|
5261
5499
|
return {};
|
|
5262
5500
|
}
|
|
5263
|
-
return JSON.parse(
|
|
5501
|
+
return JSON.parse(readFileSync14(manifestPath3, "utf8"));
|
|
5264
5502
|
}
|
|
5265
5503
|
function saveManifest3(manifest) {
|
|
5266
5504
|
const dir = deployCacheDir();
|
|
5267
|
-
|
|
5268
|
-
|
|
5505
|
+
mkdirSync8(dir, { recursive: true });
|
|
5506
|
+
writeFileSync13(manifestFilePath(), JSON.stringify(manifest, null, 2), "utf8");
|
|
5269
5507
|
}
|
|
5270
5508
|
function updateManifestEntries(manifest, entries, projectRoot) {
|
|
5271
5509
|
for (const entry of entries) {
|
|
@@ -5398,7 +5636,7 @@ function buildSftpConnectOptions(settings) {
|
|
|
5398
5636
|
};
|
|
5399
5637
|
}
|
|
5400
5638
|
async function sleep(ms) {
|
|
5401
|
-
await new Promise((
|
|
5639
|
+
await new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
5402
5640
|
}
|
|
5403
5641
|
async function uploadZipWithRetry(settings, localZip, remoteZipPath) {
|
|
5404
5642
|
let lastError;
|
|
@@ -5442,7 +5680,7 @@ async function ensureRemoteDir(sftp, dir) {
|
|
|
5442
5680
|
}
|
|
5443
5681
|
}
|
|
5444
5682
|
function execCommand(client, command) {
|
|
5445
|
-
return new Promise((
|
|
5683
|
+
return new Promise((resolve8, reject) => {
|
|
5446
5684
|
client.exec(command, (err, stream) => {
|
|
5447
5685
|
if (err) return reject(err);
|
|
5448
5686
|
let stdout = "";
|
|
@@ -5452,7 +5690,7 @@ function execCommand(client, command) {
|
|
|
5452
5690
|
reject(new Error(`\u8FDC\u7A0B\u547D\u4EE4\u5931\u8D25 (${code}): ${stderr || stdout}`));
|
|
5453
5691
|
return;
|
|
5454
5692
|
}
|
|
5455
|
-
|
|
5693
|
+
resolve8(stdout);
|
|
5456
5694
|
}).on("data", (data) => {
|
|
5457
5695
|
stdout += data.toString();
|
|
5458
5696
|
});
|
|
@@ -5635,7 +5873,7 @@ function shouldUploadLibFile(localPath, remoteAttr, manifest, projectRoot) {
|
|
|
5635
5873
|
if (!remoteAttr) {
|
|
5636
5874
|
return [false, "\u8FDC\u7A0B\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7"];
|
|
5637
5875
|
}
|
|
5638
|
-
const localSize =
|
|
5876
|
+
const localSize = statSync8(localPath).size;
|
|
5639
5877
|
const remoteSize = remoteAttr.size;
|
|
5640
5878
|
if (localSize !== remoteSize) {
|
|
5641
5879
|
return [true, `\u5927\u5C0F\u53D8\u5316 ${remoteSize} -> ${localSize}`];
|
|
@@ -5658,7 +5896,7 @@ function shouldUploadLibFile(localPath, remoteAttr, manifest, projectRoot) {
|
|
|
5658
5896
|
}
|
|
5659
5897
|
function listLibFilesToUpload(localLibDir, remoteStats, projectRoot, manifest = null) {
|
|
5660
5898
|
const entries = [];
|
|
5661
|
-
const jarFiles =
|
|
5899
|
+
const jarFiles = readdirSync6(localLibDir).filter((name) => name.endsWith(".jar")).sort();
|
|
5662
5900
|
for (const jarName of jarFiles) {
|
|
5663
5901
|
const jarPath = path6.join(localLibDir, jarName);
|
|
5664
5902
|
const remoteAttr = remoteStats.get(jarName);
|
|
@@ -5676,12 +5914,12 @@ function listLibFilesToUpload(localLibDir, remoteStats, projectRoot, manifest =
|
|
|
5676
5914
|
}
|
|
5677
5915
|
async function createUpdatePackage(entries, packageName) {
|
|
5678
5916
|
const dir = deployCacheDirectory();
|
|
5679
|
-
|
|
5917
|
+
mkdirSync9(dir, { recursive: true });
|
|
5680
5918
|
const zipPath = path6.join(dir, packageName);
|
|
5681
5919
|
log(`\u521B\u5EFA\u66F4\u65B0\u5305: ${path6.basename(zipPath)}\uFF08${entries.length} \u4E2A\u6587\u4EF6\uFF09`);
|
|
5682
5920
|
const zip = new JSZip2();
|
|
5683
5921
|
for (const entry of entries) {
|
|
5684
|
-
const content =
|
|
5922
|
+
const content = readFileSync15(entry.path);
|
|
5685
5923
|
zip.file(entry.arcname, content);
|
|
5686
5924
|
log(` \u6253\u5305: ${entry.arcname} (${entry.reason})`);
|
|
5687
5925
|
}
|
|
@@ -5690,11 +5928,11 @@ async function createUpdatePackage(entries, packageName) {
|
|
|
5690
5928
|
compression: "DEFLATE",
|
|
5691
5929
|
compressionOptions: { level: 6 }
|
|
5692
5930
|
});
|
|
5693
|
-
|
|
5931
|
+
writeFileSync14(zipPath, buffer);
|
|
5694
5932
|
return zipPath;
|
|
5695
5933
|
}
|
|
5696
5934
|
function listAllLibFilesForArchive(libDir) {
|
|
5697
|
-
return
|
|
5935
|
+
return readdirSync6(libDir).filter((name) => name.endsWith(".jar")).sort().map((jarName) => ({
|
|
5698
5936
|
path: path6.join(libDir, jarName),
|
|
5699
5937
|
arcname: jarName,
|
|
5700
5938
|
reason: "\u4EC5\u6253\u5305\u5F52\u6863"
|
|
@@ -5702,7 +5940,7 @@ function listAllLibFilesForArchive(libDir) {
|
|
|
5702
5940
|
}
|
|
5703
5941
|
|
|
5704
5942
|
// src/commands/deploy/internal/wisdom-backend/maven-build.ts
|
|
5705
|
-
import { existsSync as
|
|
5943
|
+
import { existsSync as existsSync20, readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
|
|
5706
5944
|
import path7 from "node:path";
|
|
5707
5945
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
5708
5946
|
function getMvnExecutable() {
|
|
@@ -5751,14 +5989,14 @@ function runMavenBuild(projectRoot, mavenLocalRepo, repoSource) {
|
|
|
5751
5989
|
}
|
|
5752
5990
|
function locateLibDir(projectRoot) {
|
|
5753
5991
|
const targetDir = getTargetDir(projectRoot);
|
|
5754
|
-
if (!
|
|
5992
|
+
if (!existsSync20(targetDir)) {
|
|
5755
5993
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
5756
5994
|
}
|
|
5757
5995
|
const libDir = path7.join(targetDir, "lib");
|
|
5758
|
-
if (!
|
|
5996
|
+
if (!existsSync20(libDir) || !statSync9(libDir).isDirectory()) {
|
|
5759
5997
|
fail(`lib \u76EE\u5F55\u4E0D\u5B58\u5728: ${libDir}`);
|
|
5760
5998
|
}
|
|
5761
|
-
const libJars =
|
|
5999
|
+
const libJars = readdirSync7(libDir).filter((name) => name.endsWith(".jar"));
|
|
5762
6000
|
if (libJars.length === 0) {
|
|
5763
6001
|
fail(`lib \u76EE\u5F55\u4E0B\u6CA1\u6709\u4F9D\u8D56 JAR: ${libDir}`);
|
|
5764
6002
|
}
|
|
@@ -5767,10 +6005,10 @@ function locateLibDir(projectRoot) {
|
|
|
5767
6005
|
}
|
|
5768
6006
|
function locateMainJar(projectRoot) {
|
|
5769
6007
|
const targetDir = getTargetDir(projectRoot);
|
|
5770
|
-
if (!
|
|
6008
|
+
if (!existsSync20(targetDir)) {
|
|
5771
6009
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
5772
6010
|
}
|
|
5773
|
-
const jarFiles =
|
|
6011
|
+
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);
|
|
5774
6012
|
if (jarFiles.length === 0) {
|
|
5775
6013
|
fail(`target \u76EE\u5F55\u4E0B\u6CA1\u6709\u4E3B JAR: ${targetDir}`);
|
|
5776
6014
|
}
|
|
@@ -5927,8 +6165,8 @@ function springbootOutputIndicatesSuccess(action, combined) {
|
|
|
5927
6165
|
async function connectSsh(config) {
|
|
5928
6166
|
const client = new Client2();
|
|
5929
6167
|
log(`\u8FDE\u63A5\u670D\u52A1\u5668 ${config.username}@${config.host}:${config.port}`);
|
|
5930
|
-
await new Promise((
|
|
5931
|
-
client.on("ready", () =>
|
|
6168
|
+
await new Promise((resolve8, reject) => {
|
|
6169
|
+
client.on("ready", () => resolve8()).on("error", (err) => reject(err)).connect({
|
|
5932
6170
|
host: config.host,
|
|
5933
6171
|
port: config.port,
|
|
5934
6172
|
username: config.username,
|
|
@@ -5996,7 +6234,7 @@ async function runRemoteCommand(client, command, options) {
|
|
|
5996
6234
|
const check = options?.check ?? true;
|
|
5997
6235
|
const stream = options?.stream ?? false;
|
|
5998
6236
|
const label = options?.label ?? "\u8FDC\u7A0B\u547D\u4EE4";
|
|
5999
|
-
return new Promise((
|
|
6237
|
+
return new Promise((resolve8, reject) => {
|
|
6000
6238
|
client.exec(command, (err, execStream) => {
|
|
6001
6239
|
if (err) {
|
|
6002
6240
|
reject(err);
|
|
@@ -6026,7 +6264,7 @@ ${errText}`.trim();
|
|
|
6026
6264
|
\u8F93\u51FA: ${combined}` : "")
|
|
6027
6265
|
);
|
|
6028
6266
|
}
|
|
6029
|
-
|
|
6267
|
+
resolve8({ exitCode: code, out: out.trim(), err: errText.trim() });
|
|
6030
6268
|
});
|
|
6031
6269
|
});
|
|
6032
6270
|
});
|
|
@@ -6256,15 +6494,15 @@ function isWisdomDeployConfigured(cfg) {
|
|
|
6256
6494
|
return Boolean(w?.host?.trim() && w?.remotePath?.trim());
|
|
6257
6495
|
}
|
|
6258
6496
|
function detectWisdomProjectType(cwd) {
|
|
6259
|
-
return
|
|
6497
|
+
return existsSync21(path10.join(cwd, "package.json")) ? "frontend" : "backend";
|
|
6260
6498
|
}
|
|
6261
6499
|
function readPackageScripts(cwd) {
|
|
6262
6500
|
const pkgPath = path10.join(cwd, "package.json");
|
|
6263
|
-
if (!
|
|
6501
|
+
if (!existsSync21(pkgPath)) {
|
|
6264
6502
|
return {};
|
|
6265
6503
|
}
|
|
6266
6504
|
try {
|
|
6267
|
-
const raw =
|
|
6505
|
+
const raw = readFileSync16(pkgPath, "utf8");
|
|
6268
6506
|
const parsed = JSON.parse(raw);
|
|
6269
6507
|
return parsed.scripts ?? {};
|
|
6270
6508
|
} catch {
|
|
@@ -6287,7 +6525,7 @@ function resolveFrontendDistDir(cwd) {
|
|
|
6287
6525
|
for (const rel of candidates) {
|
|
6288
6526
|
const full = path10.join(cwd, rel);
|
|
6289
6527
|
try {
|
|
6290
|
-
if (
|
|
6528
|
+
if (existsSync21(full) && statSync10(full).isDirectory()) {
|
|
6291
6529
|
return full;
|
|
6292
6530
|
}
|
|
6293
6531
|
} catch {
|
|
@@ -6855,7 +7093,7 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
6855
7093
|
}
|
|
6856
7094
|
|
|
6857
7095
|
// src/commands/clean-session-cache.ts
|
|
6858
|
-
import { existsSync as
|
|
7096
|
+
import { existsSync as existsSync22, rmSync as rmSync4 } from "node:fs";
|
|
6859
7097
|
|
|
6860
7098
|
// src/commands/connect/pre-step-cache.ts
|
|
6861
7099
|
var PULL_TTL_MS = 3e4;
|
|
@@ -6897,7 +7135,7 @@ function cleanSessionWorkspaceCache(sessionId, workdir) {
|
|
|
6897
7135
|
return;
|
|
6898
7136
|
}
|
|
6899
7137
|
const dir = sessionDir(trimmedSessionId, workspaceApmDir(trimmedWorkdir));
|
|
6900
|
-
if (
|
|
7138
|
+
if (existsSync22(dir)) {
|
|
6901
7139
|
rmSync4(dir, { recursive: true, force: true });
|
|
6902
7140
|
console.log(`[apm] \u5DF2\u6E05\u7406\u4F1A\u8BDD\u7F13\u5B58 ${dir}`);
|
|
6903
7141
|
} else {
|
|
@@ -6907,16 +7145,16 @@ function cleanSessionWorkspaceCache(sessionId, workdir) {
|
|
|
6907
7145
|
}
|
|
6908
7146
|
|
|
6909
7147
|
// src/commands/clean-webide-cache.ts
|
|
6910
|
-
import { existsSync as
|
|
6911
|
-
import { resolve as
|
|
7148
|
+
import { existsSync as existsSync23, rmSync as rmSync5 } from "node:fs";
|
|
7149
|
+
import { resolve as resolve6 } from "node:path";
|
|
6912
7150
|
function cleanWebIdeWorkspaceCache(taskId, workdir) {
|
|
6913
7151
|
const trimmedTaskId = taskId.trim();
|
|
6914
7152
|
const trimmedWorkdir = workdir.trim();
|
|
6915
7153
|
if (!trimmedTaskId || !trimmedWorkdir) {
|
|
6916
7154
|
return;
|
|
6917
7155
|
}
|
|
6918
|
-
const dir =
|
|
6919
|
-
if (
|
|
7156
|
+
const dir = resolve6(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
|
|
7157
|
+
if (existsSync23(dir)) {
|
|
6920
7158
|
rmSync5(dir, { recursive: true, force: true });
|
|
6921
7159
|
console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
|
|
6922
7160
|
} else {
|
|
@@ -7267,17 +7505,17 @@ ${JSON.stringify(event, null, 2)}
|
|
|
7267
7505
|
}
|
|
7268
7506
|
|
|
7269
7507
|
// src/commands/connect/agent-session-registry.ts
|
|
7270
|
-
import { existsSync as
|
|
7271
|
-
import { dirname as
|
|
7508
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
|
|
7509
|
+
import { dirname as dirname7, resolve as resolve7 } from "node:path";
|
|
7272
7510
|
function registryPath(workdir, sessionId) {
|
|
7273
|
-
return
|
|
7511
|
+
return resolve7(workdir, ".apm", "sessions", sessionId, "cursor-agents.json");
|
|
7274
7512
|
}
|
|
7275
7513
|
function readRegistry(path19) {
|
|
7276
|
-
if (!
|
|
7514
|
+
if (!existsSync24(path19)) {
|
|
7277
7515
|
return {};
|
|
7278
7516
|
}
|
|
7279
7517
|
try {
|
|
7280
|
-
const parsed = JSON.parse(
|
|
7518
|
+
const parsed = JSON.parse(readFileSync17(path19, "utf8"));
|
|
7281
7519
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7282
7520
|
const result = {};
|
|
7283
7521
|
for (const [key, value] of Object.entries(
|
|
@@ -7294,8 +7532,8 @@ function readRegistry(path19) {
|
|
|
7294
7532
|
return {};
|
|
7295
7533
|
}
|
|
7296
7534
|
function writeRegistry(path19, registry) {
|
|
7297
|
-
|
|
7298
|
-
|
|
7535
|
+
mkdirSync10(dirname7(path19), { recursive: true });
|
|
7536
|
+
writeFileSync15(path19, `${JSON.stringify(registry, null, 2)}
|
|
7299
7537
|
`, "utf8");
|
|
7300
7538
|
}
|
|
7301
7539
|
function loadSessionAgentId(workdir, sessionId, user) {
|
|
@@ -7898,12 +8136,12 @@ ${WORKSPACE_BOUNDARY_HINT}`;
|
|
|
7898
8136
|
}
|
|
7899
8137
|
|
|
7900
8138
|
// src/commands/connect/local-agent-store.ts
|
|
7901
|
-
import { mkdirSync as
|
|
7902
|
-
import { join as
|
|
8139
|
+
import { mkdirSync as mkdirSync11 } from "node:fs";
|
|
8140
|
+
import { join as join19 } from "node:path";
|
|
7903
8141
|
import { JsonlLocalAgentStore } from "@cursor/sdk";
|
|
7904
8142
|
function createWorkspaceLocalAgentStore(workdir) {
|
|
7905
|
-
const rootDir =
|
|
7906
|
-
|
|
8143
|
+
const rootDir = join19(workdir, ".apm", "cursor-agent-store");
|
|
8144
|
+
mkdirSync11(rootDir, { recursive: true });
|
|
7907
8145
|
return new JsonlLocalAgentStore(rootDir);
|
|
7908
8146
|
}
|
|
7909
8147
|
|
|
@@ -8183,20 +8421,20 @@ async function ensureMessageHasReply(cfg, sessionId, messageId, fallback) {
|
|
|
8183
8421
|
}
|
|
8184
8422
|
|
|
8185
8423
|
// src/commands/connect/cli-version-sync.ts
|
|
8186
|
-
import { existsSync as
|
|
8187
|
-
import { join as
|
|
8424
|
+
import { existsSync as existsSync25, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
8425
|
+
import { join as join20 } from "path";
|
|
8188
8426
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
8189
|
-
function
|
|
8190
|
-
return
|
|
8427
|
+
function manifestPath2(apmDir) {
|
|
8428
|
+
return join20(apmDir, CLI_VERSION_FILE);
|
|
8191
8429
|
}
|
|
8192
8430
|
function loadManifest4(apmDir) {
|
|
8193
|
-
const path19 = toFsPath(
|
|
8194
|
-
if (!
|
|
8431
|
+
const path19 = toFsPath(manifestPath2(apmDir));
|
|
8432
|
+
if (!existsSync25(path19)) {
|
|
8195
8433
|
return null;
|
|
8196
8434
|
}
|
|
8197
8435
|
try {
|
|
8198
8436
|
const parsed = JSON.parse(
|
|
8199
|
-
|
|
8437
|
+
readFileSync18(path19, "utf8")
|
|
8200
8438
|
);
|
|
8201
8439
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
8202
8440
|
return parsed;
|
|
@@ -8207,8 +8445,8 @@ function loadManifest4(apmDir) {
|
|
|
8207
8445
|
}
|
|
8208
8446
|
function saveManifest4(apmDir, cliVersion) {
|
|
8209
8447
|
const manifest = { version: 1, cliVersion };
|
|
8210
|
-
|
|
8211
|
-
toFsPath(
|
|
8448
|
+
writeFileSync16(
|
|
8449
|
+
toFsPath(manifestPath2(apmDir)),
|
|
8212
8450
|
`${JSON.stringify(manifest, null, 2)}
|
|
8213
8451
|
`,
|
|
8214
8452
|
"utf8"
|
|
@@ -8261,7 +8499,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8261
8499
|
);
|
|
8262
8500
|
}
|
|
8263
8501
|
const queuedAt = Date.now();
|
|
8264
|
-
return new Promise((
|
|
8502
|
+
return new Promise((resolve8) => {
|
|
8265
8503
|
waiters.push(() => {
|
|
8266
8504
|
active += 1;
|
|
8267
8505
|
const waitedMs = Date.now() - queuedAt;
|
|
@@ -8272,7 +8510,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8272
8510
|
)}s\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`
|
|
8273
8511
|
);
|
|
8274
8512
|
}
|
|
8275
|
-
|
|
8513
|
+
resolve8();
|
|
8276
8514
|
});
|
|
8277
8515
|
});
|
|
8278
8516
|
};
|
|
@@ -8293,9 +8531,9 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8293
8531
|
init_webide_terminal_registry();
|
|
8294
8532
|
import { Worker } from "node:worker_threads";
|
|
8295
8533
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8296
|
-
import { dirname as
|
|
8297
|
-
var workerFile =
|
|
8298
|
-
|
|
8534
|
+
import { dirname as dirname8, join as join21 } from "node:path";
|
|
8535
|
+
var workerFile = join21(
|
|
8536
|
+
dirname8(fileURLToPath3(import.meta.url)),
|
|
8299
8537
|
"webide-message-worker.js"
|
|
8300
8538
|
);
|
|
8301
8539
|
function spawnWebIdeMessageWorker(cfg, msg) {
|
|
@@ -8304,8 +8542,8 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8304
8542
|
});
|
|
8305
8543
|
const registry = getWebIdeTerminalRegistry(cfg);
|
|
8306
8544
|
let resolveDone;
|
|
8307
|
-
const done = new Promise((
|
|
8308
|
-
resolveDone =
|
|
8545
|
+
const done = new Promise((resolve8) => {
|
|
8546
|
+
resolveDone = resolve8;
|
|
8309
8547
|
});
|
|
8310
8548
|
worker.on("message", (m) => {
|
|
8311
8549
|
if (m?.type === "terminal-rpc") {
|
|
@@ -8550,11 +8788,11 @@ async function handleInboundMessage(cfg, msg, signal, ctx) {
|
|
|
8550
8788
|
}
|
|
8551
8789
|
function interruptibleSleep(ms, signal) {
|
|
8552
8790
|
if (signal.aborted) return Promise.resolve();
|
|
8553
|
-
return new Promise((
|
|
8554
|
-
const timer = setTimeout(
|
|
8791
|
+
return new Promise((resolve8) => {
|
|
8792
|
+
const timer = setTimeout(resolve8, ms);
|
|
8555
8793
|
const onAbort = () => {
|
|
8556
8794
|
clearTimeout(timer);
|
|
8557
|
-
|
|
8795
|
+
resolve8();
|
|
8558
8796
|
};
|
|
8559
8797
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
8560
8798
|
});
|
|
@@ -8766,7 +9004,7 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
8766
9004
|
});
|
|
8767
9005
|
}
|
|
8768
9006
|
function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
8769
|
-
return new Promise((
|
|
9007
|
+
return new Promise((resolve8, reject) => {
|
|
8770
9008
|
const ws = new WebSocket(url);
|
|
8771
9009
|
let stopHeartbeat;
|
|
8772
9010
|
let settled = false;
|
|
@@ -8795,7 +9033,7 @@ function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
|
8795
9033
|
finish(() => reject(new Error("shutdown")));
|
|
8796
9034
|
return;
|
|
8797
9035
|
}
|
|
8798
|
-
finish(
|
|
9036
|
+
finish(resolve8);
|
|
8799
9037
|
});
|
|
8800
9038
|
ws.on("error", (err) => {
|
|
8801
9039
|
console.error("[apm] WebSocket \u9519\u8BEF:", err.message);
|
|
@@ -9081,38 +9319,111 @@ function normalizeDeployEnvironment(env) {
|
|
|
9081
9319
|
if (normalized === "online") return "ONLINE";
|
|
9082
9320
|
return null;
|
|
9083
9321
|
}
|
|
9322
|
+
async function resolveRepositoryIdForWebIdeDeploy(cwd, api) {
|
|
9323
|
+
const start = resolveWorkdirPath(cwd);
|
|
9324
|
+
let manifest = findWorkspaceReposManifestNearPath(start);
|
|
9325
|
+
if (!manifest) {
|
|
9326
|
+
throw new DeployExecutionError(
|
|
9327
|
+
"\u672A\u627E\u5230 .apm/workspace-repos.json\uFF0C\u65E0\u6CD5\u5339\u914D\u5E73\u53F0\u4ED3\u5E93",
|
|
9328
|
+
1
|
|
9329
|
+
);
|
|
9330
|
+
}
|
|
9331
|
+
try {
|
|
9332
|
+
manifest = await enrichWorkspaceReposRemoteUrls(manifest);
|
|
9333
|
+
} catch (err) {
|
|
9334
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9335
|
+
throw new DeployExecutionError(
|
|
9336
|
+
`\u5237\u65B0 workspace-repos remoteUrl \u5931\u8D25: ${detail}`,
|
|
9337
|
+
1
|
|
9338
|
+
);
|
|
9339
|
+
}
|
|
9340
|
+
const entry = matchWorkspaceRepoEntryForPath(manifest, start);
|
|
9341
|
+
if (!entry) {
|
|
9342
|
+
throw new DeployExecutionError(
|
|
9343
|
+
`\u5F53\u524D\u76EE\u5F55\u672A\u547D\u4E2D workspace-repos \u4E2D\u7684\u4ED3\u5E93: ${start}`,
|
|
9344
|
+
1
|
|
9345
|
+
);
|
|
9346
|
+
}
|
|
9347
|
+
const abs = absoluteRepoPath(manifest.workdir, entry);
|
|
9348
|
+
const remoteUrl = toHttpsGitRemoteUrl(entry.remoteUrl ?? "") || await tryReadHttpsGitOriginUrl(abs);
|
|
9349
|
+
if (!remoteUrl) {
|
|
9350
|
+
throw new DeployExecutionError(
|
|
9351
|
+
`\u4ED3 ${entry.path} \u65E0\u53EF\u7528\u7684 https remote\uFF0C\u65E0\u6CD5\u5339\u914D\u5E73\u53F0\u4ED3\u5E93`,
|
|
9352
|
+
1
|
|
9353
|
+
);
|
|
9354
|
+
}
|
|
9355
|
+
let baseBranch = "";
|
|
9356
|
+
try {
|
|
9357
|
+
const gitRoot = await resolveGitRepoRoot(abs);
|
|
9358
|
+
baseBranch = (await resolveDefaultRemoteBranch(gitRoot)).trim();
|
|
9359
|
+
} catch (err) {
|
|
9360
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9361
|
+
throw new DeployExecutionError(`\u89E3\u6790\u5F53\u524D\u4ED3\u57FA\u7EBF\u5206\u652F\u5931\u8D25: ${detail}`, 1);
|
|
9362
|
+
}
|
|
9363
|
+
if (!baseBranch) {
|
|
9364
|
+
throw new DeployExecutionError(
|
|
9365
|
+
"\u65E0\u6CD5\u786E\u5B9A\u5F53\u524D\u4ED3\u57FA\u7EBF\u5206\u652F\uFF0C\u65E0\u6CD5\u5339\u914D\u5E73\u53F0\u4ED3\u5E93",
|
|
9366
|
+
1
|
|
9367
|
+
);
|
|
9368
|
+
}
|
|
9369
|
+
let matched;
|
|
9370
|
+
try {
|
|
9371
|
+
matched = await api.cli.matchRepository({
|
|
9372
|
+
url: remoteUrl,
|
|
9373
|
+
baseBranch
|
|
9374
|
+
});
|
|
9375
|
+
} catch (err) {
|
|
9376
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
9377
|
+
throw new DeployExecutionError(
|
|
9378
|
+
`\u6309 https remote + \u57FA\u7EBF\u5206\u652F\u5339\u914D\u5E73\u53F0\u4ED3\u5E93\u5931\u8D25: ${detail}`,
|
|
9379
|
+
1
|
|
9380
|
+
);
|
|
9381
|
+
}
|
|
9382
|
+
const repositoryId = matched.repositoryId?.trim() || "";
|
|
9383
|
+
if (!repositoryId) {
|
|
9384
|
+
throw new DeployExecutionError(
|
|
9385
|
+
`\u672A\u5339\u914D\u5230\u5E73\u53F0\u4ED3\u5E93 path=${entry.path} url=${remoteUrl} baseBranch=${baseBranch}`,
|
|
9386
|
+
1
|
|
9387
|
+
);
|
|
9388
|
+
}
|
|
9389
|
+
console.log(
|
|
9390
|
+
`[apm] \u90E8\u7F72\u8BB0\u5F55\u4ED3\u5E93 path=${entry.path} https+baseBranch=${baseBranch} \u2192 repositoryId=${repositoryId}`
|
|
9391
|
+
);
|
|
9392
|
+
return repositoryId;
|
|
9393
|
+
}
|
|
9084
9394
|
async function runDeployWithBackendTracking(options) {
|
|
9395
|
+
const { tracking, ...deployOptions } = options;
|
|
9085
9396
|
const cfg = await tryReadApmConfig();
|
|
9086
9397
|
if (!cfg || !resolveApiKey(cfg)) {
|
|
9087
|
-
|
|
9088
|
-
await executeDeploy(options);
|
|
9089
|
-
return;
|
|
9398
|
+
throw new DeployExecutionError("\u672A\u767B\u5F55\uFF0C\u65E0\u6CD5\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55", 1);
|
|
9090
9399
|
}
|
|
9091
|
-
const environment = normalizeDeployEnvironment(
|
|
9400
|
+
const environment = normalizeDeployEnvironment(deployOptions.env);
|
|
9092
9401
|
if (!environment) {
|
|
9093
|
-
|
|
9094
|
-
|
|
9402
|
+
throw new DeployExecutionError(
|
|
9403
|
+
`\u672A\u77E5\u90E8\u7F72\u73AF\u5883 ${deployOptions.env}\uFF0C\u4EC5\u652F\u6301 test/online`,
|
|
9404
|
+
1
|
|
9095
9405
|
);
|
|
9096
|
-
await executeDeploy(options);
|
|
9097
|
-
return;
|
|
9098
9406
|
}
|
|
9099
9407
|
const api = createApmApiClient(cfg);
|
|
9408
|
+
const repositoryId = tracking.kind === "task" ? await resolveRepositoryIdForWebIdeDeploy(deployOptions.cwd, api) : void 0;
|
|
9100
9409
|
let deploymentRunId;
|
|
9101
9410
|
try {
|
|
9102
9411
|
const run = await api.cli.createTaskDeployment({
|
|
9103
|
-
sessionId:
|
|
9412
|
+
...tracking.kind === "session" ? { sessionId: tracking.sessionId } : { taskId: tracking.taskId },
|
|
9104
9413
|
environment,
|
|
9105
|
-
workdirPath: resolveWorkdirPath(
|
|
9414
|
+
workdirPath: resolveWorkdirPath(deployOptions.cwd),
|
|
9415
|
+
...repositoryId ? { repositoryId } : {}
|
|
9106
9416
|
});
|
|
9107
9417
|
deploymentRunId = run.id;
|
|
9108
9418
|
console.log(
|
|
9109
9419
|
`[apm] \u5DF2\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55 id=${deploymentRunId} env=${environment}`
|
|
9110
9420
|
);
|
|
9111
9421
|
} catch (error) {
|
|
9422
|
+
if (error instanceof DeployExecutionError) {
|
|
9423
|
+
throw error;
|
|
9424
|
+
}
|
|
9112
9425
|
const detail = error instanceof Error ? error.message : String(error);
|
|
9113
|
-
|
|
9114
|
-
await executeDeploy(options);
|
|
9115
|
-
return;
|
|
9426
|
+
throw new DeployExecutionError(`\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5931\u8D25: ${detail}`, 1);
|
|
9116
9427
|
}
|
|
9117
9428
|
await api.cli.updateTaskDeploymentStatus({
|
|
9118
9429
|
id: deploymentRunId,
|
|
@@ -9123,7 +9434,7 @@ async function runDeployWithBackendTracking(options) {
|
|
|
9123
9434
|
deploymentRunId,
|
|
9124
9435
|
run: async (appendLog) => {
|
|
9125
9436
|
const output = await executeDeploy({
|
|
9126
|
-
...
|
|
9437
|
+
...deployOptions,
|
|
9127
9438
|
captureOutput: true,
|
|
9128
9439
|
archiveDeployArtifact: true
|
|
9129
9440
|
});
|
|
@@ -9149,7 +9460,10 @@ function registerDeployMainCommand(program) {
|
|
|
9149
9460
|
"apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
|
|
9150
9461
|
).option(
|
|
9151
9462
|
"--session <sessionId>",
|
|
9152
|
-
"\u6C9F\u901A\u7FA4 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7"
|
|
9463
|
+
"\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"
|
|
9464
|
+
).option(
|
|
9465
|
+
"--task <taskId>",
|
|
9466
|
+
"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"
|
|
9153
9467
|
).option(
|
|
9154
9468
|
"--pack-only",
|
|
9155
9469
|
"\u4EC5\u6784\u5EFA/\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B SFTP/SSH\uFF08\u65E0\u9700 wisdomDeploy\uFF09"
|
|
@@ -9157,14 +9471,30 @@ function registerDeployMainCommand(program) {
|
|
|
9157
9471
|
async (env, opts) => {
|
|
9158
9472
|
const cwd = process.cwd();
|
|
9159
9473
|
const sessionId = opts.session?.trim();
|
|
9474
|
+
const taskId = opts.task?.trim();
|
|
9160
9475
|
const packOnly = Boolean(opts.packOnly);
|
|
9476
|
+
if (sessionId && taskId) {
|
|
9477
|
+
console.error("[apm] --session \u4E0E --task \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
9478
|
+
process.exit(1);
|
|
9479
|
+
}
|
|
9161
9480
|
try {
|
|
9162
9481
|
if (sessionId) {
|
|
9163
9482
|
await runDeployWithBackendTracking({
|
|
9164
9483
|
env,
|
|
9165
9484
|
cwd,
|
|
9166
9485
|
configPath: opts.config,
|
|
9167
|
-
sessionId,
|
|
9486
|
+
tracking: { kind: "session", sessionId },
|
|
9487
|
+
packOnly,
|
|
9488
|
+
deployTrigger: "session"
|
|
9489
|
+
});
|
|
9490
|
+
return;
|
|
9491
|
+
}
|
|
9492
|
+
if (taskId) {
|
|
9493
|
+
await runDeployWithBackendTracking({
|
|
9494
|
+
env,
|
|
9495
|
+
cwd,
|
|
9496
|
+
configPath: opts.config,
|
|
9497
|
+
tracking: { kind: "task", taskId },
|
|
9168
9498
|
packOnly,
|
|
9169
9499
|
deployTrigger: "session"
|
|
9170
9500
|
});
|
|
@@ -9198,7 +9528,7 @@ import path15 from "node:path";
|
|
|
9198
9528
|
import Docker from "dockerode";
|
|
9199
9529
|
|
|
9200
9530
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
9201
|
-
import { existsSync as
|
|
9531
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19 } from "node:fs";
|
|
9202
9532
|
import path12 from "node:path";
|
|
9203
9533
|
function asOptionalTlsBuffer(value) {
|
|
9204
9534
|
if (typeof value !== "string") {
|
|
@@ -9210,8 +9540,8 @@ function asOptionalTlsBuffer(value) {
|
|
|
9210
9540
|
if (normalized === "") {
|
|
9211
9541
|
return void 0;
|
|
9212
9542
|
}
|
|
9213
|
-
if (
|
|
9214
|
-
return
|
|
9543
|
+
if (existsSync26(normalized)) {
|
|
9544
|
+
return readFileSync19(normalized);
|
|
9215
9545
|
}
|
|
9216
9546
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
9217
9547
|
if (looksLikePath) {
|
|
@@ -9336,17 +9666,17 @@ var DockerodeClient = class {
|
|
|
9336
9666
|
await this.client.getImage(image).remove({ force: true });
|
|
9337
9667
|
}
|
|
9338
9668
|
async pullImage(image, auth) {
|
|
9339
|
-
const stream = await new Promise((
|
|
9669
|
+
const stream = await new Promise((resolve8, reject) => {
|
|
9340
9670
|
const pullOptions = auth ? { authconfig: auth } : void 0;
|
|
9341
9671
|
this.client.pull(image, pullOptions, (err, output) => {
|
|
9342
9672
|
if (err || !output) {
|
|
9343
9673
|
reject(err ?? new Error("docker pull \u8FD4\u56DE\u7A7A\u8F93\u51FA"));
|
|
9344
9674
|
return;
|
|
9345
9675
|
}
|
|
9346
|
-
|
|
9676
|
+
resolve8(output);
|
|
9347
9677
|
});
|
|
9348
9678
|
});
|
|
9349
|
-
await new Promise((
|
|
9679
|
+
await new Promise((resolve8, reject) => {
|
|
9350
9680
|
this.client.modem.followProgress(
|
|
9351
9681
|
stream,
|
|
9352
9682
|
(err) => {
|
|
@@ -9354,7 +9684,7 @@ var DockerodeClient = class {
|
|
|
9354
9684
|
reject(err);
|
|
9355
9685
|
return;
|
|
9356
9686
|
}
|
|
9357
|
-
|
|
9687
|
+
resolve8();
|
|
9358
9688
|
},
|
|
9359
9689
|
() => void 0
|
|
9360
9690
|
);
|
|
@@ -9421,7 +9751,7 @@ var DockerodeClient = class {
|
|
|
9421
9751
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
9422
9752
|
|
|
9423
9753
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
9424
|
-
import { existsSync as
|
|
9754
|
+
import { existsSync as existsSync27, readFileSync as readFileSync20, statSync as statSync11 } from "node:fs";
|
|
9425
9755
|
import path13 from "node:path";
|
|
9426
9756
|
function stripSurroundingQuotes(value) {
|
|
9427
9757
|
const t = value.trim();
|
|
@@ -9438,10 +9768,10 @@ function loadEnvFromFile(envFilePath) {
|
|
|
9438
9768
|
return {};
|
|
9439
9769
|
}
|
|
9440
9770
|
const targetPath = path13.resolve(envFilePath);
|
|
9441
|
-
if (!
|
|
9771
|
+
if (!existsSync27(targetPath) || !statSync11(targetPath).isFile()) {
|
|
9442
9772
|
return {};
|
|
9443
9773
|
}
|
|
9444
|
-
const raw =
|
|
9774
|
+
const raw = readFileSync20(targetPath, "utf-8");
|
|
9445
9775
|
const result = {};
|
|
9446
9776
|
for (const line of raw.split(/\r?\n/)) {
|
|
9447
9777
|
const normalized = line.trim();
|
|
@@ -9612,12 +9942,12 @@ function dockerPushImage(params, cwd) {
|
|
|
9612
9942
|
}
|
|
9613
9943
|
|
|
9614
9944
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
9615
|
-
import { existsSync as
|
|
9945
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
9616
9946
|
import path14 from "node:path";
|
|
9617
9947
|
function resolveDockerBuildPaths(cwd) {
|
|
9618
9948
|
const dockerfilePath = path14.join(cwd, "Dockerfile");
|
|
9619
9949
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
9620
|
-
if (!
|
|
9950
|
+
if (!existsSync28(dockerfilePath)) {
|
|
9621
9951
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
9622
9952
|
}
|
|
9623
9953
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|
|
@@ -10048,12 +10378,12 @@ function buildProgram() {
|
|
|
10048
10378
|
await runSyncDeployConfig();
|
|
10049
10379
|
});
|
|
10050
10380
|
program.command("sync-project-documents").description(
|
|
10051
|
-
"\u540C\u6B65\u9879\u76EE\u6587\u6863\uFF1A\u9ED8\u8BA4 pull \u5230 .apm/
|
|
10052
|
-
).option("--push", "\u63A8\u9001\u672C\u5730 .apm/
|
|
10381
|
+
"\u540C\u6B65\u9879\u76EE\u6587\u6863\uFF1A\u9ED8\u8BA4 pull \u5230 .apm/project/<\u9879\u76EEID>/\uFF1B\u52A0 --push \u5C06\u672C\u5730\u53D8\u66F4\u63A8\u9001\u5230\u5E73\u53F0"
|
|
10382
|
+
).option("--push", "\u63A8\u9001\u672C\u5730 .apm/project/<\u9879\u76EEID>/ \u5230\u5E73\u53F0").option("--pull", "\u4ECE\u5E73\u53F0\u62C9\u53D6\u5230 .apm/project/<\u9879\u76EEID>/").action(async (opts) => {
|
|
10053
10383
|
await runSyncProjectDocuments(opts);
|
|
10054
10384
|
});
|
|
10055
10385
|
program.command("pull").description(
|
|
10056
|
-
"\u62C9\u53D6\u6C9F\u901A\u7FA4\u6570\u636E\u5230 .apm/sessions/<sessionId>/\uFF0C\u5E76\u540C\u6B65\u90E8\u7F72\u914D\u7F6E\u4E0E\u9879\u76EE\u6587\u6863\u5230 .apm/
|
|
10386
|
+
"\u62C9\u53D6\u6C9F\u901A\u7FA4\u6570\u636E\u5230 .apm/sessions/<sessionId>/\uFF0C\u5E76\u540C\u6B65\u90E8\u7F72\u914D\u7F6E\u4E0E\u9879\u76EE\u6587\u6863\u5230 .apm/project/<\u9879\u76EEID>/"
|
|
10057
10387
|
).argument("<sessionId>", "\u6C9F\u901A\u7FA4 ID").action(async (sessionId) => {
|
|
10058
10388
|
await runPull(sessionId);
|
|
10059
10389
|
});
|