@copado/agentia-cli 1.0.0 → 1.2.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 (226) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +2252 -1529
  3. package/dist/commands/ai/agent/ask.js +4 -4
  4. package/dist/commands/ai/agent/chat.js +4 -4
  5. package/dist/commands/cicd/cloud/commit.js +7 -2
  6. package/dist/commands/cicd/credential/auth/status.js +38 -0
  7. package/dist/commands/cicd/credential/auth/web/login.js +54 -0
  8. package/dist/commands/cicd/credential/list.js +13 -17
  9. package/dist/commands/cicd/credential/open.js +30 -0
  10. package/dist/commands/cicd/credential/update.js +9 -12
  11. package/dist/commands/cicd/environment/auth/status.js +34 -13
  12. package/dist/commands/cicd/environment/auth/web/login.js +20 -4
  13. package/dist/commands/cicd/environment/open.js +6 -22
  14. package/dist/commands/cicd/extension/create.js +53 -0
  15. package/dist/commands/cicd/extension/install.js +127 -0
  16. package/dist/commands/cicd/extension/package.js +35 -0
  17. package/dist/commands/cicd/extension/publish.js +61 -0
  18. package/dist/commands/cicd/extension/uninstall.js +99 -0
  19. package/dist/commands/cicd/extension/validate.js +47 -0
  20. package/dist/commands/cicd/extension-configuration/get.js +24 -0
  21. package/dist/commands/cicd/extension-configuration/list.js +49 -0
  22. package/dist/commands/cicd/extension-configuration/open.js +38 -0
  23. package/dist/commands/cicd/metadata/content/get.js +1 -1
  24. package/dist/commands/cicd/metadata/dependency/list.js +2 -2
  25. package/dist/commands/cicd/metadata/explore.js +81 -0
  26. package/dist/commands/cicd/metadata/list.js +3 -3
  27. package/dist/commands/cicd/metadata/refresh/deleted.js +1 -1
  28. package/dist/commands/cicd/metadata/refresh/run.js +2 -2
  29. package/dist/commands/cicd/metadata/refresh/status.js +2 -2
  30. package/dist/commands/cicd/pipeline/automation/activate.js +39 -0
  31. package/dist/commands/cicd/pipeline/automation/create.js +33 -0
  32. package/dist/commands/cicd/pipeline/automation/deactivate.js +39 -0
  33. package/dist/commands/cicd/pipeline/automation/delete.js +45 -0
  34. package/dist/commands/cicd/pipeline/automation/get.js +32 -0
  35. package/dist/commands/cicd/pipeline/automation/list.js +38 -0
  36. package/dist/commands/cicd/pipeline/automation/open.js +38 -0
  37. package/dist/commands/cicd/pipeline/automation/update.js +38 -0
  38. package/dist/commands/cicd/pipeline/quality-gate/activate.js +39 -0
  39. package/dist/commands/cicd/pipeline/quality-gate/create.js +34 -0
  40. package/dist/commands/cicd/pipeline/quality-gate/deactivate.js +39 -0
  41. package/dist/commands/cicd/pipeline/quality-gate/delete.js +45 -0
  42. package/dist/commands/cicd/pipeline/quality-gate/get.js +32 -0
  43. package/dist/commands/cicd/pipeline/quality-gate/list.js +34 -0
  44. package/dist/commands/cicd/pipeline/quality-gate/open.js +38 -0
  45. package/dist/commands/cicd/pipeline/quality-gate/update.js +38 -0
  46. package/dist/commands/cicd/work/create.js +1 -0
  47. package/dist/commands/cicd/work/environment-sync.js +8 -7
  48. package/dist/commands/cicd/work/get.js +18 -2
  49. package/dist/commands/cicd/work/set.js +6 -4
  50. package/dist/commands/cicd/work/submit.js +3 -2
  51. package/dist/commands/cicd/work/update.js +1 -0
  52. package/dist/commands/plugins/install.js +2 -5
  53. package/dist/commands/setup/skills/create.js +29 -3
  54. package/dist/commands/setup/skills/list.js +55 -0
  55. package/dist/commands/setup/skills/update.js +37 -4
  56. package/dist/commands/setup.js +3 -3
  57. package/dist/commands/testing/data-table/create.js +1 -2
  58. package/dist/commands/testing/data-table/delete.js +1 -2
  59. package/dist/commands/testing/data-table/export.js +2 -6
  60. package/dist/commands/testing/data-table/get.js +2 -4
  61. package/dist/commands/testing/data-table/list.js +1 -2
  62. package/dist/commands/testing/data-table/update.js +3 -4
  63. package/dist/commands/testing/job/create.js +26 -22
  64. package/dist/commands/testing/job/delete.js +2 -2
  65. package/dist/commands/testing/job/files/download.js +73 -0
  66. package/dist/commands/testing/job/files/list.js +43 -0
  67. package/dist/commands/testing/job/{upload.js → files/upload.js} +13 -9
  68. package/dist/commands/testing/job/get.js +2 -2
  69. package/dist/commands/testing/job/list.js +1 -1
  70. package/dist/commands/testing/job/refs.js +4 -4
  71. package/dist/commands/testing/job/run.js +134 -1
  72. package/dist/commands/testing/{build → job/runs}/abort.js +10 -8
  73. package/dist/commands/testing/job/runs/get.js +42 -0
  74. package/dist/commands/testing/{build → job/runs}/list.js +19 -10
  75. package/dist/commands/testing/{logs.js → job/runs/logs.js} +9 -6
  76. package/dist/commands/testing/{build → job/runs}/search.js +9 -7
  77. package/dist/commands/testing/job/schedule/get.js +5 -11
  78. package/dist/commands/testing/job/schedule/remove.js +3 -3
  79. package/dist/commands/testing/job/schedule/set.js +3 -3
  80. package/dist/commands/testing/job/update.js +22 -65
  81. package/dist/commands/testing/live/continue.js +5 -10
  82. package/dist/commands/testing/live/execute.js +3 -3
  83. package/dist/commands/testing/live/history.js +7 -2
  84. package/dist/commands/testing/live/inspect.js +5 -4
  85. package/dist/commands/testing/live/interrupt.js +5 -10
  86. package/dist/commands/testing/live/recorder.js +23 -115
  87. package/dist/commands/testing/live/reports.js +3 -3
  88. package/dist/commands/testing/live/screenshot.js +3 -3
  89. package/dist/commands/testing/live/set-options.js +11 -4
  90. package/dist/commands/testing/live/start.js +9 -4
  91. package/dist/commands/testing/live/status.js +2 -5
  92. package/dist/commands/testing/live/stop.js +3 -5
  93. package/dist/commands/testing/live/view.js +2 -2
  94. package/dist/commands/testing/project/create.js +1 -17
  95. package/dist/commands/testing/project/get.js +0 -1
  96. package/dist/commands/testing/project/list.js +2 -2
  97. package/dist/commands/testing/project/permission/set.js +3 -7
  98. package/dist/commands/testing/project/permission/update.js +2 -2
  99. package/dist/commands/testing/robot/create.js +22 -25
  100. package/dist/commands/testing/robot/get.js +1 -1
  101. package/dist/commands/testing/robot/list.js +3 -3
  102. package/dist/commands/testing/robot/update.js +3 -3
  103. package/dist/commands/testing/user-parameter/create.js +3 -9
  104. package/dist/commands/testing/user-parameter/update.js +1 -7
  105. package/dist/commands/testing/variable/create.js +4 -9
  106. package/dist/commands/testing/variable/list.js +3 -3
  107. package/dist/commands/testing/variable/update.js +5 -12
  108. package/dist/help.js +17 -0
  109. package/dist/lib/ai-types.js +2 -1
  110. package/dist/lib/claude-mcp-config.js +15 -0
  111. package/dist/lib/credential-sync.js +1 -2
  112. package/dist/lib/defaults-store.js +4 -1
  113. package/dist/lib/environment-auth-status.js +2 -1
  114. package/dist/lib/environment-auth.js +2 -1
  115. package/dist/lib/environment-credential-flags.js +3 -1
  116. package/dist/lib/environment-credential-operations.js +8 -2
  117. package/dist/lib/environment-types.js +3 -1
  118. package/dist/lib/extension/assets.js +4 -0
  119. package/dist/lib/extension/create.js +3 -0
  120. package/dist/lib/extension/git.js +17 -0
  121. package/dist/lib/extension/index.js +27 -0
  122. package/dist/lib/extension/install.js +4 -0
  123. package/dist/lib/extension/manifest.js +21 -0
  124. package/dist/lib/extension/package.js +3 -0
  125. package/dist/lib/extension/paths.js +5 -0
  126. package/dist/lib/extension/publish.js +3 -0
  127. package/dist/lib/extension/sf-deploy.js +8 -0
  128. package/dist/lib/extension/source.js +7 -0
  129. package/dist/lib/extension/uninstall.js +3 -0
  130. package/dist/lib/extension-configuration-ops.js +4 -0
  131. package/dist/lib/extension-configuration-sanitize.js +7 -0
  132. package/dist/lib/extension-configuration-types.js +8 -0
  133. package/dist/lib/function-types.js +3 -1
  134. package/dist/lib/http-proxy.js +13 -0
  135. package/dist/lib/mcp/ai-tools.js +3 -3
  136. package/dist/lib/mcp/command-id.js +2 -0
  137. package/dist/lib/mcp/pipeline-automation-quality-tools.js +452 -0
  138. package/dist/lib/mcp/server.js +70 -1
  139. package/dist/lib/mcp/testing-live-tools.js +24 -13
  140. package/dist/lib/mcp/testing-tools.js +239 -550
  141. package/dist/lib/mcp/tool-annotations.js +27 -18
  142. package/dist/lib/mcp/tools.js +117 -32
  143. package/dist/lib/mcp/work-tools.js +37 -10
  144. package/dist/lib/metadata-explore.js +8 -0
  145. package/dist/lib/network-error.js +8 -0
  146. package/dist/lib/pipeline-automation-flags.js +12 -0
  147. package/dist/lib/pipeline-automation-ops.js +9 -0
  148. package/dist/lib/pipeline-automation-types.js +18 -0
  149. package/dist/lib/pipeline-lifecycle-id.js +3 -0
  150. package/dist/lib/pipeline-quality-gate-flags.js +12 -0
  151. package/dist/lib/pipeline-quality-gate-ops.js +9 -0
  152. package/dist/lib/pipeline-quality-gate-types.js +17 -0
  153. package/dist/lib/plugin-host/ai.js +2 -1
  154. package/dist/lib/plugin-skills.js +22 -0
  155. package/dist/lib/plugin-trust/gate.js +1 -2
  156. package/dist/lib/project-root.js +3 -1
  157. package/dist/lib/project-setup.js +5 -4
  158. package/dist/lib/runtime.js +1 -1
  159. package/dist/lib/salesforce-tooling-check.js +6 -0
  160. package/dist/lib/setup-skills.js +4 -1
  161. package/dist/lib/setup-templates.js +1 -4
  162. package/dist/lib/skill-packs.js +7 -0
  163. package/dist/lib/template-types.js +3 -1
  164. package/dist/lib/testing-archive.js +9 -0
  165. package/dist/lib/testing-data-table.js +39 -0
  166. package/dist/lib/testing-execution.js +22 -0
  167. package/dist/lib/testing-flags.js +6 -2
  168. package/dist/lib/testing-gateway.js +4 -1
  169. package/dist/lib/testing-live-command.js +3 -1
  170. package/dist/lib/testing-live-operations.js +7 -1
  171. package/dist/lib/testing-live-recorder.js +3 -1
  172. package/dist/lib/testing-live-state.js +8 -1
  173. package/dist/lib/testing-operations.js +6 -21
  174. package/dist/lib/testing-sanitization.js +2 -1
  175. package/dist/lib/testing-secret-input.js +2 -1
  176. package/dist/lib/testing-types.js +24 -3
  177. package/dist/lib/work-committed-metadata.js +4 -0
  178. package/dist/lib/work-environment-sync.js +3 -1
  179. package/dist/lib/work-flags.js +6 -1
  180. package/dist/lib/work-get.js +2 -1
  181. package/dist/lib/work-local-development-flow.js +4 -0
  182. package/dist/lib/work-submit-wait.js +3 -1
  183. package/oclif.manifest.json +9771 -9650
  184. package/package.json +35 -2
  185. package/templates/rules/cursor/agentia.mdc +29 -0
  186. package/templates/skills/agentia/SKILL.md +29 -0
  187. package/templates/skills/agentia-ai/SKILL.md +3 -4
  188. package/templates/skills/agentia-ai/references/ai-agents.md +2 -2
  189. package/templates/skills/agentia-cicd/SKILL.md +9 -4
  190. package/templates/skills/agentia-cicd/references/environments-and-credentials.md +19 -13
  191. package/templates/skills/agentia-cicd/references/extensions.md +52 -0
  192. package/templates/skills/agentia-cicd/references/pipelines.md +36 -2
  193. package/templates/skills/agentia-cicd/references/work.md +25 -8
  194. package/templates/skills/agentia-metadata/SKILL.md +140 -0
  195. package/templates/skills/agentia-metadata/references/metadata-explore.md +142 -0
  196. package/templates/skills/agentia-testing/SKILL.md +3 -3
  197. package/templates/skills/agentia-testing/references/tests.md +14 -14
  198. package/dist/commands/testing/build/get.js +0 -38
  199. package/dist/commands/testing/build/latest.js +0 -40
  200. package/dist/commands/testing/build/logs.js +0 -47
  201. package/dist/commands/testing/build/run.js +0 -26
  202. package/dist/commands/testing/create.js +0 -2
  203. package/dist/commands/testing/job/download.js +0 -54
  204. package/dist/commands/testing/job/files.js +0 -34
  205. package/dist/commands/testing/run.js +0 -26
  206. package/dist/commands/testing/status.js +0 -45
  207. package/dist/commands/testing/test/create.js +0 -2
  208. package/dist/commands/testing/test/logs.js +0 -2
  209. package/dist/commands/testing/test/run.js +0 -26
  210. package/dist/commands/testing/test/status.js +0 -2
  211. package/dist/commands/testing/test/update.js +0 -2
  212. package/dist/commands/testing/update.js +0 -65
  213. package/dist/lib/testing-data-command.js +0 -8
  214. package/dist/lib/testing-data-core.js +0 -20
  215. package/dist/lib/testing-data-export.js +0 -6
  216. package/dist/lib/testing-data-import.js +0 -6
  217. package/dist/lib/testing-data-io.js +0 -12
  218. package/dist/lib/testing-data-operations.js +0 -10
  219. package/dist/lib/testing-data-types.js +0 -4
  220. package/dist/lib/testing-live-endpoints.js +0 -6
  221. package/dist/lib/testing-live-history.js +0 -7
  222. package/dist/lib/testing-run-command.js +0 -3
  223. package/dist/lib/testing-schedule.js +0 -5
  224. package/dist/lib/testing-session.js +0 -5
  225. package/dist/lib/testing-watch.js +0 -4
  226. package/templates/AGENTS.md +0 -24
