@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
@@ -0,0 +1,452 @@
1
+ import { z } from 'zod';
2
+ import { fetchExtensionConfiguration, fetchExtensionConfigurations } from '../extension-configuration-ops.js';
3
+ import { listPaginationZodFields, mcpPaginatedListPayload } from '../list-pagination.js';
4
+ import { normalizeAutomationFilterCriteria, validateAutomationCreateControls, } from '../pipeline-automation-flags.js';
5
+ import { activatePipelineAutomationRule, createPipelineAutomationRule, deactivatePipelineAutomationRule, deletePipelineAutomationRule, fetchPipelineAutomationRule, fetchPipelineAutomationRules, updatePipelineAutomationRule, } from '../pipeline-automation-ops.js';
6
+ import { AUTOMATION_CRITERIA_LOGICS, AUTOMATION_CRITERIA_MODES, AUTOMATION_CRITERIA_OPERATORS, AUTOMATION_EXECUTION_TIMES, AUTOMATION_PROMOTION_TRIGGERS, AUTOMATION_SCOPES, AUTOMATION_SOURCE_ACTION_STATUSES, AUTOMATION_SOURCE_ACTIONS, } from '../pipeline-automation-types.js';
7
+ import { assertSalesforceLifecycleId } from '../pipeline-lifecycle-id.js';
8
+ import { buildPipelineQualityGateCreateArgsPayload, normalizeQualityGateFilterCriteria, } from '../pipeline-quality-gate-flags.js';
9
+ import { activatePipelineQualityGate, createPipelineQualityGates, deactivatePipelineQualityGate, deletePipelineQualityGate, fetchPipelineQualityGate, fetchPipelineQualityGates, updatePipelineQualityGate, } from '../pipeline-quality-gate-ops.js';
10
+ import { QUALITY_GATE_EXECUTION_SEQUENCES, QUALITY_GATE_FILTER_FIELDS, QUALITY_GATE_FILTER_OPERATORS, QUALITY_GATE_TESTS_FROM_VALUES, } from '../pipeline-quality-gate-types.js';
11
+ import { safelyHandleTool } from './result.js';
12
+ const automationFilterCriteriaSchema = z
13
+ .object({
14
+ conditions: z
15
+ .array(z.object({
16
+ field: z.string(),
17
+ operator: z.enum(AUTOMATION_CRITERIA_OPERATORS),
18
+ value: z.union([z.string(), z.number(), z.boolean()]),
19
+ }))
20
+ .optional(),
21
+ logic: z.enum(AUTOMATION_CRITERIA_LOGICS).optional(),
22
+ mode: z.enum(AUTOMATION_CRITERIA_MODES),
23
+ whereCondition: z.string().optional(),
24
+ })
25
+ .describe('User-story filter. Builder: {mode:"builder",logic:"AND",conditions:[{field,operator,value}]}. Custom: {mode:"custom",whereCondition:"Name LIKE \'US-%\'"}.');
26
+ const qualityGateFilterCriteriaSchema = z
27
+ .object({
28
+ conditions: z
29
+ .array(z.object({
30
+ field: z.enum(QUALITY_GATE_FILTER_FIELDS),
31
+ operator: z.enum(QUALITY_GATE_FILTER_OPERATORS),
32
+ value: z.string(),
33
+ }))
34
+ .min(1),
35
+ logic: z.string().optional(),
36
+ })
37
+ .describe('Metadata-change filter. Example: {conditions:[{field:"Type",operator:"equals",value:"ApexClass"}],logic:"1"}. Fields: Name, Type, Directory.');
38
+ function buildAutomationCreatePayload(args) {
39
+ const stageIds = args.stageIds ?? [];
40
+ const environmentIds = args.environmentIds ?? [];
41
+ validateAutomationCreateControls({
42
+ cronExpression: args.cronExpression,
43
+ customAutomationConnector: args.customAutomationConnector,
44
+ environmentIds,
45
+ environmentSyncSource: args.environmentSyncSource,
46
+ executionTime: args.executionTime,
47
+ promotionTrigger: args.promotionTrigger,
48
+ scope: args.scope,
49
+ sourceAction: args.sourceAction,
50
+ sourceActionStatus: args.sourceActionStatus,
51
+ stageIds,
52
+ });
53
+ const payload = {
54
+ environmentIds,
55
+ executionTime: args.executionTime,
56
+ name: args.name,
57
+ scope: args.scope,
58
+ stageIds,
59
+ };
60
+ if (args.description !== undefined)
61
+ payload.description = args.description;
62
+ if (args.cronExpression !== undefined)
63
+ payload.cronExpression = args.cronExpression;
64
+ if (args.callbackAction !== undefined)
65
+ payload.callbackAction = args.callbackAction;
66
+ if (args.promotionTrigger !== undefined)
67
+ payload.promotionTrigger = args.promotionTrigger;
68
+ if (args.environmentSyncSource !== undefined)
69
+ payload.environmentSyncSource = args.environmentSyncSource;
70
+ if (args.sourceAction !== undefined)
71
+ payload.sourceAction = args.sourceAction;
72
+ if (args.sourceActionStatus !== undefined)
73
+ payload.sourceActionStatus = args.sourceActionStatus;
74
+ if (args.customAutomationConnector !== undefined) {
75
+ payload.customAutomationConnector = args.customAutomationConnector;
76
+ }
77
+ if (args.filterCriteria !== undefined) {
78
+ payload.filterCriteria = normalizeAutomationFilterCriteria(args.filterCriteria);
79
+ }
80
+ return payload;
81
+ }
82
+ function buildAutomationUpdatePayload(args) {
83
+ const payload = {};
84
+ if (args.name !== undefined)
85
+ payload.name = args.name;
86
+ if (args.description !== undefined)
87
+ payload.description = args.description;
88
+ if (args.executionTime !== undefined)
89
+ payload.executionTime = args.executionTime;
90
+ if (args.cronExpression !== undefined)
91
+ payload.cronExpression = args.cronExpression;
92
+ if (args.callbackAction !== undefined)
93
+ payload.callbackAction = args.callbackAction;
94
+ if (args.stageIds !== undefined)
95
+ payload.stageIds = args.stageIds;
96
+ if (args.environmentIds !== undefined)
97
+ payload.environmentIds = args.environmentIds;
98
+ if (args.promotionTrigger !== undefined)
99
+ payload.promotionTrigger = args.promotionTrigger;
100
+ if (args.environmentSyncSource !== undefined)
101
+ payload.environmentSyncSource = args.environmentSyncSource;
102
+ if (args.sourceAction !== undefined)
103
+ payload.sourceAction = args.sourceAction;
104
+ if (args.sourceActionStatus !== undefined)
105
+ payload.sourceActionStatus = args.sourceActionStatus;
106
+ if (args.customAutomationConnector !== undefined) {
107
+ payload.customAutomationConnector = args.customAutomationConnector;
108
+ }
109
+ if (args.filterCriteria !== undefined) {
110
+ payload.filterCriteria = normalizeAutomationFilterCriteria(args.filterCriteria);
111
+ }
112
+ if (Object.keys(payload).length === 0) {
113
+ throw new Error('Must provide at least one field to update.');
114
+ }
115
+ return payload;
116
+ }
117
+ function buildQualityGateCreatePayload(args) {
118
+ return buildPipelineQualityGateCreateArgsPayload({
119
+ action: args.action,
120
+ entirePipeline: args.entirePipeline,
121
+ environmentIds: args.environmentIds,
122
+ executionSequence: args.executionSequence,
123
+ extensionConfigurationId: args.extensionConfigurationId,
124
+ filterCriteria: args.filterCriteria,
125
+ stageIds: args.stageIds,
126
+ testsFrom: args.testsFrom,
127
+ tool: args.tool,
128
+ });
129
+ }
130
+ function buildQualityGateUpdatePayload(args) {
131
+ const payload = {};
132
+ if (args.action !== undefined)
133
+ payload.action = args.action;
134
+ if (args.executionSequence !== undefined)
135
+ payload.executionSequence = args.executionSequence;
136
+ if (args.extensionConfigurationId !== undefined) {
137
+ payload.extensionConfigurationId = args.extensionConfigurationId;
138
+ }
139
+ if (args.testsFrom !== undefined)
140
+ payload.testsFrom = args.testsFrom;
141
+ if (args.entirePipeline !== undefined)
142
+ payload.entirePipeline = args.entirePipeline;
143
+ if (args.stageId !== undefined)
144
+ payload.stageId = args.stageId;
145
+ if (args.environmentId !== undefined)
146
+ payload.environmentId = args.environmentId;
147
+ if (payload.stageId !== undefined && payload.environmentId !== undefined) {
148
+ throw new Error('stageId and environmentId cannot both be set.');
149
+ }
150
+ if (payload.entirePipeline === true && (payload.stageId !== undefined || payload.environmentId !== undefined)) {
151
+ throw new Error('entirePipeline cannot be combined with stageId or environmentId.');
152
+ }
153
+ if (args.filterCriteria !== undefined) {
154
+ payload.filterCriteria = normalizeQualityGateFilterCriteria(args.filterCriteria);
155
+ }
156
+ if (Object.keys(payload).length === 0) {
157
+ throw new Error('Must provide at least one field to update.');
158
+ }
159
+ return payload;
160
+ }
161
+ async function automationList(args) {
162
+ return mcpPaginatedListPayload('automationRules', await fetchPipelineAutomationRules(args.pipelineId, {
163
+ active: args.active,
164
+ cursor: args.cursor,
165
+ executionTime: args.executionTime,
166
+ includeSystemGenerated: args.includeSystemGenerated,
167
+ name: args.name,
168
+ pageSize: args.pageSize,
169
+ sourceAction: args.sourceAction,
170
+ }));
171
+ }
172
+ async function automationGet(args) {
173
+ return {
174
+ automationRule: await fetchPipelineAutomationRule(args.pipelineId, args.id),
175
+ };
176
+ }
177
+ async function automationCreate(args) {
178
+ return {
179
+ automationRule: await createPipelineAutomationRule(args.pipelineId, buildAutomationCreatePayload(args)),
180
+ };
181
+ }
182
+ async function automationUpdate(args) {
183
+ return {
184
+ automationRule: await updatePipelineAutomationRule(args.pipelineId, args.id, buildAutomationUpdatePayload(args)),
185
+ };
186
+ }
187
+ async function automationDelete(args) {
188
+ await deletePipelineAutomationRule(args.pipelineId, args.id);
189
+ return { id: args.id, pipelineId: args.pipelineId };
190
+ }
191
+ async function automationActivate(args) {
192
+ const id = assertSalesforceLifecycleId(args.id, 'Automation rule ID');
193
+ await activatePipelineAutomationRule(args.pipelineId, id);
194
+ return { id, pipelineId: args.pipelineId };
195
+ }
196
+ async function automationDeactivate(args) {
197
+ const id = assertSalesforceLifecycleId(args.id, 'Automation rule ID');
198
+ await deactivatePipelineAutomationRule(args.pipelineId, id);
199
+ return { id, pipelineId: args.pipelineId };
200
+ }
201
+ async function qualityGateList(args) {
202
+ return mcpPaginatedListPayload('qualityGates', await fetchPipelineQualityGates(args.pipelineId, {
203
+ cursor: args.cursor,
204
+ name: args.name,
205
+ pageSize: args.pageSize,
206
+ tool: args.tool,
207
+ }));
208
+ }
209
+ async function qualityGateGet(args) {
210
+ return {
211
+ qualityGate: await fetchPipelineQualityGate(args.pipelineId, args.id),
212
+ };
213
+ }
214
+ async function qualityGateCreate(args) {
215
+ return {
216
+ qualityGates: await createPipelineQualityGates(args.pipelineId, buildQualityGateCreatePayload(args)),
217
+ };
218
+ }
219
+ async function qualityGateUpdate(args) {
220
+ return {
221
+ qualityGate: await updatePipelineQualityGate(args.pipelineId, args.id, buildQualityGateUpdatePayload(args)),
222
+ };
223
+ }
224
+ async function qualityGateDelete(args) {
225
+ await deletePipelineQualityGate(args.pipelineId, args.id);
226
+ return { id: args.id, pipelineId: args.pipelineId };
227
+ }
228
+ async function qualityGateActivate(args) {
229
+ const id = assertSalesforceLifecycleId(args.id, 'Quality gate ID');
230
+ await activatePipelineQualityGate(args.pipelineId, id);
231
+ return { id, pipelineId: args.pipelineId };
232
+ }
233
+ async function qualityGateDeactivate(args) {
234
+ const id = assertSalesforceLifecycleId(args.id, 'Quality gate ID');
235
+ await deactivatePipelineQualityGate(args.pipelineId, id);
236
+ return { id, pipelineId: args.pipelineId };
237
+ }
238
+ async function extensionConfigurationList(args = {}) {
239
+ return mcpPaginatedListPayload('extensionConfigurations', await fetchExtensionConfigurations({
240
+ active: args.active,
241
+ cursor: args.cursor,
242
+ name: args.name,
243
+ pageSize: args.pageSize,
244
+ testType: args.testType,
245
+ tool: args.tool,
246
+ }));
247
+ }
248
+ async function extensionConfigurationGet(args) {
249
+ return {
250
+ extensionConfiguration: await fetchExtensionConfiguration(args.id),
251
+ };
252
+ }
253
+ export const agentiaMcpPipelineAutomationQualityToolHandlers = {
254
+ extensionConfigurationGet,
255
+ extensionConfigurationList,
256
+ pipelineAutomationActivate: automationActivate,
257
+ pipelineAutomationCreate: automationCreate,
258
+ pipelineAutomationDeactivate: automationDeactivate,
259
+ pipelineAutomationDelete: automationDelete,
260
+ pipelineAutomationGet: automationGet,
261
+ pipelineAutomationList: automationList,
262
+ pipelineAutomationUpdate: automationUpdate,
263
+ pipelineQualityGateActivate: qualityGateActivate,
264
+ pipelineQualityGateCreate: qualityGateCreate,
265
+ pipelineQualityGateDeactivate: qualityGateDeactivate,
266
+ pipelineQualityGateDelete: qualityGateDelete,
267
+ pipelineQualityGateGet: qualityGateGet,
268
+ pipelineQualityGateList: qualityGateList,
269
+ pipelineQualityGateUpdate: qualityGateUpdate,
270
+ };
271
+ export function registerAgentiaMcpPipelineAutomationQualityTools(server) {
272
+ server.registerTool('agentia_pipeline_automation_list', {
273
+ description: 'List Copado pipeline automation rules via the CICD gateway.',
274
+ inputSchema: {
275
+ ...listPaginationZodFields,
276
+ active: z.boolean().optional().describe('Filter by active status.'),
277
+ executionTime: z.enum(AUTOMATION_EXECUTION_TIMES).optional().describe('Filter by execution time.'),
278
+ includeSystemGenerated: z.boolean().optional().describe('Include system-generated rules.'),
279
+ name: z.string().optional().describe('Filter by automation rule name.'),
280
+ pipelineId: z.string().describe('Pipeline ID or name.'),
281
+ sourceAction: z.enum(AUTOMATION_SOURCE_ACTIONS).optional().describe('Filter by source action.'),
282
+ },
283
+ title: 'Agentia Pipeline Automation List',
284
+ }, (args) => safelyHandleTool(() => automationList(args)));
285
+ server.registerTool('agentia_pipeline_automation_get', {
286
+ description: 'Get a Copado pipeline automation rule via the CICD gateway.',
287
+ inputSchema: {
288
+ id: z.string().describe('Automation rule ID or name.'),
289
+ pipelineId: z.string().describe('Pipeline ID or name.'),
290
+ },
291
+ title: 'Agentia Pipeline Automation Get',
292
+ }, (args) => safelyHandleTool(() => automationGet(args)));
293
+ server.registerTool('agentia_pipeline_automation_create', {
294
+ description: 'Create an inactive Copado pipeline automation rule via the CICD gateway.',
295
+ inputSchema: {
296
+ callbackAction: z.string().optional(),
297
+ cronExpression: z.string().optional(),
298
+ customAutomationConnector: z.string().optional(),
299
+ description: z.string().optional(),
300
+ environmentIds: z.array(z.string()).optional(),
301
+ environmentSyncSource: z.string().optional(),
302
+ executionTime: z.enum(AUTOMATION_EXECUTION_TIMES).describe('Execution time.'),
303
+ filterCriteria: automationFilterCriteriaSchema.optional(),
304
+ name: z.string().describe('Automation rule name.'),
305
+ pipelineId: z.string().describe('Pipeline ID or name.'),
306
+ promotionTrigger: z.enum(AUTOMATION_PROMOTION_TRIGGERS).optional(),
307
+ scope: z.enum(AUTOMATION_SCOPES).describe('Automation scope (immutable after create).'),
308
+ sourceAction: z.enum(AUTOMATION_SOURCE_ACTIONS).optional(),
309
+ sourceActionStatus: z.enum(AUTOMATION_SOURCE_ACTION_STATUSES).optional(),
310
+ stageIds: z.array(z.string()).optional(),
311
+ },
312
+ title: 'Agentia Pipeline Automation Create',
313
+ }, (args) => safelyHandleTool(() => automationCreate(args)));
314
+ server.registerTool('agentia_pipeline_automation_update', {
315
+ description: 'Update a Copado pipeline automation rule via the CICD gateway. Scope is immutable.',
316
+ inputSchema: {
317
+ callbackAction: z.string().optional(),
318
+ cronExpression: z.string().optional(),
319
+ customAutomationConnector: z.string().optional(),
320
+ description: z.string().optional(),
321
+ environmentIds: z.array(z.string()).optional(),
322
+ environmentSyncSource: z.string().optional(),
323
+ executionTime: z.enum(AUTOMATION_EXECUTION_TIMES).optional(),
324
+ filterCriteria: automationFilterCriteriaSchema.optional(),
325
+ id: z.string().describe('Automation rule ID or name.'),
326
+ name: z.string().optional(),
327
+ pipelineId: z.string().describe('Pipeline ID or name.'),
328
+ promotionTrigger: z.enum(AUTOMATION_PROMOTION_TRIGGERS).optional(),
329
+ sourceAction: z.enum(AUTOMATION_SOURCE_ACTIONS).optional(),
330
+ sourceActionStatus: z.enum(AUTOMATION_SOURCE_ACTION_STATUSES).optional(),
331
+ stageIds: z.array(z.string()).optional(),
332
+ },
333
+ title: 'Agentia Pipeline Automation Update',
334
+ }, (args) => safelyHandleTool(() => automationUpdate(args)));
335
+ server.registerTool('agentia_pipeline_automation_delete', {
336
+ description: 'Delete a Copado pipeline automation rule via the CICD gateway.',
337
+ inputSchema: {
338
+ id: z.string().describe('Automation rule ID or name.'),
339
+ pipelineId: z.string().describe('Pipeline ID or name.'),
340
+ },
341
+ title: 'Agentia Pipeline Automation Delete',
342
+ }, (args) => safelyHandleTool(() => automationDelete(args)));
343
+ server.registerTool('agentia_pipeline_automation_activate', {
344
+ description: 'Activate a Copado pipeline automation rule. Requires a Salesforce Id (not name).',
345
+ inputSchema: {
346
+ id: z.string().describe('Automation rule Salesforce ID.'),
347
+ pipelineId: z.string().describe('Pipeline ID or name.'),
348
+ },
349
+ title: 'Agentia Pipeline Automation Activate',
350
+ }, (args) => safelyHandleTool(() => automationActivate(args)));
351
+ server.registerTool('agentia_pipeline_automation_deactivate', {
352
+ description: 'Deactivate a Copado pipeline automation rule. Requires a Salesforce Id (not name).',
353
+ inputSchema: {
354
+ id: z.string().describe('Automation rule Salesforce ID.'),
355
+ pipelineId: z.string().describe('Pipeline ID or name.'),
356
+ },
357
+ title: 'Agentia Pipeline Automation Deactivate',
358
+ }, (args) => safelyHandleTool(() => automationDeactivate(args)));
359
+ server.registerTool('agentia_pipeline_quality_gate_list', {
360
+ description: 'List Copado pipeline quality gates via the CICD gateway.',
361
+ inputSchema: {
362
+ ...listPaginationZodFields,
363
+ name: z.string().optional().describe('Filter by quality gate name.'),
364
+ pipelineId: z.string().describe('Pipeline ID or name.'),
365
+ tool: z.string().optional().describe('Filter by tool.'),
366
+ },
367
+ title: 'Agentia Pipeline Quality Gate List',
368
+ }, (args) => safelyHandleTool(() => qualityGateList(args)));
369
+ server.registerTool('agentia_pipeline_quality_gate_get', {
370
+ description: 'Get a Copado pipeline quality gate via the CICD gateway.',
371
+ inputSchema: {
372
+ id: z.string().describe('Quality gate ID or name.'),
373
+ pipelineId: z.string().describe('Pipeline ID or name.'),
374
+ },
375
+ title: 'Agentia Pipeline Quality Gate Get',
376
+ }, (args) => safelyHandleTool(() => qualityGateGet(args)));
377
+ server.registerTool('agentia_pipeline_quality_gate_create', {
378
+ description: 'Create inactive Copado pipeline quality gates via the CICD gateway.',
379
+ inputSchema: {
380
+ action: z.string().describe('Pipeline action the gate runs for (for example Commit, Promotion, Deployment).'),
381
+ entirePipeline: z.boolean().optional().describe('Apply to the entire pipeline.'),
382
+ environmentIds: z.array(z.string()).optional(),
383
+ executionSequence: z.enum(QUALITY_GATE_EXECUTION_SEQUENCES).describe('Execution sequence.'),
384
+ extensionConfigurationId: z.string().describe('Active extension configuration ID.'),
385
+ filterCriteria: qualityGateFilterCriteriaSchema.optional(),
386
+ pipelineId: z.string().describe('Pipeline ID or name.'),
387
+ stageIds: z.array(z.string()).optional(),
388
+ testsFrom: z.enum(QUALITY_GATE_TESTS_FROM_VALUES).optional(),
389
+ tool: z.string().describe('Quality gate tool name.'),
390
+ },
391
+ title: 'Agentia Pipeline Quality Gate Create',
392
+ }, (args) => safelyHandleTool(() => qualityGateCreate(args)));
393
+ server.registerTool('agentia_pipeline_quality_gate_update', {
394
+ description: 'Update an inactive Copado pipeline quality gate via the CICD gateway.',
395
+ inputSchema: {
396
+ action: z.string().optional(),
397
+ entirePipeline: z.boolean().optional(),
398
+ environmentId: z.string().optional(),
399
+ executionSequence: z.enum(QUALITY_GATE_EXECUTION_SEQUENCES).optional(),
400
+ extensionConfigurationId: z.string().optional(),
401
+ filterCriteria: qualityGateFilterCriteriaSchema.optional(),
402
+ id: z.string().describe('Quality gate ID or name.'),
403
+ pipelineId: z.string().describe('Pipeline ID or name.'),
404
+ stageId: z.string().optional(),
405
+ testsFrom: z.enum(QUALITY_GATE_TESTS_FROM_VALUES).optional(),
406
+ },
407
+ title: 'Agentia Pipeline Quality Gate Update',
408
+ }, (args) => safelyHandleTool(() => qualityGateUpdate(args)));
409
+ server.registerTool('agentia_pipeline_quality_gate_delete', {
410
+ description: 'Delete an inactive Copado pipeline quality gate via the CICD gateway.',
411
+ inputSchema: {
412
+ id: z.string().describe('Quality gate ID or name.'),
413
+ pipelineId: z.string().describe('Pipeline ID or name.'),
414
+ },
415
+ title: 'Agentia Pipeline Quality Gate Delete',
416
+ }, (args) => safelyHandleTool(() => qualityGateDelete(args)));
417
+ server.registerTool('agentia_pipeline_quality_gate_activate', {
418
+ description: 'Activate a Copado pipeline quality gate. Requires a Salesforce Id (not name).',
419
+ inputSchema: {
420
+ id: z.string().describe('Quality gate Salesforce ID.'),
421
+ pipelineId: z.string().describe('Pipeline ID or name.'),
422
+ },
423
+ title: 'Agentia Pipeline Quality Gate Activate',
424
+ }, (args) => safelyHandleTool(() => qualityGateActivate(args)));
425
+ server.registerTool('agentia_pipeline_quality_gate_deactivate', {
426
+ description: 'Deactivate a Copado pipeline quality gate. Requires a Salesforce Id (not name).',
427
+ inputSchema: {
428
+ id: z.string().describe('Quality gate Salesforce ID.'),
429
+ pipelineId: z.string().describe('Pipeline ID or name.'),
430
+ },
431
+ title: 'Agentia Pipeline Quality Gate Deactivate',
432
+ }, (args) => safelyHandleTool(() => qualityGateDeactivate(args)));
433
+ server.registerTool('agentia_extension_configuration_list', {
434
+ description: 'List Copado extension configurations via the CICD gateway.',
435
+ inputSchema: {
436
+ ...listPaginationZodFields,
437
+ active: z.boolean().optional().describe('Filter by active status.'),
438
+ name: z.string().optional().describe('Filter by name.'),
439
+ testType: z.string().optional().describe('Filter by test type.'),
440
+ tool: z.string().optional().describe('Filter by extension tool.'),
441
+ },
442
+ title: 'Agentia Extension Configuration List',
443
+ }, (args) => safelyHandleTool(() => extensionConfigurationList(args || {})));
444
+ server.registerTool('agentia_extension_configuration_get', {
445
+ description: 'Get a Copado extension configuration via the CICD gateway.',
446
+ inputSchema: {
447
+ id: z.string().describe('Extension configuration ID or name.'),
448
+ },
449
+ title: 'Agentia Extension Configuration Get',
450
+ }, (args) => safelyHandleTool(() => extensionConfigurationGet(args)));
451
+ }
452
+ //# sourceMappingURL=pipeline-automation-quality-tools.js.map
@@ -2,6 +2,8 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { createRequire } from 'node:module';
4
4
  import process from 'node:process';
