@pmate/cli 0.13.3 → 0.14.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.
Files changed (3) hide show
  1. package/README.md +9 -3
  2. package/dist/index.js +286 -188
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -149,9 +149,15 @@ pmate linear pr --account work
149
149
 
150
150
  ## Auth session
151
151
 
152
- `pmate login` stores a session token in `~/.pmate/session.json`. Use `--app <app-id>`
153
- to authenticate against a specific app; the default remains `@pmate/cli`. Commands like
154
- `pmate sts` require this session; if it is missing, log in first.
152
+ `pmate login` stores sessions in `~/.pmate/session.json`. The file now keeps a
153
+ multi-app session registry keyed by app id, so logging into one app no longer
154
+ overwrites another app's session. Use `--app <app-id>` to authenticate against
155
+ a specific app; the default remains `@pmate/cli`.
156
+
157
+ Notes:
158
+ - Existing single-session files are migrated automatically on first read.
159
+ - Platform commands such as `pmate sts`, `pmate agent`, and `pmate app` still
160
+ default to the `@pmate/cli` session.
155
161
 
156
162
  ## Notion config
157
163
 
package/dist/index.js CHANGED
@@ -34,6 +34,149 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  ));
35
35
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
36
 
37
+ // src/sessionStore.ts
38
+ function buildSessionStorePath() {
39
+ return import_node_path3.default.join(import_node_os2.default.homedir(), ".pmate", "session.json");
40
+ }
41
+ function saveLoginSession(session, requestedApp = DEFAULT_APP_ID) {
42
+ const store = loadExistingSessionStoreOrEmpty();
43
+ const app = resolveStoredAppId(session, requestedApp);
44
+ const nextSession = {
45
+ ...session,
46
+ app,
47
+ session: {
48
+ ...session.session,
49
+ ...session.session.app ? {} : { app }
50
+ },
51
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
52
+ };
53
+ store.sessions[app] = nextSession;
54
+ store.activeApp = app;
55
+ writeSessionStore(store);
56
+ return {
57
+ app,
58
+ sessionPath: buildSessionStorePath()
59
+ };
60
+ }
61
+ function readRequiredSession(options) {
62
+ const { sessionPath, store } = loadSessionStoreWithPath();
63
+ const resolvedApp = resolveReadApp(store, options);
64
+ const session = store.sessions[resolvedApp];
65
+ if (!session) {
66
+ throw new Error(buildMissingSessionMessage(sessionPath, resolvedApp));
67
+ }
68
+ const token = session.token?.trim();
69
+ if (!token) {
70
+ throw new Error(`Missing token in ${sessionPath}. Run "pmate login --app ${resolvedApp}" again.`);
71
+ }
72
+ return {
73
+ ...session,
74
+ token
75
+ };
76
+ }
77
+ function loadSessionStore() {
78
+ return loadSessionStoreWithPath().store;
79
+ }
80
+ function loadExistingSessionStoreOrEmpty() {
81
+ const sessionPath = buildSessionStorePath();
82
+ if (!(0, import_node_fs2.existsSync)(sessionPath)) {
83
+ return {
84
+ version: SESSION_STORE_VERSION,
85
+ activeApp: DEFAULT_APP_ID,
86
+ sessions: {}
87
+ };
88
+ }
89
+ return loadSessionStore();
90
+ }
91
+ function loadSessionStoreWithPath() {
92
+ const sessionPath = buildSessionStorePath();
93
+ if (!(0, import_node_fs2.existsSync)(sessionPath)) {
94
+ throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
95
+ }
96
+ const raw = (0, import_node_fs2.readFileSync)(sessionPath, "utf8");
97
+ const parsed = JSON.parse(raw);
98
+ const store = normalizeStore(parsed);
99
+ const nextRaw = JSON.stringify(store, null, 2);
100
+ if (nextRaw !== raw.trim()) {
101
+ writeSessionStore(store);
102
+ }
103
+ return { sessionPath, store };
104
+ }
105
+ function normalizeStore(value) {
106
+ if (isSessionStore(value)) {
107
+ return {
108
+ version: SESSION_STORE_VERSION,
109
+ activeApp: value.activeApp || DEFAULT_APP_ID,
110
+ sessions: value.sessions || {}
111
+ };
112
+ }
113
+ const legacy = value;
114
+ const app = resolveStoredAppId(legacy, legacy.session?.app || legacy.app || DEFAULT_APP_ID);
115
+ return {
116
+ version: SESSION_STORE_VERSION,
117
+ activeApp: app,
118
+ sessions: {
119
+ [app]: {
120
+ ...legacy,
121
+ app,
122
+ session: {
123
+ ...legacy.session,
124
+ ...legacy.session?.app ? {} : { app }
125
+ },
126
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
127
+ }
128
+ }
129
+ };
130
+ }
131
+ function isSessionStore(value) {
132
+ return !!value && typeof value === "object" && "version" in value && "sessions" in value && typeof value.sessions === "object";
133
+ }
134
+ function resolveStoredAppId(session, fallbackApp) {
135
+ return session.session?.app?.trim() || session.app?.trim() || fallbackApp.trim() || DEFAULT_APP_ID;
136
+ }
137
+ function resolveReadApp(store, options) {
138
+ const requestedApp = options?.app?.trim();
139
+ if (requestedApp) {
140
+ return requestedApp;
141
+ }
142
+ const preferredApp = options?.preferredApp?.trim();
143
+ if (preferredApp && store.sessions[preferredApp]) {
144
+ return preferredApp;
145
+ }
146
+ if (options?.fallbackToActiveApp && store.activeApp && store.sessions[store.activeApp]) {
147
+ return store.activeApp;
148
+ }
149
+ return preferredApp || store.activeApp || DEFAULT_APP_ID;
150
+ }
151
+ function writeSessionStore(store) {
152
+ const sessionPath = buildSessionStorePath();
153
+ (0, import_node_fs2.mkdirSync)(import_node_path3.default.dirname(sessionPath), { recursive: true });
154
+ (0, import_node_fs2.writeFileSync)(sessionPath, JSON.stringify(store, null, 2), {
155
+ mode: 384
156
+ });
157
+ try {
158
+ (0, import_node_fs2.chmodSync)(sessionPath, 384);
159
+ } catch {
160
+ }
161
+ }
162
+ function buildMissingSessionMessage(sessionPath, app) {
163
+ if (app === DEFAULT_APP_ID) {
164
+ return `Missing ${DEFAULT_APP_ID} session in ${sessionPath}. Run "pmate login" first.`;
165
+ }
166
+ return `Missing session for app ${app} in ${sessionPath}. Run "pmate login --app ${app}" first.`;
167
+ }
168
+ var import_node_fs2, import_node_os2, import_node_path3, DEFAULT_APP_ID, SESSION_STORE_VERSION;
169
+ var init_sessionStore = __esm({
170
+ "src/sessionStore.ts"() {
171
+ "use strict";
172
+ import_node_fs2 = require("fs");
173
+ import_node_os2 = __toESM(require("os"));
174
+ import_node_path3 = __toESM(require("path"));
175
+ DEFAULT_APP_ID = "@pmate/cli";
176
+ SESSION_STORE_VERSION = 2;
177
+ }
178
+ });
179
+
37
180
  // node_modules/.pnpm/@pmate+meta@1.1.2/node_modules/@pmate/meta/dist/types/account.types.js