@@ -1,13 +1,15 @@
1
1
  /* eslint-disable unicorn/text-encoding-identifier-case -- CRT file APIs require the literal utf-8 enum. */
2
2
  import { z } from 'zod';
3
- import { prepareTestingData, TESTING_DATA_MAX_CELL_BYTES, TESTING_DATA_MAX_COLUMNS, TESTING_DATA_MAX_ROWS, } from '../testing-data-core.js';
4
- import { createTestingDataTable, deleteTestingDataTable, getTestingDataTable, listTestingDataTables, updateTestingDataTable, } from '../testing-data-operations.js';
5
- import { abortTestingBuild, buildTestingGitStorageUpdate, countTestingBuilds, createTestingJob, createTestingProject, createTestingRobot, createTestingUserParameter, createTestingVariable, deleteTestingJob, deleteTestingProject, deleteTestingRobot, deleteTestingUserParameter, deleteTestingVariable, downloadTestingJobFiles, getTestingBuild, getTestingBuildLogs, getTestingJob, getTestingJobRefs, getTestingProject, getTestingProjectPermission, getTestingRobot, getTestingUserParameter, getTestingVariable, latestTestingBuilds, listTestingBuilds, listTestingJobFiles, listTestingJobs, listTestingProjectPermissions, listTestingProjects, listTestingRobots, listTestingUserParameters, listTestingVariables, normalizeTestingRemotePath, runTestingBuild, searchTestingBuilds, setTestingProjectPermission, updateTestingJob, updateTestingProject, updateTestingRobot, updateTestingUserParameter, updateTestingVariable, uploadTestingJobFiles, waitForTestingBuildResult, } from '../testing-operations.js';
3
+ import { createTestingDataTable, deleteTestingDataTable, getTestingDataTable, listTestingDataTables, TESTING_DATA_MAX_CELL_BYTES, TESTING_DATA_MAX_COLUMNS, TESTING_DATA_MAX_ROWS, updateTestingDataTable, } from '../testing-data-table.js';
4
+ import { buildTestingRunOptions } from '../testing-flags.js';
5
+ import { abortTestingBuild, countTestingBuilds, createTestingJob, createTestingProject, createTestingRobot, createTestingUserParameter, createTestingVariable, deleteTestingJob, deleteTestingProject, deleteTestingRobot, deleteTestingUserParameter, deleteTestingVariable, downloadTestingJobFiles, executeTestingBuildRun, getTestingBuild, getTestingBuildLogs, getTestingJob, getTestingJobRefs, getTestingJobScheduleStatus, getTestingProject, getTestingProjectPermission, getTestingRobot, getTestingUserParameter, getTestingVariable, listTestingBuilds, listTestingJobFiles, listTestingJobs, listTestingProjectPermissions, listTestingProjects, listTestingRobots, listTestingUserParameters, listTestingVariables, removeTestingJobSchedule, searchTestingBuilds, setTestingJobSchedule, setTestingProjectPermission, updateTestingJob, updateTestingProject, updateTestingRobot, updateTestingUserParameter, updateTestingVariable, uploadTestingJobFiles, } from '../testing-operations.js';
6
6
  import { sanitizeTestingOutput } from '../testing-sanitization.js';
7
- import { getTestingJobSchedule, removeTestingJobSchedule, setTestingJobSchedule, } from '../testing-schedule.js';
8
- import { normalizeTestingId, TESTING_BUILD_STATUSES, TESTING_CONSOLE_COLORS, TESTING_JOB_PARALLEL_MODES, TESTING_JOB_SUITE_TYPES, TESTING_PROJECT_EXECUTORS, TESTING_PROJECT_TYPES, TESTING_RECORD_BUILD_OPTIONS, TESTING_ROBOT_REPORTING, TESTING_ROBOT_RUN_ENVIRONMENTS, TESTING_ROBOT_TYPES, TESTING_RUN_TYPES, TESTING_VARIABLE_TYPES, } from '../testing-types.js';
7
+ import { TESTING_BUILD_STATUSES, TESTING_CONSOLE_COLORS, TESTING_JOB_PARALLEL_MODES, TESTING_JOB_SUITE_TYPES, TESTING_RECORD_BUILD_OPTIONS, TESTING_ROBOT_ACCEPTED_RUN_ENVIRONMENTS, TESTING_ROBOT_REPORTING, TESTING_ROBOT_REPORTING_DESCRIPTION, TESTING_ROBOT_RUN_ENVIRONMENT_DESCRIPTION, TESTING_ROBOT_TYPE_DESCRIPTION, TESTING_ROBOT_TYPES, TESTING_RUN_TYPES, TESTING_VARIABLE_TYPES, } from '../testing-types.js';
9
8
  import { safelyHandleTool } from './result.js';
10
9
  import { registerTestingLiveMcpTools, testingLiveMcpHandlers } from './testing-live-tools.js';
10
+ const projectIdSchema = z.number().int().positive().describe('CRT project ID.');
11
+ const jobIdSchema = z.number().int().positive().describe('CRT job ID.');
12
+ const optionalJobIdSchema = z.number().int().positive().optional().describe('CRT job ID.');
11
13
  const gitStorageSchema = {
12
14
  gitBranch: z.string().optional().describe('Git branch to use for a Git-backed CRT job.'),
13
15
  gitDomainCredential: z.string().optional().describe('CRT domain credential ID for Git repository access.'),
@@ -17,50 +19,14 @@ const gitStorageSchema = {
17
19
  gitUseCallerCredentials: z.boolean().optional().describe('Use caller credentials for Git repository access.'),
18
20
  gitUsername: z.string().optional().describe('Git username for repository access. Prefer domain credentials.'),
19
21
  };
20
- function parseParameter(spec) {
21
- const separator = spec.indexOf('=');
22
- const key = separator === -1 ? spec.trim() : spec.slice(0, separator).trim();
23
- if (separator === -1 || key.length === 0) {
24
- throw new Error(`Invalid execution parameter: ${spec}. Use KEY=VALUE.`);
25
- }
26
- return { key, value: spec.slice(separator + 1) };
27
- }
28
- function runOptions(args) {
29
- if (args.branch !== undefined && args.tag !== undefined) {
30
- throw new Error('Use either branch or tag, not both.');
31
- }
32
- if (args.rerunFailed !== undefined && args.rerunFailedFromLatest === true) {
33
- throw new Error('Use either rerunFailed or rerunFailedFromLatest, not both.');
34
- }
35
- return {
36
- branch: args.branch,
37
- consoleColors: args.consoleColors,
38
- consoleWidth: args.consoleWidth,
39
- dataTables: args.datatable,
40
- doc: args.doc,
41
- dryRun: args.dryRun,
42
- exclude: args.exclude,
43
- exitOnError: args.exitOnError,
44
- exitOnFailure: args.exitOnFailure,
45
- include: args.include,
46
- jobId: args.job,
47
- metadata: args.metadata,
48
- name: args.name,
49
- parameters: (args.param ?? []).map((param) => parseParameter(param)),
50
- projectId: args.project,
51
- record: args.record,
52
- rerunFailedFromLatest: args.rerunFailedFromLatest === true ? true : undefined,
53
- rerunFailedId: args.rerunFailed,
54
- runEmptySuite: args.runEmptySuite,
55
- runType: args.runType,
56
- setTags: args.setTag,
57
- skip: args.skip,
58
- skipOnFailure: args.skipOnFailure,
59
- suites: args.suite,
60
- tag: args.tag,
61
- tests: args.test,
62
- variables: args.variable,
63
- };
22
+ const jobScreenSchema = {
23
+ screenDepth: z.number().int().positive().optional().describe('Screen color depth.'),
24
+ screenHeight: z.number().int().positive().optional().describe('Screen height.'),
25
+ screenWidth: z.number().int().positive().optional().describe('Screen width.'),
26
+ };
27
+ function requireConfirm(confirm, action) {
28
+ if (confirm !== true)
29
+ throw new Error(`${action} requires confirm: true.`);
64
30
  }
65
31
  async function testingProjectList(args = {}) {
66
32
  return { result: await listTestingProjects({ name: args.name }) };
@@ -68,11 +34,8 @@ async function testingProjectList(args = {}) {
68
34
  async function testingProjectCreate(args) {
69
35
  return {
70
36
  result: await createTestingProject({
71
- dashboardId: args.dashboardId,
72
37
  description: args.description,
73
38
  name: args.name,
74
- projectExecutor: args.executor,
75
- projectType: args.type,
76
39
  }),
77
40
  };
78
41
  }
@@ -100,8 +63,7 @@ async function testingProjectPermissionSet(args) {
100
63
  };
101
64
  }
102
65
  async function testingProjectDelete(args) {
103
- if (args.confirm !== true)
104
- throw new Error('Project deletion requires confirm: true.');
66
+ requireConfirm(args.confirm, 'Project deletion');
105
67
  return { result: await deleteTestingProject({ projectId: args.id }) };
106
68
  }
107
69
  async function testingRobotList(args) {
@@ -111,41 +73,16 @@ async function testingRobotGet(args) {
111
73
  return { result: await getTestingRobot({ projectId: args.project, robotId: args.id }) };
112
74
  }
113
75
  async function testingRobotDelete(args) {
114
- if (args.confirm !== true)
115
- throw new Error('Robot deletion requires confirm: true.');
76
+ requireConfirm(args.confirm, 'Robot deletion');
116
77
  return { result: await deleteTestingRobot({ projectId: args.project, robotId: args.id }) };
117
78
  }
118
79
  async function testingRobotCreate(args) {
119
- if (args.kind !== undefined && args.runEnvironment !== undefined) {
120
- throw new Error('Use either kind or runEnvironment, not both.');
121
- }
122
- return {
123
- result: await createTestingRobot({
124
- description: args.description,
125
- fwVersion: args.fwVersion,
126
- kind: args.runEnvironment ?? args.kind,
127
- label: args.label,
128
- name: args.name,
129
- os: args.os,
130
- projectId: args.project,
131
- reporting: args.reporting,
132
- robotType: args.robotType,
133
- }),
134
- };
80
+ const { project: projectId, ...rest } = args;
81
+ return { result: await createTestingRobot({ ...rest, projectId }) };
135
82
  }
136
83
  async function testingRobotUpdate(args) {
137
- return {
138
- result: await updateTestingRobot({
139
- description: args.description,
140
- fwVersion: args.fwVersion,
141
- label: args.label,
142
- name: args.name,
143
- projectId: args.project,
144
- reporting: args.reporting,
145
- robotId: args.id,
146
- robotType: args.robotType,
147
- }),
148
- };
84
+ const { id: robotId, project: projectId, ...rest } = args;
85
+ return { result: await updateTestingRobot({ ...rest, projectId, robotId }) };
149
86
  }
150
87
  async function testingJobList(args) {
151
88
  return { result: await listTestingJobs({ name: args.name, projectId: args.project }) };
@@ -154,78 +91,37 @@ async function testingJobGet(args) {
154
91
  return { result: await getTestingJob({ jobId: args.id, projectId: args.project }) };
155
92
  }
156
93
  async function testingJobUpdate(args) {
157
- if (args.showVideoParams === true && args.hideVideoParams === true) {
158
- throw new Error('Use either showVideoParams or hideVideoParams, not both.');
159
- }
160
- const screenValues = [args.screenDepth, args.screenHeight, args.screenWidth];
161
- const screenSupplied = screenValues.filter((value) => value !== undefined);
162
- if (screenSupplied.length > 0 && screenSupplied.length !== screenValues.length) {
163
- throw new Error('Provide screenWidth, screenHeight, and screenDepth together.');
164
- }
94
+ const { gitDomainCredential: domainCredentialId, id: jobId, parallelMode: parallelExecution, project: projectId, robot: robotId, ...rest } = args;
165
95
  return {
166
96
  result: await updateTestingJob({
167
- analytics: args.caseDurationChangeDetection === undefined
168
- ? undefined
169
- : { caseDurationChangeDetection: args.caseDurationChangeDetection },
170
- description: args.description,
171
- domainCredentialId: args.gitDomainCredential,
172
- jobId: args.id,
173
- name: args.name,
174
- parallelExecution: args.parallelMode,
175
- projectId: args.project,
176
- robotId: args.robot,
177
- screen: screenSupplied.length === 0
178
- ? undefined
179
- : { depth: args.screenDepth, height: args.screenHeight, width: args.screenWidth },
180
- showVideoParams: args.showVideoParams === true ? true : args.hideVideoParams === true ? false : undefined,
181
- storage: buildTestingGitStorageUpdate({
182
- gitBranch: args.gitBranch,
183
- gitPassword: args.gitPassword,
184
- gitTag: args.gitTag,
185
- gitUrl: args.gitUrl,
186
- gitUseCallerCredentials: args.gitUseCallerCredentials,
187
- gitUsername: args.gitUsername,
188
- }),
189
- suiteType: args.suiteType,
190
- timeout: args.timeout,
97
+ ...rest,
98
+ domainCredentialId,
99
+ jobId,
100
+ parallelExecution,
101
+ projectId,
102
+ robotId,
103
+ screenMissingMessage: 'Provide screenWidth, screenHeight, and screenDepth together.',
191
104
  }),
192
105
  };
193
106
  }
194
107
  async function testingJobDelete(args) {
195
- if (args.confirm !== true)
196
- throw new Error('Job deletion requires confirm: true.');
108
+ requireConfirm(args.confirm, 'Job deletion');
197
109
  return { result: await deleteTestingJob({ jobId: args.id, projectId: args.project }) };
198
110
  }
199
111
  async function testingJobScheduleGet(args) {
200
- const schedule = await getTestingJobSchedule({ jobId: args.job, projectId: args.project });
201
- return { result: { configured: schedule !== undefined, jobId: args.job, projectId: args.project, schedule } };
112
+ return { result: await getTestingJobScheduleStatus({ jobId: args.job, projectId: args.project }) };
202
113
  }
203
114
  async function testingJobScheduleSet(args) {
204
- return {
205
- result: await setTestingJobSchedule({
206
- cron: args.cron,
207
- jobId: args.job,
208
- projectId: args.project,
209
- record: args.record,
210
- timezone: args.timezone,
211
- }),
212
- };
115
+ const { job: jobId, project: projectId, ...rest } = args;
116
+ return { result: await setTestingJobSchedule({ ...rest, jobId, projectId }) };
213
117
  }
214
118
  async function testingJobScheduleRemove(args) {
215
- if (args.confirm !== true)
216
- throw new Error('Schedule removal requires confirm: true.');
119
+ requireConfirm(args.confirm, 'Schedule removal');
217
120
  return { result: await removeTestingJobSchedule({ jobId: args.job, projectId: args.project }) };
218
121
  }
219
122
  async function testingDataTableList(args) {
220
- return {
221
- result: await listTestingDataTables({
222
- fields: args.fields,
223
- jobId: args.job,
224
- name: args.name,
225
- projectId: args.project,
226
- version: args.revision,
227
- }),
228
- };
123
+ const { job: jobId, project: projectId, revision: version, ...rest } = args;
124
+ return { result: await listTestingDataTables({ ...rest, jobId, projectId, version }) };
229
125
  }
230
126
  async function testingDataTableGet(args) {
231
127
  return {
@@ -238,15 +134,16 @@ async function testingDataTableGet(args) {
238
134
  };
239
135
  }
240
136
  async function testingDataTableCreate(args) {
241
- if (args.confirm !== true)
242
- throw new Error('Data-table creation requires confirm: true.');
137
+ requireConfirm(args.confirm, 'Data-table creation');
243
138
  return {
244
139
  result: await createTestingDataTable({
245
140
  body: {
246
141
  ...(args.aiGenerated === undefined ? {} : { aiGenerated: args.aiGenerated }),
247
- data: prepareTestingData(args.data, args.header ?? 'row'),
142
+ data: args.data,
248
143
  ...(args.defaultRow === undefined ? {} : { defaultRow: args.defaultRow }),
144
+ header: args.header ?? 'row',
249
145
  name: args.name,
146
+ prepare: true,
250
147
  ...(args.topics === undefined ? {} : { topics: args.topics }),
251
148
  },
252
149
  jobId: args.job,
@@ -255,19 +152,15 @@ async function testingDataTableCreate(args) {
255
152
  };
256
153
  }
257
154
  async function testingDataTableUpdate(args) {
258
- if (args.confirm !== true)
259
- throw new Error('Data-table update requires confirm: true.');
260
- const body = {
261
- ...(args.aiGenerated === undefined ? {} : { aiGenerated: args.aiGenerated }),
262
- ...(args.data === undefined ? {} : { data: prepareTestingData(args.data, args.header ?? 'row') }),
263
- ...(args.defaultRow === undefined ? {} : { defaultRow: args.defaultRow }),
264
- ...(args.topics === undefined ? {} : { topics: args.topics }),
265
- };
266
- if (Object.keys(body).length === 0)
267
- throw new Error('Data-table update requires at least one field.');
155
+ requireConfirm(args.confirm, 'Data-table update');
268
156
  return {
269
157
  result: await updateTestingDataTable({
270
- body,
158
+ body: {
159
+ ...(args.aiGenerated === undefined ? {} : { aiGenerated: args.aiGenerated }),
160
+ ...(args.data === undefined ? {} : { data: args.data, header: args.header ?? 'row', prepare: true }),
161
+ ...(args.defaultRow === undefined ? {} : { defaultRow: args.defaultRow }),
162
+ ...(args.topics === undefined ? {} : { topics: args.topics }),
163
+ },
271
164
  jobId: args.job,
272
165
  projectId: args.project,
273
166
  tableId: args.id,
@@ -275,51 +168,31 @@ async function testingDataTableUpdate(args) {
275
168
  };
276
169
  }
277
170
  async function testingDataTableDelete(args) {
278
- if (args.confirm !== true)
279
- throw new Error('Data-table deletion requires confirm: true.');
280
- return {
281
- result: await deleteTestingDataTable({
282
- jobId: args.job,
283
- projectId: args.project,
284
- tableId: args.id,
285
- }),
286
- };
171
+ requireConfirm(args.confirm, 'Data-table deletion');
172
+ return { result: await deleteTestingDataTable({ jobId: args.job, projectId: args.project, tableId: args.id }) };
287
173
  }
288
174
  async function testingJobCreate(args) {
289
- const screenValues = [args.screenDepth, args.screenHeight, args.screenWidth];
290
- if (screenValues.some((value) => value !== undefined) && screenValues.includes(undefined)) {
291
- throw new Error('Provide screenWidth, screenHeight, and screenDepth together.');
292
- }
175
+ const { gitDomainCredential: gitDomainCredentialId, parallelMode: parallelExecution, project: projectId, robot: robotId, ...rest } = args;
293
176
  return {
294
177
  result: await createTestingJob({
295
- analytics: args.caseDurationChangeDetection === undefined
296
- ? undefined
297
- : { caseDurationChangeDetection: args.caseDurationChangeDetection },
298
- description: args.description,
299
- dryRun: args.dryRun,
300
- gitBranch: args.gitBranch,
301
- gitDomainCredentialId: args.gitDomainCredential,
302
- gitPassword: args.gitPassword,
303
- gitTag: args.gitTag,
304
- gitUrl: args.gitUrl,
305
- gitUseCallerCredentials: args.gitUseCallerCredentials,
306
- gitUsername: args.gitUsername,
307
- name: args.name,
308
- parallelExecution: args.parallelMode,
309
- projectId: args.project,
310
- robotId: args.robot,
311
- screen: args.screenWidth === undefined
312
- ? undefined
313
- : { depth: args.screenDepth, height: args.screenHeight, width: args.screenWidth },
314
- showVideoParams: args.showVideoParams,
315
- suiteType: args.suiteType,
316
- timeout: args.timeout,
317
- validation: args.validation,
178
+ ...rest,
179
+ gitDomainCredentialId,
180
+ parallelExecution,
181
+ projectId,
182
+ robotId,
183
+ screenMissingMessage: 'Provide screenWidth, screenHeight, and screenDepth together.',
318
184
  }),
319
185
  };
320
186
  }
321
187
  async function testingJobFiles(args) {
322
- return { result: await listTestingJobFiles({ jobId: args.job, projectId: args.project }) };
188
+ return {
189
+ result: await listTestingJobFiles({
190
+ branch: args.branch,
191
+ jobId: args.job,
192
+ projectId: args.project,
193
+ sharedCredentials: args.sharedCredentials,
194
+ }),
195
+ };
323
196
  }
324
197
  async function testingJobRefs(args) {
325
198
  return {
@@ -331,197 +204,89 @@ async function testingJobRefs(args) {
331
204
  };
332
205
  }
333
206
  async function testingJobUpload(args) {
334
- const operations = args.operations.map((operation) => ({
335
- encoding: operation.encoding,
336
- op: operation.op,
337
- path: normalizeTestingRemotePath(operation.path),
338
- value: operation.value,
339
- }));
340
- for (const operation of operations) {
341
- if (operation.op === 'remove' && operation.value !== undefined) {
342
- throw new Error('Remove operations must not include value.');
343
- }
344
- if (operation.op !== 'remove' && operation.value === undefined) {
345
- throw new Error(`${operation.op} operations require value.`);
346
- }
347
- }
207
+ const { authorEmail, authorName, job: jobId, project: projectId, ...rest } = args;
348
208
  return {
349
209
  result: await uploadTestingJobFiles({
350
- author: args.authorName === undefined && args.authorEmail === undefined
210
+ ...rest,
211
+ author: authorName === undefined && authorEmail === undefined
351
212
  ? undefined
352
- : { email: args.authorEmail ?? 'agentia@copado.com', name: args.authorName ?? 'Agentia CLI' },
353
- branch: args.branch,
354
- commitMessage: args.commitMessage,
355
- dryRun: args.dryRun,
356
- jobId: args.job,
357
- operations,
358
- parentCommitHash: args.parentCommitHash,
359
- projectId: args.project,
213
+ : { email: authorEmail ?? 'agentia@copado.com', name: authorName ?? 'Agentia CLI' },
214
+ jobId,
215
+ projectId,
360
216
  }),
361
217
  };
362
218
  }
363
219
  async function testingJobDownload(args) {
220
+ const { file: files, job: jobId, project: projectId, ...rest } = args;
221
+ return { result: await downloadTestingJobFiles({ ...rest, files, jobId, projectId }) };
222
+ }
223
+ async function testingBuildRun(args) {
224
+ const options = buildTestingRunOptions(args);
364
225
  return {
365
- result: await downloadTestingJobFiles({
366
- branch: args.branch,
367
- files: args.file,
368
- jobId: args.job,
369
- outputDir: args.outputDir,
370
- projectId: args.project,
226
+ result: await executeTestingBuildRun({
227
+ ...options,
228
+ streamLogs: args.streamLogs,
229
+ strictDataDrivenWait: true,
230
+ timeout: args.timeout,
231
+ wait: args.waitForResult === true || args.streamLogs === true,
232
+ waitForResult: args.waitForResult,
371
233
  }),
372
234
  };
373
235
  }
374
- async function testingBuildRun(args) {
375
- if ((args.datatable?.length ?? 0) > 0 && (args.waitForResult === true || args.streamLogs === true)) {
376
- throw new Error('Data-driven MCP runs start a batch and cannot wait or stream logs.');
377
- }
378
- const options = runOptions(args);
379
- const run = await runTestingBuild(options);
380
- if (args.waitForResult !== true && args.streamLogs !== true)
381
- return { result: run };
382
- const buildId = normalizeTestingId(run.build);
383
- if (buildId === undefined)
384
- throw new Error('CRT did not return a build ID for the started run.');
385
- const wait = await waitForTestingBuildResult({
386
- ...options,
387
- buildId,
388
- sensitiveValues: options.parameters?.filter((parameter) => parameter.sensitive === true).map((parameter) => parameter.value ?? ''),
389
- streamLogs: args.streamLogs,
390
- timeoutMs: (args.timeout ?? 60) * 60_000,
391
- });
392
- return { result: { ...run, finalBuild: wait.build, wait } };
393
- }
394
236
  async function testingBuildList(args) {
395
237
  if (args.count === true) {
396
238
  if (args.job === undefined)
397
239
  throw new Error('count requires job.');
398
240
  return { result: { count: await countTestingBuilds({ jobId: args.job, projectId: args.project }) } };
399
241
  }
400
- return {
401
- result: await listTestingBuilds({
402
- jobId: args.job,
403
- page: args.page,
404
- pageSize: args.pageSize,
405
- projectId: args.project,
406
- resultSize: args.resultSize ?? 'compact',
407
- status: args.status,
408
- }),
409
- };
242
+ const { job: jobId, project: projectId, resultSize = 'compact', ...rest } = args;
243
+ return { result: await listTestingBuilds({ ...rest, jobId, projectId, resultSize }) };
410
244
  }
411
245
  async function testingBuildGet(args) {
412
246
  return {
413
- result: await getTestingBuild({
414
- buildId: args.build,
415
- full: args.full,
416
- jobId: args.job,
417
- projectId: args.project,
418
- }),
419
- };
420
- }
421
- async function testingBuildLatest(args) {
422
- return {
423
- result: await latestTestingBuilds({
424
- projectId: args.project,
425
- resultSize: args.resultSize ?? 'compact',
426
- status: args.status,
427
- }),
247
+ result: await getTestingBuild({ buildId: args.build, full: args.full, jobId: args.job, projectId: args.project }),
428
248
  };
429
249
  }
430
250
  async function testingBuildSearch(args) {
431
- return {
432
- result: await searchTestingBuilds({
433
- count: args.count,
434
- from: args.from,
435
- jobId: args.job,
436
- order: args.order,
437
- page: args.page,
438
- pageSize: args.pageSize,
439
- projectId: args.project,
440
- robots: args.robot,
441
- runTypes: args.runType,
442
- sort: args.sort,
443
- statuses: args.status,
444
- to: args.to,
445
- }),
446
- };
251
+ const { job: jobId, project: projectId, robot: robots, runType: runTypes, status: statuses, ...rest } = args;
252
+ return { result: await searchTestingBuilds({ ...rest, jobId, projectId, robots, runTypes, statuses }) };
447
253
  }
448
254
  async function testingBuildLogs(args) {
255
+ const { build: buildId, job: jobId, project: projectId, ...rest } = args;
449
256
  return {
450
- result: sanitizeTestingOutput(await getTestingBuildLogs({
451
- buildId: args.build,
452
- container: args.container,
453
- jobId: args.job,
454
- limitBytes: args.limitBytes,
455
- output: args.output,
456
- pretty: args.pretty,
457
- projectId: args.project,
458
- sinceSeconds: args.sinceSeconds,
459
- tailLines: args.tailLines,
460
- timestamps: args.timestamps,
461
- })),
257
+ result: sanitizeTestingOutput(await getTestingBuildLogs({ ...rest, buildId, jobId, projectId }), {
258
+ preserveLogKeys: true,
259
+ }),
462
260
  };
463
261
  }
464
262
  async function testingBuildAbort(args) {
465
- if (args.confirm !== true)
466
- throw new Error('Build abort requires confirm: true.');
467
- return {
468
- result: await abortTestingBuild({
469
- buildId: args.build,
470
- jobId: args.job,
471
- projectId: args.project,
472
- }),
473
- };
263
+ requireConfirm(args.confirm, 'Build abort');
264
+ return { result: await abortTestingBuild({ buildId: args.build, jobId: args.job, projectId: args.project }) };
474
265
  }
475
266
  async function testingVariableList(args) {
476
- return {
477
- result: await listTestingVariables({
478
- jobId: args.job,
479
- key: args.key,
480
- projectId: args.project,
481
- robotId: args.robot,
482
- sensitive: args.sensitive,
483
- type: args.type,
484
- userSpecific: args.userSpecific,
485
- }),
486
- };
267
+ const { job: jobId, project: projectId, robot: robotId, ...rest } = args;
268
+ return { result: await listTestingVariables({ ...rest, jobId, projectId, robotId }) };
487
269
  }
488
270
  async function testingVariableGet(args) {
489
271
  return { result: await getTestingVariable({ projectId: args.project, variableId: args.id }) };
490
272
  }
491
273
  async function testingVariableCreate(args) {
492
- return {
493
- result: await createTestingVariable({
494
- description: args.description,
495
- jobId: args.job,
496
- key: args.key,
497
- projectId: args.project,
498
- robotId: args.robot,
499
- sensitive: args.sensitive,
500
- type: args.type,
501
- userSpecific: args.userSpecific,
502
- value: args.value,
503
- }),
504
- };
274
+ const { job: jobId, project: projectId, robot: robotId, ...rest } = args;
275
+ return { result: await createTestingVariable({ ...rest, jobId, projectId, robotId }) };
505
276
  }
506
277
  async function testingVariableUpdate(args) {
507
- if (args.sensitive === true && args.notSensitive === true) {
508
- throw new Error('Use either sensitive or notSensitive, not both.');
509
- }
278
+ const { id: variableId, project: projectId, ...rest } = args;
510
279
  return {
511
280
  result: await updateTestingVariable({
512
- description: args.description,
513
- key: args.key,
514
- projectId: args.project,
515
- sensitive: args.sensitive === true ? true : args.notSensitive === true ? false : undefined,
516
- type: args.type,
517
- value: args.value,
518
- variableId: args.id,
281
+ ...rest,
282
+ projectId,
283
+ sensitiveConflictMessage: 'Use either sensitive or notSensitive, not both.',
284
+ variableId,
519
285
  }),
520
286
  };
521
287
  }
522
288
  async function testingVariableDelete(args) {
523
- if (args.confirm !== true)
524
- throw new Error('Variable deletion requires confirm: true.');
289
+ requireConfirm(args.confirm, 'Variable deletion');
525
290
  return { result: await deleteTestingVariable({ projectId: args.project, variableId: args.id }) };
526
291
  }
527
292
  async function testingUserParameterList(args) {
@@ -531,38 +296,22 @@ async function testingUserParameterGet(args) {
531
296
  return { result: await getTestingUserParameter({ parameterId: args.id }) };
532
297
  }
533
298
  async function testingUserParameterCreate(args) {
534
- return {
535
- result: await createTestingUserParameter({
536
- description: args.description,
537
- key: args.key,
538
- sensitive: args.sensitive,
539
- unique: args.unique,
540
- value: args.value,
541
- }),
542
- };
299
+ return { result: await createTestingUserParameter(args) };
543
300
  }
544
301
  async function testingUserParameterUpdate(args) {
545
- return {
546
- result: await updateTestingUserParameter({
547
- description: args.description,
548
- key: args.key,
549
- parameterId: args.id,
550
- unique: args.unique,
551
- value: args.value,
552
- }),
553
- };
302
+ const { id: parameterId, ...rest } = args;
303
+ return { result: await updateTestingUserParameter({ ...rest, parameterId }) };
554
304
  }
555
305
  async function testingUserParameterDelete(args) {
556
- if (args.confirm !== true)
557
- throw new Error('User-parameter deletion requires confirm: true.');
306
+ requireConfirm(args.confirm, 'User-parameter deletion');
558
307
  return { result: await deleteTestingUserParameter({ parameterId: args.id }) };
559
308
  }
560
309
  const buildListSchema = {
561
310
  count: z.boolean().optional().describe('Return only the build count; requires job.'),
562
- job: z.number().int().positive().optional().describe('CRT job/test ID.'),
311
+ job: optionalJobIdSchema,
563
312
  page: z.number().int().positive().optional().describe('Build page number.'),
564
313
  pageSize: z.number().int().positive().optional().describe('Build page size.'),
565
- project: z.number().int().positive().describe('CRT project ID.'),
314
+ project: projectIdSchema,
566
315
  resultSize: z.enum(['compact']).optional().describe('CRT result size.'),
567
316
  status: z.enum(TESTING_BUILD_STATUSES).optional().describe('Build status filter.'),
568
317
  };
@@ -572,21 +321,28 @@ const uploadSchema = {
572
321
  branch: z.string().optional().describe('Optional CRT branch name.'),
573
322
  commitMessage: z.string().optional().describe('Commit message for CRT file history.'),
574
323
  dryRun: z.boolean().optional().describe('Return a sanitized plan without making a network mutation.'),
575
- job: z.number().int().positive().describe('CRT job/test ID.'),
576
- operations: z.array(z.object({
324
+ job: jobIdSchema,
325
+ operations: z
326
+ .array(z.object({
577
327
  encoding: z.enum(['utf-8', 'base64']).optional(),
578
328
  op: z.enum(['add', 'replace', 'remove']),
579
329
  path: z.string().min(1),
580
330
  value: z.string().max(1_048_576).optional(),
581
- })).min(1).max(100).describe('Bounded structured file operations; local paths and stdin are not available in MCP.'),
331
+ }))
332
+ .min(1)
333
+ .max(100)
334
+ .describe('Bounded structured file operations; local paths and stdin are not available in MCP.'),
582
335
  parentCommitHash: z.string().optional().describe('Expected parent commit hash.'),
583
- project: z.number().int().positive().describe('CRT project ID.'),
336
+ project: projectIdSchema,
584
337
  };
585
338
  const runOptionSchema = {
586
339
  branch: z.string().optional().describe('Git branch/ref to use for this run. Mutually exclusive with tag.'),
587
340
  consoleColors: z.enum(TESTING_CONSOLE_COLORS).optional().describe('Robot Framework console color mode.'),
588
341
  consoleWidth: z.number().int().positive().optional().describe('Robot Framework console width.'),
589
- datatable: z.array(z.string()).optional().describe('Data-driven TABLE_ID:DATASETS selections.'),
342
+ datatable: z
343
+ .array(z.string())
344
+ .optional()
345
+ .describe('Data-driven TABLE_ID:DATASETS selections. Batch runs cannot wait or stream logs.'),
590
346
  doc: z.string().optional().describe('Top-level Robot Framework suite documentation.'),
591
347
  dryRun: z.boolean().optional().describe('Validate Robot Framework data without executing library keywords.'),
592
348
  exclude: z.array(z.string()).optional().describe('Robot Framework tags to exclude from this run.'),
@@ -604,30 +360,32 @@ const runOptionSchema = {
604
360
  setTag: z.array(z.string()).optional().describe('Tags to set on every executed test.'),
605
361
  skip: z.array(z.string()).optional().describe('Tags for tests to skip.'),
606
362
  skipOnFailure: z.array(z.string()).optional().describe('Tags whose failing tests should be skipped.'),
607
- streamLogs: z.boolean().optional().describe('Poll logs while waiting and return them once; MCP never streams chunks.'),
363
+ streamLogs: z
364
+ .boolean()
365
+ .optional()
366
+ .describe('Wait for the run and return the finished log once. MCP never streams chunks. Implies a wait, and is rejected for data-driven runs.'),
608
367
  suite: z.array(z.string()).optional().describe('Robot Framework suites to select.'),
609
368
  tag: z.string().optional().describe('Git tag to use for this run. Mutually exclusive with branch.'),
610
369
  test: z.array(z.string()).optional().describe('Robot Framework tests/tasks to select.'),
611
370
  timeout: z.number().int().positive().optional().describe('Maximum wait time in minutes.'),
612
371
  variable: z.array(z.string()).optional().describe('Robot Framework variables.'),
613
- waitForResult: z.boolean().optional().describe('Poll until the build reaches a terminal result.'),
614
- };
615
- const buildRunSchema = {
616
- job: z.number().int().positive().describe('CRT job/test ID.'),
617
- project: z.number().int().positive().describe('CRT project ID.'),
618
- ...runOptionSchema,
372
+ waitForResult: z
373
+ .boolean()
374
+ .optional()
375
+ .describe('Poll until the build reaches a terminal result. Omitted means do not wait. The CLI waits by default; this tool does not. Rejected for data-driven runs.'),
619
376
  };
377
+ const buildRunSchema = { job: jobIdSchema, project: projectIdSchema, ...runOptionSchema };
620
378
  const testingDataMatrixSchema = z
621
379
  .array(z.array(z.string().max(TESTING_DATA_MAX_CELL_BYTES)).max(TESTING_DATA_MAX_COLUMNS))
622
380
  .max(TESTING_DATA_MAX_ROWS);
623
381
  const buildLogSchema = {
624
382
  build: z.number().int().positive().describe('CRT build/run ID.'),
625
383
  container: z.string().optional().describe('Specific CRT log stream/container.'),
626
- job: z.number().int().positive().describe('CRT job/test ID.'),
384
+ job: jobIdSchema,
627
385
  limitBytes: z.number().int().positive().optional().describe('Maximum log bytes to fetch.'),
628
386
  output: z.string().optional().describe('Output file for logs.'),
629
387
  pretty: z.boolean().optional().describe('Request readable log formatting.'),
630
- project: z.number().int().positive().describe('CRT project ID.'),
388
+ project: projectIdSchema,
631
389
  sinceSeconds: z.number().int().nonnegative().optional().describe('Fetch logs from the last N seconds.'),
632
390
  tailLines: z.number().int().nonnegative().optional().describe('Return only the last N lines.'),
633
391
  timestamps: z.boolean().optional().describe('Add timestamps to log lines.'),
@@ -635,7 +393,7 @@ const buildLogSchema = {
635
393
  export const agentiaMcpTestingToolHandlers = {
636
394
  testingBuildAbort,
637
395
  testingBuildGet,
638
- testingBuildLatest,
396
+ testingBuildLatest: testingBuildList,
639
397
  testingBuildList,
640
398
  testingBuildLogs,
641
399
  testingBuildRun,
@@ -697,11 +455,8 @@ export function registerAgentiaMcpTestingTools(server) {
697
455
  server.registerTool('agentia_testing_project_create', {
698
456
  description: 'Create a Copado Robotic Testing project.',
699
457
  inputSchema: {
700
- dashboardId: z.number().int().positive().optional().describe('Optional CRT dashboard ID.'),
701
458
  description: z.string().optional().describe('Project description.'),
702
- executor: z.enum(TESTING_PROJECT_EXECUTORS).optional().describe('Project execution backend.'),
703
459
  name: z.string().describe('Project name.'),
704
- type: z.enum(TESTING_PROJECT_TYPES).optional().describe('CRT project type.'),
705
460
  },
706
461
  title: 'Agentia Testing Project Create',
707
462
  }, (args) => safelyHandleTool(() => testingProjectCreate(args)));
@@ -721,18 +476,18 @@ export function registerAgentiaMcpTestingTools(server) {
721
476
  }, (args) => safelyHandleTool(() => testingProjectUpdate(args)));
722
477
  server.registerTool('agentia_testing_project_permission_list', {
723
478
  description: 'List assignments for a Copado Robotic Testing project.',
724
- inputSchema: { project: z.number().int().positive().describe('CRT project ID.') },
479
+ inputSchema: { project: projectIdSchema },
725
480
  title: 'Agentia Testing Project Permission List',
726
481
  }, (args) => safelyHandleTool(() => testingProjectPermissionList(args)));
727
482
  server.registerTool('agentia_testing_project_permission_get', {
728
483
  description: "Get the caller's permission on a Copado Robotic Testing project.",
729
- inputSchema: { project: z.number().int().positive().describe('CRT project ID.') },
484
+ inputSchema: { project: projectIdSchema },
730
485
  title: 'Agentia Testing Project Permission Get',
731
486
  }, (args) => safelyHandleTool(() => testingProjectPermissionGet(args)));
732
487
  const permissionMutationSchema = {
733
488
  edit: z.boolean().optional().describe('Grant edit access.'),
734
489
  group: z.number().int().positive().optional().describe('Platform group ID; exclusive with user.'),
735
- project: z.number().int().positive().describe('CRT project ID.'),
490
+ project: projectIdSchema,
736
491
  user: z.number().int().positive().optional().describe('Platform user ID; exclusive with group.'),
737
492
  view: z.boolean().optional().describe('Grant view access.'),
738
493
  };
@@ -748,23 +503,17 @@ export function registerAgentiaMcpTestingTools(server) {
748
503
  }, (args) => safelyHandleTool(() => testingProjectPermissionSet(args)));
749
504
  server.registerTool('agentia_testing_project_delete', {
750
505
  description: 'Delete a Copado Robotic Testing project.',
751
- inputSchema: {
752
- confirm: z.boolean().describe('Must be true to confirm project deletion.'),
753
- id: z.number().int().positive().describe('CRT project ID.'),
754
- },
506
+ inputSchema: { confirm: z.boolean().describe('Must be true to confirm project deletion.'), id: projectIdSchema },
755
507
  title: 'Agentia Testing Project Delete',
756
508
  }, (args) => safelyHandleTool(() => testingProjectDelete(args)));
757
509
  server.registerTool('agentia_testing_robot_list', {
758
510
  description: 'List Copado Robotic Testing robots.',
759
- inputSchema: { project: z.number().int().positive().describe('CRT project ID.') },
511
+ inputSchema: { project: projectIdSchema },
760
512
  title: 'Agentia Testing Robot List',
761
513
  }, (args) => safelyHandleTool(() => testingRobotList(args)));
762
514
  server.registerTool('agentia_testing_robot_get', {
763
515
  description: 'Get a Copado Robotic Testing robot from the project robot list.',
764
- inputSchema: {
765
- id: z.string().describe('CRT robot ID.'),
766
- project: z.number().int().positive().describe('CRT project ID.'),
767
- },
516
+ inputSchema: { id: z.string().describe('CRT robot ID.'), project: projectIdSchema },
768
517
  title: 'Agentia Testing Robot Get',
769
518
  }, (args) => safelyHandleTool(() => testingRobotGet(args)));
770
519
  server.registerTool('agentia_testing_robot_delete', {
@@ -772,7 +521,7 @@ export function registerAgentiaMcpTestingTools(server) {
772
521
  inputSchema: {
773
522
  confirm: z.boolean().describe('Must be true to confirm robot deletion.'),
774
523
  id: z.string().describe('CRT robot ID.'),
775
- project: z.number().int().positive().describe('CRT project ID.'),
524
+ project: projectIdSchema,
776
525
  },
777
526
  title: 'Agentia Testing Robot Delete',
778
527
  }, (args) => safelyHandleTool(() => testingRobotDelete(args)));
@@ -781,14 +530,15 @@ export function registerAgentiaMcpTestingTools(server) {
781
530
  inputSchema: {
782
531
  description: z.string().optional().describe('Robot description.'),
783
532
  fwVersion: z.string().optional().describe('Robot framework version.'),
784
- kind: z.enum(TESTING_ROBOT_RUN_ENVIRONMENTS).optional().describe('Robot run environment.'),
785
533
  label: z.string().optional().describe('Robot label.'),
786
534
  name: z.string().describe('Robot name.'),
787
- os: z.string().optional().describe('Robot operating system.'),
788
- project: z.number().int().positive().describe('CRT project ID.'),
789
- reporting: z.enum(TESTING_ROBOT_REPORTING).optional().describe('Testing result retention.'),
790
- robotType: z.enum(TESTING_ROBOT_TYPES).optional().describe('CRT robot type.'),
791
- runEnvironment: z.enum(TESTING_ROBOT_RUN_ENVIRONMENTS).optional().describe('Robot execution environment.'),
535
+ project: projectIdSchema,
536
+ reporting: z.enum(TESTING_ROBOT_REPORTING).optional().describe(TESTING_ROBOT_REPORTING_DESCRIPTION),
537
+ robotType: z.enum(TESTING_ROBOT_TYPES).optional().describe(TESTING_ROBOT_TYPE_DESCRIPTION),
538
+ runEnvironment: z
539
+ .enum(TESTING_ROBOT_ACCEPTED_RUN_ENVIRONMENTS)
540
+ .optional()
541
+ .describe(TESTING_ROBOT_RUN_ENVIRONMENT_DESCRIPTION),
792
542
  },
793
543
  title: 'Agentia Testing Robot Create',
794
544
  }, (args) => safelyHandleTool(() => testingRobotCreate(args)));
@@ -800,72 +550,66 @@ export function registerAgentiaMcpTestingTools(server) {
800
550
  id: z.string().describe('CRT robot ID.'),
801
551
  label: z.string().optional().describe('New robot label.'),
802
552
  name: z.string().optional().describe('New robot name.'),
803
- project: z.number().int().positive().describe('CRT project ID.'),
804
- reporting: z.enum(TESTING_ROBOT_REPORTING).optional().describe('Testing result retention.'),
805
- robotType: z.enum(TESTING_ROBOT_TYPES).optional().describe('CRT robot type.'),
553
+ project: projectIdSchema,
554
+ reporting: z.enum(TESTING_ROBOT_REPORTING).optional().describe(TESTING_ROBOT_REPORTING_DESCRIPTION),
555
+ robotType: z.enum(TESTING_ROBOT_TYPES).optional().describe(TESTING_ROBOT_TYPE_DESCRIPTION),
806
556
  },
807
557
  title: 'Agentia Testing Robot Update',
808
558
  }, (args) => safelyHandleTool(() => testingRobotUpdate(args)));
809
559
  server.registerTool('agentia_testing_job_list', {
810
- description: 'List Copado Robotic Testing jobs/tests.',
560
+ description: 'List Copado Robotic Testing jobs.',
811
561
  inputSchema: {
812
- name: z.string().optional().describe('Case-insensitive exact job/test name filter.'),
813
- project: z.number().int().positive().describe('CRT project ID.'),
562
+ name: z.string().optional().describe('Case-insensitive exact job name filter.'),
563
+ project: projectIdSchema,
814
564
  },
815
565
  title: 'Agentia Testing Job List',
816
566
  }, (args) => safelyHandleTool(() => testingJobList(args)));
817
567
  server.registerTool('agentia_testing_job_get', {
818
- description: 'Get a Copado Robotic Testing job/test from the project job list.',
819
- inputSchema: {
820
- id: z.string().describe('CRT job/test ID.'),
821
- project: z.number().int().positive().describe('CRT project ID.'),
822
- },
568
+ description: 'Get a Copado Robotic Testing job from the project job list.',
569
+ inputSchema: { id: z.string().describe('CRT job ID.'), project: projectIdSchema },
823
570
  title: 'Agentia Testing Job Get',
824
571
  }, (args) => safelyHandleTool(() => testingJobGet(args)));
825
572
  server.registerTool('agentia_testing_job_update', {
826
- description: 'Update Copado Robotic Testing job/test metadata or Git storage.',
573
+ description: 'Update Copado Robotic Testing job metadata or Git storage.',
827
574
  inputSchema: {
828
575
  caseDurationChangeDetection: z.boolean().optional().describe('Enable or disable duration analytics.'),
829
- description: z.string().optional().describe('Job/test description.'),
576
+ description: z.string().optional().describe('Job description.'),
830
577
  ...gitStorageSchema,
831
- hideVideoParams: z.boolean().optional().describe('Hide video parameters.'),
832
- id: z.number().int().positive().describe('CRT job/test ID.'),
833
- name: z.string().optional().describe('Job/test name.'),
578
+ id: jobIdSchema,
579
+ name: z.string().optional().describe('Job name.'),
834
580
  parallelMode: z.enum(TESTING_JOB_PARALLEL_MODES).optional().describe('Parallel execution mode.'),
835
- project: z.number().int().positive().describe('CRT project ID.'),
581
+ project: projectIdSchema,
836
582
  robot: z.number().int().positive().optional().describe('CRT robot ID.'),
837
- screenDepth: z.number().int().positive().optional().describe('Screen color depth.'),
838
- screenHeight: z.number().int().positive().optional().describe('Screen height.'),
839
- screenWidth: z.number().int().positive().optional().describe('Screen width.'),
840
- showVideoParams: z.boolean().optional().describe('Show video parameters.'),
583
+ ...jobScreenSchema,
584
+ showVideoParams: z
585
+ .boolean()
586
+ .optional()
587
+ .describe('Enable or disable video streaming and recording capabilities when running the test job.'),
841
588
  suiteType: z.enum(TESTING_JOB_SUITE_TYPES).optional().describe('CRT suite/job type.'),
842
589
  timeout: z.string().optional().describe('Build timeout, for example 10m.'),
843
590
  },
844
591
  title: 'Agentia Testing Job Update',
845
592
  }, (args) => safelyHandleTool(() => testingJobUpdate(args)));
846
593
  server.registerTool('agentia_testing_job_delete', {
847
- description: 'Delete a Copado Robotic Testing job/test.',
594
+ description: 'Delete a Copado Robotic Testing job.',
848
595
  inputSchema: {
849
596
  confirm: z.boolean().describe('Must be true to confirm job deletion.'),
850
- id: z.number().int().positive().describe('CRT job/test ID.'),
851
- project: z.number().int().positive().describe('CRT project ID.'),
597
+ id: jobIdSchema,
598
+ project: projectIdSchema,
852
599
  },
853
600
  title: 'Agentia Testing Job Delete',
854
601
  }, (args) => safelyHandleTool(() => testingJobDelete(args)));
855
602
  server.registerTool('agentia_testing_job_schedule_get', {
856
603
  description: 'Get a Copado Robotic Testing job schedule.',
857
- inputSchema: {
858
- job: z.number().int().positive().describe('CRT job/test ID.'),
859
- project: z.number().int().positive().describe('CRT project ID.'),
860
- },
604
+ inputSchema: { job: jobIdSchema, project: projectIdSchema },
861
605
  title: 'Agentia Testing Job Schedule Get',
862
606
  }, (args) => safelyHandleTool(() => testingJobScheduleGet(args)));
863
607
  server.registerTool('agentia_testing_job_schedule_set', {
864
608
  description: 'Create or update a Copado Robotic Testing job schedule.',
865
609
  inputSchema: {
866
610
  cron: z.string().min(1).describe('Cron expression.'),
867
- job: z.number().int().positive().describe('CRT job/test ID.'),
868
- project: z.number().int().positive().describe('CRT project ID.'),
611
+ job: jobIdSchema,
612
+ project: projectIdSchema,
869
613
  record: z.enum(TESTING_RECORD_BUILD_OPTIONS).optional().describe('Scheduled run recording mode.'),
870
614
  timezone: z.string().optional().describe('Schedule timezone.'),
871
615
  },
@@ -875,8 +619,8 @@ export function registerAgentiaMcpTestingTools(server) {
875
619
  description: 'Remove a Copado Robotic Testing job schedule.',
876
620
  inputSchema: {
877
621
  confirm: z.boolean().describe('Must be true to confirm schedule removal.'),
878
- job: z.number().int().positive().describe('CRT job/test ID.'),
879
- project: z.number().int().positive().describe('CRT project ID.'),
622
+ job: jobIdSchema,
623
+ project: projectIdSchema,
880
624
  },
881
625
  title: 'Agentia Testing Job Schedule Remove',
882
626
  }, (args) => safelyHandleTool(() => testingJobScheduleRemove(args)));
@@ -884,9 +628,9 @@ export function registerAgentiaMcpTestingTools(server) {
884
628
  description: 'List Copado Robotic Testing data tables.',
885
629
  inputSchema: {
886
630
  fields: z.string().optional().describe('Comma-separated response fields.'),
887
- job: z.number().int().positive().optional().describe('CRT job/test ID filter.'),
631
+ job: optionalJobIdSchema,
888
632
  name: z.string().optional().describe('Exact table name filter.'),
889
- project: z.number().int().positive().describe('CRT project ID.'),
633
+ project: projectIdSchema,
890
634
  revision: z.string().optional().describe('Table revision/version filter.'),
891
635
  },
892
636
  title: 'Agentia Testing Data Table List',
@@ -895,8 +639,8 @@ export function registerAgentiaMcpTestingTools(server) {
895
639
  description: 'Get a Copado Robotic Testing data table.',
896
640
  inputSchema: {
897
641
  id: z.number().int().positive().describe('CRT data-table ID.'),
898
- job: z.number().int().positive().optional().describe('CRT job/test ID filter.'),
899
- project: z.number().int().positive().describe('CRT project ID.'),
642
+ job: optionalJobIdSchema,
643
+ project: projectIdSchema,
900
644
  revision: z.string().optional().describe('Table revision/version.'),
901
645
  },
902
646
  title: 'Agentia Testing Data Table Get',
@@ -909,9 +653,9 @@ export function registerAgentiaMcpTestingTools(server) {
909
653
  data: testingDataMatrixSchema.min(1).describe('Rows with a header row followed by datasets.'),
910
654
  defaultRow: z.number().int().positive().optional().describe('Default dataset row.'),
911
655
  header: z.enum(['row', 'column']).optional().describe('Input header orientation.'),
912
- job: z.number().int().positive().optional().describe('Optional CRT job/test ID scope.'),
656
+ job: optionalJobIdSchema,
913
657
  name: z.string().min(1).describe('Data-table name.'),
914
- project: z.number().int().positive().describe('CRT project ID.'),
658
+ project: projectIdSchema,
915
659
  topics: z.array(z.string()).optional().describe('Topic tags.'),
916
660
  },
917
661
  title: 'Agentia Testing Data Table Create',
@@ -925,8 +669,8 @@ export function registerAgentiaMcpTestingTools(server) {
925
669
  defaultRow: z.number().int().positive().optional().describe('Default dataset row.'),
926
670
  header: z.enum(['row', 'column']).optional().describe('Input header orientation.'),
927
671
  id: z.number().int().positive().describe('CRT data-table ID.'),
928
- job: z.number().int().positive().optional().describe('Optional CRT job/test ID scope.'),
929
- project: z.number().int().positive().describe('CRT project ID.'),
672
+ job: optionalJobIdSchema,
673
+ project: projectIdSchema,
930
674
  topics: z.array(z.string()).optional().describe('Replacement topic tags.'),
931
675
  },
932
676
  title: 'Agentia Testing Data Table Update',
@@ -936,25 +680,26 @@ export function registerAgentiaMcpTestingTools(server) {
936
680
  inputSchema: {
937
681
  confirm: z.boolean().describe('Must be true to confirm deletion.'),
938
682
  id: z.number().int().positive().describe('CRT data-table ID.'),
939
- job: z.number().int().positive().optional().describe('Optional CRT job/test ID scope.'),
940
- project: z.number().int().positive().describe('CRT project ID.'),
683
+ job: optionalJobIdSchema,
684
+ project: projectIdSchema,
941
685
  },
942
686
  title: 'Agentia Testing Data Table Delete',
943
687
  }, (args) => safelyHandleTool(() => testingDataTableDelete(args)));
944
688
  server.registerTool('agentia_testing_job_create', {
945
- description: 'Create a Copado Robotic Testing job/test from uploaded files or Git storage.',
689
+ description: 'Create a Copado Robotic Testing job from uploaded files or Git storage.',
946
690
  inputSchema: {
947
691
  caseDurationChangeDetection: z.boolean().optional().describe('Enable or disable duration analytics.'),
948
- description: z.string().optional().describe('Job/test description.'),
692
+ description: z.string().optional().describe('Job description.'),
949
693
  dryRun: z.boolean().optional().describe('Return a sanitized creation plan without network mutation.'),
950
- name: z.string().describe('Job/test name.'),
694
+ name: z.string().describe('Job name.'),
951
695
  parallelMode: z.enum(TESTING_JOB_PARALLEL_MODES).optional().describe('Parallel execution mode.'),
952
- project: z.number().int().positive().describe('CRT project ID.'),
696
+ project: projectIdSchema,
953
697
  robot: z.string().describe('CRT robot ID.'),
954
- screenDepth: z.number().int().positive().optional().describe('Screen color depth.'),
955
- screenHeight: z.number().int().positive().optional().describe('Screen height.'),
956
- screenWidth: z.number().int().positive().optional().describe('Screen width.'),
957
- showVideoParams: z.boolean().optional().describe('Show or hide video parameters.'),
698
+ ...jobScreenSchema,
699
+ showVideoParams: z
700
+ .boolean()
701
+ .optional()
702
+ .describe('Enable or disable video streaming and recording capabilities when running the test job.'),
958
703
  suiteType: z.enum(TESTING_JOB_SUITE_TYPES).optional().describe('CRT suite/job type.'),
959
704
  timeout: z.string().optional().describe('Build timeout, for example 10m.'),
960
705
  validation: z.boolean().optional().describe('Ask CRT to validate the created job.'),
@@ -963,111 +708,99 @@ export function registerAgentiaMcpTestingTools(server) {
963
708
  title: 'Agentia Testing Job Create',
964
709
  }, (args) => safelyHandleTool(() => testingJobCreate(args)));
965
710
  server.registerTool('agentia_testing_job_run', {
966
- description: 'Run a Copado Robotic Testing job/test.',
711
+ description: 'Run a Copado Robotic Testing job. Does not wait unless waitForResult or streamLogs is set. Data-driven runs reject waiting.',
967
712
  inputSchema: buildRunSchema,
968
713
  title: 'Agentia Testing Job Run',
969
714
  }, (args) => safelyHandleTool(() => testingBuildRun(args)));
970
- server.registerTool('agentia_testing_job_files', {
971
- description: 'List files for a Copado Robotic Testing job/test.',
715
+ server.registerTool('agentia_testing_job_files_list', {
716
+ description: 'List files for a Copado Robotic Testing job.',
972
717
  inputSchema: {
973
- job: z.number().int().positive().describe('CRT job/test ID.'),
974
- project: z.number().int().positive().describe('CRT project ID.'),
718
+ branch: z.string().optional().describe('Optional CRT branch name.'),
719
+ job: jobIdSchema,
720
+ project: projectIdSchema,
721
+ sharedCredentials: z.boolean().optional().describe('Use shared stored Git credentials.'),
975
722
  },
976
- title: 'Agentia Testing Job Files',
723
+ title: 'Agentia Testing Job Files List',
977
724
  }, (args) => safelyHandleTool(() => testingJobFiles(args)));
978
725
  server.registerTool('agentia_testing_job_refs', {
979
- description: 'List Git branches and tags for a Copado Robotic Testing job/test.',
726
+ description: 'List Git branches and tags for a Copado Robotic Testing job.',
980
727
  inputSchema: {
981
- job: z.number().int().positive().describe('CRT job/test ID.'),
982
- project: z.number().int().positive().describe('CRT project ID.'),
728
+ job: jobIdSchema,
729
+ project: projectIdSchema,
983
730
  sharedCredentials: z.boolean().optional().describe('Use shared stored Git credentials.'),
984
731
  },
985
732
  title: 'Agentia Testing Job Refs',
986
733
  }, (args) => safelyHandleTool(() => testingJobRefs(args)));
987
- server.registerTool('agentia_testing_job_upload', {
988
- description: 'Upload file operations to a Copado Robotic Testing job/test.',
734
+ server.registerTool('agentia_testing_job_files_upload', {
735
+ description: 'Upload file operations to a Copado Robotic Testing job.',
989
736
  inputSchema: uploadSchema,
990
- title: 'Agentia Testing Job Upload',
737
+ title: 'Agentia Testing Job Files Upload',
991
738
  }, (args) => safelyHandleTool(() => testingJobUpload(args)));
992
- server.registerTool('agentia_testing_job_download', {
993
- description: 'Download files from a Copado Robotic Testing job/test.',
739
+ server.registerTool('agentia_testing_job_files_download', {
740
+ description: 'Download files from a Copado Robotic Testing job.',
994
741
  inputSchema: {
995
742
  branch: z.string().optional().describe('Optional CRT branch name.'),
996
743
  file: z.array(z.string()).describe('Remote CRT file paths.'),
997
- job: z.number().int().positive().describe('CRT job/test ID.'),
744
+ job: jobIdSchema,
998
745
  outputDir: z.string().optional().describe('Output directory for downloaded files.'),
999
- project: z.number().int().positive().describe('CRT project ID.'),
746
+ project: projectIdSchema,
1000
747
  },
1001
- title: 'Agentia Testing Job Download',
748
+ title: 'Agentia Testing Job Files Download',
1002
749
  }, (args) => safelyHandleTool(() => testingJobDownload(args)));
1003
- server.registerTool('agentia_testing_build_run', {
1004
- description: 'Run a Copado Robotic Testing job/test.',
1005
- inputSchema: buildRunSchema,
1006
- title: 'Agentia Testing Build Run',
1007
- }, (args) => safelyHandleTool(() => testingBuildRun(args)));
1008
- server.registerTool('agentia_testing_build_list', {
1009
- description: 'List Copado Robotic Testing builds/runs.',
750
+ server.registerTool('agentia_testing_job_runs_list', {
751
+ description: 'List Copado Robotic Testing job runs.',
1010
752
  inputSchema: buildListSchema,
1011
- title: 'Agentia Testing Build List',
753
+ title: 'Agentia Testing Job Runs List',
1012
754
  }, (args) => safelyHandleTool(() => testingBuildList(args)));
1013
- server.registerTool('agentia_testing_build_get', {
1014
- description: 'Get a Copado Robotic Testing build/run.',
755
+ server.registerTool('agentia_testing_job_runs_get', {
756
+ description: 'Get the result of a Copado Robotic Testing job run.',
1015
757
  inputSchema: {
1016
758
  build: z.number().int().positive().describe('CRT build/run ID.'),
1017
759
  full: z.boolean().optional().describe('Fetch the full build result.'),
1018
- job: z.number().int().positive().describe('CRT job/test ID.'),
1019
- project: z.number().int().positive().describe('CRT project ID.'),
760
+ job: jobIdSchema,
761
+ project: projectIdSchema,
1020
762
  },
1021
- title: 'Agentia Testing Build Get',
763
+ title: 'Agentia Testing Job Runs Get',
1022
764
  }, (args) => safelyHandleTool(() => testingBuildGet(args)));
1023
- server.registerTool('agentia_testing_build_latest', {
1024
- description: 'List the latest Copado Robotic Testing builds/runs.',
1025
- inputSchema: {
1026
- project: z.number().int().positive().describe('CRT project ID.'),
1027
- resultSize: z.enum(['compact']).optional().describe('CRT result size.'),
1028
- status: z.enum(TESTING_BUILD_STATUSES).optional().describe('Build status filter.'),
1029
- },
1030
- title: 'Agentia Testing Build Latest',
1031
- }, (args) => safelyHandleTool(() => testingBuildLatest(args)));
1032
- server.registerTool('agentia_testing_build_search', {
1033
- description: 'Search Copado Robotic Testing build metrics.',
765
+ server.registerTool('agentia_testing_job_runs_search', {
766
+ description: 'Search Copado Robotic Testing job run metrics.',
1034
767
  inputSchema: {
1035
768
  count: z.boolean().optional().describe('Return only the filtered count.'),
1036
769
  from: z.string().optional().describe('Start date or epoch filter.'),
1037
- job: z.number().int().positive().describe('CRT job/test ID.'),
770
+ job: jobIdSchema,
1038
771
  order: z.enum(['asc', 'desc']).optional().describe('Sort order.'),
1039
772
  page: z.number().int().positive().optional().describe('Result page.'),
1040
773
  pageSize: z.number().int().positive().optional().describe('Result page size.'),
1041
- project: z.number().int().positive().describe('CRT project ID.'),
774
+ project: projectIdSchema,
1042
775
  robot: z.array(z.string()).optional().describe('Robot ID filters.'),
1043
776
  runType: z.array(z.enum(TESTING_RUN_TYPES)).optional().describe('Run type filters.'),
1044
777
  sort: z.enum(['date', 'duration', 'id', 'status']).optional().describe('Sort field.'),
1045
778
  status: z.array(z.string()).optional().describe('Status filters.'),
1046
779
  to: z.string().optional().describe('End date or epoch filter.'),
1047
780
  },
1048
- title: 'Agentia Testing Build Search',
781
+ title: 'Agentia Testing Job Runs Search',
1049
782
  }, (args) => safelyHandleTool(() => testingBuildSearch(args)));
1050
- server.registerTool('agentia_testing_build_logs', {
1051
- description: 'Get logs for a Copado Robotic Testing build/run.',
783
+ server.registerTool('agentia_testing_job_runs_logs', {
784
+ description: 'Get logs for a Copado Robotic Testing job run.',
1052
785
  inputSchema: buildLogSchema,
1053
- title: 'Agentia Testing Build Logs',
786
+ title: 'Agentia Testing Job Runs Logs',
1054
787
  }, (args) => safelyHandleTool(() => testingBuildLogs(args)));
1055
- server.registerTool('agentia_testing_build_abort', {
1056
- description: 'Abort a Copado Robotic Testing build/run.',
788
+ server.registerTool('agentia_testing_job_runs_abort', {
789
+ description: 'Abort a Copado Robotic Testing job run.',
1057
790
  inputSchema: {
1058
791
  build: z.number().int().positive().describe('CRT build/run ID.'),
1059
792
  confirm: z.boolean().describe('Must be true to confirm the abort.'),
1060
- job: z.number().int().positive().describe('CRT job/test ID.'),
1061
- project: z.number().int().positive().describe('CRT project ID.'),
793
+ job: jobIdSchema,
794
+ project: projectIdSchema,
1062
795
  },
1063
- title: 'Agentia Testing Build Abort',
796
+ title: 'Agentia Testing Job Runs Abort',
1064
797
  }, (args) => safelyHandleTool(() => testingBuildAbort(args)));
1065
798
  server.registerTool('agentia_testing_variable_list', {
1066
799
  description: 'List Copado Robotic Testing variables/secrets.',
1067
800
  inputSchema: {
1068
- job: z.number().int().positive().optional().describe('Job/test ID filter.'),
801
+ job: optionalJobIdSchema,
1069
802
  key: z.string().optional().describe('Exact variable key filter.'),
1070
- project: z.number().int().positive().describe('CRT project ID.'),
803
+ project: projectIdSchema,
1071
804
  robot: z.number().int().positive().optional().describe('Robot ID filter.'),
1072
805
  sensitive: z.boolean().optional().describe('Sensitive status filter.'),
1073
806
  type: z.enum(TESTING_VARIABLE_TYPES).optional().describe('Variable type filter.'),
@@ -1077,19 +810,16 @@ export function registerAgentiaMcpTestingTools(server) {
1077
810
  }, (args) => safelyHandleTool(() => testingVariableList(args)));
1078
811
  server.registerTool('agentia_testing_variable_get', {
1079
812
  description: 'Get a Copado Robotic Testing variable/secret with value redaction.',
1080
- inputSchema: {
1081
- id: z.string().describe('CRT variable/secret ID.'),
1082
- project: z.number().int().positive().describe('CRT project ID.'),
1083
- },
813
+ inputSchema: { id: z.string().describe('CRT variable/secret ID.'), project: projectIdSchema },
1084
814
  title: 'Agentia Testing Variable Get',
1085
815
  }, (args) => safelyHandleTool(() => testingVariableGet(args)));
1086
816
  server.registerTool('agentia_testing_variable_create', {
1087
817
  description: 'Create a Copado Robotic Testing variable/secret.',
1088
818
  inputSchema: {
1089
819
  description: z.string().optional().describe('Variable description.'),
1090
- job: z.number().int().positive().optional().describe('CRT job/test ID scope.'),
820
+ job: optionalJobIdSchema,
1091
821
  key: z.string().describe('Variable key.'),
1092
- project: z.number().int().positive().describe('CRT project ID.'),
822
+ project: projectIdSchema,
1093
823
  robot: z.number().int().positive().optional().describe('CRT robot ID scope.'),
1094
824
  sensitive: z.boolean().optional().describe('Mark variable as sensitive.'),
1095
825
  type: z.enum(TESTING_VARIABLE_TYPES).optional().describe('Variable type.'),
@@ -1105,7 +835,7 @@ export function registerAgentiaMcpTestingTools(server) {
1105
835
  id: z.string().describe('CRT variable/secret ID.'),
1106
836
  key: z.string().optional().describe('Variable key.'),
1107
837
  notSensitive: z.boolean().optional().describe('Mark variable as not sensitive.'),
1108
- project: z.number().int().positive().describe('CRT project ID.'),
838
+ project: projectIdSchema,
1109
839
  sensitive: z.boolean().optional().describe('Mark variable as sensitive.'),
1110
840
  type: z.enum(TESTING_VARIABLE_TYPES).optional().describe('Variable type.'),
1111
841
  value: z.string().max(1_048_576).optional().describe('Structured variable value; redacted from output.'),
@@ -1117,7 +847,7 @@ export function registerAgentiaMcpTestingTools(server) {
1117
847
  inputSchema: {
1118
848
  confirm: z.boolean().describe('Must be true to confirm variable deletion.'),
1119
849
  id: z.string().describe('CRT variable/secret ID.'),
1120
- project: z.number().int().positive().describe('CRT project ID.'),
850
+ project: projectIdSchema,
1121
851
  },
1122
852
  title: 'Agentia Testing Variable Delete',
1123
853
  }, (args) => safelyHandleTool(() => testingVariableDelete(args)));
@@ -1165,47 +895,6 @@ export function registerAgentiaMcpTestingTools(server) {
1165
895
  },
1166
896
  title: 'Agentia Testing User Parameter Delete',
1167
897
  }, (args) => safelyHandleTool(() => testingUserParameterDelete(args)));
1168
- server.registerTool('agentia_testing_create', {
1169
- description: 'Create a Copado Robotic Testing test from uploaded files or Git storage.',
1170
- inputSchema: {
1171
- caseDurationChangeDetection: z.boolean().optional().describe('Enable or disable duration analytics.'),
1172
- description: z.string().optional().describe('Test description.'),
1173
- dryRun: z.boolean().optional().describe('Return a sanitized creation plan without network mutation.'),
1174
- name: z.string().describe('Test name.'),
1175
- parallelMode: z.enum(TESTING_JOB_PARALLEL_MODES).optional().describe('Parallel execution mode.'),
1176
- project: z.number().int().positive().describe('CRT project ID.'),
1177
- robot: z.string().describe('CRT robot ID.'),
1178
- screenDepth: z.number().int().positive().optional().describe('Screen color depth.'),
1179
- screenHeight: z.number().int().positive().optional().describe('Screen height.'),
1180
- screenWidth: z.number().int().positive().optional().describe('Screen width.'),
1181
- showVideoParams: z.boolean().optional().describe('Show or hide video parameters.'),
1182
- suiteType: z.enum(TESTING_JOB_SUITE_TYPES).optional().describe('CRT suite/job type.'),
1183
- timeout: z.string().optional().describe('Build timeout, for example 10m.'),
1184
- validation: z.boolean().optional().describe('Ask CRT to validate the created job.'),
1185
- ...gitStorageSchema,
1186
- },
1187
- title: 'Agentia Testing Create',
1188
- }, (args) => safelyHandleTool(() => testingJobCreate(args)));
1189
- server.registerTool('agentia_testing_update', {
1190
- description: 'Update a Copado Robotic Testing test by uploading file operations.',
1191
- inputSchema: uploadSchema,
1192
- title: 'Agentia Testing Update',
1193
- }, (args) => safelyHandleTool(() => testingJobUpload(args)));
1194
- server.registerTool('agentia_testing_run', {
1195
- description: 'Run a Copado Robotic Testing test.',
1196
- inputSchema: buildRunSchema,
1197
- title: 'Agentia Testing Run',
1198
- }, (args) => safelyHandleTool(() => testingBuildRun(args)));
1199
- server.registerTool('agentia_testing_status', {
1200
- description: 'List Copado Robotic Testing run status.',
1201
- inputSchema: buildListSchema,
1202
- title: 'Agentia Testing Status',
1203
- }, (args) => safelyHandleTool(() => testingBuildList(args)));
1204
- server.registerTool('agentia_testing_logs', {
1205
- description: 'Get logs for a Copado Robotic Testing run.',
1206
- inputSchema: buildLogSchema,
1207
- title: 'Agentia Testing Logs',
1208
- }, (args) => safelyHandleTool(() => testingBuildLogs(args)));
1209
898
  registerTestingLiveMcpTools(server);
1210
899
  }
1211
900
  //# sourceMappingURL=testing-tools.js.map