ai-project-manage-cli 6.0.97 → 6.0.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +171 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3758,7 +3758,13 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT) {
|
|
|
3758
3758
|
}
|
|
3759
3759
|
|
|
3760
3760
|
// src/commands/connect-lock.ts
|
|
3761
|
-
import {
|
|
3761
|
+
import {
|
|
3762
|
+
existsSync as existsSync13,
|
|
3763
|
+
mkdirSync as mkdirSync6,
|
|
3764
|
+
readFileSync as readFileSync12,
|
|
3765
|
+
unlinkSync,
|
|
3766
|
+
writeFileSync as writeFileSync12
|
|
3767
|
+
} from "fs";
|
|
3762
3768
|
import { join as join14 } from "path";
|
|
3763
3769
|
var CONNECT_LOCK_PATH = join14(APM_CONFIG_DIR, "connect.lock");
|
|
3764
3770
|
function isProcessAlive(pid) {
|
|
@@ -3770,6 +3776,22 @@ function isProcessAlive(pid) {
|
|
|
3770
3776
|
return false;
|
|
3771
3777
|
}
|
|
3772
3778
|
}
|
|
3779
|
+
function sleepSync(ms) {
|
|
3780
|
+
const deadline = Date.now() + ms;
|
|
3781
|
+
while (Date.now() < deadline) {
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
function waitForPm2LockHandoff(timeoutMs = 5e3) {
|
|
3785
|
+
const deadline = Date.now() + timeoutMs;
|
|
3786
|
+
while (Date.now() < deadline) {
|
|
3787
|
+
pruneStaleConnectLock();
|
|
3788
|
+
const lock = readConnectLock();
|
|
3789
|
+
if (!lock || lock.mode !== "pm2" || lock.pid === process.pid || !isProcessAlive(lock.pid)) {
|
|
3790
|
+
return;
|
|
3791
|
+
}
|
|
3792
|
+
sleepSync(100);
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3773
3795
|
function readConnectLock() {
|
|
3774
3796
|
if (!existsSync13(CONNECT_LOCK_PATH)) return null;
|
|
3775
3797
|
try {
|
|
@@ -3796,10 +3818,17 @@ function acquireConnectLock(mode) {
|
|
|
3796
3818
|
pruneStaleConnectLock();
|
|
3797
3819
|
const existing = readConnectLock();
|
|
3798
3820
|
if (existing && isProcessAlive(existing.pid)) {
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3821
|
+
if (existing.pid === process.pid) {
|
|
3822
|
+
return;
|
|
3823
|
+
}
|
|
3824
|
+
if (mode === "pm2" && existing.mode === "pm2") {
|
|
3825
|
+
forceReleaseConnectLock();
|
|
3826
|
+
} else {
|
|
3827
|
+
console.error(
|
|
3828
|
+
`[apm] \u5DF2\u6709 apm connect \u5728\u8FD0\u884C (pid=${existing.pid}, mode=${existing.mode})`
|
|
3829
|
+
);
|
|
3830
|
+
process.exit(1);
|
|
3831
|
+
}
|
|
3803
3832
|
}
|
|
3804
3833
|
mkdirSync6(APM_CONFIG_DIR, { recursive: true });
|
|
3805
3834
|
const lock = {
|
|
@@ -3807,7 +3836,11 @@ function acquireConnectLock(mode) {
|
|
|
3807
3836
|
mode,
|
|
3808
3837
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3809
3838
|
};
|
|
3810
|
-
writeFileSync12(
|
|
3839
|
+
writeFileSync12(
|
|
3840
|
+
CONNECT_LOCK_PATH,
|
|
3841
|
+
JSON.stringify(lock, null, 2) + "\n",
|
|
3842
|
+
"utf8"
|
|
3843
|
+
);
|
|
3811
3844
|
}
|
|
3812
3845
|
function releaseConnectLock() {
|
|
3813
3846
|
const lock = readConnectLock();
|
|
@@ -3829,10 +3862,18 @@ function forceReleaseConnectLock() {
|
|
|
3829
3862
|
// src/commands/daemon.ts
|
|
3830
3863
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
3831
3864
|
import { setTimeout as delay } from "node:timers/promises";
|
|
3832
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync7, writeFileSync as writeFileSync13 } from "fs";
|
|
3865
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync13 } from "fs";
|
|
3833
3866
|
import { join as join15 } from "path";
|
|
3834
3867
|
var PM2_APP_NAME = "apm-connect";
|
|
3835
|
-
var PM2_ECOSYSTEM_PATH = join15(
|
|
3868
|
+
var PM2_ECOSYSTEM_PATH = join15(
|
|
3869
|
+
APM_CONFIG_DIR,
|
|
3870
|
+
"connect.ecosystem.config.cjs"
|
|
3871
|
+
);
|
|
3872
|
+
var LEGACY_PM2_ECOSYSTEM_PATH = join15(
|
|
3873
|
+
APM_CONFIG_DIR,
|
|
3874
|
+
"connect.ecosystem.cjs"
|
|
3875
|
+
);
|
|
3876
|
+
var LEGACY_PM2_APP_NAMES = ["connect.ecosystem"];
|
|
3836
3877
|
function resolveConnectArgs(server) {
|
|
3837
3878
|
const args = ["connect"];
|
|
3838
3879
|
const trimmed = server?.trim();
|
|
@@ -3847,24 +3888,28 @@ function buildConnectPm2Ecosystem(options) {
|
|
|
3847
3888
|
if (baseUrl) {
|
|
3848
3889
|
env.AI_PM_SERVER = baseUrl;
|
|
3849
3890
|
}
|
|
3891
|
+
const app = {
|
|
3892
|
+
name: PM2_APP_NAME,
|
|
3893
|
+
script: options.apmScript,
|
|
3894
|
+
interpreter: options.nodePath,
|
|
3895
|
+
args: options.connectArgs,
|
|
3896
|
+
autorestart: true,
|
|
3897
|
+
min_uptime: "10s",
|
|
3898
|
+
max_restarts: 10,
|
|
3899
|
+
restart_delay: 3e3,
|
|
3900
|
+
exp_backoff_restart_delay: 1e3,
|
|
3901
|
+
max_memory_restart: "1G",
|
|
3902
|
+
kill_timeout: 5e3,
|
|
3903
|
+
shutdown_with_message: true,
|
|
3904
|
+
instances: 1,
|
|
3905
|
+
exec_mode: "fork",
|
|
3906
|
+
env
|
|
3907
|
+
};
|
|
3908
|
+
if (process.platform === "win32") {
|
|
3909
|
+
app.windowsHide = true;
|
|
3910
|
+
}
|
|
3850
3911
|
return {
|
|
3851
|
-
apps: [
|
|
3852
|
-
{
|
|
3853
|
-
name: PM2_APP_NAME,
|
|
3854
|
-
script: options.apmScript,
|
|
3855
|
-
interpreter: options.nodePath,
|
|
3856
|
-
args: options.connectArgs,
|
|
3857
|
-
autorestart: true,
|
|
3858
|
-
min_uptime: "10s",
|
|
3859
|
-
max_restarts: 0,
|
|
3860
|
-
restart_delay: 3e3,
|
|
3861
|
-
exp_backoff_restart_delay: 1e3,
|
|
3862
|
-
max_memory_restart: "1G",
|
|
3863
|
-
kill_timeout: 5e3,
|
|
3864
|
-
shutdown_with_message: true,
|
|
3865
|
-
env
|
|
3866
|
-
}
|
|
3867
|
-
]
|
|
3912
|
+
apps: [app]
|
|
3868
3913
|
};
|
|
3869
3914
|
}
|
|
3870
3915
|
function formatConnectPm2EcosystemFile(ecosystem) {
|
|
@@ -4033,14 +4078,66 @@ function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
|
4033
4078
|
process.exit(1);
|
|
4034
4079
|
}
|
|
4035
4080
|
function isRunningUnderPm2() {
|
|
4036
|
-
|
|
4081
|
+
if (process.env.pm_id === void 0) {
|
|
4082
|
+
return false;
|
|
4083
|
+
}
|
|
4084
|
+
const name = process.env.name;
|
|
4085
|
+
return name === PM2_APP_NAME || name !== void 0 && LEGACY_PM2_APP_NAMES.includes(name);
|
|
4086
|
+
}
|
|
4087
|
+
function isConnectPm2Process(app) {
|
|
4088
|
+
if (app.name === PM2_APP_NAME) {
|
|
4089
|
+
return true;
|
|
4090
|
+
}
|
|
4091
|
+
return app.name !== void 0 && LEGACY_PM2_APP_NAMES.includes(app.name);
|
|
4092
|
+
}
|
|
4093
|
+
function listPm2Processes() {
|
|
4094
|
+
try {
|
|
4095
|
+
const raw = runPm2Json(["jlist"]);
|
|
4096
|
+
return JSON.parse(raw);
|
|
4097
|
+
} catch {
|
|
4098
|
+
return [];
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
function findPm2ConnectProcess() {
|
|
4102
|
+
return listPm2Processes().find(isConnectPm2Process) ?? null;
|
|
4103
|
+
}
|
|
4104
|
+
function resolvePm2ConnectName(app) {
|
|
4105
|
+
return app?.name ?? PM2_APP_NAME;
|
|
4106
|
+
}
|
|
4107
|
+
function deletePm2AppIfExists(name) {
|
|
4108
|
+
const pm2Bin = findGlobalPm2();
|
|
4109
|
+
if (!pm2Bin) {
|
|
4110
|
+
return;
|
|
4111
|
+
}
|
|
4112
|
+
ensurePm2DaemonUpdated(pm2Bin);
|
|
4113
|
+
spawnSync2(pm2Bin, ["delete", name], {
|
|
4114
|
+
encoding: "utf8",
|
|
4115
|
+
shell: useNpmShell2,
|
|
4116
|
+
stdio: "ignore",
|
|
4117
|
+
windowsHide: useNpmShell2
|
|
4118
|
+
});
|
|
4119
|
+
}
|
|
4120
|
+
function removePm2ConnectProcesses() {
|
|
4121
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4122
|
+
for (const app of listPm2Processes()) {
|
|
4123
|
+
if (!isConnectPm2Process(app) || !app.name || seen.has(app.name)) {
|
|
4124
|
+
continue;
|
|
4125
|
+
}
|
|
4126
|
+
seen.add(app.name);
|
|
4127
|
+
deletePm2AppIfExists(app.name);
|
|
4128
|
+
}
|
|
4129
|
+
for (const legacyName of LEGACY_PM2_APP_NAMES) {
|
|
4130
|
+
deletePm2AppIfExists(legacyName);
|
|
4131
|
+
}
|
|
4132
|
+
deletePm2AppIfExists(PM2_APP_NAME);
|
|
4037
4133
|
}
|
|
4038
4134
|
function runPm2(args, options) {
|
|
4039
4135
|
const pm2Bin = ensureGlobalPm2({ quiet: true });
|
|
4040
4136
|
const spawnOptions = {
|
|
4041
4137
|
encoding: "utf8",
|
|
4042
4138
|
stdio: options?.inherit ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
4043
|
-
shell: useNpmShell2
|
|
4139
|
+
shell: useNpmShell2,
|
|
4140
|
+
windowsHide: useNpmShell2
|
|
4044
4141
|
};
|
|
4045
4142
|
const result = spawnSync2(pm2Bin, args, spawnOptions);
|
|
4046
4143
|
if (result.error) {
|
|
@@ -4064,7 +4161,8 @@ function runPm2Json(args) {
|
|
|
4064
4161
|
const result = spawnSync2(pm2Bin, args, {
|
|
4065
4162
|
encoding: "utf8",
|
|
4066
4163
|
stdio: ["ignore", "pipe", "pipe"],
|
|
4067
|
-
shell: useNpmShell2
|
|
4164
|
+
shell: useNpmShell2,
|
|
4165
|
+
windowsHide: useNpmShell2
|
|
4068
4166
|
});
|
|
4069
4167
|
if (result.status !== 0) return "[]";
|
|
4070
4168
|
return result.stdout?.toString() ?? "[]";
|
|
@@ -4075,15 +4173,6 @@ function isPm2ConnectOnline() {
|
|
|
4075
4173
|
const status = app.pm2_env?.status;
|
|
4076
4174
|
return status === "online" || status === "launching";
|
|
4077
4175
|
}
|
|
4078
|
-
function findPm2ConnectProcess() {
|
|
4079
|
-
try {
|
|
4080
|
-
const raw = runPm2Json(["jlist"]);
|
|
4081
|
-
const list = JSON.parse(raw);
|
|
4082
|
-
return list.find((app) => app.name === PM2_APP_NAME) ?? null;
|
|
4083
|
-
} catch {
|
|
4084
|
-
return null;
|
|
4085
|
-
}
|
|
4086
|
-
}
|
|
4087
4176
|
function printConnectNotRunningHint() {
|
|
4088
4177
|
console.log(`[apm] ${PM2_APP_NAME} \u672A\u5728\u8FD0\u884C`);
|
|
4089
4178
|
console.log("[apm] \u542F\u52A8\u5B88\u62A4: apm connect --daemon");
|
|
@@ -4091,13 +4180,13 @@ function printConnectNotRunningHint() {
|
|
|
4091
4180
|
function assertConnectNotRunning() {
|
|
4092
4181
|
pruneStaleConnectLock();
|
|
4093
4182
|
const lock = readConnectLock();
|
|
4094
|
-
if (lock && isProcessAlive(lock.pid)) {
|
|
4183
|
+
if (lock && isProcessAlive(lock.pid) && lock.pid !== process.pid) {
|
|
4095
4184
|
console.error(
|
|
4096
4185
|
`[apm] \u5DF2\u6709 apm connect \u5728\u8FD0\u884C (pid=${lock.pid}, mode=${lock.mode})\uFF0C\u8BF7\u5148\u505C\u6B62\u540E\u518D\u542F\u52A8`
|
|
4097
4186
|
);
|
|
4098
4187
|
process.exit(1);
|
|
4099
4188
|
}
|
|
4100
|
-
if (isPm2ConnectOnline()) {
|
|
4189
|
+
if (!isRunningUnderPm2() && isPm2ConnectOnline()) {
|
|
4101
4190
|
console.error(
|
|
4102
4191
|
"[apm] \u5DF2\u6709 apm connect \u5B88\u62A4\u8FDB\u7A0B\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u6267\u884C apm daemon stop"
|
|
4103
4192
|
);
|
|
@@ -4128,10 +4217,8 @@ async function handleConnectAfterUpdate(options) {
|
|
|
4128
4217
|
console.log("[apm] \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u4EE5\u65B0\u7248\u672C\u91CD\u65B0\u8FDE\u63A5\u2026");
|
|
4129
4218
|
await prepareEcosystem(options.server);
|
|
4130
4219
|
if (isRunningUnderPm2()) {
|
|
4131
|
-
runPm2(["
|
|
4132
|
-
|
|
4133
|
-
});
|
|
4134
|
-
console.log("[apm] \u5DF2\u901A\u77E5 PM2 \u4F7F\u7528\u65B0\u7248\u672C\u91CD\u542F connect");
|
|
4220
|
+
runPm2(["reload", PM2_ECOSYSTEM_PATH, "--update-env"], { inherit: true });
|
|
4221
|
+
console.log("[apm] \u5DF2\u901A\u77E5 PM2 \u4F7F\u7528\u65B0\u7248\u672C\u91CD\u65B0\u52A0\u8F7D connect");
|
|
4135
4222
|
process.exit(0);
|
|
4136
4223
|
}
|
|
4137
4224
|
reexecConnectWithResolvedPath(options);
|
|
@@ -4151,6 +4238,12 @@ function writeEcosystemFile(options) {
|
|
|
4151
4238
|
formatConnectPm2EcosystemFile(ecosystem),
|
|
4152
4239
|
"utf8"
|
|
4153
4240
|
);
|
|
4241
|
+
if (existsSync14(LEGACY_PM2_ECOSYSTEM_PATH)) {
|
|
4242
|
+
try {
|
|
4243
|
+
unlinkSync2(LEGACY_PM2_ECOSYSTEM_PATH);
|
|
4244
|
+
} catch {
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4154
4247
|
}
|
|
4155
4248
|
async function prepareEcosystem(server) {
|
|
4156
4249
|
await ensureLoggedConfig();
|
|
@@ -4171,7 +4264,14 @@ async function runDaemonStart(options) {
|
|
|
4171
4264
|
await runUpdate();
|
|
4172
4265
|
ensureGlobalPm2();
|
|
4173
4266
|
const cfg = await prepareEcosystem(options.server);
|
|
4267
|
+
removePm2ConnectProcesses();
|
|
4174
4268
|
runPm2(["start", PM2_ECOSYSTEM_PATH, "--update-env"], { inherit: true });
|
|
4269
|
+
await delay(1e3);
|
|
4270
|
+
if (!isPm2ConnectOnline()) {
|
|
4271
|
+
console.error(
|
|
4272
|
+
`[apm] ${PM2_APP_NAME} \u542F\u52A8\u540E\u672A\u5904\u4E8E online \u72B6\u6001\uFF0C\u8BF7\u6267\u884C: apm daemon logs -n 200`
|
|
4273
|
+
);
|
|
4274
|
+
}
|
|
4175
4275
|
console.log(
|
|
4176
4276
|
`[apm] ${PM2_APP_NAME} \u5DF2\u7531 PM2 \u542F\u52A8\uFF08server=${options.server?.trim() || cfg.baseUrl}\uFF09`
|
|
4177
4277
|
);
|
|
@@ -4194,14 +4294,18 @@ async function runDaemonStop() {
|
|
|
4194
4294
|
console.log(`[apm] ${PM2_APP_NAME} \u672A\u5728\u8FD0\u884C`);
|
|
4195
4295
|
return;
|
|
4196
4296
|
}
|
|
4197
|
-
runPm2(["stop",
|
|
4297
|
+
runPm2(["stop", resolvePm2ConnectName(findPm2ConnectProcess())], {
|
|
4298
|
+
inherit: true
|
|
4299
|
+
});
|
|
4198
4300
|
for (let i = 0; i < 10; i += 1) {
|
|
4199
4301
|
if (!isPm2ConnectOnline()) break;
|
|
4200
4302
|
await delay(500);
|
|
4201
4303
|
}
|
|
4202
4304
|
if (isPm2ConnectOnline()) {
|
|
4203
4305
|
console.log(`[apm] \u4F18\u96C5\u505C\u6B62\u8D85\u65F6\uFF0C\u5F3A\u5236\u79FB\u9664 ${PM2_APP_NAME}\u2026`);
|
|
4204
|
-
runPm2(["delete",
|
|
4306
|
+
runPm2(["delete", resolvePm2ConnectName(findPm2ConnectProcess())], {
|
|
4307
|
+
inherit: true
|
|
4308
|
+
});
|
|
4205
4309
|
}
|
|
4206
4310
|
killConnectLockProcessIfAlive();
|
|
4207
4311
|
forceReleaseConnectLock();
|
|
@@ -4236,36 +4340,38 @@ async function runDaemonRestart(options) {
|
|
|
4236
4340
|
}
|
|
4237
4341
|
await runUpdate();
|
|
4238
4342
|
await prepareEcosystem(options.server);
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
});
|
|
4343
|
+
removePm2ConnectProcesses();
|
|
4344
|
+
runPm2(["start", PM2_ECOSYSTEM_PATH, "--update-env"], { inherit: true });
|
|
4242
4345
|
console.log(`[apm] ${PM2_APP_NAME} \u5DF2\u91CD\u542F`);
|
|
4243
4346
|
}
|
|
4244
4347
|
async function runDaemonDelete() {
|
|
4245
4348
|
ensureGlobalPm2();
|
|
4246
|
-
|
|
4349
|
+
const app = findPm2ConnectProcess();
|
|
4350
|
+
if (!app?.name) {
|
|
4247
4351
|
console.log(`[apm] ${PM2_APP_NAME} \u672A\u5728 PM2 \u4E2D\u6CE8\u518C`);
|
|
4248
4352
|
return;
|
|
4249
4353
|
}
|
|
4250
|
-
runPm2(["delete",
|
|
4354
|
+
runPm2(["delete", app.name], { inherit: true });
|
|
4251
4355
|
forceReleaseConnectLock();
|
|
4252
|
-
console.log(`[apm] ${
|
|
4356
|
+
console.log(`[apm] ${app.name} \u5DF2\u4ECE PM2 \u79FB\u9664`);
|
|
4253
4357
|
}
|
|
4254
4358
|
async function runDaemonStatus() {
|
|
4255
4359
|
ensureGlobalPm2();
|
|
4256
|
-
|
|
4360
|
+
const app = findPm2ConnectProcess();
|
|
4361
|
+
if (!app?.name) {
|
|
4257
4362
|
printConnectNotRunningHint();
|
|
4258
4363
|
return;
|
|
4259
4364
|
}
|
|
4260
|
-
runPm2(["describe",
|
|
4365
|
+
runPm2(["describe", app.name], { inherit: true });
|
|
4261
4366
|
}
|
|
4262
4367
|
async function runDaemonLogs(options) {
|
|
4263
4368
|
ensureGlobalPm2();
|
|
4264
|
-
|
|
4369
|
+
const app = findPm2ConnectProcess();
|
|
4370
|
+
if (!app?.name) {
|
|
4265
4371
|
printConnectNotRunningHint();
|
|
4266
4372
|
return;
|
|
4267
4373
|
}
|
|
4268
|
-
const args = ["logs",
|
|
4374
|
+
const args = ["logs", app.name, "--lines", String(options.lines ?? 100)];
|
|
4269
4375
|
if (!options.follow) {
|
|
4270
4376
|
args.push("--nostream");
|
|
4271
4377
|
}
|
|
@@ -4616,9 +4722,12 @@ function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
|
4616
4722
|
});
|
|
4617
4723
|
}
|
|
4618
4724
|
async function runConnect(options) {
|
|
4619
|
-
const
|
|
4620
|
-
if (
|
|
4621
|
-
await
|
|
4725
|
+
const underPm2 = isRunningUnderPm2();
|
|
4726
|
+
if (!underPm2) {
|
|
4727
|
+
const { didUpdate } = await runUpdate();
|
|
4728
|
+
if (didUpdate) {
|
|
4729
|
+
await handleConnectAfterUpdate(options);
|
|
4730
|
+
}
|
|
4622
4731
|
}
|
|
4623
4732
|
const cfg = await ensureLoggedConfig();
|
|
4624
4733
|
if (options.server?.trim()) {
|
|
@@ -4630,7 +4739,10 @@ async function runConnect(options) {
|
|
|
4630
4739
|
process.exit(1);
|
|
4631
4740
|
}
|
|
4632
4741
|
assertConnectNotRunning();
|
|
4633
|
-
|
|
4742
|
+
if (underPm2) {
|
|
4743
|
+
waitForPm2LockHandoff();
|
|
4744
|
+
}
|
|
4745
|
+
const lockMode = underPm2 ? "pm2" : "foreground";
|
|
4634
4746
|
acquireConnectLock(lockMode);
|
|
4635
4747
|
process.on("exit", releaseConnectLock);
|
|
4636
4748
|
let shuttingDown = false;
|