@pmate/cli 0.32.0 → 0.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -239,12 +239,12 @@ Notes:
239
239
  Service logs use the same authenticated API as `dev.pmate.chat`. Each registered Service has `app` (application/deployment) and `runtime` (PM2/Nginx) Table topics on the dedicated `log` chain.
240
240
 
241
241
  ```sh
242
- pmate service log pmate:issues-api --topic app --page 0 --json
243
- pmate service log pmate:issues-api --topic runtime --source nginx --level error --env prod
244
- pmate service log pmate:issues-api --request-id <id> --follow
242
+ pmate service log pmate:issues-api --topic application --page 0 --json
243
+ pmate service log pmate:issues-api --topic nginx --field status=500 --env prod
244
+ pmate service log pmate:issues-api --field requestId=<id> --follow
245
245
  ```
246
246
 
247
- Pages are zero-based. Lists and `--search` cover the chain's configured retention window (30 days in production). `--since-ms` adds an epoch-millisecond lower bound. `--type`, `--level`, `--source`, `--request-id` and `--env` filter on the server. The legacy `--app` argument is optional and does not select a different source.
247
+ Pages are zero-based. Lists and `--search` cover the chain's configured retention window (30 days in production). `--since-ms` adds an epoch-millisecond lower bound. `--field name=value` (repeatable, scalar JSON values) and `--env` filter on the server. Topics are independent sources such as `application`, `nginx`, `pm2`, `deployment`, `pv`, and `vitals`; custom fields live in `data`. Old `--type`, `--level`, `--source`, and `--request-id` flags are removed. The legacy `--app` argument is optional and does not select a different source.
248
248
 
249
249
  A current CLI session is exchanged in memory for `pmate:developers`; the active App and session file are unchanged. If needed, run `pmate login --app pmate:developers`. Permission denial never falls back to anonymous Indexer reads. Credentials are never printed.
250
250
 
package/dist/index.d.ts CHANGED
@@ -970,11 +970,8 @@ type ServiceCommandArgs = {
970
970
  } | {
971
971
  type: Command.Service;
972
972
  action: "log";
973
- topic?: "app" | "runtime";
974
- level?: string;
975
- source?: string;
976
- requestId?: string;
977
- logType?: string;
973
+ topic?: string;
974
+ fields?: Record<string, string | number | boolean>;
978
975
  app?: string;
979
976
  sinceMs?: number;
980
977
  namespace: string;
package/dist/index.js CHANGED
@@ -18777,8 +18777,9 @@ async function queryDeveloperLogs(input, fetcher = fetch) {
18777
18777
  });
18778
18778
  if (exchanged?.session?.identity?.app !== appRef || exchanged.session.identity.accountId !== session.accountId || typeof exchanged.token !== "string" || !exchanged.token)
18779
18779
  throw new Error("Developers session identity mismatch");
18780
- const params = new URLSearchParams({ service: input.service, page: String(input.page), topic: input.topic ?? "app" });
18781
- for (const key of ["type", "level", "source", "requestId", "environment"]) if (input[key]) params.set(key, input[key]);
18780
+ const params = new URLSearchParams({ service: input.service, page: String(input.page), topic: input.topic ?? "application" });
18781
+ if (input.environment) params.set("environment", input.environment);
18782
+ if (input.fields) params.set("fields", JSON.stringify(input.fields));
18782
18783
  if (input.keyword) params.set("keyword", input.keyword);
18783
18784
  if (input.sinceMs !== void 0) params.set("sinceMs", String(input.sinceMs));
18784
18785
  return request2(`https://dev-api.pmate.chat/api/logs?${params}`, { headers: { Authorization: `Bearer ${exchanged.token}` } });
@@ -19526,7 +19527,7 @@ var ServiceRuntimeRunner = class {
19526
19527
  `git pull --rebase`,
19527
19528
  `pnpm install`,
19528
19529
  ...envSyncCommand ? [envSyncCommand] : [],
19529
- buildIfNeeded,
19530
+ `{ ${buildIfNeeded}; }`,
19530
19531
  `if [ -f "${appDir}/ecosystem.config.cjs" ]; then eco="${appDir}/ecosystem.config.cjs"; elif [ -f "${appDir}/ecosystem.config.js" ]; then eco="${appDir}/ecosystem.config.js"; else echo "Missing pm2 config: ${appDir}/ecosystem.config.cjs|.js" 1>&2; exit 2; fi`,
19531
19532
  pm2Start,
19532
19533
  pm2Reload
@@ -19804,10 +19805,7 @@ var ServiceRuntimeRunner = class {
19804
19805
  page: options.page,
19805
19806
  keyword: options.search,
19806
19807
  topic: options.topic,
19807
- type: options.logType,
19808
- level: options.level,
19809
- source: options.source,
19810
- requestId: options.requestId,
19808
+ fields: options.fields,
19811
19809
  environment: options.envName,
19812
19810
  sinceMs: options.sinceMs
19813
19811
  });
@@ -20707,7 +20705,7 @@ var ServiceCommandHandler = class {
20707
20705
  }
