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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +935 -256
  3. package/dist/commands/adv/auth/status.js +20 -0
  4. package/dist/commands/adv/component/add.js +48 -0
  5. package/dist/commands/adv/component/list.js +46 -0
  6. package/dist/commands/adv/component/refresh.js +23 -0
  7. package/dist/commands/adv/component/remove.js +35 -0
  8. package/dist/commands/adv/component/selected.js +26 -0
  9. package/dist/commands/adv/component/types.js +16 -0
  10. package/dist/commands/adv/deployment/cancel.js +45 -0
  11. package/dist/commands/adv/deployment/create.js +23 -0
  12. package/dist/commands/adv/deployment/deploy.js +46 -0
  13. package/dist/commands/adv/deployment/get.js +21 -0
  14. package/dist/commands/adv/deployment/list.js +30 -0
  15. package/dist/commands/adv/deployment/options.js +33 -0
  16. package/dist/commands/adv/deployment/quick-deploy.js +54 -0
  17. package/dist/commands/adv/deployment/validate.js +29 -0
  18. package/dist/commands/adv/job/get.js +21 -0
  19. package/dist/commands/adv/job/list.js +30 -0
  20. package/dist/commands/adv/job/wait.js +29 -0
  21. package/dist/commands/adv/organization/get.js +21 -0
  22. package/dist/commands/adv/organization/list.js +21 -0
  23. package/dist/commands/adv/organization/validate.js +20 -0
  24. package/dist/commands/auth/get.js +24 -3
  25. package/dist/commands/auth/set.js +18 -0
  26. package/dist/commands/auth/unset.js +4 -0
  27. package/dist/commands/cicd/notification/get.js +44 -0
  28. package/dist/commands/cicd/work/publish.js +1 -0
  29. package/dist/commands/cicd/work/test/apex.js +37 -4
  30. package/dist/commands/cicd/work/test.js +20 -1
  31. package/dist/commands/setup/skills/create.js +4 -0
  32. package/dist/commands/setup/skills/update.js +4 -0
  33. package/dist/hooks/init/migrate-user-config.js +5 -1
  34. package/dist/hooks/init/version-warning.js +5 -2
  35. package/dist/lib/adv-config.js +9 -0
  36. package/dist/lib/adv-flags.js +8 -0
  37. package/dist/lib/adv-gateway.js +8 -0
  38. package/dist/lib/adv-operations.js +26 -0
  39. package/dist/lib/adv-sanitization.js +8 -0
  40. package/dist/lib/adv-types.js +9 -0
  41. package/dist/lib/agentia-command.js +30 -1
  42. package/dist/lib/auth-config.js +2 -1
  43. package/dist/lib/auth-status-format.js +2 -1
  44. package/dist/lib/cicd-gateway.js +3 -1
  45. package/dist/lib/cli-severity-color.js +4 -0
  46. package/dist/lib/local-quality-gates.js +4 -1
  47. package/dist/lib/mcp/adv-tools.js +221 -0
  48. package/dist/lib/mcp/command-id.js +4 -1
  49. package/dist/lib/mcp/tool-annotations.js +23 -0
  50. package/dist/lib/mcp/tools.js +42 -0
  51. package/dist/lib/mcp/work-tools.js +48 -9
  52. package/dist/lib/notifications-get.js +10 -0
  53. package/dist/lib/plugin-host/event-log.js +3 -0
  54. package/dist/lib/runtime.js +1 -1
  55. package/dist/lib/setup-templates.js +2 -1
  56. package/dist/lib/work-apex-test-failures.js +13 -0
  57. package/dist/lib/work-apex-test.js +4 -1
  58. package/oclif.manifest.json +1359 -153
  59. package/package.json +35 -2
  60. package/templates/AGENTS.md +1 -1
  61. package/templates/skills/agentia-adv/SKILL.md +20 -0
  62. package/templates/skills/agentia-adv/references/pipelines-advanced.md +34 -0
  63. package/templates/skills/agentia-cicd/SKILL.md +4 -2
  64. package/templates/skills/agentia-cicd/references/notifications.md +79 -0
  65. package/templates/skills/agentia-cicd/references/work.md +21 -2
@@ -0,0 +1,20 @@
1
+ import { Args } from '@oclif/core';
2
+ import { validateAdvOrganization } from '../../../lib/adv-operations.js';
3
+ import { AgentiaCommand } from '../../../lib/agentia-command.js';
4
+ export default class AdvOrganizationValidate extends AgentiaCommand {
5
+ static args = {
6
+ id: Args.integer({ description: 'Pipelines Advanced organization ID.', required: true }),
7
+ };
8
+ static description = 'Validate that Pipelines Advanced can connect to an organization';
9
+ static examples = [
10
+ '<%= config.bin %> <%= command.id %> 910001',
11
+ '<%= config.bin %> <%= command.id %> 910001 --json',
12
+ ];
13
+ async run() {
14
+ const { args } = await this.parse(AdvOrganizationValidate);
15
+ const result = await this.withSpinner('Validating Pipelines Advanced organization connection', () => validateAdvOrganization(args.id));
16
+ this.display(() => this.log(result.message));
17
+ return result;
18
+ }
19
+ }
20
+ //# sourceMappingURL=validate.js.map
@@ -1,9 +1,9 @@
1
1
  import { Flags, ux } from '@oclif/core';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { AgentiaCommand } from '../../lib/agentia-command.js';
4
- import { getAiAuthStatus, getCicdAuthStatus, getCrtAuthStatus } from '../../lib/auth-config.js';
4
+ import { getAdvAuthStatus, getAiAuthStatus, getCicdAuthStatus, getCrtAuthStatus } from '../../lib/auth-config.js';
5
5
  import { readAuthProfile } from '../../lib/auth-profile.js';
