@pmate/cli 0.13.0 → 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/dist/index.js +492 -471
- 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,235 +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 DEFAULT_APP_ID = "@pmate/cli";
|
|
12573
|
-
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
12574
|
-
function buildHostedLoginUrl(redirectUrl, appId = DEFAULT_APP_ID) {
|
|
12575
|
-
const url = new URL(AUTH_UI_BASE_URL);
|
|
12576
|
-
url.searchParams.set("redirect", redirectUrl);
|
|
12577
|
-
url.searchParams.set("app", appId);
|
|
12578
|
-
return url.toString();
|
|
12579
|
-
}
|
|
12580
|
-
var LoginCommandHandler = class {
|
|
12581
|
-
async handle(args) {
|
|
12582
|
-
const callback = await this.startCallbackServer();
|
|
12583
|
-
const appId = args.app?.trim() || DEFAULT_APP_ID;
|
|
12584
|
-
const loginUrl = buildHostedLoginUrl(callback.redirectUrl, appId);
|
|
12585
|
-
ui.info("Opening browser for login.", {
|
|
12586
|
-
url: loginUrl,
|
|
12587
|
-
app: appId
|
|
12588
|
-
});
|
|
12589
|
-
if (!this.openBrowser(loginUrl)) {
|
|
12590
|
-
ui.warn("Unable to open the browser automatically.");
|
|
12591
|
-
ui.plain(loginUrl);
|
|
12592
|
-
}
|
|
12593
|
-
ui.info("Waiting for login redirect...", {
|
|
12594
|
-
callback: callback.redirectUrl,
|
|
12595
|
-
app: appId
|
|
12596
|
-
});
|
|
12597
|
-
try {
|
|
12598
|
-
const token = await callback.waitForToken;
|
|
12599
|
-
const loginResponse = await this.fetchSession(token);
|
|
12600
|
-
const sessionPath = this.writeSession(loginResponse);
|
|
12601
|
-
ui.success(`Logged in. Session saved to ${sessionPath}`);
|
|
12602
|
-
} finally {
|
|
12603
|
-
await callback.close();
|
|
12604
|
-
}
|
|
12605
|
-
}
|
|
12606
|
-
async fetchSession(token) {
|
|
12607
|
-
const response = await fetch(`${AUTH_API_BASE_URL}/session`, {
|
|
12608
|
-
method: "GET",
|
|
12609
|
-
headers: {
|
|
12610
|
-
Authorization: `Bearer ${token}`
|
|
12611
|
-
}
|
|
12612
|
-
});
|
|
12613
|
-
if (!response.ok) {
|
|
12614
|
-
const detail = await response.text();
|
|
12615
|
-
throw new Error(
|
|
12616
|
-
`Failed to validate session (${response.status}): ${detail || response.statusText}`
|
|
12617
|
-
);
|
|
12618
|
-
}
|
|
12619
|
-
const resp = await response.json();
|
|
12620
|
-
return {
|
|
12621
|
-
...resp.data,
|
|
12622
|
-
token
|
|
12623
|
-
};
|
|
12624
|
-
}
|
|
12625
|
-
async startCallbackServer() {
|
|
12626
|
-
let resolveToken;
|
|
12627
|
-
let rejectToken;
|
|
12628
|
-
const waitForToken = new Promise((resolve, reject) => {
|
|
12629
|
-
resolveToken = resolve;
|
|
12630
|
-
rejectToken = reject;
|
|
12631
|
-
});
|
|
12632
|
-
const server = (0, import_node_http.createServer)((request, response) => {
|
|
12633
|
-
this.handleCallbackRequest(request, response, resolveToken, rejectToken);
|
|
12634
|
-
});
|
|
12635
|
-
await new Promise((resolve, reject) => {
|
|
12636
|
-
server.once("error", reject);
|
|
12637
|
-
server.listen(0, "127.0.0.1", () => resolve());
|
|
12638
|
-
});
|
|
12639
|
-
const address = server.address();
|
|
12640
|
-
if (!address || typeof address === "string") {
|
|
12641
|
-
server.close();
|
|
12642
|
-
throw new Error("Failed to start login callback server.");
|
|
12643
|
-
}
|
|
12644
|
-
const redirectUrl = `http://127.0.0.1:${address.port}${CALLBACK_PATH}`;
|
|
12645
|
-
const timeout = setTimeout(() => {
|
|
12646
|
-
rejectToken(
|
|
12647
|
-
new Error(
|
|
12648
|
-
`Timed out waiting for browser login after ${LOGIN_TIMEOUT_MS / 1e3} seconds.`
|
|
12649
|
-
)
|
|
12650
|
-
);
|
|
12651
|
-
}, LOGIN_TIMEOUT_MS);
|
|
12652
|
-
const close = async () => {
|
|
12653
|
-
clearTimeout(timeout);
|
|
12654
|
-
await new Promise((resolve) => {
|
|
12655
|
-
server.close(() => resolve());
|
|
12656
|
-
});
|
|
12657
|
-
};
|
|
12658
|
-
return {
|
|
12659
|
-
redirectUrl,
|
|
12660
|
-
waitForToken,
|
|
12661
|
-
close
|
|
12662
|
-
};
|
|
12663
|
-
}
|
|
12664
|
-
handleCallbackRequest(request, response, resolveToken, rejectToken) {
|
|
12665
|
-
const url = new URL(request.url || "/", "http://127.0.0.1");
|
|
12666
|
-
if (url.pathname !== CALLBACK_PATH) {
|
|
12667
|
-
response.statusCode = 404;
|
|
12668
|
-
response.end("Not found");
|
|
12669
|
-
return;
|
|
12670
|
-
}
|
|
12671
|
-
const token = url.searchParams.get("sessionId")?.trim();
|
|
12672
|
-
if (!token) {
|
|
12673
|
-
response.statusCode = 400;
|
|
12674
|
-
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
12675
|
-
response.end(this.renderHtml("Login failed", "Missing sessionId in redirect URL."));
|
|
12676
|
-
rejectToken(new Error("Login callback did not include sessionId."));
|
|
12677
|
-
return;
|
|
12678
|
-
}
|
|
12679
|
-
response.statusCode = 200;
|
|
12680
|
-
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
12681
|
-
response.end(
|
|
12682
|
-
this.renderHtml(
|
|
12683
|
-
"Login complete",
|
|
12684
|
-
"You can close this tab and return to the terminal."
|
|
12685
|
-
)
|
|
12686
|
-
);
|
|
12687
|
-
resolveToken(token);
|
|
12688
|
-
}
|
|
12689
|
-
renderHtml(title, message) {
|
|
12690
|
-
return `<!doctype html>
|
|
12691
|
-
<html lang="en">
|
|
12692
|
-
<head>
|
|
12693
|
-
<meta charset="utf-8" />
|
|
12694
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12695
|
-
<title>${title}</title>
|
|
12696
|
-
<style>
|
|
12697
|
-
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; padding: 32px; color: #111; }
|
|
12698
|
-
main { max-width: 560px; margin: 10vh auto; }
|
|
12699
|
-
h1 { font-size: 28px; margin-bottom: 12px; }
|
|
12700
|
-
p { font-size: 16px; line-height: 1.5; }
|
|
12701
|
-
</style>
|
|
12702
|
-
</head>
|
|
12703
|
-
<body>
|
|
12704
|
-
<main>
|
|
12705
|
-
<h1>${title}</h1>
|
|
12706
|
-
<p>${message}</p>
|
|
12707
|
-
</main>
|
|
12708
|
-
</body>
|
|
12709
|
-
</html>`;
|
|
12710
|
-
}
|
|
12711
|
-
openBrowser(url) {
|
|
12712
|
-
const platform = process.platform;
|
|
12713
|
-
const command = platform === "darwin" ? { cmd: "open", args: [url] } : platform === "win32" ? { cmd: "cmd", args: ["/c", "start", "", url] } : { cmd: "xdg-open", args: [url] };
|
|
12714
|
-
try {
|
|
12715
|
-
const child = (0, import_node_child_process.spawn)(command.cmd, command.args, {
|
|
12716
|
-
detached: true,
|
|
12717
|
-
stdio: "ignore"
|
|
12718
|
-
});
|
|
12719
|
-
child.unref();
|
|
12720
|
-
return true;
|
|
12721
|
-
} catch {
|
|
12722
|
-
return false;
|
|
12723
|
-
}
|
|
12724
|
-
}
|
|
12725
|
-
writeSession(session) {
|
|
12726
|
-
const sessionDir = import_node_path2.default.join(import_node_os.default.homedir(), ".pmate");
|
|
12727
|
-
const sessionPath = import_node_path2.default.join(sessionDir, "session.json");
|
|
12728
|
-
(0, import_node_fs2.mkdirSync)(sessionDir, { recursive: true });
|
|
12729
|
-
(0, import_node_fs2.writeFileSync)(sessionPath, JSON.stringify(session, null, 2), {
|
|
12730
|
-
mode: 384
|
|
12731
|
-
});
|
|
12732
|
-
try {
|
|
12733
|
-
(0, import_node_fs2.chmodSync)(sessionPath, 384);
|
|
12734
|
-
} catch {
|
|
12735
|
-
}
|
|
12736
|
-
return sessionPath;
|
|
12737
|
-
}
|
|
12738
|
-
};
|
|
12739
|
-
|
|
12740
|
-
// src/services/AliyunService.ts
|
|
12741
|
-
var import_alidns20150109 = __toESM(require("@alicloud/alidns20150109"));
|
|
12742
|
-
var import_cdn20180510 = __toESM(require("@alicloud/cdn20180510"));
|
|
12743
|
-
var import_openapi_client = require("@alicloud/openapi-client");
|
|
12744
|
-
var import_ali_oss = __toESM(require("ali-oss"));
|
|
12745
|
-
var import_node_crypto = require("crypto");
|
|
12746
|
-
var import_node_fs4 = require("fs");
|
|
12747
|
-
var import_node_path4 = __toESM(require("path"));
|
|
12748
12527
|
|
|
12749
12528
|
// src/config.ts
|
|
12750
|
-
var
|
|
12751
|
-
var
|
|
12752
|
-
var
|
|
12529
|
+
var import_node_fs = require("fs");
|
|
12530
|
+
var import_node_os = __toESM(require("os"));
|
|
12531
|
+
var import_node_path = __toESM(require("path"));
|
|
12753
12532
|
var import_ajv = __toESM(require("ajv"));
|
|
12754
|
-
var
|
|
12533
|
+
var import_yaml = __toESM(require("yaml"));
|
|
12755
12534
|
var cachedConfig;
|
|
12756
12535
|
var CONFIG = new Proxy({}, {
|
|
12757
12536
|
get(_target, prop) {
|
|
@@ -12873,13 +12652,13 @@ function loadPmateConfig() {
|
|
|
12873
12652
|
if (cachedConfig !== void 0) {
|
|
12874
12653
|
return cachedConfig ?? {};
|
|
12875
12654
|
}
|
|
12876
|
-
const pmateDir =
|
|
12877
|
-
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");
|
|
12878
12657
|
let yamlConfig = null;
|
|
12879
|
-
if ((0,
|
|
12880
|
-
const raw = (0,
|
|
12658
|
+
if ((0, import_node_fs.existsSync)(yamlPath)) {
|
|
12659
|
+
const raw = (0, import_node_fs.readFileSync)(yamlPath, "utf8");
|
|
12881
12660
|
try {
|
|
12882
|
-
const parsed =
|
|
12661
|
+
const parsed = import_yaml.default.parse(raw);
|
|
12883
12662
|
yamlConfig = validateParsedConfig(parsed, yamlPath);
|
|
12884
12663
|
} catch (error) {
|
|
12885
12664
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -12890,19 +12669,38 @@ function loadPmateConfig() {
|
|
|
12890
12669
|
return cachedConfig;
|
|
12891
12670
|
}
|
|
12892
12671
|
function loadRepoConfig(cwd) {
|
|
12893
|
-
const
|
|
12894
|
-
if (!
|
|
12672
|
+
const paths = findRepoConfigPaths(cwd, true);
|
|
12673
|
+
if (!paths) {
|
|
12895
12674
|
return null;
|
|
12896
12675
|
}
|
|
12897
|
-
const
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
12901
|
-
|
|
12902
|
-
|
|
12903
|
-
|
|
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
|
+
);
|
|
12904
12691
|
}
|
|
12905
|
-
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;
|
|
12906
12704
|
}
|
|
12907
12705
|
function validateParsedConfig(value, configPath) {
|
|
12908
12706
|
if (value === null || value === void 0) {
|
|
@@ -12918,101 +12716,384 @@ ${detail}`);
|
|
|
12918
12716
|
}
|
|
12919
12717
|
return value;
|
|
12920
12718
|
}
|
|
12921
|
-
function
|
|
12922
|
-
let current =
|
|
12719
|
+
function findRepoConfigPaths(cwd, searchParents) {
|
|
12720
|
+
let current = import_node_path.default.resolve(cwd);
|
|
12923
12721
|
while (true) {
|
|
12924
|
-
const candidate =
|
|
12925
|
-
if ((0,
|
|
12926
|
-
|
|
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;
|
|
12927
12733
|
}
|
|
12928
|
-
const parent =
|
|
12734
|
+
const parent = import_node_path.default.dirname(current);
|
|
12929
12735
|
if (parent === current) {
|
|
12930
12736
|
return null;
|
|
12931
12737
|
}
|
|
12932
|
-
current = parent;
|
|
12933
|
-
}
|
|
12934
|
-
}
|
|
12935
|
-
function
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
const
|
|
12941
|
-
|
|
12942
|
-
|
|
12738
|
+
current = parent;
|
|
12739
|
+
}
|
|
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
|
+
}
|
|
12806
|
+
function normalizeRepoConfig(value, configPath) {
|
|
12807
|
+
if (!value || typeof value !== "object") {
|
|
12808
|
+
return null;
|
|
12809
|
+
}
|
|
12810
|
+
const config = value;
|
|
12811
|
+
const hasRepoKeys = "githubUser" in config || "linear" in config;
|
|
12812
|
+
if (!hasRepoKeys) {
|
|
12813
|
+
return null;
|
|
12814
|
+
}
|
|
12815
|
+
const repoConfig = {};
|
|
12816
|
+
if (config.githubUser !== void 0) {
|
|
12817
|
+
if (typeof config.githubUser !== "string" || !config.githubUser.trim()) {
|
|
12818
|
+
throw new Error(
|
|
12819
|
+
`Invalid repo config in ${configPath}: githubUser must be a non-empty string.`
|
|
12820
|
+
);
|
|
12821
|
+
}
|
|
12822
|
+
repoConfig.githubUser = config.githubUser.trim();
|
|
12823
|
+
}
|
|
12824
|
+
if (config.linear !== void 0) {
|
|
12825
|
+
if (!config.linear || typeof config.linear !== "object") {
|
|
12826
|
+
throw new Error(
|
|
12827
|
+
`Invalid repo config in ${configPath}: linear must be an object.`
|
|
12828
|
+
);
|
|
12829
|
+
}
|
|
12830
|
+
const linear = config.linear;
|
|
12831
|
+
const teamId = getOptionalString(linear.teamId);
|
|
12832
|
+
const teamKey = getOptionalString(linear.teamKey);
|
|
12833
|
+
const rawAccount = linear.account ?? linear.accounts;
|
|
12834
|
+
if (!rawAccount) {
|
|
12835
|
+
throw new Error(
|
|
12836
|
+
`Invalid repo config in ${configPath}: linear account is required.`
|
|
12837
|
+
);
|
|
12838
|
+
}
|
|
12839
|
+
const account = normalizeRepoLinearAccount(rawAccount, configPath);
|
|
12840
|
+
repoConfig.linear = {
|
|
12841
|
+
teamId,
|
|
12842
|
+
teamKey,
|
|
12843
|
+
account
|
|
12844
|
+
};
|
|
12845
|
+
}
|
|
12846
|
+
return repoConfig;
|
|
12847
|
+
}
|
|
12848
|
+
function normalizeRepoLinearAccount(value, configPath) {
|
|
12849
|
+
const account = Array.isArray(value) ? value : [value];
|
|
12850
|
+
if (account.length !== 1) {
|
|
12851
|
+
throw new Error(
|
|
12852
|
+
`Invalid repo config in ${configPath}: linear account must be a single entry.`
|
|
12853
|
+
);
|
|
12854
|
+
}
|
|
12855
|
+
const entry = account[0];
|
|
12856
|
+
if (!entry || typeof entry !== "object") {
|
|
12857
|
+
throw new Error(
|
|
12858
|
+
`Invalid repo config in ${configPath}: linear account must be an object.`
|
|
12859
|
+
);
|
|
12860
|
+
}
|
|
12861
|
+
const raw = entry;
|
|
12862
|
+
const apiKey = getOptionalString(raw.apiKey);
|
|
12863
|
+
if (!apiKey) {
|
|
12864
|
+
throw new Error(
|
|
12865
|
+
`Invalid repo config in ${configPath}: linear account apiKey is required.`
|
|
12866
|
+
);
|
|
12867
|
+
}
|
|
12868
|
+
const title = getOptionalString(raw.title) || "Repo";
|
|
12869
|
+
const teamId = getOptionalString(raw.teamId);
|
|
12870
|
+
const teamKey = getOptionalString(raw.teamKey);
|
|
12871
|
+
return {
|
|
12872
|
+
title,
|
|
12873
|
+
apiKey,
|
|
12874
|
+
teamId,
|
|
12875
|
+
teamKey
|
|
12876
|
+
};
|
|
12877
|
+
}
|
|
12878
|
+
function getOptionalString(value) {
|
|
12879
|
+
if (typeof value !== "string") {
|
|
12880
|
+
return void 0;
|
|
12881
|
+
}
|
|
12882
|
+
const trimmed = value.trim();
|
|
12883
|
+
return trimmed ? trimmed : void 0;
|
|
12884
|
+
}
|
|
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
|
+
}
|
|
12943
12954
|
}
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
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();
|
|
12947
12964
|
throw new Error(
|
|
12948
|
-
`
|
|
12965
|
+
`Failed to validate session (${response.status}): ${detail || response.statusText}`
|
|
12949
12966
|
);
|
|
12950
12967
|
}
|
|
12951
|
-
|
|
12968
|
+
const resp = await response.json();
|
|
12969
|
+
return {
|
|
12970
|
+
...resp.data,
|
|
12971
|
+
token
|
|
12972
|
+
};
|
|
12952
12973
|
}
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
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.");
|
|
12958
12992
|
}
|
|
12959
|
-
const
|
|
12960
|
-
const
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
`Invalid repo config in ${configPath}: linear account is required.`
|
|
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
|
+
)
|
|
12966
12999
|
);
|
|
12967
|
-
}
|
|
12968
|
-
const
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
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
|
|
12973
13011
|
};
|
|
12974
13012
|
}
|
|
12975
|
-
|
|
12976
|
-
|
|
12977
|
-
|
|
12978
|
-
|
|
12979
|
-
|
|
12980
|
-
|
|
12981
|
-
|
|
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
|
+
)
|
|
12982
13035
|
);
|
|
13036
|
+
resolveToken(token);
|
|
12983
13037
|
}
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
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>`;
|
|
12989
13059
|
}
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
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
|
+
}
|
|
12996
13073
|
}
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
}
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
return void 0;
|
|
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;
|
|
13010
13086
|
}
|
|
13011
|
-
|
|
13012
|
-
return trimmed ? trimmed : void 0;
|
|
13013
|
-
}
|
|
13087
|
+
};
|
|
13014
13088
|
|
|
13015
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"));
|
|
13016
13097
|
var AliyunService = class {
|
|
13017
13098
|
/** Add a DNS record via Aliyun DNS. */
|
|
13018
13099
|
static async addRecord(input) {
|
|
@@ -13155,7 +13236,7 @@ var AliyunService = class {
|
|
|
13155
13236
|
const options = contentType ? { headers: { "Content-Type": contentType } } : void 0;
|
|
13156
13237
|
const existing = existingMap.get(objectKey);
|
|
13157
13238
|
if (existing && typeof existing.size === "number") {
|
|
13158
|
-
const stat = await
|
|
13239
|
+
const stat = await import_node_fs3.promises.stat(filePath);
|
|
13159
13240
|
if (stat.size === existing.size) {
|
|
13160
13241
|
const etag = this.normalizeEtag(existing.etag);
|
|
13161
13242
|
if (etag && !etag.includes("-")) {
|
|
@@ -13180,7 +13261,7 @@ var AliyunService = class {
|
|
|
13180
13261
|
if (!region) throw new Error("Missing oss.public.region in ~/.pmate/config.yaml.");
|
|
13181
13262
|
if (!accessKeyId) throw new Error("Missing aliyun.ak in ~/.pmate/config.yaml.");
|
|
13182
13263
|
if (!accessKeySecret) throw new Error("Missing aliyun.sk in ~/.pmate/config.yaml.");
|
|
13183
|
-
if (!(0,
|
|
13264
|
+
if (!(0, import_node_fs3.existsSync)(localFile)) {
|
|
13184
13265
|
throw new Error(`File not found: ${localFile}`);
|
|
13185
13266
|
}
|
|
13186
13267
|
const client = new import_ali_oss.default({ region, accessKeyId, accessKeySecret, bucket });
|
|
@@ -13455,7 +13536,7 @@ var AliyunService = class {
|
|
|
13455
13536
|
}
|
|
13456
13537
|
/** Recursively collect file paths under a directory. */
|
|
13457
13538
|
static async collectFiles(dir) {
|
|
13458
|
-
const entries = await
|
|
13539
|
+
const entries = await import_node_fs3.promises.readdir(dir, { withFileTypes: true });
|
|
13459
13540
|
const files = [];
|
|
13460
13541
|
for (const entry of entries) {
|
|
13461
13542
|
const fullPath = import_node_path4.default.join(dir, entry.name);
|
|
@@ -13507,7 +13588,7 @@ var AliyunService = class {
|
|
|
13507
13588
|
static getFileMd5(filePath) {
|
|
13508
13589
|
return new Promise((resolve, reject) => {
|
|
13509
13590
|
const hash = (0, import_node_crypto.createHash)("md5");
|
|
13510
|
-
const stream = (0,
|
|
13591
|
+
const stream = (0, import_node_fs3.createReadStream)(filePath);
|
|
13511
13592
|
stream.on("data", (chunk) => {
|
|
13512
13593
|
hash.update(chunk);
|
|
13513
13594
|
});
|
|
@@ -13592,7 +13673,7 @@ var AddDnsCommandHandler = class {
|
|
|
13592
13673
|
};
|
|
13593
13674
|
|
|
13594
13675
|
// src/commands/StsCommandHandler.ts
|
|
13595
|
-
var
|
|
13676
|
+
var import_node_fs4 = require("fs");
|
|
13596
13677
|
var import_node_os3 = __toESM(require("os"));
|
|
13597
13678
|
var import_node_path5 = __toESM(require("path"));
|
|
13598
13679
|
var import_chalk2 = __toESM(require("chalk"));
|
|
@@ -13624,10 +13705,10 @@ var StsCommandHandler = class {
|
|
|
13624
13705
|
}
|
|
13625
13706
|
readSession() {
|
|
13626
13707
|
const sessionPath = import_node_path5.default.join(import_node_os3.default.homedir(), ".pmate", "session.json");
|
|
13627
|
-
if (!(0,
|
|
13708
|
+
if (!(0, import_node_fs4.existsSync)(sessionPath)) {
|
|
13628
13709
|
throw new Error("Missing session. Run `pmate login` first.");
|
|
13629
13710
|
}
|
|
13630
|
-
const raw = (0,
|
|
13711
|
+
const raw = (0, import_node_fs4.readFileSync)(sessionPath, "utf8");
|
|
13631
13712
|
return JSON.parse(raw);
|
|
13632
13713
|
}
|
|
13633
13714
|
};
|
|
@@ -13642,10 +13723,9 @@ var BucketCommandHandler = class {
|
|
|
13642
13723
|
};
|
|
13643
13724
|
|
|
13644
13725
|
// src/commands/DeployCommandHandler.ts
|
|
13645
|
-
var
|
|
13726
|
+
var import_node_fs5 = require("fs");
|
|
13646
13727
|
var import_node_path7 = __toESM(require("path"));
|
|
13647
13728
|
var import_node_child_process2 = require("child_process");
|
|
13648
|
-
var import_yaml3 = __toESM(require("yaml"));
|
|
13649
13729
|
|
|
13650
13730
|
// src/appDir.ts
|
|
13651
13731
|
var import_node_path6 = __toESM(require("path"));
|
|
@@ -13695,11 +13775,12 @@ var DeployCommandHandler = class {
|
|
|
13695
13775
|
);
|
|
13696
13776
|
}
|
|
13697
13777
|
const cwd = this.resolveCwd(args.deployCwd);
|
|
13698
|
-
const
|
|
13778
|
+
const loadedConfig = this.loadConfig(cwd);
|
|
13779
|
+
const config = loadedConfig.config;
|
|
13699
13780
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
13700
13781
|
if (!appConfig) {
|
|
13701
13782
|
throw new Error(
|
|
13702
|
-
`No app named ${appName} found in ${
|
|
13783
|
+
`No app named ${appName} found in ${describeLoadedAppConfig(loadedConfig)}`
|
|
13703
13784
|
);
|
|
13704
13785
|
}
|
|
13705
13786
|
if (args.deployAction === "logs") {
|
|
@@ -13743,7 +13824,7 @@ var DeployCommandHandler = class {
|
|
|
13743
13824
|
async deployVite(appName, cwd, appConfig) {
|
|
13744
13825
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
13745
13826
|
const packageJsonPath = import_node_path7.default.join(appDir, "package.json");
|
|
13746
|
-
if (!(0,
|
|
13827
|
+
if (!(0, import_node_fs5.existsSync)(packageJsonPath)) {
|
|
13747
13828
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
13748
13829
|
}
|
|
13749
13830
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -13753,7 +13834,7 @@ var DeployCommandHandler = class {
|
|
|
13753
13834
|
}
|
|
13754
13835
|
await this.runCommand("pnpm", ["--filter", pkgName, "build"], cwd);
|
|
13755
13836
|
const distDir = import_node_path7.default.join(appDir, "dist");
|
|
13756
|
-
if (!(0,
|
|
13837
|
+
if (!(0, import_node_fs5.existsSync)(distDir)) {
|
|
13757
13838
|
throw new Error(`No dist directory found at ${distDir}`);
|
|
13758
13839
|
}
|
|
13759
13840
|
const bucketName = appConfig.bucket?.trim();
|
|
@@ -13767,7 +13848,7 @@ var DeployCommandHandler = class {
|
|
|
13767
13848
|
async deployStatic(appName, cwd, appConfig) {
|
|
13768
13849
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
13769
13850
|
const srcDir = import_node_path7.default.join(appDir, "src");
|
|
13770
|
-
if (!(0,
|
|
13851
|
+
if (!(0, import_node_fs5.existsSync)(srcDir)) {
|
|
13771
13852
|
throw new Error(`No src directory found at ${srcDir}`);
|
|
13772
13853
|
}
|
|
13773
13854
|
const bucketName = appConfig.bucket?.trim();
|
|
@@ -13882,7 +13963,7 @@ var DeployCommandHandler = class {
|
|
|
13882
13963
|
return target ? import_node_path7.default.resolve(process.cwd(), target) : process.cwd();
|
|
13883
13964
|
}
|
|
13884
13965
|
loadPackageJson(packageJsonPath) {
|
|
13885
|
-
const raw = (0,
|
|
13966
|
+
const raw = (0, import_node_fs5.readFileSync)(packageJsonPath, "utf8");
|
|
13886
13967
|
const parsed = JSON.parse(raw);
|
|
13887
13968
|
if (!parsed || typeof parsed !== "object") {
|
|
13888
13969
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -13890,16 +13971,7 @@ var DeployCommandHandler = class {
|
|
|
13890
13971
|
return parsed;
|
|
13891
13972
|
}
|
|
13892
13973
|
loadConfig(cwd) {
|
|
13893
|
-
|
|
13894
|
-
if (!(0, import_node_fs6.existsSync)(configPath)) {
|
|
13895
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
13896
|
-
}
|
|
13897
|
-
const raw = (0, import_node_fs6.readFileSync)(configPath, "utf8");
|
|
13898
|
-
const parsed = import_yaml3.default.parse(raw);
|
|
13899
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
13900
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
13901
|
-
}
|
|
13902
|
-
return parsed;
|
|
13974
|
+
return loadAppConfig(cwd);
|
|
13903
13975
|
}
|
|
13904
13976
|
runCommand(command, args, cwd) {
|
|
13905
13977
|
return new Promise((resolve, reject) => {
|
|
@@ -13969,11 +14041,10 @@ var DeployCommandHandler = class {
|
|
|
13969
14041
|
};
|
|
13970
14042
|
|
|
13971
14043
|
// src/commands/LogCommandHandler.ts
|
|
13972
|
-
var
|
|
14044
|
+
var import_node_fs6 = require("fs");
|
|
13973
14045
|
var import_node_child_process3 = require("child_process");
|
|
13974
14046
|
var import_node_path8 = __toESM(require("path"));
|
|
13975
14047
|
var import_node_module = require("module");
|
|
13976
|
-
var import_yaml4 = __toESM(require("yaml"));
|
|
13977
14048
|
var LogCommandHandler = class {
|
|
13978
14049
|
async handle(args) {
|
|
13979
14050
|
const appName = args.logApp.trim();
|
|
@@ -13981,14 +14052,13 @@ var LogCommandHandler = class {
|
|
|
13981
14052
|
throw new Error("Missing app name. Usage: log <app-name> [--cwd <dir>].");
|
|
13982
14053
|
}
|
|
13983
14054
|
const cwd = this.resolveCwd(args.logCwd);
|
|
13984
|
-
const { config, configPath } = this.loadClosestConfig(cwd);
|
|
14055
|
+
const { config, configPath, repoRoot } = this.loadClosestConfig(cwd);
|
|
13985
14056
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
13986
14057
|
if (!appConfig) {
|
|
13987
14058
|
throw new Error(`No app named ${appName} found in ${configPath}`);
|
|
13988
14059
|
}
|
|
13989
14060
|
if (appConfig.type === "node") {
|
|
13990
14061
|
const server = this.resolveNodeServer(appName, appConfig);
|
|
13991
|
-
const repoRoot = import_node_path8.default.dirname(configPath);
|
|
13992
14062
|
const pm2Name = this.resolvePm2AppName(repoRoot, appName, appConfig);
|
|
13993
14063
|
await this.runRemotePm2Logs(server, pm2Name);
|
|
13994
14064
|
return;
|
|
@@ -14005,30 +14075,12 @@ var LogCommandHandler = class {
|
|
|
14005
14075
|
return target ? import_node_path8.default.resolve(process.cwd(), target) : process.cwd();
|
|
14006
14076
|
}
|
|
14007
14077
|
loadClosestConfig(cwd) {
|
|
14008
|
-
const
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
14015
|
-
throw new Error(`Invalid .pmate.yaml: missing apps array (${configPath})`);
|
|
14016
|
-
}
|
|
14017
|
-
return { config: parsed, configPath };
|
|
14018
|
-
}
|
|
14019
|
-
findRepoConfigPath(cwd) {
|
|
14020
|
-
let current = import_node_path8.default.resolve(cwd);
|
|
14021
|
-
while (true) {
|
|
14022
|
-
const candidate = import_node_path8.default.join(current, ".pmate.yaml");
|
|
14023
|
-
if ((0, import_node_fs7.existsSync)(candidate)) {
|
|
14024
|
-
return candidate;
|
|
14025
|
-
}
|
|
14026
|
-
const parent = import_node_path8.default.dirname(current);
|
|
14027
|
-
if (parent === current) {
|
|
14028
|
-
return null;
|
|
14029
|
-
}
|
|
14030
|
-
current = parent;
|
|
14031
|
-
}
|
|
14078
|
+
const loaded = loadAppConfig(cwd, { searchParents: true });
|
|
14079
|
+
return {
|
|
14080
|
+
config: loaded.config,
|
|
14081
|
+
configPath: describeLoadedAppConfig(loaded),
|
|
14082
|
+
repoRoot: loaded.rootDir
|
|
14083
|
+
};
|
|
14032
14084
|
}
|
|
14033
14085
|
resolveNodeServer(appName, appConfig) {
|
|
14034
14086
|
const server = appConfig.server?.trim();
|
|
@@ -14052,11 +14104,11 @@ var LogCommandHandler = class {
|
|
|
14052
14104
|
}
|
|
14053
14105
|
findEcosystemPath(appDir) {
|
|
14054
14106
|
const cjs = import_node_path8.default.join(appDir, "ecosystem.config.cjs");
|
|
14055
|
-
if ((0,
|
|
14107
|
+
if ((0, import_node_fs6.existsSync)(cjs)) {
|
|
14056
14108
|
return cjs;
|
|
14057
14109
|
}
|
|
14058
14110
|
const js = import_node_path8.default.join(appDir, "ecosystem.config.js");
|
|
14059
|
-
if ((0,
|
|
14111
|
+
if ((0, import_node_fs6.existsSync)(js)) {
|
|
14060
14112
|
return js;
|
|
14061
14113
|
}
|
|
14062
14114
|
return null;
|
|
@@ -14157,11 +14209,11 @@ var LogCommandHandler = class {
|
|
|
14157
14209
|
};
|
|
14158
14210
|
|
|
14159
14211
|
// src/commands/InitCommandHandler.ts
|
|
14160
|
-
var
|
|
14212
|
+
var import_node_fs7 = require("fs");
|
|
14161
14213
|
var import_node_path9 = __toESM(require("path"));
|
|
14162
14214
|
var import_node_child_process4 = require("child_process");
|
|
14163
14215
|
var import_promises2 = require("readline/promises");
|
|
14164
|
-
var
|
|
14216
|
+
var import_yaml2 = __toESM(require("yaml"));
|
|
14165
14217
|
|
|
14166
14218
|
// src/serverAddress.ts
|
|
14167
14219
|
var import_promises = require("dns/promises");
|
|
@@ -14189,14 +14241,14 @@ var InitCommandHandler = class {
|
|
|
14189
14241
|
throw new Error("Missing app name. Usage: init <app-name> [--cwd <dir>].");
|
|
14190
14242
|
}
|
|
14191
14243
|
const cwd = this.resolveCwd(args.initCwd);
|
|
14192
|
-
const config = this.loadConfig(cwd);
|
|
14244
|
+
const { config } = this.loadConfig(cwd);
|
|
14193
14245
|
let appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
14194
14246
|
if (!appConfig) {
|
|
14195
14247
|
appConfig = await this.addAppConfig(config, appName, cwd);
|
|
14196
14248
|
}
|
|
14197
14249
|
if (appConfig.type !== "rust") {
|
|
14198
14250
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
14199
|
-
if (!(0,
|
|
14251
|
+
if (!(0, import_node_fs7.existsSync)(appDir)) {
|
|
14200
14252
|
throw new Error(`No app folder found at ${appDir}`);
|
|
14201
14253
|
}
|
|
14202
14254
|
}
|
|
@@ -14364,10 +14416,10 @@ var InitCommandHandler = class {
|
|
|
14364
14416
|
const serverAddress = await resolveServerAddress(server);
|
|
14365
14417
|
const templateName = serviceType === "ws" ? "nginx.ws.template" : "nginx.rest.template";
|
|
14366
14418
|
const templatePath = import_node_path9.default.join(__dirname, "..", "templates", templateName);
|
|
14367
|
-
if (!(0,
|
|
14419
|
+
if (!(0, import_node_fs7.existsSync)(templatePath)) {
|
|
14368
14420
|
throw new Error(`Missing nginx template at ${templatePath}`);
|
|
14369
14421
|
}
|
|
14370
|
-
const template = (0,
|
|
14422
|
+
const template = (0, import_node_fs7.readFileSync)(templatePath, "utf8");
|
|
14371
14423
|
const host = `${subdomain}.pmate.chat`;
|
|
14372
14424
|
const rendered = template.replace(/\$\{\{PORT\}\}/g, String(port)).replace(/\$\{\{HOSTS\}\}/g, host).replace(/\$\{\{HOST\}\}/g, host);
|
|
14373
14425
|
const remotePath = `/etc/nginx/sites-enabled/${subdomain}.conf`;
|
|
@@ -14400,15 +14452,15 @@ var InitCommandHandler = class {
|
|
|
14400
14452
|
if (options.ensurePackageJson) {
|
|
14401
14453
|
const appDir = resolveLocalAppDir(cwd, appConfig.app, appConfig.dir);
|
|
14402
14454
|
ui.info(`Resolved appDir: ${appDir}`);
|
|
14403
|
-
if (!(0,
|
|
14455
|
+
if (!(0, import_node_fs7.existsSync)(appDir)) {
|
|
14404
14456
|
throw new Error(`Missing app folder at ${appDir}`);
|
|
14405
14457
|
}
|
|
14406
14458
|
const packageJsonPath = import_node_path9.default.join(appDir, "package.json");
|
|
14407
14459
|
ui.info(`Resolved package.json: ${packageJsonPath}`);
|
|
14408
|
-
if (!(0,
|
|
14460
|
+
if (!(0, import_node_fs7.existsSync)(packageJsonPath)) {
|
|
14409
14461
|
throw new Error(`Missing package.json at ${packageJsonPath}`);
|
|
14410
14462
|
}
|
|
14411
|
-
const pkgStat = (0,
|
|
14463
|
+
const pkgStat = (0, import_node_fs7.statSync)(packageJsonPath);
|
|
14412
14464
|
ui.info(
|
|
14413
14465
|
`package.json stat: isFile=${pkgStat.isFile()} isDirectory=${pkgStat.isDirectory()}`
|
|
14414
14466
|
);
|
|
@@ -14474,16 +14526,7 @@ var InitCommandHandler = class {
|
|
|
14474
14526
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
14475
14527
|
}
|
|
14476
14528
|
loadConfig(cwd) {
|
|
14477
|
-
|
|
14478
|
-
if (!(0, import_node_fs8.existsSync)(configPath)) {
|
|
14479
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
14480
|
-
}
|
|
14481
|
-
const raw = (0, import_node_fs8.readFileSync)(configPath, "utf8");
|
|
14482
|
-
const parsed = import_yaml5.default.parse(raw);
|
|
14483
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
14484
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
14485
|
-
}
|
|
14486
|
-
return parsed;
|
|
14529
|
+
return loadAppConfig(cwd);
|
|
14487
14530
|
}
|
|
14488
14531
|
async addAppConfig(config, appName, cwd) {
|
|
14489
14532
|
ui.title(`App ${appName} not found in .pmate.yaml.`);
|
|
@@ -14601,7 +14644,7 @@ var InitCommandHandler = class {
|
|
|
14601
14644
|
}
|
|
14602
14645
|
}
|
|
14603
14646
|
loadPackageJson(packageJsonPath) {
|
|
14604
|
-
const raw = (0,
|
|
14647
|
+
const raw = (0, import_node_fs7.readFileSync)(packageJsonPath, "utf8");
|
|
14605
14648
|
const parsed = JSON.parse(raw);
|
|
14606
14649
|
if (!parsed || typeof parsed !== "object") {
|
|
14607
14650
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -14610,13 +14653,13 @@ var InitCommandHandler = class {
|
|
|
14610
14653
|
}
|
|
14611
14654
|
writePackageJson(packageJsonPath, data) {
|
|
14612
14655
|
const serialized = JSON.stringify(data, null, 2);
|
|
14613
|
-
(0,
|
|
14656
|
+
(0, import_node_fs7.writeFileSync)(packageJsonPath, `${serialized}
|
|
14614
14657
|
`, "utf8");
|
|
14615
14658
|
}
|
|
14616
14659
|
writeConfig(cwd, config) {
|
|
14617
14660
|
const configPath = import_node_path9.default.join(cwd, ".pmate.yaml");
|
|
14618
|
-
const serialized =
|
|
14619
|
-
(0,
|
|
14661
|
+
const serialized = import_yaml2.default.stringify(config).trimEnd();
|
|
14662
|
+
(0, import_node_fs7.writeFileSync)(configPath, `${serialized}
|
|
14620
14663
|
`, "utf8");
|
|
14621
14664
|
}
|
|
14622
14665
|
async promptRequired(rl, question) {
|
|
@@ -14652,10 +14695,9 @@ var InitCommandHandler = class {
|
|
|
14652
14695
|
};
|
|
14653
14696
|
|
|
14654
14697
|
// src/commands/DevCommandHandler.ts
|
|
14655
|
-
var
|
|
14698
|
+
var import_node_fs8 = require("fs");
|
|
14656
14699
|
var import_node_path10 = __toESM(require("path"));
|
|
14657
14700
|
var import_node_child_process5 = require("child_process");
|
|
14658
|
-
var import_yaml6 = __toESM(require("yaml"));
|
|
14659
14701
|
var DevCommandHandler = class {
|
|
14660
14702
|
async handle(args) {
|
|
14661
14703
|
const appName = args.devApp.trim();
|
|
@@ -14663,16 +14705,17 @@ var DevCommandHandler = class {
|
|
|
14663
14705
|
throw new Error("Missing app name. Usage: dev <app-name> [--cwd <dir>].");
|
|
14664
14706
|
}
|
|
14665
14707
|
const cwd = this.resolveCwd(args.devCwd);
|
|
14666
|
-
const
|
|
14708
|
+
const loadedConfig = this.loadConfig(cwd);
|
|
14709
|
+
const config = loadedConfig.config;
|
|
14667
14710
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
14668
14711
|
if (!appConfig) {
|
|
14669
14712
|
throw new Error(
|
|
14670
|
-
`No app named ${appName} found in ${
|
|
14713
|
+
`No app named ${appName} found in ${describeLoadedAppConfig(loadedConfig)}`
|
|
14671
14714
|
);
|
|
14672
14715
|
}
|
|
14673
14716
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
14674
14717
|
const packageJsonPath = import_node_path10.default.join(appDir, "package.json");
|
|
14675
|
-
if (!(0,
|
|
14718
|
+
if (!(0, import_node_fs8.existsSync)(packageJsonPath)) {
|
|
14676
14719
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
14677
14720
|
}
|
|
14678
14721
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -14689,19 +14732,10 @@ var DevCommandHandler = class {
|
|
|
14689
14732
|
return target ? import_node_path10.default.resolve(process.cwd(), target) : process.cwd();
|
|
14690
14733
|
}
|
|
14691
14734
|
loadConfig(cwd) {
|
|
14692
|
-
|
|
14693
|
-
if (!(0, import_node_fs9.existsSync)(configPath)) {
|
|
14694
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
14695
|
-
}
|
|
14696
|
-
const raw = (0, import_node_fs9.readFileSync)(configPath, "utf8");
|
|
14697
|
-
const parsed = import_yaml6.default.parse(raw);
|
|
14698
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
14699
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
14700
|
-
}
|
|
14701
|
-
return parsed;
|
|
14735
|
+
return loadAppConfig(cwd);
|
|
14702
14736
|
}
|
|
14703
14737
|
loadPackageJson(packageJsonPath) {
|
|
14704
|
-
const raw = (0,
|
|
14738
|
+
const raw = (0, import_node_fs8.readFileSync)(packageJsonPath, "utf8");
|
|
14705
14739
|
const parsed = JSON.parse(raw);
|
|
14706
14740
|
if (!parsed || typeof parsed !== "object") {
|
|
14707
14741
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -14729,7 +14763,7 @@ var DevCommandHandler = class {
|
|
|
14729
14763
|
};
|
|
14730
14764
|
|
|
14731
14765
|
// src/commands/OssCommandHandler.ts
|
|
14732
|
-
var
|
|
14766
|
+
var import_node_fs9 = require("fs");
|
|
14733
14767
|
var import_node_path11 = __toESM(require("path"));
|
|
14734
14768
|
var import_promises3 = require("readline/promises");
|
|
14735
14769
|
var OssCommandHandler = class {
|
|
@@ -14765,10 +14799,10 @@ var OssCommandHandler = class {
|
|
|
14765
14799
|
}
|
|
14766
14800
|
}
|
|
14767
14801
|
assertFile(filePath) {
|
|
14768
|
-
if (!(0,
|
|
14802
|
+
if (!(0, import_node_fs9.existsSync)(filePath)) {
|
|
14769
14803
|
throw new Error(`File not found: ${filePath}`);
|
|
14770
14804
|
}
|
|
14771
|
-
const stat = (0,
|
|
14805
|
+
const stat = (0, import_node_fs9.statSync)(filePath);
|
|
14772
14806
|
if (!stat.isFile()) {
|
|
14773
14807
|
throw new Error(`Not a file: ${filePath}`);
|
|
14774
14808
|
}
|
|
@@ -14804,10 +14838,8 @@ var OssCommandHandler = class {
|
|
|
14804
14838
|
};
|
|
14805
14839
|
|
|
14806
14840
|
// src/commands/EnvCommandHandler.ts
|
|
14807
|
-
var import_node_fs11 = require("fs");
|
|
14808
14841
|
var import_node_path12 = __toESM(require("path"));
|
|
14809
14842
|
var import_node_child_process6 = require("child_process");
|
|
14810
|
-
var import_yaml7 = __toESM(require("yaml"));
|
|
14811
14843
|
var EnvCommandHandler = class {
|
|
14812
14844
|
async handle(args) {
|
|
14813
14845
|
const appName = args.envApp.trim();
|
|
@@ -14816,14 +14848,12 @@ var EnvCommandHandler = class {
|
|
|
14816
14848
|
"Missing app name. Usage: env <app-name> --list|--set KEY --value VALUE|--delete KEY [--cwd <dir>] [--verbose|-v]"
|
|
14817
14849
|
);
|
|
14818
14850
|
}
|
|
14819
|
-
const
|
|
14851
|
+
const loadedConfig = this.loadConfig(args.envCwd);
|
|
14852
|
+
const config = loadedConfig.config;
|
|
14820
14853
|
const appConfig = config.apps.find((entry) => entry?.app === appName);
|
|
14821
14854
|
if (!appConfig) {
|
|
14822
14855
|
throw new Error(
|
|
14823
|
-
`No app named ${appName} found in ${
|
|
14824
|
-
process.cwd(),
|
|
14825
|
-
".pmate.yaml"
|
|
14826
|
-
)}`
|
|
14856
|
+
`No app named ${appName} found in ${describeLoadedAppConfig(loadedConfig)}`
|
|
14827
14857
|
);
|
|
14828
14858
|
}
|
|
14829
14859
|
if (appConfig.type !== "node") {
|
|
@@ -15091,16 +15121,7 @@ var EnvCommandHandler = class {
|
|
|
15091
15121
|
}
|
|
15092
15122
|
}
|
|
15093
15123
|
loadConfig(cwd) {
|
|
15094
|
-
|
|
15095
|
-
if (!(0, import_node_fs11.existsSync)(configPath)) {
|
|
15096
|
-
throw new Error(`No .pmate.yaml found in ${cwd}`);
|
|
15097
|
-
}
|
|
15098
|
-
const raw = (0, import_node_fs11.readFileSync)(configPath, "utf8");
|
|
15099
|
-
const parsed = import_yaml7.default.parse(raw);
|
|
15100
|
-
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.apps)) {
|
|
15101
|
-
throw new Error("Invalid .pmate.yaml: missing apps array");
|
|
15102
|
-
}
|
|
15103
|
-
return parsed;
|
|
15124
|
+
return loadAppConfig(cwd);
|
|
15104
15125
|
}
|
|
15105
15126
|
runRemoteCommand(server, command) {
|
|
15106
15127
|
return new Promise((resolve, reject) => {
|
|
@@ -16003,7 +16024,7 @@ function truncate2(value, limit) {
|
|
|
16003
16024
|
|
|
16004
16025
|
// src/commands/LinearCommandHandler.ts
|
|
16005
16026
|
var import_node_child_process9 = require("child_process");
|
|
16006
|
-
var
|
|
16027
|
+
var import_node_fs11 = require("fs");
|
|
16007
16028
|
var import_node_os5 = __toESM(require("os"));
|
|
16008
16029
|
var import_node_path15 = __toESM(require("path"));
|
|
16009
16030
|
var import_promises4 = require("readline/promises");
|
|
@@ -16893,11 +16914,11 @@ var LinearCommandHandler = class {
|
|
|
16893
16914
|
}
|
|
16894
16915
|
readCachedLinearSelection(cwd) {
|
|
16895
16916
|
const selectionPath = this.getLinearSelectionPath();
|
|
16896
|
-
if (!(0,
|
|
16917
|
+
if (!(0, import_node_fs11.existsSync)(selectionPath)) {
|
|
16897
16918
|
return void 0;
|
|
16898
16919
|
}
|
|
16899
16920
|
try {
|
|
16900
|
-
const raw = (0,
|
|
16921
|
+
const raw = (0, import_node_fs11.readFileSync)(selectionPath, "utf8").trim();
|
|
16901
16922
|
if (!raw) return void 0;
|
|
16902
16923
|
const parsed = JSON.parse(raw);
|
|
16903
16924
|
const value = parsed[cwd];
|
|
@@ -16909,11 +16930,11 @@ var LinearCommandHandler = class {
|
|
|
16909
16930
|
writeCachedLinearSelection(cwd, title) {
|
|
16910
16931
|
const selectionPath = this.getLinearSelectionPath();
|
|
16911
16932
|
const dir = import_node_path15.default.dirname(selectionPath);
|
|
16912
|
-
(0,
|
|
16933
|
+
(0, import_node_fs11.mkdirSync)(dir, { recursive: true });
|
|
16913
16934
|
let data = {};
|
|
16914
|
-
if ((0,
|
|
16935
|
+
if ((0, import_node_fs11.existsSync)(selectionPath)) {
|
|
16915
16936
|
try {
|
|
16916
|
-
const raw = (0,
|
|
16937
|
+
const raw = (0, import_node_fs11.readFileSync)(selectionPath, "utf8").trim();
|
|
16917
16938
|
if (raw) {
|
|
16918
16939
|
data = JSON.parse(raw);
|
|
16919
16940
|
}
|
|
@@ -16922,7 +16943,7 @@ var LinearCommandHandler = class {
|
|
|
16922
16943
|
}
|
|
16923
16944
|
}
|
|
16924
16945
|
data[cwd] = title;
|
|
16925
|
-
(0,
|
|
16946
|
+
(0, import_node_fs11.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
|
|
16926
16947
|
`, "utf8");
|
|
16927
16948
|
}
|
|
16928
16949
|
async lookupIssue(client, issueRef) {
|
|
@@ -17099,14 +17120,14 @@ var LinearCommandHandler = class {
|
|
|
17099
17120
|
if (process.platform !== "darwin") {
|
|
17100
17121
|
throw new Error("Screenshot capture only supports macOS.");
|
|
17101
17122
|
}
|
|
17102
|
-
const dir = await
|
|
17123
|
+
const dir = await import_node_fs11.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-screenshot-"));
|
|
17103
17124
|
const filePath = import_node_path15.default.join(dir, `screenshot-${index}.png`);
|
|
17104
17125
|
try {
|
|
17105
17126
|
const code = await this.run("screencapture", ["-i", "-x", filePath], true);
|
|
17106
17127
|
if (code !== 0) {
|
|
17107
17128
|
throw new Error("Screenshot capture canceled or failed.");
|
|
17108
17129
|
}
|
|
17109
|
-
const buffer = await
|
|
17130
|
+
const buffer = await import_node_fs11.promises.readFile(filePath);
|
|
17110
17131
|
if (buffer.length === 0) {
|
|
17111
17132
|
throw new Error("Screenshot capture produced an empty file.");
|
|
17112
17133
|
}
|
|
@@ -17118,7 +17139,7 @@ var LinearCommandHandler = class {
|
|
|
17118
17139
|
return { buffer, mime, filename: `screenshot-${index}.${extension}` };
|
|
17119
17140
|
} finally {
|
|
17120
17141
|
try {
|
|
17121
|
-
await
|
|
17142
|
+
await import_node_fs11.promises.rm(dir, { recursive: true, force: true });
|
|
17122
17143
|
} catch {
|
|
17123
17144
|
}
|
|
17124
17145
|
}
|
|
@@ -17262,17 +17283,17 @@ var LinearCommandHandler = class {
|
|
|
17262
17283
|
return compact.length > limit ? `${compact.slice(0, limit)}...` : compact;
|
|
17263
17284
|
}
|
|
17264
17285
|
async convertToPng(buffer, ext) {
|
|
17265
|
-
const dir = await
|
|
17286
|
+
const dir = await import_node_fs11.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-"));
|
|
17266
17287
|
const inputPath = import_node_path15.default.join(dir, `clipboard.${ext}`);
|
|
17267
17288
|
const outputPath = import_node_path15.default.join(dir, "clipboard.png");
|
|
17268
17289
|
try {
|
|
17269
|
-
await
|
|
17290
|
+
await import_node_fs11.promises.writeFile(inputPath, buffer);
|
|
17270
17291
|
const stderr = await this.runCapture(
|
|
17271
17292
|
"sips",
|
|
17272
17293
|
["-s", "format", "png", inputPath, "--out", outputPath],
|
|
17273
17294
|
true
|
|
17274
17295
|
);
|
|
17275
|
-
const out = await
|
|
17296
|
+
const out = await import_node_fs11.promises.readFile(outputPath);
|
|
17276
17297
|
if (this.detectImageMime(out) !== "image/png") {
|
|
17277
17298
|
throw new Error(
|
|
17278
17299
|
stderr?.trim() ? `Failed to convert clipboard ${ext} to PNG: ${stderr.trim()}` : `Failed to convert clipboard ${ext} to PNG.`
|
|
@@ -17281,7 +17302,7 @@ var LinearCommandHandler = class {
|
|
|
17281
17302
|
return out;
|
|
17282
17303
|
} finally {
|
|
17283
17304
|
try {
|
|
17284
|
-
await
|
|
17305
|
+
await import_node_fs11.promises.rm(dir, { recursive: true, force: true });
|
|
17285
17306
|
} catch {
|
|
17286
17307
|
}
|
|
17287
17308
|
}
|
|
@@ -17627,7 +17648,7 @@ function sleep(ms) {
|
|
|
17627
17648
|
}
|
|
17628
17649
|
|
|
17629
17650
|
// src/commands/NotionCommandHandler.ts
|
|
17630
|
-
var
|
|
17651
|
+
var import_node_fs12 = require("fs");
|
|
17631
17652
|
var import_node_path16 = __toESM(require("path"));
|
|
17632
17653
|
|
|
17633
17654
|
// src/services/NotionService.ts
|
|
@@ -17968,13 +17989,13 @@ var NotionCommandHandler = class {
|
|
|
17968
17989
|
return "";
|
|
17969
17990
|
}
|
|
17970
17991
|
const resolved = import_node_path16.default.resolve(process.cwd(), args.filePath);
|
|
17971
|
-
return (0,
|
|
17992
|
+
return (0, import_node_fs12.readFileSync)(resolved, "utf8");
|
|
17972
17993
|
}
|
|
17973
17994
|
};
|
|
17974
17995
|
|
|
17975
17996
|
// src/commands/QrcodeCommandHandler.ts
|
|
17976
17997
|
var import_node_child_process10 = require("child_process");
|
|
17977
|
-
var
|
|
17998
|
+
var import_node_fs13 = require("fs");
|
|
17978
17999
|
var import_node_os6 = __toESM(require("os"));
|
|
17979
18000
|
var import_node_path17 = __toESM(require("path"));
|
|
17980
18001
|
var import_promises5 = require("readline/promises");
|
|
@@ -18002,7 +18023,7 @@ var QrcodeCommandHandler = class {
|
|
|
18002
18023
|
ui.success("QR code value:", value);
|
|
18003
18024
|
} finally {
|
|
18004
18025
|
try {
|
|
18005
|
-
await
|
|
18026
|
+
await import_node_fs13.promises.rm(dir, { recursive: true, force: true });
|
|
18006
18027
|
} catch {
|
|
18007
18028
|
}
|
|
18008
18029
|
}
|
|
@@ -18018,13 +18039,13 @@ var QrcodeCommandHandler = class {
|
|
|
18018
18039
|
} finally {
|
|
18019
18040
|
rl.close();
|
|
18020
18041
|
}
|
|
18021
|
-
const dir = await
|
|
18042
|
+
const dir = await import_node_fs13.promises.mkdtemp(import_node_path17.default.join(import_node_os6.default.tmpdir(), "pmate-qrcode-"));
|
|
18022
18043
|
const filePath = import_node_path17.default.join(dir, "qrcode.png");
|
|
18023
18044
|
const code = await this.run("screencapture", ["-i", "-x", filePath], true);
|
|
18024
18045
|
if (code !== 0) {
|
|
18025
18046
|
throw new Error("Screenshot capture canceled or failed.");
|
|
18026
18047
|
}
|
|
18027
|
-
const buffer = await
|
|
18048
|
+
const buffer = await import_node_fs13.promises.readFile(filePath);
|
|
18028
18049
|
if (buffer.length === 0) {
|
|
18029
18050
|
throw new Error("Screenshot capture produced an empty file.");
|
|
18030
18051
|
}
|
|
@@ -18040,7 +18061,7 @@ var QrcodeCommandHandler = class {
|
|
|
18040
18061
|
async decodeQr(filePath) {
|
|
18041
18062
|
let buffer;
|
|
18042
18063
|
try {
|
|
18043
|
-
buffer = await
|
|
18064
|
+
buffer = await import_node_fs13.promises.readFile(filePath);
|
|
18044
18065
|
} catch {
|
|
18045
18066
|
return null;
|
|
18046
18067
|
}
|
|
@@ -18300,7 +18321,7 @@ function clampNumber(value, min, max, fallback) {
|
|
|
18300
18321
|
// src/commands/CollectCommandHandler.ts
|
|
18301
18322
|
var import_playwright = require("playwright");
|
|
18302
18323
|
var import_node_crypto3 = require("crypto");
|
|
18303
|
-
var
|
|
18324
|
+
var import_node_fs14 = require("fs");
|
|
18304
18325
|
var import_node_os7 = __toESM(require("os"));
|
|
18305
18326
|
var import_node_path18 = __toESM(require("path"));
|
|
18306
18327
|
var CollectCommandHandler = class {
|
|
@@ -18677,11 +18698,11 @@ async function toDisplayableImagePath(src) {
|
|
|
18677
18698
|
return src;
|
|
18678
18699
|
}
|
|
18679
18700
|
try {
|
|
18680
|
-
const stat = await
|
|
18701
|
+
const stat = await import_node_fs14.promises.stat(src);
|
|
18681
18702
|
if (!stat.isFile()) {
|
|
18682
18703
|
return src;
|
|
18683
18704
|
}
|
|
18684
|
-
const fh = await
|
|
18705
|
+
const fh = await import_node_fs14.promises.open(src, "r");
|
|
18685
18706
|
try {
|
|
18686
18707
|
const buf = Buffer.alloc(32);
|
|
18687
18708
|
const { bytesRead } = await fh.read(buf, 0, 32, 0);
|
|
@@ -18696,11 +18717,11 @@ async function toDisplayableImagePath(src) {
|
|
|
18696
18717
|
"messages",
|
|
18697
18718
|
"images"
|
|
18698
18719
|
);
|
|
18699
|
-
await
|
|
18720
|
+
await import_node_fs14.promises.mkdir(cacheDir, { recursive: true });
|
|
18700
18721
|
const base = (0, import_node_crypto3.createHash)("sha1").update(src).digest("hex");
|
|
18701
18722
|
const displayPath = import_node_path18.default.join(cacheDir, `${base}.${guessedExt}`);
|
|
18702
|
-
await
|
|
18703
|
-
await
|
|
18723
|
+
await import_node_fs14.promises.rm(displayPath, { force: true }).catch(() => void 0);
|
|
18724
|
+
await import_node_fs14.promises.copyFile(src, displayPath);
|
|
18704
18725
|
return displayPath;
|
|
18705
18726
|
} finally {
|
|
18706
18727
|
await fh.close();
|
|
@@ -18756,7 +18777,7 @@ function parseMessageText(raw) {
|
|
|
18756
18777
|
}
|
|
18757
18778
|
|
|
18758
18779
|
// src/commands/AgentCommandHandler.ts
|
|
18759
|
-
var
|
|
18780
|
+
var import_node_fs15 = require("fs");
|
|
18760
18781
|
var import_node_os8 = __toESM(require("os"));
|
|
18761
18782
|
var import_node_path19 = __toESM(require("path"));
|
|
18762
18783
|
var AgentCommandHandler = class {
|
|
@@ -18841,10 +18862,10 @@ var AgentCommandHandler = class {
|
|
|
18841
18862
|
}
|
|
18842
18863
|
readToken() {
|
|
18843
18864
|
const sessionPath = import_node_path19.default.join(import_node_os8.default.homedir(), ".pmate", "session.json");
|
|
18844
|
-
if (!(0,
|
|
18865
|
+
if (!(0, import_node_fs15.existsSync)(sessionPath)) {
|
|
18845
18866
|
throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
|
|
18846
18867
|
}
|
|
18847
|
-
const raw = (0,
|
|
18868
|
+
const raw = (0, import_node_fs15.readFileSync)(sessionPath, "utf8");
|
|
18848
18869
|
const parsed = JSON.parse(raw);
|
|
18849
18870
|
const token = parsed.token?.trim();
|
|
18850
18871
|
if (!token) {
|
|
@@ -18854,10 +18875,10 @@ var AgentCommandHandler = class {
|
|
|
18854
18875
|
}
|
|
18855
18876
|
readJsonFile(filePath) {
|
|
18856
18877
|
const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
|
|
18857
|
-
if (!(0,
|
|
18878
|
+
if (!(0, import_node_fs15.existsSync)(absolutePath)) {
|
|
18858
18879
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
18859
18880
|
}
|
|
18860
|
-
const raw = (0,
|
|
18881
|
+
const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
|
|
18861
18882
|
try {
|
|
18862
18883
|
return JSON.parse(raw);
|
|
18863
18884
|
} catch (error) {
|
|
@@ -18926,7 +18947,7 @@ var AgentCommandHandler = class {
|
|
|
18926
18947
|
};
|
|
18927
18948
|
|
|
18928
18949
|
// src/commands/AppCommandHandler.ts
|
|
18929
|
-
var
|
|
18950
|
+
var import_node_fs16 = require("fs");
|
|
18930
18951
|
var import_node_os9 = __toESM(require("os"));
|
|
18931
18952
|
var import_node_path20 = __toESM(require("path"));
|
|
18932
18953
|
var AppCommandHandler = class {
|
|
@@ -18998,10 +19019,10 @@ var AppCommandHandler = class {
|
|
|
18998
19019
|
}
|
|
18999
19020
|
readToken() {
|
|
19000
19021
|
const sessionPath = import_node_path20.default.join(import_node_os9.default.homedir(), ".pmate", "session.json");
|
|
19001
|
-
if (!(0,
|
|
19022
|
+
if (!(0, import_node_fs16.existsSync)(sessionPath)) {
|
|
19002
19023
|
throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
|
|
19003
19024
|
}
|
|
19004
|
-
const raw = (0,
|
|
19025
|
+
const raw = (0, import_node_fs16.readFileSync)(sessionPath, "utf8");
|
|
19005
19026
|
const parsed = JSON.parse(raw);
|
|
19006
19027
|
const token = parsed.token?.trim();
|
|
19007
19028
|
if (!token) {
|
|
@@ -19011,10 +19032,10 @@ var AppCommandHandler = class {
|
|
|
19011
19032
|
}
|
|
19012
19033
|
readJsonFile(filePath) {
|
|
19013
19034
|
const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
|
|
19014
|
-
if (!(0,
|
|
19035
|
+
if (!(0, import_node_fs16.existsSync)(absolutePath)) {
|
|
19015
19036
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
19016
19037
|
}
|
|
19017
|
-
const raw = (0,
|
|
19038
|
+
const raw = (0, import_node_fs16.readFileSync)(absolutePath, "utf8");
|
|
19018
19039
|
try {
|
|
19019
19040
|
return JSON.parse(raw);
|
|
19020
19041
|
} catch (error) {
|
|
@@ -19431,7 +19452,7 @@ function requireValue2(tokens, optionName) {
|
|
|
19431
19452
|
|
|
19432
19453
|
// src/index.ts
|
|
19433
19454
|
var pkg = JSON.parse(
|
|
19434
|
-
(0,
|
|
19455
|
+
(0, import_node_fs17.readFileSync)(import_node_path21.default.resolve(__dirname, "..", "package.json"), "utf8")
|
|
19435
19456
|
);
|
|
19436
19457
|
var HELP_TEXT = [
|
|
19437
19458
|
import_chalk3.default.bold(`pmate v${pkg.version}`),
|