20708
20706
  case "log": {
20709
20707
  if (args.app) {
20710
- const result = await queryDeveloperLogs({ app: args.app, service: `${args.namespace}:${args.name}`, page: args.page, keyword: args.search, sinceMs: args.sinceMs, topic: args.topic, type: args.logType, level: args.level, source: args.source, requestId: args.requestId });
20708
+ const result = await queryDeveloperLogs({ app: args.app, service: `${args.namespace}:${args.name}`, page: args.page, keyword: args.search, sinceMs: args.sinceMs, topic: args.topic, fields: args.fields, environment: args.env });
20711
20709
  console.log(JSON.stringify(result, null, args.json ? void 0 : 2));
20712
20710
  return;
20713
20711
  }
@@ -20720,10 +20718,7 @@ var ServiceCommandHandler = class {
20720
20718
  follow: args.follow,
20721
20719
  envName: args.env,
20722
20720
  topic: args.topic,
20723
- level: args.level,
20724
- source: args.source,
20725
- requestId: args.requestId,
20726
- logType: args.logType,
20721
+ fields: args.fields,
20727
20722
  sinceMs: args.sinceMs,
20728
20723
  json: args.json
20729
20724
  });
@@ -24004,24 +23999,26 @@ function parseServiceArgs(tokens) {
24004
23999
  while (rest.length > 0) {
24005
24000
  const token = rest.shift();
24006
24001
  switch (token) {
24007
- case "--topic":
24008
- case "--level":
24009
- case "--source":
24010
- case "--request-id":
24011
- case "--type": {
24002
+ case "--topic": {
24012
24003
  if (action !== "log") throw new Error(`Unknown service ${action} option: ${token}`);
24013
24004
  const value = requireValue4(rest, token);
24014
- if (token === "--topic") {
24015
- if (value !== "app" && value !== "runtime") throw new Error("Invalid --topic");
24016
- logFilters.topic = value;
24017
- } else if (token === "--level") {
24018
- if (!["debug", "info", "warn", "error"].includes(value)) throw new Error("Invalid --level");
24019
- logFilters.level = value;
24020
- } else if (token === "--source") {
24021
- if (!["pm2", "nginx", "application", "deployment"].includes(value)) throw new Error("Invalid --source");
24022
- logFilters.source = value;
24023
- } else if (token === "--request-id") logFilters.requestId = value;
24024
- else logFilters.logType = value;
24005
+ if (!/^[a-z][a-z0-9-]{0,31}$/.test(value)) throw new Error("Invalid --topic");
24006
+ logFilters.topic = value;
24007
+ break;
24008
+ }
24009
+ case "--field": {
24010
+ if (action !== "log") throw new Error(`Unknown service ${action} option: ${token}`);
24011
+ const value = requireValue4(rest, token);
24012
+ const match = /^([a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*)=(.*)$/.exec(value);
24013
+ if (!match || match[1].length > 128 || match[2].length > 256) throw new Error("Use --field name=value");
24014
+ let parsed = match[2];
24015
+ try {
24016
+ parsed = JSON.parse(match[2]);
24017
+ } catch {
24018
+ }
24019
+ if (!["string", "number", "boolean"].includes(typeof parsed)) throw new Error("Field value must be text, number or boolean");
24020
+ logFilters.fields = { ...logFilters.fields, [match[1]]: parsed };
24021
+ if (Object.keys(logFilters.fields).length > 20) throw new Error("At most 20 field filters");
24025
24022
  break;
24026
24023
  }
24027
24024
  case "--app":
@@ -26321,7 +26318,7 @@ var HELP_TEXT = [
26321
26318
  ` ${import_chalk4.default.gray(" init <ns:objectId> [--cwd <dir>] [--base-url <url>]")}`,
26322
26319
  ` ${import_chalk4.default.gray(" ssl set <ns:objectId> --cert <key> [--base-url <url>] [--json]")}`,
26323
26320
  ` ${import_chalk4.default.gray(" ssl refresh <ns:objectId> [--cert <key>] [--dry-run] [--base-url <url>] [--json]")}`,
26324
- ` ${import_chalk4.default.gray(" log <ns:objectId> [--topic app|runtime] [--env <env>] [--level <level>] [--source <source>] [--type <type>] [--request-id <id>] [--search <keyword>] [--since-ms <ms>] [--page <n>] [--follow|-f] [--json]")}`,
26321
+ ` ${import_chalk4.default.gray(" log <ns:objectId> [--topic <topic>] [--env <env>] [--field <name=value>] [--search <keyword>] [--since-ms <ms>] [--page <n>] [--follow|-f] [--json]")}`,
26325
26322
  ` ${import_chalk4.default.gray(" default base URL: https://apps-api.pmate.chat")}`,
26326
26323
  ` ${import_chalk4.default.cyan("host")} Manage host-level environment variables`,
26327
26324
  ` ${import_chalk4.default.gray(" env list [--host <id>] [--json]")}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.32.0",
3
+ "version": "0.33.1",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {