@pmate/cli 0.20.10 → 0.21.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 CHANGED
@@ -418,6 +418,17 @@ type AgentCommandArgs = {
418
418
  name: string;
419
419
  baseUrl?: string;
420
420
  json: boolean;
421
+ } | {
422
+ type: Command.Agent;
423
+ action: "call";
424
+ namespace: string;
425
+ name: string;
426
+ payload?: Record<string, unknown>;
427
+ filePath?: string;
428
+ baseUrl?: string;
429
+ hubBaseUrl?: string;
430
+ from?: string;
431
+ json: boolean;
421
432
  } | {
422
433
  type: Command.Agent;
423
434
  action: "rename";
@@ -543,6 +554,7 @@ type ServiceCommandArgs = {
543
554
  action: "list";
544
555
  namespace?: string;
545
556
  repository?: string;
557
+ server?: string;
546
558
  baseUrl?: string;
547
559
  json: boolean;
548
560
  } | {
package/dist/index.js CHANGED
@@ -158,7 +158,15 @@ function loadExistingSessionStoreOrEmpty() {
158
158
  sessions: {}
159
159
  };
160
160
  }
161
- return loadSessionStore();
161
+ try {
162
+ return loadSessionStore();
163
+ } catch {
164
+ return {
165
+ version: SESSION_STORE_VERSION,
166
+ activeAppRef: DEFAULT_APP_ID,
167
+ sessions: {}
168
+ };
169
+ }
162
170
  }
