@oxagen/cli 0.4.0 → 0.5.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 (109) hide show
  1. package/README.md +2 -2
  2. package/dist/commands/agent.mcp.consent.list.d.ts +3 -0
  3. package/dist/commands/agent.mcp.consent.list.d.ts.map +1 -0
  4. package/dist/commands/agent.mcp.consent.list.js +30 -0
  5. package/dist/commands/agent.mcp.consent.list.js.map +1 -0
  6. package/dist/commands/agent.mcp.consent.resolve.d.ts +3 -0
  7. package/dist/commands/agent.mcp.consent.resolve.d.ts.map +1 -0
  8. package/dist/commands/agent.mcp.consent.resolve.js +34 -0
  9. package/dist/commands/agent.mcp.consent.resolve.js.map +1 -0
  10. package/dist/commands/agent.mcp.delete.d.ts +3 -0
  11. package/dist/commands/agent.mcp.delete.d.ts.map +1 -0
  12. package/dist/commands/agent.mcp.delete.js +27 -0
  13. package/dist/commands/agent.mcp.delete.js.map +1 -0
  14. package/dist/commands/agent.mcp.set_enabled.d.ts +3 -0
  15. package/dist/commands/agent.mcp.set_enabled.d.ts.map +1 -0
  16. package/dist/commands/agent.mcp.set_enabled.js +33 -0
  17. package/dist/commands/agent.mcp.set_enabled.js.map +1 -0
  18. package/dist/commands/audit.log.query.d.ts +3 -0
  19. package/dist/commands/audit.log.query.d.ts.map +1 -0
  20. package/dist/commands/audit.log.query.js +42 -0
  21. package/dist/commands/audit.log.query.js.map +1 -0
  22. package/dist/commands/automation.create.d.ts.map +1 -1
  23. package/dist/commands/automation.create.js +43 -4
  24. package/dist/commands/automation.create.js.map +1 -1
  25. package/dist/commands/automation.disable.d.ts +3 -0
  26. package/dist/commands/automation.disable.d.ts.map +1 -0
  27. package/dist/commands/automation.disable.js +24 -0
  28. package/dist/commands/automation.disable.js.map +1 -0
  29. package/dist/commands/automation.enable.d.ts +3 -0
  30. package/dist/commands/automation.enable.d.ts.map +1 -0
  31. package/dist/commands/automation.enable.js +24 -0
  32. package/dist/commands/automation.enable.js.map +1 -0
  33. package/dist/commands/automation.update.d.ts +3 -0
  34. package/dist/commands/automation.update.d.ts.map +1 -0
  35. package/dist/commands/automation.update.js +42 -0
  36. package/dist/commands/automation.update.js.map +1 -0
  37. package/dist/commands/conversation.files.list.d.ts +3 -0
  38. package/dist/commands/conversation.files.list.d.ts.map +1 -0
  39. package/dist/commands/conversation.files.list.js +39 -0
  40. package/dist/commands/conversation.files.list.js.map +1 -0
  41. package/dist/commands/markdown.generate.d.ts +3 -0
  42. package/dist/commands/markdown.generate.d.ts.map +1 -0
  43. package/dist/commands/markdown.generate.js +37 -0
  44. package/dist/commands/markdown.generate.js.map +1 -0
  45. package/dist/commands/mermaid.generate.d.ts +3 -0
  46. package/dist/commands/mermaid.generate.d.ts.map +1 -0
  47. package/dist/commands/mermaid.generate.js +33 -0
  48. package/dist/commands/mermaid.generate.js.map +1 -0
  49. package/dist/commands/ontology.neighbors.d.ts +3 -0
  50. package/dist/commands/ontology.neighbors.d.ts.map +1 -0
  51. package/dist/commands/ontology.neighbors.js +34 -0
  52. package/dist/commands/ontology.neighbors.js.map +1 -0
  53. package/dist/commands/ontology.query.d.ts +3 -0
  54. package/dist/commands/ontology.query.d.ts.map +1 -0
  55. package/dist/commands/ontology.query.js +36 -0
  56. package/dist/commands/ontology.query.js.map +1 -0
  57. package/dist/commands/privacy.erase.d.ts.map +1 -1
  58. package/dist/commands/privacy.erase.js +2 -1
  59. package/dist/commands/privacy.erase.js.map +1 -1
  60. package/dist/commands/privacy.erase.test.d.ts +2 -0
  61. package/dist/commands/privacy.erase.test.d.ts.map +1 -0
  62. package/dist/commands/privacy.erase.test.js +125 -0
  63. package/dist/commands/privacy.erase.test.js.map +1 -0
  64. package/dist/commands/skill.edit.d.ts +3 -0
  65. package/dist/commands/skill.edit.d.ts.map +1 -0
  66. package/dist/commands/skill.edit.js +28 -0
  67. package/dist/commands/skill.edit.js.map +1 -0
  68. package/dist/commands/skill.export.d.ts +3 -0
  69. package/dist/commands/skill.export.d.ts.map +1 -0
  70. package/dist/commands/skill.export.js +25 -0
  71. package/dist/commands/skill.export.js.map +1 -0
  72. package/dist/commands/skill.metrics.read.d.ts +3 -0
  73. package/dist/commands/skill.metrics.read.d.ts.map +1 -0
  74. package/dist/commands/skill.metrics.read.js +56 -0
  75. package/dist/commands/skill.metrics.read.js.map +1 -0
  76. package/dist/commands/skill.version.activate.d.ts +3 -0
  77. package/dist/commands/skill.version.activate.d.ts.map +1 -0
  78. package/dist/commands/skill.version.activate.js +24 -0
  79. package/dist/commands/skill.version.activate.js.map +1 -0
  80. package/dist/commands/skill.version.get.d.ts +3 -0
  81. package/dist/commands/skill.version.get.d.ts.map +1 -0
  82. package/dist/commands/skill.version.get.js +43 -0
  83. package/dist/commands/skill.version.get.js.map +1 -0
  84. package/dist/commands/skill.version.list.d.ts +3 -0
  85. package/dist/commands/skill.version.list.d.ts.map +1 -0
  86. package/dist/commands/skill.version.list.js +38 -0
  87. package/dist/commands/skill.version.list.js.map +1 -0
  88. package/dist/commands/skill.version.upload.d.ts +3 -0
  89. package/dist/commands/skill.version.upload.d.ts.map +1 -0
  90. package/dist/commands/skill.version.upload.js +28 -0
  91. package/dist/commands/skill.version.upload.js.map +1 -0
  92. package/dist/commands/skill.workspace.install.d.ts +3 -0
  93. package/dist/commands/skill.workspace.install.d.ts.map +1 -0
  94. package/dist/commands/skill.workspace.install.js +52 -0
  95. package/dist/commands/skill.workspace.install.js.map +1 -0
  96. package/dist/commands.test.js +117 -73
  97. package/dist/commands.test.js.map +1 -1
  98. package/dist/components/DevStatus.d.ts.map +1 -1
  99. package/dist/components/DevStatus.js +1 -1
  100. package/dist/components/DevStatus.js.map +1 -1
  101. package/dist/index.js +53 -7
  102. package/dist/index.js.map +1 -1
  103. package/dist/lib/config.d.ts.map +1 -1
  104. package/dist/lib/config.js +9 -2
  105. package/dist/lib/config.js.map +1 -1
  106. package/dist/lib/config.test.js +21 -3
  107. package/dist/lib/config.test.js.map +1 -1
  108. package/package.json +1 -1
  109. package/README.html +0 -379
