@pmate/cli 0.12.8 → 0.13.1
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 +3 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +437 -403
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12407,10 +12407,10 @@ function resolveHubBaseUrl(value) {
|
|
|
12407
12407
|
}
|
|
12408
12408
|
function readSessionToken() {
|
|
12409
12409
|
const sessionPath = import_node_path13.default.join(import_node_os4.default.homedir(), ".pmate", "session.json");
|
|
12410
|
-
if (!(0,
|
|
12410
|
+
if (!(0, import_node_fs10.existsSync)(sessionPath)) {
|
|
12411
12411
|
throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
|
|
12412
12412
|
}
|
|
12413
|
-
const raw = (0,
|
|
12413
|
+
const raw = (0, import_node_fs10.readFileSync)(sessionPath, "utf8");
|
|
12414
12414
|
const parsed = JSON.parse(raw);
|
|
12415
12415
|
const token = parsed.token?.trim();
|
|
12416
12416
|
if (!token) {
|
|
@@ -12427,11 +12427,11 @@ function unwrapAgentResult(value) {
|
|
|
12427
12427
|
}
|
|
12428
12428
|
return value;
|
|
12429
12429
|
}
|
|
12430
|
-
var
|
|
12430
|
+
var import_node_fs10, import_node_os4, import_node_path13, import_agent_sdk, DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_HUB_BASE_URL, DEFAULT_NAMESPACE, DEFAULT_FROM, AgentLlmClient;
|
|
12431
12431
|
var init_AgentLlmClient = __esm({
|
|
12432
12432
|
"src/llm/AgentLlmClient.ts"() {
|
|
12433
12433
|
"use strict";
|
|
12434
|
-
|
|
12434
|
+
import_node_fs10 = require("fs");
|
|
12435
12435
|
import_node_os4 = __toESM(require("os"));
|
|
12436
12436
|
import_node_path13 = __toESM(require("path"));
|
|
12437
12437
|
import_agent_sdk = __toESM(require_dist4());
|
|
@@ -12479,7 +12479,7 @@ __export(index_exports, {
|
|
|
12479
12479
|
parseCommandArgs: () => parseCommandArgs
|
|
12480
12480
|
});
|
|
12481
12481
|
module.exports = __toCommonJS(index_exports);
|
|
12482
|
-
var
|
|
12482
|
+
var import_node_fs17 = require("fs");
|
|
12483
12483
|
var import_node_path21 = __toESM(require("path"));
|
|
12484
12484
|
var import_chalk3 = __toESM(require("chalk"));
|
|
12485
12485
|
|
|
@@ -12523,232 +12523,14 @@ var ui = {
|
|
|
12523
12523
|
};
|
|
12524
12524
|
|
|
12525
12525
|
// src/commands/ListCommandHandler.ts
|
|
12526
|
-
var import_node_fs = require("fs");
|
|
12527
|
-
var import_node_path = __toESM(require("path"));
|
|
12528
|
-
var import_yaml = __toESM(require("yaml"));
|
|
12529
|
-
var ListCommandHandler = class {
|
|
12530
|
-
handle(args) {
|
|
12531
|
-
const targetDir = this.resolveTargetDir(args.targetPath);
|
|
12532
|
-
const config = this.loadConfig(targetDir);
|
|
12533
|
-
if (config.apps.length === 0) {
|
|
12534
|
-
ui.warn("No apps defined.");
|
|
12535
|
-
return;
|
|
12536
|
-
}
|
|
12537
|
-
for (const app of config.apps) {
|
|
12538
|
-
if (app && typeof app.app === "string") {
|
|
12539
|
-
if (typeof app.dir !== "string" || !app.dir.trim()) {
|
|
12540
|
-
throw new Error(`Invalid .pmate.yaml: missing dir for app ${app.app}`);
|
|
12541
|
-
}
|
|
12542
|
-
ui.info(`${app.app} -> ${app.dir}`);
|
|
12543
|
-
}
|
|
12544
|
-
}
|
|
12545
|
-
}
|
|
12546
|
-
resolveTargetDir(targetPath) {
|
|
12547
|
-
return targetPath ? import_node_path.default.resolve(process.cwd(), targetPath) : process.cwd();
|
|
12548
|
-
}
|
|
12549
|
-
loadConfig(targetDir) {
|
|
12550
|
-
const configPath = import_node_path.default.join(targetDir, ".pmate.yaml");
|
|
12551
|
-
if (!(0, import_node_fs.existsSync)(configPath)) {
|
|
12552
|
-
throw new Error(`No .pmate.yaml found in ${targetDir}`);
|
|
12553
|
-
}
|
|
12554
|
-
const raw = (0, import_node_fs.readFileSync)(configPath, "utf8");
|
|
12555
|
-
const parsed = import_yaml.default.parse(raw);
|
|
12556
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
12557
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
12558
|
-
}
|
|
12559
|
-
return parsed;
|
|
12560
|
-
}
|
|
12561
|
-
};
|
|
12562
|
-
|
|
12563
|
-
// src/commands/LoginCommandHandler.ts
|
|
12564
|
-
var import_node_fs2 = require("fs");
|
|
12565
|
-
var import_node_http = require("http");
|
|
12566
|
-
var import_node_os = __toESM(require("os"));
|
|
12567
12526
|
var import_node_path2 = __toESM(require("path"));
|
|
12568
|
-
var import_node_child_process = require("child_process");
|
|
12569
|
-
var AUTH_UI_BASE_URL = "https://auth.pmate.chat";
|
|
12570
|
-
var AUTH_API_BASE_URL = "https://auth-api-v2.pmate.chat";
|
|
12571
|
-
var CALLBACK_PATH = "/pmate-login-callback";
|
|
12572
|
-
var APP_ID = "@pmate/cli";
|
|
12573
|
-
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
12574
|
-
function buildHostedLoginUrl(redirectUrl) {
|
|
12575
|
-
const url = new URL(AUTH_UI_BASE_URL);
|
|
12576
|
-
url.searchParams.set("redirect", redirectUrl);
|
|
12577
|
-
url.searchParams.set("app", APP_ID);
|
|
12578
|
-
return url.toString();
|
|
12579
|
-
}
|
|
12580
|
-
var LoginCommandHandler = class {
|
|
12581
|
-
async handle(_args) {
|
|
12582
|
-
const callback = await this.startCallbackServer();
|
|
12583
|
-
const loginUrl = buildHostedLoginUrl(callback.redirectUrl);
|
|
12584
|
-
ui.info("Opening browser for login.", {
|
|
12585
|
-
url: loginUrl
|
|
12586
|
-
});
|
|
12587
|
-
if (!this.openBrowser(loginUrl)) {
|
|
12588
|
-
ui.warn("Unable to open the browser automatically.");
|
|
12589
|
-
ui.plain(loginUrl);
|
|
12590
|
-
}
|
|
12591
|
-
ui.info("Waiting for login redirect...", {
|
|
12592
|
-
callback: callback.redirectUrl
|
|
12593
|
-
});
|
|
12594
|
-
try {
|
|
12595
|
-
const token = await callback.waitForToken;
|
|
12596
|
-
const loginResponse = await this.fetchSession(token);
|
|
12597
|
-
const sessionPath = this.writeSession(loginResponse);
|
|
12598
|
-
ui.success(`Logged in. Session saved to ${sessionPath}`);
|
|
12599
|
-
} finally {
|
|
12600
|
-
await callback.close();
|
|
12601
|
-
}
|
|
12602
|
-
}
|
|
12603
|
-
async fetchSession(token) {
|
|
12604
|
-
const response = await fetch(`${AUTH_API_BASE_URL}/session`, {
|
|
12605
|
-
method: "GET",
|
|
12606
|
-
headers: {
|
|
12607
|
-
Authorization: `Bearer ${token}`
|
|
12608
|
-
}
|
|
12609
|
-
});
|
|
12610
|
-
if (!response.ok) {
|
|
12611
|
-
const detail = await response.text();
|
|
12612
|
-
throw new Error(
|
|
12613
|
-
`Failed to validate session (${response.status}): ${detail || response.statusText}`
|
|
12614
|
-
);
|
|
12615
|
-
}
|
|
12616
|
-
const resp = await response.json();
|
|
12617
|
-
return {
|
|
12618
|
-
...resp.data,
|
|
12619
|
-
token
|
|
12620
|
-
};
|
|
12621
|
-
}
|
|
12622
|
-
async startCallbackServer() {
|
|
12623
|
-
let resolveToken;
|
|
12624
|
-
let rejectToken;
|
|
12625
|
-
const waitForToken = new Promise((resolve, reject) => {
|
|
12626
|
-
resolveToken = resolve;
|
|
12627
|
-
rejectToken = reject;
|
|
12628
|
-
});
|
|
12629
|
-
const server = (0, import_node_http.createServer)((request, response) => {
|
|
12630
|
-
this.handleCallbackRequest(request, response, resolveToken, rejectToken);
|
|
12631
|
-
});
|
|
12632
|
-
await new Promise((resolve, reject) => {
|
|
12633
|
-
server.once("error", reject);
|
|
12634
|
-
server.listen(0, "127.0.0.1", () => resolve());
|
|
12635
|
-
});
|
|
12636
|
-
const address = server.address();
|
|
12637
|
-
if (!address || typeof address === "string") {
|
|
12638
|
-
server.close();
|
|
12639
|
-
throw new Error("Failed to start login callback server.");
|
|
12640
|
-
}
|
|
12641
|
-
const redirectUrl = `http://127.0.0.1:${address.port}${CALLBACK_PATH}`;
|
|
12642
|
-
const timeout = setTimeout(() => {
|
|
12643
|
-
rejectToken(
|
|
12644
|
-
new Error(
|
|
12645
|
-
`Timed out waiting for browser login after ${LOGIN_TIMEOUT_MS / 1e3} seconds.`
|
|
12646
|
-
)
|
|
12647
|
-
);
|
|
12648
|
-
}, LOGIN_TIMEOUT_MS);
|
|
12649
|
-
const close = async () => {
|
|
12650
|
-
clearTimeout(timeout);
|
|
12651
|
-
await new Promise((resolve) => {
|
|
12652
|
-
server.close(() => resolve());
|
|
12653
|
-
});
|
|
12654
|
-
};
|
|
12655
|
-
return {
|
|
12656
|
-
redirectUrl,
|
|
12657
|
-
waitForToken,
|
|
12658
|
-
close
|
|
12659
|
-
};
|
|
12660
|
-
}
|
|
12661
|
-
handleCallbackRequest(request, response, resolveToken, rejectToken) {
|
|
12662
|
-
const url = new URL(request.url || "/", "http://127.0.0.1");
|
|
12663
|
-
if (url.pathname !== CALLBACK_PATH) {
|
|
12664
|
-
response.statusCode = 404;
|
|
12665
|
-
response.end("Not found");
|
|
12666
|
-
return;
|
|
12667
|
-
}
|
|
12668
|
-
const token = url.searchParams.get("sessionId")?.trim();
|
|
12669
|
-
if (!token) {
|
|
12670
|
-
response.statusCode = 400;
|
|
12671
|
-
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
12672
|
-
response.end(this.renderHtml("Login failed", "Missing sessionId in redirect URL."));
|
|
12673
|
-
rejectToken(new Error("Login callback did not include sessionId."));
|
|
12674
|
-
return;
|
|
12675
|
-
}
|
|
12676
|
-
response.statusCode = 200;
|
|
12677
|
-
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
12678
|
-
response.end(
|
|
12679
|
-
this.renderHtml(
|
|
12680
|
-
"Login complete",
|
|
12681
|
-
"You can close this tab and return to the terminal."
|
|
12682
|
-
)
|
|
12683
|
-
);
|
|
12684
|
-
resolveToken(token);
|
|
12685
|
-
}
|
|
12686
|
-
renderHtml(title, message) {
|
|
12687
|
-
return `<!doctype html>
|
|
12688
|
-
<html lang="en">
|
|
12689
|
-
<head>
|
|
12690
|
-
<meta charset="utf-8" />
|
|
12691
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12692
|
-
<title>${title}</title>
|
|
12693
|
-
<style>
|
|
12694
|
-
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; padding: 32px; color: #111; }
|
|
12695
|
-
main { max-width: 560px; margin: 10vh auto; }
|
|
12696
|
-
h1 { font-size: 28px; margin-bottom: 12px; }
|
|
12697
|
-
p { font-size: 16px; line-height: 1.5; }
|
|
12698
|
-
</style>
|
|
12699
|
-
</head>
|
|
12700
|
-
<body>
|
|
12701
|
-
<main>
|
|
12702
|
-
<h1>${title}</h1>
|
|
12703
|
-
<p>${message}</p>
|
|
12704
|
-
</main>
|
|
12705
|
-
</body>
|
|
12706
|
-
</html>`;
|
|
12707
|
-
}
|
|
12708
|
-
openBrowser(url) {
|
|
12709
|
-
const platform = process.platform;
|
|
12710
|
-
const command = platform === "darwin" ? { cmd: "open", args: [url] } : platform === "win32" ? { cmd: "cmd", args: ["/c", "start", "", url] } : { cmd: "xdg-open", args: [url] };
|
|
12711
|
-
try {
|
|
12712
|
-
const child = (0, import_node_child_process.spawn)(command.cmd, command.args, {
|
|
12713
|
-
detached: true,
|
|
12714
|
-
stdio: "ignore"
|
|
12715
|
-
});
|
|
12716
|
-
child.unref();
|
|
12717
|
-
return true;
|
|
12718
|
-
} catch {
|
|
12719
|
-
return false;
|
|
12720
|
-
}
|
|
12721
|
-
}
|
|
12722
|
-
writeSession(session) {
|
|
12723
|
-
const sessionDir = import_node_path2.default.join(import_node_os.default.homedir(), ".pmate");
|
|
12724
|
-
const sessionPath = import_node_path2.default.join(sessionDir, "session.json");
|
|
12725
|
-
(0, import_node_fs2.mkdirSync)(sessionDir, { recursive: true });
|
|
12726
|
-
(0, import_node_fs2.writeFileSync)(sessionPath, JSON.stringify(session, null, 2), {
|
|
12727
|
-
mode: 384
|
|
12728
|
-
});
|
|
12729
|
-
try {
|
|
12730
|
-
(0, import_node_fs2.chmodSync)(sessionPath, 384);
|
|
12731
|
-
} catch {
|
|
12732
|
-
}
|
|
12733
|
-
return sessionPath;
|
|
12734
|
-
}
|
|
12735
|
-
};
|
|
12736
|
-
|
|
12737
|
-
// src/services/AliyunService.ts
|
|
12738
|
-
var import_alidns20150109 = __toESM(require("@alicloud/alidns20150109"));
|
|
12739
|
-
var import_cdn20180510 = __toESM(require("@alicloud/cdn20180510"));
|
|
12740
|
-
var import_openapi_client = require("@alicloud/openapi-client");
|
|
12741
|
-
var import_ali_oss = __toESM(require("ali-oss"));
|
|
12742
|
-
var import_node_crypto = require("crypto");
|
|
12743
|
-
var import_node_fs4 = require("fs");
|
|
12744
|
-
var import_node_path4 = __toESM(require("path"));
|
|
12745
12527
|
|
|
12746
12528
|
// src/config.ts
|
|
12747
|
-
var
|
|
12748
|
-
var
|
|
12749
|
-
var
|
|
12529
|
+
var import_node_fs = require("fs");
|
|
12530
|
+
var import_node_os = __toESM(require("os"));
|
|
12531
|
+
var import_node_path = __toESM(require("path"));
|
|
12750
12532
|
var import_ajv = __toESM(require("ajv"));
|
|
12751
|
-
var
|
|
12533
|
+
var import_yaml = __toESM(require("yaml"));
|
|
12752
12534
|
var cachedConfig;
|
|
12753
12535
|
var CONFIG = new Proxy({}, {
|
|
12754
12536
|
get(_target, prop) {
|
|
@@ -12870,13 +12652,13 @@ function loadPmateConfig() {
|
|
|
12870
12652
|
if (cachedConfig !== void 0) {
|
|
12871
12653
|
return cachedConfig ?? {};
|
|
12872
12654
|
}
|
|
12873
|
-
const pmateDir =
|
|
12874
|
-
const yamlPath =
|
|
12655
|
+
const pmateDir = import_node_path.default.join(import_node_os.default.homedir(), ".pmate");
|
|
12656
|
+
const yamlPath = import_node_path.default.join(pmateDir, "config.yaml");
|
|
12875
12657
|
let yamlConfig = null;
|
|
12876
|
-
if ((0,
|
|
12877
|
-
const raw = (0,
|
|
12658
|
+
if ((0, import_node_fs.existsSync)(yamlPath)) {
|
|
12659
|
+
const raw = (0, import_node_fs.readFileSync)(yamlPath, "utf8");
|
|
12878
12660
|
try {
|
|
12879
|
-
const parsed =
|
|
12661
|
+
const parsed = import_yaml.default.parse(raw);
|
|
12880
12662
|
yamlConfig = validateParsedConfig(parsed, yamlPath);
|
|
12881
12663
|
} catch (error) {
|
|
12882
12664
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -12887,19 +12669,38 @@ function loadPmateConfig() {
|
|
|
12887
12669
|
return cachedConfig;
|
|
12888
12670
|
}
|
|
12889
12671
|
function loadRepoConfig(cwd) {
|
|
12890
|
-
const
|
|
12891
|
-
if (!
|
|
12672
|
+
const paths = findRepoConfigPaths(cwd, true);
|
|
12673
|
+
if (!paths) {
|
|
12892
12674
|
return null;
|
|
12893
12675
|
}
|
|
12894
|
-
const
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
12676
|
+
const parsed = loadMergedRepoYaml(paths);
|
|
12677
|
+
return normalizeRepoConfig(parsed, paths.configPath);
|
|
12678
|
+
}
|
|
12679
|
+
function loadAppConfig(cwd, options = {}) {
|
|
12680
|
+
const paths = findRepoConfigPaths(cwd, options.searchParents ?? false);
|
|
12681
|
+
if (!paths) {
|
|
12682
|
+
const suffix = options.searchParents ? " or parent directories" : "";
|
|
12683
|
+
throw new Error(`No .pmate.yaml found in ${cwd}${suffix}`);
|
|
12684
|
+
}
|
|
12685
|
+
const parsed = loadMergedRepoYaml(paths);
|
|
12686
|
+
const appConfig = parsed;
|
|
12687
|
+
if (!appConfig || typeof appConfig !== "object" || !Array.isArray(appConfig.apps)) {
|
|
12688
|
+
throw new Error(
|
|
12689
|
+
`Invalid .pmate.yaml: missing apps array (${describeRepoConfigPaths(paths)})`
|
|
12690
|
+
);
|
|
12901
12691
|
}
|
|
12902
|
-
return
|
|
12692
|
+
return {
|
|
12693
|
+
config: appConfig,
|
|
12694
|
+
rootDir: paths.rootDir,
|
|
12695
|
+
configPath: paths.configPath,
|
|
12696
|
+
localConfigPath: paths.localConfigPath
|
|
12697
|
+
};
|
|
12698
|
+
}
|
|
12699
|
+
function describeLoadedAppConfig({
|
|
12700
|
+
configPath,
|
|
12701
|
+
localConfigPath
|
|
12702
|
+
}) {
|
|
12703
|
+
return localConfigPath ? `${configPath} + ${localConfigPath}` : configPath;
|
|
12903
12704
|
}
|
|
12904
12705
|
function validateParsedConfig(value, configPath) {
|
|
12905
12706
|
if (value === null || value === void 0) {
|
|
@@ -12915,20 +12716,93 @@ ${detail}`);
|
|
|
12915
12716
|
}
|
|
12916
12717
|
return value;
|
|
12917
12718
|
}
|
|
12918
|
-
function
|
|
12919
|
-
let current =
|
|
12719
|
+
function findRepoConfigPaths(cwd, searchParents) {
|
|
12720
|
+
let current = import_node_path.default.resolve(cwd);
|
|
12920
12721
|
while (true) {
|
|
12921
|
-
const candidate =
|
|
12922
|
-
if ((0,
|
|
12923
|
-
|
|
12722
|
+
const candidate = import_node_path.default.join(current, ".pmate.yaml");
|
|
12723
|
+
if ((0, import_node_fs.existsSync)(candidate)) {
|
|
12724
|
+
const localCandidate = import_node_path.default.join(current, ".pmate.local.yaml");
|
|
12725
|
+
return {
|
|
12726
|
+
rootDir: current,
|
|
12727
|
+
configPath: candidate,
|
|
12728
|
+
localConfigPath: (0, import_node_fs.existsSync)(localCandidate) ? localCandidate : void 0
|
|
12729
|
+
};
|
|
12730
|
+
}
|
|
12731
|
+
if (!searchParents) {
|
|
12732
|
+
return null;
|
|
12924
12733
|
}
|
|
12925
|
-
const parent =
|
|
12734
|
+
const parent = import_node_path.default.dirname(current);
|
|
12926
12735
|
if (parent === current) {
|
|
12927
12736
|
return null;
|
|
12928
12737
|
}
|
|
12929
12738
|
current = parent;
|
|
12930
12739
|
}
|
|
12931
12740
|
}
|
|
12741
|
+
function loadMergedRepoYaml(paths) {
|
|
12742
|
+
const base = parseYamlFile(paths.configPath);
|
|
12743
|
+
if (!paths.localConfigPath) {
|
|
12744
|
+
return base;
|
|
12745
|
+
}
|
|
12746
|
+
const local = parseYamlFile(paths.localConfigPath);
|
|
12747
|
+
return mergeRepoConfigValues(base, local);
|
|
12748
|
+
}
|
|
12749
|
+
function parseYamlFile(configPath) {
|
|
12750
|
+
const raw = (0, import_node_fs.readFileSync)(configPath, "utf8");
|
|
12751
|
+
try {
|
|
12752
|
+
return import_yaml.default.parse(raw);
|
|
12753
|
+
} catch (error) {
|
|
12754
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12755
|
+
throw new Error(`Invalid YAML in ${configPath}: ${message}`);
|
|
12756
|
+
}
|
|
12757
|
+
}
|
|
12758
|
+
function describeRepoConfigPaths(paths) {
|
|
12759
|
+
return paths.localConfigPath ? `${paths.configPath} + ${paths.localConfigPath}` : paths.configPath;
|
|
12760
|
+
}
|
|
12761
|
+
function mergeRepoConfigValues(base, local) {
|
|
12762
|
+
if (Array.isArray(base) && Array.isArray(local)) {
|
|
12763
|
+
return [...base, ...local];
|
|
12764
|
+
}
|
|
12765
|
+
if (isPlainObject(base) && isPlainObject(local)) {
|
|
12766
|
+
const merged = { ...base };
|
|
12767
|
+
for (const [key, localValue] of Object.entries(local)) {
|
|
12768
|
+
const baseValue = merged[key];
|
|
12769
|
+
if (key === "apps" && Array.isArray(baseValue) && Array.isArray(localValue)) {
|
|
12770
|
+
merged[key] = mergeApps(baseValue, localValue);
|
|
12771
|
+
continue;
|
|
12772
|
+
}
|
|
12773
|
+
merged[key] = mergeRepoConfigValues(baseValue, localValue);
|
|
12774
|
+
}
|
|
12775
|
+
return merged;
|
|
12776
|
+
}
|
|
12777
|
+
return local === void 0 ? base : local;
|
|
12778
|
+
}
|
|
12779
|
+
function mergeApps(baseApps, localApps) {
|
|
12780
|
+
const merged = [...baseApps];
|
|
12781
|
+
for (const localApp of localApps) {
|
|
12782
|
+
const localName = getAppName(localApp);
|
|
12783
|
+
if (!localName) {
|
|
12784
|
+
merged.push(localApp);
|
|
12785
|
+
continue;
|
|
12786
|
+
}
|
|
12787
|
+
const baseIndex = merged.findIndex((entry) => getAppName(entry) === localName);
|
|
12788
|
+
if (baseIndex === -1) {
|
|
12789
|
+
merged.push(localApp);
|
|
12790
|
+
continue;
|
|
12791
|
+
}
|
|
12792
|
+
merged[baseIndex] = mergeRepoConfigValues(merged[baseIndex], localApp);
|
|
12793
|
+
}
|
|
12794
|
+
return merged;
|
|
12795
|
+
}
|
|
12796
|
+
function getAppName(value) {
|
|
12797
|
+
if (!isPlainObject(value) || typeof value.app !== "string") {
|
|
12798
|
+
return void 0;
|
|
12799
|
+
}
|
|
12800
|
+
const app = value.app.trim();
|
|
12801
|
+
return app || void 0;
|
|
12802
|
+
}
|
|
12803
|
+
function isPlainObject(value) {
|
|
12804
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
12805
|
+
}
|
|
12932
12806
|
function normalizeRepoConfig(value, configPath) {
|
|
12933
12807
|
if (!value || typeof value !== "object") {
|
|
12934
12808
|
return null;
|
|
@@ -13009,7 +12883,217 @@ function getOptionalString(value) {
|
|
|
13009
12883
|
return trimmed ? trimmed : void 0;
|
|
13010
12884
|
}
|
|
13011
12885
|
|
|
12886
|
+
// src/commands/ListCommandHandler.ts
|
|
12887
|
+
var ListCommandHandler = class {
|
|
12888
|
+
handle(args) {
|
|
12889
|
+
const targetDir = this.resolveTargetDir(args.targetPath);
|
|
12890
|
+
const config = this.loadConfig(targetDir);
|
|
12891
|
+
if (config.apps.length === 0) {
|
|
12892
|
+
ui.warn("No apps defined.");
|
|
12893
|
+
return;
|
|
12894
|
+
}
|
|
12895
|
+
for (const app of config.apps) {
|
|
12896
|
+
if (app && typeof app.app === "string") {
|
|
12897
|
+
if (typeof app.dir !== "string" || !app.dir.trim()) {
|
|
12898
|
+
throw new Error(`Invalid .pmate.yaml: missing dir for app ${app.app}`);
|
|
12899
|
+
}
|
|
12900
|
+
ui.info(`${app.app} -> ${app.dir}`);
|
|
12901
|
+
}
|
|
12902
|
+
}
|
|
12903
|
+
}
|
|
12904
|
+
resolveTargetDir(targetPath) {
|
|
12905
|
+
return targetPath ? import_node_path2.default.resolve(process.cwd(), targetPath) : process.cwd();
|
|
12906
|
+
}
|
|
12907
|
+
loadConfig(targetDir) {
|
|
12908
|
+
return loadAppConfig(targetDir).config;
|
|
12909
|
+
}
|
|
12910
|
+
};
|
|
12911
|
+
|
|
12912
|
+
// src/commands/LoginCommandHandler.ts
|
|
12913
|
+
var import_node_fs2 = require("fs");
|
|
12914
|
+
var import_node_http = require("http");
|
|
12915
|
+
var import_node_os2 = __toESM(require("os"));
|
|
12916
|
+
var import_node_path3 = __toESM(require("path"));
|
|
12917
|
+
var import_node_child_process = require("child_process");
|
|
12918
|
+
var AUTH_UI_BASE_URL = "https://auth.pmate.chat";
|
|
12919
|
+
var AUTH_API_BASE_URL = "https://auth-api-v2.pmate.chat";
|
|
12920
|
+
var CALLBACK_PATH = "/pmate-login-callback";
|
|
12921
|
+
var DEFAULT_APP_ID = "@pmate/cli";
|
|
12922
|
+
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
12923
|
+
function buildHostedLoginUrl(redirectUrl, appId = DEFAULT_APP_ID) {
|
|
12924
|
+
const url = new URL(AUTH_UI_BASE_URL);
|
|
12925
|
+
url.searchParams.set("redirect", redirectUrl);
|
|
12926
|
+
url.searchParams.set("app", appId);
|
|
12927
|
+
return url.toString();
|
|
12928
|
+
}
|
|
12929
|
+
var LoginCommandHandler = class {
|
|
12930
|
+
async handle(args) {
|
|
12931
|
+
const callback = await this.startCallbackServer();
|
|
12932
|
+
const appId = args.app?.trim() || DEFAULT_APP_ID;
|
|
12933
|
+
const loginUrl = buildHostedLoginUrl(callback.redirectUrl, appId);
|
|
12934
|
+
ui.info("Opening browser for login.", {
|
|
12935
|
+
url: loginUrl,
|
|
12936
|
+
app: appId
|
|
12937
|
+
});
|
|
12938
|
+
if (!this.openBrowser(loginUrl)) {
|
|
12939
|
+
ui.warn("Unable to open the browser automatically.");
|
|
12940
|
+
ui.plain(loginUrl);
|
|
12941
|
+
}
|
|
12942
|
+
ui.info("Waiting for login redirect...", {
|
|
12943
|
+
callback: callback.redirectUrl,
|
|
12944
|
+
app: appId
|
|
12945
|
+
});
|
|
12946
|
+
try {
|
|
12947
|
+
const token = await callback.waitForToken;
|
|
12948
|
+
const loginResponse = await this.fetchSession(token);
|
|
12949
|
+
const sessionPath = this.writeSession(loginResponse);
|
|
12950
|
+
ui.success(`Logged in. Session saved to ${sessionPath}`);
|
|
12951
|
+
} finally {
|
|
12952
|
+
await callback.close();
|
|
12953
|
+
}
|
|
12954
|
+
}
|
|
12955
|
+
async fetchSession(token) {
|
|
12956
|
+
const response = await fetch(`${AUTH_API_BASE_URL}/session`, {
|
|
12957
|
+
method: "GET",
|
|
12958
|
+
headers: {
|
|
12959
|
+
Authorization: `Bearer ${token}`
|
|
12960
|
+
}
|
|
12961
|
+
});
|
|
12962
|
+
if (!response.ok) {
|
|
12963
|
+
const detail = await response.text();
|
|
12964
|
+
throw new Error(
|
|
12965
|
+
`Failed to validate session (${response.status}): ${detail || response.statusText}`
|
|
12966
|
+
);
|
|
12967
|
+
}
|
|
12968
|
+
const resp = await response.json();
|
|
12969
|
+
return {
|
|
12970
|
+
...resp.data,
|
|
12971
|
+
token
|
|
12972
|
+
};
|
|
12973
|
+
}
|
|
12974
|
+
async startCallbackServer() {
|
|
12975
|
+
let resolveToken;
|
|
12976
|
+
let rejectToken;
|
|
12977
|
+
const waitForToken = new Promise((resolve, reject) => {
|
|
12978
|
+
resolveToken = resolve;
|
|
12979
|
+
rejectToken = reject;
|
|
12980
|
+
});
|
|
12981
|
+
const server = (0, import_node_http.createServer)((request, response) => {
|
|
12982
|
+
this.handleCallbackRequest(request, response, resolveToken, rejectToken);
|
|
12983
|
+
});
|
|
12984
|
+
await new Promise((resolve, reject) => {
|
|
12985
|
+
server.once("error", reject);
|
|
12986
|
+
server.listen(0, "127.0.0.1", () => resolve());
|
|
12987
|
+
});
|
|
12988
|
+
const address = server.address();
|
|
12989
|
+
if (!address || typeof address === "string") {
|
|
12990
|
+
server.close();
|
|
12991
|
+
throw new Error("Failed to start login callback server.");
|
|
12992
|
+
}
|
|
12993
|
+
const redirectUrl = `http://127.0.0.1:${address.port}${CALLBACK_PATH}`;
|
|
12994
|
+
const timeout = setTimeout(() => {
|
|
12995
|
+
rejectToken(
|
|
12996
|
+
new Error(
|
|
12997
|
+
`Timed out waiting for browser login after ${LOGIN_TIMEOUT_MS / 1e3} seconds.`
|
|
12998
|
+
)
|
|
12999
|
+
);
|
|
13000
|
+
}, LOGIN_TIMEOUT_MS);
|
|
13001
|
+
const close = async () => {
|
|
13002
|
+
clearTimeout(timeout);
|
|
13003
|
+
await new Promise((resolve) => {
|
|
13004
|
+
server.close(() => resolve());
|
|
13005
|
+
});
|
|
13006
|
+
};
|
|
13007
|
+
return {
|
|
13008
|
+
redirectUrl,
|
|
13009
|
+
waitForToken,
|
|
13010
|
+
close
|
|
13011
|
+
};
|
|
13012
|
+
}
|
|
13013
|
+
handleCallbackRequest(request, response, resolveToken, rejectToken) {
|
|
13014
|
+
const url = new URL(request.url || "/", "http://127.0.0.1");
|
|
13015
|
+
if (url.pathname !== CALLBACK_PATH) {
|
|
13016
|
+
response.statusCode = 404;
|
|
13017
|
+
response.end("Not found");
|
|
13018
|
+
return;
|
|
13019
|
+
}
|
|
13020
|
+
const token = url.searchParams.get("sessionId")?.trim();
|
|
13021
|
+
if (!token) {
|
|
13022
|
+
response.statusCode = 400;
|
|
13023
|
+
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
13024
|
+
response.end(this.renderHtml("Login failed", "Missing sessionId in redirect URL."));
|
|
13025
|
+
rejectToken(new Error("Login callback did not include sessionId."));
|
|
13026
|
+
return;
|
|
13027
|
+
}
|
|
13028
|
+
response.statusCode = 200;
|
|
13029
|
+
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
13030
|
+
response.end(
|
|
13031
|
+
this.renderHtml(
|
|
13032
|
+
"Login complete",
|
|
13033
|
+
"You can close this tab and return to the terminal."
|
|
13034
|
+
)
|
|
13035
|
+
);
|
|
13036
|
+
resolveToken(token);
|
|
13037
|
+
}
|
|
13038
|
+
renderHtml(title, message) {
|
|
13039
|
+
return `<!doctype html>
|
|
13040
|
+
<html lang="en">
|
|
13041
|
+
<head>
|
|
13042
|
+
<meta charset="utf-8" />
|
|
13043
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
13044
|
+
<title>${title}</title>
|
|
13045
|
+
<style>
|
|
13046
|
+
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; padding: 32px; color: #111; }
|
|
13047
|
+
main { max-width: 560px; margin: 10vh auto; }
|
|
13048
|
+
h1 { font-size: 28px; margin-bottom: 12px; }
|
|
13049
|
+
p { font-size: 16px; line-height: 1.5; }
|
|
13050
|
+
</style>
|
|
13051
|
+
</head>
|
|
13052
|
+
<body>
|
|
13053
|
+
<main>
|
|
13054
|
+
<h1>${title}</h1>
|
|
13055
|
+
<p>${message}</p>
|
|
13056
|
+
</main>
|
|
13057
|
+
</body>
|
|
13058
|
+
</html>`;
|
|
13059
|
+
}
|
|
13060
|
+
openBrowser(url) {
|
|
13061
|
+
const platform = process.platform;
|
|
13062
|
+
const command = platform === "darwin" ? { cmd: "open", args: [url] } : platform === "win32" ? { cmd: "cmd", args: ["/c", "start", "", url] } : { cmd: "xdg-open", args: [url] };
|
|
13063
|
+
try {
|
|
13064
|
+
const child = (0, import_node_child_process.spawn)(command.cmd, command.args, {
|
|
13065
|
+
detached: true,
|
|
13066
|
+
stdio: "ignore"
|
|
13067
|
+
});
|
|
13068
|
+
child.unref();
|
|
13069
|
+
return true;
|
|
13070
|
+
} catch {
|
|
13071
|
+
return false;
|
|
13072
|
+
}
|
|
13073
|
+
}
|
|
13074
|
+
writeSession(session) {
|
|
13075
|
+
const sessionDir = import_node_path3.default.join(import_node_os2.default.homedir(), ".pmate");
|
|
13076
|
+
const sessionPath = import_node_path3.default.join(sessionDir, "session.json");
|
|
13077
|
+
(0, import_node_fs2.mkdirSync)(sessionDir, { recursive: true });
|
|
13078
|
+
(0, import_node_fs2.writeFileSync)(sessionPath, JSON.stringify(session, null, 2), {
|
|
13079
|
+
mode: 384
|
|
13080
|
+
});
|
|
13081
|
+
try {
|
|
13082
|
+
(0, import_node_fs2.chmodSync)(sessionPath, 384);
|
|
13083
|
+
} catch {
|
|
13084
|
+
}
|
|
13085
|
+
return sessionPath;
|
|
13086
|
+
}
|
|
13087
|
+
};
|
|
13088
|
+
|
|
13012
13089
|
// src/services/AliyunService.ts
|
|
13090
|
+
var import_alidns20150109 = __toESM(require("@alicloud/alidns20150109"));
|
|
13091
|
+
var import_cdn20180510 = __toESM(require("@alicloud/cdn20180510"));
|
|
13092
|
+
var import_openapi_client = require("@alicloud/openapi-client");
|
|
13093
|
+
var import_ali_oss = __toESM(require("ali-oss"));
|
|
13094
|
+
var import_node_crypto = require("crypto");
|
|
13095
|
+
var import_node_fs3 = require("fs");
|
|
13096
|
+
var import_node_path4 = __toESM(require("path"));
|
|
13013
13097
|
var AliyunService = class {
|
|
13014
13098
|
/** Add a DNS record via Aliyun DNS. */
|
|
13015
13099
|
static async addRecord(input) {
|
|
@@ -13152,7 +13236,7 @@ var AliyunService = class {
|
|
|
13152
13236
|
const options = contentType ? { headers: { "Content-Type": contentType } } : void 0;
|
|
13153
13237
|
const existing = existingMap.get(objectKey);
|
|
13154
13238
|
if (existing && typeof existing.size === "number") {
|
|
13155
|
-
const stat = await
|
|
13239
|
+
const stat = await import_node_fs3.promises.stat(filePath);
|
|
13156
13240
|
if (stat.size === existing.size) {
|
|
13157
13241
|
const etag = this.normalizeEtag(existing.etag);
|
|
13158
13242
|
if (etag && !etag.includes("-")) {
|
|
@@ -13177,7 +13261,7 @@ var AliyunService = class {
|
|
|
13177
13261
|
if (!region) throw new Error("Missing oss.public.region in ~/.pmate/config.yaml.");
|
|
13178
13262
|
if (!accessKeyId) throw new Error("Missing aliyun.ak in ~/.pmate/config.yaml.");
|
|
13179
13263
|
if (!accessKeySecret) throw new Error("Missing aliyun.sk in ~/.pmate/config.yaml.");
|
|
13180
|
-
if (!(0,
|
|
13264
|
+
if (!(0, import_node_fs3.existsSync)(localFile)) {
|
|
13181
13265
|
throw new Error(`File not found: ${localFile}`);
|
|
13182
13266
|
}
|
|
13183
13267
|
const client = new import_ali_oss.default({ region, accessKeyId, accessKeySecret, bucket });
|
|
@@ -13452,7 +13536,7 @@ var AliyunService = class {
|
|
|
13452
13536
|
}
|
|
13453
13537
|
/** Recursively collect file paths under a directory. */
|
|
13454
13538
|
static async collectFiles(dir) {
|
|
13455
|
-
const entries = await
|
|
13539
|
+
const entries = await import_node_fs3.promises.readdir(dir, { withFileTypes: true });
|
|
13456
13540
|
const files = [];
|
|
13457
13541
|
for (const entry of entries) {
|
|
13458
13542
|
const fullPath = import_node_path4.default.join(dir, entry.name);
|
|
@@ -13504,7 +13588,7 @@ var AliyunService = class {
|
|
|
13504
13588
|
static getFileMd5(filePath) {
|
|
13505
13589
|
return new Promise((resolve, reject) => {
|
|
13506
13590
|
const hash = (0, import_node_crypto.createHash)("md5");
|
|
13507
|
-
const stream = (0,
|
|
13591
|
+
const stream = (0, import_node_fs3.createReadStream)(filePath);
|
|
13508
13592
|
stream.on("data", (chunk) => {
|
|
13509
13593
|
hash.update(chunk);
|
|
13510
13594
|
});
|
|
@@ -13589,7 +13673,7 @@ var AddDnsCommandHandler = class {
|
|
|
13589
13673
|
};
|
|
13590
13674
|
|
|
13591
13675
|
// src/commands/StsCommandHandler.ts
|
|
13592
|
-
var
|
|
13676
|
+
var import_node_fs4 = require("fs");
|
|
13593
13677
|
var import_node_os3 = __toESM(require("os"));
|
|
13594
13678
|
var import_node_path5 = __toESM(require("path"));
|
|
13595
13679
|
var import_chalk2 = __toESM(require("chalk"));
|
|
@@ -13621,10 +13705,10 @@ var StsCommandHandler = class {
|
|
|
13621
13705
|
}
|
|
13622
13706
|
readSession() {
|
|
13623
13707
|
const sessionPath = import_node_path5.default.join(import_node_os3.default.homedir(), ".pmate", "session.json");
|
|
13624
|
-
if (!(0,
|
|
13708
|
+
if (!(0, import_node_fs4.existsSync)(sessionPath)) {
|
|
13625
13709
|
throw new Error("Missing session. Run `pmate login` first.");
|
|
13626
13710
|
}
|
|
13627
|
-
const raw = (0,
|
|
13711
|
+
const raw = (0, import_node_fs4.readFileSync)(sessionPath, "utf8");
|
|
13628
13712
|
return JSON.parse(raw);
|
|
13629
13713
|
}
|
|
13630
13714
|
};
|
|
@@ -13639,10 +13723,9 @@ var BucketCommandHandler = class {
|
|
|
13639
13723
|
};
|
|
13640
13724
|
|
|
13641
13725
|
// src/commands/DeployCommandHandler.ts
|
|
13642
|
-
var
|
|
13726
|
+
var import_node_fs5 = require("fs");
|
|
13643
13727
|
var import_node_path7 = __toESM(require("path"));
|
|
13644
13728
|
var import_node_child_process2 = require("child_process");
|
|
13645
|
-
var import_yaml3 = __toESM(require("yaml"));
|
|
13646
13729
|
|
|
13647
13730
|
// src/appDir.ts
|
|
13648
13731
|
var import_node_path6 = __toESM(require("path"));
|
|
@@ -13692,11 +13775,12 @@ var DeployCommandHandler = class {
|
|
|
13692
13775
|
);
|
|
13693
13776
|
}
|
|
13694
13777
|
const cwd = this.resolveCwd(args.deployCwd);
|
|
13695
|
-
const
|
|
13778
|
+
const loadedConfig = this.loadConfig(cwd);
|
|
13779
|
+
const config = loadedConfig.config;
|
|
13696
13780
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
13697
13781
|
if (!appConfig) {
|
|
13698
13782
|
throw new Error(
|
|
13699
|
-
`No app named ${appName} found in ${
|
|
13783
|
+
`No app named ${appName} found in ${describeLoadedAppConfig(loadedConfig)}`
|
|
13700
13784
|
);
|
|
13701
13785
|
}
|
|
13702
13786
|
if (args.deployAction === "logs") {
|
|
@@ -13740,7 +13824,7 @@ var DeployCommandHandler = class {
|
|
|
13740
13824
|
async deployVite(appName, cwd, appConfig) {
|
|
13741
13825
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
13742
13826
|
const packageJsonPath = import_node_path7.default.join(appDir, "package.json");
|
|
13743
|
-
if (!(0,
|
|
13827
|
+
if (!(0, import_node_fs5.existsSync)(packageJsonPath)) {
|
|
13744
13828
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
13745
13829
|
}
|
|
13746
13830
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -13750,7 +13834,7 @@ var DeployCommandHandler = class {
|
|
|
13750
13834
|
}
|
|
13751
13835
|
await this.runCommand("pnpm", ["--filter", pkgName, "build"], cwd);
|
|
13752
13836
|
const distDir = import_node_path7.default.join(appDir, "dist");
|
|
13753
|
-
if (!(0,
|
|
13837
|
+
if (!(0, import_node_fs5.existsSync)(distDir)) {
|
|
13754
13838
|
throw new Error(`No dist directory found at ${distDir}`);
|
|
13755
13839
|
}
|
|
13756
13840
|
const bucketName = appConfig.bucket?.trim();
|
|
@@ -13764,7 +13848,7 @@ var DeployCommandHandler = class {
|
|
|
13764
13848
|
async deployStatic(appName, cwd, appConfig) {
|
|
13765
13849
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
13766
13850
|
const srcDir = import_node_path7.default.join(appDir, "src");
|
|
13767
|
-
if (!(0,
|
|
13851
|
+
if (!(0, import_node_fs5.existsSync)(srcDir)) {
|
|
13768
13852
|
throw new Error(`No src directory found at ${srcDir}`);
|
|
13769
13853
|
}
|
|
13770
13854
|
const bucketName = appConfig.bucket?.trim();
|
|
@@ -13879,7 +13963,7 @@ var DeployCommandHandler = class {
|
|
|
13879
13963
|
return target ? import_node_path7.default.resolve(process.cwd(), target) : process.cwd();
|
|
13880
13964
|
}
|
|
13881
13965
|
loadPackageJson(packageJsonPath) {
|
|
13882
|
-
const raw = (0,
|
|
13966
|
+
const raw = (0, import_node_fs5.readFileSync)(packageJsonPath, "utf8");
|
|
13883
13967
|
const parsed = JSON.parse(raw);
|
|
13884
13968
|
if (!parsed || typeof parsed !== "object") {
|
|
13885
13969
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -13887,16 +13971,7 @@ var DeployCommandHandler = class {
|
|
|
13887
13971
|
return parsed;
|
|
13888
13972
|
}
|
|
13889
13973
|
loadConfig(cwd) {
|
|
13890
|
-
|
|
13891
|
-
if (!(0, import_node_fs6.existsSync)(configPath)) {
|
|
13892
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
13893
|
-
}
|
|
13894
|
-
const raw = (0, import_node_fs6.readFileSync)(configPath, "utf8");
|
|
13895
|
-
const parsed = import_yaml3.default.parse(raw);
|
|
13896
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
13897
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
13898
|
-
}
|
|
13899
|
-
return parsed;
|
|
13974
|
+
return loadAppConfig(cwd);
|
|
13900
13975
|
}
|
|
13901
13976
|
runCommand(command, args, cwd) {
|
|
13902
13977
|
return new Promise((resolve, reject) => {
|
|
@@ -13966,11 +14041,10 @@ var DeployCommandHandler = class {
|
|
|
13966
14041
|
};
|
|
13967
14042
|
|
|
13968
14043
|
// src/commands/LogCommandHandler.ts
|
|
13969
|
-
var
|
|
14044
|
+
var import_node_fs6 = require("fs");
|
|
13970
14045
|
var import_node_child_process3 = require("child_process");
|
|
13971
14046
|
var import_node_path8 = __toESM(require("path"));
|
|
13972
14047
|
var import_node_module = require("module");
|
|
13973
|
-
var import_yaml4 = __toESM(require("yaml"));
|
|
13974
14048
|
var LogCommandHandler = class {
|
|
13975
14049
|
async handle(args) {
|
|
13976
14050
|
const appName = args.logApp.trim();
|
|
@@ -13978,14 +14052,13 @@ var LogCommandHandler = class {
|
|
|
13978
14052
|
throw new Error("Missing app name. Usage: log <app-name> [--cwd <dir>].");
|
|
13979
14053
|
}
|
|
13980
14054
|
const cwd = this.resolveCwd(args.logCwd);
|
|
13981
|
-
const { config, configPath } = this.loadClosestConfig(cwd);
|
|
14055
|
+
const { config, configPath, repoRoot } = this.loadClosestConfig(cwd);
|
|
13982
14056
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
13983
14057
|
if (!appConfig) {
|
|
13984
14058
|
throw new Error(`No app named ${appName} found in ${configPath}`);
|
|
13985
14059
|
}
|
|
13986
14060
|
if (appConfig.type === "node") {
|
|
13987
14061
|
const server = this.resolveNodeServer(appName, appConfig);
|
|
13988
|
-
const repoRoot = import_node_path8.default.dirname(configPath);
|
|
13989
14062
|
const pm2Name = this.resolvePm2AppName(repoRoot, appName, appConfig);
|
|
13990
14063
|
await this.runRemotePm2Logs(server, pm2Name);
|
|
13991
14064
|
return;
|
|
@@ -14002,30 +14075,12 @@ var LogCommandHandler = class {
|
|
|
14002
14075
|
return target ? import_node_path8.default.resolve(process.cwd(), target) : process.cwd();
|
|
14003
14076
|
}
|
|
14004
14077
|
loadClosestConfig(cwd) {
|
|
14005
|
-
const
|
|
14006
|
-
|
|
14007
|
-
|
|
14008
|
-
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
14012
|
-
throw new Error(`Invalid .pmate.yaml: missing apps array (${configPath})`);
|
|
14013
|
-
}
|
|
14014
|
-
return { config: parsed, configPath };
|
|
14015
|
-
}
|
|
14016
|
-
findRepoConfigPath(cwd) {
|
|
14017
|
-
let current = import_node_path8.default.resolve(cwd);
|
|
14018
|
-
while (true) {
|
|
14019
|
-
const candidate = import_node_path8.default.join(current, ".pmate.yaml");
|
|
14020
|
-
if ((0, import_node_fs7.existsSync)(candidate)) {
|
|
14021
|
-
return candidate;
|
|
14022
|
-
}
|
|
14023
|
-
const parent = import_node_path8.default.dirname(current);
|
|
14024
|
-
if (parent === current) {
|
|
14025
|
-
return null;
|
|
14026
|
-
}
|
|
14027
|
-
current = parent;
|
|
14028
|
-
}
|
|
14078
|
+
const loaded = loadAppConfig(cwd, { searchParents: true });
|
|
14079
|
+
return {
|
|
14080
|
+
config: loaded.config,
|
|
14081
|
+
configPath: describeLoadedAppConfig(loaded),
|
|
14082
|
+
repoRoot: loaded.rootDir
|
|
14083
|
+
};
|
|
14029
14084
|
}
|
|
14030
14085
|
resolveNodeServer(appName, appConfig) {
|
|
14031
14086
|
const server = appConfig.server?.trim();
|
|
@@ -14049,11 +14104,11 @@ var LogCommandHandler = class {
|
|
|
14049
14104
|
}
|
|
14050
14105
|
findEcosystemPath(appDir) {
|
|
14051
14106
|
const cjs = import_node_path8.default.join(appDir, "ecosystem.config.cjs");
|
|
14052
|
-
if ((0,
|
|
14107
|
+
if ((0, import_node_fs6.existsSync)(cjs)) {
|
|
14053
14108
|
return cjs;
|
|
14054
14109
|
}
|
|
14055
14110
|
const js = import_node_path8.default.join(appDir, "ecosystem.config.js");
|
|
14056
|
-
if ((0,
|
|
14111
|
+
if ((0, import_node_fs6.existsSync)(js)) {
|
|
14057
14112
|
return js;
|
|
14058
14113
|
}
|
|
14059
14114
|
return null;
|
|
@@ -14154,11 +14209,11 @@ var LogCommandHandler = class {
|
|
|
14154
14209
|
};
|
|
14155
14210
|
|
|
14156
14211
|
// src/commands/InitCommandHandler.ts
|
|
14157
|
-
var
|
|
14212
|
+
var import_node_fs7 = require("fs");
|
|
14158
14213
|
var import_node_path9 = __toESM(require("path"));
|
|
14159
14214
|
var import_node_child_process4 = require("child_process");
|
|
14160
14215
|
var import_promises2 = require("readline/promises");
|
|
14161
|
-
var
|
|
14216
|
+
var import_yaml2 = __toESM(require("yaml"));
|
|
14162
14217
|
|
|
14163
14218
|
// src/serverAddress.ts
|
|
14164
14219
|
var import_promises = require("dns/promises");
|
|
@@ -14186,14 +14241,14 @@ var InitCommandHandler = class {
|
|
|
14186
14241
|
throw new Error("Missing app name. Usage: init <app-name> [--cwd <dir>].");
|
|
14187
14242
|
}
|
|
14188
14243
|
const cwd = this.resolveCwd(args.initCwd);
|
|
14189
|
-
const config = this.loadConfig(cwd);
|
|
14244
|
+
const { config } = this.loadConfig(cwd);
|
|
14190
14245
|
let appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
14191
14246
|
if (!appConfig) {
|
|
14192
14247
|
appConfig = await this.addAppConfig(config, appName, cwd);
|
|
14193
14248
|
}
|
|
14194
14249
|
if (appConfig.type !== "rust") {
|
|
14195
14250
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
14196
|
-
if (!(0,
|
|
14251
|
+
if (!(0, import_node_fs7.existsSync)(appDir)) {
|
|
14197
14252
|
throw new Error(`No app folder found at ${appDir}`);
|
|
14198
14253
|
}
|
|
14199
14254
|
}
|
|
@@ -14361,10 +14416,10 @@ var InitCommandHandler = class {
|
|
|
14361
14416
|
const serverAddress = await resolveServerAddress(server);
|
|
14362
14417
|
const templateName = serviceType === "ws" ? "nginx.ws.template" : "nginx.rest.template";
|
|
14363
14418
|
const templatePath = import_node_path9.default.join(__dirname, "..", "templates", templateName);
|
|
14364
|
-
if (!(0,
|
|
14419
|
+
if (!(0, import_node_fs7.existsSync)(templatePath)) {
|
|
14365
14420
|
throw new Error(`Missing nginx template at ${templatePath}`);
|
|
14366
14421
|
}
|
|
14367
|
-
const template = (0,
|
|
14422
|
+
const template = (0, import_node_fs7.readFileSync)(templatePath, "utf8");
|
|
14368
14423
|
const host = `${subdomain}.pmate.chat`;
|
|
14369
14424
|
const rendered = template.replace(/\$\{\{PORT\}\}/g, String(port)).replace(/\$\{\{HOSTS\}\}/g, host).replace(/\$\{\{HOST\}\}/g, host);
|
|
14370
14425
|
const remotePath = `/etc/nginx/sites-enabled/${subdomain}.conf`;
|
|
@@ -14397,15 +14452,15 @@ var InitCommandHandler = class {
|
|
|
14397
14452
|
if (options.ensurePackageJson) {
|
|
14398
14453
|
const appDir = resolveLocalAppDir(cwd, appConfig.app, appConfig.dir);
|
|
14399
14454
|
ui.info(`Resolved appDir: ${appDir}`);
|
|
14400
|
-
if (!(0,
|
|
14455
|
+
if (!(0, import_node_fs7.existsSync)(appDir)) {
|
|
14401
14456
|
throw new Error(`Missing app folder at ${appDir}`);
|
|
14402
14457
|
}
|
|
14403
14458
|
const packageJsonPath = import_node_path9.default.join(appDir, "package.json");
|
|
14404
14459
|
ui.info(`Resolved package.json: ${packageJsonPath}`);
|
|
14405
|
-
if (!(0,
|
|
14460
|
+
if (!(0, import_node_fs7.existsSync)(packageJsonPath)) {
|
|
14406
14461
|
throw new Error(`Missing package.json at ${packageJsonPath}`);
|
|
14407
14462
|
}
|
|
14408
|
-
const pkgStat = (0,
|
|
14463
|
+
const pkgStat = (0, import_node_fs7.statSync)(packageJsonPath);
|
|
14409
14464
|
ui.info(
|
|
14410
14465
|
`package.json stat: isFile=${pkgStat.isFile()} isDirectory=${pkgStat.isDirectory()}`
|
|
14411
14466
|
);
|
|
@@ -14471,16 +14526,7 @@ var InitCommandHandler = class {
|
|
|
14471
14526
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
14472
14527
|
}
|
|
14473
14528
|
loadConfig(cwd) {
|
|
14474
|
-
|
|
14475
|
-
if (!(0, import_node_fs8.existsSync)(configPath)) {
|
|
14476
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
14477
|
-
}
|
|
14478
|
-
const raw = (0, import_node_fs8.readFileSync)(configPath, "utf8");
|
|
14479
|
-
const parsed = import_yaml5.default.parse(raw);
|
|
14480
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
14481
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
14482
|
-
}
|
|
14483
|
-
return parsed;
|
|
14529
|
+
return loadAppConfig(cwd);
|
|
14484
14530
|
}
|
|
14485
14531
|
async addAppConfig(config, appName, cwd) {
|
|
14486
14532
|
ui.title(`App ${appName} not found in .pmate.yaml.`);
|
|
@@ -14598,7 +14644,7 @@ var InitCommandHandler = class {
|
|
|
14598
14644
|
}
|
|
14599
14645
|
}
|
|
14600
14646
|
loadPackageJson(packageJsonPath) {
|
|
14601
|
-
const raw = (0,
|
|
14647
|
+
const raw = (0, import_node_fs7.readFileSync)(packageJsonPath, "utf8");
|
|
14602
14648
|
const parsed = JSON.parse(raw);
|
|
14603
14649
|
if (!parsed || typeof parsed !== "object") {
|
|
14604
14650
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -14607,13 +14653,13 @@ var InitCommandHandler = class {
|
|
|
14607
14653
|
}
|
|
14608
14654
|
writePackageJson(packageJsonPath, data) {
|
|
14609
14655
|
const serialized = JSON.stringify(data, null, 2);
|
|
14610
|
-
(0,
|
|
14656
|
+
(0, import_node_fs7.writeFileSync)(packageJsonPath, `${serialized}
|
|
14611
14657
|
`, "utf8");
|
|
14612
14658
|
}
|
|
14613
14659
|
writeConfig(cwd, config) {
|
|
14614
14660
|
const configPath = import_node_path9.default.join(cwd, ".pmate.yaml");
|
|
14615
|
-
const serialized =
|
|
14616
|
-
(0,
|
|
14661
|
+
const serialized = import_yaml2.default.stringify(config).trimEnd();
|
|
14662
|
+
(0, import_node_fs7.writeFileSync)(configPath, `${serialized}
|
|
14617
14663
|
`, "utf8");
|
|
14618
14664
|
}
|
|
14619
14665
|
async promptRequired(rl, question) {
|
|
@@ -14649,10 +14695,9 @@ var InitCommandHandler = class {
|
|
|
14649
14695
|
};
|
|
14650
14696
|
|
|
14651
14697
|
// src/commands/DevCommandHandler.ts
|
|
14652
|
-
var
|
|
14698
|
+
var import_node_fs8 = require("fs");
|
|
14653
14699
|
var import_node_path10 = __toESM(require("path"));
|
|
14654
14700
|
var import_node_child_process5 = require("child_process");
|
|
14655
|
-
var import_yaml6 = __toESM(require("yaml"));
|
|
14656
14701
|
var DevCommandHandler = class {
|
|
14657
14702
|
async handle(args) {
|
|
14658
14703
|
const appName = args.devApp.trim();
|
|
@@ -14660,16 +14705,17 @@ var DevCommandHandler = class {
|
|
|
14660
14705
|
throw new Error("Missing app name. Usage: dev <app-name> [--cwd <dir>].");
|
|
14661
14706
|
}
|
|
14662
14707
|
const cwd = this.resolveCwd(args.devCwd);
|
|
14663
|
-
const
|
|
14708
|
+
const loadedConfig = this.loadConfig(cwd);
|
|
14709
|
+
const config = loadedConfig.config;
|
|
14664
14710
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
14665
14711
|
if (!appConfig) {
|
|
14666
14712
|
throw new Error(
|
|
14667
|
-
`No app named ${appName} found in ${
|
|
14713
|
+
`No app named ${appName} found in ${describeLoadedAppConfig(loadedConfig)}`
|
|
14668
14714
|
);
|
|
14669
14715
|
}
|
|
14670
14716
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
14671
14717
|
const packageJsonPath = import_node_path10.default.join(appDir, "package.json");
|
|
14672
|
-
if (!(0,
|
|
14718
|
+
if (!(0, import_node_fs8.existsSync)(packageJsonPath)) {
|
|
14673
14719
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
14674
14720
|
}
|
|
14675
14721
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -14686,19 +14732,10 @@ var DevCommandHandler = class {
|
|
|
14686
14732
|
return target ? import_node_path10.default.resolve(process.cwd(), target) : process.cwd();
|
|
14687
14733
|
}
|
|
14688
14734
|
loadConfig(cwd) {
|
|
14689
|
-
|
|
14690
|
-
if (!(0, import_node_fs9.existsSync)(configPath)) {
|
|
14691
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
14692
|
-
}
|
|
14693
|
-
const raw = (0, import_node_fs9.readFileSync)(configPath, "utf8");
|
|
14694
|
-
const parsed = import_yaml6.default.parse(raw);
|
|
14695
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
14696
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
14697
|
-
}
|
|
14698
|
-
return parsed;
|
|
14735
|
+
return loadAppConfig(cwd);
|
|
14699
14736
|
}
|
|
14700
14737
|
loadPackageJson(packageJsonPath) {
|
|
14701
|
-
const raw = (0,
|
|
14738
|
+
const raw = (0, import_node_fs8.readFileSync)(packageJsonPath, "utf8");
|
|
14702
14739
|
const parsed = JSON.parse(raw);
|
|
14703
14740
|
if (!parsed || typeof parsed !== "object") {
|
|
14704
14741
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -14726,7 +14763,7 @@ var DevCommandHandler = class {
|
|
|
14726
14763
|
};
|
|
14727
14764
|
|
|
14728
14765
|
// src/commands/OssCommandHandler.ts
|
|
14729
|
-
var
|
|
14766
|
+
var import_node_fs9 = require("fs");
|
|
14730
14767
|
var import_node_path11 = __toESM(require("path"));
|
|
14731
14768
|
var import_promises3 = require("readline/promises");
|
|
14732
14769
|
var OssCommandHandler = class {
|
|
@@ -14762,10 +14799,10 @@ var OssCommandHandler = class {
|
|
|
14762
14799
|
}
|
|
14763
14800
|
}
|
|
14764
14801
|
assertFile(filePath) {
|
|
14765
|
-
if (!(0,
|
|
14802
|
+
if (!(0, import_node_fs9.existsSync)(filePath)) {
|
|
14766
14803
|
throw new Error(`File not found: ${filePath}`);
|
|
14767
14804
|
}
|
|
14768
|
-
const stat = (0,
|
|
14805
|
+
const stat = (0, import_node_fs9.statSync)(filePath);
|
|
14769
14806
|
if (!stat.isFile()) {
|
|
14770
14807
|
throw new Error(`Not a file: ${filePath}`);
|
|
14771
14808
|
}
|
|
@@ -14801,10 +14838,8 @@ var OssCommandHandler = class {
|
|
|
14801
14838
|
};
|
|
14802
14839
|
|
|
14803
14840
|
// src/commands/EnvCommandHandler.ts
|
|
14804
|
-
var import_node_fs11 = require("fs");
|
|
14805
14841
|
var import_node_path12 = __toESM(require("path"));
|
|
14806
14842
|
var import_node_child_process6 = require("child_process");
|
|
14807
|
-
var import_yaml7 = __toESM(require("yaml"));
|
|
14808
14843
|
var EnvCommandHandler = class {
|
|
14809
14844
|
async handle(args) {
|
|
14810
14845
|
const appName = args.envApp.trim();
|
|
@@ -14813,14 +14848,12 @@ var EnvCommandHandler = class {
|
|
|
14813
14848
|
"Missing app name. Usage: env <app-name> --list|--set KEY --value VALUE|--delete KEY [--cwd <dir>] [--verbose|-v]"
|
|
14814
14849
|
);
|
|
14815
14850
|
}
|
|
14816
|
-
const
|
|
14851
|
+
const loadedConfig = this.loadConfig(args.envCwd);
|
|
14852
|
+
const config = loadedConfig.config;
|
|
14817
14853
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
14818
14854
|
if (!appConfig) {
|
|
14819
14855
|
throw new Error(
|
|
14820
|
-
`No app named ${appName} found in ${
|
|
14821
|
-
process.cwd(),
|
|
14822
|
-
".pmate.yaml"
|
|
14823
|
-
)}`
|
|
14856
|
+
`No app named ${appName} found in ${describeLoadedAppConfig(loadedConfig)}`
|
|
14824
14857
|
);
|
|
14825
14858
|
}
|
|
14826
14859
|
if (appConfig.type !== "node") {
|
|
@@ -15088,16 +15121,7 @@ var EnvCommandHandler = class {
|
|
|
15088
15121
|
}
|
|
15089
15122
|
}
|
|
15090
15123
|
loadConfig(cwd) {
|
|
15091
|
-
|
|
15092
|
-
if (!(0, import_node_fs11.existsSync)(configPath)) {
|
|
15093
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
15094
|
-
}
|
|
15095
|
-
const raw = (0, import_node_fs11.readFileSync)(configPath, "utf8");
|
|
15096
|
-
const parsed = import_yaml7.default.parse(raw);
|
|
15097
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
15098
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
15099
|
-
}
|
|
15100
|
-
return parsed;
|
|
15124
|
+
return loadAppConfig(cwd);
|
|
15101
15125
|
}
|
|
15102
15126
|
runRemoteCommand(server, command) {
|
|
15103
15127
|
return new Promise((resolve, reject) => {
|
|
@@ -16000,7 +16024,7 @@ function truncate2(value, limit) {
|
|
|
16000
16024
|
|
|
16001
16025
|
// src/commands/LinearCommandHandler.ts
|
|
16002
16026
|
var import_node_child_process9 = require("child_process");
|
|
16003
|
-
var
|
|
16027
|
+
var import_node_fs11 = require("fs");
|
|
16004
16028
|
var import_node_os5 = __toESM(require("os"));
|
|
16005
16029
|
var import_node_path15 = __toESM(require("path"));
|
|
16006
16030
|
var import_promises4 = require("readline/promises");
|
|
@@ -16890,11 +16914,11 @@ var LinearCommandHandler = class {
|
|
|
16890
16914
|
}
|
|
16891
16915
|
readCachedLinearSelection(cwd) {
|
|
16892
16916
|
const selectionPath = this.getLinearSelectionPath();
|
|
16893
|
-
if (!(0,
|
|
16917
|
+
if (!(0, import_node_fs11.existsSync)(selectionPath)) {
|
|
16894
16918
|
return void 0;
|
|
16895
16919
|
}
|
|
16896
16920
|
try {
|
|
16897
|
-
const raw = (0,
|
|
16921
|
+
const raw = (0, import_node_fs11.readFileSync)(selectionPath, "utf8").trim();
|
|
16898
16922
|
if (!raw) return void 0;
|
|
16899
16923
|
const parsed = JSON.parse(raw);
|
|
16900
16924
|
const value = parsed[cwd];
|
|
@@ -16906,11 +16930,11 @@ var LinearCommandHandler = class {
|
|
|
16906
16930
|
writeCachedLinearSelection(cwd, title) {
|
|
16907
16931
|
const selectionPath = this.getLinearSelectionPath();
|
|
16908
16932
|
const dir = import_node_path15.default.dirname(selectionPath);
|
|
16909
|
-
(0,
|
|
16933
|
+
(0, import_node_fs11.mkdirSync)(dir, { recursive: true });
|
|
16910
16934
|
let data = {};
|
|
16911
|
-
if ((0,
|
|
16935
|
+
if ((0, import_node_fs11.existsSync)(selectionPath)) {
|
|
16912
16936
|
try {
|
|
16913
|
-
const raw = (0,
|
|
16937
|
+
const raw = (0, import_node_fs11.readFileSync)(selectionPath, "utf8").trim();
|
|
16914
16938
|
if (raw) {
|
|
16915
16939
|
data = JSON.parse(raw);
|
|
16916
16940
|
}
|
|
@@ -16919,7 +16943,7 @@ var LinearCommandHandler = class {
|
|
|
16919
16943
|
}
|
|
16920
16944
|
}
|
|
16921
16945
|
data[cwd] = title;
|
|
16922
|
-
(0,
|
|
16946
|
+
(0, import_node_fs11.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
|
|
16923
16947
|
`, "utf8");
|
|
16924
16948
|
}
|
|
16925
16949
|
async lookupIssue(client, issueRef) {
|
|
@@ -17096,14 +17120,14 @@ var LinearCommandHandler = class {
|
|
|
17096
17120
|
if (process.platform !== "darwin") {
|
|
17097
17121
|
throw new Error("Screenshot capture only supports macOS.");
|
|
17098
17122
|
}
|
|
17099
|
-
const dir = await
|
|
17123
|
+
const dir = await import_node_fs11.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-screenshot-"));
|
|
17100
17124
|
const filePath = import_node_path15.default.join(dir, `screenshot-${index}.png`);
|
|
17101
17125
|
try {
|
|
17102
17126
|
const code = await this.run("screencapture", ["-i", "-x", filePath], true);
|
|
17103
17127
|
if (code !== 0) {
|
|
17104
17128
|
throw new Error("Screenshot capture canceled or failed.");
|
|
17105
17129
|
}
|
|
17106
|
-
const buffer = await
|
|
17130
|
+
const buffer = await import_node_fs11.promises.readFile(filePath);
|
|
17107
17131
|
if (buffer.length === 0) {
|
|
17108
17132
|
throw new Error("Screenshot capture produced an empty file.");
|
|
17109
17133
|
}
|
|
@@ -17115,7 +17139,7 @@ var LinearCommandHandler = class {
|
|
|
17115
17139
|
return { buffer, mime, filename: `screenshot-${index}.${extension}` };
|
|
17116
17140
|
} finally {
|
|
17117
17141
|
try {
|
|
17118
|
-
await
|
|
17142
|
+
await import_node_fs11.promises.rm(dir, { recursive: true, force: true });
|
|
17119
17143
|
} catch {
|
|
17120
17144
|
}
|
|
17121
17145
|
}
|
|
@@ -17259,17 +17283,17 @@ var LinearCommandHandler = class {
|
|
|
17259
17283
|
return compact.length > limit ? `${compact.slice(0, limit)}...` : compact;
|
|
17260
17284
|
}
|
|
17261
17285
|
async convertToPng(buffer, ext) {
|
|
17262
|
-
const dir = await
|
|
17286
|
+
const dir = await import_node_fs11.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-"));
|
|
17263
17287
|
const inputPath = import_node_path15.default.join(dir, `clipboard.${ext}`);
|
|
17264
17288
|
const outputPath = import_node_path15.default.join(dir, "clipboard.png");
|
|
17265
17289
|
try {
|
|
17266
|
-
await
|
|
17290
|
+
await import_node_fs11.promises.writeFile(inputPath, buffer);
|
|
17267
17291
|
const stderr = await this.runCapture(
|
|
17268
17292
|
"sips",
|
|
17269
17293
|
["-s", "format", "png", inputPath, "--out", outputPath],
|
|
17270
17294
|
true
|
|
17271
17295
|
);
|
|
17272
|
-
const out = await
|
|
17296
|
+
const out = await import_node_fs11.promises.readFile(outputPath);
|
|
17273
17297
|
if (this.detectImageMime(out) !== "image/png") {
|
|
17274
17298
|
throw new Error(
|
|
17275
17299
|
stderr?.trim() ? `Failed to convert clipboard ${ext} to PNG: ${stderr.trim()}` : `Failed to convert clipboard ${ext} to PNG.`
|
|
@@ -17278,7 +17302,7 @@ var LinearCommandHandler = class {
|
|
|
17278
17302
|
return out;
|
|
17279
17303
|
} finally {
|
|
17280
17304
|
try {
|
|
17281
|
-
await
|
|
17305
|
+
await import_node_fs11.promises.rm(dir, { recursive: true, force: true });
|
|
17282
17306
|
} catch {
|
|
17283
17307
|
}
|
|
17284
17308
|
}
|
|
@@ -17624,7 +17648,7 @@ function sleep(ms) {
|
|
|
17624
17648
|
}
|
|
17625
17649
|
|
|
17626
17650
|
// src/commands/NotionCommandHandler.ts
|
|
17627
|
-
var
|
|
17651
|
+
var import_node_fs12 = require("fs");
|
|
17628
17652
|
var import_node_path16 = __toESM(require("path"));
|
|
17629
17653
|
|
|
17630
17654
|
// src/services/NotionService.ts
|
|
@@ -17965,13 +17989,13 @@ var NotionCommandHandler = class {
|
|
|
17965
17989
|
return "";
|
|
17966
17990
|
}
|
|
17967
17991
|
const resolved = import_node_path16.default.resolve(process.cwd(), args.filePath);
|
|
17968
|
-
return (0,
|
|
17992
|
+
return (0, import_node_fs12.readFileSync)(resolved, "utf8");
|
|
17969
17993
|
}
|
|
17970
17994
|
};
|
|
17971
17995
|
|
|
17972
17996
|
// src/commands/QrcodeCommandHandler.ts
|
|
17973
17997
|
var import_node_child_process10 = require("child_process");
|
|
17974
|
-
var
|
|
17998
|
+
var import_node_fs13 = require("fs");
|
|
17975
17999
|
var import_node_os6 = __toESM(require("os"));
|
|
17976
18000
|
var import_node_path17 = __toESM(require("path"));
|
|
17977
18001
|
var import_promises5 = require("readline/promises");
|
|
@@ -17999,7 +18023,7 @@ var QrcodeCommandHandler = class {
|
|
|
17999
18023
|
ui.success("QR code value:", value);
|
|
18000
18024
|
} finally {
|
|
18001
18025
|
try {
|
|
18002
|
-
await
|
|
18026
|
+
await import_node_fs13.promises.rm(dir, { recursive: true, force: true });
|
|
18003
18027
|
} catch {
|
|
18004
18028
|
}
|
|
18005
18029
|
}
|
|
@@ -18015,13 +18039,13 @@ var QrcodeCommandHandler = class {
|
|
|
18015
18039
|
} finally {
|
|
18016
18040
|
rl.close();
|
|
18017
18041
|
}
|
|
18018
|
-
const dir = await
|
|
18042
|
+
const dir = await import_node_fs13.promises.mkdtemp(import_node_path17.default.join(import_node_os6.default.tmpdir(), "pmate-qrcode-"));
|
|
18019
18043
|
const filePath = import_node_path17.default.join(dir, "qrcode.png");
|
|
18020
18044
|
const code = await this.run("screencapture", ["-i", "-x", filePath], true);
|
|
18021
18045
|
if (code !== 0) {
|
|
18022
18046
|
throw new Error("Screenshot capture canceled or failed.");
|
|
18023
18047
|
}
|
|
18024
|
-
const buffer = await
|
|
18048
|
+
const buffer = await import_node_fs13.promises.readFile(filePath);
|
|
18025
18049
|
if (buffer.length === 0) {
|
|
18026
18050
|
throw new Error("Screenshot capture produced an empty file.");
|
|
18027
18051
|
}
|
|
@@ -18037,7 +18061,7 @@ var QrcodeCommandHandler = class {
|
|
|
18037
18061
|
async decodeQr(filePath) {
|
|
18038
18062
|
let buffer;
|
|
18039
18063
|
try {
|
|
18040
|
-
buffer = await
|
|
18064
|
+
buffer = await import_node_fs13.promises.readFile(filePath);
|
|
18041
18065
|
} catch {
|
|
18042
18066
|
return null;
|
|
18043
18067
|
}
|
|
@@ -18297,7 +18321,7 @@ function clampNumber(value, min, max, fallback) {
|
|
|
18297
18321
|
// src/commands/CollectCommandHandler.ts
|
|
18298
18322
|
var import_playwright = require("playwright");
|
|
18299
18323
|
var import_node_crypto3 = require("crypto");
|
|
18300
|
-
var
|
|
18324
|
+
var import_node_fs14 = require("fs");
|
|
18301
18325
|
var import_node_os7 = __toESM(require("os"));
|
|
18302
18326
|
var import_node_path18 = __toESM(require("path"));
|
|
18303
18327
|
var CollectCommandHandler = class {
|
|
@@ -18674,11 +18698,11 @@ async function toDisplayableImagePath(src) {
|
|
|
18674
18698
|
return src;
|
|
18675
18699
|
}
|
|
18676
18700
|
try {
|
|
18677
|
-
const stat = await
|
|
18701
|
+
const stat = await import_node_fs14.promises.stat(src);
|
|
18678
18702
|
if (!stat.isFile()) {
|
|
18679
18703
|
return src;
|
|
18680
18704
|
}
|
|
18681
|
-
const fh = await
|
|
18705
|
+
const fh = await import_node_fs14.promises.open(src, "r");
|
|
18682
18706
|
try {
|
|
18683
18707
|
const buf = Buffer.alloc(32);
|
|
18684
18708
|
const { bytesRead } = await fh.read(buf, 0, 32, 0);
|
|
@@ -18693,11 +18717,11 @@ async function toDisplayableImagePath(src) {
|
|
|
18693
18717
|
"messages",
|
|
18694
18718
|
"images"
|
|
18695
18719
|
);
|
|
18696
|
-
await
|
|
18720
|
+
await import_node_fs14.promises.mkdir(cacheDir, { recursive: true });
|
|
18697
18721
|
const base = (0, import_node_crypto3.createHash)("sha1").update(src).digest("hex");
|
|
18698
18722
|
const displayPath = import_node_path18.default.join(cacheDir, `${base}.${guessedExt}`);
|
|
18699
|
-
await
|
|
18700
|
-
await
|
|
18723
|
+
await import_node_fs14.promises.rm(displayPath, { force: true }).catch(() => void 0);
|
|
18724
|
+
await import_node_fs14.promises.copyFile(src, displayPath);
|
|
18701
18725
|
return displayPath;
|
|
18702
18726
|
} finally {
|
|
18703
18727
|
await fh.close();
|
|
@@ -18753,7 +18777,7 @@ function parseMessageText(raw) {
|
|
|
18753
18777
|
}
|
|
18754
18778
|
|
|
18755
18779
|
// src/commands/AgentCommandHandler.ts
|
|
18756
|
-
var
|
|
18780
|
+
var import_node_fs15 = require("fs");
|
|
18757
18781
|
var import_node_os8 = __toESM(require("os"));
|
|
18758
18782
|
var import_node_path19 = __toESM(require("path"));
|
|
18759
18783
|
var AgentCommandHandler = class {
|
|
@@ -18838,10 +18862,10 @@ var AgentCommandHandler = class {
|
|
|
18838
18862
|
}
|
|
18839
18863
|
readToken() {
|
|
18840
18864
|
const sessionPath = import_node_path19.default.join(import_node_os8.default.homedir(), ".pmate", "session.json");
|
|
18841
|
-
if (!(0,
|
|
18865
|
+
if (!(0, import_node_fs15.existsSync)(sessionPath)) {
|
|
18842
18866
|
throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
|
|
18843
18867
|
}
|
|
18844
|
-
const raw = (0,
|
|
18868
|
+
const raw = (0, import_node_fs15.readFileSync)(sessionPath, "utf8");
|
|
18845
18869
|
const parsed = JSON.parse(raw);
|
|
18846
18870
|
const token = parsed.token?.trim();
|
|
18847
18871
|
if (!token) {
|
|
@@ -18851,10 +18875,10 @@ var AgentCommandHandler = class {
|
|
|
18851
18875
|
}
|
|
18852
18876
|
readJsonFile(filePath) {
|
|
18853
18877
|
const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
|
|
18854
|
-
if (!(0,
|
|
18878
|
+
if (!(0, import_node_fs15.existsSync)(absolutePath)) {
|
|
18855
18879
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
18856
18880
|
}
|
|
18857
|
-
const raw = (0,
|
|
18881
|
+
const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
|
|
18858
18882
|
try {
|
|
18859
18883
|
return JSON.parse(raw);
|
|
18860
18884
|
} catch (error) {
|
|
@@ -18923,7 +18947,7 @@ var AgentCommandHandler = class {
|
|
|
18923
18947
|
};
|
|
18924
18948
|
|
|
18925
18949
|
// src/commands/AppCommandHandler.ts
|
|
18926
|
-
var
|
|
18950
|
+
var import_node_fs16 = require("fs");
|
|
18927
18951
|
var import_node_os9 = __toESM(require("os"));
|
|
18928
18952
|
var import_node_path20 = __toESM(require("path"));
|
|
18929
18953
|
var AppCommandHandler = class {
|
|
@@ -18995,10 +19019,10 @@ var AppCommandHandler = class {
|
|
|
18995
19019
|
}
|
|
18996
19020
|
readToken() {
|
|
18997
19021
|
const sessionPath = import_node_path20.default.join(import_node_os9.default.homedir(), ".pmate", "session.json");
|
|
18998
|
-
if (!(0,
|
|
19022
|
+
if (!(0, import_node_fs16.existsSync)(sessionPath)) {
|
|
18999
19023
|
throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
|
|
19000
19024
|
}
|
|
19001
|
-
const raw = (0,
|
|
19025
|
+
const raw = (0, import_node_fs16.readFileSync)(sessionPath, "utf8");
|
|
19002
19026
|
const parsed = JSON.parse(raw);
|
|
19003
19027
|
const token = parsed.token?.trim();
|
|
19004
19028
|
if (!token) {
|
|
@@ -19008,10 +19032,10 @@ var AppCommandHandler = class {
|
|
|
19008
19032
|
}
|
|
19009
19033
|
readJsonFile(filePath) {
|
|
19010
19034
|
const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
|
|
19011
|
-
if (!(0,
|
|
19035
|
+
if (!(0, import_node_fs16.existsSync)(absolutePath)) {
|
|
19012
19036
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
19013
19037
|
}
|
|
19014
|
-
const raw = (0,
|
|
19038
|
+
const raw = (0, import_node_fs16.readFileSync)(absolutePath, "utf8");
|
|
19015
19039
|
try {
|
|
19016
19040
|
return JSON.parse(raw);
|
|
19017
19041
|
} catch (error) {
|
|
@@ -19428,7 +19452,7 @@ function requireValue2(tokens, optionName) {
|
|
|
19428
19452
|
|
|
19429
19453
|
// src/index.ts
|
|
19430
19454
|
var pkg = JSON.parse(
|
|
19431
|
-
(0,
|
|
19455
|
+
(0, import_node_fs17.readFileSync)(import_node_path21.default.resolve(__dirname, "..", "package.json"), "utf8")
|
|
19432
19456
|
);
|
|
19433
19457
|
var HELP_TEXT = [
|
|
19434
19458
|
import_chalk3.default.bold(`pmate v${pkg.version}`),
|
|
@@ -19444,6 +19468,7 @@ var HELP_TEXT = [
|
|
|
19444
19468
|
import_chalk3.default.bold("Commands:"),
|
|
19445
19469
|
` ${import_chalk3.default.cyan("list [path]")} List apps from .pmate.yaml in the target folder`,
|
|
19446
19470
|
` ${import_chalk3.default.cyan("login")} Log in and store a session in ~/.pmate/session.json`,
|
|
19471
|
+
` ${import_chalk3.default.gray(" [--app <app-id>]")}`,
|
|
19447
19472
|
` ${import_chalk3.default.cyan("add-dns")} Add a DNS record via Aliyun DNS`,
|
|
19448
19473
|
` ${import_chalk3.default.gray(" --type <t> --value <v> --rr <rr> [--ttl <n>] [--domain <name>]")}`,
|
|
19449
19474
|
` ${import_chalk3.default.cyan("sts")} Request an OSS STS token from the CI server`,
|
|
@@ -19572,10 +19597,19 @@ function parseCommandArgs(args) {
|
|
|
19572
19597
|
return { type: "list" /* List */, targetPath };
|
|
19573
19598
|
}
|
|
19574
19599
|
if (args.rest[0] === "login") {
|
|
19575
|
-
|
|
19576
|
-
|
|
19600
|
+
const rest = args.rest.slice(1);
|
|
19601
|
+
let app;
|
|
19602
|
+
while (rest.length > 0) {
|
|
19603
|
+
const token = rest.shift();
|
|
19604
|
+
switch (token) {
|
|
19605
|
+
case "--app":
|
|
19606
|
+
app = requireValue3(rest, token);
|
|
19607
|
+
break;
|
|
19608
|
+
default:
|
|
19609
|
+
throw new Error(`Unknown login option: ${token}`);
|
|
19610
|
+
}
|
|
19577
19611
|
}
|
|
19578
|
-
return { type: "login" /* Login
|
|
19612
|
+
return { type: "login" /* Login */, app };
|
|
19579
19613
|
}
|
|
19580
19614
|
if (args.rest[0] === "add-dns") {
|
|
19581
19615
|
return parseAddDnsArgs(args.rest.slice(1));
|