6
- import { formatAiStatusLine, formatCicdStatusLine, formatCrtStatusLine } from '../../lib/auth-status-format.js';
6
+ import { formatAdvStatusLine, formatAiStatusLine, formatCicdStatusLine, formatCrtStatusLine } from '../../lib/auth-status-format.js';
7
7
  import { ALL_CREDENTIAL_TYPES, credentialLabel, } from '../../lib/credential-store.js';
8
8
  import { getDefaultsStorePaths } from '../../lib/defaults-store.js';
9
9
  export default class AuthGet extends AgentiaCommand {
@@ -11,12 +11,16 @@ export default class AuthGet extends AgentiaCommand {
11
11
  static examples = [
12
12
  '<%= config.bin %> <%= command.id %>',
13
13
  '<%= config.bin %> <%= command.id %> --ai',
14
+ '<%= config.bin %> <%= command.id %> --adv',
14
15
  '<%= config.bin %> <%= command.id %> --cicd',
15
16
  '<%= config.bin %> <%= command.id %> --crt',
16
17
  '<%= config.bin %> <%= command.id %> --cicd --crt',
17
18
  '<%= config.bin %> <%= command.id %> --json',
18
19
  ];
19
20
  static flags = {
21
+ adv: Flags.boolean({
22
+ description: 'Show PAT for Pipelines Advanced authentication',
23
+ }),
20
24
  ai: Flags.boolean({
21
25
  description: 'Show PAK for Copado AI authentication',
22
26
  }),
@@ -39,10 +43,13 @@ export default class AuthGet extends AgentiaCommand {
39
43
  if (flags.ai) {
40
44
  types.push('ai');
41
45
  }
46
+ if (flags.adv) {
47
+ types.push('adv');
48
+ }
42
49
  const selectedTypes = types.length > 0 ? types : ALL_CREDENTIAL_TYPES;
43
50
  const credentials = selectedTypes.map((type) => this.buildCredentialResult(type));
44
51
  this.display(() => {
45
- for (const type of ['cicd', 'ai', 'crt']) {
52
+ for (const type of ['cicd', 'ai', 'crt', 'adv']) {
46
53
  if (!selectedTypes.includes(type))
47
54
  continue;
48
55
  const scopes = this.hasLocalAuthentication(type) ? ['global', 'local'] : [undefined];
@@ -81,6 +88,17 @@ export default class AuthGet extends AgentiaCommand {
81
88
  if (type === 'cicd') {
82
89
  return this.buildCicdCredentialResult(scope);
83
90
  }
91
+ if (type === 'adv') {
92
+ const status = getAdvAuthStatus(scope);
93
+ return {
94
+ baseUrl: status.baseUrl,
95
+ label: credentialLabel(type),
96
+ masked: status.masked,
97
+ set: status.set,
98
+ source: status.source,
99
+ type,
100
+ };
101
+ }
84
102
  if (type === 'ai') {
85
103
  const status = getAiAuthStatus(scope);
86
104
  return {
@@ -119,6 +137,9 @@ export default class AuthGet extends AgentiaCommand {
119
137
  if (credential.type === 'crt') {
120
138
  return formatCrtStatusLine(credential);
121
139
  }
140
+ if (credential.type === 'adv') {
141
+ return formatAdvStatusLine(credential);
142
+ }
122
143
  return '';
123
144
  }
124
145
  hasLocalAuthentication(type) {
@@ -10,6 +10,8 @@ export default class AuthSet extends AgentiaCommand {
10
10
  '<%= config.bin %> <%= command.id %> --ai <pak> --ai-domain robotic.copado.com --ai-org 42888 --ai-workspace 42d0b908-37b7-4565-9ec9-86eda40c9782',
11
11
  '<%= config.bin %> <%= command.id %> --ai <pak> --ai-gateway-url http://localhost:8080/organizations/42888',
12
12
  '<%= config.bin %> <%= command.id %> --ai-workspace 42d0b908-37b7-4565-9ec9-86eda40c9782',
13
+ '<%= config.bin %> <%= command.id %> --adv <pat>',
14
+ '<%= config.bin %> <%= command.id %> --adv <pat> --adv-base-url https://uat.pipeline.copado.com',
13
15
  '<%= config.bin %> <%= command.id %> --cicd <copado-api-key> --region na',
14
16
  '<%= config.bin %> <%= command.id %> --cicd <copado-api-key> --custom-url https://dev.api.copado.com',
15
17
  '<%= config.bin %> <%= command.id %> --cicd <copado-api-key>',
@@ -19,6 +21,12 @@ export default class AuthSet extends AgentiaCommand {
19
21
  '<%= config.bin %> <%= command.id %> --cicd <copado-api-key> --region na --json',
20
22
  ];
21
23
  static flags = {
24
+ adv: Flags.string({
25
+ description: 'Personal Access Token for Copado Pipelines Advanced authentication',
26
+ }),
27
+ 'adv-base-url': Flags.string({
28
+ description: 'Optional Pipelines Advanced base URL; omit to auto-discover from the PAT',
29
+ }),
22
30
  ai: Flags.string({ description: 'PAK for Copado AI authentication' }),
23
31
  'ai-domain': Flags.string({
24
32
  description: 'Optional Copado AI domain hostname; omit to auto-discover from the PAK and organization ID',
@@ -59,6 +67,8 @@ export default class AuthSet extends AgentiaCommand {
59
67
  let result;
60
68
  try {
61
69
  result = await this.withSpinnerForAuth(flags, () => applyAuthSet({
70
+ adv: flags.adv,
71
+ advBaseUrl: flags['adv-base-url'],
62
72
  ai: flags.ai,
63
73
  aiDomain: flags['ai-domain'],
64
74
  aiGatewayUrl: flags['ai-gateway-url'],
@@ -103,6 +113,9 @@ export default class AuthSet extends AgentiaCommand {
103
113
  if (result.ai?.workspaceId !== undefined) {
104
114
  this.log(`Stored AI workspace ID: ${result.ai.workspaceId}.`);
105
115
  }
116
+ if (result.adv?.baseUrl !== undefined) {
117
+ this.log(`Stored Pipelines Advanced endpoint: ${result.adv.baseUrl}.`);
118
+ }
106
119
  return result;
107
120
  }
108
121
  async withSpinnerForAuth(flags, action) {
@@ -125,6 +138,11 @@ export default class AuthSet extends AgentiaCommand {
125
138
  if (flags.ai !== undefined) {
126
139
  return this.withSpinner('Validating AI credentials', action);
127
140
  }
141
+ if (flags.adv !== undefined) {
142
+ return this.withSpinner(flags['adv-base-url'] === undefined
143
+ ? 'Discovering Pipelines Advanced endpoint'
144
+ : 'Validating Pipelines Advanced PAT for custom endpoint', action);
145
+ }
128
146
  return action();
129
147
  }
130
148
  }
@@ -8,12 +8,16 @@ export default class AuthUnset extends AgentiaCommand {
8
8
  static examples = [
9
9
  '<%= config.bin %> <%= command.id %>',
10
10
  '<%= config.bin %> <%= command.id %> --ai',
11
+ '<%= config.bin %> <%= command.id %> --adv',
11
12
  '<%= config.bin %> <%= command.id %> --cicd',
12
13
  '<%= config.bin %> <%= command.id %> --crt',
13
14
  '<%= config.bin %> <%= command.id %> --cicd --crt --yes',
14
15
  '<%= config.bin %> <%= command.id %> --json --yes',
15
16
  ];
16
17
  static flags = {
18
+ adv: Flags.boolean({
19
+ description: 'Remove Pipelines Advanced PAT and endpoint configuration',
20
+ }),
17
21
  ai: Flags.boolean({
18
22
  description: 'Remove Copado AI PAK, domain, organization, workspace, and gateway URL configuration',
19
23
  }),
@@ -0,0 +1,44 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { AgentiaCommand } from '../../../lib/agentia-command.js';
3
+ import { NotificationConfigureInputError } from '../../../lib/notifications-configure.js';
4
+ import { formatNotificationSubscriptionsTable, getNotificationSubscriptions, NotificationGetUserUnavailableError, } from '../../../lib/notifications-get.js';
5
+ export default class NotificationGet extends AgentiaCommand {
6
+ static description = 'List Slack notification subscriptions for the current user on a pipeline';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %> --pipeline-id <pipeline-id>',
9
+ '<%= config.bin %> <%= command.id %> -p <pipeline-id> --json',
10
+ ];
11
+ static flags = {
12
+ 'pipeline-id': Flags.string({
13
+ char: 'p',
14
+ description: 'Copado pipeline Salesforce Id',
15
+ required: true,
16
+ }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(NotificationGet);
20
+ const result = await this.withSpinner('Fetching notification subscriptions', async () => {
21
+ try {
22
+ return await getNotificationSubscriptions(flags['pipeline-id']);
23
+ }
24
+ catch (error) {
25
+ if (error instanceof NotificationConfigureInputError) {
26
+ this.error(error.message, { exit: error.exitCode });
27
+ }
28
+ if (error instanceof NotificationGetUserUnavailableError) {
29
+ this.error(error.message, { exit: error.exitCode });
30
+ }
31
+ throw error;
32
+ }
33
+ });
34
+ this.display(() => {
35
+ if (result.subscriptions.length === 0) {
36
+ this.log('No notification subscriptions found for this pipeline.');
37
+ return;
38
+ }
39
+ this.log(formatNotificationSubscriptionsTable(result.subscriptions));
40
+ });
41
+ return result;
42
+ }
43
+ }
44
+ //# sourceMappingURL=get.js.map
@@ -5,6 +5,7 @@ export default class WorkPublish extends AgentiaCommand {
5
5
  static description = WORK_PUBLISH_DESCRIPTION;
6
6
  static examples = [
7
7
  '<%= config.bin %> <%= command.id %>',
8
+ '<%= config.bin %> <%= command.id %> --dry-run',
8
9
  '<%= config.bin %> <%= command.id %> --permissions CustomField:Account.SLA__c,ApexClass:AccountService',
9
10
  '<%= config.bin %> <%= command.id %> --full-metadata PermissionSet:Sales_Onboarding',
10
11
  '<%= config.bin %> <%= command.id %> --skip-nested-metadata-detection',
@@ -1,22 +1,32 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { AgentiaCommand } from '../../../../lib/agentia-command.js';
3
- import { DEFAULT_APEX_TEST_WAIT_MINUTES, formatWorkApexTestHuman, parseApexTestClassNames, runWorkApexTests, validateApexTestWaitMinutes, WorkApexTestError, } from '../../../../lib/work-apex-test.js';
3
+ import { planWorkApexTestRun, recordWorkApexTestOutcome, WorkApexRerunError, } from '../../../../lib/work-apex-test-failures.js';
4
+ import { DEFAULT_APEX_TEST_WAIT_MINUTES, formatWorkApexTestHuman, parseApexTestClassNames, runWorkApexTests, skippedWorkApexTestResult, validateApexTestWaitMinutes, WorkApexTestError, } from '../../../../lib/work-apex-test.js';
4
5
  export default class WorkTestApex extends AgentiaCommand {
5
6
  static description = [
6
7
  'Run specified Apex test classes via Salesforce CLI (`sf apex run test`) with code coverage.',
7
8
  'Usually run from project-root local quality gates (`.agentia_quality_gates.sh` / `.agentia_quality_gates.cmd`) when those scripts are configured.',
9
+ 'When `--apex-test-classes` is omitted or empty, logs that no Apex tests were specified and exits without running Salesforce CLI.',
10
+ 'Failed runs save `.agentia/apex.tests.<user-story>.json`; successful runs delete that file.',
11
+ '`--rerun-failed-apex-tests` runs the previously failed classes (optionally filtered by `--apex-test-classes`).',
8
12
  'Prints the test-run summary when the run passes, or failing tests with their messages and stack traces when it fails.',
13
+ 'Exits with the same process exit code as Salesforce CLI (`sf`), including 100 when Apex tests fail.',
9
14
  ].join(' ');
10
15
  static examples = [
11
16
  '<%= config.bin %> <%= command.id %> -t HelloWorldTest',
12
17
  '<%= config.bin %> <%= command.id %> --apex-test-classes=MyTest,OtherTest',
13
18
  '<%= config.bin %> <%= command.id %> -t MyTest,OtherTest -w 10 --json',
19
+ '<%= config.bin %> <%= command.id %> -t "$AGENTIA_APEX_TEST_CLASSES"',
20
+ '<%= config.bin %> <%= command.id %> --rerun-failed-apex-tests',
14
21
  ];
15
22
  static flags = {
16
23
  'apex-test-classes': Flags.string({
17
24
  char: 't',
18
- description: 'Comma-separated Apex test class names to run',
19
- required: true,
25
+ description: 'Comma-separated Apex test class names to run. Omit or leave empty to skip without running Salesforce CLI.',
26
+ }),
27
+ 'rerun-failed-apex-tests': Flags.boolean({
28
+ default: false,
29
+ description: 'Rerun Apex classes saved from the last failure for this user story (`.agentia/apex.tests.<user-story>.json`). Combined with --apex-test-classes, only matching failed classes run.',
20
30
  }),
21
31
  wait: Flags.integer({
22
32
  char: 'w',
@@ -36,8 +46,30 @@ export default class WorkTestApex extends AgentiaCommand {
36
46
  catch (error) {
37
47
  this.error(error.message, { exit: 2 });
38
48
  }
49
+ let plan;
50
+ try {
51
+ plan = await planWorkApexTestRun({
52
+ requestedClassNames: classNames,
53
+ rerunFailed: flags['rerun-failed-apex-tests'] === true,
54
+ });
55
+ }
56
+ catch (error) {
57
+ if (error instanceof WorkApexRerunError) {
58
+ this.error(error.message, { exit: 2 });
59
+ }
60
+ throw error;
61
+ }
62
+ if (plan.kind === 'skip') {
63
+ const result = skippedWorkApexTestResult(waitMinutes);
64
+ this.display(() => {
65
+ this.log(plan.message);
66
+ });
67
+ this.logElapsed(startedAt);
68
+ return result;
69
+ }
39
70
  try {
40
- const result = await this.withSpinner(`Running Apex tests (${classNames.join(', ')}), waiting up to ${waitMinutes} minute(s)`, () => runWorkApexTests({ classNames, waitMinutes }));
71
+ const result = await this.withSpinner(`Running Apex tests (${plan.classNames.join(', ')}), waiting up to ${waitMinutes} minute(s)`, () => runWorkApexTests({ classNames: plan.classNames, waitMinutes }));
72
+ await recordWorkApexTestOutcome({ failed: false, result, userStory: plan.userStory });
41
73
  this.display(() => {
42
74
  this.log(formatWorkApexTestHuman(result));
43
75
  });
@@ -46,6 +78,7 @@ export default class WorkTestApex extends AgentiaCommand {
46
78
  }
47
79
  catch (error) {
48
80
  if (error instanceof WorkApexTestError) {
81
+ await recordWorkApexTestOutcome({ failed: true, result: error.result, userStory: plan.userStory });
49
82
  this.display(() => {
50
83
  this.log(formatWorkApexTestHuman(error.result));
51
84
  });
@@ -2,7 +2,7 @@ import { Flags } from '@oclif/core';
2
2
  import path from 'node:path';
3
3
  import { AgentiaCommand } from '../../../lib/agentia-command.js';
4
4
  import { getCurrentBranch } from '../../../lib/git-worktree.js';
5
- import { LocalQualityGatesError, resolveLocalQualityGatesScript } from '../../../lib/local-quality-gates.js';
5
+ import { LocalQualityGatesError, parseQualityGatesEnvAssignments, resolveLocalQualityGatesScript, } from '../../../lib/local-quality-gates.js';
6
6
  import { runWorkTestLocalQualityGates } from '../../../lib/stock-quality-gates.js';
7
7
  import { reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../../../lib/work-local-run-tests.js';
8
8
  import { extractUserStoryFromFeatureBranch } from '../../../lib/work-types.js';
@@ -17,6 +17,8 @@ export default class WorkTest extends AgentiaCommand {
17
17
  static examples = [
18
18
  '<%= config.bin %> <%= command.id %>',
19
19
  '<%= config.bin %> <%= command.id %> --local --apex-test-classes=MyTest,OtherTest',
20
+ '<%= config.bin %> <%= command.id %> --local --rerun-failed-apex-tests',
21
+ '<%= config.bin %> <%= command.id %> -e SKIP_LWC_TESTS=1 -e TOOL_API_KEY=secret',
20
22
  '<%= config.bin %> <%= command.id %> --json',
21
23
  '<%= config.bin %> <%= command.id %> --cloud',
22
24
  ];
@@ -28,10 +30,19 @@ export default class WorkTest extends AgentiaCommand {
28
30
  default: false,
29
31
  description: 'Run remote Copado quality gates (not implemented yet).',
30
32
  }),
33
+ env: Flags.string({
34
+ char: 'e',
35
+ description: 'Extra environment variable for the quality-gate script as NAME=value. Repeatable. Applied before reserved AGENTIA_APEX_* variables.',
36
+ multiple: true,
37
+ }),
31
38
  local: Flags.boolean({
32
39
  default: false,
33
40
  description: 'Run local project-root quality gates scripts. Used by default when --cloud is omitted.',
34
41
  }),
42
+ 'rerun-failed-apex-tests': Flags.boolean({
43
+ default: false,
44
+ description: 'Pass AGENTIA_APEX_RERUN_FAILED=--rerun-failed-apex-tests to local quality gates so sample scripts forward that flag to work test apex.',
45
+ }),
35
46
  };
36
47
  async run() {
37
48
  const { flags } = await this.parse(WorkTest);
@@ -45,6 +56,12 @@ export default class WorkTest extends AgentiaCommand {
45
56
  suggestions: [`${this.config.bin} cicd work test --local`],
46
57
  });
47
58
  }
59
+ try {
60
+ parseQualityGatesEnvAssignments(flags.env);
61
+ }
62
+ catch (error) {
63
+ this.error(error.message, { exit: 2 });
64
+ }
48
65
  let qualityGates;
49
66
  try {
50
67
  const scriptPath = resolveLocalQualityGatesScript();
@@ -60,7 +77,9 @@ export default class WorkTest extends AgentiaCommand {
60
77
  }
61
78
  qualityGates = await runWorkTestLocalQualityGates({
62
79
  apexTestClasses: flags['apex-test-classes'],
80
+ env: flags.env,
63
81
  onWarning: (message) => this.warn(message),
82
+ rerunFailed: flags['rerun-failed-apex-tests'] === true,
64
83
  });
65
84
  if (qualityGates.ran && qualityGates.scriptPath !== undefined) {
66
85
  this.display(() => {
@@ -6,11 +6,15 @@ export default class SetupSkillsCreate extends AgentiaCommand {
6
6
  static description = 'Create portable Markdown-only Agentia CLI skills in this project without overwriting managed files';
7
7
  static examples = [
8
8
  '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --adv --target agents --no-prompt',
9
10
  '<%= config.bin %> <%= command.id %> --cicd --target agents --no-prompt',
10
11
  '<%= config.bin %> <%= command.id %> --testing --ai --target cursor --no-prompt',
11
12
  '<%= config.bin %> <%= command.id %> --json',
12
13
  ];
13
14
  static flags = {
15
+ adv: Flags.boolean({
16
+ description: 'Create the Copado Pipelines Advanced skill pack',
17
+ }),
14
18
  ai: Flags.boolean({
15
19
  description: 'Create the Copado AI agent skill pack',
16
20
  }),
@@ -7,10 +7,14 @@ export default class SetupSkillsUpdate extends AgentiaCommand {
7
7
  static examples = [
8
8
  '<%= config.bin %> <%= command.id %>',
9
9
  '<%= config.bin %> <%= command.id %> --ai --target cursor --no-prompt',
10
+ '<%= config.bin %> <%= command.id %> --adv --target agents --no-prompt',
10
11
  '<%= config.bin %> <%= command.id %> --cicd --testing --target agents --no-prompt',
11
12
  '<%= config.bin %> <%= command.id %> --force --json',
12
13
  ];
13
14
  static flags = {
15
+ adv: Flags.boolean({
16
+ description: 'Update the Copado Pipelines Advanced skill pack',
17
+ }),
14
18
  ai: Flags.boolean({
15
19
  description: 'Update the Copado AI agent skill pack',
16
20
  }),
@@ -1,3 +1,5 @@
1
+ import { Errors } from '@oclif/core';
2
+ import { colorizeCliSeverityText } from '../../lib/cli-severity-color.js';
1
3
  import { migrateUserSettingsFromProjectConfig } from '../../lib/defaults-store.js';
2
4
  const hook = async function ({ id }) {
3
5
  if (id === undefined || !id.startsWith('cicd')) {
@@ -6,7 +8,9 @@ const hook = async function ({ id }) {
6
8
  try {
7
9
  const result = await migrateUserSettingsFromProjectConfig();
8
10
  if (result.migrated) {
9
- this.warn('Moved user settings from .agentia/config.json to .agentia/config.user.json.');
11
+ const warning = new Errors.CLIError.Warn(colorizeCliSeverityText('Moved user settings from .agentia/config.json to .agentia/config.user.json.', 'warning'));
12
+ warning.name = colorizeCliSeverityText('Warning', 'warning');
13
+ Errors.warn(warning);
10
14
  }
11
15
  }
12
16
  catch {
@@ -1,4 +1,5 @@
1
- import { ux } from '@oclif/core';
1
+ import { Errors, ux } from '@oclif/core';
2
+ import { colorizeCliSeverityText } from '../../lib/cli-severity-color.js';
2
3
  import { checkVersionWarning, isJsonOutputRequested } from '../../lib/version-warning.js';
3
4
  const hook = async function ({ argv, config, id }) {
4
5
  if (id === 'mcp:start') {
@@ -13,7 +14,9 @@ const hook = async function ({ argv, config, id }) {
13
14
  skip: config.scopedEnvVarTrue('SKIP_NEW_VERSION_CHECK'),
14
15
  });
15
16
  if (result.warning !== undefined && !isJsonOutputRequested(argv, config.scopedEnvVar('CONTENT_TYPE'))) {
16
- this.warn(result.warning);
17
+ const warning = new Errors.CLIError.Warn(colorizeCliSeverityText(result.warning, 'warning'));
18
+ warning.name = colorizeCliSeverityText('Warning', 'warning');
19
+ Errors.warn(warning);
17
20
  }
18
21
  }
19
22
  catch {
@@ -0,0 +1,9 @@
1
+ import {modules} from './runtime.js';
2
+ const ADV_REGIONAL_BASE_URLS = modules["adv-config.js"]["ADV_REGIONAL_BASE_URLS"]
3
+ const AdvConfigurationError = modules["adv-config.js"]["AdvConfigurationError"]
4
+ const advBaseUrlForRegion = modules["adv-config.js"]["advBaseUrlForRegion"]
5
+ const advRegionEntries = modules["adv-config.js"]["advRegionEntries"]
6
+ const normalizeAdvBaseUrl = modules["adv-config.js"]["normalizeAdvBaseUrl"]
7
+ const readAdvAuthMetadata = modules["adv-config.js"]["readAdvAuthMetadata"]
8
+ const resolveAdvCredentials = modules["adv-config.js"]["resolveAdvCredentials"]
9
+ export {ADV_REGIONAL_BASE_URLS, AdvConfigurationError, advBaseUrlForRegion, advRegionEntries, normalizeAdvBaseUrl, readAdvAuthMetadata, resolveAdvCredentials};
@@ -0,0 +1,8 @@
1
+ import {modules} from './runtime.js';
2
+ const advWaitFlags = modules["adv-flags.js"]["advWaitFlags"]
3
+ const advYesFlag = modules["adv-flags.js"]["advYesFlag"]
4
+ const confirmAdvAction = modules["adv-flags.js"]["confirmAdvAction"]
5
+ const hasAdvActionTestConfirm = modules["adv-flags.js"]["hasAdvActionTestConfirm"]
6
+ const requiresAdvExplicitYes = modules["adv-flags.js"]["requiresAdvExplicitYes"]
7
+ const setAdvActionConfirmForTests = modules["adv-flags.js"]["setAdvActionConfirmForTests"]
8
+ export {advWaitFlags, advYesFlag, confirmAdvAction, hasAdvActionTestConfirm, requiresAdvExplicitYes, setAdvActionConfirmForTests};
@@ -0,0 +1,8 @@
1
+ import {modules} from './runtime.js';
2
+ const ADV_DEFAULT_TIMEOUT_MS = modules["adv-gateway.js"]["ADV_DEFAULT_TIMEOUT_MS"]
3
+ const ADV_MAX_RESPONSE_BYTES = modules["adv-gateway.js"]["ADV_MAX_RESPONSE_BYTES"]
4
+ const AdvGateway = modules["adv-gateway.js"]["AdvGateway"]
5
+ const AdvGatewayError = modules["adv-gateway.js"]["AdvGatewayError"]
6
+ const resetAdvHttpRequestForTests = modules["adv-gateway.js"]["resetAdvHttpRequestForTests"]
7
+ const setAdvHttpRequestForTests = modules["adv-gateway.js"]["setAdvHttpRequestForTests"]
8
+ export {ADV_DEFAULT_TIMEOUT_MS, ADV_MAX_RESPONSE_BYTES, AdvGateway, AdvGatewayError, resetAdvHttpRequestForTests, setAdvHttpRequestForTests};
@@ -0,0 +1,26 @@
1
+ import {modules} from './runtime.js';
2
+ const addAdvComponents = modules["adv-operations.js"]["addAdvComponents"]
3
+ const cancelAdvDeployment = modules["adv-operations.js"]["cancelAdvDeployment"]
4
+ const createAdvDeployment = modules["adv-operations.js"]["createAdvDeployment"]
5
+ const deriveAdvJobResult = modules["adv-operations.js"]["deriveAdvJobResult"]
6
+ const getAdvAuthStatus = modules["adv-operations.js"]["getAdvAuthStatus"]
7
+ const getAdvDeployment = modules["adv-operations.js"]["getAdvDeployment"]
8
+ const getAdvJob = modules["adv-operations.js"]["getAdvJob"]
9
+ const getAdvOrganization = modules["adv-operations.js"]["getAdvOrganization"]
10
+ const getStoredAdvAuthSummary = modules["adv-operations.js"]["getStoredAdvAuthSummary"]
11
+ const listAdvComponentTypes = modules["adv-operations.js"]["listAdvComponentTypes"]
12
+ const listAdvComponents = modules["adv-operations.js"]["listAdvComponents"]
13
+ const listAdvDeployments = modules["adv-operations.js"]["listAdvDeployments"]
14
+ const listAdvJobs = modules["adv-operations.js"]["listAdvJobs"]
15
+ const listAdvOrganizations = modules["adv-operations.js"]["listAdvOrganizations"]
16
+ const parseAdvComponentSpec = modules["adv-operations.js"]["parseAdvComponentSpec"]
17
+ const readAdvComponentsFromJsonFile = modules["adv-operations.js"]["readAdvComponentsFromJsonFile"]
18
+ const readAdvComponentsFromTextFile = modules["adv-operations.js"]["readAdvComponentsFromTextFile"]
19
+ const refreshAdvComponents = modules["adv-operations.js"]["refreshAdvComponents"]
20
+ const removeAdvComponents = modules["adv-operations.js"]["removeAdvComponents"]
21
+ const runAdvDeploymentAction = modules["adv-operations.js"]["runAdvDeploymentAction"]
22
+ const selectedAdvComponents = modules["adv-operations.js"]["selectedAdvComponents"]
23
+ const updateAdvDeploymentOptions = modules["adv-operations.js"]["updateAdvDeploymentOptions"]
24
+ const validateAdvOrganization = modules["adv-operations.js"]["validateAdvOrganization"]
25
+ const waitForAdvJob = modules["adv-operations.js"]["waitForAdvJob"]
26
+ export {addAdvComponents, cancelAdvDeployment, createAdvDeployment, deriveAdvJobResult, getAdvAuthStatus, getAdvDeployment, getAdvJob, getAdvOrganization, getStoredAdvAuthSummary, listAdvComponentTypes, listAdvComponents, listAdvDeployments, listAdvJobs, listAdvOrganizations, parseAdvComponentSpec, readAdvComponentsFromJsonFile, readAdvComponentsFromTextFile, refreshAdvComponents, removeAdvComponents, runAdvDeploymentAction, selectedAdvComponents, updateAdvDeploymentOptions, validateAdvOrganization, waitForAdvJob};
@@ -0,0 +1,8 @@
1
+ import {modules} from './runtime.js';
2
+ const ADV_MAX_ERROR_MESSAGE_LENGTH = modules["adv-sanitization.js"]["ADV_MAX_ERROR_MESSAGE_LENGTH"]
3
+ const ADV_REDACTED = modules["adv-sanitization.js"]["ADV_REDACTED"]
4
+ const advProviderErrorMessage = modules["adv-sanitization.js"]["advProviderErrorMessage"]
5
+ const sanitizeAdvOutput = modules["adv-sanitization.js"]["sanitizeAdvOutput"]
6
+ const sanitizeAdvUrl = modules["adv-sanitization.js"]["sanitizeAdvUrl"]
7
+ const summarizeAdvDebugBody = modules["adv-sanitization.js"]["summarizeAdvDebugBody"]
8
+ export {ADV_MAX_ERROR_MESSAGE_LENGTH, ADV_REDACTED, advProviderErrorMessage, sanitizeAdvOutput, sanitizeAdvUrl, summarizeAdvDebugBody};
@@ -0,0 +1,9 @@
1
+ import {modules} from './runtime.js';
2
+ const asAdvRecord = modules["adv-types.js"]["asAdvRecord"]
3
+ const formatAdvComponents = modules["adv-types.js"]["formatAdvComponents"]
4
+ const formatAdvDeployments = modules["adv-types.js"]["formatAdvDeployments"]
5
+ const formatAdvJobs = modules["adv-types.js"]["formatAdvJobs"]
6
+ const formatAdvOrganizations = modules["adv-types.js"]["formatAdvOrganizations"]
7
+ const formatAdvRecord = modules["adv-types.js"]["formatAdvRecord"]
8
+ const normalizeAdvId = modules["adv-types.js"]["normalizeAdvId"]
9
+ export {asAdvRecord, formatAdvComponents, formatAdvDeployments, formatAdvJobs, formatAdvOrganizations, formatAdvRecord, normalizeAdvId};
@@ -1,6 +1,7 @@
1
- import { Command, ux } from '@oclif/core';
1
+ import { Command, Errors, ux } from '@oclif/core';
2
2
  import { format } from 'node:util';
3
3
  import { createTransactionId, runWithGatewayTransactionContext } from './cicd-gateway.js';
4
+ import { colorizeCliSeverityError, colorizeCliSeverityText } from './cli-severity-color.js';
4
5
  import { isCommandOutputCaptureActive } from './command-output-buffer.js';
5
6
  import { rememberIdeCommandError } from './ide-command-events.js';
6
7
  const TRANSACTION_ID_REPORTED = Symbol('agentiaTransactionIdReported');
@@ -20,6 +21,9 @@ export class AgentiaCommand extends Command {
20
21
  }
21
22
  async catch(error) {
22
23
  this.reportHumanErrorTransactionId(error);
24
+ if (!this.jsonEnabled()) {
25
+ colorizeCliSeverityError(error, 'error');
26
+ }
23
27
  return super.catch(error);
24
28
  }
25
29
  display(render) {
@@ -27,6 +31,21 @@ export class AgentiaCommand extends Command {
27
31
  render();
28
32
  }
29
33
  }
34
+ error(input, options = {}) {
35
+ // exit:false prints immediately (no catch); colorize here. Throwing errors are colorized in catch.
36
+ if (!this.jsonEnabled() && options.exit === false) {
37
+ if (typeof input === 'string') {
38
+ const error = new Errors.CLIError(input, options);
39
+ colorizeCliSeverityError(error, 'error');
40
+ Errors.error(error, { exit: false });
41
+ return;
42
+ }
43
+ colorizeCliSeverityError(input, 'error');
44
+ Errors.error(input, { exit: false });
45
+ return;
46
+ }
47
+ return Errors.error(input, options);
48
+ }
30
49
  async finally(error) {
31
50
  rememberIdeCommandError(error);
32
51
  return super.finally(error);
@@ -51,6 +70,16 @@ export class AgentiaCommand extends Command {
51
70
  toSuccessJson(result) {
52
71
  return { result, status: 0, transactionId: this.commandTransactionId };
53
72
  }
73
+ warn(input) {
74
+ if (this.jsonEnabled()) {
75
+ return super.warn(input);
76
+ }
77
+ const text = typeof input === 'string' ? input : input.message;
78
+ const warning = new Errors.CLIError.Warn(colorizeCliSeverityText(text, 'warning'));
79
+ warning.name = colorizeCliSeverityText('Warning', 'warning');
80
+ Errors.warn(warning);
81
+ return input;
82
+ }
54
83
  async withSpinner(message, action) {
55
84
  if (this.jsonEnabled()) {
56
85
  if (isCommandOutputCaptureActive()) {
@@ -9,6 +9,7 @@ const formatAuthUnsetConfirmation = modules["auth-config.js"]["formatAuthUnsetCo
9
9
  const formatCicdApiKeyHelp = modules["auth-config.js"]["formatCicdApiKeyHelp"]
10
10
  const formatPersonalAccessKeyHelp = modules["auth-config.js"]["formatPersonalAccessKeyHelp"]
11
11
  const formatTerminalHyperlink = modules["auth-config.js"]["formatTerminalHyperlink"]
12
+ const getAdvAuthStatus = modules["auth-config.js"]["getAdvAuthStatus"]
12
13
  const getAiAuthStatus = modules["auth-config.js"]["getAiAuthStatus"]
13
14
  const getCicdAuthStatus = modules["auth-config.js"]["getCicdAuthStatus"]
14
15
  const getCrtAuthStatus = modules["auth-config.js"]["getCrtAuthStatus"]
@@ -17,4 +18,4 @@ const isCicdConfigured = modules["auth-config.js"]["isCicdConfigured"]
17
18
  const resetAuthUnsetConfirmForTests = modules["auth-config.js"]["resetAuthUnsetConfirmForTests"]
18
19
  const resolveAuthUnsetTypes = modules["auth-config.js"]["resolveAuthUnsetTypes"]
19
20
  const setAuthUnsetConfirmForTests = modules["auth-config.js"]["setAuthUnsetConfirmForTests"]
20
- export {AuthSetError, COPADO_ACCOUNT_SUMMARY_LOGIN_URL, COPADO_ROBOTIC_PERSONAL_ACCESS_KEY_URL, applyAuthSet, applyAuthUnset, confirmAuthUnset, formatAuthUnsetConfirmation, formatCicdApiKeyHelp, formatPersonalAccessKeyHelp, formatTerminalHyperlink, getAiAuthStatus, getCicdAuthStatus, getCrtAuthStatus, hasAuthUnsetTestConfirm, isCicdConfigured, resetAuthUnsetConfirmForTests, resolveAuthUnsetTypes, setAuthUnsetConfirmForTests};
21
+ export {AuthSetError, COPADO_ACCOUNT_SUMMARY_LOGIN_URL, COPADO_ROBOTIC_PERSONAL_ACCESS_KEY_URL, applyAuthSet, applyAuthUnset, confirmAuthUnset, formatAuthUnsetConfirmation, formatCicdApiKeyHelp, formatPersonalAccessKeyHelp, formatTerminalHyperlink, getAdvAuthStatus, getAiAuthStatus, getCicdAuthStatus, getCrtAuthStatus, hasAuthUnsetTestConfirm, isCicdConfigured, resetAuthUnsetConfirmForTests, resolveAuthUnsetTypes, setAuthUnsetConfirmForTests};
@@ -1,6 +1,7 @@
1
1
  import {modules} from './runtime.js';
2
+ const formatAdvStatusLine = modules["auth-status-format.js"]["formatAdvStatusLine"]
2
3
  const formatAiStatusLine = modules["auth-status-format.js"]["formatAiStatusLine"]
3
4
  const formatAuthScope = modules["auth-status-format.js"]["formatAuthScope"]
4
5
  const formatCicdStatusLine = modules["auth-status-format.js"]["formatCicdStatusLine"]
5
6
  const formatCrtStatusLine = modules["auth-status-format.js"]["formatCrtStatusLine"]
6
- export {formatAiStatusLine, formatAuthScope, formatCicdStatusLine, formatCrtStatusLine};
7
+ export {formatAdvStatusLine, formatAiStatusLine, formatAuthScope, formatCicdStatusLine, formatCrtStatusLine};
@@ -1,4 +1,5 @@
1
1
  import {modules} from './runtime.js';
2
+ const ADV_GATEWAY_EVENT_SERVICE = modules["cicd-gateway.js"]["ADV_GATEWAY_EVENT_SERVICE"]
2
3
  const AGENTIA_CLIENT_ORIGIN_ENV = modules["cicd-gateway.js"]["AGENTIA_CLIENT_ORIGIN_ENV"]
3
4
  const AGENTIA_IDE_VERSION_ENV = modules["cicd-gateway.js"]["AGENTIA_IDE_VERSION_ENV"]
4
5
  const AI_GATEWAY_EVENT_SERVICE = modules["cicd-gateway.js"]["AI_GATEWAY_EVENT_SERVICE"]
@@ -9,6 +10,7 @@ const CicdGatewayError = modules["cicd-gateway.js"]["CicdGatewayError"]
9
10
  const GATEWAY_EVENT_API_CALL = modules["cicd-gateway.js"]["GATEWAY_EVENT_API_CALL"]
10
11
  const GATEWAY_EVENT_UNKNOWN = modules["cicd-gateway.js"]["GATEWAY_EVENT_UNKNOWN"]
11
12
  const MCP_CICD_DEFAULT_REQUEST_TIMEOUT_MS = modules["cicd-gateway.js"]["MCP_CICD_DEFAULT_REQUEST_TIMEOUT_MS"]
13
+ const PLUGIN_GATEWAY_EVENT_SERVICE = modules["cicd-gateway.js"]["PLUGIN_GATEWAY_EVENT_SERVICE"]
12
14
  const buildGatewayEventLogPayload = modules["cicd-gateway.js"]["buildGatewayEventLogPayload"]
13
15
  const cicdApiUrl = modules["cicd-gateway.js"]["cicdApiUrl"]
14
16
  const createTransactionId = modules["cicd-gateway.js"]["createTransactionId"]
@@ -40,4 +42,4 @@ const scheduleGatewayEventLog = modules["cicd-gateway.js"]["scheduleGatewayEvent
40
42
  const setGatewayEventLogSenderForTests = modules["cicd-gateway.js"]["setGatewayEventLogSenderForTests"]
41
43
  const setHttpRequestForTests = modules["cicd-gateway.js"]["setHttpRequestForTests"]
42
44
  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};
45
+ export {ADV_GATEWAY_EVENT_SERVICE, 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};
@@ -0,0 +1,4 @@
1
+ import {modules} from './runtime.js';
2
+ const colorizeCliSeverityError = modules["cli-severity-color.js"]["colorizeCliSeverityError"]
3
+ const colorizeCliSeverityText = modules["cli-severity-color.js"]["colorizeCliSeverityText"]
4
+ export {colorizeCliSeverityError, colorizeCliSeverityText};