@@ -0,0 +1,38 @@
1
+ import { Command } from "commander";
2
+ import { apiRequest, ApiError } from "../lib/api-client.js";
3
+ export const skillVersionListCommand = new Command("list")
4
+ .description("List the version history for a skill")
5
+ .requiredOption("-s, --skill <id>", "Skill public ID (e.g. skl_...)")
6
+ .option("-l, --limit <n>", "Maximum versions to return (default 20)", parseInt)
7
+ .option("-o, --offset <n>", "Pagination offset (default 0)", parseInt)
8
+ .action(async (options) => {
9
+ try {
10
+ const params = new URLSearchParams({ skill_id: options.skill });
11
+ if (options.limit !== undefined)
12
+ params.set("limit", String(options.limit));
13
+ if (options.offset !== undefined)
14
+ params.set("offset", String(options.offset));
15
+ const data = await apiRequest(`/skill/version/list?${params.toString()}`);
16
+ if (data.versions.length === 0) {
17
+ console.log(`No versions found for skill ${data.skill_id}.`);
18
+ return;
19
+ }
20
+ console.log(`Skill ${data.skill_id} — ${data.total} version(s):`);
21
+ for (const v of data.versions) {
22
+ const flags = [];
23
+ if (v.isActive)
24
+ flags.push("active");
25
+ if (v.isLatest)
26
+ flags.push("latest");
27
+ const flagStr = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
28
+ const by = v.createdBy ? ` by ${v.createdBy}` : "";
29
+ console.log(` v${v.versionNumber} ${v.id}${flagStr} ${v.createdAt}${by}`);
30
+ }
31
+ }
32
+ catch (err) {
33
+ const msg = err instanceof ApiError ? err.message : String(err);
34
+ console.error(`Error: ${msg}`);
35
+ process.exit(1);
36
+ }
37
+ });
38
+ //# sourceMappingURL=skill.version.list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.version.list.js","sourceRoot":"","sources":["../../src/commands/skill.version.list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAiB5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KACvD,WAAW,CAAC,sCAAsC,CAAC;KACnD,cAAc,CAAC,kBAAkB,EAAE,gCAAgC,CAAC;KACpE,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,EAAE,QAAQ,CAAC;KAC9E,MAAM,CAAC,kBAAkB,EAAE,+BAA+B,EAAE,QAAQ,CAAC;KACrE,MAAM,CAAC,KAAK,EAAE,OAA2D,EAAE,EAAE;IAC5E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,uBAAuB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAC3C,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,KAAK,cAAc,CAAC,CAAC;QAClE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,CAAC,CAAC,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,EAAE,GAAG,OAAO,KAAK,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const skillVersionUploadCommand: Command;
3
+ //# sourceMappingURL=skill.version.upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.version.upload.d.ts","sourceRoot":"","sources":["../../src/commands/skill.version.upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,yBAAyB,SA0BlC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { Command } from "commander";
2
+ import { readFile } from "node:fs/promises";
3
+ import { apiRequest, ApiError } from "../lib/api-client.js";
4
+ export const skillVersionUploadCommand = new Command("upload")
5
+ .description("Upload a new immutable version of a skill from a .skill.md file")
6
+ .requiredOption("-s, --skill <id>", "Skill public ID (e.g. skl_…)")
7
+ .requiredOption("-f, --file <path>", "Path to the .skill.md file to upload")
8
+ .option("--no-activate", "Upload without setting as the active version (default: activate)")
9
+ .action(async (options) => {
10
+ try {
11
+ const body = await readFile(options.file, "utf8");
12
+ const data = await apiRequest("/skill/version/upload", {
13
+ method: "POST",
14
+ body: JSON.stringify({
15
+ skill_id: options.skill,
16
+ body,
17
+ activate: options.activate,
18
+ }),
19
+ });
20
+ console.log(`Uploaded skill ${data.skill_id} → version ${data.version_number} (${data.version_id})${data.activated ? " [active]" : ""}`);
21
+ }
22
+ catch (err) {
23
+ const msg = err instanceof ApiError ? err.message : String(err);
24
+ console.error(`Error: ${msg}`);
25
+ process.exit(1);
26
+ }
27
+ });
28
+ //# sourceMappingURL=skill.version.upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.version.upload.js","sourceRoot":"","sources":["../../src/commands/skill.version.upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAS5D,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC3D,WAAW,CAAC,iEAAiE,CAAC;KAC9E,cAAc,CAAC,kBAAkB,EAAE,8BAA8B,CAAC;KAClE,cAAc,CAAC,mBAAmB,EAAE,sCAAsC,CAAC;KAC3E,MAAM,CAAC,eAAe,EAAE,kEAAkE,CAAC;KAC3F,MAAM,CAAC,KAAK,EAAE,OAA2D,EAAE,EAAE;IAC5E,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAElD,MAAM,IAAI,GAAG,MAAM,UAAU,CAA6B,uBAAuB,EAAE;YACjF,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,QAAQ,EAAE,OAAO,CAAC,KAAK;gBACvB,IAAI;gBACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC;SACH,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CACT,kBAAkB,IAAI,CAAC,QAAQ,cAAc,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5H,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const skillWorkspaceInstallCommand: Command;
3
+ //# sourceMappingURL=skill.workspace.install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.workspace.install.d.ts","sourceRoot":"","sources":["../../src/commands/skill.workspace.install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,4BAA4B,SA4DtC,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { Command } from "commander";
2
+ import { apiRequest, ApiError } from "../lib/api-client.js";
3
+ import { getWorkspaceId } from "../lib/config.js";
4
+ export const skillWorkspaceInstallCommand = new Command("install")
5
+ .description("Install a skill into the workspace from a builtin template or a custom definition")
6
+ .option("-s, --slug <slug>", "Slug of a builtin skill template to install (e.g. 'summarization')")
7
+ .option("-n, --name <name>", "Name for a custom skill (use with --body)")
8
+ .option("-b, --body <body>", "Body/content of a custom skill definition (use with --name)")
9
+ .option("-r, --references <refs...>", "Reference paths for a custom skill")
10
+ .option("-w, --workspace <id>", "Workspace ID (defaults to current workspace)")
11
+ .action(async (options) => {
12
+ try {
13
+ if (!options.slug && !options.name) {
14
+ console.error("Error: Either --slug (builtin template) or --name + --body (custom) must be provided.");
15
+ process.exit(1);
16
+ }
17
+ const payload = {};
18
+ if (options.slug) {
19
+ payload.slug = options.slug;
20
+ }
21
+ else {
22
+ if (!options.body) {
23
+ console.error("Error: --body is required when installing a custom skill.");
24
+ process.exit(1);
25
+ }
26
+ payload.custom = {
27
+ name: options.name,
28
+ body: options.body,
29
+ ...(options.references ? { references: options.references } : {}),
30
+ };
31
+ }
32
+ const workspaceId = options.workspace ?? getWorkspaceId();
33
+ if (workspaceId)
34
+ payload.workspace_id = workspaceId;
35
+ const data = await apiRequest("/skill/workspace/install", {
36
+ method: "POST",
37
+ body: JSON.stringify(payload),
38
+ });
39
+ if (data.installed) {
40
+ console.log(`Skill installed: ${data.slug} (${data.publicId}) v${data.activeVersion}`);
41
+ }
42
+ else {
43
+ console.log(`Skill already installed (idempotent): ${data.slug} (${data.publicId}) v${data.activeVersion}`);
44
+ }
45
+ }
46
+ catch (err) {
47
+ const msg = err instanceof ApiError ? err.message : String(err);
48
+ console.error(`Error: ${msg}`);
49
+ process.exit(1);
50
+ }
51
+ });
52
+ //# sourceMappingURL=skill.workspace.install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.workspace.install.js","sourceRoot":"","sources":["../../src/commands/skill.workspace.install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AASlD,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KAC/D,WAAW,CAAC,mFAAmF,CAAC;KAChG,MAAM,CAAC,mBAAmB,EAAE,oEAAoE,CAAC;KACjG,MAAM,CAAC,mBAAmB,EAAE,2CAA2C,CAAC;KACxE,MAAM,CAAC,mBAAmB,EAAE,6DAA6D,CAAC;KAC1F,MAAM,CAAC,4BAA4B,EAAE,oCAAoC,CAAC;KAC1E,MAAM,CAAC,sBAAsB,EAAE,8CAA8C,CAAC;KAC9E,MAAM,CACL,KAAK,EAAE,OAMN,EAAE,EAAE;IACH,IAAI,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CACX,uFAAuF,CACxF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAA4B,EAAE,CAAC;QAE5C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;gBAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,MAAM,GAAG;gBACf,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClE,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,IAAI,cAAc,EAAE,CAAC;QAC1D,IAAI,WAAW;YAAE,OAAO,CAAC,YAAY,GAAG,WAAW,CAAC;QAEpD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAuB,0BAA0B,EAAE;YAC9E,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CACT,yCAAyC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,aAAa,EAAE,CAC/F,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CACF,CAAC"}
@@ -70,6 +70,8 @@ import { documentReadCommand } from "./commands/document.read.js";
70
70
  import { formCreateCommand } from "./commands/form.create.js";