163
171
  function loadSessionStoreWithPath() {
164
172
  const sessionPath = buildSessionStorePath();
@@ -12683,12 +12691,15 @@ var init_AgentLlmClient = __esm({
12683
12691
  }
12684
12692
  async prompt(name, payload, namespace = DEFAULT_NAMESPACE) {
12685
12693
  const agentId = `${namespace}:${name}`;
12694
+ return this.call(agentId, payload);
12695
+ }
12696
+ async call(agentId, payload, options) {
12686
12697
  const client = new import_agent_sdk.AgentClient({
12687
- baseUrl: this.hubBaseUrl,
12698
+ baseUrl: options?.hubBaseUrl ?? this.hubBaseUrl,
12688
12699
  agentService: this.agentService
12689
12700
  });
12690
12701
  try {
12691
- await client.login(this.from, {
12702
+ await client.login(options?.from ?? this.from, {
12692
12703
  token: this.token
12693
12704
  });
12694
12705
  const result = await client.prompt({
@@ -19108,6 +19119,7 @@ function parseMessageText(raw) {
19108
19119
  // src/commands/AgentCommandHandler.ts
19109
19120
  var import_node_fs11 = require("fs");
19110
19121
  var import_node_path16 = __toESM(require("path"));
19122
+ init_AgentLlmClient();
19111
19123
  init_sessionStore();
19112
19124
 
19113
19125
  // src/storeClient.ts
@@ -19476,6 +19488,25 @@ var AgentCommandHandler = class {
19476
19488
  this.renderJson(record, args.json);
19477
19489
  return;
19478
19490
  }
19491
+ case "call": {
19492
+ const payload = args.filePath ? this.readJsonObjectFile(args.filePath) : args.payload;
19493
+ const client = this.createRuntimeClient({
19494
+ token,
19495
+ agentApiBaseUrl: baseUrl,
19496
+ hubBaseUrl: args.hubBaseUrl,
19497
+ from: args.from
19498
+ });
19499
+ const result = await client.call(
19500
+ formatNamespacedDisplayId(args.namespace, args.name),
19501
+ payload,
19502
+ {
19503
+ hubBaseUrl: args.hubBaseUrl,
19504
+ from: args.from
19505
+ }
19506
+ );
19507
+ this.renderCallResult(result, args.json);
19508
+ return;
19509
+ }
19479
19510
  case "delete": {
19480
19511
  const record = await this.request(
19481
19512
  baseUrl,
@@ -19547,6 +19578,14 @@ var AgentCommandHandler = class {
19547
19578
  throw new Error(`Invalid JSON in ${absolutePath}: ${message}`);
19548
19579
  }
19549
19580
  }
19581
+ readJsonObjectFile(filePath) {
19582
+ const parsed = this.readJsonFile(filePath);
19583
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
19584
+ const absolutePath = import_node_path16.default.resolve(process.cwd(), filePath);
19585
+ throw new Error(`Invalid JSON in ${absolutePath}: expected an object`);
19586
+ }
19587
+ return parsed;
19588
+ }
19550
19589
  async request(baseUrl, token, method, pathname, body) {
19551
19590
  const response = await fetch(`${baseUrl}${pathname}`, {
19552
19591
  method,
@@ -19589,6 +19628,24 @@ var AgentCommandHandler = class {
19589
19628
  }
19590
19629
  ui.plain(JSON.stringify(value, null, 2));
19591
19630
  }
19631
+ renderCallResult(value, asJson) {
19632
+ if (value === null) {
19633
+ if (asJson) {
19634
+ this.renderJson(value, true);
19635
+ return;
19636
+ }
19637
+ ui.warn("Agent returned no result.");
19638
+ return;
19639
+ }
19640
+ if (typeof value === "string" && !asJson) {
19641
+ ui.plain(value);
19642
+ return;
19643
+ }
19644
+ this.renderJson(value, true);
19645
+ }
19646
+ createRuntimeClient(options) {
19647
+ return new AgentLlmClient(options);
19648
+ }
19592
19649
  renderNamespaces(items, asJson) {
19593
19650
  if (asJson) {
19594
19651
  ui.plain(JSON.stringify(items, null, 2));
@@ -20960,15 +21017,24 @@ var ServiceRegistryClient = class {
20960
21017
  if (repository) {
20961
21018
  searchParams.set("repo", repository);
20962
21019
  }
21020
+ const server = filters?.server?.trim();
21021
+ if (server) {
21022
+ searchParams.set("server", server);
21023
+ }
20963
21024
  const payload = await this.request(
20964
21025
  "GET",
20965
21026
  `/services${searchParams.size > 0 ? `?${searchParams.toString()}` : ""}`
20966
21027
  );
20967
21028
  const namespace = filters?.namespace?.trim();
20968
- if (!namespace) {
20969
- return payload.items;
20970
- }
20971
- return payload.items.filter((item) => item.namespace === namespace);
21029
+ return payload.items.filter((item) => {
21030
+ if (namespace && item.namespace !== namespace) {
21031
+ return false;
21032
+ }
21033
+ if (server && item.deploy?.server?.trim() !== server) {
21034
+ return false;
21035
+ }
21036
+ return true;
21037
+ });
20972
21038
  }
20973
21039
  async getService(namespace, name) {
20974
21040
  return this.request(
@@ -21038,7 +21104,8 @@ var ServiceCommandHandler = class {
21038
21104
  case "list": {
21039
21105
  const items = await registry.listServices({
21040
21106
  namespace: args.namespace,
21041
- repository: args.repository
21107
+ repository: args.repository,
21108
+ server: args.server
21042
21109
  });
21043
21110
  this.renderList(items, args.json);
21044
21111
  return;
@@ -21052,6 +21119,7 @@ var ServiceCommandHandler = class {
21052
21119
  case "create": {
21053
21120
  const payload = this.readJsonFile(args.filePath);
21054
21121
  await this.requireNamespace(payload, baseUrl);
21122
+ await this.requireUniqueServerPort(payload, registry);
21055
21123
  const record = await this.request(
21056
21124
  baseUrl,
21057
21125
  "POST",
@@ -21064,6 +21132,10 @@ var ServiceCommandHandler = class {
21064
21132
  }
21065
21133
  case "update": {
21066
21134
  const payload = this.readJsonFile(args.filePath);
21135
+ await this.requireUniqueServerPort(payload, registry, {
21136
+ namespace: args.namespace,
21137
+ name: args.name
21138
+ });
21067
21139
  const record = await this.request(
21068
21140
  baseUrl,
21069
21141
  "PUT",
@@ -21176,6 +21248,37 @@ var ServiceCommandHandler = class {
21176
21248
  throw new Error(`Namespace "${namespace}" is not registered. Run: pmate ns create ${namespace}`);
21177
21249
  }
21178
21250
  }
21251
+ async requireUniqueServerPort(payload, registry, currentService) {
21252
+ if (!payload || typeof payload !== "object") {
21253
+ return;
21254
+ }
21255
+ const deploy = payload.deploy;
21256
+ if (!deploy || typeof deploy !== "object") {
21257
+ return;
21258
+ }
21259
+ const serverValue = deploy.server;
21260
+ const portValue = deploy.port;
21261
+ const server = typeof serverValue === "string" ? serverValue.trim() : "";
21262
+ const port = typeof portValue === "number" ? portValue : typeof portValue === "string" && portValue.trim() ? Number(portValue) : void 0;
21263
+ if (!server || port === void 0 || !Number.isFinite(port)) {
21264
+ return;
21265
+ }
21266
+ const services = await registry.listServices({ server });
21267
+ const conflict = services.find((service) => {
21268
+ if (service.deploy?.port !== port) {
21269
+ return false;
21270
+ }
21271
+ if (!currentService) {
21272
+ return true;
21273
+ }
21274
+ return !(service.namespace === currentService.namespace && service.name === currentService.name);
21275
+ });
21276
+ if (conflict) {
21277
+ throw new Error(
21278
+ `Port ${port} is already used on server ${server} by ${formatNamespacedDisplayId(conflict.namespace, conflict.name)}`
21279
+ );
21280
+ }
21281
+ }
21179
21282
  renderList(items, asJson) {
21180
21283
  if (asJson) {
21181
21284
  ui.plain(JSON.stringify(items, null, 2));
@@ -21186,11 +21289,7 @@ var ServiceCommandHandler = class {
21186
21289
  return;
21187
21290
  }
21188
21291
  for (const item of items) {
21189
- ui.info(formatNamespacedDisplayId(item.namespace, item.name), {
21190
- kind: item.kind,
21191
- runtimeType: item.runtimeType,
21192
- status: item.status
21193
- });
21292
+ ui.info(formatNamespacedDisplayId(item.namespace, item.name), item);
21194
21293
  }
21195
21294
  }
21196
21295
  renderJson(value, asJson) {
@@ -21552,7 +21651,7 @@ function parseAgentArgs(tokens) {
21552
21651
  const rawAction = rest.shift();
21553
21652
  const action = rawAction === "view" ? "view" : rawAction;
21554
21653
  if (!action) {
21555
- throw new Error("Missing agent action. Use: agent namespaces|list|get|view|create|update|rename|delete");
21654
+ throw new Error("Missing agent action. Use: agent namespaces|list|get|view|create|update|rename|call|delete");
21556
21655
  }
21557
21656
  let baseUrl;
21558
21657
  let json = false;
@@ -21716,6 +21815,62 @@ function parseAgentArgs(tokens) {
21716
21815
  json
21717
21816
  };
21718
21817
  }
21818
+ if (action === "call") {
21819
+ const ref = rest.shift();
21820
+ if (!ref) {
21821
+ throw new Error(
21822
+ "Usage: agent call <ns:objectId> [--payload <json>] [--file <path>] [--base-url <url>] [--hub-base-url <url>] [--from <id>] [--json]"
21823
+ );
21824
+ }
21825
+ const parsed = parseNamespacedRef(ref, { entityLabel: "agent ref" });
21826
+ let filePath;
21827
+ let payload;
21828
+ let hubBaseUrl;
21829
+ let from;
21830
+ while (rest.length > 0) {
21831
+ const token = rest.shift();
21832
+ switch (token) {
21833
+ case "--payload":
21834
+ if (filePath) {
21835
+ throw new Error("Agent call accepts either --payload or --file, not both.");
21836
+ }
21837
+ payload = parseJsonObject(requireValue(rest, token), token);
21838
+ break;
21839
+ case "--file":
21840
+ if (payload) {
21841
+ throw new Error("Agent call accepts either --payload or --file, not both.");
21842
+ }
21843
+ filePath = requireValue(rest, token);
21844
+ break;
21845
+ case "--base-url":
21846
+ baseUrl = requireValue(rest, token);
21847
+ break;
21848
+ case "--hub-base-url":
21849
+ hubBaseUrl = requireValue(rest, token);
21850
+ break;
21851
+ case "--from":
21852
+ from = requireValue(rest, token);
21853
+ break;
21854
+ case "--json":
21855
+ json = true;
21856
+ break;
21857
+ default:
21858
+ throw new Error(`Unknown agent call option: ${token}`);
21859
+ }
21860
+ }
21861
+ return {
21862
+ type: "agent" /* Agent */,
21863
+ action,
21864
+ namespace: parsed.namespace,
21865
+ name: parsed.objectId,
21866
+ payload,
21867
+ filePath,
21868
+ baseUrl,
21869
+ hubBaseUrl,
21870
+ from,
21871
+ json
21872
+ };
21873
+ }
21719
21874
  if (action === "rename") {
21720
21875
  let namespace;
21721
21876
  let from;
@@ -21774,6 +21929,19 @@ function parseBareRenameId(value, entityName) {
21774
21929
  }
21775
21930
  return normalized;
21776
21931
  }
21932
+ function parseJsonObject(value, optionName) {
21933
+ let parsed;
21934
+ try {
21935
+ parsed = JSON.parse(value);
21936
+ } catch (error) {
21937
+ const message = error instanceof Error ? error.message : String(error);
21938
+ throw new Error(`Invalid JSON for ${optionName}: ${message}`);
21939
+ }
21940
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
21941
+ throw new Error(`Invalid JSON for ${optionName}: expected an object.`);
21942
+ }
21943
+ return parsed;
21944
+ }
21777
21945
 
21778
21946
  // src/nsCommandParser.ts
21779
21947
  var DEFAULT_CHAIN = "pmate";
@@ -22257,6 +22425,7 @@ function parseServiceArgs(tokens) {
22257
22425
  if (action === "list") {
22258
22426
  let namespace;
22259
22427
  let repository;
22428
+ let server;
22260
22429
  while (rest.length > 0) {
22261
22430
  const token = rest.shift();
22262
22431
  switch (token) {
@@ -22266,6 +22435,9 @@ function parseServiceArgs(tokens) {
22266
22435
  case "--repo":
22267
22436
  repository = requireValue5(rest, token);
22268
22437
  break;
22438
+ case "--server":
22439
+ server = requireValue5(rest, token);
22440
+ break;
22269
22441
  case "--base-url":
22270
22442
  baseUrl = requireValue5(rest, token);
22271
22443
  break;
@@ -22276,7 +22448,7 @@ function parseServiceArgs(tokens) {
22276
22448
  throw new Error(`Unknown service list option: ${token}`);
22277
22449
  }
22278
22450
  }
22279
- return { type: "service" /* Service */, action, namespace, repository, baseUrl, json };
22451
+ return { type: "service" /* Service */, action, namespace, repository, server, baseUrl, json };
22280
22452
  }
22281
22453
  if (action === "view") {
22282
22454
  const ref = rest.shift();
@@ -22777,7 +22949,7 @@ var HELP_TEXT = [
22777
22949
  ` ${import_chalk4.default.cyan("collect")} Collect threads/messages from Electron chat app via CDP`,
22778
22950
  ` ${import_chalk4.default.gray(" --list [--endpoint <url>] [--json]")}`,
22779
22951
  ` ${import_chalk4.default.gray(" --thread <name> [--endpoint <url>] [--json]")}`,
22780
- ` ${import_chalk4.default.cyan("agent")} Manage agent registry entries via agent-ui-api`,
22952
+ ` ${import_chalk4.default.cyan("agent")} Manage agent registry entries and call agents for debugging`,
22781
22953
  ` ${import_chalk4.default.gray(" namespaces [--base-url <url>] [--json]")}`,
22782
22954
  ` ${import_chalk4.default.gray(" list [--namespace <ns>] [--base-url <url>] [--json]")}`,
22783
22955
  ` ${import_chalk4.default.gray(" get <ns:objectId> [--base-url <url>] [--json]")}`,
@@ -22785,8 +22957,9 @@ var HELP_TEXT = [
22785
22957
  ` ${import_chalk4.default.gray(" create [<namespace>] --file <path> [--base-url <url>] [--json]")}`,
22786
22958
  ` ${import_chalk4.default.gray(" update <ns:objectId> --file <path> [--base-url <url>] [--json]")}`,
22787
22959
  ` ${import_chalk4.default.gray(" rename --from <id> --to <id> --ns <namespace> [--base-url <url>] [--json]")}`,
22960
+ ` ${import_chalk4.default.gray(" call <ns:objectId> [--payload <json>] [--file <path>] [--base-url <url>] [--hub-base-url <url>] [--from <id>] [--json]")}`,
22788
22961
  ` ${import_chalk4.default.gray(" delete <ns:objectId> [--base-url <url>] [--json]")}`,
22789
- ` ${import_chalk4.default.gray(" list defaults to all namespaces; create defaults to namespace: pmate; default base URL: https://agent-api.pmate.chat")}`,
22962
+ ` ${import_chalk4.default.gray(" list defaults to all namespaces; create defaults to namespace: pmate; default base URL: https://agent-api.pmate.chat; call uses pmate:cli session and default hub: https://hub.pmate.chat")}`,
22790
22963
  ` ${import_chalk4.default.cyan("ns")} Manage registered namespaces`,
22791
22964
  ` ${import_chalk4.default.gray(" list [--chain <chain>] [--base-url <url>] [--json]")}`,
22792
22965
  ` ${import_chalk4.default.gray(" get <namespace> [--chain <chain>] [--base-url <url>] [--json]")}`,
@@ -22816,7 +22989,7 @@ var HELP_TEXT = [
22816
22989
  ` ${import_chalk4.default.gray(" delete <ns:objectId> [--base-url <url>] [--json]")}`,
22817
22990
  ` ${import_chalk4.default.gray(" default base URL: https://apps-api.pmate.chat")}`,
22818
22991
  ` ${import_chalk4.default.cyan("service")} Manage service registry entries via apps-api`,
22819
- ` ${import_chalk4.default.gray(" list [--namespace <ns>] [--repo <owner/name|https://github.com/owner/name>] [--base-url <url>] [--json]")}`,
22992
+ ` ${import_chalk4.default.gray(" list [--namespace <ns>] [--repo <owner/name|https://github.com/owner/name>] [--server <name>] [--base-url <url>] [--json]")}`,
22820
22993
  ` ${import_chalk4.default.gray(" get <ns:objectId> [--base-url <url>] [--json]")}`,
22821
22994
  ` ${import_chalk4.default.gray(" view <ns:objectId> [--base-url <url>]")}`,
22822
22995
  ` ${import_chalk4.default.gray(" create --file <path> [--base-url <url>] [--json]")}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.20.10",
3
+ "version": "0.21.0",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {