@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 +12 -0
- package/dist/index.js +191 -18
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
20969
|
-
|
|
20970
|
-
|
|
20971
|
-
|
|
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
|
|
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]")}`,
|