@copado/agentia-cli 1.3.0 → 1.5.0-rc.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.
- package/CHANGELOG.md +35 -0
- package/README.md +437 -428
- package/dist/commands/cicd/cloud/commit.js +4 -3
- package/dist/commands/cicd/cloud/promote.js +40 -18
- package/dist/commands/cicd/credential/list.js +2 -1
- package/dist/commands/cicd/environment/list.js +2 -1
- package/dist/commands/cicd/extension-configuration/list.js +2 -1
- package/dist/commands/cicd/function/list.js +10 -13
- package/dist/commands/cicd/job/list.js +2 -1
- package/dist/commands/cicd/job/result-file/get.js +11 -6
- package/dist/commands/cicd/pipeline/automation/list.js +2 -1
- package/dist/commands/cicd/pipeline/list.js +2 -1
- package/dist/commands/cicd/pipeline/quality-gate/list.js +2 -1
- package/dist/commands/cicd/project/list.js +2 -1
- package/dist/commands/cicd/promotion/list.js +2 -1
- package/dist/commands/cicd/promotion/status.js +29 -0
- package/dist/commands/cicd/repository/list.js +5 -8
- package/dist/commands/cicd/stage/list.js +2 -1
- package/dist/commands/cicd/template/list.js +9 -12
- package/dist/commands/cicd/work/delete.js +2 -2
- package/dist/commands/cicd/work/environment-sync.js +138 -62
- package/dist/commands/cicd/work/get.js +2 -2
- package/dist/commands/cicd/work/list.js +2 -1
- package/dist/commands/cicd/work/test/apex.js +18 -33
- package/dist/commands/cicd/work/test.js +114 -9
- package/dist/commands/cicd/work/update.js +2 -2
- package/dist/lib/defaults-store.js +3 -1
- package/dist/lib/function-list.js +3 -0
- package/dist/lib/git-worktree.js +4 -1
- package/dist/lib/job-get.js +2 -1
- package/dist/lib/job-types.js +2 -1
- package/dist/lib/list-pagination.js +6 -1
- package/dist/lib/local-quality-gates.js +4 -1
- package/dist/lib/mcp/result.js +18 -2
- package/dist/lib/mcp/testing-browser-tools.js +1 -16
- package/dist/lib/mcp/tool-annotations.js +0 -1
- package/dist/lib/mcp/tools.js +30 -25
- package/dist/lib/mcp/work-tools.js +100 -47
- package/dist/lib/promotion-run.js +3 -1
- package/dist/lib/promotion-status.js +12 -0
- package/dist/lib/quality-gates.js +13 -0
- package/dist/lib/repository-list.js +3 -0
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/stock-quality-gates.js +2 -1
- package/dist/lib/support-ai.js +1 -2
- package/dist/lib/template-list.js +3 -0
- package/dist/lib/testing-browser-operations.js +1 -2
- package/dist/lib/testing-browser-session.js +1 -2
- package/dist/lib/work-apex-test-failures.js +2 -1
- package/dist/lib/work-environment-sync-ready.js +7 -1
- package/dist/lib/work-environment-sync.js +8 -1
- package/dist/lib/work-local-run-tests.js +2 -1
- package/dist/lib/work-promote-deploy.js +3 -1
- package/dist/lib/work-types.js +3 -1
- package/oclif.manifest.json +151 -93
- package/package.json +1 -1
- package/templates/skills/agentia-ai/references/ai-agents.md +1 -1
- package/templates/skills/agentia-cicd/SKILL.md +4 -3
- package/templates/skills/agentia-cicd/references/jobs.md +3 -2
- package/templates/skills/agentia-cicd/references/promotions.md +16 -4
- package/templates/skills/agentia-cicd/references/work.md +25 -11
- package/templates/skills/agentia-testing/references/browser-testing.md +0 -1
- package/templates/skills/agentia-testing/references/tests.md +1 -1
- package/vendor/java/var-replace-command.jar +0 -0
- package/dist/commands/testing/browser/reports.js +0 -33
package/dist/lib/job-get.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {modules} from './runtime.js';
|
|
2
2
|
const fetchJob = modules["job-get.js"]["fetchJob"]
|
|
3
3
|
const fetchJobs = modules["job-get.js"]["fetchJobs"]
|
|
4
|
-
|
|
4
|
+
const resolveJobResultFileId = modules["job-get.js"]["resolveJobResultFileId"]
|
|
5
|
+
export {fetchJob, fetchJobs, resolveJobResultFileId};
|
package/dist/lib/job-types.js
CHANGED
|
@@ -23,4 +23,5 @@ const normalizeJobResultFiles = modules["job-types.js"]["normalizeJobResultFiles
|
|
|
23
23
|
const normalizeJobs = modules["job-types.js"]["normalizeJobs"]
|
|
24
24
|
const normalizeJobsListPage = modules["job-types.js"]["normalizeJobsListPage"]
|
|
25
25
|
const resolveJobStepForLog = modules["job-types.js"]["resolveJobStepForLog"]
|
|
26
|
-
|
|
26
|
+
const validateJobResultFileId = modules["job-types.js"]["validateJobResultFileId"]
|
|
27
|
+
export {JOB_LIST_PAGE_SIZE_MAX, JOB_LIST_PAGE_SIZE_MIN, decodeJobResultFileBase64, formatJobDetail, formatJobOperationResult, formatJobResultFileTable, formatJobTable, jobEndpoint, jobKillEndpoint, jobListEndpoint, jobPauseEndpoint, jobResultFileContentEndpoint, jobResultFilesEndpoint, jobResultLogEndpoint, jobResumeEndpoint, jobRunEndpoint, jobStepResultId, normalizeJob, normalizeJobOperation, normalizeJobResultFileContent, normalizeJobResultFiles, normalizeJobs, normalizeJobsListPage, resolveJobStepForLog, validateJobResultFileId};
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import {modules} from './runtime.js';
|
|
2
|
+
const EXPIRED_LIST_CURSOR_CATEGORY = modules["list-pagination.js"]["EXPIRED_LIST_CURSOR_CATEGORY"]
|
|
3
|
+
const EXPIRED_LIST_CURSOR_WARNING = modules["list-pagination.js"]["EXPIRED_LIST_CURSOR_WARNING"]
|
|
2
4
|
const LIST_PAGE_SIZE_MAX = modules["list-pagination.js"]["LIST_PAGE_SIZE_MAX"]
|
|
3
5
|
const LIST_PAGE_SIZE_MIN = modules["list-pagination.js"]["LIST_PAGE_SIZE_MIN"]
|
|
4
6
|
const appendListPaginationQueryParams = modules["list-pagination.js"]["appendListPaginationQueryParams"]
|
|
5
7
|
const buildListPaginationQuery = modules["list-pagination.js"]["buildListPaginationQuery"]
|
|
6
8
|
const buildPaginatedListResult = modules["list-pagination.js"]["buildPaginatedListResult"]
|
|
7
9
|
const displayListPagination = modules["list-pagination.js"]["displayListPagination"]
|
|
10
|
+
const emitPaginatedListWarnings = modules["list-pagination.js"]["emitPaginatedListWarnings"]
|
|
8
11
|
const formatListContinuationHint = modules["list-pagination.js"]["formatListContinuationHint"]
|
|
9
12
|
const formatListPageFooter = modules["list-pagination.js"]["formatListPageFooter"]
|
|
13
|
+
const isExpiredListCursorError = modules["list-pagination.js"]["isExpiredListCursorError"]
|
|
10
14
|
const listPaginationFlags = modules["list-pagination.js"]["listPaginationFlags"]
|
|
11
15
|
const listPaginationZodFields = modules["list-pagination.js"]["listPaginationZodFields"]
|
|
12
16
|
const mcpPaginatedListPayload = modules["list-pagination.js"]["mcpPaginatedListPayload"]
|
|
13
17
|
const paginatedResultFromNestedData = modules["list-pagination.js"]["paginatedResultFromNestedData"]
|
|
14
18
|
const paginatedResultFromPage = modules["list-pagination.js"]["paginatedResultFromPage"]
|
|
15
19
|
const pickCursorPageMeta = modules["list-pagination.js"]["pickCursorPageMeta"]
|
|
16
|
-
|
|
20
|
+
const withExpiredListCursorRetry = modules["list-pagination.js"]["withExpiredListCursorRetry"]
|
|
21
|
+
export {EXPIRED_LIST_CURSOR_CATEGORY, EXPIRED_LIST_CURSOR_WARNING, LIST_PAGE_SIZE_MAX, LIST_PAGE_SIZE_MIN, appendListPaginationQueryParams, buildListPaginationQuery, buildPaginatedListResult, displayListPagination, emitPaginatedListWarnings, formatListContinuationHint, formatListPageFooter, isExpiredListCursorError, listPaginationFlags, listPaginationZodFields, mcpPaginatedListPayload, paginatedResultFromNestedData, paginatedResultFromPage, pickCursorPageMeta, withExpiredListCursorRetry};
|
|
@@ -2,10 +2,13 @@ import {modules} from './runtime.js';
|
|
|
2
2
|
const AGENTIA_APEX_RERUN_FAILED_ENV = modules["local-quality-gates.js"]["AGENTIA_APEX_RERUN_FAILED_ENV"]
|
|
3
3
|
const AGENTIA_APEX_RERUN_FAILED_FLAG = modules["local-quality-gates.js"]["AGENTIA_APEX_RERUN_FAILED_FLAG"]
|
|
4
4
|
const AGENTIA_APEX_TEST_CLASSES_ENV = modules["local-quality-gates.js"]["AGENTIA_APEX_TEST_CLASSES_ENV"]
|
|
5
|
+
const AGENTIA_BASE_BRANCH_ENV = modules["local-quality-gates.js"]["AGENTIA_BASE_BRANCH_ENV"]
|
|
6
|
+
const AGENTIA_QUALITY_GATES_ACTIVE_ENV = modules["local-quality-gates.js"]["AGENTIA_QUALITY_GATES_ACTIVE_ENV"]
|
|
5
7
|
const LocalQualityGatesError = modules["local-quality-gates.js"]["LocalQualityGatesError"]
|
|
6
8
|
const QUALITY_GATES_SCRIPT_UNIX = modules["local-quality-gates.js"]["QUALITY_GATES_SCRIPT_UNIX"]
|
|
7
9
|
const QUALITY_GATES_SCRIPT_WINDOWS = modules["local-quality-gates.js"]["QUALITY_GATES_SCRIPT_WINDOWS"]
|
|
8
10
|
const buildQualityGatesCommand = modules["local-quality-gates.js"]["buildQualityGatesCommand"]
|
|
11
|
+
const isInsideQualityGatesScript = modules["local-quality-gates.js"]["isInsideQualityGatesScript"]
|
|
9
12
|
const parseQualityGatesEnvAssignments = modules["local-quality-gates.js"]["parseQualityGatesEnvAssignments"]
|
|
10
13
|
const qualityGatesScriptName = modules["local-quality-gates.js"]["qualityGatesScriptName"]
|
|
11
14
|
const resetLocalQualityGatesForTests = modules["local-quality-gates.js"]["resetLocalQualityGatesForTests"]
|
|
@@ -13,4 +16,4 @@ const resolveLocalQualityGatesScript = modules["local-quality-gates.js"]["resolv
|
|
|
13
16
|
const runLocalQualityGates = modules["local-quality-gates.js"]["runLocalQualityGates"]
|
|
14
17
|
const setLocalQualityGatesExistsSyncForTests = modules["local-quality-gates.js"]["setLocalQualityGatesExistsSyncForTests"]
|
|
15
18
|
const setLocalQualityGatesSpawnForTests = modules["local-quality-gates.js"]["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};
|
|
19
|
+
export {AGENTIA_APEX_RERUN_FAILED_ENV, AGENTIA_APEX_RERUN_FAILED_FLAG, AGENTIA_APEX_TEST_CLASSES_ENV, AGENTIA_BASE_BRANCH_ENV, AGENTIA_QUALITY_GATES_ACTIVE_ENV, LocalQualityGatesError, QUALITY_GATES_SCRIPT_UNIX, QUALITY_GATES_SCRIPT_WINDOWS, buildQualityGatesCommand, isInsideQualityGatesScript, parseQualityGatesEnvAssignments, qualityGatesScriptName, resetLocalQualityGatesForTests, resolveLocalQualityGatesScript, runLocalQualityGates, setLocalQualityGatesExistsSyncForTests, setLocalQualityGatesSpawnForTests};
|
package/dist/lib/mcp/result.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { runWithCicdConnectionOverride } from '../cicd-connection.js';
|
|
3
|
-
import { createTransactionId, runWithGatewayTransactionContext } from '../cicd-gateway.js';
|
|
3
|
+
import { createTransactionId, getGatewayTransactionOrigin, runWithGatewayTransactionContext } from '../cicd-gateway.js';
|
|
4
4
|
import { recordMcpToolHistory } from '../command-history.js';
|
|
5
|
+
import { publishIdeCommandCompleted } from '../ide-command-events.js';
|
|
5
6
|
import { mcpCommandIdFromToolName, mcpToolNameFromHandler } from './command-id.js';
|
|
6
7
|
import { redactErrorMessage, redactSecrets } from './redaction.js';
|
|
7
8
|
const require = createRequire(import.meta.url);
|
|
@@ -12,10 +13,15 @@ export function runWithMcpToolContext(toolName, fn, options = {}) {
|
|
|
12
13
|
const executionId = createTransactionId();
|
|
13
14
|
const commandId = mcpCommandIdFromToolName(toolName);
|
|
14
15
|
const startedAtMs = Date.now();
|
|
16
|
+
// Wrappers can nest; only the outermost call notifies the IDE.
|
|
17
|
+
const notifyIde = getGatewayTransactionOrigin() !== 'mcp';
|
|
15
18
|
return runWithGatewayTransactionContext({ origin: 'mcp', referer: commandId, transactionId }, async () => {
|
|
16
19
|
let error;
|
|
20
|
+
let toolFailed = false;
|
|
17
21
|
try {
|
|
18
|
-
|
|
22
|
+
const result = await runWithCicdConnectionOverride(options.cicdConnection, fn);
|
|
23
|
+
toolFailed = isMcpErrorResult(result);
|
|
24
|
+
return result;
|
|
19
25
|
}
|
|
20
26
|
catch (error_) {
|
|
21
27
|
error = error_;
|
|
@@ -30,9 +36,19 @@ export function runWithMcpToolContext(toolName, fn, options = {}) {
|
|
|
30
36
|
startedAtMs,
|
|
31
37
|
transactionId,
|
|
32
38
|
});
|
|
39
|
+
if (notifyIde) {
|
|
40
|
+
await publishIdeCommandCompleted({
|
|
41
|
+
cliVersion: packageJson.version,
|
|
42
|
+
commandId,
|
|
43
|
+
error: error ?? (toolFailed ? new Error('MCP tool failed') : undefined),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
33
46
|
}
|
|
34
47
|
});
|
|
35
48
|
}
|
|
49
|
+
function isMcpErrorResult(result) {
|
|
50
|
+
return typeof result === 'object' && result !== null && result.isError === true;
|
|
51
|
+
}
|
|
36
52
|
export function cicdConnectionFromToolArgs(args) {
|
|
37
53
|
const first = args[0];
|
|
38
54
|
if (first === null || typeof first !== 'object' || Array.isArray(first))
|
|
@@ -2,7 +2,7 @@ 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 { executeTestingLive, getTestingLiveHistory,
|
|
5
|
+
import { executeTestingLive, getTestingLiveHistory, getTestingLiveStatus, inspectTestingLive, saveTestingLiveScreenshot, setTestingLiveOptions, startTestingLive, stopTestingLive, } from '../testing-browser-operations.js';
|
|
6
6
|
import { assertTestingLiveStopConfirmed, normalizeTestingLiveExecuteSource, normalizeTestingLiveRecorderOptions, normalizeTestingLiveStartScreen, shapeTestingLiveHistoryResult, } from '../testing-browser-requests.js';
|
|
7
7
|
import { TESTING_LIVE_LIBRARIES } from '../testing-browser-types.js';
|
|
8
8
|
import { safelyHandleTool } from './result.js';
|
|
@@ -62,15 +62,6 @@ async function testingBrowserScreenshot(args) {
|
|
|
62
62
|
}),
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
async function testingBrowserReports(args) {
|
|
66
|
-
return {
|
|
67
|
-
result: await getTestingLiveReports({
|
|
68
|
-
jobId: args.job,
|
|
69
|
-
projectId: args.project,
|
|
70
|
-
sessionId: args.sessionId,
|
|
71
|
-
}),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
65
|
async function testingBrowserSetOptions(args) {
|
|
75
66
|
return {
|
|
76
67
|
result: await setTestingLiveOptions({
|
|
@@ -96,7 +87,6 @@ export const testingBrowserMcpHandlers = {
|
|
|
96
87
|
testingBrowserExecute,
|
|
97
88
|
testingBrowserHistory,
|
|
98
89
|
testingBrowserInspect,
|
|
99
|
-
testingBrowserReports,
|
|
100
90
|
testingBrowserScreenshot,
|
|
101
91
|
testingBrowserSetOptions,
|
|
102
92
|
testingBrowserStart,
|
|
@@ -167,11 +157,6 @@ export function registerTestingLiveMcpTools(server) {
|
|
|
167
157
|
inputSchema: liveSessionSchema,
|
|
168
158
|
title: 'Agentia Testing Browser Screenshot',
|
|
169
159
|
}, (args) => safelyHandleTool(() => testingBrowserScreenshot(args)));
|
|
170
|
-
server.registerTool('agentia_testing_browser_reports', {
|
|
171
|
-
description: 'List browser session report metadata.',
|
|
172
|
-
inputSchema: liveSessionSchema,
|
|
173
|
-
title: 'Agentia Testing Browser Reports',
|
|
174
|
-
}, (args) => safelyHandleTool(() => testingBrowserReports(args)));
|
|
175
160
|
server.registerTool('agentia_testing_browser_set_options', {
|
|
176
161
|
description: 'Set CRT browser recorder options.',
|
|
177
162
|
inputSchema: { recorder: liveRecorderOptionsSchema, ...liveSessionSchema },
|
|
@@ -205,7 +205,6 @@ const READ_TOOLS = [
|
|
|
205
205
|
'agentia_testing_job_schedule_get',
|
|
206
206
|
'agentia_testing_browser_history',
|
|
207
207
|
'agentia_testing_browser_inspect',
|
|
208
|
-
'agentia_testing_browser_reports',
|
|
209
208
|
'agentia_testing_browser_screenshot',
|
|
210
209
|
'agentia_testing_browser_status',
|
|
211
210
|
'agentia_testing_project_get',
|
package/dist/lib/mcp/tools.js
CHANGED
|
@@ -5,7 +5,6 @@ import { buildMetadataContentRequest } from '../../commands/cicd/metadata/conten
|
|
|
5
5
|
import { buildDependencyRequest, enrichDependencyResult, } from '../../commands/cicd/metadata/dependency/list.js';
|
|
6
6
|
import { buildMetadataCompareRequest } from '../../commands/cicd/metadata/index/compare.js';
|
|
7
7
|
import { buildMetadataIndexRequest } from '../../commands/cicd/metadata/list.js';
|
|
8
|
-
import { AI_METADATA_ACTIONS, buildAiMetadataToolRequest, callAiMetadataTool, } from '../metadata-explore.js';
|
|
9
8
|
import { assertRequired } from '../assert.js';
|
|
10
9
|
import { applyAuthSet, getAiAuthStatus, getCicdAuthStatus, getCrtAuthStatus } from '../auth-config.js';
|
|
11
10
|
import { CicdGateway } from '../cicd-gateway.js';
|
|
@@ -18,13 +17,14 @@ import { createEnvironmentCredential, listCredentials, resolveEnvironmentOrgType
|
|
|
18
17
|
import { buildCreatePayload, buildMutationPayload, ENVIRONMENT_STRING_VALIDATION_KEYS, validateNonEmptyStringFields, } from '../environment-flags.js';
|
|
19
18
|
import { fetchEnvironment, fetchEnvironments } from '../environment-get.js';
|
|
20
19
|
import { DEFAULT_ENVIRONMENT_PLATFORM, DEFAULT_ENVIRONMENT_TYPE, ENVIRONMENT_TYPES, environmentEndpoint, } from '../environment-types.js';
|
|
20
|
+
import { fetchFunctions } from '../function-list.js';
|
|
21
21
|
import { executeLocalFunctionRun } from '../function-local-run.js';
|
|
22
|
-
import { FUNCTION_LIST_TYPES, FUNCTION_RUNTIMES, functionEndpoint, functionResultEndpoint, functionResultLogEndpoint, functionRunEndpoint, functionsEndpoint, normalizeFunction, normalizeFunctionResultStatus, normalizeFunctionRunResult,
|
|
23
|
-
import { fetchJob, fetchJobs } from '../job-get.js';
|
|
24
|
-
import { fetchPromotionQueue, removePromotionQueueItems } from '../promotion-queue.js';
|
|
22
|
+
import { FUNCTION_LIST_TYPES, FUNCTION_RUNTIMES, functionEndpoint, functionResultEndpoint, functionResultLogEndpoint, functionRunEndpoint, functionsEndpoint, normalizeFunction, normalizeFunctionResultStatus, normalizeFunctionRunResult, normalizeFunctionUpsertPayload, } from '../function-types.js';
|
|
23
|
+
import { fetchJob, fetchJobs, resolveJobResultFileId } from '../job-get.js';
|
|
25
24
|
import { jobEndpoint, jobKillEndpoint, jobPauseEndpoint, jobResultFileContentEndpoint, jobResultFilesEndpoint, jobResultLogEndpoint, jobResumeEndpoint, jobRunEndpoint, normalizeJob, normalizeJobOperation, normalizeJobResultFileContent, normalizeJobResultFiles, resolveJobStepForLog, } from '../job-types.js';
|
|
26
25
|
import { listPaginationZodFields, mcpPaginatedListPayload } from '../list-pagination.js';
|
|
27
26
|
import { COMPARISON_MODES, CONTENT_SOURCES, contentResultToCompareSide, createUnifiedDiff, INDEX_SOURCES, MODULE_TYPES, ORDER_DIRECTIONS, PLATFORM_EXPERIENCES, RETRIEVE_MODES, sourceSideLabel, } from '../metadata-common.js';
|
|
27
|
+
import { AI_METADATA_ACTIONS, buildAiMetadataToolRequest, callAiMetadataTool, } from '../metadata-explore.js';
|
|
28
28
|
import { buildRefreshDeletedRequest, buildRefreshIndexRequest, refreshStatusEndpoint, resolveRefreshSourceFromEnv, } from '../metadata-refresh.js';
|
|
29
29
|
import { NAVIGATION_RESOURCE_TYPES, resolveNavigationTarget } from '../navigation.js';
|
|
30
30
|
import { configureNotification, NOTIFICATION_DESTINATION_TYPES, NOTIFICATION_EVENTS, NOTIFICATION_SUBSCRIPTIONS, withNotificationConfigureErrorTranslation, } from '../notifications-configure.js';
|
|
@@ -43,14 +43,18 @@ import { normalizeProject, projectEndpoint, projectsListEndpoint, } from '../pro
|
|
|
43
43
|
import { buildPromotionConflictResolutionRequest, normalizePromotionConflicts, PROMOTION_CONFLICT_MODES, promotionConflictContentEndpoint, promotionConflictResolveEndpoint, promotionConflictsEndpoint, promotionConflictUndoEndpoint, withPromotionConflictErrorTranslation, } from '../promotion-conflicts.js';
|
|
44
44
|
import { fetchPromotion, fetchPromotions } from '../promotion-get.js';
|
|
45
45
|
import { buildPromotionManualTaskUpdatePayload, PROMOTION_MANUAL_TASK_STATUSES, promotionManualTaskEndpoint, } from '../promotion-job-steps.js';
|
|
46
|
+
import { fetchPromotionQueue, removePromotionQueueItems } from '../promotion-queue.js';
|
|
46
47
|
import { performPromotionResume, performPromotionRun, PROMOTION_OPERATIONS, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS, } from '../promotion-run.js';
|
|
48
|
+
import { fetchPromotionStatus } from '../promotion-status.js';
|
|
47
49
|
import { REPOSITORY_STRING_VALIDATION_KEYS, validateNonEmptyStringFields as validateRepositoryNonEmptyStringFields, } from '../repository-flags.js';
|
|
48
|
-
import {
|
|
50
|
+
import { fetchRepositories } from '../repository-list.js';
|
|
51
|
+
import { normalizeRepository, normalizeRepositoryValidateResult, repositoriesEndpoint, REPOSITORY_PROVIDERS, REPOSITORY_SOURCE_FORMATS, repositoryEndpoint, repositoryHttpsAuthEndpoint, repositoryResetEndpoint, repositorySshAuthEndpoint, repositoryValidateEndpoint, } from '../repository-types.js';
|
|
49
52
|
import { buildStageMutationPayload, validateStagePayload } from '../stage-flags.js';
|
|
50
53
|
import { fetchStages } from '../stage-list.js';
|
|
51
54
|
import { normalizePipelineStageConnection, normalizeStage, pipelineStageConnectionEndpoint, pipelineStageConnectionsEndpoint, STAGE_META_STAGE_SUGGESTIONS, stageEndpoint, stagesEndpoint, } from '../stage-types.js';
|
|
52
55
|
import { buildTemplateDefaultsQuery } from '../template-flags.js';
|
|
53
|
-
import {
|
|
56
|
+
import { fetchTemplates } from '../template-list.js';
|
|
57
|
+
import { normalizeTemplate, normalizeTemplateUpsertPayload, TEMPLATE_LIST_TYPES, templateDefaultsEndpoint, templateEndpoint, } from '../template-types.js';
|
|
54
58
|
import { getUserContext } from '../user-context.js';
|
|
55
59
|
import { fetchUser } from '../user-get.js';
|
|
56
60
|
import { DEFAULT_USER_ID } from '../user-types.js';
|
|
@@ -83,6 +87,9 @@ async function promotionList(args = {}) {
|
|
|
83
87
|
async function promotionGet(args) {
|
|
84
88
|
return { promotion: await fetchPromotion(assertRequired(args.id, 'id')) };
|
|
85
89
|
}
|
|
90
|
+
async function promotionStatus(args) {
|
|
91
|
+
return { status: await fetchPromotionStatus(assertRequired(args.id, 'id')) };
|
|
92
|
+
}
|
|
86
93
|
async function promotionRun(args) {
|
|
87
94
|
const waitTimeout = args.waitTimeout ?? PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS;
|
|
88
95
|
if (!Number.isInteger(waitTimeout) || waitTimeout <= 0) {
|
|
@@ -512,11 +519,7 @@ async function projectList(args = {}) {
|
|
|
512
519
|
return mcpPaginatedListPayload('projects', await fetchProjects(args));
|
|
513
520
|
}
|
|
514
521
|
async function repositoryList(args = {}) {
|
|
515
|
-
|
|
516
|
-
endpoint: repositoriesEndpoint(args),
|
|
517
|
-
method: 'GET',
|
|
518
|
-
});
|
|
519
|
-
return mcpPaginatedListPayload('repositories', normalizeRepositoriesListPage(response));
|
|
522
|
+
return mcpPaginatedListPayload('repositories', await fetchRepositories(args));
|
|
520
523
|
}
|
|
521
524
|
async function repositoryGet(args) {
|
|
522
525
|
const response = await CicdGateway.call({
|
|
@@ -605,11 +608,7 @@ async function repositoryValidate(args) {
|
|
|
605
608
|
return { validation: normalizeRepositoryValidateResult(response) };
|
|
606
609
|
}
|
|
607
610
|
async function functionList(args = {}) {
|
|
608
|
-
|
|
609
|
-
endpoint: functionsEndpoint({ ...args, type: args.type ?? 'custom' }),
|
|
610
|
-
method: 'GET',
|
|
611
|
-
});
|
|
612
|
-
return mcpPaginatedListPayload('functions', normalizeFunctionsListPage(response));
|
|
611
|
+
return mcpPaginatedListPayload('functions', await fetchFunctions({ ...args, type: args.type ?? 'custom' }));
|
|
613
612
|
}
|
|
614
613
|
async function functionGet(args) {
|
|
615
614
|
const response = await CicdGateway.call({
|
|
@@ -655,11 +654,7 @@ async function functionDelete(args) {
|
|
|
655
654
|
return { apiName };
|
|
656
655
|
}
|
|
657
656
|
async function templateList(args = {}) {
|
|
658
|
-
|
|
659
|
-
endpoint: templatesEndpoint({ ...args, type: args.type ?? 'custom' }),
|
|
660
|
-
method: 'GET',
|
|
661
|
-
});
|
|
662
|
-
return mcpPaginatedListPayload('templates', normalizeTemplatesListPage(response));
|
|
657
|
+
return mcpPaginatedListPayload('templates', await fetchTemplates({ ...args, type: args.type ?? 'custom' }));
|
|
663
658
|
}
|
|
664
659
|
async function templateGet(args) {
|
|
665
660
|
const response = await CicdGateway.call({
|
|
@@ -1119,8 +1114,9 @@ async function jobResultFileList(args) {
|
|
|
1119
1114
|
}
|
|
1120
1115
|
async function jobResultFileGet(args) {
|
|
1121
1116
|
const resultId = assertRequired(args.resultId, 'resultId');
|
|
1117
|
+
const fileId = await resolveJobResultFileId(resultId, assertRequired(args.fileId, 'fileId'));
|
|
1122
1118
|
const response = await CicdGateway.call({
|
|
1123
|
-
endpoint: jobResultFileContentEndpoint(resultId,
|
|
1119
|
+
endpoint: jobResultFileContentEndpoint(resultId, fileId),
|
|
1124
1120
|
method: 'GET',
|
|
1125
1121
|
});
|
|
1126
1122
|
return { file: { ...normalizeJobResultFileContent(response), resultId } };
|
|
@@ -1321,8 +1317,6 @@ export const agentiaMcpToolHandlers = wrapMcpToolHandlers({
|
|
|
1321
1317
|
jobList,
|
|
1322
1318
|
jobLogGet,
|
|
1323
1319
|
jobPause,
|
|
1324
|
-
promotionQueueList,
|
|
1325
|
-
promotionQueueRemove,
|
|
1326
1320
|
jobResultFileGet,
|
|
1327
1321
|
jobResultFileList,
|
|
1328
1322
|
jobResume,
|
|
@@ -1366,6 +1360,8 @@ export const agentiaMcpToolHandlers = wrapMcpToolHandlers({
|
|
|
1366
1360
|
promotionGet,
|
|
1367
1361
|
promotionJobStepUpdate,
|
|
1368
1362
|
promotionList,
|
|
1363
|
+
promotionQueueList,
|
|
1364
|
+
promotionQueueRemove,
|
|
1369
1365
|
promotionRun,
|
|
1370
1366
|
repositoryCreate,
|
|
1371
1367
|
repositoryDelete,
|
|
@@ -1559,6 +1555,13 @@ export function registerAgentiaMcpTools(server) {
|
|
|
1559
1555
|
},
|
|
1560
1556
|
title: 'Agentia Promotion Get',
|
|
1561
1557
|
}, (args) => safelyHandleTool(() => promotionGet(args)));
|
|
1558
|
+
server.registerTool('agentia_promotion_status', {
|
|
1559
|
+
description: 'Get actionable Copado promotion status: user stories, current job step, queue summary, and Manual Task or queue action-needed. Prefer this when the user asks whether a promotion is blocked or what is running.',
|
|
1560
|
+
inputSchema: {
|
|
1561
|
+
id: z.string().describe('Copado promotion Id.'),
|
|
1562
|
+
},
|
|
1563
|
+
title: 'Agentia Promotion Status',
|
|
1564
|
+
}, (args) => safelyHandleTool(() => promotionStatus(args)));
|
|
1562
1565
|
server.registerTool('agentia_promotion_run', {
|
|
1563
1566
|
description: 'Preflight, start, and optionally wait for a Copado promotion. Can also resume an existing execution without starting a duplicate run.',
|
|
1564
1567
|
inputSchema: {
|
|
@@ -2079,7 +2082,9 @@ export function registerAgentiaMcpTools(server) {
|
|
|
2079
2082
|
server.registerTool('agentia_job_result_file_get', {
|
|
2080
2083
|
description: 'Get a File linked to a Copado job Result.',
|
|
2081
2084
|
inputSchema: {
|
|
2082
|
-
fileId: z
|
|
2085
|
+
fileId: z
|
|
2086
|
+
.string()
|
|
2087
|
+
.describe('fileId returned by result-file list (068...); contentDocumentId (069...) is resolved automatically'),
|
|
2083
2088
|
resultId: z.string().describe('Copado Result ID.'),
|
|
2084
2089
|
},
|
|
2085
2090
|
title: 'Agentia Job Result File Get',
|
|
@@ -9,20 +9,22 @@ import { listPaginationZodFields, mcpPaginatedListPayload } from '../list-pagina
|
|
|
9
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
|
-
import { performPromotionRun, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS,
|
|
13
|
-
import {
|
|
12
|
+
import { performPromotionRun, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS, PromotionRunValidationError, resolveOrCreatePromotionForWorkItem, } from '../promotion-run.js';
|
|
13
|
+
import { isApexOnlySelection, resolveQualityGateSelection } from '../quality-gates.js';
|
|
14
|
+
import { listLocalQualityGates, runWorkTestLocalQualityGates } from '../stock-quality-gates.js';
|
|
14
15
|
import { getUserContext } from '../user-context.js';
|
|
15
16
|
import { resolveWorkItemId } from '../work-active.js';
|
|
16
|
-
import {
|
|
17
|
-
import { DEFAULT_APEX_TEST_WAIT_MINUTES, parseApexTestClassNames,
|
|
17
|
+
import { executeWorkApexTestRun } from '../work-apex-test-failures.js';
|
|
18
|
+
import { DEFAULT_APEX_TEST_WAIT_MINUTES, parseApexTestClassNames, validateApexTestWaitMinutes, WorkApexTestError, } from '../work-apex-test.js';
|
|
18
19
|
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
20
|
import { buildWorkCreatePayload } from '../work-defaults.js';
|
|
20
21
|
import { normalizeWorkCustomFields, validateWorkMutationPayload, WORK_LONG_TEXT_MAX_LENGTH, WORK_SHORT_TEXT_MAX_LENGTH, } from '../work-flags.js';
|
|
21
22
|
import { fetchWorkItems, fetchWorkItemWithOptions } from '../work-get.js';
|
|
22
23
|
import { performWorkLocalCommit } from '../work-local-commit.js';
|
|
23
|
-
import { reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../work-local-run-tests.js';
|
|
24
|
+
import { reportApexGateRun, reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../work-local-run-tests.js';
|
|
24
25
|
import { capturingWorkPushHooks, performWorkPush, resolveActiveFeatureWorkItem, resolveWorkPushContext, resolveWorkPushNeed, uploadCapturedPublishLogsBestEffort, } from '../work-push.js';
|
|
25
26
|
import { performWorkSetNone } from '../work-set-none.js';
|
|
27
|
+
import { WorkPromoteValidationError } from '../work-promote.js';
|
|
26
28
|
import { isWorkSetWarning, parseWorkSetSelection, toWorkSetWarningResult, writeWorkSetWarningSelection, } from '../work-set-selection.js';
|
|
27
29
|
import { reportSubmitUserStoriesAheadBehind } from '../work-submit-ahead-behind.js';
|
|
28
30
|
import { waitForPendingCommitJobIfNeeded } from '../work-submit-wait.js';
|
|
@@ -403,11 +405,35 @@ async function workTest(args = {}) {
|
|
|
403
405
|
throw new Error('Cloud quality gates are not implemented yet. Pass local: true or omit cloud to run project-root quality gates.');
|
|
404
406
|
}
|
|
405
407
|
parseQualityGatesEnvAssignments(args.env);
|
|
408
|
+
const selection = resolveQualityGateSelection({ all: args.all, gates: args.gates });
|
|
409
|
+
if (args.listGates === true) {
|
|
410
|
+
const catalog = await listLocalQualityGates();
|
|
411
|
+
return { gates: catalog.gates, local: true, qualityGates: { ran: false, skipped: false } };
|
|
412
|
+
}
|
|
413
|
+
if (isApexOnlySelection(selection)) {
|
|
414
|
+
let apex;
|
|
415
|
+
try {
|
|
416
|
+
apex = await workTestApex({
|
|
417
|
+
apexTestClasses: args.apexTestClasses,
|
|
418
|
+
rerunFailedApexTests: args.rerunFailedApexTests,
|
|
419
|
+
wait: args.wait,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
if (error instanceof WorkApexTestError) {
|
|
424
|
+
await reportApexGateRunBestEffort(error.result, true);
|
|
425
|
+
}
|
|
426
|
+
throw error;
|
|
427
|
+
}
|
|
428
|
+
await reportApexGateRunBestEffort(apex, false);
|
|
429
|
+
return { apex, local: true, qualityGates: { ran: apex.skipped !== true, skipped: false } };
|
|
430
|
+
}
|
|
406
431
|
let qualityGates;
|
|
407
432
|
try {
|
|
408
433
|
qualityGates = await runWorkTestLocalQualityGates({
|
|
409
434
|
apexTestClasses: args.apexTestClasses,
|
|
410
435
|
env: args.env,
|
|
436
|
+
gates: selection.gates,
|
|
411
437
|
onOutput() {
|
|
412
438
|
// Capture output for the tool result/error; do not stream to the MCP stdio transport.
|
|
413
439
|
},
|
|
@@ -442,28 +468,22 @@ async function workTest(args = {}) {
|
|
|
442
468
|
qualityGates,
|
|
443
469
|
};
|
|
444
470
|
}
|
|
445
|
-
async function
|
|
446
|
-
const classNames = parseApexTestClassNames(args.apexTestClasses);
|
|
447
|
-
const waitMinutes = validateApexTestWaitMinutes(args.wait ?? DEFAULT_APEX_TEST_WAIT_MINUTES);
|
|
448
|
-
const plan = await planWorkApexTestRun({
|
|
449
|
-
requestedClassNames: classNames,
|
|
450
|
-
rerunFailed: args.rerunFailedApexTests === true,
|
|
451
|
-
});
|
|
452
|
-
if (plan.kind === 'skip') {
|
|
453
|
-
return skippedWorkApexTestResult(waitMinutes);
|
|
454
|
-
}
|
|
471
|
+
async function reportApexGateRunBestEffort(result, failed) {
|
|
455
472
|
try {
|
|
456
|
-
const
|
|
457
|
-
await
|
|
458
|
-
return result;
|
|
473
|
+
const { workItem } = await requireFeatureBranchWorkItem();
|
|
474
|
+
await reportApexGateRun({ failed, result, workItem });
|
|
459
475
|
}
|
|
460
|
-
catch
|
|
461
|
-
|
|
462
|
-
await recordWorkApexTestOutcome({ failed: true, result: error.result, userStory: plan.userStory });
|
|
463
|
-
}
|
|
464
|
-
throw error;
|
|
476
|
+
catch {
|
|
477
|
+
// Best-effort reporting; never mask the Apex outcome.
|
|
465
478
|
}
|
|
466
479
|
}
|
|
480
|
+
async function workTestApex(args) {
|
|
481
|
+
return executeWorkApexTestRun({
|
|
482
|
+
requestedClassNames: parseApexTestClassNames(args.apexTestClasses),
|
|
483
|
+
rerunFailed: args.rerunFailedApexTests === true,
|
|
484
|
+
waitMinutes: validateApexTestWaitMinutes(args.wait ?? DEFAULT_APEX_TEST_WAIT_MINUTES),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
467
487
|
function hasMcpSimpleCommitArgs(args) {
|
|
468
488
|
return (args.action !== undefined ||
|
|
469
489
|
args.metadataCategory !== undefined ||
|
|
@@ -579,21 +599,37 @@ async function cloudPromote(args = {}) {
|
|
|
579
599
|
throw new Error('waitTimeout must be a positive integer.');
|
|
580
600
|
}
|
|
581
601
|
const workItemId = await resolveWorkItemId(args.id);
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
602
|
+
let createdPromotion;
|
|
603
|
+
try {
|
|
604
|
+
const resolved = await resolveOrCreatePromotionForWorkItem(workItemId, args.promotionId);
|
|
605
|
+
createdPromotion = resolved.createdPromotion;
|
|
606
|
+
const promotionId = resolved.promotionId;
|
|
607
|
+
const result = await performPromotionRun({
|
|
608
|
+
deploymentStepIds: args.deploymentStepIds,
|
|
609
|
+
hooks: {
|
|
610
|
+
log() { },
|
|
611
|
+
withSpinner: async (_message, action) => action(),
|
|
612
|
+
},
|
|
613
|
+
ignoredMetadata: args.ignoredMetadata,
|
|
614
|
+
operation: args.deploy === true ? 'merge_and_deploy' : 'merge',
|
|
615
|
+
promotionId,
|
|
616
|
+
recreatePromotionBranch: args.recreatePromotionBranch,
|
|
617
|
+
timeoutSeconds: waitTimeout,
|
|
618
|
+
wait: args.wait ?? true,
|
|
619
|
+
});
|
|
620
|
+
return {
|
|
621
|
+
...result,
|
|
622
|
+
...(createdPromotion === undefined ? {} : { createdPromotion }),
|
|
623
|
+
workItemId,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
catch (error) {
|
|
627
|
+
// Map validation errors to plain Error messages for MCP clients.
|
|
628
|
+
if (error instanceof PromotionRunValidationError || error instanceof WorkPromoteValidationError) {
|
|
629
|
+
throw new Error(error.message);
|
|
630
|
+
}
|
|
631
|
+
throw error;
|
|
632
|
+
}
|
|
597
633
|
}
|
|
598
634
|
/** Compatibility alias of agentia_work_submit with done=true. Prefer agentia_work_submit({ done: true }). */
|
|
599
635
|
async function workDone(args = {}) {
|
|
@@ -646,7 +682,7 @@ const workMutationSchema = {
|
|
|
646
682
|
plannedPoints: z.number().int().optional().describe('Planned points.'),
|
|
647
683
|
priority: z.number().int().optional().describe('Priority.'),
|
|
648
684
|
project: z.string().optional().describe('Project ID.'),
|
|
649
|
-
recordType: z.string().optional().describe('Record type.'),
|
|
685
|
+
recordType: z.string().optional().describe('Record type DeveloperName.'),
|
|
650
686
|
releaseId: z.string().optional().describe('Release ID.'),
|
|
651
687
|
soThat: z.string().max(WORK_SHORT_TEXT_MAX_LENGTH).optional().describe('User story "so that" clause (maximum 255 characters).'),
|
|
652
688
|
sourceCredential: z.string().optional().describe('Source credential ID. When set, sourceEnvironment is sent as null so Salesforce assigns the environment from the credential.'),
|
|
@@ -686,7 +722,7 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
686
722
|
.boolean()
|
|
687
723
|
.optional()
|
|
688
724
|
.describe('When true, also include the Story committed metadata list as committedMetadata in the result.'),
|
|
689
|
-
id: z.string().optional().describe('User story Id. Defaults to the active work item from work set.'),
|
|
725
|
+
id: z.string().optional().describe('User story Id or name. Defaults to the active work item from work set.'),
|
|
690
726
|
},
|
|
691
727
|
title: 'Agentia Work Get',
|
|
692
728
|
}, (args) => safelyHandleTool(() => workGet(args || {})));
|
|
@@ -699,14 +735,14 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
699
735
|
description: 'Update a Copado user story by Id via the CICD gateway. Omit Id to use the active work item from work set.',
|
|
700
736
|
inputSchema: {
|
|
701
737
|
...workMutationSchema,
|
|
702
|
-
id: z.string().optional().describe('User story Id. Defaults to the active work item from work set.'),
|
|
738
|
+
id: z.string().optional().describe('User story Id or name. Defaults to the active work item from work set.'),
|
|
703
739
|
},
|
|
704
740
|
title: 'Agentia Work Update',
|
|
705
741
|
}, (args) => safelyHandleTool(() => workUpdate(args)));
|
|
706
742
|
server.registerTool('agentia_work_delete', {
|
|
707
743
|
description: 'Delete a Copado user story by Id via the CICD gateway.',
|
|
708
744
|
inputSchema: {
|
|
709
|
-
id: z.string().describe('User story Id.'),
|
|
745
|
+
id: z.string().describe('User story Id or name.'),
|
|
710
746
|
},
|
|
711
747
|
title: 'Agentia Work Delete',
|
|
712
748
|
}, (args) => safelyHandleTool(() => workDelete(args)));
|
|
@@ -799,7 +835,7 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
799
835
|
promotionId: z
|
|
800
836
|
.string()
|
|
801
837
|
.optional()
|
|
802
|
-
.describe('Explicit 18-character Promotion ID when the User Story belongs to multiple promotions.'),
|
|
838
|
+
.describe('Explicit 18-character Promotion ID when the User Story belongs to multiple promotions. Used as is; never creates a promotion.'),
|
|
803
839
|
recreatePromotionBranch: z.boolean().optional().describe('Recreate the promotion branch before execution.'),
|
|
804
840
|
wait: z.boolean().optional().describe('Poll all created executions to terminal status. Defaults to true.'),
|
|
805
841
|
waitTimeout: z
|
|
@@ -825,7 +861,7 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
825
861
|
title: 'Agentia Work Commit',
|
|
826
862
|
}, (args) => safelyHandleTool(() => workCommit(args || {})));
|
|
827
863
|
server.registerTool('agentia_cloud_promote', {
|
|
828
|
-
description: 'Resolve a Promotion from an explicit or active User Story, then preflight, start, and optionally wait for the cloud promotion.',
|
|
864
|
+
description: 'Resolve a Promotion from an explicit or active User Story, then preflight, start, and optionally wait for the cloud promotion. When no promotion contains the story, creates a forward Draft promotion, adds the story, then runs. Returns createdPromotion when a promotion was created. promotionId is used as is and never creates a promotion.',
|
|
829
865
|
inputSchema: cloudPromoteInputSchema,
|
|
830
866
|
title: 'Agentia Cloud Promote',
|
|
831
867
|
}, (args) => safelyHandleTool(() => cloudPromote(args || {})));
|
|
@@ -853,8 +889,12 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
853
889
|
title: 'Agentia Work Submit',
|
|
854
890
|
}, (args) => safelyHandleTool(() => workSubmit(args || {})));
|
|
855
891
|
server.registerTool('agentia_work_test', {
|
|
856
|
-
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).',
|
|
892
|
+
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). By default every gate runs; pass gates to run a subset (scripts declare gates with `# agentia-gate: <id> - <description>`) or listGates to list them. Optional env is an array of NAME=value strings injected into the quality-gate script environment (same as CLI -e/--env).',
|
|
857
893
|
inputSchema: {
|
|
894
|
+
all: z
|
|
895
|
+
.boolean()
|
|
896
|
+
.optional()
|
|
897
|
+
.describe('Run every gate in the quality-gates script (default when gates is omitted). Mutually exclusive with gates.'),
|
|
858
898
|
apexTestClasses: z
|
|
859
899
|
.string()
|
|
860
900
|
.optional()
|
|
@@ -867,6 +907,14 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
867
907
|
.array(z.string())
|
|
868
908
|
.optional()
|
|
869
909
|
.describe('Extra environment variables for the quality-gate script as NAME=value strings (same as CLI -e/--env). Applied before reserved AGENTIA_APEX_* variables.'),
|
|
910
|
+
gates: z
|
|
911
|
+
.array(z.string())
|
|
912
|
+
.optional()
|
|
913
|
+
.describe('Run only these gate ids (standard: apex, lint, lwc; or custom ids declared in the script). Exported as AGENTIA_GATES. Only ["apex"] skips the script and runs the Apex tests directly.'),
|
|
914
|
+
listGates: z
|
|
915
|
+
.boolean()
|
|
916
|
+
.optional()
|
|
917
|
+
.describe('List the gates declared in the quality-gates script (or the stock sample) and return without running anything.'),
|
|
870
918
|
local: z
|
|
871
919
|
.boolean()
|
|
872
920
|
.optional()
|
|
@@ -874,12 +922,17 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
874
922
|
rerunFailedApexTests: z
|
|
875
923
|
.boolean()
|
|
876
924
|
.optional()
|
|
877
|
-
.describe('Pass AGENTIA_APEX_RERUN_FAILED=--rerun-failed-apex-tests to local quality gates so sample scripts forward that flag to
|
|
925
|
+
.describe('Pass AGENTIA_APEX_RERUN_FAILED=--rerun-failed-apex-tests to local quality gates so sample scripts forward that flag to the apex gate.'),
|
|
926
|
+
wait: z
|
|
927
|
+
.number()
|
|
928
|
+
.int()
|
|
929
|
+
.optional()
|
|
930
|
+
.describe(`Minutes to wait for Apex test results when gates is ["apex"]. Defaults to ${DEFAULT_APEX_TEST_WAIT_MINUTES}.`),
|
|
878
931
|
},
|
|
879
932
|
title: 'Agentia Work Test',
|
|
880
933
|
}, (args) => safelyHandleTool(() => workTest(args || {})));
|
|
881
934
|
server.registerTool('agentia_work_test_apex', {
|
|
882
|
-
description: 'Run specified Apex test classes via Salesforce CLI (`sf apex run test`) with code coverage.
|
|
935
|
+
description: 'Run specified Apex test classes via Salesforce CLI (`sf apex run test`) with code coverage. Equivalent to agentia_work_test with gates ["apex"]. 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.',
|
|
883
936
|
inputSchema: {
|
|
884
937
|
apexTestClasses: z
|
|
885
938
|
.string()
|
|
@@ -23,6 +23,8 @@ const promotionRunErrorJson = modules["promotion-run.js"]["promotionRunErrorJson
|
|
|
23
23
|
const promotionValidateResolutionEndpoint = modules["promotion-run.js"]["promotionValidateResolutionEndpoint"]
|
|
24
24
|
const requirePromotionId = modules["promotion-run.js"]["requirePromotionId"]
|
|
25
25
|
const resetPromotionRunSleepForTests = modules["promotion-run.js"]["resetPromotionRunSleepForTests"]
|
|
26
|
+
const resolveOrCreatePromotionForWorkItem = modules["promotion-run.js"]["resolveOrCreatePromotionForWorkItem"]
|
|
26
27
|
const resolvePromotionIdForWorkItem = modules["promotion-run.js"]["resolvePromotionIdForWorkItem"]
|
|
27
28
|
const setPromotionRunSleepForTests = modules["promotion-run.js"]["setPromotionRunSleepForTests"]
|
|
28
|
-
|
|
29
|
+
const waitForPromotionDeploymentExecution = modules["promotion-run.js"]["waitForPromotionDeploymentExecution"]
|
|
30
|
+
export {NoPromotionForUserStoryError, PROMOTION_OPERATIONS, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS, PromotionRunIncompleteResponseError, PromotionRunJobFailedError, PromotionRunTimeoutError, PromotionRunValidationError, assertPromotionContextReady, formatPromotionRunResult, isPromotionRunExecutionError, parseIgnoredMetadataJson, performPromotionResume, performPromotionRun, promotionContextEndpoint, promotionDeploymentStepsEndpoint, promotionIgnoredMetadataEndpoint, promotionJobMonitorEndpoint, promotionResumeEndpoint, promotionRunDetailEndpoint, promotionRunEndpoint, promotionRunErrorJson, promotionValidateResolutionEndpoint, requirePromotionId, resetPromotionRunSleepForTests, resolveOrCreatePromotionForWorkItem, resolvePromotionIdForWorkItem, setPromotionRunSleepForTests, waitForPromotionDeploymentExecution};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {modules} from './runtime.js';
|
|
2
|
+
const buildPromotionActionNeeded = modules["promotion-status.js"]["buildPromotionActionNeeded"]
|
|
3
|
+
const buildPromotionStatusSnapshot = modules["promotion-status.js"]["buildPromotionStatusSnapshot"]
|
|
4
|
+
const fetchPromotionStatus = modules["promotion-status.js"]["fetchPromotionStatus"]
|
|
5
|
+
const formatPromotionStatus = modules["promotion-status.js"]["formatPromotionStatus"]
|
|
6
|
+
const isManualTaskStep = modules["promotion-status.js"]["isManualTaskStep"]
|
|
7
|
+
const isPendingManualTaskStep = modules["promotion-status.js"]["isPendingManualTaskStep"]
|
|
8
|
+
const pickCurrentJobStep = modules["promotion-status.js"]["pickCurrentJobStep"]
|
|
9
|
+
const pickPendingManualTaskStep = modules["promotion-status.js"]["pickPendingManualTaskStep"]
|
|
10
|
+
const resolvePromotionStatusJobId = modules["promotion-status.js"]["resolvePromotionStatusJobId"]
|
|
11
|
+
const toPromotionStatusStep = modules["promotion-status.js"]["toPromotionStatusStep"]
|
|
12
|
+
export {buildPromotionActionNeeded, buildPromotionStatusSnapshot, fetchPromotionStatus, formatPromotionStatus, isManualTaskStep, isPendingManualTaskStep, pickCurrentJobStep, pickPendingManualTaskStep, resolvePromotionStatusJobId, toPromotionStatusStep};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {modules} from './runtime.js';
|
|
2
|
+
const AGENTIA_GATES_ALL = modules["quality-gates.js"]["AGENTIA_GATES_ALL"]
|
|
3
|
+
const AGENTIA_GATES_ENV = modules["quality-gates.js"]["AGENTIA_GATES_ENV"]
|
|
4
|
+
const APEX_QUALITY_GATE_ID = modules["quality-gates.js"]["APEX_QUALITY_GATE_ID"]
|
|
5
|
+
const STANDARD_QUALITY_GATE_IDS = modules["quality-gates.js"]["STANDARD_QUALITY_GATE_IDS"]
|
|
6
|
+
const UnknownQualityGateError = modules["quality-gates.js"]["UnknownQualityGateError"]
|
|
7
|
+
const formatDeclaredQualityGates = modules["quality-gates.js"]["formatDeclaredQualityGates"]
|
|
8
|
+
const isApexOnlySelection = modules["quality-gates.js"]["isApexOnlySelection"]
|
|
9
|
+
const parseDeclaredQualityGates = modules["quality-gates.js"]["parseDeclaredQualityGates"]
|
|
10
|
+
const parseQualityGateIds = modules["quality-gates.js"]["parseQualityGateIds"]
|
|
11
|
+
const qualityGatesEnvValue = modules["quality-gates.js"]["qualityGatesEnvValue"]
|
|
12
|
+
const resolveQualityGateSelection = modules["quality-gates.js"]["resolveQualityGateSelection"]
|
|
13
|
+
export {AGENTIA_GATES_ALL, AGENTIA_GATES_ENV, APEX_QUALITY_GATE_ID, STANDARD_QUALITY_GATE_IDS, UnknownQualityGateError, formatDeclaredQualityGates, isApexOnlySelection, parseDeclaredQualityGates, parseQualityGateIds, qualityGatesEnvValue, resolveQualityGateSelection};
|