@copado/agentia-cli 1.0.0-beta.2 → 1.0.0-beta.5
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 +55 -0
- package/README.md +416 -293
- package/dist/commands/cicd/data/template/save-detail.js +2 -2
- package/dist/commands/cicd/repository/auth/https/configure.js +21 -0
- package/dist/commands/cicd/repository/auth/oauth/login.js +56 -0
- package/dist/commands/cicd/repository/auth/setup.js +28 -0
- package/dist/commands/cicd/repository/auth/ssh/configure.js +22 -0
- package/dist/commands/cicd/repository/create.js +2 -2
- package/dist/commands/cicd/repository/reset.js +17 -5
- package/dist/commands/cicd/repository/update.js +6 -14
- package/dist/commands/cicd/work/environment-sync.js +66 -61
- package/dist/commands/cicd/work/get.js +5 -9
- package/dist/commands/cicd/work/submit.js +1 -1
- package/dist/commands/cicd/work/test/apex.js +37 -4
- package/dist/commands/cicd/work/test.js +20 -1
- package/dist/commands/runtime.js +26 -0
- package/dist/hooks/finally/ide-command-event.js +1 -1
- package/dist/hooks/init/plugin-host.js +6 -0
- package/dist/lib/agentia-command.js +16 -0
- package/dist/lib/cicd-gateway.js +2 -1
- package/dist/lib/cursor-mcp-config.js +3 -1
- package/dist/lib/data-types.js +3 -1
- package/dist/lib/git-worktree.js +2 -1
- package/dist/lib/local-quality-gates.js +4 -1
- package/dist/lib/mcp/data-tools.js +2 -2
- package/dist/lib/mcp/server.js +33 -7
- package/dist/lib/mcp/tool-annotations.js +3 -0
- package/dist/lib/mcp/tools.js +55 -12
- package/dist/lib/mcp/work-tools.js +44 -13
- package/dist/lib/plugin-host/auth.js +4 -0
- package/dist/lib/plugin-host/event-log.js +3 -0
- package/dist/lib/plugin-host/format.js +3 -0
- package/dist/lib/plugin-host/index.js +7 -0
- package/dist/lib/plugin-host/organization.js +4 -0
- package/dist/lib/plugin-host/projection-utils.js +6 -0
- package/dist/lib/plugin-host/registry.js +6 -0
- package/dist/lib/plugin-host/request-scope.js +4 -0
- package/dist/lib/plugin-host/work.js +4 -0
- package/dist/lib/project-root.js +3 -1
- package/dist/lib/repository-auth.js +8 -0
- package/dist/lib/repository-flags.js +2 -2
- package/dist/lib/repository-types.js +6 -1
- package/dist/lib/repository-url-prefill.js +4 -0
- package/dist/lib/runtime-invoke-context.js +6 -0
- package/dist/lib/runtime-rpc.js +14 -0
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/setup-templates.js +2 -1
- package/dist/lib/work-apex-test-failures.js +13 -0
- package/dist/lib/work-apex-test.js +4 -1
- package/dist/lib/work-environment-sync.js +1 -2
- package/dist/lib/work-get.js +3 -0
- package/oclif.manifest.json +315 -174
- package/package.json +4 -3
- package/templates/skills/agentia-cicd/SKILL.md +1 -1
- package/templates/skills/agentia-cicd/references/work.md +2 -2
|
@@ -3,6 +3,7 @@ import { format } from 'node:util';
|
|
|
3
3
|
import { createTransactionId, runWithGatewayTransactionContext } from './cicd-gateway.js';
|
|
4
4
|
import { isCommandOutputCaptureActive } from './command-output-buffer.js';
|
|
5
5
|
import { rememberIdeCommandError } from './ide-command-events.js';
|
|
6
|
+
const TRANSACTION_ID_REPORTED = Symbol('agentiaTransactionIdReported');
|
|
6
7
|
export function elapsedSecondsSince(startedAtMs, nowMs = Date.now()) {
|
|
7
8
|
return Math.max(0, Math.floor((nowMs - startedAtMs) / 1000));
|
|
8
9
|
}
|
|
@@ -17,6 +18,10 @@ export class AgentiaCommand extends Command {
|
|
|
17
18
|
this.commandTransactionId = transactionId;
|
|
18
19
|
return runWithGatewayTransactionContext({ origin: 'cli', referer: this.id, transactionId }, () => super._run());
|
|
19
20
|
}
|
|
21
|
+
async catch(error) {
|
|
22
|
+
this.reportHumanErrorTransactionId(error);
|
|
23
|
+
return super.catch(error);
|
|
24
|
+
}
|
|
20
25
|
display(render) {
|
|
21
26
|
if (!this.jsonEnabled() || isCommandOutputCaptureActive()) {
|
|
22
27
|
render();
|
|
@@ -64,5 +69,16 @@ export class AgentiaCommand extends Command {
|
|
|
64
69
|
throw error;
|
|
65
70
|
}
|
|
66
71
|
}
|
|
72
|
+
reportHumanErrorTransactionId(error) {
|
|
73
|
+
if (this.jsonEnabled() || this.commandTransactionId === undefined) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const reportedError = error;
|
|
77
|
+
if (reportedError[TRANSACTION_ID_REPORTED]) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
reportedError[TRANSACTION_ID_REPORTED] = true;
|
|
81
|
+
this.logToStderr(`Transaction ID: ${this.commandTransactionId}`);
|
|
82
|
+
}
|
|
67
83
|
}
|
|
68
84
|
//# sourceMappingURL=agentia-command.js.map
|
package/dist/lib/cicd-gateway.js
CHANGED
|
@@ -9,6 +9,7 @@ const CicdGatewayError = modules["cicd-gateway.js"]["CicdGatewayError"]
|
|
|
9
9
|
const GATEWAY_EVENT_API_CALL = modules["cicd-gateway.js"]["GATEWAY_EVENT_API_CALL"]
|
|
10
10
|
const GATEWAY_EVENT_UNKNOWN = modules["cicd-gateway.js"]["GATEWAY_EVENT_UNKNOWN"]
|
|
11
11
|
const MCP_CICD_DEFAULT_REQUEST_TIMEOUT_MS = modules["cicd-gateway.js"]["MCP_CICD_DEFAULT_REQUEST_TIMEOUT_MS"]
|
|
12
|
+
const PLUGIN_GATEWAY_EVENT_SERVICE = modules["cicd-gateway.js"]["PLUGIN_GATEWAY_EVENT_SERVICE"]
|
|
12
13
|
const buildGatewayEventLogPayload = modules["cicd-gateway.js"]["buildGatewayEventLogPayload"]
|
|
13
14
|
const cicdApiUrl = modules["cicd-gateway.js"]["cicdApiUrl"]
|
|
14
15
|
const createTransactionId = modules["cicd-gateway.js"]["createTransactionId"]
|
|
@@ -40,4 +41,4 @@ const scheduleGatewayEventLog = modules["cicd-gateway.js"]["scheduleGatewayEvent
|
|
|
40
41
|
const setGatewayEventLogSenderForTests = modules["cicd-gateway.js"]["setGatewayEventLogSenderForTests"]
|
|
41
42
|
const setHttpRequestForTests = modules["cicd-gateway.js"]["setHttpRequestForTests"]
|
|
42
43
|
const tryResolveCicdCredentials = modules["cicd-gateway.js"]["tryResolveCicdCredentials"]
|
|
43
|
-
export {AGENTIA_CLIENT_ORIGIN_ENV, AGENTIA_IDE_VERSION_ENV, AI_GATEWAY_EVENT_SERVICE, CICD_ENV, CRT_GATEWAY_EVENT_SERVICE, CicdGateway, CicdGatewayError, GATEWAY_EVENT_API_CALL, GATEWAY_EVENT_UNKNOWN, MCP_CICD_DEFAULT_REQUEST_TIMEOUT_MS, buildGatewayEventLogPayload, cicdApiUrl, createTransactionId, discoverCicdBaseUrl, flushGatewayEventLogsForTests, formatCicdGatewayError, formatGatewayEventTimestamp, gatewayEventSource, gatewayRefererHeaders, gatewayUserAgent, getActiveHttpRequestOptionsForTests, getGatewayClientOrigin, getGatewayReferer, getGatewayTransactionId, isCicdWarningResponseBody, isCicdWarningStatus, maskUrlSecrets, maskedCicdApiUrl, normalizeCicdBaseUrl, parseRetryAfterHeader, resetGatewayEventLogSenderForTests, resetHttpRequestForTests, resolveAndValidateCicdEndpoint, resolveCicdCredentials, resolveCicdRequestTimeoutMs, resolveConfiguredCicdBaseUrl, runWithGatewayTransactionContext, scheduleGatewayEventLog, setGatewayEventLogSenderForTests, setHttpRequestForTests, tryResolveCicdCredentials};
|
|
44
|
+
export {AGENTIA_CLIENT_ORIGIN_ENV, AGENTIA_IDE_VERSION_ENV, AI_GATEWAY_EVENT_SERVICE, CICD_ENV, CRT_GATEWAY_EVENT_SERVICE, CicdGateway, CicdGatewayError, GATEWAY_EVENT_API_CALL, GATEWAY_EVENT_UNKNOWN, MCP_CICD_DEFAULT_REQUEST_TIMEOUT_MS, PLUGIN_GATEWAY_EVENT_SERVICE, buildGatewayEventLogPayload, cicdApiUrl, createTransactionId, discoverCicdBaseUrl, flushGatewayEventLogsForTests, formatCicdGatewayError, formatGatewayEventTimestamp, gatewayEventSource, gatewayRefererHeaders, gatewayUserAgent, getActiveHttpRequestOptionsForTests, getGatewayClientOrigin, getGatewayReferer, getGatewayTransactionId, isCicdWarningResponseBody, isCicdWarningStatus, maskUrlSecrets, maskedCicdApiUrl, normalizeCicdBaseUrl, parseRetryAfterHeader, resetGatewayEventLogSenderForTests, resetHttpRequestForTests, resolveAndValidateCicdEndpoint, resolveCicdCredentials, resolveCicdRequestTimeoutMs, resolveConfiguredCicdBaseUrl, runWithGatewayTransactionContext, scheduleGatewayEventLog, setGatewayEventLogSenderForTests, setHttpRequestForTests, tryResolveCicdCredentials};
|
|
@@ -3,14 +3,16 @@ const AGENTIA_MCP_ENTRY = modules["cursor-mcp-config.js"]["AGENTIA_MCP_ENTRY"]
|
|
|
3
3
|
const AGENTIA_MCP_SERVER_NAME = modules["cursor-mcp-config.js"]["AGENTIA_MCP_SERVER_NAME"]
|
|
4
4
|
const detectCursorInstall = modules["cursor-mcp-config.js"]["detectCursorInstall"]
|
|
5
5
|
const findAgentiaMcpServer = modules["cursor-mcp-config.js"]["findAgentiaMcpServer"]
|
|
6
|
+
const findCurrentAgentiaMcpServer = modules["cursor-mcp-config.js"]["findCurrentAgentiaMcpServer"]
|
|
6
7
|
const getCursorMcpStatus = modules["cursor-mcp-config.js"]["getCursorMcpStatus"]
|
|
7
8
|
const globalCursorMcpPath = modules["cursor-mcp-config.js"]["globalCursorMcpPath"]
|
|
8
9
|
const hasConflictingAgentiaEntry = modules["cursor-mcp-config.js"]["hasConflictingAgentiaEntry"]
|
|
9
10
|
const inspectCursorMcpStatus = modules["cursor-mcp-config.js"]["inspectCursorMcpStatus"]
|
|
10
11
|
const isAgentiaMcpEntry = modules["cursor-mcp-config.js"]["isAgentiaMcpEntry"]
|
|
12
|
+
const isCurrentAgentiaMcpEntry = modules["cursor-mcp-config.js"]["isCurrentAgentiaMcpEntry"]
|
|
11
13
|
const localCursorMcpPath = modules["cursor-mcp-config.js"]["localCursorMcpPath"]
|
|
12
14
|
const readCursorMcpDocument = modules["cursor-mcp-config.js"]["readCursorMcpDocument"]
|
|
13
15
|
const resetCursorMcpDepsForTests = modules["cursor-mcp-config.js"]["resetCursorMcpDepsForTests"]
|
|
14
16
|
const setCursorMcpDepsForTests = modules["cursor-mcp-config.js"]["setCursorMcpDepsForTests"]
|
|
15
17
|
const upsertAgentiaCursorMcp = modules["cursor-mcp-config.js"]["upsertAgentiaCursorMcp"]
|
|
16
|
-
export {AGENTIA_MCP_ENTRY, AGENTIA_MCP_SERVER_NAME, detectCursorInstall, findAgentiaMcpServer, getCursorMcpStatus, globalCursorMcpPath, hasConflictingAgentiaEntry, inspectCursorMcpStatus, isAgentiaMcpEntry, localCursorMcpPath, readCursorMcpDocument, resetCursorMcpDepsForTests, setCursorMcpDepsForTests, upsertAgentiaCursorMcp};
|
|
18
|
+
export {AGENTIA_MCP_ENTRY, AGENTIA_MCP_SERVER_NAME, detectCursorInstall, findAgentiaMcpServer, findCurrentAgentiaMcpServer, getCursorMcpStatus, globalCursorMcpPath, hasConflictingAgentiaEntry, inspectCursorMcpStatus, isAgentiaMcpEntry, isCurrentAgentiaMcpEntry, localCursorMcpPath, readCursorMcpDocument, resetCursorMcpDepsForTests, setCursorMcpDepsForTests, upsertAgentiaCursorMcp};
|
package/dist/lib/data-types.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {modules} from './runtime.js';
|
|
2
2
|
const DATA_TEMPLATES_BASE = modules["data-types.js"]["DATA_TEMPLATES_BASE"]
|
|
3
|
+
const DEFAULT_DATA_TEMPLATE_QUERY_LIMIT = modules["data-types.js"]["DEFAULT_DATA_TEMPLATE_QUERY_LIMIT"]
|
|
3
4
|
const advancedFilterEndpoint = modules["data-types.js"]["advancedFilterEndpoint"]
|
|
4
5
|
const advancedFiltersEndpoint = modules["data-types.js"]["advancedFiltersEndpoint"]
|
|
5
6
|
const dataTemplateConvertOldEndpoint = modules["data-types.js"]["dataTemplateConvertOldEndpoint"]
|
|
@@ -21,10 +22,11 @@ const formatDatasetFileTable = modules["data-types.js"]["formatDatasetFileTable"
|
|
|
21
22
|
const formatRecordMatchingFormulaTable = modules["data-types.js"]["formatRecordMatchingFormulaTable"]
|
|
22
23
|
const formatSyncResultTable = modules["data-types.js"]["formatSyncResultTable"]
|
|
23
24
|
const formatUserStoryDataCommitTable = modules["data-types.js"]["formatUserStoryDataCommitTable"]
|
|
25
|
+
const normalizeDataTemplateSavePayload = modules["data-types.js"]["normalizeDataTemplateSavePayload"]
|
|
24
26
|
const normalizeDataTemplates = modules["data-types.js"]["normalizeDataTemplates"]
|
|
25
27
|
const recordMatchingFormulaEndpoint = modules["data-types.js"]["recordMatchingFormulaEndpoint"]
|
|
26
28
|
const recordMatchingFormulasByObjectEndpoint = modules["data-types.js"]["recordMatchingFormulasByObjectEndpoint"]
|
|
27
29
|
const sobjectFieldsEndpoint = modules["data-types.js"]["sobjectFieldsEndpoint"]
|
|
28
30
|
const sobjectRelationshipsEndpoint = modules["data-types.js"]["sobjectRelationshipsEndpoint"]
|
|
29
31
|
const userStoryDataCommitsEndpoint = modules["data-types.js"]["userStoryDataCommitsEndpoint"]
|
|
30
|
-
export {DATA_TEMPLATES_BASE, advancedFilterEndpoint, advancedFiltersEndpoint, dataTemplateConvertOldEndpoint, dataTemplateDetailEndpoint, dataTemplateEndpoint, dataTemplateRecordMatchingFormulasEndpoint, dataTemplateUpdatesEndpoint, dataTemplatesCommitEndpoint, dataTemplatesListEndpoint, dataTemplatesRecordsEndpoint, dataTemplatesRecordsMatchEndpoint, dataTemplatesSyncEndpoint, datasetFileContentEndpoint, datasetFilesEndpoint, formatAdvancedFilterTable, formatDataRecordTable, formatDataTemplateTable, formatDatasetFileTable, formatRecordMatchingFormulaTable, formatSyncResultTable, formatUserStoryDataCommitTable, normalizeDataTemplates, recordMatchingFormulaEndpoint, recordMatchingFormulasByObjectEndpoint, sobjectFieldsEndpoint, sobjectRelationshipsEndpoint, userStoryDataCommitsEndpoint};
|
|
32
|
+
export {DATA_TEMPLATES_BASE, DEFAULT_DATA_TEMPLATE_QUERY_LIMIT, advancedFilterEndpoint, advancedFiltersEndpoint, dataTemplateConvertOldEndpoint, dataTemplateDetailEndpoint, dataTemplateEndpoint, dataTemplateRecordMatchingFormulasEndpoint, dataTemplateUpdatesEndpoint, dataTemplatesCommitEndpoint, dataTemplatesListEndpoint, dataTemplatesRecordsEndpoint, dataTemplatesRecordsMatchEndpoint, dataTemplatesSyncEndpoint, datasetFileContentEndpoint, datasetFilesEndpoint, formatAdvancedFilterTable, formatDataRecordTable, formatDataTemplateTable, formatDatasetFileTable, formatRecordMatchingFormulaTable, formatSyncResultTable, formatUserStoryDataCommitTable, normalizeDataTemplateSavePayload, normalizeDataTemplates, recordMatchingFormulaEndpoint, recordMatchingFormulasByObjectEndpoint, sobjectFieldsEndpoint, sobjectRelationshipsEndpoint, userStoryDataCommitsEndpoint};
|
package/dist/lib/git-worktree.js
CHANGED
|
@@ -13,6 +13,7 @@ const createAndCheckoutBranch = modules["git-worktree.js"]["createAndCheckoutBra
|
|
|
13
13
|
const fetchAndCheckoutBranch = modules["git-worktree.js"]["fetchAndCheckoutBranch"]
|
|
14
14
|
const fetchOriginBranch = modules["git-worktree.js"]["fetchOriginBranch"]
|
|
15
15
|
const fetchOriginBranchIfExists = modules["git-worktree.js"]["fetchOriginBranchIfExists"]
|
|
16
|
+
const formatGitExecError = modules["git-worktree.js"]["formatGitExecError"]
|
|
16
17
|
const getCommitsNameStatus = modules["git-worktree.js"]["getCommitsNameStatus"]
|
|
17
18
|
const getCurrentBranch = modules["git-worktree.js"]["getCurrentBranch"]
|
|
18
19
|
const getFileAtRef = modules["git-worktree.js"]["getFileAtRef"]
|
|
@@ -48,4 +49,4 @@ const restoreFeatureBranch = modules["git-worktree.js"]["restoreFeatureBranch"]
|
|
|
48
49
|
const restoreHeadPaths = modules["git-worktree.js"]["restoreHeadPaths"]
|
|
49
50
|
const setGitExecForTests = modules["git-worktree.js"]["setGitExecForTests"]
|
|
50
51
|
const stageAndCommit = modules["git-worktree.js"]["stageAndCommit"]
|
|
51
|
-
export {NAME_STATUS_PRETTY_FORMAT, abortMerge, checkoutBranch, checkoutFeatureBranch, checkoutPreferredBranch, commitAllTrackedChanges, commitAllowEmpty, commitCurrentMerge, commitStagedChanges, countCommitsSince, createAndCheckoutBranch, fetchAndCheckoutBranch, fetchOriginBranch, fetchOriginBranchIfExists, getCommitsNameStatus, getCurrentBranch, getFileAtRef, getGitRepoRoot, getHeadCommitId, getHumanGitStatus, getMergeBase, getRemoteUrl, hasUnpushedCommits, isAncestor, isInsideGitWorkTree, isMergeInProgress, isSafeGitBranchName, listDiffNamesVsHead, listPendingChanges, listStagedChanges, listUnmergedFiles, localBranchExists, mergeFfOnly, mergeNoFf, mergeNoFfNoCommit, mergeTheirsIgnoreSpaceChange, originBranchRef, originFetchRefspec, parseNameOnly, parsePorcelainPaths, pullOriginBranch, pushOriginBranch, pushOriginBranches, resetGitExecForTests, resetHardHead, restoreFeatureBranch, restoreHeadPaths, setGitExecForTests, stageAndCommit};
|
|
52
|
+
export {NAME_STATUS_PRETTY_FORMAT, abortMerge, checkoutBranch, checkoutFeatureBranch, checkoutPreferredBranch, commitAllTrackedChanges, commitAllowEmpty, commitCurrentMerge, commitStagedChanges, countCommitsSince, createAndCheckoutBranch, fetchAndCheckoutBranch, fetchOriginBranch, fetchOriginBranchIfExists, formatGitExecError, getCommitsNameStatus, getCurrentBranch, getFileAtRef, getGitRepoRoot, getHeadCommitId, getHumanGitStatus, getMergeBase, getRemoteUrl, hasUnpushedCommits, isAncestor, isInsideGitWorkTree, isMergeInProgress, isSafeGitBranchName, listDiffNamesVsHead, listPendingChanges, listStagedChanges, listUnmergedFiles, localBranchExists, mergeFfOnly, mergeNoFf, mergeNoFfNoCommit, mergeTheirsIgnoreSpaceChange, originBranchRef, originFetchRefspec, parseNameOnly, parsePorcelainPaths, pullOriginBranch, pushOriginBranch, pushOriginBranches, resetGitExecForTests, resetHardHead, restoreFeatureBranch, restoreHeadPaths, setGitExecForTests, stageAndCommit};
|
|
@@ -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};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { assertRequired } from '../assert.js';
|
|
3
3
|
import { CicdGateway } from '../cicd-gateway.js';
|
|
4
|
-
import { advancedFilterEndpoint, advancedFiltersEndpoint, DATA_TEMPLATES_BASE, datasetFileContentEndpoint, datasetFilesEndpoint, dataTemplateConvertOldEndpoint, dataTemplateDetailEndpoint, dataTemplateEndpoint, dataTemplateRecordMatchingFormulasEndpoint, dataTemplatesCommitEndpoint, dataTemplatesListEndpoint, dataTemplatesRecordsEndpoint, dataTemplatesRecordsMatchEndpoint, dataTemplatesSyncEndpoint, dataTemplateUpdatesEndpoint, normalizeDataTemplates, recordMatchingFormulaEndpoint, recordMatchingFormulasByObjectEndpoint, sobjectFieldsEndpoint, sobjectRelationshipsEndpoint, userStoryDataCommitsEndpoint, } from '../data-types.js';
|
|
4
|
+
import { advancedFilterEndpoint, advancedFiltersEndpoint, DATA_TEMPLATES_BASE, datasetFileContentEndpoint, datasetFilesEndpoint, dataTemplateConvertOldEndpoint, dataTemplateDetailEndpoint, dataTemplateEndpoint, dataTemplateRecordMatchingFormulasEndpoint, dataTemplatesCommitEndpoint, dataTemplatesListEndpoint, dataTemplatesRecordsEndpoint, dataTemplatesRecordsMatchEndpoint, dataTemplatesSyncEndpoint, dataTemplateUpdatesEndpoint, normalizeDataTemplateSavePayload, normalizeDataTemplates, recordMatchingFormulaEndpoint, recordMatchingFormulasByObjectEndpoint, sobjectFieldsEndpoint, sobjectRelationshipsEndpoint, userStoryDataCommitsEndpoint, } from '../data-types.js';
|
|
5
5
|
import { safelyHandleTool } from './result.js';
|
|
6
6
|
async function dataTemplateList(args = {}) {
|
|
7
7
|
const response = await CicdGateway.call({
|
|
@@ -55,7 +55,7 @@ async function dataTemplateSaveDetail(args) {
|
|
|
55
55
|
throw new Error('Requires `body`.');
|
|
56
56
|
}
|
|
57
57
|
const result = await CicdGateway.call({
|
|
58
|
-
body: args.body,
|
|
58
|
+
body: normalizeDataTemplateSavePayload(args.body),
|
|
59
59
|
endpoint: dataTemplateDetailEndpoint(id),
|
|
60
60
|
headers: { 'Content-Type': 'application/json' },
|
|
61
61
|
method: 'PUT',
|
package/dist/lib/mcp/server.js
CHANGED
|
@@ -3,19 +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
9
|
import { withToolAnnotations } from './tool-annotations.js';
|
|
10
10
|
import { registerAgentiaMcpTools } from './tools.js';
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
12
12
|
const packageJson = require('../../../package.json');
|
|
13
|
-
export function createAgentiaMcpServer(lifecycleSignal) {
|
|
13
|
+
export function createAgentiaMcpServer(lifecycleSignal, projectContextReady = Promise.resolve()) {
|
|
14
14
|
const server = new McpServer({
|
|
15
15
|
name: packageJson.name ?? 'agentia-cli',
|
|
16
16
|
version: packageJson.version,
|
|
17
17
|
});
|
|
18
|
-
wrapMcpToolRegistration(server, lifecycleSignal);
|
|
18
|
+
wrapMcpToolRegistration(server, lifecycleSignal, projectContextReady);
|
|
19
19
|
registerAgentiaMcpTools(server);
|
|
20
20
|
return server;
|
|
21
21
|
}
|
|
@@ -42,13 +42,14 @@ function combineSignals(requestSignal, lifecycleSignal) {
|
|
|
42
42
|
signal: controller.signal,
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
-
function wrapMcpToolRegistration(server, lifecycleSignal) {
|
|
45
|
+
function wrapMcpToolRegistration(server, lifecycleSignal, projectContextReady = Promise.resolve()) {
|
|
46
46
|
const registerTool = server.registerTool.bind(server);
|
|
47
47
|
server.registerTool = ((name, config, handler) => registerTool(name, withToolAnnotations(name, config), (...args) => {
|
|
48
48
|
const extra = args.at(-1);
|
|
49
49
|
const { dispose, signal } = combineSignals(extra?.signal, lifecycleSignal);
|
|
50
50
|
return runWithMcpRequestSignal(signal, async () => {
|
|
51
51
|
try {
|
|
52
|
+
await projectContextReady;
|
|
52
53
|
return await runWithMcpToolContext(name, async () => handler(...args));
|
|
53
54
|
}
|
|
54
55
|
finally {
|
|
@@ -57,13 +58,38 @@ function wrapMcpToolRegistration(server, lifecycleSignal) {
|
|
|
57
58
|
});
|
|
58
59
|
}));
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
-
|
|
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);
|
|
62
67
|
await migrateUserSettingsFromProjectConfig().catch(() => {
|
|
63
68
|
// Best-effort; MCP tools still fall back to reading legacy project keys.
|
|
64
69
|
});
|
|
70
|
+
}
|
|
71
|
+
export async function startAgentiaMcpServer(transport = new StdioServerTransport()) {
|
|
65
72
|
const lifecycle = new AbortController();
|
|
66
|
-
|
|
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
|
+
}
|
|
67
93
|
let closing = false;
|
|
68
94
|
const close = async () => {
|
|
69
95
|
if (closing)
|
|
@@ -128,6 +128,7 @@ const READ_TOOLS = [
|
|
|
128
128
|
'agentia_function_list',
|
|
129
129
|
'agentia_function_result_get',
|
|
130
130
|
'agentia_function_result_log_get',
|
|
131
|
+
'agentia_health_check',
|
|
131
132
|
'agentia_job_get',
|
|
132
133
|
'agentia_job_list',
|
|
133
134
|
'agentia_job_log_get',
|
|
@@ -212,6 +213,8 @@ const UPDATE_TOOLS = [
|
|
|
212
213
|
'agentia_promotion_conflict_unresolve',
|
|
213
214
|
'agentia_promotion_job_step_update',
|
|
214
215
|
'agentia_repository_update',
|
|
216
|
+
'agentia_repository_auth_https',
|
|
217
|
+
'agentia_repository_auth_ssh',
|
|
215
218
|
'agentia_stage_update',
|
|
216
219
|
'agentia_testing_data_table_update',
|
|
217
220
|
'agentia_testing_job_schedule_set',
|
package/dist/lib/mcp/tools.js
CHANGED
|
@@ -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,
|
|
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';
|
|
@@ -561,17 +561,12 @@ async function repositoryUpdate(args) {
|
|
|
561
561
|
if (Object.keys(explicitPayload).length === 0) {
|
|
562
562
|
throw new Error('Must provide at least one field to update.');
|
|
563
563
|
}
|
|
564
|
-
const
|
|
565
|
-
endpoint: repositoryEndpoint(id),
|
|
566
|
-
method: 'GET',
|
|
567
|
-
});
|
|
568
|
-
const payload = withRequiredRepositoryFields(explicitPayload, normalizeRepository(currentResponse));
|
|
569
|
-
const validationError = validateRepositoryPayload(payload);
|
|
564
|
+
const validationError = validateRepositoryMutationPayload(explicitPayload);
|
|
570
565
|
if (validationError !== undefined) {
|
|
571
566
|
throw new Error(validationError);
|
|
572
567
|
}
|
|
573
568
|
const response = await CicdGateway.call({
|
|
574
|
-
body:
|
|
569
|
+
body: explicitPayload,
|
|
575
570
|
endpoint: repositoryEndpoint(id),
|
|
576
571
|
headers: {
|
|
577
572
|
'Content-Type': 'application/json',
|
|
@@ -580,6 +575,26 @@ async function repositoryUpdate(args) {
|
|
|
580
575
|
});
|
|
581
576
|
return { repository: normalizeRepository(response) };
|
|
582
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
|
+
}
|
|
583
598
|
async function repositoryDelete(args) {
|
|
584
599
|
const id = assertRequired(args.id, 'id');
|
|
585
600
|
await CicdGateway.call({
|
|
@@ -765,6 +780,9 @@ function validateRepositoryPayload(payload) {
|
|
|
765
780
|
}
|
|
766
781
|
return undefined;
|
|
767
782
|
}
|
|
783
|
+
function validateRepositoryMutationPayload(payload) {
|
|
784
|
+
return validateRepositoryNonEmptyStringFields(payload, REPOSITORY_STRING_VALIDATION_KEYS);
|
|
785
|
+
}
|
|
768
786
|
async function userGet(args = {}) {
|
|
769
787
|
const user = await CicdGateway.call({
|
|
770
788
|
endpoint: userEndpoint(resolveUserId(args.id)),
|
|
@@ -1334,18 +1352,14 @@ const pipelineConnectionMutationSchema = {
|
|
|
1334
1352
|
};
|
|
1335
1353
|
const repositoryMutationSchema = {
|
|
1336
1354
|
allowFunctionsGitCache: z.boolean().optional().describe('Allow Functions Git cache for this repository.'),
|
|
1337
|
-
authType: z.enum(REPOSITORY_AUTH_TYPES).optional().describe('Repository authentication type.'),
|
|
1338
1355
|
branchBaseUrl: z.string().nullable().optional().describe('Base URL for repository branch links.'),
|
|
1339
1356
|
commitBaseUrl: z.string().nullable().optional().describe('Base URL for repository commit links.'),
|
|
1340
|
-
extraHeaders: z.string().nullable().optional().describe('Additional authentication headers.'),
|
|
1341
1357
|
isCopadoTunnelEnabled: z.boolean().optional().describe('Enable Copado tunnel for this repository.'),
|
|
1342
|
-
password: z.string().nullable().optional().describe('Repository password or token. Sensitive input.'),
|
|
1343
1358
|
provider: z.enum(REPOSITORY_PROVIDERS).optional().describe('Git repository provider.'),
|
|
1344
1359
|
pullRequestBaseUrl: z.string().nullable().optional().describe('Base URL for repository pull request links.'),
|
|
1345
1360
|
sourceFormat: z.enum(REPOSITORY_SOURCE_FORMATS).optional().describe('Git repository source format.'),
|
|
1346
1361
|
tagBaseUrl: z.string().nullable().optional().describe('Base URL for repository tag links.'),
|
|
1347
1362
|
uri: z.string().nullable().optional().describe('Repository clone URI.'),
|
|
1348
|
-
username: z.string().nullable().optional().describe('Repository username.'),
|
|
1349
1363
|
};
|
|
1350
1364
|
const promotionListSchema = {
|
|
1351
1365
|
createdById: z.string().optional().describe('Filter by creator ID.'),
|
|
@@ -1955,6 +1969,35 @@ export function registerAgentiaMcpTools(server) {
|
|
|
1955
1969
|
},
|
|
1956
1970
|
title: 'Agentia Repository Update',
|
|
1957
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)));
|
|
1958
2001
|
server.registerTool('agentia_repository_delete', {
|
|
1959
2002
|
description: 'Delete a Copado Git repository by ID via the CICD gateway.',
|
|
1960
2003
|
inputSchema: { id: z.string().describe('Copado Git repository ID.') },
|
|
@@ -6,17 +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 {
|
|
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';
|
|
17
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';
|
|
18
19
|
import { buildWorkCreatePayload } from '../work-defaults.js';
|
|
19
20
|
import { validateWorkMutationPayload, WORK_LONG_TEXT_MAX_LENGTH, WORK_SHORT_TEXT_MAX_LENGTH, } from '../work-flags.js';
|
|
21
|
+
import { fetchUserStory } from '../work-get.js';
|
|
20
22
|
import { performWorkLocalCommit } from '../work-local-commit.js';
|
|
21
23
|
import { reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../work-local-run-tests.js';
|
|
22
24
|
import { capturingWorkPushHooks, performWorkPush, resolveActiveFeatureWorkItem, resolveWorkPushContext, resolveWorkPushNeed, } from '../work-push.js';
|
|
@@ -128,11 +130,7 @@ async function workList(args = {}) {
|
|
|
128
130
|
return mcpPaginatedListPayload('userStories', normalizeUserStoriesListPage(response));
|
|
129
131
|
}
|
|
130
132
|
async function workGet(args = {}) {
|
|
131
|
-
const
|
|
132
|
-
const userStory = await CicdGateway.call({
|
|
133
|
-
endpoint: workEndpoint(workItemId),
|
|
134
|
-
method: 'GET',
|
|
135
|
-
});
|
|
133
|
+
const userStory = await fetchUserStory(args.id);
|
|
136
134
|
return { userStory };
|
|
137
135
|
}
|
|
138
136
|
async function workCreate(args = {}) {
|
|
@@ -382,13 +380,16 @@ async function workTest(args = {}) {
|
|
|
382
380
|
if (args.cloud === true) {
|
|
383
381
|
throw new Error('Cloud quality gates are not implemented yet. Pass local: true or omit cloud to run project-root quality gates.');
|
|
384
382
|
}
|
|
383
|
+
parseQualityGatesEnvAssignments(args.env);
|
|
385
384
|
let qualityGates;
|
|
386
385
|
try {
|
|
387
386
|
qualityGates = await runWorkTestLocalQualityGates({
|
|
388
387
|
apexTestClasses: args.apexTestClasses,
|
|
388
|
+
env: args.env,
|
|
389
389
|
onOutput() {
|
|
390
390
|
// Capture output for the tool result/error; do not stream to the MCP stdio transport.
|
|
391
391
|
},
|
|
392
|
+
rerunFailed: args.rerunFailedApexTests === true,
|
|
392
393
|
});
|
|
393
394
|
}
|
|
394
395
|
catch (error) {
|
|
@@ -420,9 +421,26 @@ async function workTest(args = {}) {
|
|
|
420
421
|
};
|
|
421
422
|
}
|
|
422
423
|
async function workTestApex(args) {
|
|
423
|
-
const classNames = parseApexTestClassNames(
|
|
424
|
+
const classNames = parseApexTestClassNames(args.apexTestClasses);
|
|
424
425
|
const waitMinutes = validateApexTestWaitMinutes(args.wait ?? DEFAULT_APEX_TEST_WAIT_MINUTES);
|
|
425
|
-
|
|
426
|
+
const plan = await planWorkApexTestRun({
|
|
427
|
+
requestedClassNames: classNames,
|
|
428
|
+
rerunFailed: args.rerunFailedApexTests === true,
|
|
429
|
+
});
|
|
430
|
+
if (plan.kind === 'skip') {
|
|
431
|
+
return skippedWorkApexTestResult(waitMinutes);
|
|
432
|
+
}
|
|
433
|
+
try {
|
|
434
|
+
const result = await runWorkApexTests({ classNames: plan.classNames, waitMinutes });
|
|
435
|
+
await recordWorkApexTestOutcome({ failed: false, result, userStory: plan.userStory });
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
if (error instanceof WorkApexTestError) {
|
|
440
|
+
await recordWorkApexTestOutcome({ failed: true, result: error.result, userStory: plan.userStory });
|
|
441
|
+
}
|
|
442
|
+
throw error;
|
|
443
|
+
}
|
|
426
444
|
}
|
|
427
445
|
function hasMcpSimpleCommitArgs(args) {
|
|
428
446
|
return (args.action !== undefined ||
|
|
@@ -770,7 +788,7 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
770
788
|
title: 'Agentia Cloud Promote',
|
|
771
789
|
}, (args) => safelyHandleTool(() => cloudPromote(args || {})));
|
|
772
790
|
server.registerTool('agentia_work_submit', {
|
|
773
|
-
description: 'Submit the current feature/US-XXXX work item for pipeline quality gates and validation. Runs project-root .agentia_quality_gates.sh (macOS/Linux) or .agentia_quality_gates.cmd (Windows) when present, then fetches origin/<lastBaseBranch> and counts origin/<lastBaseBranch>..HEAD before checking origin. Pushes and registers commits when that feature-only range is non-empty and the branch is ahead of origin. When the last pending related job template name contains Commit, waits up to 5 minutes for that job before calling headless work/submit. Before submit or promote, counts user stories ahead and behind between the source environment and the next pipeline environment, and warns when stories behind might cause promotion conflicts. With done=true or deploy=true, matches Copado UI Submit when promoting (headless work/done) and uses the same commit wait. Prefer this over agentia_work_done.',
|
|
791
|
+
description: 'Submit the current feature/US-XXXX work item for pipeline quality gates and validation. Runs project-root .agentia_quality_gates.sh (macOS/Linux) or .agentia_quality_gates.cmd (Windows) when present, then fetches origin/<lastBaseBranch> and counts origin/<lastBaseBranch>..HEAD before checking origin. Pushes and registers commits when that feature-only range is non-empty and the branch is ahead of origin. When the last pending related job template name contains Commit, waits up to 5 minutes for that job before calling headless work/submit. Before submit or promote, counts user stories ahead and behind between the source environment and the next pipeline environment, and warns when stories behind might cause promotion conflicts (advising agentia cicd work environment-sync). With done=true or deploy=true, matches Copado UI Submit when promoting (headless work/done) and uses the same commit wait. Prefer this over agentia_work_done.',
|
|
774
792
|
inputSchema: {
|
|
775
793
|
apexTestClasses: z
|
|
776
794
|
.string()
|
|
@@ -793,7 +811,7 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
793
811
|
title: 'Agentia Work Submit',
|
|
794
812
|
}, (args) => safelyHandleTool(() => workSubmit(args || {})));
|
|
795
813
|
server.registerTool('agentia_work_test', {
|
|
796
|
-
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).',
|
|
814
|
+
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).',
|
|
797
815
|
inputSchema: {
|
|
798
816
|
apexTestClasses: z
|
|
799
817
|
.string()
|
|
@@ -803,19 +821,32 @@ export function registerAgentiaMcpWorkTools(server) {
|
|
|
803
821
|
.boolean()
|
|
804
822
|
.optional()
|
|
805
823
|
.describe('Run remote Copado quality gates (not implemented yet).'),
|
|
824
|
+
env: z
|
|
825
|
+
.array(z.string())
|
|
826
|
+
.optional()
|
|
827
|
+
.describe('Extra environment variables for the quality-gate script as NAME=value strings (same as CLI -e/--env). Applied before reserved AGENTIA_APEX_* variables.'),
|
|
806
828
|
local: z
|
|
807
829
|
.boolean()
|
|
808
830
|
.optional()
|
|
809
831
|
.describe('Run local project-root quality gates scripts. Used by default when cloud is omitted.'),
|
|
832
|
+
rerunFailedApexTests: z
|
|
833
|
+
.boolean()
|
|
834
|
+
.optional()
|
|
835
|
+
.describe('Pass AGENTIA_APEX_RERUN_FAILED=--rerun-failed-apex-tests to local quality gates so sample scripts forward that flag to work test apex.'),
|
|
810
836
|
},
|
|
811
837
|
title: 'Agentia Work Test',
|
|
812
838
|
}, (args) => safelyHandleTool(() => workTest(args || {})));
|
|
813
839
|
server.registerTool('agentia_work_test_apex', {
|
|
814
|
-
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.',
|
|
840
|
+
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.',
|
|
815
841
|
inputSchema: {
|
|
816
842
|
apexTestClasses: z
|
|
817
843
|
.string()
|
|
818
|
-
.
|
|
844
|
+
.optional()
|
|
845
|
+
.describe('Comma-separated Apex test class names to run. Omit or leave empty to skip without running Salesforce CLI.'),
|
|
846
|
+
rerunFailedApexTests: z
|
|
847
|
+
.boolean()
|
|
848
|
+
.optional()
|
|
849
|
+
.describe('Rerun Apex classes saved from the last failure for this user story. Combined with apexTestClasses, only matching failed classes run.'),
|
|
819
850
|
wait: z
|
|
820
851
|
.number()
|
|
821
852
|
.int()
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {modules} from '../runtime.js';
|
|
2
|
+
const AGENTIA_PLUGIN_HOST_API_VERSION = modules["plugin-host/index.js"]["AGENTIA_PLUGIN_HOST_API_VERSION"]
|
|
3
|
+
const AGENTIA_PLUGIN_HOST_KEY = modules["plugin-host/index.js"]["AGENTIA_PLUGIN_HOST_KEY"]
|
|
4
|
+
const createPluginHost = modules["plugin-host/index.js"]["createPluginHost"]
|
|
5
|
+
const getRegisteredPluginHost = modules["plugin-host/index.js"]["getRegisteredPluginHost"]
|
|
6
|
+
const registerPluginHost = modules["plugin-host/index.js"]["registerPluginHost"]
|
|
7
|
+
export {AGENTIA_PLUGIN_HOST_API_VERSION, AGENTIA_PLUGIN_HOST_KEY, createPluginHost, getRegisteredPluginHost, registerPluginHost};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import {modules} from '../runtime.js';
|
|
2
|
+
const createOrganizationApi = modules["plugin-host/organization.js"]["createOrganizationApi"]
|
|
3
|
+
const projectHealthReport = modules["plugin-host/organization.js"]["projectHealthReport"]
|
|
4
|
+
export {createOrganizationApi, projectHealthReport};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import {modules} from '../runtime.js';
|
|
2
|
+
const deepFreeze = modules["plugin-host/projection-utils.js"]["deepFreeze"]
|
|
3
|
+
const nonNegativeInt = modules["plugin-host/projection-utils.js"]["nonNegativeInt"]
|
|
4
|
+
const omitUndefined = modules["plugin-host/projection-utils.js"]["omitUndefined"]
|
|
5
|
+
const optionalText = modules["plugin-host/projection-utils.js"]["optionalText"]
|
|
6
|
+
export {deepFreeze, nonNegativeInt, omitUndefined, optionalText};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import {modules} from '../runtime.js';
|
|
2
|
+
const AGENTIA_PLUGIN_HOST_API_VERSION = modules["plugin-host/registry.js"]["AGENTIA_PLUGIN_HOST_API_VERSION"]
|
|
3
|
+
const AGENTIA_PLUGIN_HOST_KEY = modules["plugin-host/registry.js"]["AGENTIA_PLUGIN_HOST_KEY"]
|
|
4
|
+
const getRegisteredPluginHost = modules["plugin-host/registry.js"]["getRegisteredPluginHost"]
|
|
5
|
+
const registerPluginHost = modules["plugin-host/registry.js"]["registerPluginHost"]
|
|
6
|
+
export {AGENTIA_PLUGIN_HOST_API_VERSION, AGENTIA_PLUGIN_HOST_KEY, getRegisteredPluginHost, registerPluginHost};
|
package/dist/lib/project-root.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {modules} from './runtime.js';
|
|
2
2
|
const AGENTIA_PROJECT_ROOT_ENV = modules["project-root.js"]["AGENTIA_PROJECT_ROOT_ENV"]
|
|
3
|
+
const CLAUDE_PROJECT_DIR_ENV = modules["project-root.js"]["CLAUDE_PROJECT_DIR_ENV"]
|
|
3
4
|
const applyProjectRoot = modules["project-root.js"]["applyProjectRoot"]
|
|
5
|
+
const hasExplicitProjectRoot = modules["project-root.js"]["hasExplicitProjectRoot"]
|
|
4
6
|
const resetProjectRootDepsForTests = modules["project-root.js"]["resetProjectRootDepsForTests"]
|
|
5
7
|
const resolveProjectRoot = modules["project-root.js"]["resolveProjectRoot"]
|
|
6
8
|
const setProjectRootDepsForTests = modules["project-root.js"]["setProjectRootDepsForTests"]
|
|
7
|
-
export {AGENTIA_PROJECT_ROOT_ENV, applyProjectRoot, resetProjectRootDepsForTests, resolveProjectRoot, setProjectRootDepsForTests};
|
|
9
|
+
export {AGENTIA_PROJECT_ROOT_ENV, CLAUDE_PROJECT_DIR_ENV, applyProjectRoot, hasExplicitProjectRoot, resetProjectRootDepsForTests, resolveProjectRoot, setProjectRootDepsForTests};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import {modules} from './runtime.js';
|
|
2
|
+
const configureHttps = modules["repository-auth.js"]["configureHttps"]
|
|
3
|
+
const configureSsh = modules["repository-auth.js"]["configureSsh"]
|
|
4
|
+
const getRepository = modules["repository-auth.js"]["getRepository"]
|
|
5
|
+
const promptConnection = modules["repository-auth.js"]["promptConnection"]
|
|
6
|
+
const promptHttpsPayload = modules["repository-auth.js"]["promptHttpsPayload"]
|
|
7
|
+
const readHttpsAuthPayloadFromStdin = modules["repository-auth.js"]["readHttpsAuthPayloadFromStdin"]
|
|
8
|
+
export {configureHttps, configureSsh, getRepository, promptConnection, promptHttpsPayload, readHttpsAuthPayloadFromStdin};
|
|
@@ -6,11 +6,11 @@ const buildRepositoryMutationPayload = modules["repository-flags.js"]["buildRepo
|
|
|
6
6
|
const collectRepositoryMutationFlagKeys = modules["repository-flags.js"]["collectRepositoryMutationFlagKeys"]
|
|
7
7
|
const repositoryBooleanFlags = modules["repository-flags.js"]["repositoryBooleanFlags"]
|
|
8
8
|
const repositoryClearFlags = modules["repository-flags.js"]["repositoryClearFlags"]
|
|
9
|
+
const repositoryConnectionStringFlags = modules["repository-flags.js"]["repositoryConnectionStringFlags"]
|
|
9
10
|
const repositoryCreateFlags = modules["repository-flags.js"]["repositoryCreateFlags"]
|
|
10
11
|
const repositoryListFlags = modules["repository-flags.js"]["repositoryListFlags"]
|
|
11
|
-
const repositoryOptionalStringFlags = modules["repository-flags.js"]["repositoryOptionalStringFlags"]
|
|
12
12
|
const repositoryRequiredMutationFlags = modules["repository-flags.js"]["repositoryRequiredMutationFlags"]
|
|
13
13
|
const repositoryUpdateFlags = modules["repository-flags.js"]["repositoryUpdateFlags"]
|
|
14
14
|
const validateNonEmptyStringFields = modules["repository-flags.js"]["validateNonEmptyStringFields"]
|
|
15
15
|
const validateRepositoryMutationFlags = modules["repository-flags.js"]["validateRepositoryMutationFlags"]
|
|
16
|
-
export {REPOSITORY_STRING_VALIDATION_KEYS, buildRepositoryCreatePayload, buildRepositoryListFilters, buildRepositoryMutationPayload, collectRepositoryMutationFlagKeys, repositoryBooleanFlags, repositoryClearFlags, repositoryCreateFlags, repositoryListFlags,
|
|
16
|
+
export {REPOSITORY_STRING_VALIDATION_KEYS, buildRepositoryCreatePayload, buildRepositoryListFilters, buildRepositoryMutationPayload, collectRepositoryMutationFlagKeys, repositoryBooleanFlags, repositoryClearFlags, repositoryConnectionStringFlags, repositoryCreateFlags, repositoryListFlags, repositoryRequiredMutationFlags, repositoryUpdateFlags, validateNonEmptyStringFields, validateRepositoryMutationFlags};
|