@autifyhq/aximo-cli 0.8.0 → 0.10.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 (70) hide show
  1. package/README.md +19 -7
  2. package/dist/client.d.ts +7 -1
  3. package/dist/client.js +21 -2
  4. package/dist/client.test.js +36 -0
  5. package/dist/commands/case/case.test.js +62 -0
  6. package/dist/commands/case/create.d.ts +1 -1
  7. package/dist/commands/case/create.js +4 -4
  8. package/dist/commands/case/index.js +1 -0
  9. package/dist/commands/case/update.d.ts +50 -0
  10. package/dist/commands/case/update.js +78 -0
  11. package/dist/commands/device/connect.js +19 -1
  12. package/dist/commands/device/doctor.d.ts +2 -0
  13. package/dist/commands/device/doctor.js +37 -10
  14. package/dist/commands/device/doctor.test.js +26 -1
  15. package/dist/commands/health/check.js +15 -3
  16. package/dist/commands/health/check.test.js +27 -3
  17. package/dist/commands/mcp/server.test.js +3 -1
  18. package/dist/commands/mcp/tools.js +28 -0
  19. package/dist/commands/mcp/tools.test.js +90 -0
  20. package/dist/commands/mobile/connect-core.d.ts +5 -3
  21. package/dist/commands/mobile/connect-core.js +60 -12
  22. package/dist/commands/mobile/connect.d.ts +5 -0
  23. package/dist/commands/mobile/connect.js +6 -1
  24. package/dist/commands/mobile/signing-consent.d.ts +18 -0
  25. package/dist/commands/mobile/signing-consent.js +22 -0
  26. package/dist/commands/mobile/signing-consent.test.d.ts +1 -0
  27. package/dist/commands/mobile/signing-consent.test.js +50 -0
  28. package/dist/commands/plan/index.js +1 -0
  29. package/dist/commands/plan/plan.test.js +61 -0
  30. package/dist/commands/plan/update.d.ts +42 -0
  31. package/dist/commands/plan/update.js +78 -0
  32. package/dist/commands/schema.js +1 -1
  33. package/dist/commands/session/save-as-case.js +3 -3
  34. package/dist/commands/trigger/plan/run.d.ts +6 -1
  35. package/dist/commands/trigger/plan/run.js +9 -3
  36. package/dist/commands/trigger/trigger.test.js +22 -3
  37. package/dist/commands/upload/put.d.ts +5 -0
  38. package/dist/commands/upload/put.js +44 -11
  39. package/dist/commands/upload/upload.test.js +82 -0
  40. package/dist/desktop-server/preflight.d.ts +43 -0
  41. package/dist/desktop-server/preflight.js +78 -0
  42. package/dist/desktop-server/preflight.test.d.ts +1 -0
  43. package/dist/desktop-server/preflight.test.js +115 -0
  44. package/dist/mobile-control/appium-controller.d.ts +28 -0
  45. package/dist/mobile-control/appium-controller.js +271 -92
  46. package/dist/mobile-control/appium-controller.test.js +258 -8
  47. package/dist/mobile-control/bundle-id-map.js +3 -0
  48. package/dist/mobile-control/controller.d.ts +3 -0
  49. package/dist/mobile-control/frame-sender.d.ts +34 -0
  50. package/dist/mobile-control/frame-sender.js +96 -0
  51. package/dist/mobile-control/frame-sender.test.d.ts +1 -0
  52. package/dist/mobile-control/frame-sender.test.js +108 -0
  53. package/dist/mobile-control/mjpeg-stream.d.ts +43 -0
  54. package/dist/mobile-control/mjpeg-stream.js +160 -0
  55. package/dist/mobile-control/mjpeg-stream.test.d.ts +1 -0
  56. package/dist/mobile-control/mjpeg-stream.test.js +93 -0
  57. package/dist/mobile-control/tunnel.d.ts +10 -1
  58. package/dist/mobile-control/tunnel.js +43 -2
  59. package/dist/mobile-control/tunnel.test.js +108 -0
  60. package/dist/mobile-control/webdriver.d.ts +9 -1
  61. package/dist/mobile-control/webdriver.js +17 -5
  62. package/dist/mutate.d.ts +1 -1
  63. package/dist/mutate.js +4 -2
  64. package/dist/prompt.d.ts +11 -0
  65. package/dist/prompt.js +19 -0
  66. package/dist/types.d.ts +66 -4
  67. package/dist/validate.d.ts +6 -1
  68. package/dist/validate.js +46 -0
  69. package/dist/validate.test.js +39 -1
  70. package/package.json +1 -1