38
181
  var require_account_types = __commonJS({
39
182
  "node_modules/.pnpm/@pmate+meta@1.1.2/node_modules/@pmate/meta/dist/types/account.types.js"(exports2) {
@@ -12406,17 +12549,9 @@ function resolveHubBaseUrl(value) {
12406
12549
  return (value || process.env.PMATE_AGENT_HUB_BASE_URL || DEFAULT_AGENT_HUB_BASE_URL).replace(/\/+$/, "");
12407
12550
  }
12408
12551
  function readSessionToken() {
12409
- const sessionPath = import_node_path13.default.join(import_node_os4.default.homedir(), ".pmate", "session.json");
12410
- if (!(0, import_node_fs9.existsSync)(sessionPath)) {
12411
- throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
12412
- }
12413
- const raw = (0, import_node_fs9.readFileSync)(sessionPath, "utf8");
12414
- const parsed = JSON.parse(raw);
12415
- const token = parsed.token?.trim();
12416
- if (!token) {
12417
- throw new Error(`Missing token in ${sessionPath}. Run "pmate login" again.`);
12418
- }
12419
- return token;
12552
+ return readRequiredSession({
12553
+ preferredApp: DEFAULT_APP_ID
12554
+ }).token;
12420
12555
  }
12421
12556
  function unwrapAgentResult(value) {
12422
12557
  if (!value || typeof value !== "object") {
@@ -12427,14 +12562,12 @@ function unwrapAgentResult(value) {
12427
12562
  }
12428
12563
  return value;
12429
12564
  }
12430
- var import_node_fs9, import_node_os4, import_node_path13, import_agent_sdk, DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_HUB_BASE_URL, DEFAULT_NAMESPACE, DEFAULT_FROM, AgentLlmClient;
12565
+ var import_agent_sdk, DEFAULT_AGENT_API_BASE_URL, DEFAULT_AGENT_HUB_BASE_URL, DEFAULT_NAMESPACE, DEFAULT_FROM, AgentLlmClient;
12431
12566
  var init_AgentLlmClient = __esm({
12432
12567
  "src/llm/AgentLlmClient.ts"() {
12433
12568
  "use strict";
12434
- import_node_fs9 = require("fs");
12435
- import_node_os4 = __toESM(require("os"));
12436
- import_node_path13 = __toESM(require("path"));
12437
12569
  import_agent_sdk = __toESM(require_dist4());
12570
+ init_sessionStore();
12438
12571
  DEFAULT_AGENT_API_BASE_URL = "https://agent-api.pmate.chat";
12439
12572
  DEFAULT_AGENT_HUB_BASE_URL = "https://hub.pmate.chat";
12440
12573
  DEFAULT_NAMESPACE = "pmate-cli";
@@ -12479,8 +12612,8 @@ __export(index_exports, {
12479
12612
  parseCommandArgs: () => parseCommandArgs
12480
12613
  });
12481
12614
  module.exports = __toCommonJS(index_exports);
12482
- var import_node_fs16 = require("fs");
12483
- var import_node_path21 = __toESM(require("path"));
12615
+ var import_node_fs14 = require("fs");
12616
+ var import_node_path19 = __toESM(require("path"));
12484
12617
  var import_chalk3 = __toESM(require("chalk"));
12485
12618
 
12486
12619
  // src/cli.ts
@@ -12910,15 +13043,12 @@ var ListCommandHandler = class {
12910
13043
  };
12911
13044
 
12912
13045
  // src/commands/LoginCommandHandler.ts
12913
- var import_node_fs2 = require("fs");
12914
13046
  var import_node_http = require("http");
12915
- var import_node_os2 = __toESM(require("os"));
12916
- var import_node_path3 = __toESM(require("path"));
12917
13047
  var import_node_child_process = require("child_process");
13048
+ init_sessionStore();
12918
13049
  var AUTH_UI_BASE_URL = "https://auth.pmate.chat";
12919
13050
  var AUTH_API_BASE_URL = "https://auth-api-v2.pmate.chat";
12920
13051
  var CALLBACK_PATH = "/pmate-login-callback";
12921
- var DEFAULT_APP_ID = "@pmate/cli";
12922
13052
  var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
12923
13053
  function buildHostedLoginUrl(redirectUrl, appId = DEFAULT_APP_ID) {
12924
13054
  const url = new URL(AUTH_UI_BASE_URL);
@@ -12945,15 +13075,17 @@ var LoginCommandHandler = class {
12945
13075
  });
12946
13076
  try {
12947
13077
  const token = await callback.waitForToken;
12948
- const loginResponse = await this.fetchSession(token);
12949
- const sessionPath = this.writeSession(loginResponse);
12950
- ui.success(`Logged in. Session saved to ${sessionPath}`);
13078
+ const loginResponse = await this.fetchSession(token, appId);
13079
+ const saved = saveLoginSession(loginResponse, appId);
13080
+ ui.success(`Logged in to ${saved.app}. Session saved to ${saved.sessionPath}`);
12951
13081
  } finally {
12952
13082
  await callback.close();
12953
13083
  }
12954
13084
  }
12955
- async fetchSession(token) {
12956
- const response = await fetch(`${AUTH_API_BASE_URL}/session`, {
13085
+ async fetchSession(token, appId) {
13086
+ const url = new URL(`${AUTH_API_BASE_URL}/session`);
13087
+ url.searchParams.set("app", appId);
13088
+ const response = await fetch(url.toString(), {
12957
13089
  method: "GET",
12958
13090
  headers: {
12959
13091
  Authorization: `Bearer ${token}`
@@ -13071,19 +13203,6 @@ var LoginCommandHandler = class {
13071
13203
  return false;
13072
13204
  }
13073
13205
  }
13074
- writeSession(session) {
13075
- const sessionDir = import_node_path3.default.join(import_node_os2.default.homedir(), ".pmate");
13076
- const sessionPath = import_node_path3.default.join(sessionDir, "session.json");
13077
- (0, import_node_fs2.mkdirSync)(sessionDir, { recursive: true });
13078
- (0, import_node_fs2.writeFileSync)(sessionPath, JSON.stringify(session, null, 2), {
13079
- mode: 384
13080
- });
13081
- try {
13082
- (0, import_node_fs2.chmodSync)(sessionPath, 384);
13083
- } catch {
13084
- }
13085
- return sessionPath;
13086
- }
13087
13206
  };
13088
13207
 
13089
13208
  // src/services/AliyunService.ts
@@ -13673,10 +13792,8 @@ var AddDnsCommandHandler = class {
13673
13792
  };
13674
13793
 
13675
13794
  // src/commands/StsCommandHandler.ts
13676
- var import_node_fs4 = require("fs");
13677
- var import_node_os3 = __toESM(require("os"));
13678
- var import_node_path5 = __toESM(require("path"));
13679
13795
  var import_chalk2 = __toESM(require("chalk"));
13796
+ init_sessionStore();
13680
13797
  var StsCommandHandler = class {
13681
13798
  async handle(_args) {
13682
13799
  const session = this.readSession();
@@ -13704,12 +13821,9 @@ var StsCommandHandler = class {
13704
13821
  ui.plain(import_chalk2.default.cyan(JSON.stringify(payload, null, 2)));
13705
13822
  }
13706
13823
  readSession() {
13707
- const sessionPath = import_node_path5.default.join(import_node_os3.default.homedir(), ".pmate", "session.json");
13708
- if (!(0, import_node_fs4.existsSync)(sessionPath)) {
13709
- throw new Error("Missing session. Run `pmate login` first.");
13710
- }
13711
- const raw = (0, import_node_fs4.readFileSync)(sessionPath, "utf8");
13712
- return JSON.parse(raw);
13824
+ return readRequiredSession({
13825
+ preferredApp: DEFAULT_APP_ID
13826
+ });
13713
13827
  }
13714
13828
  };
13715
13829
 
@@ -13723,12 +13837,12 @@ var BucketCommandHandler = class {
13723
13837
  };
13724
13838
 
13725
13839
  // src/commands/DeployCommandHandler.ts
13726
- var import_node_fs5 = require("fs");
13727
- var import_node_path7 = __toESM(require("path"));
13840
+ var import_node_fs4 = require("fs");
13841
+ var import_node_path6 = __toESM(require("path"));
13728
13842
  var import_node_child_process2 = require("child_process");
13729
13843
 
13730
13844
  // src/appDir.ts
13731
- var import_node_path6 = __toESM(require("path"));
13845
+ var import_node_path5 = __toESM(require("path"));
13732
13846
  function normalizeRelativeDir(input, appName) {
13733
13847
  if (typeof input !== "string") {
13734
13848
  throw new Error(`Missing dir for ${appName} in .pmate.yaml`);
@@ -13741,7 +13855,7 @@ function normalizeRelativeDir(input, appName) {
13741
13855
  if (unixLike.startsWith("/")) {
13742
13856
  throw new Error(`Invalid dir for ${appName} in .pmate.yaml: must be relative`);
13743
13857
  }
13744
- const normalized = import_node_path6.default.posix.normalize(unixLike);
13858
+ const normalized = import_node_path5.default.posix.normalize(unixLike);
13745
13859
  if (normalized.startsWith("../") || normalized === "..") {
13746
13860
  throw new Error(
13747
13861
  `Invalid dir for ${appName} in .pmate.yaml: must stay within repo`
@@ -13751,7 +13865,7 @@ function normalizeRelativeDir(input, appName) {
13751
13865
  }
13752
13866
  function resolveLocalAppDir(repoRoot, appName, dir) {
13753
13867
  const relative = normalizeRelativeDir(dir, appName);
13754
- return import_node_path6.default.resolve(repoRoot, relative);
13868
+ return import_node_path5.default.resolve(repoRoot, relative);
13755
13869
  }
13756
13870
  function resolveRemoteAppDir(appName, dir) {
13757
13871
  return normalizeRelativeDir(dir, appName);
@@ -13823,8 +13937,8 @@ var DeployCommandHandler = class {
13823
13937
  }
13824
13938
  async deployVite(appName, cwd, appConfig) {
13825
13939
  const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
13826
- const packageJsonPath = import_node_path7.default.join(appDir, "package.json");
13827
- if (!(0, import_node_fs5.existsSync)(packageJsonPath)) {
13940
+ const packageJsonPath = import_node_path6.default.join(appDir, "package.json");
13941
+ if (!(0, import_node_fs4.existsSync)(packageJsonPath)) {
13828
13942
  throw new Error(`No package.json found at ${packageJsonPath}`);
13829
13943
  }
13830
13944
  const pkg2 = this.loadPackageJson(packageJsonPath);
@@ -13833,28 +13947,28 @@ var DeployCommandHandler = class {
13833
13947
  throw new Error(`Missing package name in ${packageJsonPath}`);
13834
13948
  }
13835
13949
  await this.runCommand("pnpm", ["--filter", pkgName, "build"], cwd);
13836
- const distDir = import_node_path7.default.join(appDir, "dist");
13837
- if (!(0, import_node_fs5.existsSync)(distDir)) {
13950
+ const distDir = import_node_path6.default.join(appDir, "dist");
13951
+ if (!(0, import_node_fs4.existsSync)(distDir)) {
13838
13952
  throw new Error(`No dist directory found at ${distDir}`);
13839
13953
  }
13840
13954
  const bucketName = appConfig.bucket?.trim();
13841
13955
  if (!bucketName) {
13842
13956
  throw new Error(
13843
- `Missing bucket for ${appName} in ${import_node_path7.default.join(cwd, ".pmate.yaml")}`
13957
+ `Missing bucket for ${appName} in ${import_node_path6.default.join(cwd, ".pmate.yaml")}`
13844
13958
  );
13845
13959
  }
13846
13960
  await AliyunService.uploadDirectory(distDir, bucketName);
13847
13961
  }
13848
13962
  async deployStatic(appName, cwd, appConfig) {
13849
13963
  const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
13850
- const srcDir = import_node_path7.default.join(appDir, "src");
13851
- if (!(0, import_node_fs5.existsSync)(srcDir)) {
13964
+ const srcDir = import_node_path6.default.join(appDir, "src");
13965
+ if (!(0, import_node_fs4.existsSync)(srcDir)) {
13852
13966
  throw new Error(`No src directory found at ${srcDir}`);
13853
13967
  }
13854
13968
  const bucketName = appConfig.bucket?.trim();
13855
13969
  if (!bucketName) {
13856
13970
  throw new Error(
13857
- `Missing bucket for ${appName} in ${import_node_path7.default.join(cwd, ".pmate.yaml")}`
13971
+ `Missing bucket for ${appName} in ${import_node_path6.default.join(cwd, ".pmate.yaml")}`
13858
13972
  );
13859
13973
  }
13860
13974
  await AliyunService.uploadDirectory(srcDir, bucketName);
@@ -13960,10 +14074,10 @@ var DeployCommandHandler = class {
13960
14074
  await this.runRemoteCommand(server, command);
13961
14075
  }
13962
14076
  resolveCwd(target) {
13963
- return target ? import_node_path7.default.resolve(process.cwd(), target) : process.cwd();
14077
+ return target ? import_node_path6.default.resolve(process.cwd(), target) : process.cwd();
13964
14078
  }
13965
14079
  loadPackageJson(packageJsonPath) {
13966
- const raw = (0, import_node_fs5.readFileSync)(packageJsonPath, "utf8");
14080
+ const raw = (0, import_node_fs4.readFileSync)(packageJsonPath, "utf8");
13967
14081
  const parsed = JSON.parse(raw);
13968
14082
  if (!parsed || typeof parsed !== "object") {
13969
14083
  throw new Error(`Invalid package.json at ${packageJsonPath}`);
@@ -14041,7 +14155,7 @@ var DeployCommandHandler = class {
14041
14155
  };
14042
14156
 
14043
14157
  // src/commands/LogCommandHandler.ts
14044
- var import_node_path8 = __toESM(require("path"));
14158
+ var import_node_path7 = __toESM(require("path"));
14045
14159
  var LogCommandHandler = class {
14046
14160
  async handle(args) {
14047
14161
  const appName = args.logApp.trim();
@@ -14065,7 +14179,7 @@ var LogCommandHandler = class {
14065
14179
  this.renderPage(page);
14066
14180
  }
14067
14181
  resolveCwd(target) {
14068
- return target ? import_node_path8.default.resolve(process.cwd(), target) : process.cwd();
14182
+ return target ? import_node_path7.default.resolve(process.cwd(), target) : process.cwd();
14069
14183
  }
14070
14184
  loadClosestConfig(cwd) {
14071
14185
  const loaded = loadAppConfig(cwd, { searchParents: true });
@@ -14112,8 +14226,8 @@ var LogCommandHandler = class {
14112
14226
  };
14113
14227
 
14114
14228
  // src/commands/InitCommandHandler.ts
14115
- var import_node_fs6 = require("fs");
14116
- var import_node_path9 = __toESM(require("path"));
14229
+ var import_node_fs5 = require("fs");
14230
+ var import_node_path8 = __toESM(require("path"));
14117
14231
  var import_node_child_process3 = require("child_process");
14118
14232
  var import_promises2 = require("readline/promises");
14119
14233
  var import_yaml2 = __toESM(require("yaml"));
@@ -14151,7 +14265,7 @@ var InitCommandHandler = class {
14151
14265
  }
14152
14266
  if (appConfig.type !== "rust") {
14153
14267
  const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
14154
- if (!(0, import_node_fs6.existsSync)(appDir)) {
14268
+ if (!(0, import_node_fs5.existsSync)(appDir)) {
14155
14269
  throw new Error(`No app folder found at ${appDir}`);
14156
14270
  }
14157
14271
  }
@@ -14180,12 +14294,12 @@ var InitCommandHandler = class {
14180
14294
  const bucketName = appConfig.bucket?.trim();
14181
14295
  if (!bucketName) {
14182
14296
  throw new Error(
14183
- `Missing bucket for ${appName} in ${import_node_path9.default.join(cwd, ".pmate.yaml")}`
14297
+ `Missing bucket for ${appName} in ${import_node_path8.default.join(cwd, ".pmate.yaml")}`
14184
14298
  );
14185
14299
  }
14186
14300
  const baseDomain = config.domain?.trim();
14187
14301
  if (!baseDomain) {
14188
- throw new Error(`Missing domain in ${import_node_path9.default.join(cwd, ".pmate.yaml")}`);
14302
+ throw new Error(`Missing domain in ${import_node_path8.default.join(cwd, ".pmate.yaml")}`);
14189
14303
  }
14190
14304
  const subdomain = appConfig.subdomain?.trim();
14191
14305
  const dnsRr = subdomain || "@";
@@ -14319,7 +14433,7 @@ var InitCommandHandler = class {
14319
14433
  const serverAddress = await resolveServerAddress(server);
14320
14434
  const templateName = serviceType === "ws" ? "nginx.ws.template" : "nginx.rest.template";
14321
14435
  const templatePath = this.resolveTemplatePath(templateName);
14322
- const template = (0, import_node_fs6.readFileSync)(templatePath, "utf8");
14436
+ const template = (0, import_node_fs5.readFileSync)(templatePath, "utf8");
14323
14437
  const host = `${subdomain}.pmate.chat`;
14324
14438
  const rendered = template.replace(/\$\{\{PORT\}\}/g, String(port)).replace(/\$\{\{HOSTS\}\}/g, host).replace(/\$\{\{HOST\}\}/g, host);
14325
14439
  const remotePath = `/etc/nginx/sites-enabled/${subdomain}.conf`;
@@ -14352,15 +14466,15 @@ var InitCommandHandler = class {
14352
14466
  if (options.ensurePackageJson) {
14353
14467
  const appDir = resolveLocalAppDir(cwd, appConfig.app, appConfig.dir);
14354
14468
  ui.info(`Resolved appDir: ${appDir}`);
14355
- if (!(0, import_node_fs6.existsSync)(appDir)) {
14469
+ if (!(0, import_node_fs5.existsSync)(appDir)) {
14356
14470
  throw new Error(`Missing app folder at ${appDir}`);
14357
14471
  }
14358
- const packageJsonPath = import_node_path9.default.join(appDir, "package.json");
14472
+ const packageJsonPath = import_node_path8.default.join(appDir, "package.json");
14359
14473
  ui.info(`Resolved package.json: ${packageJsonPath}`);
14360
- if (!(0, import_node_fs6.existsSync)(packageJsonPath)) {
14474
+ if (!(0, import_node_fs5.existsSync)(packageJsonPath)) {
14361
14475
  throw new Error(`Missing package.json at ${packageJsonPath}`);
14362
14476
  }
14363
- const pkgStat = (0, import_node_fs6.statSync)(packageJsonPath);
14477
+ const pkgStat = (0, import_node_fs5.statSync)(packageJsonPath);
14364
14478
  ui.info(
14365
14479
  `package.json stat: isFile=${pkgStat.isFile()} isDirectory=${pkgStat.isDirectory()}`
14366
14480
  );
@@ -14380,12 +14494,12 @@ var InitCommandHandler = class {
14380
14494
  }
14381
14495
  resolveTemplatePath(templateName) {
14382
14496
  const candidates = [
14383
- import_node_path9.default.join(__dirname, "templates", templateName),
14384
- import_node_path9.default.join(__dirname, "..", "templates", templateName),
14385
- import_node_path9.default.join(__dirname, "..", "src", "templates", templateName)
14497
+ import_node_path8.default.join(__dirname, "templates", templateName),
14498
+ import_node_path8.default.join(__dirname, "..", "templates", templateName),
14499
+ import_node_path8.default.join(__dirname, "..", "src", "templates", templateName)
14386
14500
  ];
14387
14501
  for (const candidate of candidates) {
14388
- if ((0, import_node_fs6.existsSync)(candidate)) {
14502
+ if ((0, import_node_fs5.existsSync)(candidate)) {
14389
14503
  return candidate;
14390
14504
  }
14391
14505
  }
@@ -14433,7 +14547,7 @@ var InitCommandHandler = class {
14433
14547
  });
14434
14548
  }
14435
14549
  resolveCwd(target) {
14436
- return target ? import_node_path9.default.resolve(process.cwd(), target) : process.cwd();
14550
+ return target ? import_node_path8.default.resolve(process.cwd(), target) : process.cwd();
14437
14551
  }
14438
14552
  sleep(ms) {
14439
14553
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -14557,7 +14671,7 @@ var InitCommandHandler = class {
14557
14671
  }
14558
14672
  }
14559
14673
  loadPackageJson(packageJsonPath) {
14560
- const raw = (0, import_node_fs6.readFileSync)(packageJsonPath, "utf8");
14674
+ const raw = (0, import_node_fs5.readFileSync)(packageJsonPath, "utf8");
14561
14675
  const parsed = JSON.parse(raw);
14562
14676
  if (!parsed || typeof parsed !== "object") {
14563
14677
  throw new Error(`Invalid package.json at ${packageJsonPath}`);
@@ -14566,13 +14680,13 @@ var InitCommandHandler = class {
14566
14680
  }
14567
14681
  writePackageJson(packageJsonPath, data) {
14568
14682
  const serialized = JSON.stringify(data, null, 2);
14569
- (0, import_node_fs6.writeFileSync)(packageJsonPath, `${serialized}
14683
+ (0, import_node_fs5.writeFileSync)(packageJsonPath, `${serialized}
14570
14684
  `, "utf8");
14571
14685
  }
14572
14686
  writeConfig(cwd, config) {
14573
- const configPath = import_node_path9.default.join(cwd, ".pmate.yaml");
14687
+ const configPath = import_node_path8.default.join(cwd, ".pmate.yaml");
14574
14688
  const serialized = import_yaml2.default.stringify(config).trimEnd();
14575
- (0, import_node_fs6.writeFileSync)(configPath, `${serialized}
14689
+ (0, import_node_fs5.writeFileSync)(configPath, `${serialized}
14576
14690
  `, "utf8");
14577
14691
  }
14578
14692
  async promptRequired(rl, question) {
@@ -14608,8 +14722,8 @@ var InitCommandHandler = class {
14608
14722
  };
14609
14723
 
14610
14724
  // src/commands/DevCommandHandler.ts
14611
- var import_node_fs7 = require("fs");
14612
- var import_node_path10 = __toESM(require("path"));
14725
+ var import_node_fs6 = require("fs");
14726
+ var import_node_path9 = __toESM(require("path"));
14613
14727
  var import_node_child_process4 = require("child_process");
14614
14728
  var DevCommandHandler = class {
14615
14729
  async handle(args) {
@@ -14627,8 +14741,8 @@ var DevCommandHandler = class {
14627
14741
  );
14628
14742
  }
14629
14743
  const appDir = resolveLocalAppDir(cwd, appName, appConfig.dir);
14630
- const packageJsonPath = import_node_path10.default.join(appDir, "package.json");
14631
- if (!(0, import_node_fs7.existsSync)(packageJsonPath)) {
14744
+ const packageJsonPath = import_node_path9.default.join(appDir, "package.json");
14745
+ if (!(0, import_node_fs6.existsSync)(packageJsonPath)) {
14632
14746
  throw new Error(`No package.json found at ${packageJsonPath}`);
14633
14747
  }
14634
14748
  const pkg2 = this.loadPackageJson(packageJsonPath);
@@ -14642,13 +14756,13 @@ var DevCommandHandler = class {
14642
14756
  await this.runCommand("pnpm", ["--filter", pkgName, "run", "dev"], cwd);
14643
14757
  }
14644
14758
  resolveCwd(target) {
14645
- return target ? import_node_path10.default.resolve(process.cwd(), target) : process.cwd();
14759
+ return target ? import_node_path9.default.resolve(process.cwd(), target) : process.cwd();
14646
14760
  }
14647
14761
  loadConfig(cwd) {
14648
14762
  return loadAppConfig(cwd);
14649
14763
  }
14650
14764
  loadPackageJson(packageJsonPath) {
14651
- const raw = (0, import_node_fs7.readFileSync)(packageJsonPath, "utf8");
14765
+ const raw = (0, import_node_fs6.readFileSync)(packageJsonPath, "utf8");
14652
14766
  const parsed = JSON.parse(raw);
14653
14767
  if (!parsed || typeof parsed !== "object") {
14654
14768
  throw new Error(`Invalid package.json at ${packageJsonPath}`);
@@ -14676,8 +14790,8 @@ var DevCommandHandler = class {
14676
14790
  };
14677
14791
 
14678
14792
  // src/commands/OssCommandHandler.ts
14679
- var import_node_fs8 = require("fs");
14680
- var import_node_path11 = __toESM(require("path"));
14793
+ var import_node_fs7 = require("fs");
14794
+ var import_node_path10 = __toESM(require("path"));
14681
14795
  var OssCommandHandler = class _OssCommandHandler {
14682
14796
  static {
14683
14797
  this.DEFAULT_BUCKET = "parrot-static";
@@ -14694,17 +14808,17 @@ var OssCommandHandler = class _OssCommandHandler {
14694
14808
  }
14695
14809
  return;
14696
14810
  }
14697
- const resolvedFile = import_node_path11.default.resolve(process.cwd(), args.filePath);
14811
+ const resolvedFile = import_node_path10.default.resolve(process.cwd(), args.filePath);
14698
14812
  this.assertFile(resolvedFile);
14699
14813
  const objectKey = this.normalizeObjectKey(args.objectKey);
14700
14814
  const bucket = this.resolveBucket(args.bucket);
14701
14815
  await AliyunService.uploadFile(resolvedFile, bucket, objectKey);
14702
14816
  }
14703
14817
  assertFile(filePath) {
14704
- if (!(0, import_node_fs8.existsSync)(filePath)) {
14818
+ if (!(0, import_node_fs7.existsSync)(filePath)) {
14705
14819
  throw new Error(`File not found: ${filePath}`);
14706
14820
  }
14707
- const stat = (0, import_node_fs8.statSync)(filePath);
14821
+ const stat = (0, import_node_fs7.statSync)(filePath);
14708
14822
  if (!stat.isFile()) {
14709
14823
  throw new Error(`Not a file: ${filePath}`);
14710
14824
  }
@@ -14726,7 +14840,7 @@ var OssCommandHandler = class _OssCommandHandler {
14726
14840
  };
14727
14841
 
14728
14842
  // src/commands/EnvCommandHandler.ts
14729
- var import_node_path12 = __toESM(require("path"));
14843
+ var import_node_path11 = __toESM(require("path"));
14730
14844
  var import_node_child_process5 = require("child_process");
14731
14845
  var EnvCommandHandler = class {
14732
14846
  async handle(args) {
@@ -14800,8 +14914,8 @@ var EnvCommandHandler = class {
14800
14914
  ui.success(`Set ${envKey} in .env.local`, appName);
14801
14915
  }
14802
14916
  async listEnvKeys(server, repoDir, appDir, verbose) {
14803
- const envLocalPath = import_node_path12.default.posix.join(appDir, ".env.local");
14804
- const envPath = import_node_path12.default.posix.join(appDir, ".env");
14917
+ const envLocalPath = import_node_path11.default.posix.join(appDir, ".env.local");
14918
+ const envPath = import_node_path11.default.posix.join(appDir, ".env");
14805
14919
  if (verbose) {
14806
14920
  const repoPath = `$HOME/${repoDir}`;
14807
14921
  ui.info("Env list target", {
@@ -14894,8 +15008,8 @@ var EnvCommandHandler = class {
14894
15008
  }
14895
15009
  }
14896
15010
  async appendEnvLine(server, repoDir, appDir, envKey, envLine, verbose) {
14897
- const envLocalPath = import_node_path12.default.posix.join(appDir, ".env.local");
14898
- const envPath = import_node_path12.default.posix.join(appDir, ".env");
15011
+ const envLocalPath = import_node_path11.default.posix.join(appDir, ".env.local");
15012
+ const envPath = import_node_path11.default.posix.join(appDir, ".env");
14899
15013
  if (verbose) {
14900
15014
  const repoPath = `$HOME/${repoDir}`;
14901
15015
  ui.info("Env add target", {
@@ -14943,8 +15057,8 @@ var EnvCommandHandler = class {
14943
15057
  await this.runRemoteCommand(server, command);
14944
15058
  }
14945
15059
  async deleteEnvKey(server, repoDir, appDir, envKey, verbose) {
14946
- const envLocalPath = import_node_path12.default.posix.join(appDir, ".env.local");
14947
- const envPath = import_node_path12.default.posix.join(appDir, ".env");
15060
+ const envLocalPath = import_node_path11.default.posix.join(appDir, ".env.local");
15061
+ const envPath = import_node_path11.default.posix.join(appDir, ".env");
14948
15062
  if (verbose) {
14949
15063
  const repoPath = `$HOME/${repoDir}`;
14950
15064
  ui.info("Env delete target", {
@@ -15714,7 +15828,7 @@ var CommitCommandHandler = class {
15714
15828
 
15715
15829
  // src/commands/SummaryCommandHandler.ts
15716
15830
  var import_node_child_process7 = require("child_process");
15717
- var import_node_path14 = __toESM(require("path"));
15831
+ var import_node_path12 = __toESM(require("path"));
15718
15832
  var SummaryCommandHandler = class {
15719
15833
  async handle(args) {
15720
15834
  const cwd = this.resolveCwd(args.cwd);
@@ -15899,7 +16013,7 @@ var SummaryCommandHandler = class {
15899
16013
  return this.runCapture("gh", args, allowFailure, await this.getGhEnv(cwd), cwd);
15900
16014
  }
15901
16015
  resolveCwd(value) {
15902
- return value ? import_node_path14.default.resolve(process.cwd(), value) : process.cwd();
16016
+ return value ? import_node_path12.default.resolve(process.cwd(), value) : process.cwd();
15903
16017
  }
15904
16018
  };
15905
16019
  function truncate2(value, limit) {
@@ -15912,9 +16026,9 @@ function truncate2(value, limit) {
15912
16026
 
15913
16027
  // src/commands/LinearCommandHandler.ts
15914
16028
  var import_node_child_process8 = require("child_process");
15915
- var import_node_fs10 = require("fs");
15916
- var import_node_os5 = __toESM(require("os"));
15917
- var import_node_path15 = __toESM(require("path"));
16029
+ var import_node_fs8 = require("fs");
16030
+ var import_node_os3 = __toESM(require("os"));
16031
+ var import_node_path13 = __toESM(require("path"));
15918
16032
  var import_promises3 = require("readline/promises");
15919
16033
  var import_openai = __toESM(require("openai"));
15920
16034
  var import_sdk = require("@linear/sdk");
@@ -16798,15 +16912,15 @@ var LinearCommandHandler = class {
16798
16912
  }
16799
16913
  }
16800
16914
  getLinearSelectionPath() {
16801
- return import_node_path15.default.join(import_node_os5.default.homedir(), ".pmate", "linear-selection.json");
16915
+ return import_node_path13.default.join(import_node_os3.default.homedir(), ".pmate", "linear-selection.json");
16802
16916
  }
16803
16917
  readCachedLinearSelection(cwd) {
16804
16918
  const selectionPath = this.getLinearSelectionPath();
16805
- if (!(0, import_node_fs10.existsSync)(selectionPath)) {
16919
+ if (!(0, import_node_fs8.existsSync)(selectionPath)) {
16806
16920
  return void 0;
16807
16921
  }
16808
16922
  try {
16809
- const raw = (0, import_node_fs10.readFileSync)(selectionPath, "utf8").trim();
16923
+ const raw = (0, import_node_fs8.readFileSync)(selectionPath, "utf8").trim();
16810
16924
  if (!raw) return void 0;
16811
16925
  const parsed = JSON.parse(raw);
16812
16926
  const value = parsed[cwd];
@@ -16817,12 +16931,12 @@ var LinearCommandHandler = class {
16817
16931
  }
16818
16932
  writeCachedLinearSelection(cwd, title) {
16819
16933
  const selectionPath = this.getLinearSelectionPath();
16820
- const dir = import_node_path15.default.dirname(selectionPath);
16821
- (0, import_node_fs10.mkdirSync)(dir, { recursive: true });
16934
+ const dir = import_node_path13.default.dirname(selectionPath);
16935
+ (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
16822
16936
  let data = {};
16823
- if ((0, import_node_fs10.existsSync)(selectionPath)) {
16937
+ if ((0, import_node_fs8.existsSync)(selectionPath)) {
16824
16938
  try {
16825
- const raw = (0, import_node_fs10.readFileSync)(selectionPath, "utf8").trim();
16939
+ const raw = (0, import_node_fs8.readFileSync)(selectionPath, "utf8").trim();
16826
16940
  if (raw) {
16827
16941
  data = JSON.parse(raw);
16828
16942
  }
@@ -16831,7 +16945,7 @@ var LinearCommandHandler = class {
16831
16945
  }
16832
16946
  }
16833
16947
  data[cwd] = title;
16834
- (0, import_node_fs10.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
16948
+ (0, import_node_fs8.writeFileSync)(selectionPath, `${JSON.stringify(data, null, 2)}
16835
16949
  `, "utf8");
16836
16950
  }
16837
16951
  async lookupIssue(client, issueRef) {
@@ -17008,14 +17122,14 @@ var LinearCommandHandler = class {
17008
17122
  if (process.platform !== "darwin") {
17009
17123
  throw new Error("Screenshot capture only supports macOS.");
17010
17124
  }
17011
- const dir = await import_node_fs10.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-screenshot-"));
17012
- const filePath = import_node_path15.default.join(dir, `screenshot-${index}.png`);
17125
+ const dir = await import_node_fs8.promises.mkdtemp(import_node_path13.default.join(import_node_os3.default.tmpdir(), "pmate-screenshot-"));
17126
+ const filePath = import_node_path13.default.join(dir, `screenshot-${index}.png`);
17013
17127
  try {
17014
17128
  const code = await this.run("screencapture", ["-i", "-x", filePath], true);
17015
17129
  if (code !== 0) {
17016
17130
  throw new Error("Screenshot capture canceled or failed.");
17017
17131
  }
17018
- const buffer = await import_node_fs10.promises.readFile(filePath);
17132
+ const buffer = await import_node_fs8.promises.readFile(filePath);
17019
17133
  if (buffer.length === 0) {
17020
17134
  throw new Error("Screenshot capture produced an empty file.");
17021
17135
  }
@@ -17027,7 +17141,7 @@ var LinearCommandHandler = class {
17027
17141
  return { buffer, mime, filename: `screenshot-${index}.${extension}` };
17028
17142
  } finally {
17029
17143
  try {
17030
- await import_node_fs10.promises.rm(dir, { recursive: true, force: true });
17144
+ await import_node_fs8.promises.rm(dir, { recursive: true, force: true });
17031
17145
  } catch {
17032
17146
  }
17033
17147
  }
@@ -17171,17 +17285,17 @@ var LinearCommandHandler = class {
17171
17285
  return compact.length > limit ? `${compact.slice(0, limit)}...` : compact;
17172
17286
  }
17173
17287
  async convertToPng(buffer, ext) {
17174
- const dir = await import_node_fs10.promises.mkdtemp(import_node_path15.default.join(import_node_os5.default.tmpdir(), "pmate-"));
17175
- const inputPath = import_node_path15.default.join(dir, `clipboard.${ext}`);
17176
- const outputPath = import_node_path15.default.join(dir, "clipboard.png");
17288
+ const dir = await import_node_fs8.promises.mkdtemp(import_node_path13.default.join(import_node_os3.default.tmpdir(), "pmate-"));
17289
+ const inputPath = import_node_path13.default.join(dir, `clipboard.${ext}`);
17290
+ const outputPath = import_node_path13.default.join(dir, "clipboard.png");
17177
17291
  try {
17178
- await import_node_fs10.promises.writeFile(inputPath, buffer);
17292
+ await import_node_fs8.promises.writeFile(inputPath, buffer);
17179
17293
  const stderr = await this.runCapture(
17180
17294
  "sips",
17181
17295
  ["-s", "format", "png", inputPath, "--out", outputPath],
17182
17296
  true
17183
17297
  );
17184
- const out = await import_node_fs10.promises.readFile(outputPath);
17298
+ const out = await import_node_fs8.promises.readFile(outputPath);
17185
17299
  if (this.detectImageMime(out) !== "image/png") {
17186
17300
  throw new Error(
17187
17301
  stderr?.trim() ? `Failed to convert clipboard ${ext} to PNG: ${stderr.trim()}` : `Failed to convert clipboard ${ext} to PNG.`
@@ -17190,7 +17304,7 @@ var LinearCommandHandler = class {
17190
17304
  return out;
17191
17305
  } finally {
17192
17306
  try {
17193
- await import_node_fs10.promises.rm(dir, { recursive: true, force: true });
17307
+ await import_node_fs8.promises.rm(dir, { recursive: true, force: true });
17194
17308
  } catch {
17195
17309
  }
17196
17310
  }
@@ -17484,7 +17598,7 @@ var LinearCommandHandler = class {
17484
17598
  return this.runCapture("gh", args, allowFailure, await this.getGhEnv(cwd), cwd);
17485
17599
  }
17486
17600
  resolveCwd(value) {
17487
- return value ? import_node_path15.default.resolve(process.cwd(), value) : process.cwd();
17601
+ return value ? import_node_path13.default.resolve(process.cwd(), value) : process.cwd();
17488
17602
  }
17489
17603
  createOpenAiClient() {
17490
17604
  const config = loadPmateConfig();
@@ -17536,8 +17650,8 @@ function sleep(ms) {
17536
17650
  }
17537
17651
 
17538
17652
  // src/commands/NotionCommandHandler.ts
17539
- var import_node_fs11 = require("fs");
17540
- var import_node_path16 = __toESM(require("path"));
17653
+ var import_node_fs9 = require("fs");
17654
+ var import_node_path14 = __toESM(require("path"));
17541
17655
 
17542
17656
  // src/services/NotionService.ts
17543
17657
  var NotionService = class {
@@ -17776,9 +17890,9 @@ ${indent}\`\`\``;
17776
17890
  static richTextToPlain(richText) {
17777
17891
  return richText.map((item) => item.plain_text ?? item.text?.content ?? "").join("").trim();
17778
17892
  }
17779
- static async requestJson(path22, init) {
17893
+ static async requestJson(path20, init) {
17780
17894
  const token = this.getToken();
17781
- const response = await fetch(`${this.baseUrl}${path22}`, {
17895
+ const response = await fetch(`${this.baseUrl}${path20}`, {
17782
17896
  method: init.method,
17783
17897
  headers: {
17784
17898
  Authorization: `Bearer ${token}`,
@@ -17876,16 +17990,16 @@ var NotionCommandHandler = class {
17876
17990
  if (!args.filePath) {
17877
17991
  return "";
17878
17992
  }
17879
- const resolved = import_node_path16.default.resolve(process.cwd(), args.filePath);
17880
- return (0, import_node_fs11.readFileSync)(resolved, "utf8");
17993
+ const resolved = import_node_path14.default.resolve(process.cwd(), args.filePath);
17994
+ return (0, import_node_fs9.readFileSync)(resolved, "utf8");
17881
17995
  }
17882
17996
  };
17883
17997
 
17884
17998
  // src/commands/QrcodeCommandHandler.ts
17885
17999
  var import_node_child_process9 = require("child_process");
17886
- var import_node_fs12 = require("fs");
17887
- var import_node_os6 = __toESM(require("os"));
17888
- var import_node_path17 = __toESM(require("path"));
18000
+ var import_node_fs10 = require("fs");
18001
+ var import_node_os4 = __toESM(require("os"));
18002
+ var import_node_path15 = __toESM(require("path"));
17889
18003
  var import_promises4 = require("readline/promises");
17890
18004
  var import_jsqr = __toESM(require("jsqr"));
17891
18005
  var import_pngjs = require("pngjs");
@@ -17911,7 +18025,7 @@ var QrcodeCommandHandler = class {
17911
18025
  ui.success("QR code value:", value);
17912
18026
  } finally {
17913
18027
  try {
17914
- await import_node_fs12.promises.rm(dir, { recursive: true, force: true });
18028
+ await import_node_fs10.promises.rm(dir, { recursive: true, force: true });
17915
18029
  } catch {
17916
18030
  }
17917
18031
  }
@@ -17927,13 +18041,13 @@ var QrcodeCommandHandler = class {
17927
18041
  } finally {
17928
18042
  rl.close();
17929
18043
  }
17930
- const dir = await import_node_fs12.promises.mkdtemp(import_node_path17.default.join(import_node_os6.default.tmpdir(), "pmate-qrcode-"));
17931
- const filePath = import_node_path17.default.join(dir, "qrcode.png");
18044
+ const dir = await import_node_fs10.promises.mkdtemp(import_node_path15.default.join(import_node_os4.default.tmpdir(), "pmate-qrcode-"));
18045
+ const filePath = import_node_path15.default.join(dir, "qrcode.png");
17932
18046
  const code = await this.run("screencapture", ["-i", "-x", filePath], true);
17933
18047
  if (code !== 0) {
17934
18048
  throw new Error("Screenshot capture canceled or failed.");
17935
18049
  }
17936
- const buffer = await import_node_fs12.promises.readFile(filePath);
18050
+ const buffer = await import_node_fs10.promises.readFile(filePath);
17937
18051
  if (buffer.length === 0) {
17938
18052
  throw new Error("Screenshot capture produced an empty file.");
17939
18053
  }
@@ -17949,7 +18063,7 @@ var QrcodeCommandHandler = class {
17949
18063
  async decodeQr(filePath) {
17950
18064
  let buffer;
17951
18065
  try {
17952
- buffer = await import_node_fs12.promises.readFile(filePath);
18066
+ buffer = await import_node_fs10.promises.readFile(filePath);
17953
18067
  } catch {
17954
18068
  return null;
17955
18069
  }
@@ -18209,9 +18323,9 @@ function clampNumber(value, min, max, fallback) {
18209
18323
  // src/commands/CollectCommandHandler.ts
18210
18324
  var import_playwright = require("playwright");
18211
18325
  var import_node_crypto3 = require("crypto");
18212
- var import_node_fs13 = require("fs");
18213
- var import_node_os7 = __toESM(require("os"));
18214
- var import_node_path18 = __toESM(require("path"));
18326
+ var import_node_fs11 = require("fs");
18327
+ var import_node_os5 = __toESM(require("os"));
18328
+ var import_node_path16 = __toESM(require("path"));
18215
18329
  var CollectCommandHandler = class {
18216
18330
  async handle(args) {
18217
18331
  let browser = null;
@@ -18578,19 +18692,19 @@ function computeMessageHash(threadName, message) {
18578
18692
  return (0, import_node_crypto3.createHash)("sha1").update(base).digest("hex").slice(0, 16);
18579
18693
  }
18580
18694
  async function toDisplayableImagePath(src) {
18581
- if (!import_node_path18.default.isAbsolute(src)) {
18695
+ if (!import_node_path16.default.isAbsolute(src)) {
18582
18696
  return src;
18583
18697
  }
18584
- const ext = import_node_path18.default.extname(src);
18698
+ const ext = import_node_path16.default.extname(src);
18585
18699
  if (ext) {
18586
18700
  return src;
18587
18701
  }
18588
18702
  try {
18589
- const stat = await import_node_fs13.promises.stat(src);
18703
+ const stat = await import_node_fs11.promises.stat(src);
18590
18704
  if (!stat.isFile()) {
18591
18705
  return src;
18592
18706
  }
18593
- const fh = await import_node_fs13.promises.open(src, "r");
18707
+ const fh = await import_node_fs11.promises.open(src, "r");
18594
18708
  try {
18595
18709
  const buf = Buffer.alloc(32);
18596
18710
  const { bytesRead } = await fh.read(buf, 0, 32, 0);
@@ -18599,17 +18713,17 @@ async function toDisplayableImagePath(src) {
18599
18713
  if (!guessedExt) {
18600
18714
  return src;
18601
18715
  }
18602
- const cacheDir = import_node_path18.default.join(
18603
- import_node_os7.default.homedir(),
18716
+ const cacheDir = import_node_path16.default.join(
18717
+ import_node_os5.default.homedir(),
18604
18718
  ".pmate",
18605
18719
  "messages",
18606
18720
  "images"
18607
18721
  );
18608
- await import_node_fs13.promises.mkdir(cacheDir, { recursive: true });
18722
+ await import_node_fs11.promises.mkdir(cacheDir, { recursive: true });
18609
18723
  const base = (0, import_node_crypto3.createHash)("sha1").update(src).digest("hex");
18610
- const displayPath = import_node_path18.default.join(cacheDir, `${base}.${guessedExt}`);
18611
- await import_node_fs13.promises.rm(displayPath, { force: true }).catch(() => void 0);
18612
- await import_node_fs13.promises.copyFile(src, displayPath);
18724
+ const displayPath = import_node_path16.default.join(cacheDir, `${base}.${guessedExt}`);
18725
+ await import_node_fs11.promises.rm(displayPath, { force: true }).catch(() => void 0);
18726
+ await import_node_fs11.promises.copyFile(src, displayPath);
18613
18727
  return displayPath;
18614
18728
  } finally {
18615
18729
  await fh.close();
@@ -18665,9 +18779,9 @@ function parseMessageText(raw) {
18665
18779
  }
18666
18780
 
18667
18781
  // src/commands/AgentCommandHandler.ts
18668
- var import_node_fs14 = require("fs");
18669
- var import_node_os8 = __toESM(require("os"));
18670
- var import_node_path19 = __toESM(require("path"));
18782
+ var import_node_fs12 = require("fs");
18783
+ var import_node_path17 = __toESM(require("path"));
18784
+ init_sessionStore();
18671
18785
  var AgentCommandHandler = class {
18672
18786
  async handle(args) {
18673
18787
  const token = this.readToken();
@@ -18749,24 +18863,16 @@ var AgentCommandHandler = class {
18749
18863
  );
18750
18864
  }
18751
18865
  readToken() {
18752
- const sessionPath = import_node_path19.default.join(import_node_os8.default.homedir(), ".pmate", "session.json");
18753
- if (!(0, import_node_fs14.existsSync)(sessionPath)) {
18754
- throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
18755
- }
18756
- const raw = (0, import_node_fs14.readFileSync)(sessionPath, "utf8");
18757
- const parsed = JSON.parse(raw);
18758
- const token = parsed.token?.trim();
18759
- if (!token) {
18760
- throw new Error(`Missing token in ${sessionPath}. Run "pmate login" again.`);
18761
- }
18762
- return token;
18866
+ return readRequiredSession({
18867
+ preferredApp: DEFAULT_APP_ID
18868
+ }).token;
18763
18869
  }
18764
18870
  readJsonFile(filePath) {
18765
- const absolutePath = import_node_path19.default.resolve(process.cwd(), filePath);
18766
- if (!(0, import_node_fs14.existsSync)(absolutePath)) {
18871
+ const absolutePath = import_node_path17.default.resolve(process.cwd(), filePath);
18872
+ if (!(0, import_node_fs12.existsSync)(absolutePath)) {
18767
18873
  throw new Error(`JSON file not found: ${absolutePath}`);
18768
18874
  }
18769
- const raw = (0, import_node_fs14.readFileSync)(absolutePath, "utf8");
18875
+ const raw = (0, import_node_fs12.readFileSync)(absolutePath, "utf8");
18770
18876
  try {
18771
18877
  return JSON.parse(raw);
18772
18878
  } catch (error) {
@@ -18835,9 +18941,9 @@ var AgentCommandHandler = class {
18835
18941
  };
18836
18942
 
18837
18943
  // src/commands/AppCommandHandler.ts
18838
- var import_node_fs15 = require("fs");
18839
- var import_node_os9 = __toESM(require("os"));
18840
- var import_node_path20 = __toESM(require("path"));
18944
+ var import_node_fs13 = require("fs");
18945
+ var import_node_path18 = __toESM(require("path"));
18946
+ init_sessionStore();
18841
18947
  var AppCommandHandler = class {
18842
18948
  async handle(args) {
18843
18949
  const token = this.readToken();
@@ -18906,24 +19012,16 @@ var AppCommandHandler = class {
18906
19012
  return (baseUrl || process.env.PMATE_APPS_API_BASE_URL || "https://apps-api.pmate.chat").replace(/\/+$/, "");
18907
19013
  }
18908
19014
  readToken() {
18909
- const sessionPath = import_node_path20.default.join(import_node_os9.default.homedir(), ".pmate", "session.json");
18910
- if (!(0, import_node_fs15.existsSync)(sessionPath)) {
18911
- throw new Error(`Missing session file at ${sessionPath}. Run "pmate login" first.`);
18912
- }
18913
- const raw = (0, import_node_fs15.readFileSync)(sessionPath, "utf8");
18914
- const parsed = JSON.parse(raw);
18915
- const token = parsed.token?.trim();
18916
- if (!token) {
18917
- throw new Error(`Missing token in ${sessionPath}. Run "pmate login" again.`);
18918
- }
18919
- return token;
19015
+ return readRequiredSession({
19016
+ preferredApp: DEFAULT_APP_ID
19017
+ }).token;
18920
19018
  }
18921
19019
  readJsonFile(filePath) {
18922
- const absolutePath = import_node_path20.default.resolve(process.cwd(), filePath);
18923
- if (!(0, import_node_fs15.existsSync)(absolutePath)) {
19020
+ const absolutePath = import_node_path18.default.resolve(process.cwd(), filePath);
19021
+ if (!(0, import_node_fs13.existsSync)(absolutePath)) {
18924
19022
  throw new Error(`JSON file not found: ${absolutePath}`);
18925
19023
  }
18926
- const raw = (0, import_node_fs15.readFileSync)(absolutePath, "utf8");
19024
+ const raw = (0, import_node_fs13.readFileSync)(absolutePath, "utf8");
18927
19025
  try {
18928
19026
  return JSON.parse(raw);
18929
19027
  } catch (error) {
@@ -19340,7 +19438,7 @@ function requireValue2(tokens, optionName) {
19340
19438
 
19341
19439
  // src/index.ts
19342
19440
  var pkg = JSON.parse(
19343
- (0, import_node_fs16.readFileSync)(import_node_path21.default.resolve(__dirname, "..", "package.json"), "utf8")
19441
+ (0, import_node_fs14.readFileSync)(import_node_path19.default.resolve(__dirname, "..", "package.json"), "utf8")
19344
19442
  );
19345
19443
  var HELP_TEXT = [
19346
19444
  import_chalk3.default.bold(`pmate v${pkg.version}`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.13.3",
3
+ "version": "0.14.0",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {