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

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 (65) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +935 -256
  3. package/dist/commands/adv/auth/status.js +20 -0
  4. package/dist/commands/adv/component/add.js +48 -0
  5. package/dist/commands/adv/component/list.js +46 -0
  6. package/dist/commands/adv/component/refresh.js +23 -0
  7. package/dist/commands/adv/component/remove.js +35 -0
  8. package/dist/commands/adv/component/selected.js +26 -0
  9. package/dist/commands/adv/component/types.js +16 -0
  10. package/dist/commands/adv/deployment/cancel.js +45 -0
  11. package/dist/commands/adv/deployment/create.js +23 -0
  12. package/dist/commands/adv/deployment/deploy.js +46 -0
  13. package/dist/commands/adv/deployment/get.js +21 -0
  14. package/dist/commands/adv/deployment/list.js +30 -0
  15. package/dist/commands/adv/deployment/options.js +33 -0
  16. package/dist/commands/adv/deployment/quick-deploy.js +54 -0
  17. package/dist/commands/adv/deployment/validate.js +29 -0
  18. package/dist/commands/adv/job/get.js +21 -0
  19. package/dist/commands/adv/job/list.js +30 -0
  20. package/dist/commands/adv/job/wait.js +29 -0
  21. package/dist/commands/adv/organization/get.js +21 -0
  22. package/dist/commands/adv/organization/list.js +21 -0
  23. package/dist/commands/adv/organization/validate.js +20 -0
  24. package/dist/commands/auth/get.js +24 -3
  25. package/dist/commands/auth/set.js +18 -0
  26. package/dist/commands/auth/unset.js +4 -0
  27. package/dist/commands/cicd/notification/get.js +44 -0
  28. package/dist/commands/cicd/work/publish.js +1 -0
  29. package/dist/commands/cicd/work/test/apex.js +37 -4
  30. package/dist/commands/cicd/work/test.js +20 -1
  31. package/dist/commands/setup/skills/create.js +4 -0
  32. package/dist/commands/setup/skills/update.js +4 -0
  33. package/dist/hooks/init/migrate-user-config.js +5 -1
  34. package/dist/hooks/init/version-warning.js +5 -2
  35. package/dist/lib/adv-config.js +9 -0
  36. package/dist/lib/adv-flags.js +8 -0
  37. package/dist/lib/adv-gateway.js +8 -0
  38. package/dist/lib/adv-operations.js +26 -0
  39. package/dist/lib/adv-sanitization.js +8 -0
  40. package/dist/lib/adv-types.js +9 -0
  41. package/dist/lib/agentia-command.js +30 -1
  42. package/dist/lib/auth-config.js +2 -1
  43. package/dist/lib/auth-status-format.js +2 -1
  44. package/dist/lib/cicd-gateway.js +3 -1
  45. package/dist/lib/cli-severity-color.js +4 -0
  46. package/dist/lib/local-quality-gates.js +4 -1
  47. package/dist/lib/mcp/adv-tools.js +221 -0
  48. package/dist/lib/mcp/command-id.js +4 -1
  49. package/dist/lib/mcp/tool-annotations.js +23 -0
  50. package/dist/lib/mcp/tools.js +42 -0
  51. package/dist/lib/mcp/work-tools.js +48 -9
  52. package/dist/lib/notifications-get.js +10 -0
  53. package/dist/lib/plugin-host/event-log.js +3 -0
  54. package/dist/lib/runtime.js +1 -1
  55. package/dist/lib/setup-templates.js +2 -1
  56. package/dist/lib/work-apex-test-failures.js +13 -0
  57. package/dist/lib/work-apex-test.js +4 -1
  58. package/oclif.manifest.json +1359 -153
  59. package/package.json +35 -2
  60. package/templates/AGENTS.md +1 -1
  61. package/templates/skills/agentia-adv/SKILL.md +20 -0
  62. package/templates/skills/agentia-adv/references/pipelines-advanced.md +34 -0
  63. package/templates/skills/agentia-cicd/SKILL.md +4 -2
  64. package/templates/skills/agentia-cicd/references/notifications.md +79 -0
  65. package/templates/skills/agentia-cicd/references/work.md +21 -2
@@ -1,13 +1,16 @@
1
1
  import {modules} from './runtime.js';
2
+ const AGENTIA_APEX_RERUN_FAILED_ENV = modules["local-quality-gates.js"]["AGENTIA_APEX_RERUN_FAILED_ENV"]
3
+ const AGENTIA_APEX_RERUN_FAILED_FLAG = modules["local-quality-gates.js"]["AGENTIA_APEX_RERUN_FAILED_FLAG"]
2
4
  const AGENTIA_APEX_TEST_CLASSES_ENV = modules["local-quality-gates.js"]["AGENTIA_APEX_TEST_CLASSES_ENV"]
3
5
  const LocalQualityGatesError = modules["local-quality-gates.js"]["LocalQualityGatesError"]
4
6
  const QUALITY_GATES_SCRIPT_UNIX = modules["local-quality-gates.js"]["QUALITY_GATES_SCRIPT_UNIX"]
5
7
  const QUALITY_GATES_SCRIPT_WINDOWS = modules["local-quality-gates.js"]["QUALITY_GATES_SCRIPT_WINDOWS"]
6
8
  const buildQualityGatesCommand = modules["local-quality-gates.js"]["buildQualityGatesCommand"]
9
+ const parseQualityGatesEnvAssignments = modules["local-quality-gates.js"]["parseQualityGatesEnvAssignments"]
7
10
  const qualityGatesScriptName = modules["local-quality-gates.js"]["qualityGatesScriptName"]
8
11
  const resetLocalQualityGatesForTests = modules["local-quality-gates.js"]["resetLocalQualityGatesForTests"]
9
12
  const resolveLocalQualityGatesScript = modules["local-quality-gates.js"]["resolveLocalQualityGatesScript"]
10
13
  const runLocalQualityGates = modules["local-quality-gates.js"]["runLocalQualityGates"]
