@copado/agentia-cli 1.0.0-beta.1 → 1.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +648 -370
  3. package/dist/commands/cicd/cloud/commit.js +252 -0
  4. package/dist/commands/cicd/cloud/promote.js +139 -0
  5. package/dist/commands/cicd/data/template/save-detail.js +2 -2
  6. package/dist/commands/cicd/health-check.js +77 -0
  7. package/dist/commands/cicd/repository/auth/https/configure.js +21 -0
  8. package/dist/commands/cicd/repository/auth/oauth/login.js +56 -0
  9. package/dist/commands/cicd/repository/auth/setup.js +28 -0
  10. package/dist/commands/cicd/repository/auth/ssh/configure.js +22 -0
  11. package/dist/commands/cicd/repository/create.js +2 -2
  12. package/dist/commands/cicd/repository/reset.js +17 -5
  13. package/dist/commands/cicd/repository/update.js +6 -14
  14. package/dist/commands/cicd/work/commit.js +10 -324
  15. package/dist/commands/cicd/work/environment-sync.js +125 -0
  16. package/dist/commands/cicd/work/get.js +29 -12
  17. package/dist/commands/cicd/work/promote.js +93 -97
  18. package/dist/commands/cicd/work/set.js +4 -2
  19. package/dist/commands/cicd/work/submit.js +7 -0
  20. package/dist/commands/runtime.js +26 -0
  21. package/dist/hooks/finally/ide-command-event.js +1 -1
  22. package/dist/hooks/init/plugin-host.js +6 -0
  23. package/dist/lib/agentia-command.js +16 -0
  24. package/dist/lib/cursor-mcp-config.js +3 -1
  25. package/dist/lib/data-types.js +3 -1
  26. package/dist/lib/defaults-store.js +2 -1
  27. package/dist/lib/git-sizer.js +5 -0
  28. package/dist/lib/git-worktree.js +17 -1
  29. package/dist/lib/health-check.js +3 -0
  30. package/dist/lib/mcp/command-id.js +1 -0
  31. package/dist/lib/mcp/data-tools.js +2 -2
  32. package/dist/lib/mcp/health-check-tools.js +16 -0
  33. package/dist/lib/mcp/server.js +35 -8
  34. package/dist/lib/mcp/tool-annotations.js +268 -0
  35. package/dist/lib/mcp/tools.js +58 -12
  36. package/dist/lib/mcp/work-tools.js +98 -83
  37. package/dist/lib/metadata-pathspecs.js +4 -0
  38. package/dist/lib/metadataRegistry.json +5427 -0
  39. package/dist/lib/plugin-host/auth.js +4 -0
  40. package/dist/lib/plugin-host/format.js +3 -0
  41. package/dist/lib/plugin-host/index.js +7 -0
  42. package/dist/lib/plugin-host/organization.js +4 -0
  43. package/dist/lib/plugin-host/projection-utils.js +6 -0
  44. package/dist/lib/plugin-host/registry.js +6 -0
  45. package/dist/lib/plugin-host/request-scope.js +4 -0
  46. package/dist/lib/plugin-host/work.js +4 -0
  47. package/dist/lib/project-root.js +3 -1
  48. package/dist/lib/promotion-types.js +4 -1
  49. package/dist/lib/repository-auth.js +8 -0
  50. package/dist/lib/repository-flags.js +2 -2
  51. package/dist/lib/repository-types.js +6 -1
  52. package/dist/lib/repository-url-prefill.js +4 -0
  53. package/dist/lib/runtime-invoke-context.js +6 -0
  54. package/dist/lib/runtime-rpc.js +14 -0
  55. package/dist/lib/runtime.js +1 -1
  56. package/dist/lib/work-environment-sync-errors.js +4 -0
  57. package/dist/lib/work-environment-sync-ready.js +18 -0
  58. package/dist/lib/work-environment-sync.js +41 -0
  59. package/dist/lib/work-get.js +3 -0
  60. package/dist/lib/work-promote-deploy.js +13 -0
  61. package/dist/lib/work-promote-errors.js +5 -0
  62. package/dist/lib/work-promote.js +12 -0
  63. package/dist/lib/work-set-selection.js +2 -1
  64. package/dist/lib/work-submit-ahead-behind.js +8 -0
  65. package/dist/lib/work-types.js +2 -1
  66. package/oclif.manifest.json +1166 -605
  67. package/package.json +8 -4
  68. package/templates/skills/agentia-cicd/SKILL.md +2 -2
  69. package/templates/skills/agentia-cicd/references/promotions.md +8 -8
  70. package/templates/skills/agentia-cicd/references/work.md +16 -14
