@pmate/cli 0.8.11 → 0.9.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.
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const node_fs_1 = require("node:fs");
5
+ const node_os_1 = tslib_1.__importDefault(require("node:os"));
6
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
7
+ const vitest_1 = require("vitest");
8
+ const AgentCommandHandler_1 = require("../commands/AgentCommandHandler");
9
+ const types_1 = require("../types");
10
+ (0, vitest_1.describe)("AgentCommandHandler", () => {
11
+ const originalHome = process.env.HOME;
12
+ let tempDir;
13
+ (0, vitest_1.beforeEach)(() => {
14
+ tempDir = (0, node_fs_1.mkdtempSync)(node_path_1.default.join(node_os_1.default.tmpdir(), "pmate-agent-test-"));
15
+ process.env.HOME = tempDir;
16
+ (0, node_fs_1.mkdirSync)(node_path_1.default.join(tempDir, ".pmate"), { recursive: true });
17
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(tempDir, ".pmate", "session.json"), JSON.stringify({ token: "token-123" }, null, 2));
18
+ });
19
+ (0, vitest_1.afterEach)(() => {
20
+ process.env.HOME = originalHome;
21
+ vitest_1.vi.unstubAllGlobals();
22
+ (0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
23
+ });
24
+ (0, vitest_1.it)("lists agents through the API", async () => {
25
+ vitest_1.vi.stubGlobal("fetch", vitest_1.vi.fn().mockResolvedValue(new Response(JSON.stringify({
26
+ success: true,
27
+ data: {
28
+ accountId: "acct-admin",
29
+ items: [
30
+ {
31
+ id: "demo:writer",
32
+ namespace: "demo",
33
+ name: "writer",
34
+ status: "active",
35
+ version: 1,
36
+ },
37
+ ],
38
+ },
39
+ }), { status: 200, headers: { "content-type": "application/json" } })));
40
+ const logSpy = vitest_1.vi.spyOn(console, "log").mockImplementation(() => { });
41
+ const handler = new AgentCommandHandler_1.AgentCommandHandler();
42
+ await handler.handle({
43
+ type: types_1.Command.Agent,
44
+ action: "list",
45
+ namespace: "demo",
46
+ json: false,
47
+ baseUrl: "http://local",
48
+ });
49
+ (0, vitest_1.expect)(fetch).toHaveBeenCalledOnce();
50
+ (0, vitest_1.expect)(logSpy).toHaveBeenCalled();
51
+ });
52
+ (0, vitest_1.it)("creates agents from a json file", async () => {
53
+ const filePath = node_path_1.default.join(tempDir, "agent.json");
54
+ (0, node_fs_1.writeFileSync)(filePath, JSON.stringify({
55
+ name: "writer",
56
+ payload: {
57
+ id: "placeholder",
58
+ type: "LLM",
59
+ accuracy: "medium",
60
+ responseType: "text",
61
+ realtime: false,
62
+ variables: [{ name: "text", type: "text" }],
63
+ instruction: "Summarize the text.",
64
+ prompt: "{{text}}",
65
+ },
66
+ }));
67
+ vitest_1.vi.stubGlobal("fetch", vitest_1.vi.fn().mockResolvedValue(new Response(JSON.stringify({
68
+ success: true,
69
+ data: {
70
+ id: "demo:writer",
71
+ namespace: "demo",
72
+ name: "writer",
73
+ status: "active",
74
+ version: 1,
75
+ },
76
+ }), { status: 200, headers: { "content-type": "application/json" } })));
77
+ const logSpy = vitest_1.vi.spyOn(console, "log").mockImplementation(() => { });
78
+ const handler = new AgentCommandHandler_1.AgentCommandHandler();
79
+ await handler.handle({
80
+ type: types_1.Command.Agent,
81
+ action: "create",
82
+ namespace: "demo",
83
+ filePath,
84
+ json: true,
85
+ baseUrl: "http://local",
86
+ });
87
+ (0, vitest_1.expect)(fetch).toHaveBeenCalledOnce();
88
+ (0, vitest_1.expect)(logSpy).toHaveBeenCalled();
89
+ });
90
+ });
91
+ //# sourceMappingURL=AgentCommandHandler.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentCommandHandler.test.js","sourceRoot":"","sources":["../../src/tests/AgentCommandHandler.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const agentCommandParser_1 = require("../agentCommandParser");
5
+ (0, vitest_1.describe)("pmate agent parser", () => {
6
+ (0, vitest_1.it)("parses list arguments", () => {
7
+ (0, vitest_1.expect)((0, agentCommandParser_1.parseAgentArgs)(["list", "--namespace", "demo", "--json"])).toEqual({
8
+ type: "agent",
9
+ action: "list",
10
+ namespace: "demo",
11
+ baseUrl: undefined,
12
+ json: true,
13
+ });
14
+ });
15
+ (0, vitest_1.it)("parses create arguments", () => {
16
+ (0, vitest_1.expect)((0, agentCommandParser_1.parseAgentArgs)(["create", "demo", "--file", "agent.json", "--base-url", "http://local"])).toEqual({
17
+ type: "agent",
18
+ action: "create",
19
+ namespace: "demo",
20
+ filePath: "agent.json",
21
+ baseUrl: "http://local",
22
+ json: false,
23
+ });
24
+ });
25
+ (0, vitest_1.it)("rejects invalid invocations", () => {
26
+ (0, vitest_1.expect)(() => (0, agentCommandParser_1.parseAgentArgs)(["update", "demo"])).toThrow(/Usage: agent update/);
27
+ (0, vitest_1.expect)(() => (0, agentCommandParser_1.parseAgentArgs)(["create", "demo"])).toThrow(/Missing required option --file/);
28
+ });
29
+ });
30
+ //# sourceMappingURL=agentCommandParser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentCommandParser.test.js","sourceRoot":"","sources":["../../src/tests/agentCommandParser.test.ts"],"names":[],"mappings":";;AAAA,mCAA6C;AAC7C,8DAAsD;AAEtD,IAAA,iBAAQ,EAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAA,WAAE,EAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,IAAA,eAAM,EAAC,IAAA,mCAAc,EAAC,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACxE,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,SAAS;YAClB,IAAI,EAAE,IAAI;SACX,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,IAAA,eAAM,EACJ,IAAA,mCAAc,EAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC,CACzF,CAAC,OAAO,CAAC;YACR,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,MAAM;YACjB,QAAQ,EAAE,YAAY;YACtB,OAAO,EAAE,cAAc;YACvB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,mCAAc,EAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAA;QAC/E,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,mCAAc,EAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const shell_1 = require("../shell");
5
+ (0, vitest_1.describe)("shell helpers", () => {
6
+ (0, vitest_1.it)("quotes commands for bash -lc", () => {
7
+ (0, vitest_1.expect)((0, shell_1.quoteForBash)(`echo "hi" && printf '%s' 'done'`)).toBe(`'echo "hi" && printf '"'"'%s'"'"' '"'"'done'"'"''`);
8
+ });
9
+ (0, vitest_1.it)("builds a single remote ssh command argument", () => {
10
+ (0, vitest_1.expect)((0, shell_1.buildSshBashArgs)("pmate@example.com", `echo ok`)).toEqual([
11
+ "pmate@example.com",
12
+ `bash -lc 'echo ok'`,
13
+ ]);
14
+ });
15
+ });
16
+ //# sourceMappingURL=shell.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.test.js","sourceRoot":"","sources":["../../src/tests/shell.test.ts"],"names":[],"mappings":";;AAAA,mCAA6C;AAC7C,oCAAyD;AAEzD,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,IAAA,eAAM,EAAC,IAAA,oBAAY,EAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAC1D,mDAAmD,CACpD,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,IAAA,eAAM,EAAC,IAAA,wBAAgB,EAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/D,mBAAmB;YACnB,oBAAoB;SACrB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
package/dist/types.d.ts CHANGED
@@ -59,7 +59,8 @@ export declare enum Command {
59
59
  Oss = "oss",
60
60
  Qrcode = "qrcode",
61
61
  Random = "random",
62
- Collect = "collect"
62
+ Collect = "collect",
63
+ Agent = "agent"
63
64
  }