5
+ import { z } from 'zod';
6
+ import { logVerboseDebug } from '../debug.js';
5
7
  import { migrateUserSettingsFromProjectConfig } from '../defaults-store.js';
6
8
  import { applyProjectRoot, hasExplicitProjectRoot } from '../project-root.js';
7
9
  import { runWithMcpRequestSignal } from './request-context.js';
@@ -10,15 +12,71 @@ import { withToolAnnotations } from './tool-annotations.js';
10
12
  import { registerAgentiaMcpTools } from './tools.js';
11
13
  const require = createRequire(import.meta.url);
12
14
  const packageJson = require('../../../package.json');
15
+ /**
16
+ * SDK ListRootsResultSchema requires every uri to start with file://.
17
+ * Some clients send empty or non-file URIs; accept them here and filter below.
18
+ */
19
+ const LenientListRootsResultSchema = z
20
+ .object({
21
+ roots: z.array(z.unknown()).optional().default([]),
22
+ })
23
+ .passthrough();
24
+ /** Keep only usable local file roots; empty / non-file:// entries are ignored. */
25
+ export function collectMcpFileRootUris(roots) {
26
+ const uris = [];
27
+ for (const root of roots) {
28
+ if (root === null || typeof root !== 'object')
29
+ continue;
30
+ const { uri } = root;
31
+ if (typeof uri !== 'string')
32
+ continue;
33
+ const trimmed = uri.trim();
34
+ if (trimmed.startsWith('file://'))
35
+ uris.push(trimmed);
36
+ }
37
+ return uris;
38
+ }
13
39
  export function createAgentiaMcpServer(lifecycleSignal, projectContextReady = Promise.resolve()) {
14
40
  const server = new McpServer({
15
41
  name: packageJson.name ?? 'agentia-cli',
16
42
  version: packageJson.version,
17
43
  });
44
+ installMcpClientCallDebugLogging(server.server);
18
45
  wrapMcpToolRegistration(server, lifecycleSignal, projectContextReady);
19
46
  registerAgentiaMcpTools(server);
20
47
  return server;
21
48
  }