@@ -3,18 +3,19 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
3
3
  import { createRequire } from 'node:module';
4
4
  import process from 'node:process';
5
5
  import { migrateUserSettingsFromProjectConfig } from '../defaults-store.js';
6
- import { applyProjectRoot } from '../project-root.js';
6
+ import { applyProjectRoot, hasExplicitProjectRoot } from '../project-root.js';
7
7
  import { runWithMcpRequestSignal } from './request-context.js';
8
8
  import { runWithMcpToolContext } from './result.js';
9
+ import { withToolAnnotations } from './tool-annotations.js';
9
10
  import { registerAgentiaMcpTools } from './tools.js';
10
11
  const require = createRequire(import.meta.url);
11
12
  const packageJson = require('../../../package.json');
12
- export function createAgentiaMcpServer(lifecycleSignal) {
13
+ export function createAgentiaMcpServer(lifecycleSignal, projectContextReady = Promise.resolve()) {
13
14
  const server = new McpServer({
14
15
  name: packageJson.name ?? 'agentia-cli',
15
16
  version: packageJson.version,
16
17
  });
17
- wrapMcpToolRegistration(server, lifecycleSignal);
18
+ wrapMcpToolRegistration(server, lifecycleSignal, projectContextReady);
18
19
  registerAgentiaMcpTools(server);
19
20
  return server;
20
21
  }
@@ -41,13 +42,14 @@ function combineSignals(requestSignal, lifecycleSignal) {
41
42
  signal: controller.signal,
42
43
  };
43
44
  }
