@pmate/cli 0.25.11 → 0.27.0
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.d.ts +4 -0
- package/dist/index.js +645 -313
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -88,7 +88,7 @@ var init_namespacedRef = __esm({
|
|
|
88
88
|
|
|
89
89
|
// src/sessionStore.ts
|
|
90
90
|
function buildSessionStorePath() {
|
|
91
|
-
return
|
|
91
|
+
return import_node_path4.default.join(import_node_os3.default.homedir(), ".pmate", "session.json");
|
|
92
92
|
}
|
|
93
93
|
function assertValidAppRef(appRef) {
|
|
94
94
|
return parseNamespacedRef(appRef, { entityLabel: "app ref" }).fullId;
|
|
@@ -153,7 +153,7 @@ function loadSessionStore() {
|
|
|
153
153
|
}
|
|
154
154
|
function loadExistingSessionStoreOrEmpty() {
|
|
155
155
|
const sessionPath = buildSessionStorePath();
|
|
156
|
-
if (!(0,
|
|
156
|
+
if (!(0, import_node_fs3.existsSync)(sessionPath)) {
|
|
157
157
|
return {
|
|
158
158
|
version: SESSION_STORE_VERSION,
|
|
159
159
|
activeAppRef: DEFAULT_APP_ID,
|
|
@@ -172,10 +172,10 @@ function loadExistingSessionStoreOrEmpty() {
|
|
|
172
172
|
}
|
|
173
173
|
function loadSessionStoreWithPath() {
|
|
174
174
|
const sessionPath = buildSessionStorePath();
|
|
175
|
-
if (!(0,
|
|
175
|
+
if (!(0, import_node_fs3.existsSync)(sessionPath)) {
|
|
176
176
|
throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
|
|
177
177
|
}
|
|
178
|
-
const raw = (0,
|
|
178
|
+
const raw = (0, import_node_fs3.readFileSync)(sessionPath, "utf8");
|
|
179
179
|
const parsed = JSON.parse(raw);
|
|
180
180
|
const store = normalizeStore(parsed);
|
|
181
181
|
return { sessionPath, store };
|
|
@@ -265,12 +265,12 @@ function resolveReadApp(store, options) {
|
|
|
265
265
|
}
|
|
266
266
|
function writeSessionStore(store) {
|
|
267
267
|
const sessionPath = buildSessionStorePath();
|
|
268
|
-
(0,
|
|
269
|
-
(0,
|
|
268
|
+
(0, import_node_fs3.mkdirSync)(import_node_path4.default.dirname(sessionPath), { recursive: true });
|
|
269
|
+
(0, import_node_fs3.writeFileSync)(sessionPath, JSON.stringify(store, null, 2), {
|
|
270
270
|
mode: 384
|
|
271
271
|
});
|
|
272
272
|
try {
|
|
273
|
-
(0,
|
|
273
|
+
(0, import_node_fs3.chmodSync)(sessionPath, 384);
|
|
274
274
|
} catch {
|
|
275
275
|
}
|
|
276
276
|
}
|
|
@@ -280,13 +280,13 @@ function buildMissingSessionMessage(sessionPath, app) {
|
|
|
280
280
|
}
|
|
281
281
|
return `Missing session for app ${app} in ${sessionPath}. Run "pmate login --app ${app}" first.`;
|
|
282
282
|
}
|
|
283
|
-
var
|
|
283
|
+
var import_node_fs3, import_node_os3, import_node_path4, DEFAULT_APP_ID, SESSION_STORE_VERSION;
|
|
284
284
|
var init_sessionStore = __esm({
|
|
285
285
|
"src/sessionStore.ts"() {
|
|
286
286
|
"use strict";
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
287
|
+
import_node_fs3 = require("fs");
|
|
288
|
+
import_node_os3 = __toESM(require("os"));
|
|
289
|
+
import_node_path4 = __toESM(require("path"));
|
|
290
290
|
init_namespacedRef();
|
|
291
291
|
DEFAULT_APP_ID = "pmate:factory";
|
|
292
292
|
SESSION_STORE_VERSION = 4;
|
|
@@ -8950,14 +8950,14 @@ var init_WebsocketClientV2 = __esm({
|
|
|
8950
8950
|
if (this.reconnectTimer) return;
|
|
8951
8951
|
const base = Math.min(1e3 * 2 ** this.reconnectAttempts, this.maxBackoffMs);
|
|
8952
8952
|
const jitter = Math.floor(Math.random() * 250);
|
|
8953
|
-
const
|
|
8953
|
+
const delay2 = base + jitter;
|
|
8954
8954
|
this.reconnectTimer = globalThis.setTimeout(() => {
|
|
8955
8955
|
if (this.ws && this.ws.readyState === WebSocket.CONNECTING) return;
|
|
8956
8956
|
this.reconnectTimer = void 0;
|
|
8957
8957
|
this.reconnectAttempts++;
|
|
8958
8958
|
logger3.log("Reconnecting... attempt", this.reconnectAttempts);
|
|
8959
8959
|
this.init();
|
|
8960
|
-
},
|
|
8960
|
+
}, delay2);
|
|
8961
8961
|
}
|
|
8962
8962
|
handleHeartbeatTimeout() {
|
|
8963
8963
|
this.close(false);
|
|
@@ -9570,7 +9570,56 @@ var init_AgentTaskManager = __esm({
|
|
|
9570
9570
|
}
|
|
9571
9571
|
});
|
|
9572
9572
|
|
|
9573
|
+
// node_modules/@pmate/agent-sdk/dist/promptMany.js
|
|
9574
|
+
async function mapWithConcurrency(inputs, concurrency, run) {
|
|
9575
|
+
if (!Number.isInteger(concurrency) || concurrency < 1) {
|
|
9576
|
+
throw new Error("concurrency must be a positive integer");
|
|
9577
|
+
}
|
|
9578
|
+
const results = new Array(inputs.length);
|
|
9579
|
+
let nextIndex = 0;
|
|
9580
|
+
const workers = Array.from({ length: Math.min(concurrency, inputs.length) }, async () => {
|
|
9581
|
+
while (nextIndex < inputs.length) {
|
|
9582
|
+
const index = nextIndex;
|
|
9583
|
+
nextIndex += 1;
|
|
9584
|
+
try {
|
|
9585
|
+
results[index] = {
|
|
9586
|
+
ok: true,
|
|
9587
|
+
value: await run(inputs[index], index)
|
|
9588
|
+
};
|
|
9589
|
+
} catch (error) {
|
|
9590
|
+
const candidate = error;
|
|
9591
|
+
results[index] = {
|
|
9592
|
+
ok: false,
|
|
9593
|
+
error: {
|
|
9594
|
+
...typeof candidate?.code === "string" ? { code: candidate.code } : {},
|
|
9595
|
+
message: typeof candidate?.message === "string" ? candidate.message : String(error)
|
|
9596
|
+
}
|
|
9597
|
+
};
|
|
9598
|
+
}
|
|
9599
|
+
}
|
|
9600
|
+
});
|
|
9601
|
+
await Promise.all(workers);
|
|
9602
|
+
return results;
|
|
9603
|
+
}
|
|
9604
|
+
var init_promptMany = __esm({
|
|
9605
|
+
"node_modules/@pmate/agent-sdk/dist/promptMany.js"() {
|
|
9606
|
+
"use strict";
|
|
9607
|
+
}
|
|
9608
|
+
});
|
|
9609
|
+
|
|
9573
9610
|
// node_modules/@pmate/agent-sdk/dist/AgentClient.js
|
|
9611
|
+
function isPromptBatchTerminal(status) {
|
|
9612
|
+
return status === "completed" || status === "failed" || status === "expired" || status === "cancelled";
|
|
9613
|
+
}
|
|
9614
|
+
function delay(ms) {
|
|
9615
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9616
|
+
}
|
|
9617
|
+
function requireBatchResponse(value) {
|
|
9618
|
+
if (value === null) {
|
|
9619
|
+
throw new Error("LLM batch control returned an empty response");
|
|
9620
|
+
}
|
|
9621
|
+
return value;
|
|
9622
|
+
}
|
|
9574
9623
|
function createAgentRequestBody(payload) {
|
|
9575
9624
|
return {
|
|
9576
9625
|
kind: "request",
|
|
@@ -9586,6 +9635,7 @@ var init_AgentClient = __esm({
|
|
|
9586
9635
|
init_AgentConnectionPool();
|
|
9587
9636
|
init_AgentTaskManager();
|
|
9588
9637
|
init_debug();
|
|
9638
|
+
init_promptMany();
|
|
9589
9639
|
logger5 = Logger.getDebugger("AgentClient");
|
|
9590
9640
|
DEFAULT_TIMEOUT_MS = 4e4;
|
|
9591
9641
|
DEFAULT_STREAM_TIMEOUT_MS = 12e4;
|
|
@@ -9636,6 +9686,92 @@ var init_AgentClient = __esm({
|
|
|
9636
9686
|
payload: request.payload
|
|
9637
9687
|
});
|
|
9638
9688
|
}
|
|
9689
|
+
async promptMany(request) {
|
|
9690
|
+
return mapWithConcurrency(request.requests, request.concurrency ?? 10, (item) => this.prompt(item));
|
|
9691
|
+
}
|
|
9692
|
+
async submitPromptBatch(request) {
|
|
9693
|
+
return requireBatchResponse(await this.runInternal({
|
|
9694
|
+
agentId: request.agentId,
|
|
9695
|
+
payload: {
|
|
9696
|
+
__pmateLlmBatch: {
|
|
9697
|
+
operation: "submit",
|
|
9698
|
+
items: request.items,
|
|
9699
|
+
metadata: request.metadata
|
|
9700
|
+
}
|
|
9701
|
+
}
|
|
9702
|
+
}));
|
|
9703
|
+
}
|
|
9704
|
+
async getPromptBatch(request) {
|
|
9705
|
+
return requireBatchResponse(await this.runInternal({
|
|
9706
|
+
agentId: request.agentId,
|
|
9707
|
+
payload: {
|
|
9708
|
+
__pmateLlmBatch: {
|
|
9709
|
+
operation: "get",
|
|
9710
|
+
batchId: request.batchId
|
|
9711
|
+
}
|
|
9712
|
+
}
|
|
9713
|
+
}));
|
|
9714
|
+
}
|
|
9715
|
+
async getPromptBatchResults(request) {
|
|
9716
|
+
return requireBatchResponse(await this.runInternal({
|
|
9717
|
+
agentId: request.agentId,
|
|
9718
|
+
payload: {
|
|
9719
|
+
__pmateLlmBatch: {
|
|
9720
|
+
operation: "results",
|
|
9721
|
+
batchId: request.batchId
|
|
9722
|
+
}
|
|
9723
|
+
}
|
|
9724
|
+
}));
|
|
9725
|
+
}
|
|
9726
|
+
async waitPromptBatch(request) {
|
|
9727
|
+
const pollIntervalMs = request.pollIntervalMs ?? 1e4;
|
|
9728
|
+
const timeoutMs = request.timeoutMs ?? 24 * 60 * 60 * 1e3;
|
|
9729
|
+
if (!Number.isFinite(pollIntervalMs) || pollIntervalMs < 1) {
|
|
9730
|
+
throw new Error("pollIntervalMs must be a positive number");
|
|
9731
|
+
}
|
|
9732
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 1) {
|
|
9733
|
+
throw new Error("timeoutMs must be a positive number");
|
|
9734
|
+
}
|
|
9735
|
+
const deadline = Date.now() + timeoutMs;
|
|
9736
|
+
while (true) {
|
|
9737
|
+
const batch = await this.getPromptBatch(request);
|
|
9738
|
+
if (isPromptBatchTerminal(batch.status)) {
|
|
9739
|
+
return batch;
|
|
9740
|
+
}
|
|
9741
|
+
const remainingMs = deadline - Date.now();
|
|
9742
|
+
if (remainingMs <= 0) {
|
|
9743
|
+
throw new Error(`Timed out waiting for prompt batch "${request.batchId}"; the server-side batch was not cancelled`);
|
|
9744
|
+
}
|
|
9745
|
+
await delay(Math.min(pollIntervalMs, remainingMs));
|
|
9746
|
+
}
|
|
9747
|
+
}
|
|
9748
|
+
async promptBatch(request) {
|
|
9749
|
+
const submitted = await this.submitPromptBatch(request);
|
|
9750
|
+
const completed = await this.waitPromptBatch({
|
|
9751
|
+
agentId: request.agentId,
|
|
9752
|
+
batchId: submitted.id,
|
|
9753
|
+
pollIntervalMs: request.pollIntervalMs,
|
|
9754
|
+
timeoutMs: request.timeoutMs
|
|
9755
|
+
});
|
|
9756
|
+
if (completed.status === "failed" || completed.status === "cancelled") {
|
|
9757
|
+
throw new Error(`Prompt batch "${completed.id}" ended with status "${completed.status}"`);
|
|
9758
|
+
}
|
|
9759
|
+
return this.getPromptBatchResults({
|
|
9760
|
+
agentId: request.agentId,
|
|
9761
|
+
batchId: completed.id
|
|
9762
|
+
});
|
|
9763
|
+
}
|
|
9764
|
+
async cancelPromptBatch(request) {
|
|
9765
|
+
return requireBatchResponse(await this.runInternal({
|
|
9766
|
+
agentId: request.agentId,
|
|
9767
|
+
payload: {
|
|
9768
|
+
__pmateLlmBatch: {
|
|
9769
|
+
operation: "cancel",
|
|
9770
|
+
batchId: request.batchId
|
|
9771
|
+
}
|
|
9772
|
+
}
|
|
9773
|
+
}));
|
|
9774
|
+
}
|
|
9639
9775
|
async generateImage(request) {
|
|
9640
9776
|
return this.runInternal({
|
|
9641
9777
|
agentId: request.agentId,
|
|
@@ -10002,6 +10138,7 @@ var init_dist2 = __esm({
|
|
|
10002
10138
|
init_AgentTaskManager();
|
|
10003
10139
|
init_AgentService();
|
|
10004
10140
|
init_debug();
|
|
10141
|
+
init_promptMany();
|
|
10005
10142
|
init_src5();
|
|
10006
10143
|
}
|
|
10007
10144
|
});
|
|
@@ -10034,7 +10171,7 @@ function unwrapAgentResult(agentId, value) {
|
|
|
10034
10171
|
return value;
|
|
10035
10172
|
}
|
|
10036
10173
|
function resolveMimeType(filePath) {
|
|
10037
|
-
const ext =
|
|
10174
|
+
const ext = import_node_path12.default.extname(filePath).toLowerCase();
|
|
10038
10175
|
switch (ext) {
|
|
10039
10176
|
case ".wav":
|
|
10040
10177
|
return "audio/wav";
|
|
@@ -10054,12 +10191,12 @@ function resolveMimeType(filePath) {
|
|
|
10054
10191
|
return "application/octet-stream";
|
|
10055
10192
|
}
|
|
10056
10193
|
}
|
|
10057
|
-
var
|
|
10194
|
+
var import_node_fs7, import_node_path12, DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_HUB_BASE_URL, DEFAULT_NAMESPACE, DEFAULT_AGENT_PROMPT_TIMEOUT_MS, AgentLlmClient;
|
|
10058
10195
|
var init_AgentLlmClient = __esm({
|
|
10059
10196
|
"src/llm/AgentLlmClient.ts"() {
|
|
10060
10197
|
"use strict";
|
|
10061
|
-
|
|
10062
|
-
|
|
10198
|
+
import_node_fs7 = require("fs");
|
|
10199
|
+
import_node_path12 = __toESM(require("path"));
|
|
10063
10200
|
init_dist2();
|
|
10064
10201
|
init_sessionStore();
|
|
10065
10202
|
DEFAULT_AGENT_API_BASE_URL = "https://agent-api.pmate.chat";
|
|
@@ -10126,7 +10263,7 @@ var init_AgentLlmClient = __esm({
|
|
|
10126
10263
|
params,
|
|
10127
10264
|
minChunkSizeBytes: 0
|
|
10128
10265
|
});
|
|
10129
|
-
const file = (0,
|
|
10266
|
+
const file = (0, import_node_fs7.readFileSync)(filePath);
|
|
10130
10267
|
input.push(new Blob([file], { type: resolveMimeType(filePath) }));
|
|
10131
10268
|
input.end();
|
|
10132
10269
|
return await stream.finish();
|
|
@@ -10151,8 +10288,8 @@ __export(index_exports, {
|
|
|
10151
10288
|
parseCommandArgs: () => parseCommandArgs
|
|
10152
10289
|
});
|
|
10153
10290
|
module.exports = __toCommonJS(index_exports);
|
|
10154
|
-
var
|
|
10155
|
-
var
|
|
10291
|
+
var import_node_fs25 = require("fs");
|
|
10292
|
+
var import_node_path30 = __toESM(require("path"));
|
|
10156
10293
|
var import_chalk4 = __toESM(require("chalk"));
|
|
10157
10294
|
|
|
10158
10295
|
// src/cli.ts
|
|
@@ -10584,8 +10721,67 @@ var ListCommandHandler = class {
|
|
|
10584
10721
|
|
|
10585
10722
|
// src/commands/LoginCommandHandler.ts
|
|
10586
10723
|
var import_node_child_process = require("child_process");
|
|
10724
|
+
var import_node_path5 = __toESM(require("path"));
|
|
10587
10725
|
var import_node_http = require("http");
|
|
10588
10726
|
var import_promises = require("readline/promises");
|
|
10727
|
+
|
|
10728
|
+
// src/accessKeyFile.ts
|
|
10729
|
+
var import_node_fs2 = require("fs");
|
|
10730
|
+
var import_node_os2 = __toESM(require("os"));
|
|
10731
|
+
var import_node_path3 = __toESM(require("path"));
|
|
10732
|
+
function readAccessKeyFile(filePath, options = {}) {
|
|
10733
|
+
const absolutePath = resolveFilePath(filePath, options.cwd);
|
|
10734
|
+
if (!(0, import_node_fs2.existsSync)(absolutePath)) {
|
|
10735
|
+
throw new Error(`Access key file not found: ${absolutePath}`);
|
|
10736
|
+
}
|
|
10737
|
+
let parsed;
|
|
10738
|
+
try {
|
|
10739
|
+
parsed = JSON.parse((0, import_node_fs2.readFileSync)(absolutePath, "utf8"));
|
|
10740
|
+
} catch (error) {
|
|
10741
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10742
|
+
throw new Error(`Invalid JSON in ${absolutePath}: ${message}`);
|
|
10743
|
+
}
|
|
10744
|
+
if (!isAccessKeyFile(parsed)) {
|
|
10745
|
+
throw new Error(`Invalid PMate access key file: ${absolutePath}`);
|
|
10746
|
+
}
|
|
10747
|
+
if (options.expectedApp && parsed.app !== options.expectedApp) {
|
|
10748
|
+
throw new Error(
|
|
10749
|
+
`Access key app mismatch. expected=${options.expectedApp}, received=${parsed.app}`
|
|
10750
|
+
);
|
|
10751
|
+
}
|
|
10752
|
+
return parsed;
|
|
10753
|
+
}
|
|
10754
|
+
function scanAccessKeyFiles(app) {
|
|
10755
|
+
const dir = resolveAccessKeyDir(app);
|
|
10756
|
+
if (!(0, import_node_fs2.existsSync)(dir)) {
|
|
10757
|
+
return [];
|
|
10758
|
+
}
|
|
10759
|
+
return (0, import_node_fs2.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".access-key.json")).map((entry) => import_node_path3.default.join(dir, entry.name)).flatMap((filePath) => {
|
|
10760
|
+
try {
|
|
10761
|
+
return [{ filePath, key: readAccessKeyFile(filePath, { expectedApp: app }) }];
|
|
10762
|
+
} catch {
|
|
10763
|
+
return [];
|
|
10764
|
+
}
|
|
10765
|
+
}).sort((a, b) => a.key.name.localeCompare(b.key.name) || a.filePath.localeCompare(b.filePath));
|
|
10766
|
+
}
|
|
10767
|
+
function resolveAccessKeyDir(app) {
|
|
10768
|
+
return import_node_path3.default.join(homeDir(), ".pmate", "access-keys", app);
|
|
10769
|
+
}
|
|
10770
|
+
function resolveFilePath(filePath, cwd = process.cwd()) {
|
|
10771
|
+
return import_node_path3.default.isAbsolute(filePath) ? filePath : import_node_path3.default.resolve(cwd, filePath);
|
|
10772
|
+
}
|
|
10773
|
+
function homeDir() {
|
|
10774
|
+
return process.env.HOME || process.env.USERPROFILE || import_node_os2.default.homedir() || process.cwd();
|
|
10775
|
+
}
|
|
10776
|
+
function isAccessKeyFile(value) {
|
|
10777
|
+
if (!value || typeof value !== "object") {
|
|
10778
|
+
return false;
|
|
10779
|
+
}
|
|
10780
|
+
const candidate = value;
|
|
10781
|
+
return candidate.type === "pmate-access-key" && candidate.version === 1 && typeof candidate.id === "string" && !!candidate.id.trim() && typeof candidate.app === "string" && !!candidate.app.trim() && typeof candidate.name === "string" && !!candidate.name.trim() && typeof candidate.secret === "string" && !!candidate.secret.trim() && typeof candidate.expiresAt === "string" && !!candidate.expiresAt.trim() && typeof candidate.createdAt === "string" && !!candidate.createdAt.trim();
|
|
10782
|
+
}
|
|
10783
|
+
|
|
10784
|
+
// src/commands/LoginCommandHandler.ts
|
|
10589
10785
|
init_sessionStore();
|
|
10590
10786
|
|
|
10591
10787
|
// src/profileClient.ts
|
|
@@ -10632,7 +10828,6 @@ function resolveAuthApiBaseUrl(value) {
|
|
|
10632
10828
|
|
|
10633
10829
|
// src/commands/LoginCommandHandler.ts
|
|
10634
10830
|
var AUTH_UI_BASE_URL = "https://auth.pmate.chat";
|
|
10635
|
-
var AUTH_API_BASE_URL = DEFAULT_AUTH_API_BASE_URL;
|
|
10636
10831
|
var CALLBACK_PATH = "/pmate-login-callback";
|
|
10637
10832
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
10638
10833
|
function buildHostedLoginUrl(redirectUrl, appId = DEFAULT_APP_ID) {
|
|
@@ -10644,6 +10839,13 @@ function buildHostedLoginUrl(redirectUrl, appId = DEFAULT_APP_ID) {
|
|
|
10644
10839
|
}
|
|
10645
10840
|
var LoginCommandHandler = class {
|
|
10646
10841
|
async handle(args) {
|
|
10842
|
+
if (args.accessKey || args.accessKeyFile || args.accessKeyScan) {
|
|
10843
|
+
await this.handleAccessKeyLogin(args);
|
|
10844
|
+
return;
|
|
10845
|
+
}
|
|
10846
|
+
await this.handleHostedLogin(args);
|
|
10847
|
+
}
|
|
10848
|
+
async handleHostedLogin(args) {
|
|
10647
10849
|
const callback = await this.startCallbackServer();
|
|
10648
10850
|
const appId = assertValidAppRef(args.app?.trim() || DEFAULT_APP_ID);
|
|
10649
10851
|
const loginUrl = buildHostedLoginUrl(callback.redirectUrl, appId);
|
|
@@ -10671,6 +10873,7 @@ var LoginCommandHandler = class {
|
|
|
10671
10873
|
const profileId = await this.resolveProfileId({
|
|
10672
10874
|
appId,
|
|
10673
10875
|
requestedProfileId: args.profileId,
|
|
10876
|
+
selectProfile: args.selectProfile,
|
|
10674
10877
|
profiles
|
|
10675
10878
|
});
|
|
10676
10879
|
savedSession = saveLoginSession({ ...loginResponse, profileId }, appId);
|
|
@@ -10683,8 +10886,28 @@ var LoginCommandHandler = class {
|
|
|
10683
10886
|
);
|
|
10684
10887
|
}
|
|
10685
10888
|
}
|
|
10889
|
+
async handleAccessKeyLogin(args) {
|
|
10890
|
+
const resolved = await this.resolveAccessKeyInput(args);
|
|
10891
|
+
const appId = assertValidAppRef(resolved.app);
|
|
10892
|
+
const loginResponse = await this.exchangeAccessKeySession(resolved.secret, appId);
|
|
10893
|
+
const profiles = await fetchProfiles({
|
|
10894
|
+
token: loginResponse.token,
|
|
10895
|
+
app: appId,
|
|
10896
|
+
accountId: loginResponse.session.identity.accountId
|
|
10897
|
+
});
|
|
10898
|
+
const profileId = await this.resolveProfileId({
|
|
10899
|
+
appId,
|
|
10900
|
+
requestedProfileId: args.profileId,
|
|
10901
|
+
selectProfile: args.selectProfile,
|
|
10902
|
+
profiles
|
|
10903
|
+
});
|
|
10904
|
+
const savedSession = saveLoginSession({ ...loginResponse, profileId }, appId);
|
|
10905
|
+
ui.success(
|
|
10906
|
+
`Logged in to ${savedSession.app}. Session saved to ${savedSession.sessionPath}`
|
|
10907
|
+
);
|
|
10908
|
+
}
|
|
10686
10909
|
async exchangeSession(token, appId) {
|
|
10687
|
-
const response = await fetch(`${
|
|
10910
|
+
const response = await fetch(`${resolveAuthApiBaseUrl()}/session/exchange`, {
|
|
10688
10911
|
method: "POST",
|
|
10689
10912
|
headers: {
|
|
10690
10913
|
"Content-Type": "application/json",
|
|
@@ -10705,6 +10928,88 @@ var LoginCommandHandler = class {
|
|
|
10705
10928
|
}
|
|
10706
10929
|
return resp.data;
|
|
10707
10930
|
}
|
|
10931
|
+
async exchangeAccessKeySession(secret, appId) {
|
|
10932
|
+
const response = await fetch(`${resolveAuthApiBaseUrl()}/access-keys/session`, {
|
|
10933
|
+
method: "POST",
|
|
10934
|
+
headers: {
|
|
10935
|
+
"Content-Type": "application/json",
|
|
10936
|
+
Authorization: `Bearer ${secret}`
|
|
10937
|
+
},
|
|
10938
|
+
body: JSON.stringify({ app: appId })
|
|
10939
|
+
});
|
|
10940
|
+
if (!response.ok) {
|
|
10941
|
+
const detail = await response.text();
|
|
10942
|
+
throw new Error(
|
|
10943
|
+
`Failed to exchange access key session (${response.status}): ${detail || response.statusText}`
|
|
10944
|
+
);
|
|
10945
|
+
}
|
|
10946
|
+
const resp = await response.json();
|
|
10947
|
+
const returnedApp = resp?.data?.session?.identity?.app?.trim();
|
|
10948
|
+
if (!returnedApp || returnedApp !== appId) {
|
|
10949
|
+
throw new Error("Invalid access key session response: app-scoped session mismatch.");
|
|
10950
|
+
}
|
|
10951
|
+
return resp.data;
|
|
10952
|
+
}
|
|
10953
|
+
async resolveAccessKeyInput(args) {
|
|
10954
|
+
if (args.accessKey) {
|
|
10955
|
+
return {
|
|
10956
|
+
app: args.app?.trim() || DEFAULT_APP_ID,
|
|
10957
|
+
secret: args.accessKey.trim()
|
|
10958
|
+
};
|
|
10959
|
+
}
|
|
10960
|
+
if (args.accessKeyFile) {
|
|
10961
|
+
const key = readAccessKeyFile(args.accessKeyFile, {
|
|
10962
|
+
expectedApp: args.app?.trim()
|
|
10963
|
+
});
|
|
10964
|
+
return {
|
|
10965
|
+
app: args.app?.trim() || key.app,
|
|
10966
|
+
secret: key.secret
|
|
10967
|
+
};
|
|
10968
|
+
}
|
|
10969
|
+
const app = assertValidAppRef(args.app?.trim() || DEFAULT_APP_ID);
|
|
10970
|
+
const candidate = await this.selectScannedAccessKey(app);
|
|
10971
|
+
return {
|
|
10972
|
+
app,
|
|
10973
|
+
secret: candidate.key.secret
|
|
10974
|
+
};
|
|
10975
|
+
}
|
|
10976
|
+
async selectScannedAccessKey(app) {
|
|
10977
|
+
const candidates = scanAccessKeyFiles(app);
|
|
10978
|
+
if (candidates.length === 0) {
|
|
10979
|
+
throw new Error(
|
|
10980
|
+
`No access key found for app ${app}. Run "pmate account access-key create --app ${app} ..." or "pmate login --access-key-file <path>".`
|
|
10981
|
+
);
|
|
10982
|
+
}
|
|
10983
|
+
if (candidates.length === 1) {
|
|
10984
|
+
return candidates[0];
|
|
10985
|
+
}
|
|
10986
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
10987
|
+
const files = candidates.map((candidate) => candidate.filePath).join(", ");
|
|
10988
|
+
throw new Error(
|
|
10989
|
+
`Multiple access keys found for app ${app}. Run "pmate login --access-key-file <path>" with one of: ${files}`
|
|
10990
|
+
);
|
|
10991
|
+
}
|
|
10992
|
+
ui.info(`Multiple access keys found for ${app}. Select one:`);
|
|
10993
|
+
candidates.forEach((candidate, index) => {
|
|
10994
|
+
ui.plain(`${index + 1}. ${this.formatAccessKeyLabel(candidate)}`);
|
|
10995
|
+
});
|
|
10996
|
+
const rl = (0, import_promises.createInterface)({
|
|
10997
|
+
input: process.stdin,
|
|
10998
|
+
output: process.stdout
|
|
10999
|
+
});
|
|
11000
|
+
try {
|
|
11001
|
+
while (true) {
|
|
11002
|
+
const answer = (await rl.question("Access key number: ")).trim();
|
|
11003
|
+
const index = Number.parseInt(answer, 10);
|
|
11004
|
+
if (Number.isInteger(index) && index >= 1 && index <= candidates.length) {
|
|
11005
|
+
return candidates[index - 1];
|
|
11006
|
+
}
|
|
11007
|
+
ui.warn(`Enter a number from 1 to ${candidates.length}.`);
|
|
11008
|
+
}
|
|
11009
|
+
} finally {
|
|
11010
|
+
rl.close();
|
|
11011
|
+
}
|
|
11012
|
+
}
|
|
10708
11013
|
async resolveProfileId(input) {
|
|
10709
11014
|
const requestedProfileId = input.requestedProfileId?.trim();
|
|
10710
11015
|
if (requestedProfileId) {
|
|
@@ -10717,7 +11022,7 @@ var LoginCommandHandler = class {
|
|
|
10717
11022
|
if (input.profiles.length === 0) {
|
|
10718
11023
|
throw new Error(`No profile found for app ${input.appId}.`);
|
|
10719
11024
|
}
|
|
10720
|
-
if (input.profiles.length === 1) {
|
|
11025
|
+
if (input.profiles.length === 1 || !input.selectProfile) {
|
|
10721
11026
|
return input.profiles[0].id;
|
|
10722
11027
|
}
|
|
10723
11028
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
@@ -10747,6 +11052,17 @@ var LoginCommandHandler = class {
|
|
|
10747
11052
|
rl.close();
|
|
10748
11053
|
}
|
|
10749
11054
|
}
|
|
11055
|
+
formatAccessKeyLabel(candidate) {
|
|
11056
|
+
const key = candidate.key;
|
|
11057
|
+
const parts = [
|
|
11058
|
+
key.name?.trim(),
|
|
11059
|
+
key.id?.trim(),
|
|
11060
|
+
key.namespace?.trim(),
|
|
11061
|
+
`expires ${key.expiresAt}`,
|
|
11062
|
+
import_node_path5.default.relative(process.cwd(), candidate.filePath)
|
|
11063
|
+
].filter(Boolean);
|
|
11064
|
+
return parts.join(" / ");
|
|
11065
|
+
}
|
|
10750
11066
|
formatProfileLabel(profile) {
|
|
10751
11067
|
const parts = [
|
|
10752
11068
|
profile.nickName?.trim(),
|
|
@@ -10962,8 +11278,8 @@ var import_openapi_client = require("@alicloud/openapi-client");
|
|
|
10962
11278
|
var import_sts20150401 = __toESM(require("@alicloud/sts20150401"));
|
|
10963
11279
|
var import_ali_oss = __toESM(require("ali-oss"));
|
|
10964
11280
|
var import_node_crypto = require("crypto");
|
|
10965
|
-
var
|
|
10966
|
-
var
|
|
11281
|
+
var import_node_fs4 = require("fs");
|
|
11282
|
+
var import_node_path6 = __toESM(require("path"));
|
|
10967
11283
|
|
|
10968
11284
|
// src/certs.ts
|
|
10969
11285
|
var DEFAULT_SSL_CERT_KEY = "pmate-01";
|
|
@@ -11256,7 +11572,7 @@ var AliyunService = class {
|
|
|
11256
11572
|
])
|
|
11257
11573
|
);
|
|
11258
11574
|
for (const filePath of files) {
|
|
11259
|
-
const relativePath =
|
|
11575
|
+
const relativePath = import_node_path6.default.relative(localDir, filePath);
|
|
11260
11576
|
const objectKey = this.toObjectKey(normalizedPrefix, relativePath);
|
|
11261
11577
|
const contentType = this.getContentType(filePath);
|
|
11262
11578
|
const cacheControl = this.getStaticAssetCacheControl(relativePath);
|
|
@@ -11266,7 +11582,7 @@ var AliyunService = class {
|
|
|
11266
11582
|
const options = Object.keys(headers).length > 0 ? { headers } : void 0;
|
|
11267
11583
|
const existing = existingMap.get(objectKey);
|
|
11268
11584
|
if (existing && typeof existing.size === "number" && !cacheControl) {
|
|
11269
|
-
const stat = await
|
|
11585
|
+
const stat = await import_node_fs4.promises.stat(filePath);
|
|
11270
11586
|
if (stat.size === existing.size) {
|
|
11271
11587
|
const etag = this.normalizeEtag(existing.etag);
|
|
11272
11588
|
if (etag && !etag.includes("-")) {
|
|
@@ -11291,7 +11607,7 @@ var AliyunService = class {
|
|
|
11291
11607
|
if (!region) throw new Error("Missing oss.public.region in ~/.pmate/config.yaml.");
|
|
11292
11608
|
if (!accessKeyId) throw new Error("Missing aliyun.ak in ~/.pmate/config.yaml.");
|
|
11293
11609
|
if (!accessKeySecret) throw new Error("Missing aliyun.sk in ~/.pmate/config.yaml.");
|
|
11294
|
-
if (!(0,
|
|
11610
|
+
if (!(0, import_node_fs4.existsSync)(localFile)) {
|
|
11295
11611
|
throw new Error(`File not found: ${localFile}`);
|
|
11296
11612
|
}
|
|
11297
11613
|
const client = new import_ali_oss.default({ region, accessKeyId, accessKeySecret, bucket });
|
|
@@ -11638,10 +11954,10 @@ var AliyunService = class {
|
|
|
11638
11954
|
}
|
|
11639
11955
|
/** Recursively collect file paths under a directory. */
|
|
11640
11956
|
static async collectFiles(dir) {
|
|
11641
|
-
const entries = await
|
|
11957
|
+
const entries = await import_node_fs4.promises.readdir(dir, { withFileTypes: true });
|
|
11642
11958
|
const files = [];
|
|
11643
11959
|
for (const entry of entries) {
|
|
11644
|
-
const fullPath =
|
|
11960
|
+
const fullPath = import_node_path6.default.join(dir, entry.name);
|
|
11645
11961
|
if (entry.isDirectory()) {
|
|
11646
11962
|
files.push(...await this.collectFiles(fullPath));
|
|
11647
11963
|
} else if (entry.isFile()) {
|
|
@@ -11690,7 +12006,7 @@ var AliyunService = class {
|
|
|
11690
12006
|
static getFileMd5(filePath) {
|
|
11691
12007
|
return new Promise((resolve, reject) => {
|
|
11692
12008
|
const hash = (0, import_node_crypto.createHash)("md5");
|
|
11693
|
-
const stream = (0,
|
|
12009
|
+
const stream = (0, import_node_fs4.createReadStream)(filePath);
|
|
11694
12010
|
stream.on("data", (chunk) => {
|
|
11695
12011
|
hash.update(chunk);
|
|
11696
12012
|
});
|
|
@@ -11703,17 +12019,17 @@ var AliyunService = class {
|
|
|
11703
12019
|
});
|
|
11704
12020
|
}
|
|
11705
12021
|
static toObjectKey(prefix, relativePath) {
|
|
11706
|
-
const normalizedPath = relativePath.split(
|
|
12022
|
+
const normalizedPath = relativePath.split(import_node_path6.default.sep).join("/");
|
|
11707
12023
|
if (!prefix) {
|
|
11708
12024
|
return normalizedPath;
|
|
11709
12025
|
}
|
|
11710
12026
|
return `${prefix}/${normalizedPath}`;
|
|
11711
12027
|
}
|
|
11712
12028
|
static getContentType(filePath) {
|
|
11713
|
-
if (
|
|
12029
|
+
if (import_node_path6.default.basename(filePath).toLowerCase() === "apple-app-site-association") {
|
|
11714
12030
|
return "application/json";
|
|
11715
12031
|
}
|
|
11716
|
-
const ext =
|
|
12032
|
+
const ext = import_node_path6.default.extname(filePath).toLowerCase();
|
|
11717
12033
|
switch (ext) {
|
|
11718
12034
|
case ".html":
|
|
11719
12035
|
return "text/html";
|
|
@@ -11756,7 +12072,7 @@ var AliyunService = class {
|
|
|
11756
12072
|
}
|
|
11757
12073
|
static getStaticAssetCacheControl(filePath) {
|
|
11758
12074
|
const normalized = filePath.replace(/\\/g, "/");
|
|
11759
|
-
const base =
|
|
12075
|
+
const base = import_node_path6.default.posix.basename(normalized).toLowerCase();
|
|
11760
12076
|
if (base === "index.html" || base === "200.html" || base === "404.html" || base === "apple-app-site-association") {
|
|
11761
12077
|
return "no-cache, no-store, must-revalidate";
|
|
11762
12078
|
}
|
|
@@ -11973,7 +12289,7 @@ var BucketCommandHandler = class {
|
|
|
11973
12289
|
};
|
|
11974
12290
|
|
|
11975
12291
|
// src/commands/DeleteCommandHandler.ts
|
|
11976
|
-
var
|
|
12292
|
+
var import_node_path7 = __toESM(require("path"));
|
|
11977
12293
|
var import_node_child_process2 = require("child_process");
|
|
11978
12294
|
|
|
11979
12295
|
// src/serverAddress.ts
|
|
@@ -12131,17 +12447,17 @@ var DeleteCommandHandler = class {
|
|
|
12131
12447
|
});
|
|
12132
12448
|
}
|
|
12133
12449
|
resolveCwd(target) {
|
|
12134
|
-
return target ?
|
|
12450
|
+
return target ? import_node_path7.default.resolve(process.cwd(), target) : process.cwd();
|
|
12135
12451
|
}
|
|
12136
12452
|
};
|
|
12137
12453
|
|
|
12138
12454
|
// src/commands/DevCommandHandler.ts
|
|
12139
|
-
var
|
|
12140
|
-
var
|
|
12455
|
+
var import_node_fs5 = require("fs");
|
|
12456
|
+
var import_node_path9 = __toESM(require("path"));
|
|
12141
12457
|
var import_node_child_process3 = require("child_process");
|
|
12142
12458
|
|
|
12143
12459
|
// src/appDir.ts
|
|
12144
|
-
var
|
|
12460
|
+
var import_node_path8 = __toESM(require("path"));
|
|
12145
12461
|
function normalizeRelativeDir(input, appName) {
|
|
12146
12462
|
if (typeof input !== "string") {
|
|
12147
12463
|
throw new Error(`Missing dir for ${appName} in .pmate.yaml`);
|
|
@@ -12154,7 +12470,7 @@ function normalizeRelativeDir(input, appName) {
|
|
|
12154
12470
|
if (unixLike.startsWith("/")) {
|
|
12155
12471
|
throw new Error(`Invalid dir for ${appName} in .pmate.yaml: must be relative`);
|
|
12156
12472
|
}
|
|
12157
|
-
const normalized =
|
|
12473
|
+
const normalized = import_node_path8.default.posix.normalize(unixLike);
|
|
12158
12474
|
if (normalized.startsWith("../") || normalized === "..") {
|
|
12159
12475
|
throw new Error(
|
|
12160
12476
|
`Invalid dir for ${appName} in .pmate.yaml: must stay within repo`
|
|
@@ -12164,7 +12480,7 @@ function normalizeRelativeDir(input, appName) {
|
|
|
12164
12480
|
}
|
|
12165
12481
|
function resolveLocalAppDir(repoRoot, appName, dir) {
|
|
12166
12482
|
const relative = normalizeRelativeDir(dir, appName);
|
|
12167
|
-
return
|
|
12483
|
+
return import_node_path8.default.resolve(repoRoot, relative);
|
|
12168
12484
|
}
|
|
12169
12485
|
function resolveRemoteAppDir(appName, dir) {
|
|
12170
12486
|
return normalizeRelativeDir(dir, appName);
|
|
@@ -12187,8 +12503,8 @@ var DevCommandHandler = class {
|
|
|
12187
12503
|
);
|
|
12188
12504
|
}
|
|
12189
12505
|
const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
|
|
12190
|
-
const packageJsonPath =
|
|
12191
|
-
if (!(0,
|
|
12506
|
+
const packageJsonPath = import_node_path9.default.join(appDir, "package.json");
|
|
12507
|
+
if (!(0, import_node_fs5.existsSync)(packageJsonPath)) {
|
|
12192
12508
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
12193
12509
|
}
|
|
12194
12510
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -12202,13 +12518,13 @@ var DevCommandHandler = class {
|
|
|
12202
12518
|
await this.runCommand("pnpm", ["--filter", pkgName, "run", "dev"], cwd);
|
|
12203
12519
|
}
|
|
12204
12520
|
resolveCwd(target) {
|
|
12205
|
-
return target ?
|
|
12521
|
+
return target ? import_node_path9.default.resolve(process.cwd(), target) : process.cwd();
|
|
12206
12522
|
}
|
|
12207
12523
|
loadConfig(cwd) {
|
|
12208
12524
|
return loadAppConfig(cwd);
|
|
12209
12525
|
}
|
|
12210
12526
|
loadPackageJson(packageJsonPath) {
|
|
12211
|
-
const raw = (0,
|
|
12527
|
+
const raw = (0, import_node_fs5.readFileSync)(packageJsonPath, "utf8");
|
|
12212
12528
|
const parsed = JSON.parse(raw);
|
|
12213
12529
|
if (!parsed || typeof parsed !== "object") {
|
|
12214
12530
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -12236,8 +12552,8 @@ var DevCommandHandler = class {
|
|
|
12236
12552
|
};
|
|
12237
12553
|
|
|
12238
12554
|
// src/commands/OssCommandHandler.ts
|
|
12239
|
-
var
|
|
12240
|
-
var
|
|
12555
|
+
var import_node_fs6 = require("fs");
|
|
12556
|
+
var import_node_path10 = __toESM(require("path"));
|
|
12241
12557
|
var OssCommandHandler = class _OssCommandHandler {
|
|
12242
12558
|
static {
|
|
12243
12559
|
this.DEFAULT_BUCKET = "parrot-static";
|
|
@@ -12254,17 +12570,17 @@ var OssCommandHandler = class _OssCommandHandler {
|
|
|
12254
12570
|
}
|
|
12255
12571
|
return;
|
|
12256
12572
|
}
|
|
12257
|
-
const resolvedFile =
|
|
12573
|
+
const resolvedFile = import_node_path10.default.resolve(process.cwd(), args.filePath);
|
|
12258
12574
|
this.assertFile(resolvedFile);
|
|
12259
12575
|
const objectKey = this.normalizeObjectKey(args.objectKey);
|
|
12260
12576
|
const bucket = this.resolveBucket(args.bucket);
|
|
12261
12577
|
await AliyunService.uploadFile(resolvedFile, bucket, objectKey);
|
|
12262
12578
|
}
|
|
12263
12579
|
assertFile(filePath) {
|
|
12264
|
-
if (!(0,
|
|
12580
|
+
if (!(0, import_node_fs6.existsSync)(filePath)) {
|
|
12265
12581
|
throw new Error(`File not found: ${filePath}`);
|
|
12266
12582
|
}
|
|
12267
|
-
const stat = (0,
|
|
12583
|
+
const stat = (0, import_node_fs6.statSync)(filePath);
|
|
12268
12584
|
if (!stat.isFile()) {
|
|
12269
12585
|
throw new Error(`Not a file: ${filePath}`);
|
|
12270
12586
|
}
|
|
@@ -12286,7 +12602,7 @@ var OssCommandHandler = class _OssCommandHandler {
|
|
|
12286
12602
|
};
|
|
12287
12603
|
|
|
12288
12604
|
// src/commands/EnvCommandHandler.ts
|
|
12289
|
-
var
|
|
12605
|
+
var import_node_path11 = __toESM(require("path"));
|
|
12290
12606
|
var import_node_child_process4 = require("child_process");
|
|
12291
12607
|
|
|
12292
12608
|
// src/shell.ts
|
|
@@ -12370,8 +12686,8 @@ var EnvCommandHandler = class {
|
|
|
12370
12686
|
ui.success(`Set ${envKey} in .env.local`, appName);
|
|
12371
12687
|
}
|
|
12372
12688
|
async listEnvKeys(server, repoDir, appDir, verbose) {
|
|
12373
|
-
const envLocalPath =
|
|
12374
|
-
const envPath =
|
|
12689
|
+
const envLocalPath = import_node_path11.default.posix.join(appDir, ".env.local");
|
|
12690
|
+
const envPath = import_node_path11.default.posix.join(appDir, ".env");
|
|
12375
12691
|
if (verbose) {
|
|
12376
12692
|
const repoPath = `$HOME/${repoDir}`;
|
|
12377
12693
|
ui.info("Env list target", {
|
|
@@ -12464,8 +12780,8 @@ var EnvCommandHandler = class {
|
|
|
12464
12780
|
}
|
|
12465
12781
|
}
|
|
12466
12782
|
async appendEnvLine(server, repoDir, appDir, envKey, envLine, verbose) {
|
|
12467
|
-
const envLocalPath =
|
|
12468
|
-
const envPath =
|
|
12783
|
+
const envLocalPath = import_node_path11.default.posix.join(appDir, ".env.local");
|
|
12784
|
+
const envPath = import_node_path11.default.posix.join(appDir, ".env");
|
|
12469
12785
|
if (verbose) {
|
|
12470
12786
|
const repoPath = `$HOME/${repoDir}`;
|
|
12471
12787
|
ui.info("Env add target", {
|
|
@@ -12513,8 +12829,8 @@ var EnvCommandHandler = class {
|
|
|
12513
12829
|
await this.runRemoteCommand(server, command);
|
|
12514
12830
|
}
|
|
12515
12831
|
async deleteEnvKey(server, repoDir, appDir, envKey, verbose) {
|
|
12516
|
-
const envLocalPath =
|
|
12517
|
-
const envPath =
|
|
12832
|
+
const envLocalPath = import_node_path11.default.posix.join(appDir, ".env.local");
|
|
12833
|
+
const envPath = import_node_path11.default.posix.join(appDir, ".env");
|
|
12518
12834
|
if (verbose) {
|
|
12519
12835
|
const repoPath = `$HOME/${repoDir}`;
|
|
12520
12836
|
ui.info("Env delete target", {
|
|
@@ -13330,7 +13646,7 @@ var CommitCommandHandler = class {
|
|
|
13330
13646
|
|
|
13331
13647
|
// src/commands/SummaryCommandHandler.ts
|
|
13332
13648
|
var import_node_child_process6 = require("child_process");
|
|
13333
|
-
var
|
|
13649
|
+
var import_node_path13 = __toESM(require("path"));
|
|
13334
13650
|
var SummaryCommandHandler = class {
|
|
13335
13651
|
async handle(args) {
|
|
13336
13652
|
const cwd = this.resolveCwd(args.cwd);
|
|
@@ -13515,7 +13831,7 @@ var SummaryCommandHandler = class {
|
|
|
13515
13831
|
return this.runCapture("gh", args, allowFailure, await this.getGhEnv(cwd), cwd);
|
|
13516
13832
|
}
|
|
13517
13833
|
resolveCwd(value) {
|
|
13518
|
-
return value ?
|
|
13834
|
+
return value ? import_node_path13.default.resolve(process.cwd(), value) : process.cwd();
|
|
13519
13835
|
}
|
|
13520
13836
|
};
|
|
13521
13837
|
function truncate2(value, limit) {
|
|
@@ -13528,9 +13844,9 @@ function truncate2(value, limit) {
|
|
|
13528
13844
|
|
|
13529
13845
|
// src/commands/LinearCommandHandler.ts
|
|
13530
13846
|
var import_node_child_process7 = require("child_process");
|
|
13531
|
-
var
|
|
13532
|
-
var
|
|
13533
|
-
var
|
|
13847
|
+
var import_node_fs8 = require("fs");
|
|
13848
|
+
var import_node_os4 = __toESM(require("os"));
|
|
13849
|
+
var import_node_path14 = __toESM(require("path"));
|
|
13534
13850
|
var import_promises3 = require("readline/promises");
|
|
13535
13851
|
var import_openai = __toESM(require("openai"));
|
|
13536
13852
|
var import_sdk = require("@linear/sdk");
|
|
@@ -14414,15 +14730,15 @@ var LinearCommandHandler = class {
|
|
|
14414
14730
|
}
|
|
14415
14731
|
}
|
|
14416
14732
|
getLinearSelectionPath() {
|
|
14417
|
-
return
|
|
14733
|
+
return import_node_path14.default.join(import_node_os4.default.homedir(), ".pmate", "linear-selection.json");
|
|
14418
14734
|
}
|
|
14419
14735
|
readCachedLinearSelection(cwd) {
|
|
14420
14736
|
const selectionPath = this.getLinearSelectionPath();
|
|
14421
|
-
if (!(0,
|
|
14737
|
+
if (!(0, import_node_fs8.existsSync)(selectionPath)) {
|
|
14422
14738
|
return void 0;
|
|
14423
14739
|
}
|
|
14424
14740
|
try {
|
|
14425
|
-
const raw = (0,
|
|
14741
|
+
const raw = (0, import_node_fs8.readFileSync)(selectionPath, "utf8").trim();
|
|
14426
14742
|
if (!raw) return void 0;
|
|
14427
14743
|
const parsed = JSON.parse(raw);
|
|
14428
14744
|
const value = parsed[cwd];
|
|
@@ -14433,12 +14749,12 @@ var LinearCommandHandler = class {
|
|
|
14433
14749
|
}
|
|
14434
14750
|
writeCachedLinearSelection(cwd, title) {
|
|
14435
14751
|
const selectionPath = this.getLinearSelectionPath();
|
|
14436
|
-
const dir =
|
|
14437
|
-
(0,
|
|
14752
|
+
const dir = import_node_path14.default.dirname(selectionPath);
|
|
14753
|
+
(0, import_node_fs8.mkdirSync)(dir, { recursive: true });
|
|
14438
14754
|
let data = {};
|
|
14439
|
-
if ((0,
|
|
14755
|
+
if ((0, import_node_fs8.existsSync)(selectionPath)) {
|
|
14440
14756
|
try {
|
|
14441
|
-
const raw = (0,
|
|
14757
|
+
const raw = (0, import_node_fs8.readFileSync)(selectionPath, "utf8").trim();
|
|
14442
14758
|
if (raw) {
|
|
14443
14759
|
data = JSON.parse(raw);
|
|
14444
14760
|
}
|
|
@@ -14447,7 +14763,7 @@ var LinearCommandHandler = class {
|
|
|
14447
14763
|
}
|
|
14448
14764
|
}
|
|
14449
14765
|
data[cwd] = title;
|
|
14450
|
-
(0,
|
|
14766
|
+
(0, import_node_fs8.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
|
|
14451
14767
|
`, "utf8");
|
|
14452
14768
|
}
|
|
14453
14769
|
async lookupIssue(client, issueRef) {
|
|
@@ -14624,14 +14940,14 @@ var LinearCommandHandler = class {
|
|
|
14624
14940
|
if (process.platform !== "darwin") {
|
|
14625
14941
|
throw new Error("Screenshot capture only supports macOS.");
|
|
14626
14942
|
}
|
|
14627
|
-
const dir = await
|
|
14628
|
-
const filePath =
|
|
14943
|
+
const dir = await import_node_fs8.promises.mkdtemp(import_node_path14.default.join(import_node_os4.default.tmpdir(), "pmate-screenshot-"));
|
|
14944
|
+
const filePath = import_node_path14.default.join(dir, `screenshot-${index}.png`);
|
|
14629
14945
|
try {
|
|
14630
14946
|
const code = await this.run("screencapture", ["-i", "-x", filePath], true);
|
|
14631
14947
|
if (code !== 0) {
|
|
14632
14948
|
throw new Error("Screenshot capture canceled or failed.");
|
|
14633
14949
|
}
|
|
14634
|
-
const buffer = await
|
|
14950
|
+
const buffer = await import_node_fs8.promises.readFile(filePath);
|
|
14635
14951
|
if (buffer.length === 0) {
|
|
14636
14952
|
throw new Error("Screenshot capture produced an empty file.");
|
|
14637
14953
|
}
|
|
@@ -14643,7 +14959,7 @@ var LinearCommandHandler = class {
|
|
|
14643
14959
|
return { buffer, mime, filename: `screenshot-${index}.${extension}` };
|
|
14644
14960
|
} finally {
|
|
14645
14961
|
try {
|
|
14646
|
-
await
|
|
14962
|
+
await import_node_fs8.promises.rm(dir, { recursive: true, force: true });
|
|
14647
14963
|
} catch {
|
|
14648
14964
|
}
|
|
14649
14965
|
}
|
|
@@ -14787,17 +15103,17 @@ var LinearCommandHandler = class {
|
|
|
14787
15103
|
return compact.length > limit ? `${compact.slice(0, limit)}...` : compact;
|
|
14788
15104
|
}
|
|
14789
15105
|
async convertToPng(buffer, ext) {
|
|
14790
|
-
const dir = await
|
|
14791
|
-
const inputPath =
|
|
14792
|
-
const outputPath =
|
|
15106
|
+
const dir = await import_node_fs8.promises.mkdtemp(import_node_path14.default.join(import_node_os4.default.tmpdir(), "pmate-"));
|
|
15107
|
+
const inputPath = import_node_path14.default.join(dir, `clipboard.${ext}`);
|
|
15108
|
+
const outputPath = import_node_path14.default.join(dir, "clipboard.png");
|
|
14793
15109
|
try {
|
|
14794
|
-
await
|
|
15110
|
+
await import_node_fs8.promises.writeFile(inputPath, buffer);
|
|
14795
15111
|
const stderr = await this.runCapture(
|
|
14796
15112
|
"sips",
|
|
14797
15113
|
["-s", "format", "png", inputPath, "--out", outputPath],
|
|
14798
15114
|
true
|
|
14799
15115
|
);
|
|
14800
|
-
const out = await
|
|
15116
|
+
const out = await import_node_fs8.promises.readFile(outputPath);
|
|
14801
15117
|
if (this.detectImageMime(out) !== "image/png") {
|
|
14802
15118
|
throw new Error(
|
|
14803
15119
|
stderr?.trim() ? `Failed to convert clipboard ${ext} to PNG: ${stderr.trim()}` : `Failed to convert clipboard ${ext} to PNG.`
|
|
@@ -14806,7 +15122,7 @@ var LinearCommandHandler = class {
|
|
|
14806
15122
|
return out;
|
|
14807
15123
|
} finally {
|
|
14808
15124
|
try {
|
|
14809
|
-
await
|
|
15125
|
+
await import_node_fs8.promises.rm(dir, { recursive: true, force: true });
|
|
14810
15126
|
} catch {
|
|
14811
15127
|
}
|
|
14812
15128
|
}
|
|
@@ -15100,7 +15416,7 @@ var LinearCommandHandler = class {
|
|
|
15100
15416
|
return this.runCapture("gh", args, allowFailure, await this.getGhEnv(cwd), cwd);
|
|
15101
15417
|
}
|
|
15102
15418
|
resolveCwd(value) {
|
|
15103
|
-
return value ?
|
|
15419
|
+
return value ? import_node_path14.default.resolve(process.cwd(), value) : process.cwd();
|
|
15104
15420
|
}
|
|
15105
15421
|
createOpenAiClient() {
|
|
15106
15422
|
const config = loadPmateConfig();
|
|
@@ -15152,8 +15468,8 @@ function sleep2(ms) {
|
|
|
15152
15468
|
}
|
|
15153
15469
|
|
|
15154
15470
|
// src/commands/NotionCommandHandler.ts
|
|
15155
|
-
var
|
|
15156
|
-
var
|
|
15471
|
+
var import_node_fs9 = require("fs");
|
|
15472
|
+
var import_node_path15 = __toESM(require("path"));
|
|
15157
15473
|
|
|
15158
15474
|
// src/services/NotionService.ts
|
|
15159
15475
|
var NotionService = class {
|
|
@@ -15392,9 +15708,9 @@ ${indent}\`\`\``;
|
|
|
15392
15708
|
static richTextToPlain(richText) {
|
|
15393
15709
|
return richText.map((item) => item.plain_text ?? item.text?.content ?? "").join("").trim();
|
|
15394
15710
|
}
|
|
15395
|
-
static async requestJson(
|
|
15711
|
+
static async requestJson(path31, init) {
|
|
15396
15712
|
const token = this.getToken();
|
|
15397
|
-
const response = await fetch(`${this.baseUrl}${
|
|
15713
|
+
const response = await fetch(`${this.baseUrl}${path31}`, {
|
|
15398
15714
|
method: init.method,
|
|
15399
15715
|
headers: {
|
|
15400
15716
|
Authorization: `Bearer ${token}`,
|
|
@@ -15492,16 +15808,16 @@ var NotionCommandHandler = class {
|
|
|
15492
15808
|
if (!args.filePath) {
|
|
15493
15809
|
return "";
|
|
15494
15810
|
}
|
|
15495
|
-
const resolved =
|
|
15496
|
-
return (0,
|
|
15811
|
+
const resolved = import_node_path15.default.resolve(process.cwd(), args.filePath);
|
|
15812
|
+
return (0, import_node_fs9.readFileSync)(resolved, "utf8");
|
|
15497
15813
|
}
|
|
15498
15814
|
};
|
|
15499
15815
|
|
|
15500
15816
|
// src/commands/QrcodeCommandHandler.ts
|
|
15501
15817
|
var import_node_child_process8 = require("child_process");
|
|
15502
|
-
var
|
|
15503
|
-
var
|
|
15504
|
-
var
|
|
15818
|
+
var import_node_fs10 = require("fs");
|
|
15819
|
+
var import_node_os5 = __toESM(require("os"));
|
|
15820
|
+
var import_node_path16 = __toESM(require("path"));
|
|
15505
15821
|
var import_promises4 = require("readline/promises");
|
|
15506
15822
|
var import_jsqr = __toESM(require("jsqr"));
|
|
15507
15823
|
var import_pngjs = require("pngjs");
|
|
@@ -15527,7 +15843,7 @@ var QrcodeCommandHandler = class {
|
|
|
15527
15843
|
ui.success("QR code value:", value);
|
|
15528
15844
|
} finally {
|
|
15529
15845
|
try {
|
|
15530
|
-
await
|
|
15846
|
+
await import_node_fs10.promises.rm(dir, { recursive: true, force: true });
|
|
15531
15847
|
} catch {
|
|
15532
15848
|
}
|
|
15533
15849
|
}
|
|
@@ -15543,13 +15859,13 @@ var QrcodeCommandHandler = class {
|
|
|
15543
15859
|
} finally {
|
|
15544
15860
|
rl.close();
|
|
15545
15861
|
}
|
|
15546
|
-
const dir = await
|
|
15547
|
-
const filePath =
|
|
15862
|
+
const dir = await import_node_fs10.promises.mkdtemp(import_node_path16.default.join(import_node_os5.default.tmpdir(), "pmate-qrcode-"));
|
|
15863
|
+
const filePath = import_node_path16.default.join(dir, "qrcode.png");
|
|
15548
15864
|
const code = await this.run("screencapture", ["-i", "-x", filePath], true);
|
|
15549
15865
|
if (code !== 0) {
|
|
15550
15866
|
throw new Error("Screenshot capture canceled or failed.");
|
|
15551
15867
|
}
|
|
15552
|
-
const buffer = await
|
|
15868
|
+
const buffer = await import_node_fs10.promises.readFile(filePath);
|
|
15553
15869
|
if (buffer.length === 0) {
|
|
15554
15870
|
throw new Error("Screenshot capture produced an empty file.");
|
|
15555
15871
|
}
|
|
@@ -15565,7 +15881,7 @@ var QrcodeCommandHandler = class {
|
|
|
15565
15881
|
async decodeQr(filePath) {
|
|
15566
15882
|
let buffer;
|
|
15567
15883
|
try {
|
|
15568
|
-
buffer = await
|
|
15884
|
+
buffer = await import_node_fs10.promises.readFile(filePath);
|
|
15569
15885
|
} catch {
|
|
15570
15886
|
return null;
|
|
15571
15887
|
}
|
|
@@ -15823,8 +16139,8 @@ function clampNumber(value, min, max, fallback) {
|
|
|
15823
16139
|
}
|
|
15824
16140
|
|
|
15825
16141
|
// src/commands/QuizCommandHandler.ts
|
|
15826
|
-
var
|
|
15827
|
-
var
|
|
16142
|
+
var import_node_fs11 = require("fs");
|
|
16143
|
+
var import_node_path17 = __toESM(require("path"));
|
|
15828
16144
|
init_sessionStore();
|
|
15829
16145
|
|
|
15830
16146
|
// src/services/QuizService.ts
|
|
@@ -16369,8 +16685,8 @@ var QuizCommandHandler = class {
|
|
|
16369
16685
|
return;
|
|
16370
16686
|
}
|
|
16371
16687
|
if (args.action === "update-meta") {
|
|
16372
|
-
const resolvedFilePath =
|
|
16373
|
-
const metadata = JSON.parse((0,
|
|
16688
|
+
const resolvedFilePath = import_node_path17.default.resolve(process.cwd(), args.filePath);
|
|
16689
|
+
const metadata = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
|
|
16374
16690
|
const result = await updateQuizPaperMetadata({
|
|
16375
16691
|
apiBaseUrl,
|
|
16376
16692
|
linkBaseUrl,
|
|
@@ -16382,8 +16698,8 @@ var QuizCommandHandler = class {
|
|
|
16382
16698
|
return;
|
|
16383
16699
|
}
|
|
16384
16700
|
if (args.action === "append-step") {
|
|
16385
|
-
const resolvedFilePath =
|
|
16386
|
-
const step = JSON.parse((0,
|
|
16701
|
+
const resolvedFilePath = import_node_path17.default.resolve(process.cwd(), args.filePath);
|
|
16702
|
+
const step = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
|
|
16387
16703
|
const result = await appendQuizPaperStep({
|
|
16388
16704
|
apiBaseUrl,
|
|
16389
16705
|
linkBaseUrl,
|
|
@@ -16396,8 +16712,8 @@ var QuizCommandHandler = class {
|
|
|
16396
16712
|
return;
|
|
16397
16713
|
}
|
|
16398
16714
|
if (args.action === "update-step") {
|
|
16399
|
-
const resolvedFilePath =
|
|
16400
|
-
const step = JSON.parse((0,
|
|
16715
|
+
const resolvedFilePath = import_node_path17.default.resolve(process.cwd(), args.filePath);
|
|
16716
|
+
const step = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
|
|
16401
16717
|
step.stepId = args.stepId;
|
|
16402
16718
|
const result = await updateQuizPaperStep({
|
|
16403
16719
|
apiBaseUrl,
|
|
@@ -16460,8 +16776,8 @@ var QuizCommandHandler = class {
|
|
|
16460
16776
|
if (targetIndex < 0) {
|
|
16461
16777
|
throw new Error(`\u672A\u627E\u5230 stepId=${args.stepId}\uFF0C\u65E0\u6CD5\u66F4\u65B0\u8BE5\u9898\u76EE\u3002`);
|
|
16462
16778
|
}
|
|
16463
|
-
const resolvedFilePath =
|
|
16464
|
-
const nextStep = JSON.parse((0,
|
|
16779
|
+
const resolvedFilePath = import_node_path17.default.resolve(process.cwd(), args.filePath);
|
|
16780
|
+
const nextStep = JSON.parse((0, import_node_fs11.readFileSync)(resolvedFilePath, "utf8"));
|
|
16465
16781
|
nextStep.stepId = args.stepId;
|
|
16466
16782
|
const nextSteps = [...basePaper.steps];
|
|
16467
16783
|
nextSteps[targetIndex] = nextStep;
|
|
@@ -16511,9 +16827,9 @@ var QuizCommandHandler = class {
|
|
|
16511
16827
|
};
|
|
16512
16828
|
|
|
16513
16829
|
// src/commands/CollectCommandHandler.ts
|
|
16514
|
-
var
|
|
16515
|
-
var
|
|
16516
|
-
var
|
|
16830
|
+
var import_node_fs13 = require("fs");
|
|
16831
|
+
var import_node_os7 = __toESM(require("os"));
|
|
16832
|
+
var import_node_path19 = __toESM(require("path"));
|
|
16517
16833
|
var import_playwright = require("playwright");
|
|
16518
16834
|
|
|
16519
16835
|
// src/im1BotClient.ts
|
|
@@ -16579,13 +16895,13 @@ var Im1BotClient = class {
|
|
|
16579
16895
|
|
|
16580
16896
|
// src/collectStore.ts
|
|
16581
16897
|
var import_node_crypto3 = require("crypto");
|
|
16582
|
-
var
|
|
16583
|
-
var
|
|
16584
|
-
var
|
|
16898
|
+
var import_node_fs12 = require("fs");
|
|
16899
|
+
var import_node_os6 = __toESM(require("os"));
|
|
16900
|
+
var import_node_path18 = __toESM(require("path"));
|
|
16585
16901
|
function resolveCollectTarget(input) {
|
|
16586
16902
|
const endpoint = input.endpoint ?? (input.source === "cc" ? "http://localhost:9223" : "http://localhost:9222");
|
|
16587
16903
|
const sourceKey = input.source ?? `endpoint-${(0, import_node_crypto3.createHash)("sha1").update(endpoint).digest("hex").slice(0, 8)}`;
|
|
16588
|
-
const rootDir =
|
|
16904
|
+
const rootDir = import_node_path18.default.join(import_node_os6.default.homedir(), ".pmate", "collect", sourceKey);
|
|
16589
16905
|
return { sourceKey, endpoint, rootDir };
|
|
16590
16906
|
}
|
|
16591
16907
|
function toThreadKey(name) {
|
|
@@ -16597,7 +16913,7 @@ function toThreadKey(name) {
|
|
|
16597
16913
|
async function readStoredThread(rootDir, threadKey) {
|
|
16598
16914
|
const filePath = getThreadMetaFilePath(rootDir, threadKey);
|
|
16599
16915
|
try {
|
|
16600
|
-
const raw = await
|
|
16916
|
+
const raw = await import_node_fs12.promises.readFile(filePath, "utf8");
|
|
16601
16917
|
const parsed = JSON.parse(raw);
|
|
16602
16918
|
if ("messages" in parsed && Array.isArray(parsed.messages)) {
|
|
16603
16919
|
return parsed;
|
|
@@ -16615,15 +16931,15 @@ async function writeStoredThread(rootDir, thread) {
|
|
|
16615
16931
|
const metaPath = getThreadMetaFilePath(rootDir, thread.threadKey);
|
|
16616
16932
|
const messagePath = getThreadMessagesFilePath(rootDir, thread.threadKey);
|
|
16617
16933
|
const { messages: messages2, ...meta } = thread;
|
|
16618
|
-
await
|
|
16619
|
-
await
|
|
16934
|
+
await import_node_fs12.promises.mkdir(import_node_path18.default.dirname(metaPath), { recursive: true });
|
|
16935
|
+
await import_node_fs12.promises.writeFile(metaPath, JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
16620
16936
|
const body = messages2.map((message) => JSON.stringify(message)).join("\n");
|
|
16621
|
-
await
|
|
16937
|
+
await import_node_fs12.promises.writeFile(messagePath, `${body}${body ? "\n" : ""}`, "utf8");
|
|
16622
16938
|
}
|
|
16623
16939
|
async function writeStoredIndex(rootDir, index) {
|
|
16624
|
-
await
|
|
16625
|
-
const filePath =
|
|
16626
|
-
await
|
|
16940
|
+
await import_node_fs12.promises.mkdir(rootDir, { recursive: true });
|
|
16941
|
+
const filePath = import_node_path18.default.join(rootDir, "index.json");
|
|
16942
|
+
await import_node_fs12.promises.writeFile(filePath, JSON.stringify(index, null, 2) + "\n", "utf8");
|
|
16627
16943
|
}
|
|
16628
16944
|
function diffMessages(existing, incoming) {
|
|
16629
16945
|
const seenMessageIds = new Set(
|
|
@@ -16697,7 +17013,7 @@ function joinNormalized(values) {
|
|
|
16697
17013
|
async function readStoredMessages(rootDir, threadKey) {
|
|
16698
17014
|
const filePath = getThreadMessagesFilePath(rootDir, threadKey);
|
|
16699
17015
|
try {
|
|
16700
|
-
const raw = await
|
|
17016
|
+
const raw = await import_node_fs12.promises.readFile(filePath, "utf8");
|
|
16701
17017
|
return raw.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => normalizeStoredMessage(JSON.parse(line)));
|
|
16702
17018
|
} catch {
|
|
16703
17019
|
return [];
|
|
@@ -16706,20 +17022,20 @@ async function readStoredMessages(rootDir, threadKey) {
|
|
|
16706
17022
|
async function readLegacyStoredThread(rootDir, threadKey) {
|
|
16707
17023
|
const filePath = getLegacyThreadFilePath(rootDir, threadKey);
|
|
16708
17024
|
try {
|
|
16709
|
-
const raw = await
|
|
17025
|
+
const raw = await import_node_fs12.promises.readFile(filePath, "utf8");
|
|
16710
17026
|
return JSON.parse(raw);
|
|
16711
17027
|
} catch {
|
|
16712
17028
|
return null;
|
|
16713
17029
|
}
|
|
16714
17030
|
}
|
|
16715
17031
|
function getThreadMetaFilePath(rootDir, threadKey) {
|
|
16716
|
-
return
|
|
17032
|
+
return import_node_path18.default.join(rootDir, "threads", `${threadKey}.json`);
|
|
16717
17033
|
}
|
|
16718
17034
|
function getThreadMessagesFilePath(rootDir, threadKey) {
|
|
16719
|
-
return
|
|
17035
|
+
return import_node_path18.default.join(rootDir, "threads", `${threadKey}.jsonl`);
|
|
16720
17036
|
}
|
|
16721
17037
|
function getLegacyThreadFilePath(rootDir, threadKey) {
|
|
16722
|
-
return
|
|
17038
|
+
return import_node_path18.default.join(rootDir, "threads", `${threadKey}.json`);
|
|
16723
17039
|
}
|
|
16724
17040
|
function normalizeStoredMessage(message) {
|
|
16725
17041
|
return {
|
|
@@ -16958,7 +17274,7 @@ var CollectCommandHandler = class {
|
|
|
16958
17274
|
}
|
|
16959
17275
|
async writeSyncReport(rootDir, target, results, failures, syncedAt) {
|
|
16960
17276
|
const syncId = toSyncId(syncedAt);
|
|
16961
|
-
const reportPath =
|
|
17277
|
+
const reportPath = import_node_path19.default.join(rootDir, "syncs", `${syncId}.json`);
|
|
16962
17278
|
const threadReports = results.map((result) => ({
|
|
16963
17279
|
threadKey: result.thread.threadKey,
|
|
16964
17280
|
threadName: result.thread.threadName,
|
|
@@ -16967,8 +17283,8 @@ var CollectCommandHandler = class {
|
|
|
16967
17283
|
addedMessages: result.diff.added,
|
|
16968
17284
|
upgradedMessages: result.diff.upgraded
|
|
16969
17285
|
})).filter((thread) => thread.addedCount > 0 || thread.upgradedCount > 0);
|
|
16970
|
-
await
|
|
16971
|
-
await
|
|
17286
|
+
await import_node_fs13.promises.mkdir(import_node_path19.default.dirname(reportPath), { recursive: true });
|
|
17287
|
+
await import_node_fs13.promises.writeFile(
|
|
16972
17288
|
reportPath,
|
|
16973
17289
|
JSON.stringify(
|
|
16974
17290
|
{
|
|
@@ -17146,19 +17462,19 @@ async function archiveMessageImage(rootDir, attachmentRoot, threadKey, imagePath
|
|
|
17146
17462
|
if (!imagePath || isExternalImageRef(imagePath)) {
|
|
17147
17463
|
return imagePath;
|
|
17148
17464
|
}
|
|
17149
|
-
const normalized =
|
|
17465
|
+
const normalized = import_node_path19.default.posix.normalize(imagePath.replace(/\\/g, "/"));
|
|
17150
17466
|
if (normalized.startsWith("attachments/")) {
|
|
17151
|
-
return
|
|
17467
|
+
return import_node_path19.default.join(rootDir, ...normalized.split("/"));
|
|
17152
17468
|
}
|
|
17153
|
-
if (normalized.startsWith("../") ||
|
|
17469
|
+
if (normalized.startsWith("../") || import_node_path19.default.posix.isAbsolute(normalized)) {
|
|
17154
17470
|
return imagePath;
|
|
17155
17471
|
}
|
|
17156
|
-
const sourcePath =
|
|
17157
|
-
const destinationRelativePath =
|
|
17158
|
-
const destinationPath =
|
|
17472
|
+
const sourcePath = import_node_path19.default.join(attachmentRoot, ...normalized.split("/"));
|
|
17473
|
+
const destinationRelativePath = import_node_path19.default.posix.join("attachments", threadKey, normalized);
|
|
17474
|
+
const destinationPath = import_node_path19.default.join(rootDir, ...destinationRelativePath.split("/"));
|
|
17159
17475
|
try {
|
|
17160
|
-
await
|
|
17161
|
-
await
|
|
17476
|
+
await import_node_fs13.promises.mkdir(import_node_path19.default.dirname(destinationPath), { recursive: true });
|
|
17477
|
+
await import_node_fs13.promises.copyFile(sourcePath, destinationPath);
|
|
17162
17478
|
return destinationPath;
|
|
17163
17479
|
} catch {
|
|
17164
17480
|
return imagePath;
|
|
@@ -17168,7 +17484,7 @@ function resolveLocalAttachmentRoot(sourceKey) {
|
|
|
17168
17484
|
if (sourceKey !== "cc" && sourceKey !== "yelling") {
|
|
17169
17485
|
return null;
|
|
17170
17486
|
}
|
|
17171
|
-
return
|
|
17487
|
+
return import_node_path19.default.join(import_node_os7.default.homedir(), "Library", "Application Support", sourceKey, "attachments.noindex");
|
|
17172
17488
|
}
|
|
17173
17489
|
function isExternalImageRef(imagePath) {
|
|
17174
17490
|
return /^[a-z][a-z0-9+.-]*:/i.test(imagePath);
|
|
@@ -17780,7 +18096,7 @@ function pad2(value) {
|
|
|
17780
18096
|
}
|
|
17781
18097
|
|
|
17782
18098
|
// src/commands/ChatRoomCommandHandler.ts
|
|
17783
|
-
var
|
|
18099
|
+
var import_node_fs14 = require("fs");
|
|
17784
18100
|
var ChatRoomCommandHandler = class {
|
|
17785
18101
|
async handle(args) {
|
|
17786
18102
|
const sdk = await loadChatSdk();
|
|
@@ -17830,8 +18146,8 @@ var ChatRoomCommandHandler = class {
|
|
|
17830
18146
|
const a = await this.connect(sdk, args.botA, args.app, args.hubUrl, args.authBaseUrl);
|
|
17831
18147
|
const b = await this.connect(sdk, args.botB, args.app, args.hubUrl, args.authBaseUrl);
|
|
17832
18148
|
try {
|
|
17833
|
-
const botA = sdk.parsePmateBotKeyJson((0,
|
|
17834
|
-
const botB = sdk.parsePmateBotKeyJson((0,
|
|
18149
|
+
const botA = sdk.parsePmateBotKeyJson((0, import_node_fs14.readFileSync)(args.botA, "utf8"));
|
|
18150
|
+
const botB = sdk.parsePmateBotKeyJson((0, import_node_fs14.readFileSync)(args.botB, "utf8"));
|
|
17835
18151
|
await a.requestFriend({ to: botB.name, message: "smoke friend request" });
|
|
17836
18152
|
await b.acceptFriend({ to: botA.name, message: "smoke friend accept" });
|
|
17837
18153
|
await a.sendDm({ to: botB.name, text: "smoke dm from a" });
|
|
@@ -17850,7 +18166,7 @@ var ChatRoomCommandHandler = class {
|
|
|
17850
18166
|
if (!botPath) {
|
|
17851
18167
|
throw new Error("Missing required option: --bot");
|
|
17852
18168
|
}
|
|
17853
|
-
const botKey = sdk.parsePmateBotKeyJson((0,
|
|
18169
|
+
const botKey = sdk.parsePmateBotKeyJson((0, import_node_fs14.readFileSync)(botPath, "utf8"));
|
|
17854
18170
|
const client = sdk.createChatClient({ appId, botKey, hubUrl, authBaseUrl });
|
|
17855
18171
|
await client.connect();
|
|
17856
18172
|
return client;
|
|
@@ -17862,8 +18178,8 @@ async function loadChatSdk() {
|
|
|
17862
18178
|
}
|
|
17863
18179
|
|
|
17864
18180
|
// src/commands/AgentCommandHandler.ts
|
|
17865
|
-
var
|
|
17866
|
-
var
|
|
18181
|
+
var import_node_fs15 = require("fs");
|
|
18182
|
+
var import_node_path20 = __toESM(require("path"));
|
|
17867
18183
|
init_AgentLlmClient();
|
|
17868
18184
|
init_sessionStore();
|
|
17869
18185
|
|
|
@@ -17896,8 +18212,8 @@ function descriptorPathSegments(descriptor) {
|
|
|
17896
18212
|
return ["chains", normalized.chain, "namespaces", normalized.ns, normalized.kind, normalized.name];
|
|
17897
18213
|
}
|
|
17898
18214
|
function buildPathUrl(baseUrl, pathSegments, query) {
|
|
17899
|
-
const
|
|
17900
|
-
const url = new URL(
|
|
18215
|
+
const path31 = `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}`;
|
|
18216
|
+
const url = new URL(path31, baseUrl);
|
|
17901
18217
|
if (query) {
|
|
17902
18218
|
for (const [key, value] of Object.entries(query)) {
|
|
17903
18219
|
url.searchParams.set(key, String(value));
|
|
@@ -18354,11 +18670,11 @@ var AgentCommandHandler = class {
|
|
|
18354
18670
|
}).token;
|
|
18355
18671
|
}
|
|
18356
18672
|
readJsonFile(filePath) {
|
|
18357
|
-
const absolutePath =
|
|
18358
|
-
if (!(0,
|
|
18673
|
+
const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
|
|
18674
|
+
if (!(0, import_node_fs15.existsSync)(absolutePath)) {
|
|
18359
18675
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
18360
18676
|
}
|
|
18361
|
-
const raw = (0,
|
|
18677
|
+
const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
|
|
18362
18678
|
try {
|
|
18363
18679
|
return JSON.parse(raw);
|
|
18364
18680
|
} catch (error) {
|
|
@@ -18369,14 +18685,14 @@ var AgentCommandHandler = class {
|
|
|
18369
18685
|
readJsonObjectFile(filePath) {
|
|
18370
18686
|
const parsed = this.readJsonFile(filePath);
|
|
18371
18687
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
18372
|
-
const absolutePath =
|
|
18688
|
+
const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
|
|
18373
18689
|
throw new Error(`Invalid JSON in ${absolutePath}: expected an object`);
|
|
18374
18690
|
}
|
|
18375
18691
|
return parsed;
|
|
18376
18692
|
}
|
|
18377
18693
|
tryReadJsonObjectFile(filePath) {
|
|
18378
18694
|
const absolutePath = this.resolveExistingFile(filePath);
|
|
18379
|
-
const raw = (0,
|
|
18695
|
+
const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
|
|
18380
18696
|
try {
|
|
18381
18697
|
const parsed = JSON.parse(raw);
|
|
18382
18698
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -18388,8 +18704,8 @@ var AgentCommandHandler = class {
|
|
|
18388
18704
|
}
|
|
18389
18705
|
}
|
|
18390
18706
|
resolveExistingFile(filePath) {
|
|
18391
|
-
const absolutePath =
|
|
18392
|
-
if (!(0,
|
|
18707
|
+
const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
|
|
18708
|
+
if (!(0, import_node_fs15.existsSync)(absolutePath)) {
|
|
18393
18709
|
throw new Error(`File not found: ${absolutePath}`);
|
|
18394
18710
|
}
|
|
18395
18711
|
return absolutePath;
|
|
@@ -18473,8 +18789,8 @@ var AgentCommandHandler = class {
|
|
|
18473
18789
|
};
|
|
18474
18790
|
|
|
18475
18791
|
// src/commands/RunnerCommandHandler.ts
|
|
18476
|
-
var
|
|
18477
|
-
var
|
|
18792
|
+
var import_node_fs16 = require("fs");
|
|
18793
|
+
var import_node_path21 = __toESM(require("path"));
|
|
18478
18794
|
init_sessionStore();
|
|
18479
18795
|
init_namespacedRef();
|
|
18480
18796
|
var RunnerCommandHandler = class {
|
|
@@ -18569,11 +18885,11 @@ var RunnerCommandHandler = class {
|
|
|
18569
18885
|
}).token;
|
|
18570
18886
|
}
|
|
18571
18887
|
readJsonFile(filePath) {
|
|
18572
|
-
const absolutePath =
|
|
18573
|
-
if (!(0,
|
|
18888
|
+
const absolutePath = import_node_path21.default.resolve(process.cwd(), filePath);
|
|
18889
|
+
if (!(0, import_node_fs16.existsSync)(absolutePath)) {
|
|
18574
18890
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
18575
18891
|
}
|
|
18576
|
-
const raw = (0,
|
|
18892
|
+
const raw = (0, import_node_fs16.readFileSync)(absolutePath, "utf8");
|
|
18577
18893
|
try {
|
|
18578
18894
|
return JSON.parse(raw);
|
|
18579
18895
|
} catch (error) {
|
|
@@ -18692,8 +19008,8 @@ var NsCommandHandler = class {
|
|
|
18692
19008
|
};
|
|
18693
19009
|
|
|
18694
19010
|
// src/commands/StoreCommandHandler.ts
|
|
18695
|
-
var
|
|
18696
|
-
var
|
|
19011
|
+
var import_node_fs17 = require("fs");
|
|
19012
|
+
var import_node_path22 = __toESM(require("path"));
|
|
18697
19013
|
var StoreCommandHandler = class {
|
|
18698
19014
|
async handle(args) {
|
|
18699
19015
|
if (args.scope === "namespace") {
|
|
@@ -18835,11 +19151,11 @@ var StoreCommandHandler = class {
|
|
|
18835
19151
|
return payload.data ?? [];
|
|
18836
19152
|
}
|
|
18837
19153
|
readJsonFile(filePath) {
|
|
18838
|
-
const absolutePath =
|
|
18839
|
-
if (!(0,
|
|
19154
|
+
const absolutePath = import_node_path22.default.resolve(process.cwd(), filePath);
|
|
19155
|
+
if (!(0, import_node_fs17.existsSync)(absolutePath)) {
|
|
18840
19156
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
18841
19157
|
}
|
|
18842
|
-
const raw = (0,
|
|
19158
|
+
const raw = (0, import_node_fs17.readFileSync)(absolutePath, "utf8");
|
|
18843
19159
|
try {
|
|
18844
19160
|
return JSON.parse(raw);
|
|
18845
19161
|
} catch (error) {
|
|
@@ -18891,14 +19207,14 @@ var StoreCommandHandler = class {
|
|
|
18891
19207
|
};
|
|
18892
19208
|
|
|
18893
19209
|
// src/commands/AppCommandHandler.ts
|
|
18894
|
-
var
|
|
18895
|
-
var
|
|
19210
|
+
var import_node_fs19 = require("fs");
|
|
19211
|
+
var import_node_path24 = __toESM(require("path"));
|
|
18896
19212
|
init_sessionStore();
|
|
18897
19213
|
|
|
18898
19214
|
// src/appIcon.ts
|
|
18899
|
-
var
|
|
18900
|
-
var
|
|
18901
|
-
var
|
|
19215
|
+
var import_node_fs18 = require("fs");
|
|
19216
|
+
var import_node_os8 = __toESM(require("os"));
|
|
19217
|
+
var import_node_path23 = __toESM(require("path"));
|
|
18902
19218
|
var import_sharp = __toESM(require("sharp"));
|
|
18903
19219
|
init_namespacedRef();
|
|
18904
19220
|
var ANDROID_ICON_SPECS = [
|
|
@@ -19003,13 +19319,13 @@ function createAppIconExportPlans(input) {
|
|
|
19003
19319
|
if (!input.outDir) {
|
|
19004
19320
|
throw new Error("App icon preset export requires --out-dir.");
|
|
19005
19321
|
}
|
|
19006
|
-
const outDir =
|
|
19007
|
-
(0,
|
|
19322
|
+
const outDir = import_node_path23.default.resolve(input.cwd, input.outDir);
|
|
19323
|
+
(0, import_node_fs18.mkdirSync)(outDir, { recursive: true });
|
|
19008
19324
|
return specs.map((spec) => ({
|
|
19009
19325
|
width: spec.width,
|
|
19010
19326
|
height: spec.height,
|
|
19011
19327
|
format: "png",
|
|
19012
|
-
outputPath:
|
|
19328
|
+
outputPath: import_node_path23.default.join(
|
|
19013
19329
|
outDir,
|
|
19014
19330
|
`${namespace}-${objectId}-${spec.name}-${spec.width}x${spec.height}.png`
|
|
19015
19331
|
)
|
|
@@ -19022,8 +19338,8 @@ function createAppIconExportPlans(input) {
|
|
|
19022
19338
|
if (!input.output) {
|
|
19023
19339
|
throw new Error("Single-size app icon export requires --output.");
|
|
19024
19340
|
}
|
|
19025
|
-
const resolvedOutput =
|
|
19026
|
-
(0,
|
|
19341
|
+
const resolvedOutput = import_node_path23.default.resolve(input.cwd, input.output);
|
|
19342
|
+
(0, import_node_fs18.mkdirSync)(import_node_path23.default.dirname(resolvedOutput), { recursive: true });
|
|
19027
19343
|
return [
|
|
19028
19344
|
{
|
|
19029
19345
|
width: input.width,
|
|
@@ -19037,7 +19353,7 @@ async function exportAppIcon(icon, plans) {
|
|
|
19037
19353
|
const svg = await resolveAppIconSvg(icon);
|
|
19038
19354
|
for (const plan of plans) {
|
|
19039
19355
|
const bytes = await renderAppIcon(svg, plan.width, plan.height, plan.format);
|
|
19040
|
-
(0,
|
|
19356
|
+
(0, import_node_fs18.writeFileSync)(plan.outputPath, bytes);
|
|
19041
19357
|
}
|
|
19042
19358
|
}
|
|
19043
19359
|
async function renderAppIconVariant(input) {
|
|
@@ -19045,9 +19361,9 @@ async function renderAppIconVariant(input) {
|
|
|
19045
19361
|
const bytes = await renderAppIcon(svg, input.width, input.height, input.format);
|
|
19046
19362
|
let outputPath;
|
|
19047
19363
|
if (input.output) {
|
|
19048
|
-
outputPath =
|
|
19049
|
-
(0,
|
|
19050
|
-
(0,
|
|
19364
|
+
outputPath = import_node_path23.default.resolve(input.cwd, input.output);
|
|
19365
|
+
(0, import_node_fs18.mkdirSync)(import_node_path23.default.dirname(outputPath), { recursive: true });
|
|
19366
|
+
(0, import_node_fs18.writeFileSync)(outputPath, bytes);
|
|
19051
19367
|
}
|
|
19052
19368
|
if (input.name) {
|
|
19053
19369
|
return {
|
|
@@ -19068,7 +19384,7 @@ async function renderAppIconVariant(input) {
|
|
|
19068
19384
|
};
|
|
19069
19385
|
}
|
|
19070
19386
|
async function loadAppIconVariantFile(input) {
|
|
19071
|
-
const absolutePath =
|
|
19387
|
+
const absolutePath = import_node_path23.default.resolve(input.cwd, input.filePath);
|
|
19072
19388
|
const format = inferVariantFormatFromPath(absolutePath);
|
|
19073
19389
|
return {
|
|
19074
19390
|
value: input.name ? await uploadAppIconVariantAsset({
|
|
@@ -19077,7 +19393,7 @@ async function loadAppIconVariantFile(input) {
|
|
|
19077
19393
|
name: input.name,
|
|
19078
19394
|
format,
|
|
19079
19395
|
sourcePath: absolutePath
|
|
19080
|
-
}) : createImageDataUrl((0,
|
|
19396
|
+
}) : createImageDataUrl((0, import_node_fs18.readFileSync)(absolutePath), format),
|
|
19081
19397
|
format,
|
|
19082
19398
|
absolutePath
|
|
19083
19399
|
};
|
|
@@ -19136,7 +19452,7 @@ function shouldAutoGenerateDefaultVariant(icon) {
|
|
|
19136
19452
|
return looksLikeSvgMarkup(icon) || looksLikeSvgUrl(icon);
|
|
19137
19453
|
}
|
|
19138
19454
|
function inferVariantFormatFromPath(filePath) {
|
|
19139
|
-
const ext =
|
|
19455
|
+
const ext = import_node_path23.default.extname(filePath).toLowerCase();
|
|
19140
19456
|
switch (ext) {
|
|
19141
19457
|
case ".png":
|
|
19142
19458
|
return "png";
|
|
@@ -19207,13 +19523,13 @@ async function uploadAppIconVariantAsset(input) {
|
|
|
19207
19523
|
await AliyunService.uploadFile(sourcePath, DEFAULT_APP_ICON_VARIANT_BUCKET, objectKey);
|
|
19208
19524
|
} finally {
|
|
19209
19525
|
if (shouldCleanup) {
|
|
19210
|
-
(0,
|
|
19526
|
+
(0, import_node_fs18.rmSync)(import_node_path23.default.dirname(sourcePath), { recursive: true, force: true });
|
|
19211
19527
|
}
|
|
19212
19528
|
}
|
|
19213
19529
|
return `${DEFAULT_APP_ICON_VARIANT_PUBLIC_BASE_URL}/${objectKey}`;
|
|
19214
19530
|
}
|
|
19215
19531
|
function buildAppIconVariantObjectKey(input) {
|
|
19216
|
-
return
|
|
19532
|
+
return import_node_path23.default.posix.join(
|
|
19217
19533
|
"apps",
|
|
19218
19534
|
`${resolveAppIconAssetStem(input.icon, input.appRef)}-${input.name}.${extensionForIconFormat(input.format)}`
|
|
19219
19535
|
);
|
|
@@ -19222,8 +19538,8 @@ function resolveAppIconAssetStem(icon, appRef) {
|
|
|
19222
19538
|
if (icon) {
|
|
19223
19539
|
try {
|
|
19224
19540
|
const url = new URL(icon);
|
|
19225
|
-
const ext =
|
|
19226
|
-
const basename =
|
|
19541
|
+
const ext = import_node_path23.default.posix.extname(url.pathname);
|
|
19542
|
+
const basename = import_node_path23.default.posix.basename(url.pathname, ext);
|
|
19227
19543
|
const normalized = sanitizeAppIconAssetStem(basename);
|
|
19228
19544
|
if (normalized) {
|
|
19229
19545
|
return normalized;
|
|
@@ -19252,9 +19568,9 @@ function writeTempAppIconVariantFile(objectKey, format, bytes) {
|
|
|
19252
19568
|
if (!bytes) {
|
|
19253
19569
|
throw new Error("App icon variant upload requires bytes or a source file.");
|
|
19254
19570
|
}
|
|
19255
|
-
const tempDir = (0,
|
|
19256
|
-
const tempPath =
|
|
19257
|
-
(0,
|
|
19571
|
+
const tempDir = (0, import_node_fs18.mkdtempSync)(import_node_path23.default.join(import_node_os8.default.tmpdir(), "pmate-app-icon-"));
|
|
19572
|
+
const tempPath = import_node_path23.default.join(tempDir, import_node_path23.default.basename(objectKey) || `variant.${extensionForIconFormat(format)}`);
|
|
19573
|
+
(0, import_node_fs18.writeFileSync)(tempPath, bytes);
|
|
19258
19574
|
return tempPath;
|
|
19259
19575
|
}
|
|
19260
19576
|
|
|
@@ -19463,10 +19779,10 @@ var AppCommandHandler = class {
|
|
|
19463
19779
|
}
|
|
19464
19780
|
readJsonFile(filePath) {
|
|
19465
19781
|
const absolutePath = this.resolveFilePath(filePath);
|
|
19466
|
-
if (!(0,
|
|
19782
|
+
if (!(0, import_node_fs19.existsSync)(absolutePath)) {
|
|
19467
19783
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
19468
19784
|
}
|
|
19469
|
-
const raw = (0,
|
|
19785
|
+
const raw = (0, import_node_fs19.readFileSync)(absolutePath, "utf8");
|
|
19470
19786
|
try {
|
|
19471
19787
|
return JSON.parse(raw);
|
|
19472
19788
|
} catch (error) {
|
|
@@ -19476,10 +19792,10 @@ var AppCommandHandler = class {
|
|
|
19476
19792
|
}
|
|
19477
19793
|
async preparePayload(filePath, appRef) {
|
|
19478
19794
|
const absolutePath = this.resolveFilePath(filePath);
|
|
19479
|
-
return prepareAppPayload(this.readJsonFile(filePath),
|
|
19795
|
+
return prepareAppPayload(this.readJsonFile(filePath), import_node_path24.default.dirname(absolutePath), { appRef });
|
|
19480
19796
|
}
|
|
19481
19797
|
resolveFilePath(filePath) {
|
|
19482
|
-
return
|
|
19798
|
+
return import_node_path24.default.resolve(process.cwd(), filePath);
|
|
19483
19799
|
}
|
|
19484
19800
|
async request(baseUrl, token, method, pathname, body) {
|
|
19485
19801
|
const response = await fetch(`${baseUrl}${pathname}`, {
|
|
@@ -19599,18 +19915,18 @@ function readNamespaceFromPayload(payload) {
|
|
|
19599
19915
|
}
|
|
19600
19916
|
|
|
19601
19917
|
// src/commands/ServiceCommandHandler.ts
|
|
19602
|
-
var
|
|
19918
|
+
var import_node_fs22 = require("fs");
|
|
19603
19919
|
var import_promises5 = require("fs/promises");
|
|
19604
|
-
var
|
|
19920
|
+
var import_node_path27 = __toESM(require("path"));
|
|
19605
19921
|
var import_node_child_process11 = require("child_process");
|
|
19606
19922
|
var import_promises6 = require("readline/promises");
|
|
19607
19923
|
|
|
19608
19924
|
// src/services/AndroidApkReleaseService.ts
|
|
19609
19925
|
var import_node_child_process9 = require("child_process");
|
|
19610
19926
|
var import_node_crypto4 = require("crypto");
|
|
19611
|
-
var
|
|
19612
|
-
var
|
|
19613
|
-
var
|
|
19927
|
+
var import_node_fs20 = require("fs");
|
|
19928
|
+
var import_node_os9 = __toESM(require("os"));
|
|
19929
|
+
var import_node_path25 = __toESM(require("path"));
|
|
19614
19930
|
var ANDROID_APK_BUCKET = "parrot-static";
|
|
19615
19931
|
var ANDROID_APK_PUBLIC_BASE_URL = "https://parrot-static.pmate.chat";
|
|
19616
19932
|
var AndroidApkReleaseService = class {
|
|
@@ -19644,7 +19960,7 @@ var AndroidApkReleaseService = class {
|
|
|
19644
19960
|
}
|
|
19645
19961
|
await AliyunService.uploadFile(apkPath, ANDROID_APK_BUCKET, objectKey);
|
|
19646
19962
|
const sha256 = await sha256File(apkPath);
|
|
19647
|
-
const size = (0,
|
|
19963
|
+
const size = (0, import_node_fs20.statSync)(apkPath).size;
|
|
19648
19964
|
const artifact = {
|
|
19649
19965
|
serviceId: service.id,
|
|
19650
19966
|
env: options.env,
|
|
@@ -19682,7 +19998,7 @@ var AndroidApkReleaseService = class {
|
|
|
19682
19998
|
const prefix = `apks/${service.namespace}/${service.name}`;
|
|
19683
19999
|
const objects = await AliyunService.listObjects(ANDROID_APK_BUCKET, prefix);
|
|
19684
20000
|
return objects.filter((item) => item.name.endsWith(".apk")).map((item) => {
|
|
19685
|
-
const versionName =
|
|
20001
|
+
const versionName = import_node_path25.default.basename(item.name, ".apk");
|
|
19686
20002
|
return {
|
|
19687
20003
|
serviceId,
|
|
19688
20004
|
env: options.env ?? "unknown",
|
|
@@ -19705,7 +20021,7 @@ var AndroidApkReleaseService = class {
|
|
|
19705
20021
|
}
|
|
19706
20022
|
}
|
|
19707
20023
|
resolveRepoRoot(service, cwd) {
|
|
19708
|
-
if (cwd) return
|
|
20024
|
+
if (cwd) return import_node_path25.default.resolve(process.cwd(), cwd);
|
|
19709
20025
|
const repository = this.getRepository(service);
|
|
19710
20026
|
if (repository) {
|
|
19711
20027
|
return resolveRepositoryLocalRoot(repository);
|
|
@@ -19717,8 +20033,8 @@ var AndroidApkReleaseService = class {
|
|
|
19717
20033
|
if (!dir) {
|
|
19718
20034
|
throw new Error(`Missing dir for android service ${service.id}`);
|
|
19719
20035
|
}
|
|
19720
|
-
const appDir =
|
|
19721
|
-
if (!(0,
|
|
20036
|
+
const appDir = import_node_path25.default.resolve(repoRoot, dir);
|
|
20037
|
+
if (!(0, import_node_fs20.existsSync)(appDir)) {
|
|
19722
20038
|
throw new Error(`Android app dir not found: ${appDir}`);
|
|
19723
20039
|
}
|
|
19724
20040
|
return appDir;
|
|
@@ -19734,11 +20050,11 @@ var AndroidApkReleaseService = class {
|
|
|
19734
20050
|
return void 0;
|
|
19735
20051
|
}
|
|
19736
20052
|
async runGradleAssembleAndFindApk(repoRoot, appDir, variant) {
|
|
19737
|
-
const gradlew = [
|
|
20053
|
+
const gradlew = [import_node_path25.default.join(appDir, "gradlew"), import_node_path25.default.join(repoRoot, "gradlew")].find((candidate) => (0, import_node_fs20.existsSync)(candidate));
|
|
19738
20054
|
if (!gradlew) {
|
|
19739
20055
|
throw new Error(`Gradle wrapper not found in ${appDir} or ${repoRoot}`);
|
|
19740
20056
|
}
|
|
19741
|
-
const gradleCwd =
|
|
20057
|
+
const gradleCwd = import_node_path25.default.dirname(gradlew);
|
|
19742
20058
|
const normalizedVariant = variant.toLowerCase();
|
|
19743
20059
|
const taskSuffix = `assemble${capitalize(normalizedVariant)}`;
|
|
19744
20060
|
const tasks = [`:app:${taskSuffix}`, taskSuffix];
|
|
@@ -19806,7 +20122,7 @@ function resolveRepositoryLocalRoot(repository) {
|
|
|
19806
20122
|
if (!repoName) {
|
|
19807
20123
|
throw new Error(`Invalid repository: ${repository}`);
|
|
19808
20124
|
}
|
|
19809
|
-
return
|
|
20125
|
+
return import_node_path25.default.join(import_node_os9.default.homedir(), "dev", "pmate", repoName);
|
|
19810
20126
|
}
|
|
19811
20127
|
function bumpAndroidGradleVersionText(source, bump) {
|
|
19812
20128
|
const versionNameMatch = source.match(/(^\s*versionName\s+["'])([^"']+)(["']\s*$)/m) ?? source.match(/(^\s*versionName\s*=\s*["'])([^"']+)(["']\s*$)/m);
|
|
@@ -19862,42 +20178,42 @@ function parseGradleOutputMetadata(source, apkFileName) {
|
|
|
19862
20178
|
}
|
|
19863
20179
|
function bumpAndroidProjectVersion(appDir, bump) {
|
|
19864
20180
|
const candidates = [
|
|
19865
|
-
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
|
|
20181
|
+
import_node_path25.default.join(appDir, "app", "build.gradle.kts"),
|
|
20182
|
+
import_node_path25.default.join(appDir, "app", "build.gradle"),
|
|
20183
|
+
import_node_path25.default.join(appDir, "build.gradle.kts"),
|
|
20184
|
+
import_node_path25.default.join(appDir, "build.gradle")
|
|
19869
20185
|
];
|
|
19870
20186
|
for (const candidate of candidates) {
|
|
19871
|
-
if (!(0,
|
|
19872
|
-
const result = bumpAndroidGradleVersionText((0,
|
|
19873
|
-
(0,
|
|
20187
|
+
if (!(0, import_node_fs20.existsSync)(candidate)) continue;
|
|
20188
|
+
const result = bumpAndroidGradleVersionText((0, import_node_fs20.readFileSync)(candidate, "utf8"), bump);
|
|
20189
|
+
(0, import_node_fs20.writeFileSync)(candidate, result.source);
|
|
19874
20190
|
return { filePath: candidate, ...result };
|
|
19875
20191
|
}
|
|
19876
20192
|
throw new Error(`No Android Gradle version file found under ${appDir}`);
|
|
19877
20193
|
}
|
|
19878
20194
|
function findLatestApk(repoRoot, appDir, variant) {
|
|
19879
20195
|
const dirs = [
|
|
19880
|
-
|
|
19881
|
-
|
|
19882
|
-
|
|
20196
|
+
import_node_path25.default.join(appDir, "app", "build", "outputs", "apk", variant),
|
|
20197
|
+
import_node_path25.default.join(appDir, "build", "outputs", "apk", variant),
|
|
20198
|
+
import_node_path25.default.join(repoRoot, "app", "build", "outputs", "apk", variant)
|
|
19883
20199
|
];
|
|
19884
20200
|
const files = dirs.flatMap((dir) => listApks(dir));
|
|
19885
20201
|
if (files.length === 0) {
|
|
19886
20202
|
throw new Error(`Cannot find APK output for variant ${variant}`);
|
|
19887
20203
|
}
|
|
19888
|
-
files.sort((a, b) => (0,
|
|
20204
|
+
files.sort((a, b) => (0, import_node_fs20.statSync)(b).mtimeMs - (0, import_node_fs20.statSync)(a).mtimeMs);
|
|
19889
20205
|
return files[0];
|
|
19890
20206
|
}
|
|
19891
20207
|
function readGradleOutputMetadata(apkPath) {
|
|
19892
|
-
const metadataPath =
|
|
19893
|
-
if (!(0,
|
|
20208
|
+
const metadataPath = import_node_path25.default.join(import_node_path25.default.dirname(apkPath), "output-metadata.json");
|
|
20209
|
+
if (!(0, import_node_fs20.existsSync)(metadataPath)) {
|
|
19894
20210
|
throw new Error(`Gradle output metadata not found: ${metadataPath}`);
|
|
19895
20211
|
}
|
|
19896
|
-
return parseGradleOutputMetadata((0,
|
|
20212
|
+
return parseGradleOutputMetadata((0, import_node_fs20.readFileSync)(metadataPath, "utf8"), import_node_path25.default.basename(apkPath));
|
|
19897
20213
|
}
|
|
19898
20214
|
function listApks(dir) {
|
|
19899
|
-
if (!(0,
|
|
19900
|
-
return (0,
|
|
20215
|
+
if (!(0, import_node_fs20.existsSync)(dir)) return [];
|
|
20216
|
+
return (0, import_node_fs20.readdirSync)(dir).filter((entry) => entry.endsWith(".apk")).map((entry) => import_node_path25.default.join(dir, entry)).filter((entry) => (0, import_node_fs20.statSync)(entry).isFile());
|
|
19901
20217
|
}
|
|
19902
20218
|
function runCommand(command, args, cwd) {
|
|
19903
20219
|
return new Promise((resolve, reject) => {
|
|
@@ -19931,26 +20247,26 @@ async function runAndroidSdkToolCapture(toolName, args) {
|
|
|
19931
20247
|
return runCommandCapture(toolPath, args);
|
|
19932
20248
|
}
|
|
19933
20249
|
function findAndroidSdkTool(toolName) {
|
|
19934
|
-
const sdkRoots = [process.env.ANDROID_HOME, process.env.ANDROID_SDK_ROOT].filter((item) => Boolean(item)).map((item) =>
|
|
20250
|
+
const sdkRoots = [process.env.ANDROID_HOME, process.env.ANDROID_SDK_ROOT].filter((item) => Boolean(item)).map((item) => import_node_path25.default.resolve(item));
|
|
19935
20251
|
for (const sdkRoot of sdkRoots) {
|
|
19936
|
-
const candidates = toolName === "aapt" ? listVersionedToolCandidates(
|
|
19937
|
-
|
|
19938
|
-
...listVersionedToolCandidates(
|
|
19939
|
-
|
|
20252
|
+
const candidates = toolName === "aapt" ? listVersionedToolCandidates(import_node_path25.default.join(sdkRoot, "build-tools"), toolName) : [
|
|
20253
|
+
import_node_path25.default.join(sdkRoot, "cmdline-tools", "latest", "bin", toolName),
|
|
20254
|
+
...listVersionedToolCandidates(import_node_path25.default.join(sdkRoot, "cmdline-tools"), import_node_path25.default.join("bin", toolName)),
|
|
20255
|
+
import_node_path25.default.join(sdkRoot, "tools", "bin", toolName)
|
|
19940
20256
|
];
|
|
19941
|
-
const match = candidates.find((candidate) => (0,
|
|
20257
|
+
const match = candidates.find((candidate) => (0, import_node_fs20.existsSync)(candidate));
|
|
19942
20258
|
if (match) return match;
|
|
19943
20259
|
}
|
|
19944
20260
|
return void 0;
|
|
19945
20261
|
}
|
|
19946
20262
|
function listVersionedToolCandidates(parentDir, relativeToolPath) {
|
|
19947
|
-
if (!(0,
|
|
19948
|
-
return (0,
|
|
20263
|
+
if (!(0, import_node_fs20.existsSync)(parentDir)) return [];
|
|
20264
|
+
return (0, import_node_fs20.readdirSync)(parentDir).map((entry) => import_node_path25.default.join(parentDir, entry)).filter((entry) => (0, import_node_fs20.statSync)(entry).isDirectory()).sort((a, b) => import_node_path25.default.basename(b).localeCompare(import_node_path25.default.basename(a), void 0, { numeric: true })).map((entry) => import_node_path25.default.join(entry, relativeToolPath));
|
|
19949
20265
|
}
|
|
19950
20266
|
function sha256File(filePath) {
|
|
19951
20267
|
return new Promise((resolve, reject) => {
|
|
19952
20268
|
const hash = (0, import_node_crypto4.createHash)("sha256");
|
|
19953
|
-
const stream = (0,
|
|
20269
|
+
const stream = (0, import_node_fs20.createReadStream)(filePath);
|
|
19954
20270
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
19955
20271
|
stream.on("error", reject);
|
|
19956
20272
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
@@ -19967,9 +20283,9 @@ function capitalize(value) {
|
|
|
19967
20283
|
}
|
|
19968
20284
|
|
|
19969
20285
|
// src/services/ServiceRuntimeRunner.ts
|
|
19970
|
-
var
|
|
19971
|
-
var
|
|
19972
|
-
var
|
|
20286
|
+
var import_node_fs21 = require("fs");
|
|
20287
|
+
var import_node_os10 = __toESM(require("os"));
|
|
20288
|
+
var import_node_path26 = __toESM(require("path"));
|
|
19973
20289
|
var import_node_child_process10 = require("child_process");
|
|
19974
20290
|
var import_node_readline = require("readline");
|
|
19975
20291
|
var import_chalk3 = __toESM(require("chalk"));
|
|
@@ -20142,8 +20458,7 @@ var ServiceRegistryClient = class {
|
|
|
20142
20458
|
}
|
|
20143
20459
|
readToken() {
|
|
20144
20460
|
return readRequiredSession({
|
|
20145
|
-
preferredApp: DEFAULT_APP_ID
|
|
20146
|
-
fallbackToActiveApp: true
|
|
20461
|
+
preferredApp: DEFAULT_APP_ID
|
|
20147
20462
|
}).token;
|
|
20148
20463
|
}
|
|
20149
20464
|
async request(method, pathname) {
|
|
@@ -20433,14 +20748,14 @@ var ServiceRuntimeRunner = class {
|
|
|
20433
20748
|
}
|
|
20434
20749
|
resolveRepoRoot(service, cwd) {
|
|
20435
20750
|
if (cwd) {
|
|
20436
|
-
return
|
|
20751
|
+
return import_node_path26.default.resolve(process.cwd(), cwd);
|
|
20437
20752
|
}
|
|
20438
20753
|
const repository = this.getType(service) === "vite" || this.getType(service) === "static" ? this.getRepoStaticSite(service).repository.trim() : this.getType(service) === "fc" ? this.getFc(service).repository?.trim() : this.getType(service) === "ios" || this.getType(service) === "android" ? void 0 : this.getNetwork(service).repository?.trim();
|
|
20439
20754
|
if (repository) {
|
|
20440
20755
|
const repoName = repository.replace(/\/+$/, "").split("/").pop()?.replace(/\.git$/i, "");
|
|
20441
20756
|
if (repoName) {
|
|
20442
|
-
const candidate =
|
|
20443
|
-
if ((0,
|
|
20757
|
+
const candidate = import_node_path26.default.join(import_node_os10.default.homedir(), "dev", "pmate", repoName);
|
|
20758
|
+
if ((0, import_node_fs21.existsSync)(candidate)) {
|
|
20444
20759
|
return candidate;
|
|
20445
20760
|
}
|
|
20446
20761
|
}
|
|
@@ -20453,13 +20768,13 @@ var ServiceRuntimeRunner = class {
|
|
|
20453
20768
|
if (!dir) {
|
|
20454
20769
|
throw new Error(`Missing service dir for ${service.id}`);
|
|
20455
20770
|
}
|
|
20456
|
-
return
|
|
20771
|
+
return import_node_path26.default.resolve(repoRoot, dir);
|
|
20457
20772
|
}
|
|
20458
20773
|
async deployVite(service, options) {
|
|
20459
20774
|
this.assertDeployableStaticSite(service);
|
|
20460
20775
|
const appDir = this.resolveLocalDir(service, options.cwd);
|
|
20461
|
-
const packageJsonPath =
|
|
20462
|
-
if (!(0,
|
|
20776
|
+
const packageJsonPath = import_node_path26.default.join(appDir, "package.json");
|
|
20777
|
+
if (!(0, import_node_fs21.existsSync)(packageJsonPath)) {
|
|
20463
20778
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
20464
20779
|
}
|
|
20465
20780
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -20474,8 +20789,8 @@ var ServiceRuntimeRunner = class {
|
|
|
20474
20789
|
this.resolveRepoRoot(service, options.cwd),
|
|
20475
20790
|
buildEnv
|
|
20476
20791
|
);
|
|
20477
|
-
const distDir =
|
|
20478
|
-
if (!(0,
|
|
20792
|
+
const distDir = import_node_path26.default.join(appDir, "dist");
|
|
20793
|
+
if (!(0, import_node_fs21.existsSync)(distDir)) {
|
|
20479
20794
|
throw new Error(`No dist directory found at ${distDir}`);
|
|
20480
20795
|
}
|
|
20481
20796
|
const site = this.getSite(service);
|
|
@@ -20488,8 +20803,8 @@ var ServiceRuntimeRunner = class {
|
|
|
20488
20803
|
async deployStatic(service, options) {
|
|
20489
20804
|
this.assertDeployableStaticSite(service);
|
|
20490
20805
|
const appDir = this.resolveLocalDir(service, options.cwd);
|
|
20491
|
-
const srcDir =
|
|
20492
|
-
if (!(0,
|
|
20806
|
+
const srcDir = import_node_path26.default.join(appDir, "src");
|
|
20807
|
+
if (!(0, import_node_fs21.existsSync)(srcDir)) {
|
|
20493
20808
|
throw new Error(`No src directory found at ${srcDir}`);
|
|
20494
20809
|
}
|
|
20495
20810
|
const site = this.getSite(service);
|
|
@@ -20523,8 +20838,8 @@ var ServiceRuntimeRunner = class {
|
|
|
20523
20838
|
this.validateFcConfig(service, fc);
|
|
20524
20839
|
const repoRoot = this.resolveRepoRoot(service);
|
|
20525
20840
|
const appDir = this.resolveLocalDir(service);
|
|
20526
|
-
const packageJsonPath =
|
|
20527
|
-
if (!(0,
|
|
20841
|
+
const packageJsonPath = import_node_path26.default.join(appDir, "package.json");
|
|
20842
|
+
if (!(0, import_node_fs21.existsSync)(packageJsonPath)) {
|
|
20528
20843
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
20529
20844
|
}
|
|
20530
20845
|
const pkg2 = this.loadPackageJson(packageJsonPath);
|
|
@@ -20577,15 +20892,15 @@ var ServiceRuntimeRunner = class {
|
|
|
20577
20892
|
const repoRoot = this.resolveRepoRoot(service, options.cwd);
|
|
20578
20893
|
const appDir = this.resolveLocalDir(service, options.cwd);
|
|
20579
20894
|
await this.ensurePnpmWorkspaceRoot(repoRoot);
|
|
20580
|
-
const configPath =
|
|
20581
|
-
if (!(0,
|
|
20895
|
+
const configPath = import_node_path26.default.join(appDir, fc.configFile ?? "s.yaml");
|
|
20896
|
+
if (!(0, import_node_fs21.existsSync)(configPath)) {
|
|
20582
20897
|
throw new Error(`Missing FC config file at ${configPath}`);
|
|
20583
20898
|
}
|
|
20584
|
-
const packageJsonPath =
|
|
20585
|
-
if (!(0,
|
|
20899
|
+
const packageJsonPath = import_node_path26.default.join(appDir, "package.json");
|
|
20900
|
+
if (!(0, import_node_fs21.existsSync)(packageJsonPath)) {
|
|
20586
20901
|
throw new Error(`No package.json found at ${packageJsonPath}`);
|
|
20587
20902
|
}
|
|
20588
|
-
const rawConfig = (0,
|
|
20903
|
+
const rawConfig = (0, import_node_fs21.readFileSync)(configPath, "utf8");
|
|
20589
20904
|
if (!rawConfig.includes(fc.functionName)) {
|
|
20590
20905
|
throw new Error(`FC config ${configPath} does not mention functionName ${fc.functionName}`);
|
|
20591
20906
|
}
|
|
@@ -20863,7 +21178,7 @@ var ServiceRuntimeRunner = class {
|
|
|
20863
21178
|
const serverAddress = await resolveServerAddress(server);
|
|
20864
21179
|
const templateName = exposeType === "websocket" ? "nginx.ws.template" : "nginx.rest.template";
|
|
20865
21180
|
const templatePath = this.resolveTemplatePath(templateName);
|
|
20866
|
-
const template = (0,
|
|
21181
|
+
const template = (0, import_node_fs21.readFileSync)(templatePath, "utf8");
|
|
20867
21182
|
const host = `${subdomain}.${("domain" in network ? network.domain?.trim() : void 0) || "pmate.chat"}`;
|
|
20868
21183
|
const rendered = template.replace(/\$\{\{PORT\}\}/g, String(port)).replace(/\$\{\{HOSTS\}\}/g, host).replace(/\$\{\{HOST\}\}/g, host);
|
|
20869
21184
|
const remotePath = `/etc/nginx/sites-enabled/${subdomain}.conf`;
|
|
@@ -20895,11 +21210,11 @@ var ServiceRuntimeRunner = class {
|
|
|
20895
21210
|
}
|
|
20896
21211
|
if (config.ensurePackageJson) {
|
|
20897
21212
|
const appDir = this.resolveLocalDir(service, options.cwd);
|
|
20898
|
-
const packageJsonPath =
|
|
20899
|
-
if (!(0,
|
|
21213
|
+
const packageJsonPath = import_node_path26.default.join(appDir, "package.json");
|
|
21214
|
+
if (!(0, import_node_fs21.existsSync)(packageJsonPath)) {
|
|
20900
21215
|
throw new Error(`Missing package.json at ${packageJsonPath}`);
|
|
20901
21216
|
}
|
|
20902
|
-
const pkgStat = (0,
|
|
21217
|
+
const pkgStat = (0, import_node_fs21.statSync)(packageJsonPath);
|
|
20903
21218
|
if (!pkgStat.isFile()) {
|
|
20904
21219
|
throw new Error(`package.json is not a file at ${packageJsonPath}`);
|
|
20905
21220
|
}
|
|
@@ -21328,9 +21643,9 @@ var ServiceRuntimeRunner = class {
|
|
|
21328
21643
|
return tokens;
|
|
21329
21644
|
}
|
|
21330
21645
|
readPathValue(source, pathExpr) {
|
|
21331
|
-
const
|
|
21646
|
+
const path31 = pathExpr.split(".").map((segment) => segment.trim()).filter(Boolean);
|
|
21332
21647
|
let cursor = source;
|
|
21333
|
-
for (const segment of
|
|
21648
|
+
for (const segment of path31) {
|
|
21334
21649
|
if (!cursor || typeof cursor !== "object" || Array.isArray(cursor)) {
|
|
21335
21650
|
return void 0;
|
|
21336
21651
|
}
|
|
@@ -21373,12 +21688,12 @@ var ServiceRuntimeRunner = class {
|
|
|
21373
21688
|
}
|
|
21374
21689
|
resolveTemplatePath(templateName) {
|
|
21375
21690
|
const candidates = [
|
|
21376
|
-
|
|
21377
|
-
|
|
21378
|
-
|
|
21691
|
+
import_node_path26.default.join(__dirname, "..", "templates", templateName),
|
|
21692
|
+
import_node_path26.default.join(__dirname, "..", "src", "templates", templateName),
|
|
21693
|
+
import_node_path26.default.join(__dirname, "templates", templateName)
|
|
21379
21694
|
];
|
|
21380
21695
|
for (const candidate of candidates) {
|
|
21381
|
-
if ((0,
|
|
21696
|
+
if ((0, import_node_fs21.existsSync)(candidate)) {
|
|
21382
21697
|
return candidate;
|
|
21383
21698
|
}
|
|
21384
21699
|
}
|
|
@@ -21410,7 +21725,7 @@ var ServiceRuntimeRunner = class {
|
|
|
21410
21725
|
});
|
|
21411
21726
|
}
|
|
21412
21727
|
loadPackageJson(packageJsonPath) {
|
|
21413
|
-
const raw = (0,
|
|
21728
|
+
const raw = (0, import_node_fs21.readFileSync)(packageJsonPath, "utf8");
|
|
21414
21729
|
const parsed = JSON.parse(raw);
|
|
21415
21730
|
if (!parsed || typeof parsed !== "object") {
|
|
21416
21731
|
throw new Error(`Invalid package.json at ${packageJsonPath}`);
|
|
@@ -21419,7 +21734,7 @@ var ServiceRuntimeRunner = class {
|
|
|
21419
21734
|
}
|
|
21420
21735
|
writePackageJson(packageJsonPath, data) {
|
|
21421
21736
|
const serialized = JSON.stringify(data, null, 2);
|
|
21422
|
-
(0,
|
|
21737
|
+
(0, import_node_fs21.writeFileSync)(packageJsonPath, `${serialized}
|
|
21423
21738
|
`, "utf8");
|
|
21424
21739
|
}
|
|
21425
21740
|
validateFcConfig(service, fc) {
|
|
@@ -21446,8 +21761,8 @@ var ServiceRuntimeRunner = class {
|
|
|
21446
21761
|
}
|
|
21447
21762
|
}
|
|
21448
21763
|
async ensurePnpmWorkspaceRoot(repoRoot) {
|
|
21449
|
-
const workspacePath =
|
|
21450
|
-
if (!(0,
|
|
21764
|
+
const workspacePath = import_node_path26.default.join(repoRoot, "pnpm-workspace.yaml");
|
|
21765
|
+
if (!(0, import_node_fs21.existsSync)(workspacePath)) {
|
|
21451
21766
|
throw new Error(`Missing pnpm-workspace.yaml at ${workspacePath}`);
|
|
21452
21767
|
}
|
|
21453
21768
|
}
|
|
@@ -21521,16 +21836,16 @@ var ServiceRuntimeRunner = class {
|
|
|
21521
21836
|
if (!privateKeyPath) {
|
|
21522
21837
|
throw new Error("Missing ssl.prv in ~/.pmate/config.yaml.");
|
|
21523
21838
|
}
|
|
21524
|
-
if (!(0,
|
|
21839
|
+
if (!(0, import_node_fs21.existsSync)(certificatePath)) {
|
|
21525
21840
|
throw new Error(`SSL certificate file not found: ${certificatePath}`);
|
|
21526
21841
|
}
|
|
21527
|
-
if (!(0,
|
|
21842
|
+
if (!(0, import_node_fs21.existsSync)(privateKeyPath)) {
|
|
21528
21843
|
throw new Error(`SSL private key file not found: ${privateKeyPath}`);
|
|
21529
21844
|
}
|
|
21530
21845
|
return {
|
|
21531
21846
|
certName: host,
|
|
21532
|
-
certificate: (0,
|
|
21533
|
-
privateKey: (0,
|
|
21847
|
+
certificate: (0, import_node_fs21.readFileSync)(certificatePath, "utf8"),
|
|
21848
|
+
privateKey: (0, import_node_fs21.readFileSync)(privateKeyPath, "utf8")
|
|
21534
21849
|
};
|
|
21535
21850
|
}
|
|
21536
21851
|
resolveFcProtocol(fc, certConfig) {
|
|
@@ -21987,7 +22302,7 @@ var ServiceCommandHandler = class {
|
|
|
21987
22302
|
format: "dotenv"
|
|
21988
22303
|
}
|
|
21989
22304
|
);
|
|
21990
|
-
const outputPath =
|
|
22305
|
+
const outputPath = import_node_path27.default.resolve(process.cwd(), args.output);
|
|
21991
22306
|
await (0, import_promises5.writeFile)(outputPath, payload.content, "utf8");
|
|
21992
22307
|
ui.success(`Wrote env file for ${args.appId} to ${outputPath}`);
|
|
21993
22308
|
this.renderJson({ ...payload, output: outputPath }, args.json);
|
|
@@ -22213,11 +22528,11 @@ var ServiceCommandHandler = class {
|
|
|
22213
22528
|
return (baseUrl || process.env.PMATE_APPS_API_BASE_URL || "https://apps-api.pmate.chat").replace(/\/+$/, "");
|
|
22214
22529
|
}
|
|
22215
22530
|
readJsonFile(filePath) {
|
|
22216
|
-
const absolutePath =
|
|
22217
|
-
if (!(0,
|
|
22531
|
+
const absolutePath = import_node_path27.default.resolve(process.cwd(), filePath);
|
|
22532
|
+
if (!(0, import_node_fs22.existsSync)(absolutePath)) {
|
|
22218
22533
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
22219
22534
|
}
|
|
22220
|
-
const raw = (0,
|
|
22535
|
+
const raw = (0, import_node_fs22.readFileSync)(absolutePath, "utf8");
|
|
22221
22536
|
try {
|
|
22222
22537
|
return JSON.parse(raw);
|
|
22223
22538
|
} catch (error) {
|
|
@@ -22977,8 +23292,7 @@ var RoleCommandHandler = class {
|
|
|
22977
23292
|
}
|
|
22978
23293
|
readToken() {
|
|
22979
23294
|
return readRequiredSession({
|
|
22980
|
-
preferredApp: DEFAULT_APP_ID
|
|
22981
|
-
fallbackToActiveApp: true
|
|
23295
|
+
preferredApp: DEFAULT_APP_ID
|
|
22982
23296
|
}).token;
|
|
22983
23297
|
}
|
|
22984
23298
|
async request(baseUrl, token, method, pathname, body) {
|
|
@@ -23026,9 +23340,9 @@ var RoleCommandHandler = class {
|
|
|
23026
23340
|
};
|
|
23027
23341
|
|
|
23028
23342
|
// src/commands/AccountCommandHandler.ts
|
|
23029
|
-
var
|
|
23343
|
+
var import_node_fs23 = require("fs");
|
|
23030
23344
|
var import_node_crypto5 = require("crypto");
|
|
23031
|
-
var
|
|
23345
|
+
var import_node_path28 = __toESM(require("path"));
|
|
23032
23346
|
init_sessionStore();
|
|
23033
23347
|
var AccountCommandHandler = class {
|
|
23034
23348
|
async handle(args) {
|
|
@@ -23036,9 +23350,9 @@ var AccountCommandHandler = class {
|
|
|
23036
23350
|
case "bot-keygen": {
|
|
23037
23351
|
const keyFile = this.generateBotKeyFile(args.app, args.name);
|
|
23038
23352
|
const outPath = args.out ? this.resolveFilePath(args.out) : this.resolveDefaultBotKeyPath(args.app, args.name);
|
|
23039
|
-
(0,
|
|
23040
|
-
(0,
|
|
23041
|
-
(0,
|
|
23353
|
+
(0, import_node_fs23.mkdirSync)(import_node_path28.default.dirname(outPath), { recursive: true });
|
|
23354
|
+
(0, import_node_fs23.writeFileSync)(outPath, JSON.stringify(keyFile, null, 2), { mode: 384 });
|
|
23355
|
+
(0, import_node_fs23.chmodSync)(outPath, 384);
|
|
23042
23356
|
if (!args.json) {
|
|
23043
23357
|
ui.success(`Bot key saved to ${outPath}`);
|
|
23044
23358
|
}
|
|
@@ -23404,8 +23718,7 @@ var AccountCommandHandler = class {
|
|
|
23404
23718
|
}
|
|
23405
23719
|
readToken() {
|
|
23406
23720
|
return readRequiredSession({
|
|
23407
|
-
preferredApp: DEFAULT_APP_ID
|
|
23408
|
-
fallbackToActiveApp: true
|
|
23721
|
+
preferredApp: DEFAULT_APP_ID
|
|
23409
23722
|
}).token;
|
|
23410
23723
|
}
|
|
23411
23724
|
buildAccountViewQuery(args) {
|
|
@@ -23576,10 +23889,10 @@ var AccountCommandHandler = class {
|
|
|
23576
23889
|
throw new Error("Missing visible apps input");
|
|
23577
23890
|
}
|
|
23578
23891
|
const absolutePath = this.resolveFilePath(args.filePath);
|
|
23579
|
-
if (!(0,
|
|
23892
|
+
if (!(0, import_node_fs23.existsSync)(absolutePath)) {
|
|
23580
23893
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
23581
23894
|
}
|
|
23582
|
-
const raw = (0,
|
|
23895
|
+
const raw = (0, import_node_fs23.readFileSync)(absolutePath, "utf8");
|
|
23583
23896
|
let parsed;
|
|
23584
23897
|
try {
|
|
23585
23898
|
parsed = JSON.parse(raw);
|
|
@@ -23593,13 +23906,13 @@ var AccountCommandHandler = class {
|
|
|
23593
23906
|
return parsed;
|
|
23594
23907
|
}
|
|
23595
23908
|
resolveFilePath(filePath) {
|
|
23596
|
-
return
|
|
23909
|
+
return import_node_path28.default.resolve(process.cwd(), filePath);
|
|
23597
23910
|
}
|
|
23598
23911
|
resolveDefaultBotKeyPath(app, name) {
|
|
23599
|
-
return
|
|
23912
|
+
return import_node_path28.default.join(this.homeDir(), ".pmate", "bots", app, `${name}.bot-key.json`);
|
|
23600
23913
|
}
|
|
23601
23914
|
resolveDefaultAccessKeyPath(app, name) {
|
|
23602
|
-
return
|
|
23915
|
+
return import_node_path28.default.join(this.homeDir(), ".pmate", "access-keys", app, `${name}.access-key.json`);
|
|
23603
23916
|
}
|
|
23604
23917
|
homeDir() {
|
|
23605
23918
|
return process.env.HOME || process.env.USERPROFILE || process.cwd();
|
|
@@ -23622,10 +23935,10 @@ var AccountCommandHandler = class {
|
|
|
23622
23935
|
throw new Error("Missing bot key file");
|
|
23623
23936
|
}
|
|
23624
23937
|
const absolutePath = this.resolveFilePath(filePath);
|
|
23625
|
-
if (!(0,
|
|
23938
|
+
if (!(0, import_node_fs23.existsSync)(absolutePath)) {
|
|
23626
23939
|
throw new Error(`Bot key file not found: ${absolutePath}`);
|
|
23627
23940
|
}
|
|
23628
|
-
const parsed = JSON.parse((0,
|
|
23941
|
+
const parsed = JSON.parse((0, import_node_fs23.readFileSync)(absolutePath, "utf8"));
|
|
23629
23942
|
if (parsed.type !== "pmate-bot-key" || parsed.version !== 1 || parsed.algorithm !== "ed25519" || !parsed.publicKey || !parsed.privateKey) {
|
|
23630
23943
|
throw new Error(`Invalid PMate bot key file: ${absolutePath}`);
|
|
23631
23944
|
}
|
|
@@ -23642,10 +23955,10 @@ var AccountCommandHandler = class {
|
|
|
23642
23955
|
throw new Error("Missing access key file");
|
|
23643
23956
|
}
|
|
23644
23957
|
const absolutePath = this.resolveFilePath(filePath);
|
|
23645
|
-
if (!(0,
|
|
23958
|
+
if (!(0, import_node_fs23.existsSync)(absolutePath)) {
|
|
23646
23959
|
throw new Error(`Access key file not found: ${absolutePath}`);
|
|
23647
23960
|
}
|
|
23648
|
-
const parsed = JSON.parse((0,
|
|
23961
|
+
const parsed = JSON.parse((0, import_node_fs23.readFileSync)(absolutePath, "utf8"));
|
|
23649
23962
|
if (parsed.type !== "pmate-access-key" || parsed.version !== 1 || !parsed.id || !parsed.app || !parsed.secret || !parsed.expiresAt) {
|
|
23650
23963
|
throw new Error(`Invalid PMate access key file: ${absolutePath}`);
|
|
23651
23964
|
}
|
|
@@ -23667,9 +23980,9 @@ var AccountCommandHandler = class {
|
|
|
23667
23980
|
createdAt: result.key.createdAt
|
|
23668
23981
|
};
|
|
23669
23982
|
const outPath = out ? this.resolveFilePath(out) : this.resolveDefaultAccessKeyPath(result.key.app, result.key.name);
|
|
23670
|
-
(0,
|
|
23671
|
-
(0,
|
|
23672
|
-
(0,
|
|
23983
|
+
(0, import_node_fs23.mkdirSync)(import_node_path28.default.dirname(outPath), { recursive: true });
|
|
23984
|
+
(0, import_node_fs23.writeFileSync)(outPath, JSON.stringify(keyFile, null, 2), { mode: 384 });
|
|
23985
|
+
(0, import_node_fs23.chmodSync)(outPath, 384);
|
|
23673
23986
|
}
|
|
23674
23987
|
renderAccessKeyCreateResult(result, asJson, out) {
|
|
23675
23988
|
if (asJson) {
|
|
@@ -23709,16 +24022,12 @@ var AccountCommandHandler = class {
|
|
|
23709
24022
|
}
|
|
23710
24023
|
}
|
|
23711
24024
|
async resolveLoginProfileId(login, app, authApiBaseUrl) {
|
|
23712
|
-
|
|
23713
|
-
|
|
23714
|
-
|
|
23715
|
-
|
|
23716
|
-
|
|
23717
|
-
|
|
23718
|
-
});
|
|
23719
|
-
} catch {
|
|
23720
|
-
return login.session.identity.accessKeyId ?? login.session.identity.accountId;
|
|
23721
|
-
}
|
|
24025
|
+
return await fetchDefaultProfileId({
|
|
24026
|
+
token: login.token,
|
|
24027
|
+
app,
|
|
24028
|
+
accountId: login.session.identity.accountId,
|
|
24029
|
+
authApiBaseUrl
|
|
24030
|
+
});
|
|
23722
24031
|
}
|
|
23723
24032
|
signBotChallenge(challenge, privateKey) {
|
|
23724
24033
|
const key = (0, import_node_crypto5.createPrivateKey)({
|
|
@@ -23760,8 +24069,8 @@ function encodePathSegment2(value) {
|
|
|
23760
24069
|
}
|
|
23761
24070
|
|
|
23762
24071
|
// src/commands/OrgCommandHandler.ts
|
|
23763
|
-
var
|
|
23764
|
-
var
|
|
24072
|
+
var import_node_fs24 = require("fs");
|
|
24073
|
+
var import_node_path29 = __toESM(require("path"));
|
|
23765
24074
|
init_sessionStore();
|
|
23766
24075
|
var OrgCommandHandler = class {
|
|
23767
24076
|
async handle(args) {
|
|
@@ -23921,8 +24230,7 @@ var OrgCommandHandler = class {
|
|
|
23921
24230
|
}
|
|
23922
24231
|
readToken() {
|
|
23923
24232
|
return readRequiredSession({
|
|
23924
|
-
preferredApp: DEFAULT_APP_ID
|
|
23925
|
-
fallbackToActiveApp: true
|
|
24233
|
+
preferredApp: DEFAULT_APP_ID
|
|
23926
24234
|
}).token;
|
|
23927
24235
|
}
|
|
23928
24236
|
resolveStringArrayInput(values, filePath, itemLabel) {
|
|
@@ -23932,11 +24240,11 @@ var OrgCommandHandler = class {
|
|
|
23932
24240
|
if (!filePath) {
|
|
23933
24241
|
throw new Error(`Missing ${itemLabel} input`);
|
|
23934
24242
|
}
|
|
23935
|
-
const absolutePath =
|
|
23936
|
-
if (!(0,
|
|
24243
|
+
const absolutePath = import_node_path29.default.resolve(process.cwd(), filePath);
|
|
24244
|
+
if (!(0, import_node_fs24.existsSync)(absolutePath)) {
|
|
23937
24245
|
throw new Error(`JSON file not found: ${absolutePath}`);
|
|
23938
24246
|
}
|
|
23939
|
-
const raw = (0,
|
|
24247
|
+
const raw = (0, import_node_fs24.readFileSync)(absolutePath, "utf8");
|
|
23940
24248
|
let parsed;
|
|
23941
24249
|
try {
|
|
23942
24250
|
parsed = JSON.parse(raw);
|
|
@@ -27332,7 +27640,7 @@ function requireValue12(tokens, option) {
|
|
|
27332
27640
|
|
|
27333
27641
|
// src/index.ts
|
|
27334
27642
|
var pkg = JSON.parse(
|
|
27335
|
-
(0,
|
|
27643
|
+
(0, import_node_fs25.readFileSync)(import_node_path30.default.resolve(__dirname, "..", "package.json"), "utf8")
|
|
27336
27644
|
);
|
|
27337
27645
|
var HELP_TEXT = [
|
|
27338
27646
|
import_chalk4.default.bold(`pmate v${pkg.version}`),
|
|
@@ -27348,7 +27656,8 @@ var HELP_TEXT = [
|
|
|
27348
27656
|
import_chalk4.default.bold("Commands:"),
|
|
27349
27657
|
` ${import_chalk4.default.cyan("list [path]")} List apps from .pmate.yaml in the target folder`,
|
|
27350
27658
|
` ${import_chalk4.default.cyan("login")} Log in and store a session in ~/.pmate/session.json`,
|
|
27351
|
-
` ${import_chalk4.default.gray(" [--app <app-id>] [--profile-id <id>]")}`,
|
|
27659
|
+
` ${import_chalk4.default.gray(" [--app <app-id>] [--profile-id <id>] [--select-profile]")}`,
|
|
27660
|
+
` ${import_chalk4.default.gray(" [--access-key [secret] | --access-key-file <path>]")}`,
|
|
27352
27661
|
` ${import_chalk4.default.cyan("add-dns")} Add a DNS record via Aliyun DNS`,
|
|
27353
27662
|
` ${import_chalk4.default.gray(" --type <t> --value <v> --rr <rr> [--ttl <n>] [--domain <name>]")}`,
|
|
27354
27663
|
` ${import_chalk4.default.cyan("sts")} Request an OSS STS token from the CI server`,
|
|
@@ -27581,6 +27890,10 @@ function parseCommandArgs(args) {
|
|
|
27581
27890
|
const rest = args.rest.slice(1);
|
|
27582
27891
|
let app;
|
|
27583
27892
|
let profileId;
|
|
27893
|
+
let accessKey;
|
|
27894
|
+
let accessKeyFile;
|
|
27895
|
+
let accessKeyScan = false;
|
|
27896
|
+
let selectProfile = false;
|
|
27584
27897
|
while (rest.length > 0) {
|
|
27585
27898
|
const token = rest.shift();
|
|
27586
27899
|
switch (token) {
|
|
@@ -27590,11 +27903,30 @@ function parseCommandArgs(args) {
|
|
|
27590
27903
|
case "--profile-id":
|
|
27591
27904
|
profileId = requireValue13(rest, token);
|
|
27592
27905
|
break;
|
|
27906
|
+
case "--access-key":
|
|
27907
|
+
if (rest[0] && !rest[0].startsWith("--")) {
|
|
27908
|
+
accessKey = rest.shift();
|
|
27909
|
+
} else {
|
|
27910
|
+
accessKeyScan = true;
|
|
27911
|
+
}
|
|
27912
|
+
break;
|
|
27913
|
+
case "--access-key-file":
|
|
27914
|
+
accessKeyFile = requireValue13(rest, token);
|
|
27915
|
+
break;
|
|
27916
|
+
case "--select-profile":
|
|
27917
|
+
selectProfile = true;
|
|
27918
|
+
break;
|
|
27593
27919
|
default:
|
|
27594
27920
|
throw new Error(`Unknown login option: ${token}`);
|
|
27595
27921
|
}
|
|
27596
27922
|
}
|
|
27597
|
-
|
|
27923
|
+
if (accessKey && accessKeyFile) {
|
|
27924
|
+
throw new Error("--access-key and --access-key-file are mutually exclusive");
|
|
27925
|
+
}
|
|
27926
|
+
if (accessKeyScan && accessKeyFile) {
|
|
27927
|
+
throw new Error("--access-key and --access-key-file are mutually exclusive");
|
|
27928
|
+
}
|
|
27929
|
+
return { type: "login" /* Login */, app, profileId, accessKey, accessKeyFile, accessKeyScan, selectProfile };
|
|
27598
27930
|
}
|
|
27599
27931
|
if (args.rest[0] === "add-dns") {
|
|
27600
27932
|
return parseAddDnsArgs(args.rest.slice(1));
|