64
65
  export type NoneCommandArgs = {
65
66
  type: Command.None;
@@ -291,4 +292,40 @@ export type CollectCommandArgs = {
291
292
  mode: "list" | "thread";
292
293
  threadName?: string;
293
294
  };
294
- export type CommandArgs = NoneCommandArgs | ListCommandArgs | LoginCommandArgs | AddDnsCommandArgs | StsCommandArgs | BucketCommandArgs | DeployCommandArgs | LogCommandArgs | InitCommandArgs | DevCommandArgs | EnvCommandArgs | PrCommandArgs | CommitCommandArgs | SummaryCommandArgs | LinearCommandArgs | NotionCommandArgs | OssCommandArgs | QrcodeCommandArgs | RandomCommandArgs | CollectCommandArgs;
295
+ export type AgentCommandArgs = {
296
+ type: Command.Agent;
297
+ action: "list";
298
+ namespace?: string;
299
+ baseUrl?: string;
300
+ json: boolean;
301
+ } | {
302
+ type: Command.Agent;
303
+ action: "get";
304
+ namespace: string;
305
+ name: string;
306
+ baseUrl?: string;
307
+ json: boolean;
308
+ } | {
309
+ type: Command.Agent;
310
+ action: "create";
311
+ namespace: string;
312
+ filePath: string;
313
+ baseUrl?: string;
314
+ json: boolean;
315
+ } | {
316
+ type: Command.Agent;
317
+ action: "update";
318
+ namespace: string;
319
+ name: string;
320
+ filePath: string;
321
+ baseUrl?: string;
322
+ json: boolean;
323
+ } | {
324
+ type: Command.Agent;
325
+ action: "delete";
326
+ namespace: string;
327
+ name: string;
328
+ baseUrl?: string;
329
+ json: boolean;
330
+ };
331
+ export type CommandArgs = NoneCommandArgs | ListCommandArgs | LoginCommandArgs | AddDnsCommandArgs | StsCommandArgs | BucketCommandArgs | DeployCommandArgs | LogCommandArgs | InitCommandArgs | DevCommandArgs | EnvCommandArgs | PrCommandArgs | CommitCommandArgs | SummaryCommandArgs | LinearCommandArgs | NotionCommandArgs | OssCommandArgs | QrcodeCommandArgs | RandomCommandArgs | CollectCommandArgs | AgentCommandArgs;
package/dist/types.js CHANGED
@@ -23,5 +23,6 @@ var Command;
23
23
  Command["Qrcode"] = "qrcode";
24
24
  Command["Random"] = "random";
25
25
  Command["Collect"] = "collect";
26
+ Command["Agent"] = "agent";
26
27
  })(Command || (exports.Command = Command = {}));