71
71
  import { formSubmitCommand } from "./commands/form.submit.js";
72
72
  import { automationCreateCommand } from "./commands/automation.create.js";
73
+ import { automationEnableCommand } from "./commands/automation.enable.js";
74
+ import { automationDisableCommand } from "./commands/automation.disable.js";
73
75
  import { automationTriggerCommand } from "./commands/automation.trigger.js";
74
76
  import { skillWorkspaceListCommand } from "./commands/skill.workspace.list.js";
75
77
  import { agentMemoryRecallCommand } from "./commands/agent.memory.recall.js";
@@ -99,13 +101,10 @@ import { formFillCommand } from "./commands/form.fill.js";
99
101
  import { orgMemberInviteDeclineCommand } from "./commands/org.member.invite.decline.js";
100
102
  import { organizationCreateCommand } from "./commands/organization.create.js";
101
103
  import { pluginCredentialSetSecretCommand } from "./commands/plugin.credential.set_secret.js";
102
- import { pluginDenylistAddCommand } from "./commands/plugin.denylist.add.js";
103
- import { pluginDenylistRemoveCommand } from "./commands/plugin.denylist.remove.js";
104
104
  import { pluginOrgInstallBulkCommand } from "./commands/plugin.org.install_bulk.js";
105
105
  import { pluginOrgListCommand } from "./commands/plugin.org.list.js";