11
14
  const setLocalQualityGatesExistsSyncForTests = modules["local-quality-gates.js"]["setLocalQualityGatesExistsSyncForTests"]
12
15
  const setLocalQualityGatesSpawnForTests = modules["local-quality-gates.js"]["setLocalQualityGatesSpawnForTests"]
13
- export {AGENTIA_APEX_TEST_CLASSES_ENV, LocalQualityGatesError, QUALITY_GATES_SCRIPT_UNIX, QUALITY_GATES_SCRIPT_WINDOWS, buildQualityGatesCommand, qualityGatesScriptName, resetLocalQualityGatesForTests, resolveLocalQualityGatesScript, runLocalQualityGates, setLocalQualityGatesExistsSyncForTests, setLocalQualityGatesSpawnForTests};
16
+ export {AGENTIA_APEX_RERUN_FAILED_ENV, AGENTIA_APEX_RERUN_FAILED_FLAG, AGENTIA_APEX_TEST_CLASSES_ENV, LocalQualityGatesError, QUALITY_GATES_SCRIPT_UNIX, QUALITY_GATES_SCRIPT_WINDOWS, buildQualityGatesCommand, parseQualityGatesEnvAssignments, qualityGatesScriptName, resetLocalQualityGatesForTests, resolveLocalQualityGatesScript, runLocalQualityGates, setLocalQualityGatesExistsSyncForTests, setLocalQualityGatesSpawnForTests};
@@ -0,0 +1,221 @@
1
+ import { z } from 'zod';
2
+ import { addAdvComponents, cancelAdvDeployment, createAdvDeployment, getAdvAuthStatus, getAdvDeployment, getAdvJob, getAdvOrganization, listAdvComponents, listAdvComponentTypes, listAdvDeployments, listAdvJobs, listAdvOrganizations, parseAdvComponentSpec, refreshAdvComponents, removeAdvComponents, runAdvDeploymentAction, selectedAdvComponents, updateAdvDeploymentOptions, validateAdvOrganization, waitForAdvJob, } from '../adv-operations.js';
3
+ import { safelyHandleTool } from './result.js';
4
+ const componentReferenceSchema = z.union([
5
+ z.string().min(1).describe('Component in Type/Name format.'),
6
+ z.object({
7
+ excluded: z.boolean().optional().describe('Whether the component is excluded from deployment.'),
8
+ fullName: z.string().min(1).describe('Component full name.'),
9
+ type: z.string().min(1).describe('Metadata type name.'),
10
+ }),
11
+ ]);
12
+ const componentInputSchema = z.array(componentReferenceSchema).min(1).describe('Components as Type/Name strings or {type, fullName, excluded} objects.');
13
+ function componentList(components) {
14
+ return components.map((component) => {
15
+ if (typeof component === 'string')
16
+ return parseAdvComponentSpec(component);
17
+ return component;
18
+ });
19
+ }
20
+ function componentAddMode(components) {
21
+ return components.some((component) => typeof component !== 'string') ? 'json' : 'import';
22
+ }
23
+ function requireConfirm(confirm, action) {
24
+ if (confirm !== true)
25
+ throw new Error(`${action} requires confirm: true.`);
26
+ }
27
+ async function deploymentAction(args) {
28
+ if (args.kind !== 'validate')
29
+ requireConfirm(args.confirm, 'Pipelines Advanced deployment action');
30
+ return {
31
+ result: await runAdvDeploymentAction({
32
+ backup: args.backup,
33
+ id: args.id,
34
+ kind: args.kind,
35
+ wait: args.wait,
36
+ waitIntervalSeconds: args.interval,
37
+ waitTimeoutSeconds: args.timeout,
38
+ }),
39
+ };
40
+ }
41
+ export function registerAgentiaMcpAdvTools(server) {
42
+ server.registerTool('agentia_adv_auth_status', {
43
+ description: 'Check the configured Copado Pipelines Advanced PAT.',
44
+ inputSchema: {},
45
+ title: 'Agentia ADV Auth Status',
46
+ }, () => safelyHandleTool(async () => ({ result: await getAdvAuthStatus() })));
47
+ server.registerTool('agentia_adv_organization_list', {
48
+ description: 'List Copado Pipelines Advanced organizations visible to the PAT user.',
49
+ inputSchema: {},
50
+ title: 'Agentia ADV Organization List',
51
+ }, () => safelyHandleTool(async () => ({ result: await listAdvOrganizations() })));
52
+ server.registerTool('agentia_adv_organization_get', {
53
+ description: 'Get one Copado Pipelines Advanced organization.',
54
+ inputSchema: { id: z.number().int().positive().describe('Organization ID.') },
55
+ title: 'Agentia ADV Organization Get',
56
+ }, (args) => safelyHandleTool(async () => ({ result: await getAdvOrganization(args.id) })));
57
+ server.registerTool('agentia_adv_organization_validate', {
58
+ description: 'Validate Copado Pipelines Advanced connectivity to an organization.',
59
+ inputSchema: { id: z.number().int().positive().describe('Organization ID.') },
60
+ title: 'Agentia ADV Organization Validate',
61
+ }, (args) => safelyHandleTool(async () => ({ result: await validateAdvOrganization(args.id) })));
62
+ server.registerTool('agentia_adv_deployment_list', {
63
+ description: 'List Copado Pipelines Advanced deployments.',
64
+ inputSchema: { includeArchived: z.boolean().optional().describe('Include archived deployments.') },
65
+ title: 'Agentia ADV Deployment List',
66
+ }, (args) => safelyHandleTool(async () => ({ result: await listAdvDeployments({ includeArchived: args.includeArchived }) })));
67
+ server.registerTool('agentia_adv_deployment_get', {
68
+ description: 'Get one Copado Pipelines Advanced deployment.',
69
+ inputSchema: { id: z.number().int().positive().describe('Deployment ID.') },
70
+ title: 'Agentia ADV Deployment Get',
71
+ }, (args) => safelyHandleTool(async () => ({ result: await getAdvDeployment(args.id) })));
72
+ server.registerTool('agentia_adv_deployment_create', {
73
+ description: 'Create a Copado Pipelines Advanced deployment.',
74
+ inputSchema: {
75
+ name: z.string().min(1).describe('Deployment name.'),
76
+ sourceOrg: z.number().int().positive().describe('Source organization ID.'),
77
+ targetOrg: z.number().int().positive().describe('Target organization ID.'),
78
+ },
79
+ title: 'Agentia ADV Deployment Create',
80
+ }, (args) => safelyHandleTool(async () => ({ result: await createAdvDeployment(args) })));
81
+ server.registerTool('agentia_adv_deployment_options', {
82
+ description: 'Update Copado Pipelines Advanced deployment options.',
83
+ inputSchema: {
84
+ id: z.number().int().positive().describe('Deployment ID.'),
85
+ set: z.array(z.string()).optional().describe('Options as name=value entries.'),
86
+ },
87
+ title: 'Agentia ADV Deployment Options',
88
+ }, (args) => safelyHandleTool(async () => ({ result: await updateAdvDeploymentOptions({ id: args.id, set: args.set }) })));
89
+ server.registerTool('agentia_adv_deployment_validate', {
90
+ description: 'Start a check-only Copado Pipelines Advanced validation run.',
91
+ inputSchema: {
92
+ id: z.number().int().positive().describe('Deployment ID.'),
93
+ interval: z.number().positive().optional().describe('Seconds between polls when wait is true.'),
94
+ timeout: z.number().positive().optional().describe('Maximum seconds to wait.'),
95
+ wait: z.boolean().optional().describe('Wait for the run to finish.'),
96
+ },
97
+ title: 'Agentia ADV Deployment Validate',
98
+ }, (args) => safelyHandleTool(() => deploymentAction({ ...args, kind: 'validate' })));
99
+ server.registerTool('agentia_adv_deployment_deploy', {
100
+ description: 'Start a real Copado Pipelines Advanced deployment run.',
101
+ inputSchema: {
102
+ confirm: z.boolean().optional().describe('Required true to start a deployment.'),
103
+ id: z.number().int().positive().describe('Deployment ID.'),
104
+ interval: z.number().positive().optional().describe('Seconds between polls when wait is true.'),
105
+ timeout: z.number().positive().optional().describe('Maximum seconds to wait.'),
106
+ wait: z.boolean().optional().describe('Wait for the run to finish.'),
107
+ },
108
+ title: 'Agentia ADV Deployment Deploy',
109
+ }, (args) => safelyHandleTool(() => deploymentAction({ ...args, kind: 'deploy' })));
110
+ server.registerTool('agentia_adv_deployment_quick_deploy', {
111
+ description: 'Start a Copado Pipelines Advanced quick deploy run.',
112
+ inputSchema: {
113
+ backup: z.boolean().optional().describe('Request backup before deploying.'),
114
+ confirm: z.boolean().optional().describe('Required true to start a quick deploy.'),
115
+ id: z.number().int().positive().describe('Deployment ID.'),
116
+ interval: z.number().positive().optional().describe('Seconds between polls when wait is true.'),
117
+ timeout: z.number().positive().optional().describe('Maximum seconds to wait.'),
118
+ wait: z.boolean().optional().describe('Wait for the run to finish.'),
119
+ },
120
+ title: 'Agentia ADV Deployment Quick Deploy',
121
+ }, (args) => safelyHandleTool(() => deploymentAction({ ...args, kind: 'quick-deploy' })));
122
+ server.registerTool('agentia_adv_deployment_cancel', {
123
+ description: 'Cancel the current Copado Pipelines Advanced run.',
124
+ inputSchema: {
125
+ confirm: z.boolean().optional().describe('Required true to request cancellation.'),
126
+ id: z.number().int().positive().describe('Deployment ID.'),
127
+ interval: z.number().positive().optional().describe('Seconds between polls when wait is true.'),
128
+ timeout: z.number().positive().optional().describe('Maximum seconds to wait.'),
129
+ wait: z.boolean().optional().describe('Wait for the run to finish.'),
130
+ },
131
+ title: 'Agentia ADV Deployment Cancel',
132
+ }, (args) => safelyHandleTool(async () => {
133
+ requireConfirm(args.confirm, 'Pipelines Advanced deployment cancellation');
134
+ return {
135
+ result: await cancelAdvDeployment({
136
+ id: args.id,
137
+ wait: args.wait,
138
+ waitIntervalSeconds: args.interval,
139
+ waitTimeoutSeconds: args.timeout,
140
+ }),
141
+ };
142
+ }));
143
+ server.registerTool('agentia_adv_component_types', {
144
+ description: 'List Copado Pipelines Advanced component type views.',
145
+ inputSchema: {},
146
+ title: 'Agentia ADV Component Types',
147
+ }, () => safelyHandleTool(async () => ({ result: await listAdvComponentTypes() })));
148
+ server.registerTool('agentia_adv_component_list', {
149
+ description: 'List source components for a Copado Pipelines Advanced deployment.',
150
+ inputSchema: {
151
+ flow: z.number().int().positive().describe('Deployment ID.'),
152
+ includeManagedPackage: z.boolean().optional().describe('Include managed package components.'),
153
+ type: z.string().describe('Comma-separated component type names.'),
154
+ },
155
+ title: 'Agentia ADV Component List',
156
+ }, (args) => safelyHandleTool(async () => ({ result: await listAdvComponents(args) })));
157
+ server.registerTool('agentia_adv_component_refresh', {
158
+ description: 'Refresh Copado Pipelines Advanced component comparison cache.',
159
+ inputSchema: {
160
+ flow: z.number().int().positive().describe('Deployment ID.'),
161
+ full: z.boolean().optional().describe('Delete cached comparison data before refreshing.'),
162
+ type: z.string().describe('Comma-separated component type names.'),
163
+ },
164
+ title: 'Agentia ADV Component Refresh',
165
+ }, (args) => safelyHandleTool(async () => ({ result: await refreshAdvComponents(args) })));
166
+ server.registerTool('agentia_adv_component_selected', {
167
+ description: 'List selected components for a Copado Pipelines Advanced deployment.',
168
+ inputSchema: { deploymentId: z.number().int().positive().describe('Deployment ID.') },
169
+ title: 'Agentia ADV Component Selected',
170
+ }, (args) => safelyHandleTool(async () => ({ result: await selectedAdvComponents(args.deploymentId) })));
171
+ server.registerTool('agentia_adv_component_add', {
172
+ description: 'Add components to a Copado Pipelines Advanced deployment selection.',
173
+ inputSchema: {
174
+ components: componentInputSchema,
175
+ deploymentId: z.number().int().positive().describe('Deployment ID.'),
176
+ },
177
+ title: 'Agentia ADV Component Add',
178
+ }, (args) => safelyHandleTool(async () => ({
179
+ result: await addAdvComponents({
180
+ components: componentList(args.components),
181
+ deploymentId: args.deploymentId,
182
+ mode: componentAddMode(args.components),
183
+ }),
184
+ })));
185
+ server.registerTool('agentia_adv_component_remove', {
186
+ description: 'Remove components from a Copado Pipelines Advanced deployment selection.',
187
+ inputSchema: {
188
+ components: componentInputSchema,
189
+ deploymentId: z.number().int().positive().describe('Deployment ID.'),
190
+ },
191
+ title: 'Agentia ADV Component Remove',
192
+ }, (args) => safelyHandleTool(async () => ({
193
+ result: await removeAdvComponents({ components: componentList(args.components), deploymentId: args.deploymentId }),
194
+ })));
195
+ server.registerTool('agentia_adv_job_get', {
196
+ description: 'Get the latest Copado Pipelines Advanced run for a deployment.',
197
+ inputSchema: { deploymentId: z.number().int().positive().describe('Deployment ID.') },
198
+ title: 'Agentia ADV Job Get',
199
+ }, (args) => safelyHandleTool(async () => ({ result: await getAdvJob(args.deploymentId) })));
200
+ server.registerTool('agentia_adv_job_list', {
201
+ description: 'List Copado Pipelines Advanced run history for a deployment.',
202
+ inputSchema: {
203
+ deploymentId: z.number().int().positive().describe('Deployment ID.'),
204
+ page: z.number().int().min(0).optional().describe('Page number starting at 0.'),
205
+ pageSize: z.number().int().positive().optional().describe('Rows per page.'),
206
+ },
207
+ title: 'Agentia ADV Job List',
208
+ }, (args) => safelyHandleTool(async () => ({ result: await listAdvJobs(args) })));
209
+ server.registerTool('agentia_adv_job_wait', {
210
+ description: 'Wait for the latest Copado Pipelines Advanced run to finish.',
211
+ inputSchema: {
212
+ deploymentId: z.number().int().positive().describe('Deployment ID.'),
213
+ interval: z.number().positive().optional().describe('Seconds between polls.'),
214
+ timeout: z.number().positive().optional().describe('Maximum seconds to wait.'),
215
+ },
216
+ title: 'Agentia ADV Job Wait',
217
+ }, (args) => safelyHandleTool(async () => ({
218
+ result: await waitForAdvJob({ deploymentId: args.deploymentId, intervalSeconds: args.interval, timeoutSeconds: args.timeout }),
219
+ })));
220
+ }
221
+ //# sourceMappingURL=adv-tools.js.map
@@ -1,7 +1,9 @@
1
1
  export const MCP_ONLY_TOOL_NAMES = new Set(['agentia_navigation_resolve']);
2
- const TOP_LEVEL_COMMAND_TOPICS = new Set(['auth', 'testing']);
2
+ const TOP_LEVEL_COMMAND_TOPICS = new Set(['adv', 'auth', 'testing']);
3
3
  const TOOL_COMMAND_ID_OVERRIDES = Object.fromEntries([
4
4
  ['agentia_ai_ask', 'ai:agent:ask'],
5
+ ['agentia_repository_auth_https', 'cicd:repository:auth:https:configure'],
6
+ ['agentia_repository_auth_ssh', 'cicd:repository:auth:ssh:configure'],
5
7
  ]);
6
8
  const HANDLER_TOOL_NAME_OVERRIDES = {
7
9
  deploymentStepCreate: 'agentia_work_deployment_step_create',
@@ -29,6 +31,7 @@ const HYPHENATED_TOKEN_REPLACEMENTS = [
29
31
  ['stage_connection', 'stage-connection'],
30
32
  ['run_local', 'run-local'],
31
33
  ['set_options', 'set-options'],
34
+ ['quick_deploy', 'quick-deploy'],
32
35
  ].sort((left, right) => right[0].length - left[0].length);
33
36
  export function mcpCommandIdFromToolName(toolName) {
34
37
  const trimmed = toolName.trim();
@@ -23,6 +23,11 @@ const CLASS_ANNOTATIONS = {
23
23
  };
24
24
  /** Triggers side effects (commit, promote, run, kill, ...). */
25
25
  const ACTION_TOOLS = [
26
+ 'agentia_adv_component_refresh',
27
+ 'agentia_adv_deployment_cancel',
28
+ 'agentia_adv_deployment_deploy',
29
+ 'agentia_adv_deployment_quick_deploy',
30
+ 'agentia_adv_deployment_validate',
26
31
  'agentia_cloud_commit',
27
32
  'agentia_cloud_promote',
28
33
  'agentia_data_sync_apply',
@@ -57,6 +62,7 @@ const ASK_TOOLS = [
57
62
  ];
58
63
  /** Additive writes. */
59
64
  const CREATE_TOOLS = [
65
+ 'agentia_adv_deployment_create',
60
66
  'agentia_credential_create',
61
67
  'agentia_data_commit_create',
62
68
  'agentia_data_filter_add',
@@ -106,6 +112,18 @@ const DELETE_TOOLS = [
106
112
  /** Read-only lookups. */
107
113
  const READ_TOOLS = [
108
114
  'agentia_auth_get',
115
+ 'agentia_adv_auth_status',
116
+ 'agentia_adv_component_list',
117
+ 'agentia_adv_component_selected',
118
+ 'agentia_adv_component_types',
119
+ 'agentia_adv_job_get',
120
+ 'agentia_adv_job_list',
121
+ 'agentia_adv_job_wait',
122
+ 'agentia_adv_organization_get',
123
+ 'agentia_adv_organization_list',
124
+ 'agentia_adv_organization_validate',
125
+ 'agentia_adv_deployment_get',
126
+ 'agentia_adv_deployment_list',
109
127
  'agentia_credential_list',
110
128
  'agentia_data_commit_list',
111
129
  'agentia_data_dataset_file_content',
@@ -141,6 +159,7 @@ const READ_TOOLS = [
141
159
  'agentia_metadata_list',
142
160
  'agentia_metadata_refresh_status',
143
161
  'agentia_navigation_resolve',
162
+ 'agentia_notification_get',
144
163
  'agentia_pipeline_connection_list',
145
164
  'agentia_pipeline_get',
146
165
  'agentia_pipeline_list',
@@ -197,6 +216,10 @@ const READ_TOOLS = [
197
216
  /** Overwrites existing state. */
198
217
  const UPDATE_TOOLS = [
199
218
  'agentia_auth_set',
219
+ 'agentia_notification_configure',
220
+ 'agentia_adv_component_add',
221
+ 'agentia_adv_component_remove',
222
+ 'agentia_adv_deployment_options',
200
223
  'agentia_credential_update',
201
224
  'agentia_data_filter_update',
202
225
  'agentia_data_formula_update',
@@ -23,6 +23,8 @@ import { listPaginationZodFields, mcpPaginatedListPayload } from '../list-pagina
23
23
  import { COMPARISON_MODES, CONTENT_SOURCES, contentResultToCompareSide, createUnifiedDiff, INDEX_SOURCES, MODULE_TYPES, ORDER_DIRECTIONS, PLATFORM_EXPERIENCES, RETRIEVE_MODES, sourceSideLabel, } from '../metadata-common.js';
24
24
  import { buildRefreshDeletedRequest, buildRefreshIndexRequest, refreshStatusEndpoint, resolveRefreshSourceFromEnv, } from '../metadata-refresh.js';
25
25
  import { NAVIGATION_RESOURCE_TYPES, resolveNavigationTarget } from '../navigation.js';
26
+ import { configureNotification, NOTIFICATION_DESTINATION_TYPES, NOTIFICATION_EVENTS, NOTIFICATION_SUBSCRIPTIONS, withNotificationConfigureErrorTranslation, } from '../notifications-configure.js';
27
+ import { getNotificationSubscriptions } from '../notifications-get.js';
26
28
  import { parsePipelineConnectionMutationObject, parsePipelineConnectionUpdateObject, validatePipelineConnectionCreatePayload, validatePipelineConnectionUpdatePayload, } from '../pipeline-connection-flags.js';
27
29
  import { validatePipelineMutationPayload, } from '../pipeline-flags.js';
28
30
  import { buildPipelineStageConnectionCreatePayload, buildPipelineStageConnectionUpdatePayload, } from '../pipeline-stage-connection-flags.js';
@@ -44,6 +46,7 @@ import { getUserContext } from '../user-context.js';
44
46
  import { DEFAULT_USER_ID, resolveUserId, userEndpoint } from '../user-types.js';
45
47
  import { resolveRecordedWorkBranchMetadata } from '../work-branch-metadata.js';
46
48
  import { workStatusEndpoint } from '../work-types.js';
49
+ import { registerAgentiaMcpAdvTools } from './adv-tools.js';
47
50
  import { agentiaMcpAiToolHandlers, registerAgentiaMcpAiTools } from './ai-tools.js';
48
51
  import { agentiaMcpDataToolHandlers, registerAgentiaMcpDataTools } from './data-tools.js';
49
52
  import { agentiaMcpDeploymentStepToolHandlers, registerAgentiaMcpDeploymentStepTools } from './deployment-step-tools.js';
@@ -1221,6 +1224,20 @@ async function navigationResolve(args) {
1221
1224
  resourceType: args.resourceType,
1222
1225
  });
1223
1226
  }
1227
+ async function notificationConfigure(args) {
1228
+ const result = await withNotificationConfigureErrorTranslation(() => configureNotification({
1229
+ destinationId: assertRequired(args.destinationId, 'destinationId'),
1230
+ destinationType: args.destinationType,
1231
+ event: args.event,
1232
+ pipelineId: assertRequired(args.pipelineId, 'pipelineId'),
1233
+ subscription: args.subscription,
1234
+ }));
1235
+ return { result };
1236
+ }
1237
+ async function notificationGet(args) {
1238
+ const result = await getNotificationSubscriptions(assertRequired(args.pipelineId, 'pipelineId'));
1239
+ return { result };
1240
+ }
1224
1241
  export const agentiaMcpToolHandlers = wrapMcpToolHandlers({
1225
1242
  ...agentiaMcpAiToolHandlers,
1226
1243
  ...agentiaMcpDataToolHandlers,
@@ -1263,6 +1280,8 @@ export const agentiaMcpToolHandlers = wrapMcpToolHandlers({
1263
1280
  metadataRefreshRun,
1264
1281
  metadataRefreshStatus,
1265
1282
  navigationResolve,
1283
+ notificationConfigure,
1284
+ notificationGet,
1266
1285
  pipelineConnectionCreate,
1267
1286
  pipelineConnectionDelete,
1268
1287
  pipelineConnectionList,
@@ -1308,6 +1327,18 @@ export const agentiaMcpToolHandlers = wrapMcpToolHandlers({
1308
1327
  ...agentiaMcpTestingToolHandlers,
1309
1328
  ...agentiaMcpWorkToolHandlers,
1310
1329
  });
1330
+ const notificationConfigureSchema = {
1331
+ destinationId: z.string().describe('Slack user or channel id or name.'),
1332
+ destinationType: z.enum(NOTIFICATION_DESTINATION_TYPES).describe('Slack destination type.'),
1333
+ event: z
1334
+ .enum(NOTIFICATION_EVENTS)
1335
+ .describe('Notification event.'),
1336
+ pipelineId: z.string().describe('Copado pipeline Salesforce Id (15 or 18 characters).'),
1337
+ subscription: z.enum(NOTIFICATION_SUBSCRIPTIONS).describe('Notification audience for this event.'),
1338
+ };
1339
+ const notificationGetSchema = {
1340
+ pipelineId: z.string().describe('Copado pipeline Salesforce Id (15 or 18 characters).'),
1341
+ };
1311
1342
  const environmentMutationSchema = {
1312
1343
  apexTestLevel: z.string().optional().describe('Apex test level.'),
1313
1344
  enableRollback: z.boolean().optional().describe('Enable rollback.'),
@@ -1380,6 +1411,7 @@ const promotionListSchema = {
1380
1411
  };
1381
1412
  export function registerAgentiaMcpTools(server) {
1382
1413
  registerAgentiaMcpAiTools(server);
1414
+ registerAgentiaMcpAdvTools(server);
1383
1415
  registerAgentiaMcpDataTools(server);
1384
1416
  registerAgentiaMcpDeploymentStepTools(server);
1385
1417
  registerAgentiaMcpHealthCheckTools(server);
@@ -1721,6 +1753,16 @@ export function registerAgentiaMcpTools(server) {
1721
1753
  },
1722
1754
  title: 'Agentia Navigation Resolve',
1723
1755
  }, (args) => safelyHandleTool(() => navigationResolve(args)));
1756
+ server.registerTool('agentia_notification_configure', {
1757
+ description: 'Configure one Slack notification subscription for the current user on a pipeline. Mirrors agentia cicd notification configure.',
1758
+ inputSchema: notificationConfigureSchema,
1759
+ title: 'Agentia Notification Configure',
1760
+ }, (args) => safelyHandleTool(() => notificationConfigure(args)));
1761
+ server.registerTool('agentia_notification_get', {
1762
+ description: 'List Slack notification subscriptions for the current user on a pipeline. Mirrors agentia cicd notification get.',
1763
+ inputSchema: notificationGetSchema,
1764
+ title: 'Agentia Notification Get',
1765
+ }, (args) => safelyHandleTool(() => notificationGet(args)));
1724
1766
  server.registerTool('agentia_project_default_get', {
1725
1767
  description: 'Show Agentia project default values for the current project or globally.',
1726
1768
  inputSchema: projectSelectorSchema,
@@ -6,18 +6,19 @@ import { reconcileWorkSetCredential, sanitizeWorkSetUserStory } from '../credent
6
6
  import { readDefaults, resolveDefaults, writeLastWorkSelection, } from '../defaults-store.js';
7
7
  import { checkoutFeatureBranch, fetchOriginBranch, fetchOriginBranchIfExists, listPendingChanges, } from '../git-worktree.js';
8
8
  import { listPaginationZodFields, mcpPaginatedListPayload } from '../list-pagination.js';
9
- import { LocalQualityGatesError, runLocalQualityGates } from '../local-quality-gates.js';
9
+ import { LocalQualityGatesError, parseQualityGatesEnvAssignments, runLocalQualityGates, } from '../local-quality-gates.js';
10
10
  import { FULL_METADATA_SELECTION_TYPES_HELP } from '../nested-metadata-registry.js';
11
11
  import { PROJECT_DEFAULT_KEYS } from '../project-defaults.js';
12
12
  import { performPromotionRun, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS, resolvePromotionIdForWorkItem, } from '../promotion-run.js';
13
13
  import { runWorkTestLocalQualityGates } from '../stock-quality-gates.js';
14
14
  import { getUserContext } from '../user-context.js';
15
15
  import { resolveWorkItemId } from '../work-active.js';
16
- import { DEFAULT_APEX_TEST_WAIT_MINUTES, parseApexTestClassNames, runWorkApexTests, validateApexTestWaitMinutes, } from '../work-apex-test.js';
17
- import { fetchUserStory } from '../work-get.js';
16
+ import { planWorkApexTestRun, recordWorkApexTestOutcome } from '../work-apex-test-failures.js';
17
+ import { DEFAULT_APEX_TEST_WAIT_MINUTES, parseApexTestClassNames, runWorkApexTests, skippedWorkApexTestResult, validateApexTestWaitMinutes, WorkApexTestError, } from '../work-apex-test.js';
18
18
  import { buildWorkCommitRequest, normalizeWorkCommitInput, performWorkCommit, resolveWorkCommitPlatformExperience, WORK_COMMIT_ACTIONS, WORK_COMMIT_CHANGES_HELP, WORK_COMMIT_DEFAULT_TIMEOUT_SECONDS, WORK_COMMIT_METADATA_CATEGORY_HELP, } from '../work-commit.js';
19
19
  import { buildWorkCreatePayload } from '../work-defaults.js';
20
20
  import { validateWorkMutationPayload, WORK_LONG_TEXT_MAX_LENGTH, WORK_SHORT_TEXT_MAX_LENGTH, } from '../work-flags.js';
21
+ import { fetchUserStory } from '../work-get.js';
21
22
  import { performWorkLocalCommit } from '../work-local-commit.js';
22
23
  import { reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../work-local-run-tests.js';
23
24
  import { capturingWorkPushHooks, performWorkPush, resolveActiveFeatureWorkItem, resolveWorkPushContext, resolveWorkPushNeed, } from '../work-push.js';
@@ -250,6 +251,7 @@ async function workPublish(args = {}) {
250
251
  const context = await resolveWorkPushContext();
251
252
  return performWorkPush({
252
253
  ...context,
254
+ dryRun: args.dryRun === true,
253
255
  ...(args.fullMetadata === undefined ? {} : { fullMetadata: args.fullMetadata }),
254
256
  hooks: capturingWorkPushHooks,
255
257
  ...(args.permissions === undefined ? {} : { permissions: args.permissions }),
@@ -379,13 +381,16 @@ async function workTest(args = {}) {
379
381
  if (args.cloud === true) {
380
382
  throw new Error('Cloud quality gates are not implemented yet. Pass local: true or omit cloud to run project-root quality gates.');
381
383
  }
384
+ parseQualityGatesEnvAssignments(args.env);
382
385
  let qualityGates;
383
386
  try {
384
387
  qualityGates = await runWorkTestLocalQualityGates({
385
388
  apexTestClasses: args.apexTestClasses,
389
+ env: args.env,
386
390
  onOutput() {
387
391
  // Capture output for the tool result/error; do not stream to the MCP stdio transport.
388
392
  },
393
+ rerunFailed: args.rerunFailedApexTests === true,
389
394
  });
390
395
  }
391
396
  catch (error) {
@@ -417,9 +422,26 @@ async function workTest(args = {}) {
417
422
  };
418
423
  }
419
424
  async function workTestApex(args) {
420
- const classNames = parseApexTestClassNames(assertRequired(args.apexTestClasses, 'apexTestClasses'));
425
+ const classNames = parseApexTestClassNames(args.apexTestClasses);
421
426
  const waitMinutes = validateApexTestWaitMinutes(args.wait ?? DEFAULT_APEX_TEST_WAIT_MINUTES);
422
- return runWorkApexTests({ classNames, waitMinutes });
427
+ const plan = await planWorkApexTestRun({
428
+ requestedClassNames: classNames,
429
+ rerunFailed: args.rerunFailedApexTests === true,
430
+ });
431
+ if (plan.kind === 'skip') {
432
+ return skippedWorkApexTestResult(waitMinutes);
433
+ }
434
+ try {
435
+ const result = await runWorkApexTests({ classNames: plan.classNames, waitMinutes });
436
+ await recordWorkApexTestOutcome({ failed: false, result, userStory: plan.userStory });
437
+ return result;
438
+ }
439
+ catch (error) {
440
+ if (error instanceof WorkApexTestError) {
441
+ await recordWorkApexTestOutcome({ failed: true, result: error.result, userStory: plan.userStory });
442
+ }
443
+ throw error;
444
+ }
423
445
  }
424
446
  function hasMcpSimpleCommitArgs(args) {
425
447
  return (args.action !== undefined ||
@@ -667,6 +689,10 @@ export function registerAgentiaMcpWorkTools(server) {
667
689
  title: 'Agentia Work Set',
668
690
  }, (args) => safelyHandleTool(() => workSet(args || {})));
669
691
  const workPublishInputSchema = {
692
+ dryRun: z
693
+ .boolean()
694
+ .optional()
695
+ .describe('Preview publish: run commit collection, Copado replacements, and nested metadata detection; return the changeListUpdate that would be registered; do not commit, push, lock, register, or sync the dev org branch. Restores dirtied tracked files afterward. Requires a clean tracked working tree.'),
670
696
  fullMetadata: z
671
697
  .string()
672
698
  .optional()
@@ -678,7 +704,7 @@ export function registerAgentiaMcpWorkTools(server) {
678
704
  skipNestedMetadataDetection: skipNestedMetadataDetectionSchema,
679
705
  };
680
706
  server.registerTool('agentia_work_publish', {
681
- description: 'Publish the current feature/<lastWorkItem> branch and register commits with Copado. Requires a clean working tree, lastBaseBranch, and lastDevOrgBranch from config.user.json. Applies Copado environment-variable then yaml replacements when needed (yaml `-b` is the feature branch, matching Copado Commit), commits both as a single follow-up commit, sends one headless push changeListUpdate list of Action:MetadataType:MetadataName corrections (lastPermissionSelected and the permissions argument plus the nested metadata of the changed profiles and permission sets as RetrieveOnly so Copado registers that metadata with the Retrieve Only commit action, lastFullMetadataSelected and the fullMetadata argument plus brand-new nested parent files as fullMetadata, the ignored nested parents as unchanged, the nested metadata the branch deleted as Del, and the remaining nested metadata as Add). The changed profiles and permission sets themselves are never sent as corrections, so they stay in the change list and deploy only the permissions their RetrieveOnly entries select; brand-new nested parent files are sent as fullMetadata instead. Merges the feature branch into the recorded dev org branch after headless push. Prefer this over agentia_work_push.',
707
+ description: 'Publish the current feature/<lastWorkItem> branch and register commits with Copado. Requires a clean working tree, lastBaseBranch, and lastDevOrgBranch from config.user.json. Applies Copado environment-variable then yaml replacements when needed (yaml `-b` is the feature branch, matching Copado Commit), commits both as a single follow-up commit, sends one headless push changeListUpdate list of Action:MetadataType:MetadataName corrections (lastPermissionSelected and the permissions argument plus the nested metadata of the changed profiles and permission sets as RetrieveOnly so Copado registers that metadata with the Retrieve Only commit action, lastFullMetadataSelected and the fullMetadata argument plus brand-new nested parent files as fullMetadata, the ignored nested parents as unchanged, the nested metadata the branch deleted as Del, and the remaining nested metadata as Add). The changed profiles and permission sets themselves are never sent as corrections, so they stay in the change list and deploy only the permissions their RetrieveOnly entries select; brand-new nested parent files are sent as fullMetadata instead. Merges the feature branch into the recorded dev org branch after headless push. With dryRun=true, previews replacements and changeListUpdate, restores dirtied tracked files, and skips commit/push/lock/register/dev-org sync. Prefer this over agentia_work_push.',
682
708
  inputSchema: workPublishInputSchema,
683
709
  title: 'Agentia Work Publish',
684
710
  }, (args) => safelyHandleTool(() => workPublish(args || {})));
@@ -790,7 +816,7 @@ export function registerAgentiaMcpWorkTools(server) {
790
816
  title: 'Agentia Work Submit',
791
817
  }, (args) => safelyHandleTool(() => workSubmit(args || {})));
792
818
  server.registerTool('agentia_work_test', {
793
- description: 'Run quality gates for the current work item. With local=true (the default when cloud is omitted), runs project-root .agentia_quality_gates.sh (macOS/Linux) or .agentia_quality_gates.cmd (Windows) when present. When no project script exists, warns and runs the stock Agentia setup sample from a temporary file. With cloud=true, runs remote Copado quality gates (not implemented yet).',
819
+ description: 'Run quality gates for the current work item. With local=true (the default when cloud is omitted), runs project-root .agentia_quality_gates.sh (macOS/Linux) or .agentia_quality_gates.cmd (Windows) when present. When no project script exists, warns and runs the stock Agentia setup sample from a temporary file. With cloud=true, runs remote Copado quality gates (not implemented yet). Optional env is an array of NAME=value strings injected into the quality-gate script environment (same as CLI -e/--env).',
794
820
  inputSchema: {
795
821
  apexTestClasses: z
796
822
  .string()
@@ -800,19 +826,32 @@ export function registerAgentiaMcpWorkTools(server) {
800
826
  .boolean()
801
827
  .optional()
802
828
  .describe('Run remote Copado quality gates (not implemented yet).'),
829
+ env: z
830
+ .array(z.string())
831
+ .optional()
832
+ .describe('Extra environment variables for the quality-gate script as NAME=value strings (same as CLI -e/--env). Applied before reserved AGENTIA_APEX_* variables.'),
803
833
  local: z
804
834
  .boolean()
805
835
  .optional()
806
836
  .describe('Run local project-root quality gates scripts. Used by default when cloud is omitted.'),
837
+ rerunFailedApexTests: z
838
+ .boolean()
839
+ .optional()
840
+ .describe('Pass AGENTIA_APEX_RERUN_FAILED=--rerun-failed-apex-tests to local quality gates so sample scripts forward that flag to work test apex.'),
807
841
  },
808
842
  title: 'Agentia Work Test',
809
843
  }, (args) => safelyHandleTool(() => workTest(args || {})));
810
844
  server.registerTool('agentia_work_test_apex', {
811
- description: 'Run specified Apex test classes via Salesforce CLI (`sf apex run test`) with code coverage. Usually run from project-root local quality gates (`.agentia_quality_gates.sh` / `.agentia_quality_gates.cmd`) when those scripts are configured. Returns the test-run summary when the run passes. Failed runs include failing tests with Message and StackTrace.',
845
+ description: 'Run specified Apex test classes via Salesforce CLI (`sf apex run test`) with code coverage. Usually run from project-root local quality gates (`.agentia_quality_gates.sh` / `.agentia_quality_gates.cmd`) when those scripts are configured. When apexTestClasses is omitted or empty, skips Salesforce CLI and returns skipped=true. Failed runs save `.agentia/apex.tests.<user-story>.json`; successful runs delete that file. rerunFailedApexTests runs the previously failed classes. Returns the test-run summary when the run passes. Failed runs include failing tests with Message and StackTrace.',
812
846
  inputSchema: {
813
847
  apexTestClasses: z
814
848
  .string()
815
- .describe('Comma-separated Apex test class names to run.'),
849
+ .optional()
850
+ .describe('Comma-separated Apex test class names to run. Omit or leave empty to skip without running Salesforce CLI.'),
851
+ rerunFailedApexTests: z
852
+ .boolean()
853
+ .optional()
854
+ .describe('Rerun Apex classes saved from the last failure for this user story. Combined with apexTestClasses, only matching failed classes run.'),
816
855
  wait: z
817
856
  .number()
818
857
  .int()
@@ -0,0 +1,10 @@
1
+ import {modules} from './runtime.js';
2
+ const NOTIFICATION_SYSTEM_PROPERTIES_ENDPOINT = modules["notifications-get.js"]["NOTIFICATION_SYSTEM_PROPERTIES_ENDPOINT"]
3
+ const NotificationGetUserUnavailableError = modules["notifications-get.js"]["NotificationGetUserUnavailableError"]
4
+ const formatNotificationSubscriptionsTable = modules["notifications-get.js"]["formatNotificationSubscriptionsTable"]
5
+ const getNotificationSubscriptions = modules["notifications-get.js"]["getNotificationSubscriptions"]
6
+ const notificationSystemPropertiesEndpoint = modules["notifications-get.js"]["notificationSystemPropertiesEndpoint"]
7
+ const notificationSystemPropertyApiName = modules["notifications-get.js"]["notificationSystemPropertyApiName"]
8
+ const parseStoredNotificationSubscriptions = modules["notifications-get.js"]["parseStoredNotificationSubscriptions"]
9
+ const subscriptionsFromSystemProperties = modules["notifications-get.js"]["subscriptionsFromSystemProperties"]
10
+ export {NOTIFICATION_SYSTEM_PROPERTIES_ENDPOINT, NotificationGetUserUnavailableError, formatNotificationSubscriptionsTable, getNotificationSubscriptions, notificationSystemPropertiesEndpoint, notificationSystemPropertyApiName, parseStoredNotificationSubscriptions, subscriptionsFromSystemProperties};
@@ -0,0 +1,3 @@
1
+ import {modules} from '../runtime.js';
2
+ const schedulePluginHostEvent = modules["plugin-host/event-log.js"]["schedulePluginHostEvent"]
3
+ export {schedulePluginHostEvent};