package/dist/types.d.ts CHANGED
@@ -19,8 +19,12 @@ export interface ErrorEnvelope {
19
19
  export type Envelope<T> = SuccessEnvelope<T> | ErrorEnvelope;
20
20
  export type Platform = "ANDROID" | "IOS";
21
21
  export type FileType = "ANDROID_APP" | "IOS_APP";
22
+ export type ExecutionMode = "parallel" | "sequential";
23
+ export type CaseType = "web" | "mobile" | "desktop" | "multi_device";
24
+ export type CaseFormat = "gherkin" | "markdown" | "plain_text";
22
25
  export interface HealthStatus {
23
26
  status: string;
27
+ auth?: string | undefined;
24
28
  }
25
29
  export interface CreateSessionInput {
26
30
  title: string;
@@ -75,17 +79,53 @@ export interface CaseRunStatus {
75
79
  export interface PlanRunInput {
76
80
  model?: string | undefined;
77
81
  mobileConfig?: Record<string, unknown> | undefined;
82
+ executionMode?: ExecutionMode | undefined;
78
83
  }
79
84
  export interface PlanRunResult {
80
85
  success: boolean;
81
86
  planRunId: string;
82
87
  totalCases: number;
88
+ executionMode?: ExecutionMode | undefined;
89
+ }
90
+ export interface UpdatePlanInput {
91
+ title?: string | undefined;
92
+ description?: string | undefined;
93
+ executionMode?: ExecutionMode | undefined;
94
+ stopOnFailure?: boolean | undefined;
95
+ }
96
+ export interface UpdatePlanResult {
97
+ success: boolean;
98
+ plan: {
99
+ id: string;
100
+ title: string;
101
+ description: string | null;
102
+ executionMode: ExecutionMode;
103
+ stopOnFailure: boolean;
104
+ updatedAt: string;
105
+ };
83
106
  }
84
107
  export interface PlanRun {
85
108
  id: string;
86
109
  status?: string | undefined;
87
110
  [key: string]: unknown;
88
111
  }
112
+ export interface PlanRunSummary {
113
+ id: string;
114
+ status: string;
115
+ triggerSource: string | null;
116
+ executionMode: string;
117
+ totalCases: number;
118
+ completedCases: number;
119
+ passedCases: number;
120
+ failedCases: number;
121
+ startedAt: string | null;
122
+ completedAt: string | null;
123
+ createdAt: string;
124
+ }
125
+ export interface PlanRunList {
126
+ items: PlanRunSummary[];
127
+ nextCursor?: string | undefined;
128
+ }
89
129
  export interface Device {
90
130
  arn?: string | undefined;
91
131
  name?: string | undefined;
@@ -123,10 +163,10 @@ export interface Project {
123
163
  export interface CreateCaseInput {
124
164
  projectId: string;
125
165
  scenario: string;
126
- type?: string | undefined;
166
+ type?: CaseType | undefined;
127
167
  title?: string | undefined;
128
168
  description?: string | undefined;
129
- format?: string | undefined;
169
+ format?: CaseFormat | undefined;
130
170
  startUrl?: string | undefined;
131
171
  directoryId?: string | undefined;
132
172
  }
@@ -134,6 +174,28 @@ export interface CreateCaseResult {
134
174
  success: boolean;
135
175
  caseId: string;
136
176
  }
177
+ export interface UpdateCaseInput {
178
+ title?: string | undefined;
179
+ description?: string | undefined;
180
+ scenario?: string | undefined;
181
+ type?: CaseType | undefined;
182
+ format?: CaseFormat | undefined;
183
+ startUrl?: string | undefined;
184
+ }
185
+ export interface UpdateCaseResult {
186
+ success: boolean;
187
+ case: {
188
+ id: string;
189
+ projectId: string;
190
+ type: string;
191
+ title: string;
192
+ description: string | null;
193
+ scenario: string;
194
+ format: string;
195
+ startUrl: string | null;
196
+ updatedAt: string;
197
+ };
198
+ }
137
199
  export interface DeleteCaseResult {
138
200
  success: boolean;
139
201
  }
@@ -151,9 +213,9 @@ export interface PlanCaseResult {
151
213
  }
152
214
  export interface SaveSessionAsCaseInput {
153
215
  title?: string | undefined;
154
- type?: string | undefined;
216
+ type?: Exclude<CaseType, "multi_device"> | undefined;
155
217
  scenario?: string | undefined;
156
- format?: string | undefined;
218
+ format?: CaseFormat | undefined;
157
219
  }
158
220
  export interface SaveSessionAsCaseResult {
159
221
  success: boolean;
@@ -1,10 +1,15 @@
1
- import type { Platform, FileType } from "./types.js";
1
+ import type { CaseFormat, CaseType, ExecutionMode, FileType, Platform } from "./types.js";
2
2
  export declare function optionalString(name: string, value: unknown): string | undefined;
3
3
  export declare function parseStringList(name: string, value: unknown): string[] | undefined;
4
4
  export declare function requireString(name: string, value: unknown): string;
5
5
  export declare function requireId(name: string, value: unknown): string;
6
6
  export declare function parsePlatform(value: unknown): Platform | undefined;
7
7
  export declare function parseFileType(value: unknown): FileType | undefined;
8
+ export declare function parseExecutionMode(value: unknown): ExecutionMode | undefined;
9
+ export declare function parseCaseType(value: unknown): CaseType | undefined;
10
+ export declare function parseSaveAsCaseType(value: unknown): Exclude<CaseType, "multi_device"> | undefined;
11
+ export declare function parseCaseFormat(value: unknown): CaseFormat | undefined;
12
+ export declare function parseOptionalBoolean(name: string, value: unknown): boolean | undefined;
8
13
  export declare function parseTags(value: unknown): string[] | undefined;
9
14
  export declare const OPENAPI_URL = "https://aximo.autify.com/openapi.yaml";
10
15
  export declare class JsonBodyError extends Error {
package/dist/validate.js CHANGED
@@ -56,6 +56,52 @@ export function parseFileType(value) {
56
56
  }
57
57
  return value;
58
58
  }
59
+ const EXECUTION_MODES = new Set(["parallel", "sequential"]);
60
+ export function parseExecutionMode(value) {
61
+ if (value === undefined || value === "")
62
+ return undefined;
63
+ if (typeof value !== "string" || !EXECUTION_MODES.has(value)) {
64
+ throw new Error(`executionMode must be parallel or sequential (got ${String(value)})`);
65
+ }
66
+ return value;
67
+ }
68
+ const CASE_TYPES = new Set(["web", "mobile", "desktop", "multi_device"]);
69
+ export function parseCaseType(value) {
70
+ if (value === undefined || value === "")
71
+ return undefined;
72
+ if (typeof value !== "string" || !CASE_TYPES.has(value)) {
73
+ throw new Error(`type must be web, mobile, desktop, or multi_device (got ${String(value)})`);
74
+ }
75
+ return value;
76
+ }
77
+ // save-as-case's server schema accepts a narrower set than case create/update.
78
+ export function parseSaveAsCaseType(value) {
79
+ const parsed = parseCaseType(value);
80
+ if (parsed === "multi_device") {
81
+ throw new Error(`type must be web, mobile, or desktop (got ${String(value)})`);
82
+ }
83
+ return parsed;
84
+ }
85
+ const CASE_FORMATS = new Set(["gherkin", "markdown", "plain_text"]);
86
+ export function parseCaseFormat(value) {
87
+ if (value === undefined || value === "")
88
+ return undefined;
89
+ if (typeof value !== "string" || !CASE_FORMATS.has(value)) {
90
+ throw new Error(`format must be gherkin, markdown, or plain_text (got ${String(value)})`);
91
+ }
92
+ return value;
93
+ }
94
+ // Tri-state boolean for PATCH-style flags: absent means "leave unchanged",
95
+ // so a citty boolean (which defaults to false) would silently overwrite.
96
+ export function parseOptionalBoolean(name, value) {
97
+ if (value === undefined || value === "")
98
+ return undefined;
99
+ if (value === true || value === "true")
100
+ return true;
101
+ if (value === false || value === "false")
102
+ return false;
103
+ throw new Error(`${name} must be true or false (got ${String(value)})`);
104
+ }
59
105
  export function parseTags(value) {
60
106
  return parseStringList("tags", value);
61
107
  }
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { requireString, requireId, parsePlatform, parseFileType, parseTags, parseJsonObject, parseJsonBody, JsonBodyError, } from "./validate.js";
2
+ import { requireString, requireId, parseCaseFormat, parseCaseType, parsePlatform, parseSaveAsCaseType, parseFileType, parseTags, parseJsonObject, parseJsonBody, JsonBodyError, } from "./validate.js";
3
3
  describe("requireId", () => {
4
4
  it("accepts plain IDs", () => {
5
5
  expect(requireId("sessionId", "abc123_-")).toBe("abc123_-");
@@ -94,3 +94,41 @@ describe("parseJsonObject", () => {
94
94
  expect(parseJsonObject("x", "")).toBeUndefined();
95
95
  });
96
96
  });
97
+ describe("parseCaseType", () => {
98
+ it("accepts all case types", () => {
99
+ expect(parseCaseType("web")).toBe("web");
100
+ expect(parseCaseType("mobile")).toBe("mobile");
101
+ expect(parseCaseType("desktop")).toBe("desktop");
102
+ expect(parseCaseType("multi_device")).toBe("multi_device");
103
+ });
104
+ it("returns undefined for absent values", () => {
105
+ expect(parseCaseType(undefined)).toBeUndefined();
106
+ expect(parseCaseType("")).toBeUndefined();
107
+ });
108
+ it("rejects unknown values", () => {
109
+ expect(() => parseCaseType("banana")).toThrow(/must be web, mobile, desktop/);
110
+ });
111
+ });
112
+ describe("parseSaveAsCaseType", () => {
113
+ it("accepts the narrower save-as-case set", () => {
114
+ expect(parseSaveAsCaseType("web")).toBe("web");
115
+ expect(parseSaveAsCaseType("desktop")).toBe("desktop");
116
+ });
117
+ it("rejects multi_device, which the save-as-case endpoint does not accept", () => {
118
+ expect(() => parseSaveAsCaseType("multi_device")).toThrow(/must be web, mobile, or desktop/);
119
+ });
120
+ });
121
+ describe("parseCaseFormat", () => {
122
+ it("accepts all formats", () => {
123
+ expect(parseCaseFormat("gherkin")).toBe("gherkin");
124
+ expect(parseCaseFormat("markdown")).toBe("markdown");
125
+ expect(parseCaseFormat("plain_text")).toBe("plain_text");
126
+ });
127
+ it("returns undefined for absent values", () => {
128
+ expect(parseCaseFormat(undefined)).toBeUndefined();
129
+ expect(parseCaseFormat("")).toBeUndefined();
130
+ });
131
+ it("rejects unknown values", () => {
132
+ expect(() => parseCaseFormat("klingon")).toThrow(/must be gherkin, markdown, or plain_text/);
133
+ });
134
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autifyhq/aximo-cli",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Autify Aximo Command Line Interface (CLI)",
5
5
  "keywords": [
6
6
  "autify",