49
+ /**
50
+ * Log every server→client MCP request/notification when DEBUG=verbose.
51
+ * Covers roots/list and any future client calls made through the protocol.
52
+ */
53
+ export function installMcpClientCallDebugLogging(protocol) {
54
+ const target = protocol;
55
+ const originalRequest = target.request.bind(target);
56
+ target.request = async (request, resultSchema, options) => {
57
+ logVerboseDebug('MCP client request', request);
58
+ try {
59
+ const result = await originalRequest(request, resultSchema, options);
60
+ logVerboseDebug('MCP client response', {
61
+ method: typeof request?.method === 'string' ? request.method : undefined,
62
+ result,
63
+ });
64
+ return result;
65
+ }
66
+ catch (error) {
67
+ logVerboseDebug('MCP client error', {
68
+ error: error instanceof Error ? error.message : String(error),
69
+ method: typeof request?.method === 'string' ? request.method : undefined,
70
+ });
71
+ throw error;
72
+ }
73
+ };
74
+ const originalNotification = target.notification.bind(target);
75
+ target.notification = async (notification, options) => {
76
+ logVerboseDebug('MCP client notification', notification);
77
+ await originalNotification(notification, options);
78
+ };
79
+ }
22
80
  function combineSignals(requestSignal, lifecycleSignal) {
23
81
  if (requestSignal === undefined || lifecycleSignal === undefined) {
24
82
  return { dispose() { }, signal: requestSignal ?? lifecycleSignal };
@@ -61,8 +119,19 @@ function wrapMcpToolRegistration(server, lifecycleSignal, projectContextReady =
61
119
  function clientSupportsRoots(server) {
62
120
  return (server.server._clientCapabilities?.roots !== undefined);
63
121
  }
122
+ async function listMcpFileRootUris(server) {
123
+ try {
124
+ const result = await server.server.request({ method: 'roots/list' }, LenientListRootsResultSchema);
125
+ return collectMcpFileRootUris(result.roots);
126
+ }
127
+ catch (error) {
128
+ const message = error instanceof Error ? error.message : String(error);
129
+ process.stderr.write(`[agentia-mcp] ignoring invalid MCP roots/list response: ${message}\n`);
130
+ return undefined;
131
+ }
132
+ }
64
133
  async function applyMcpProjectRoot(server, includeMcpRoots) {
65
- const rootUris = includeMcpRoots ? (await server.server.listRoots()).roots.map((root) => root.uri) : undefined;
134
+ const rootUris = includeMcpRoots ? await listMcpFileRootUris(server) : undefined;
66
135
  applyProjectRoot(undefined, rootUris);
67
136
  await migrateUserSettingsFromProjectConfig().catch(() => {
68
137
  // Best-effort; MCP tools still fall back to reading legacy project keys.
@@ -2,15 +2,22 @@ import { mkdtemp } from 'node:fs/promises';
2
2
  import { tmpdir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
  import { z } from 'zod';
5
- import { controlTestingLive, executeTestingLive, getTestingLiveHistory, getTestingLiveReports, getTestingLiveStatus, inspectTestingLive, saveTestingLiveScreenshot, setTestingLiveOptions, startTestingLive, stopTestingLive, } from '../testing-live-operations.js';
5
+ import { controlTestingLive, executeTestingLive, getTestingLiveHistory, getTestingLiveReports, getTestingLiveStatus, inspectTestingLive, parseTestingLiveScreen, saveTestingLiveScreenshot, setTestingLiveOptions, startTestingLive, stopTestingLive, } from '../testing-live-operations.js';
6
6
  import { TESTING_LIVE_LIBRARIES } from '../testing-live-types.js';
7
7
  import { safelyHandleTool } from './result.js';
8
8
  async function testingLiveStart(args) {
9
- const screenValues = [args.screenWidth, args.screenHeight, args.screenDepth];
10
- const supplied = screenValues.filter((value) => value !== undefined);
11
- if (supplied.length > 0 && supplied.length !== 3) {
12
- throw new Error('Provide screenWidth, screenHeight, and screenDepth together.');
9
+ const hasScreenParts = args.screenDepth !== undefined || args.screenHeight !== undefined || args.screenWidth !== undefined;
10
+ if (hasScreenParts && (args.screen !== undefined || args.viewport !== undefined)) {
11
+ throw new Error('Use either screen/viewport or screenWidth/screenHeight/screenDepth, not both.');
13
12
  }
13
+ let screenInput = args.screen;
14
+ if (hasScreenParts) {
15
+ if (args.screenDepth === undefined || args.screenHeight === undefined || args.screenWidth === undefined) {
16
+ throw new Error('Provide screenWidth, screenHeight, and screenDepth together.');
17
+ }
18
+ screenInput = { depth: args.screenDepth, height: args.screenHeight, width: args.screenWidth };
19
+ }
20
+ const screen = parseTestingLiveScreen(screenInput, args.viewport);
14
21
  return {
15
22
  result: await startTestingLive({
16
23
  description: args.description,
@@ -21,9 +28,7 @@ async function testingLiveStart(args) {
21
28
  noBrowser: args.noBrowser,
22
29
  pollIntervalMs: args.pollIntervalSeconds === undefined ? undefined : args.pollIntervalSeconds * 1000,
23
30
  projectId: args.project,
24
- screen: supplied.length === 0
25
- ? undefined
26
- : { depth: args.screenDepth, height: args.screenHeight, width: args.screenWidth },
31
+ screen,
27
32
  section: args.section,
28
33
  sectionIndex: args.sectionIndex,
29
34
  sessionVersion: args.sessionVersion,
@@ -58,7 +63,9 @@ async function testingLiveExecute(args) {
58
63
  };
59
64
  }
60
65
  async function testingLiveControl(action, args) {
61
- return { result: await controlTestingLive(action, { jobId: args.job, projectId: args.project, sessionId: args.sessionId }) };
66
+ return {
67
+ result: await controlTestingLive(action, { jobId: args.job, projectId: args.project, sessionId: args.sessionId }),
68
+ };
62
69
  }
63
70
  async function testingLiveInspect(args) {
64
71
  return {
@@ -100,7 +107,9 @@ async function testingLiveSetOptions(args) {
100
107
  };
101
108
  }
102
109
  async function testingLiveHistory(args) {
103
- return { result: getTestingLiveHistory({ jobId: args.job, limit: args.limit, projectId: args.project, status: args.status }) };
110
+ return {
111
+ result: getTestingLiveHistory({ jobId: args.job, limit: args.limit, projectId: args.project, status: args.status }),
112
+ };
104
113
  }
105
114
  export const testingLiveMcpHandlers = {
106
115
  testingLiveContinue: (args) => testingLiveControl('continue', args),
@@ -116,7 +125,7 @@ export const testingLiveMcpHandlers = {
116
125
  testingLiveStop,
117
126
  };
118
127
  const liveSessionSchema = {
119
- job: z.number().int().positive().optional().describe('Optional CRT job/test ID guard.'),
128
+ job: z.number().int().positive().optional().describe('Optional CRT job ID guard.'),
120
129
  project: z.number().int().positive().describe('CRT project ID.'),
121
130
  sessionId: z.number().int().positive().optional().describe('Optional active live session ID guard.'),
122
131
  };
@@ -135,12 +144,13 @@ export function registerTestingLiveMcpTools(server) {
135
144
  inputSchema: {
136
145
  description: z.string().max(500).optional(),
137
146
  japIme: z.boolean().optional(),
138
- job: z.number().int().positive().describe('CRT job/test ID.'),
147
+ job: z.number().int().positive().describe('CRT job ID.'),
139
148
  library: z.enum(TESTING_LIVE_LIBRARIES).optional(),
140
149
  noBootstrap: z.boolean().optional(),
141
150
  noBrowser: z.boolean().optional(),
142
151
  pollIntervalSeconds: z.number().int().min(1).max(30).optional(),
143
152
  project: z.number().int().positive().describe('CRT project ID.'),
153
+ screen: z.string().max(100).optional(),
144
154
  screenDepth: z.number().int().min(8).max(32).optional(),
145
155
  screenHeight: z.number().int().min(240).max(4320).optional(),
146
156
  screenWidth: z.number().int().min(320).max(7680).optional(),
@@ -148,6 +158,7 @@ export function registerTestingLiveMcpTools(server) {
148
158
  sectionIndex: z.number().int().positive().optional(),
149
159
  sessionVersion: z.string().max(100).optional(),
150
160
  timeoutSeconds: z.number().int().min(1).max(600).optional(),
161
+ viewport: z.string().max(100).optional(),
151
162
  },
152
163
  title: 'Agentia Testing Live Start',
153
164
  }, (args) => safelyHandleTool(() => testingLiveStart(args)));
@@ -204,7 +215,7 @@ export function registerTestingLiveMcpTools(server) {
204
215
  server.registerTool('agentia_testing_live_history', {
205
216
  description: 'Read bounded sanitized local CRT live execution history.',
206
217
  inputSchema: {
207
- job: z.number().int().positive().describe('CRT job/test ID.'),
218
+ job: z.number().int().positive().describe('CRT job ID.'),
208
219
  limit: z.number().int().min(1).max(500).optional(),
209
220
  project: z.number().int().positive().describe('CRT project ID.'),
210
221
  status: z.enum(['completed', 'failed', 'recorded']).optional(),