27
28
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAmDA,IAAY,OAqBX;AArBD,WAAY,OAAO;IACjB,wBAAa,CAAA;IACb,wBAAa,CAAA;IACb,0BAAe,CAAA;IACf,6BAAkB,CAAA;IAClB,sBAAW,CAAA;IACX,4BAAiB,CAAA;IACjB,4BAAiB,CAAA;IACjB,sBAAW,CAAA;IACX,wBAAa,CAAA;IACb,sBAAW,CAAA;IACX,sBAAW,CAAA;IACX,oBAAS,CAAA;IACT,4BAAiB,CAAA;IACjB,8BAAmB,CAAA;IACnB,4BAAiB,CAAA;IACjB,4BAAiB,CAAA;IACjB,sBAAW,CAAA;IACX,4BAAiB,CAAA;IACjB,4BAAiB,CAAA;IACjB,8BAAmB,CAAA;AACrB,CAAC,EArBW,OAAO,uBAAP,OAAO,QAqBlB"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAmDA,IAAY,OAsBX;AAtBD,WAAY,OAAO;IACjB,wBAAa,CAAA;IACb,wBAAa,CAAA;IACb,0BAAe,CAAA;IACf,6BAAkB,CAAA;IAClB,sBAAW,CAAA;IACX,4BAAiB,CAAA;IACjB,4BAAiB,CAAA;IACjB,sBAAW,CAAA;IACX,wBAAa,CAAA;IACb,sBAAW,CAAA;IACX,sBAAW,CAAA;IACX,oBAAS,CAAA;IACT,4BAAiB,CAAA;IACjB,8BAAmB,CAAA;IACnB,4BAAiB,CAAA;IACjB,4BAAiB,CAAA;IACjB,sBAAW,CAAA;IACX,4BAAiB,CAAA;IACjB,4BAAiB,CAAA;IACjB,8BAAmB,CAAA;IACnB,0BAAe,CAAA;AACjB,CAAC,EAtBW,OAAO,uBAAP,OAAO,QAsBlB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.8.11",
3
+ "version": "0.9.0",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -17,6 +17,7 @@
17
17
  "dev": "ts-node src/index.ts",
18
18
  "release": "npm publish",
19
19
  "start": "node dist/index.js",
20
+ "test": "vitest run src/tests",
20
21
  "typecheck": "tsc --noEmit",
21
22
  "prepare": "npm run build"
22
23
  },
@@ -54,6 +55,7 @@
54
55
  "@types/pngjs": "^6.0.5",
55
56
  "rimraf": "^6.1.2",
56
57
  "ts-node": "^10.9.2",
57
- "typescript": "^5.9.3"
58
+ "typescript": "^5.9.3",
59
+ "vitest": "^4.0.17"
58
60
  }
59
61
  }