44
- function wrapMcpToolRegistration(server, lifecycleSignal) {
45
+ function wrapMcpToolRegistration(server, lifecycleSignal, projectContextReady = Promise.resolve()) {
45
46
  const registerTool = server.registerTool.bind(server);
46
- server.registerTool = ((name, config, handler) => registerTool(name, config, (...args) => {
47
+ server.registerTool = ((name, config, handler) => registerTool(name, withToolAnnotations(name, config), (...args) => {
47
48
  const extra = args.at(-1);
48
49
  const { dispose, signal } = combineSignals(extra?.signal, lifecycleSignal);
49
50
  return runWithMcpRequestSignal(signal, async () => {
50
51
  try {
52
+ await projectContextReady;
51
53
  return await runWithMcpToolContext(name, async () => handler(...args));
52
54
  }
53
55
  finally {
@@ -56,13 +58,38 @@ function wrapMcpToolRegistration(server, lifecycleSignal) {
56
58
  });
57
59
  }));
58
60
  }
59
- export async function startAgentiaMcpServer(transport = new StdioServerTransport()) {
60
- applyProjectRoot();
61
+ function clientSupportsRoots(server) {
62
+ return (server.server._clientCapabilities?.roots !== undefined);
63
+ }
64
+ async function applyMcpProjectRoot(server, includeMcpRoots) {
65
+ const rootUris = includeMcpRoots ? (await server.server.listRoots()).roots.map((root) => root.uri) : undefined;
66
+ applyProjectRoot(undefined, rootUris);
61
67
  await migrateUserSettingsFromProjectConfig().catch(() => {
62
68
  // Best-effort; MCP tools still fall back to reading legacy project keys.
63
69
  });
70
+ }
71
+ export async function startAgentiaMcpServer(transport = new StdioServerTransport()) {
64
72
  const lifecycle = new AbortController();
65
- const server = createAgentiaMcpServer(lifecycle.signal);
73
+ let resolveProjectContext;
74
+ let rejectProjectContext;
75
+ const projectContextReady = new Promise((resolve, reject) => {
76
+ resolveProjectContext = resolve;
77
+ rejectProjectContext = reject;
78
+ });
79
+ projectContextReady.catch((error) => {
80
+ const message = error instanceof Error ? error.message : String(error);
81
+ process.stderr.write(`[agentia-mcp] project context error: ${message}\n`);
82
+ });
83
+ const server = createAgentiaMcpServer(lifecycle.signal, projectContextReady);
84
+ if (hasExplicitProjectRoot()) {
85
+ await applyMcpProjectRoot(server, false);
86
+ resolveProjectContext();
87
+ }
88
+ else {
89
+ server.server.oninitialized = () => {
90
+ applyMcpProjectRoot(server, clientSupportsRoots(server)).then(resolveProjectContext, rejectProjectContext);
91
+ };
92
+ }
66
93
  let closing = false;
67
94
  const close = async () => {
68
95
  if (closing)
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Standard MCP tool annotations for every Agentia MCP tool.
3
+ *
4
+ * Annotations are hints for MCP clients (auto-approve, confirmation prompts); they are not
5
+ * enforcement. Gateway authorization still applies. Only a few tools enforce their own `confirm` flag.
6
+ *
7
+ * Every tool is classified here explicitly. `test/lib/mcp/tool-annotations.test.ts` fails when a
8
+ * registered tool is missing from the table, so new tools must be classified when they are added.
9
+ */
10
+ /** MCP spec: destructive means the tool may overwrite or remove existing state, not only add. */
11
+ const CLASS_ANNOTATIONS = {
12
+ // Runs or triggers something with side effects; repeating it repeats the effect.
13
+ action: { destructiveHint: true, idempotentHint: false, readOnlyHint: false },
14
+ // Read-only but not repeatable (model output varies).
15
+ ask: { destructiveHint: false, idempotentHint: false, readOnlyHint: true },
16
+ // Purely additive; repeating it creates another record.
17
+ create: { destructiveHint: false, idempotentHint: false, readOnlyHint: false },
18
+ // Removes or resets state; repeating it has no further effect.
19
+ delete: { destructiveHint: true, idempotentHint: true, readOnlyHint: false },
20
+ read: { destructiveHint: false, idempotentHint: true, readOnlyHint: true },
21
+ // Overwrites existing state with the same result when repeated.
22
+ update: { destructiveHint: true, idempotentHint: true, readOnlyHint: false },
23
+ };
24
+ /** Triggers side effects (commit, promote, run, kill, ...). */
25
+ const ACTION_TOOLS = [
26
+ 'agentia_cloud_commit',
27
+ 'agentia_cloud_promote',
28
+ 'agentia_data_sync_apply',
29
+ 'agentia_function_run',
30
+ 'agentia_function_run_local',
31
+ 'agentia_job_kill',
32
+ 'agentia_job_pause',
33
+ 'agentia_job_resume',
34
+ 'agentia_job_run',
35
+ 'agentia_metadata_refresh_deleted',
36
+ 'agentia_metadata_refresh_run',
37
+ 'agentia_promotion_run',
38
+ 'agentia_testing_build_abort',
39
+ 'agentia_testing_build_run',
40
+ 'agentia_testing_job_run',
41
+ 'agentia_testing_live_continue',
42
+ 'agentia_testing_live_execute',
43
+ 'agentia_testing_live_interrupt',
44
+ 'agentia_testing_live_stop',
45
+ 'agentia_testing_run',
46
+ 'agentia_work_commit',
47
+ 'agentia_work_done',
48
+ 'agentia_work_publish',
49
+ 'agentia_work_push',
50
+ 'agentia_work_submit',
51
+ 'agentia_work_test',
52
+ 'agentia_work_test_apex',
53
+ ];
54
+ /** Read-only, non-repeatable model calls. */
55
+ const ASK_TOOLS = [
56
+ 'agentia_ai_ask',
57
+ ];
58
+ /** Additive writes. */
59
+ const CREATE_TOOLS = [
60
+ 'agentia_credential_create',
61
+ 'agentia_data_commit_create',
62
+ 'agentia_data_filter_add',
63
+ 'agentia_data_formula_create',
64
+ 'agentia_data_template_convert_old',
65
+ 'agentia_data_template_create',
66
+ 'agentia_environment_create',
67
+ 'agentia_pipeline_connection_create',
68
+ 'agentia_pipeline_create',
69
+ 'agentia_pipeline_stage_connection_create',
70
+ 'agentia_project_create',
71
+ 'agentia_repository_create',
72
+ 'agentia_stage_create',
73
+ 'agentia_testing_create',
74
+ 'agentia_testing_data_table_create',
75
+ 'agentia_testing_job_create',
76
+ 'agentia_testing_job_download',
77
+ 'agentia_testing_live_start',
78
+ 'agentia_testing_project_create',
79
+ 'agentia_testing_robot_create',
80
+ 'agentia_testing_user_parameter_create',
81
+ 'agentia_testing_variable_create',
82
+ 'agentia_work_create',
83
+ 'agentia_work_deployment_step_create',
84
+ ];
85
+ /** Removes or resets state. */
86
+ const DELETE_TOOLS = [
87
+ 'agentia_data_filter_delete',
88
+ 'agentia_data_template_delete',
89
+ 'agentia_function_delete',
90
+ 'agentia_pipeline_connection_delete',
91
+ 'agentia_pipeline_stage_connection_delete',
92
+ 'agentia_project_delete',
93
+ 'agentia_repository_delete',
94
+ 'agentia_repository_reset',
95
+ 'agentia_stage_delete',
96
+ 'agentia_testing_data_table_delete',
97
+ 'agentia_testing_job_delete',
98
+ 'agentia_testing_job_schedule_remove',
99
+ 'agentia_testing_project_delete',
100
+ 'agentia_testing_robot_delete',
101
+ 'agentia_testing_user_parameter_delete',
102
+ 'agentia_testing_variable_delete',
103
+ 'agentia_work_delete',
104
+ 'agentia_work_deployment_step_delete',
105
+ ];
106
+ /** Read-only lookups. */
107
+ const READ_TOOLS = [
108
+ 'agentia_auth_get',
109
+ 'agentia_credential_list',
110
+ 'agentia_data_commit_list',
111
+ 'agentia_data_dataset_file_content',
112
+ 'agentia_data_dataset_file_list',
113
+ 'agentia_data_filter_list',
114
+ 'agentia_data_formula_list',
115
+ 'agentia_data_records_match',
116
+ 'agentia_data_records_search',
117
+ 'agentia_data_sobject_fields',
118
+ 'agentia_data_sobject_relationships',
119
+ 'agentia_data_sync_preview_updates',
120
+ 'agentia_data_template_get',
121
+ 'agentia_data_template_get_detail',
122
+ 'agentia_data_template_list',
123
+ 'agentia_environment_auth_status',
124
+ 'agentia_environment_get',
125
+ 'agentia_environment_list',
126
+ 'agentia_function_defaults',
127
+ 'agentia_function_get',
128
+ 'agentia_function_list',
129
+ 'agentia_function_result_get',
130
+ 'agentia_function_result_log_get',
131
+ 'agentia_health_check',
132
+ 'agentia_job_get',
133
+ 'agentia_job_list',
134
+ 'agentia_job_log_get',
135
+ 'agentia_job_result_file_get',
136
+ 'agentia_job_result_file_list',
137
+ 'agentia_metadata_content_compare',
138
+ 'agentia_metadata_content_get',
139
+ 'agentia_metadata_dependency_list',
140
+ 'agentia_metadata_index_compare',
141
+ 'agentia_metadata_list',
142
+ 'agentia_metadata_refresh_status',
143
+ 'agentia_navigation_resolve',
144
+ 'agentia_pipeline_connection_list',
145
+ 'agentia_pipeline_get',
146
+ 'agentia_pipeline_list',
147
+ 'agentia_pipeline_stage_connection_list',
148
+ 'agentia_project_default_get',
149
+ 'agentia_project_get',
150
+ 'agentia_project_list',
151
+ 'agentia_promotion_conflict_get',
152
+ 'agentia_promotion_conflict_list',
153
+ 'agentia_promotion_get',
154
+ 'agentia_promotion_list',
155
+ 'agentia_repository_get',
156
+ 'agentia_repository_list',
157
+ 'agentia_repository_validate',
158
+ 'agentia_stage_get',
159
+ 'agentia_stage_list',
160
+ 'agentia_testing_build_get',
161
+ 'agentia_testing_build_latest',
162
+ 'agentia_testing_build_list',
163
+ 'agentia_testing_build_logs',
164
+ 'agentia_testing_build_search',
165
+ 'agentia_testing_data_table_get',
166
+ 'agentia_testing_data_table_list',
167
+ 'agentia_testing_job_files',
168
+ 'agentia_testing_job_get',
169
+ 'agentia_testing_job_list',
170
+ 'agentia_testing_job_refs',
171
+ 'agentia_testing_job_schedule_get',
172
+ 'agentia_testing_live_history',
173
+ 'agentia_testing_live_inspect',
174
+ 'agentia_testing_live_reports',
175
+ 'agentia_testing_live_screenshot',
176
+ 'agentia_testing_live_status',
177
+ 'agentia_testing_logs',
178
+ 'agentia_testing_project_get',
179
+ 'agentia_testing_project_list',
180
+ 'agentia_testing_project_permission_get',
181
+ 'agentia_testing_project_permission_list',
182
+ 'agentia_testing_robot_get',
183
+ 'agentia_testing_robot_list',
184
+ 'agentia_testing_status',
185
+ 'agentia_testing_user_parameter_get',
186
+ 'agentia_testing_user_parameter_list',
187
+ 'agentia_testing_variable_get',
188
+ 'agentia_testing_variable_list',
189
+ 'agentia_user_get',
190
+ 'agentia_work_deployment_step_list',
191
+ 'agentia_work_deployment_step_salesforce_flows',
192
+ 'agentia_work_deployment_step_types',
193
+ 'agentia_work_get',
194
+ 'agentia_work_list',
195
+ 'agentia_work_status',
196
+ ];
197
+ /** Overwrites existing state. */
198
+ const UPDATE_TOOLS = [
199
+ 'agentia_auth_set',
200
+ 'agentia_credential_update',
201
+ 'agentia_data_filter_update',
202
+ 'agentia_data_formula_update',
203
+ 'agentia_data_template_save_detail',
204
+ 'agentia_environment_update',
205
+ 'agentia_function_upsert',
206
+ 'agentia_pipeline_connection_update',
207
+ 'agentia_pipeline_stage_connection_update',
208
+ 'agentia_pipeline_update',
209
+ 'agentia_project_default_set',
210
+ 'agentia_project_default_unset',
211
+ 'agentia_project_update',
212
+ 'agentia_promotion_conflict_resolve',
213
+ 'agentia_promotion_conflict_unresolve',
214
+ 'agentia_promotion_job_step_update',
215
+ 'agentia_repository_update',
216
+ 'agentia_repository_auth_https',
217
+ 'agentia_repository_auth_ssh',
218
+ 'agentia_stage_update',
219
+ 'agentia_testing_data_table_update',
220
+ 'agentia_testing_job_schedule_set',
221
+ 'agentia_testing_job_update',
222
+ 'agentia_testing_job_upload',
223
+ 'agentia_testing_live_set_options',
224
+ 'agentia_testing_project_permission_set',
225
+ 'agentia_testing_project_permission_update',
226
+ 'agentia_testing_project_update',
227
+ 'agentia_testing_robot_update',
228
+ 'agentia_testing_update',
229
+ 'agentia_testing_user_parameter_update',
230
+ 'agentia_testing_variable_update',
231
+ 'agentia_work_deployment_step_reorder',
232
+ 'agentia_work_deployment_step_update',
233
+ 'agentia_work_set',
234
+ 'agentia_work_update',
235
+ ];
236
+ /** Tools that only touch local state (keychain/config), not the gateway or Salesforce. */
237
+ const LOCAL_ONLY_TOOLS = new Set([
238
+ 'agentia_auth_get',
239
+ 'agentia_project_default_get',
240
+ 'agentia_project_default_set',
241
+ 'agentia_project_default_unset',
242
+ ]);
243
+ const TOOL_CLASSES = new Map([
244
+ ...ACTION_TOOLS.map((name) => [name, 'action']),
245
+ ...ASK_TOOLS.map((name) => [name, 'ask']),
246
+ ...CREATE_TOOLS.map((name) => [name, 'create']),
247
+ ...DELETE_TOOLS.map((name) => [name, 'delete']),
248
+ ...READ_TOOLS.map((name) => [name, 'read']),
249
+ ...UPDATE_TOOLS.map((name) => [name, 'update']),
250
+ ]);
251
+ export function listClassifiedToolNames() {
252
+ return [...TOOL_CLASSES.keys()];
253
+ }
254
+ export function getToolAnnotations(toolName) {
255
+ const toolClass = TOOL_CLASSES.get(toolName);
256
+ if (toolClass === undefined)
257
+ return undefined;
258
+ return { ...CLASS_ANNOTATIONS[toolClass], openWorldHint: !LOCAL_ONLY_TOOLS.has(toolName) };
259
+ }
260
+ /** Returns the tool config with default annotations; annotations already set on the tool win. */
261
+ export function withToolAnnotations(toolName, config) {
262
+ const defaults = getToolAnnotations(toolName);
263
+ if (defaults === undefined || typeof config !== 'object' || config === null)
264
+ return config;
265
+ const existing = config.annotations;
266
+ return { ...config, annotations: { ...defaults, ...existing } };
267
+ }
268
+ //# sourceMappingURL=tool-annotations.js.map
@@ -37,7 +37,7 @@ import { buildPromotionManualTaskUpdatePayload, PROMOTION_MANUAL_TASK_STATUSES,
37
37
  import { performPromotionResume, performPromotionRun, PROMOTION_OPERATIONS, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS, } from '../promotion-run.js';
38
38
  import { normalizePromotionDetail, normalizePromotionsListPage, promotionEndpoint, promotionListEndpoint, } from '../promotion-types.js';
39
39
  import { REPOSITORY_STRING_VALIDATION_KEYS, validateNonEmptyStringFields as validateRepositoryNonEmptyStringFields, } from '../repository-flags.js';
40
- import { normalizeRepositoriesListPage, normalizeRepository, normalizeRepositoryValidateResult, repositoriesEndpoint, REPOSITORY_AUTH_TYPES, REPOSITORY_PROVIDERS, REPOSITORY_SOURCE_FORMATS, repositoryEndpoint, repositoryResetEndpoint, repositoryValidateEndpoint, withRequiredRepositoryFields, } from '../repository-types.js';
40
+ import { normalizeRepositoriesListPage, normalizeRepository, normalizeRepositoryValidateResult, repositoriesEndpoint, REPOSITORY_PROVIDERS, REPOSITORY_SOURCE_FORMATS, repositoryEndpoint, repositoryHttpsAuthEndpoint, repositoryResetEndpoint, repositorySshAuthEndpoint, repositoryValidateEndpoint, } from '../repository-types.js';
41
41
  import { buildStageMutationPayload, validateStagePayload } from '../stage-flags.js';
42
42
  import { normalizePipelineStageConnection, normalizeStage, normalizeStagesListPage, pipelineStageConnectionEndpoint, pipelineStageConnectionsEndpoint, STAGE_META_STAGE_SUGGESTIONS, stageEndpoint, stagesEndpoint, } from '../stage-types.js';
43
43
  import { getUserContext } from '../user-context.js';
@@ -47,6 +47,7 @@ import { workStatusEndpoint } from '../work-types.js';
47
47
  import { agentiaMcpAiToolHandlers, registerAgentiaMcpAiTools } from './ai-tools.js';
48
48
  import { agentiaMcpDataToolHandlers, registerAgentiaMcpDataTools } from './data-tools.js';
49
49
  import { agentiaMcpDeploymentStepToolHandlers, registerAgentiaMcpDeploymentStepTools } from './deployment-step-tools.js';
50
+ import { agentiaMcpHealthCheckToolHandlers, registerAgentiaMcpHealthCheckTools } from './health-check-tools.js';
50
51
  import { safelyHandleTool, wrapMcpToolHandlers } from './result.js';
51
52
  import { agentiaMcpTestingToolHandlers, registerAgentiaMcpTestingTools } from './testing-tools.js';
52
53
  import { agentiaMcpWorkToolHandlers, registerAgentiaMcpWorkTools } from './work-tools.js';
@@ -560,17 +561,12 @@ async function repositoryUpdate(args) {
560
561
  if (Object.keys(explicitPayload).length === 0) {
561
562
  throw new Error('Must provide at least one field to update.');
562
563
  }
563
- const currentResponse = await CicdGateway.call({
564
- endpoint: repositoryEndpoint(id),
565
- method: 'GET',
566
- });
567
- const payload = withRequiredRepositoryFields(explicitPayload, normalizeRepository(currentResponse));
568
- const validationError = validateRepositoryPayload(payload);
564
+ const validationError = validateRepositoryMutationPayload(explicitPayload);
569
565
  if (validationError !== undefined) {
570
566
  throw new Error(validationError);
571
567
  }
572
568
  const response = await CicdGateway.call({
573
- body: payload,
569
+ body: explicitPayload,
574
570
  endpoint: repositoryEndpoint(id),
575
571
  headers: {
576
572
  'Content-Type': 'application/json',
@@ -579,6 +575,26 @@ async function repositoryUpdate(args) {
579
575
  });
580
576
  return { repository: normalizeRepository(response) };
581
577
  }
578
+ async function repositoryAuthHttps(args) {
579
+ const { id, overwrite, ...payload } = args;
580
+ await CicdGateway.call({
581
+ body: payload,
582
+ endpoint: repositoryHttpsAuthEndpoint(assertRequired(id, 'id'), overwrite === true),
583
+ headers: { 'Content-Type': 'application/json' },
584
+ method: 'PUT',
585
+ });
586
+ return { id };
587
+ }
588
+ async function repositoryAuthSsh(args) {
589
+ const { id, overwrite, ...payload } = args;
590
+ const response = await CicdGateway.call({
591
+ body: payload,
592
+ endpoint: repositorySshAuthEndpoint(assertRequired(id, 'id'), overwrite === true),
593
+ headers: { 'Content-Type': 'application/json' },
594
+ method: 'POST',
595
+ });
596
+ return { id, publicKey: response.publicKey };
597
+ }
582
598
  async function repositoryDelete(args) {
583
599
  const id = assertRequired(args.id, 'id');
584
600
  await CicdGateway.call({
@@ -764,6 +780,9 @@ function validateRepositoryPayload(payload) {
764
780
  }
765
781
  return undefined;
766
782
  }
783
+ function validateRepositoryMutationPayload(payload) {
784
+ return validateRepositoryNonEmptyStringFields(payload, REPOSITORY_STRING_VALIDATION_KEYS);
785
+ }
767
786
  async function userGet(args = {}) {
768
787
  const user = await CicdGateway.call({
769
788
  endpoint: userEndpoint(resolveUserId(args.id)),
@@ -1206,6 +1225,7 @@ export const agentiaMcpToolHandlers = wrapMcpToolHandlers({
1206
1225
  ...agentiaMcpAiToolHandlers,
1207
1226
  ...agentiaMcpDataToolHandlers,
1208
1227
  ...agentiaMcpDeploymentStepToolHandlers,
1228
+ ...agentiaMcpHealthCheckToolHandlers,
1209
1229
  authGet,
1210
1230
  authSet,
1211
1231
  credentialCreate,
@@ -1332,18 +1352,14 @@ const pipelineConnectionMutationSchema = {
1332
1352
  };
1333
1353
  const repositoryMutationSchema = {
1334
1354
  allowFunctionsGitCache: z.boolean().optional().describe('Allow Functions Git cache for this repository.'),
1335
- authType: z.enum(REPOSITORY_AUTH_TYPES).optional().describe('Repository authentication type.'),
1336
1355
  branchBaseUrl: z.string().nullable().optional().describe('Base URL for repository branch links.'),
1337
1356
  commitBaseUrl: z.string().nullable().optional().describe('Base URL for repository commit links.'),
1338
- extraHeaders: z.string().nullable().optional().describe('Additional authentication headers.'),
1339
1357
  isCopadoTunnelEnabled: z.boolean().optional().describe('Enable Copado tunnel for this repository.'),
1340
- password: z.string().nullable().optional().describe('Repository password or token. Sensitive input.'),
1341
1358
  provider: z.enum(REPOSITORY_PROVIDERS).optional().describe('Git repository provider.'),
1342
1359
  pullRequestBaseUrl: z.string().nullable().optional().describe('Base URL for repository pull request links.'),
1343
1360
  sourceFormat: z.enum(REPOSITORY_SOURCE_FORMATS).optional().describe('Git repository source format.'),
1344
1361
  tagBaseUrl: z.string().nullable().optional().describe('Base URL for repository tag links.'),
1345
1362
  uri: z.string().nullable().optional().describe('Repository clone URI.'),
1346
- username: z.string().nullable().optional().describe('Repository username.'),
1347
1363
  };
1348
1364
  const promotionListSchema = {
1349
1365
  createdById: z.string().optional().describe('Filter by creator ID.'),
@@ -1366,6 +1382,7 @@ export function registerAgentiaMcpTools(server) {
1366
1382
  registerAgentiaMcpAiTools(server);
1367
1383
  registerAgentiaMcpDataTools(server);
1368
1384
  registerAgentiaMcpDeploymentStepTools(server);
1385
+ registerAgentiaMcpHealthCheckTools(server);
1369
1386
  registerAgentiaMcpTestingTools(server);
1370
1387
  server.registerTool('agentia_environment_list', {
1371
1388
  description: 'List Copado environments via the CICD gateway.',
@@ -1952,6 +1969,35 @@ export function registerAgentiaMcpTools(server) {
1952
1969
  },
1953
1970
  title: 'Agentia Repository Update',
1954
1971
  }, (args) => safelyHandleTool(() => repositoryUpdate(args)));
1972
+ server.registerTool('agentia_repository_auth_https', {
1973
+ description: 'Configure HTTPS repository authentication. The password and optional headers are sensitive and are redacted from responses.',
1974
+ inputSchema: {
1975
+ branchBaseUrl: z.string(),
1976
+ commitBaseUrl: z.string(),
1977
+ extraHeaders: z.string().optional().describe('Sensitive optional authentication headers.'),
1978
+ id: z.string().describe('Copado Git repository ID.'),
1979
+ overwrite: z.boolean().optional().describe('Explicitly replace an existing validated credential.'),
1980
+ password: z.string().describe('Sensitive HTTPS password or personal access token.'),
1981
+ pullRequestBaseUrl: z.string(),
1982
+ tagBaseUrl: z.string(),
1983
+ uri: z.string(),
1984
+ username: z.string(),
1985
+ },
1986
+ title: 'Agentia Repository HTTPS Authentication',
1987
+ }, (args) => safelyHandleTool(() => repositoryAuthHttps(args)));
1988
+ server.registerTool('agentia_repository_auth_ssh', {
1989
+ description: 'Configure SSH repository authentication and return the generated public key.',
1990
+ inputSchema: {
1991
+ branchBaseUrl: z.string(),
1992
+ commitBaseUrl: z.string(),
1993
+ id: z.string().describe('Copado Git repository ID.'),
1994
+ overwrite: z.boolean().optional().describe('Explicitly replace an existing SSH key.'),
1995
+ pullRequestBaseUrl: z.string(),
1996
+ tagBaseUrl: z.string(),
1997
+ uri: z.string(),
1998
+ },
1999
+ title: 'Agentia Repository SSH Authentication',
2000
+ }, (args) => safelyHandleTool(() => repositoryAuthSsh(args)));
1955
2001
  server.registerTool('agentia_repository_delete', {
1956
2002
  description: 'Delete a Copado Git repository by ID via the CICD gateway.',
1957
2003
  inputSchema: { id: z.string().describe('Copado Git repository ID.') },