106
106
  import { pluginOrgSetEnabledCommand } from "./commands/plugin.org.set_enabled.js";
107
107
  import { pluginRegistryRemoveCommand } from "./commands/plugin.registry.remove.js";
108
- import { pluginRegistrySyncCommand } from "./commands/plugin.registry.sync.js";
109
108
  import { pluginSettingsSetAuthAlertsCommand } from "./commands/plugin.settings.set_auth_alerts.js";
110
109
  import { pluginWorkspaceSetEnabledCommand } from "./commands/plugin.workspace.set_enabled.js";
111
110
  import { systemInstallInstructionsCommand } from "./commands/system.install.instructions.js";
@@ -1007,14 +1006,109 @@ describe("automation list", () => {
1007
1006
  });
1008
1007
  });
1009
1008
  describe("automation create", () => {
1010
- it("creates automation", async () => {
1009
+ it("creates automation with the contract payload shape", async () => {
1011
1010
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1012
- mockApiRequest.mockResolvedValueOnce({ id: "auto1", name: "My Automation" });
1011
+ mockApiRequest.mockResolvedValueOnce({
1012
+ automation_id: "plt_1",
1013
+ playbook_id: "plb_1",
1014
+ name: "My Automation",
1015
+ status: "inactive",
1016
+ triggerType: "api",
1017
+ enabled: false,
1018
+ });
1013
1019
  await automationCreateCommand.parseAsync(["node", "cli", "-n", "My Automation"]);
1014
1020
  expect(mockApiRequest).toHaveBeenCalledWith("/automation/create", expect.objectContaining({ method: "POST" }));
1021
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1022
+ expect(body).toMatchObject({
1023
+ name: "My Automation",
1024
+ triggerType: "api",
1025
+ triggerConfig: {},
1026
+ steps: [],
1027
+ enabled: false,
1028
+ });
1015
1029
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation created"));
1016
1030
  consoleSpy.mockRestore();
1017
1031
  });
1032
+ it("builds event triggerConfig from --entity-type/--event-type/--conditions and passes --enabled", async () => {
1033
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1034
+ mockApiRequest.mockResolvedValueOnce({
1035
+ automation_id: "plt_2",
1036
+ playbook_id: "plb_2",
1037
+ name: "Watcher",
1038
+ status: "active",
1039
+ triggerType: "event",
1040
+ enabled: true,
1041
+ });
1042
+ await automationCreateCommand.parseAsync([
1043
+ "node", "cli",
1044
+ "-n", "Watcher",
1045
+ "--trigger-type", "event",
1046
+ "--entity-type", "Contact",
1047
+ "--event-type", "node.updated",
1048
+ "--conditions", '[{"property":"status","toValue":"customer","operator":"eq"}]',
1049
+ "--enabled",
1050
+ ]);
1051
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1052
+ expect(body).toMatchObject({
1053
+ name: "Watcher",
1054
+ triggerType: "event",
1055
+ triggerConfig: {
1056
+ entityType: "Contact",
1057
+ eventType: "node.updated",
1058
+ propertyConditions: [{ property: "status", toValue: "customer", operator: "eq" }],
1059
+ },
1060
+ enabled: true,
1061
+ });
1062
+ consoleSpy.mockRestore();
1063
+ });
1064
+ it("builds schedule triggerConfig from --cron/--timezone", async () => {
1065
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1066
+ mockApiRequest.mockResolvedValueOnce({
1067
+ automation_id: "plt_3",
1068
+ playbook_id: "plb_3",
1069
+ name: "Report",
1070
+ status: "inactive",
1071
+ triggerType: "schedule",
1072
+ enabled: false,
1073
+ });
1074
+ await automationCreateCommand.parseAsync([
1075
+ "node", "cli",
1076
+ "-n", "Report",
1077
+ "--trigger-type", "schedule",
1078
+ "--cron", "0 9 * * 1",
1079
+ "--timezone", "America/New_York",
1080
+ ]);
1081
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1082
+ expect(body).toMatchObject({
1083
+ triggerType: "schedule",
1084
+ triggerConfig: { cronExpression: "0 9 * * 1", timezone: "America/New_York" },
1085
+ });
1086
+ consoleSpy.mockRestore();
1087
+ });
1088
+ });
1089
+ describe("automation enable", () => {
1090
+ it("enables automation", async () => {
1091
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1092
+ mockApiRequest.mockResolvedValueOnce({ automation_id: "plt_1", enabled: true, status: "active" });
1093
+ await automationEnableCommand.parseAsync(["node", "cli", "plt_1"]);
1094
+ expect(mockApiRequest).toHaveBeenCalledWith("/automation/enable", expect.objectContaining({ method: "POST" }));
1095
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1096
+ expect(body).toEqual({ automation_id: "plt_1" });
1097
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation enabled"));
1098
+ consoleSpy.mockRestore();
1099
+ });
1100
+ });
1101
+ describe("automation disable", () => {
1102
+ it("disables automation", async () => {
1103
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1104
+ mockApiRequest.mockResolvedValueOnce({ automation_id: "plt_1", enabled: false, status: "paused" });
1105
+ await automationDisableCommand.parseAsync(["node", "cli", "plt_1"]);
1106
+ expect(mockApiRequest).toHaveBeenCalledWith("/automation/disable", expect.objectContaining({ method: "POST" }));
1107
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1108
+ expect(body).toEqual({ automation_id: "plt_1" });
1109
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation disabled"));
1110
+ consoleSpy.mockRestore();
1111
+ });
1018
1112
  });
1019
1113
  describe("automation trigger", () => {
1020
1114
  it("triggers automation", async () => {
@@ -1643,45 +1737,6 @@ describe("plugin credential set_secret", () => {
1643
1737
  });
1644
1738
  });
1645
1739
  // ---------------------------------------------------------------------------
1646
- // plugin denylist
1647
- // ---------------------------------------------------------------------------
1648
- describe("plugin denylist add", () => {
1649
- it("adds a server to the denylist", async () => {
1650
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1651
- mockApiRequest.mockResolvedValueOnce({ ok: true });
1652
- await pluginDenylistAddCommand.parseAsync(["node", "cli", "-s", "bad-server"]);
1653
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/denylist/add", expect.objectContaining({ method: "POST" }));
1654
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("bad-server"));
1655
- consoleSpy.mockRestore();
1656
- });
1657
- it("handles denylist add failure", async () => {
1658
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1659
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1660
- mockApiRequest.mockRejectedValueOnce(new Error("Server not found"));
1661
- await expect(pluginDenylistAddCommand.parseAsync(["node", "cli", "-s", "srv"])).rejects.toThrow();
1662
- consoleSpy.mockRestore();
1663
- exitSpy.mockRestore();
1664
- });
1665
- });
1666
- describe("plugin denylist remove", () => {
1667
- it("removes a server from the denylist", async () => {
1668
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1669
- mockApiRequest.mockResolvedValueOnce({ ok: true });
1670
- await pluginDenylistRemoveCommand.parseAsync(["node", "cli", "-s", "bad-server"]);
1671
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/denylist/remove", expect.objectContaining({ method: "POST" }));
1672
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("bad-server"));
1673
- consoleSpy.mockRestore();
1674
- });
1675
- it("handles denylist remove failure", async () => {
1676
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1677
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1678
- mockApiRequest.mockRejectedValueOnce(new Error("Entry not found"));
1679
- await expect(pluginDenylistRemoveCommand.parseAsync(["node", "cli", "-s", "srv"])).rejects.toThrow();
1680
- consoleSpy.mockRestore();
1681
- exitSpy.mockRestore();
1682
- });
1683
- });
1684
- // ---------------------------------------------------------------------------
1685
1740
  // plugin org install bulk
1686
1741
  // ---------------------------------------------------------------------------
1687
1742
  describe("plugin org install bulk", () => {
@@ -1793,35 +1848,6 @@ describe("plugin registry remove", () => {
1793
1848
  });
1794
1849
  });
1795
1850
  // ---------------------------------------------------------------------------
1796
- // plugin registry sync
1797
- // ---------------------------------------------------------------------------
1798
- describe("plugin registry sync", () => {
1799
- it("triggers a registry sync", async () => {
1800
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1801
- mockApiRequest.mockResolvedValueOnce({ accepted: true });
1802
- await pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"]);
1803
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/sync", expect.objectContaining({ method: "POST" }));
1804
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Sync accepted"));
1805
- consoleSpy.mockRestore();
1806
- });
1807
- it("reports sync not accepted", async () => {
1808
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1809
- mockApiRequest.mockResolvedValueOnce({ accepted: false });
1810
- await pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"]);
1811
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("not accepted"));
1812
- consoleSpy.mockRestore();
1813
- });
1814
- it("handles sync failure", async () => {
1815
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1816
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1817
- mockApiRequest.mockRejectedValueOnce(new Error("Registry not found"));
1818
- await expect(pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"])).rejects.toThrow();
1819
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
1820
- consoleSpy.mockRestore();
1821
- exitSpy.mockRestore();
1822
- });
1823
- });
1824
- // ---------------------------------------------------------------------------
1825
1851
  // plugin settings set_auth_alerts
1826
1852
  // ---------------------------------------------------------------------------
1827
1853
  describe("plugin settings set_auth_alerts", () => {
@@ -2053,6 +2079,24 @@ describe("branch coverage: ApiError error paths", () => {
2053
2079
  consoleSpy.mockRestore();
2054
2080
  exitSpy.mockRestore();
2055
2081
  });
2082
+ it("automation enable returns ApiError message", async () => {
2083
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2084
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2085
+ mockApiError(404, "Automation not found");
2086
+ await expect(automationEnableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2087
+ expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2088
+ consoleSpy.mockRestore();
2089
+ exitSpy.mockRestore();
2090
+ });
2091
+ it("automation disable returns ApiError message", async () => {
2092
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2093
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2094
+ mockApiError(404, "Automation not found");
2095
+ await expect(automationDisableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2096
+ expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2097
+ consoleSpy.mockRestore();
2098
+ exitSpy.mockRestore();
2099
+ });
2056
2100
  it("automation trigger returns ApiError message", async () => {
2057
2101
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2058
2102
  const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });