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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +648 -370
  3. package/dist/commands/cicd/cloud/commit.js +252 -0
  4. package/dist/commands/cicd/cloud/promote.js +139 -0
  5. package/dist/commands/cicd/data/template/save-detail.js +2 -2
  6. package/dist/commands/cicd/health-check.js +77 -0
  7. package/dist/commands/cicd/repository/auth/https/configure.js +21 -0
  8. package/dist/commands/cicd/repository/auth/oauth/login.js +56 -0
  9. package/dist/commands/cicd/repository/auth/setup.js +28 -0
  10. package/dist/commands/cicd/repository/auth/ssh/configure.js +22 -0
  11. package/dist/commands/cicd/repository/create.js +2 -2
  12. package/dist/commands/cicd/repository/reset.js +17 -5
  13. package/dist/commands/cicd/repository/update.js +6 -14
  14. package/dist/commands/cicd/work/commit.js +10 -324
  15. package/dist/commands/cicd/work/environment-sync.js +125 -0
  16. package/dist/commands/cicd/work/get.js +29 -12
  17. package/dist/commands/cicd/work/promote.js +93 -97
  18. package/dist/commands/cicd/work/set.js +4 -2
  19. package/dist/commands/cicd/work/submit.js +7 -0
  20. package/dist/commands/runtime.js +26 -0
  21. package/dist/hooks/finally/ide-command-event.js +1 -1
  22. package/dist/hooks/init/plugin-host.js +6 -0
  23. package/dist/lib/agentia-command.js +16 -0
  24. package/dist/lib/cursor-mcp-config.js +3 -1
  25. package/dist/lib/data-types.js +3 -1
  26. package/dist/lib/defaults-store.js +2 -1
  27. package/dist/lib/git-sizer.js +5 -0
  28. package/dist/lib/git-worktree.js +17 -1
  29. package/dist/lib/health-check.js +3 -0
  30. package/dist/lib/mcp/command-id.js +1 -0
  31. package/dist/lib/mcp/data-tools.js +2 -2
  32. package/dist/lib/mcp/health-check-tools.js +16 -0
  33. package/dist/lib/mcp/server.js +35 -8
  34. package/dist/lib/mcp/tool-annotations.js +268 -0
  35. package/dist/lib/mcp/tools.js +58 -12
  36. package/dist/lib/mcp/work-tools.js +98 -83
  37. package/dist/lib/metadata-pathspecs.js +4 -0
  38. package/dist/lib/metadataRegistry.json +5427 -0
  39. package/dist/lib/plugin-host/auth.js +4 -0
  40. package/dist/lib/plugin-host/format.js +3 -0
  41. package/dist/lib/plugin-host/index.js +7 -0
  42. package/dist/lib/plugin-host/organization.js +4 -0
  43. package/dist/lib/plugin-host/projection-utils.js +6 -0
  44. package/dist/lib/plugin-host/registry.js +6 -0
  45. package/dist/lib/plugin-host/request-scope.js +4 -0
  46. package/dist/lib/plugin-host/work.js +4 -0
  47. package/dist/lib/project-root.js +3 -1
  48. package/dist/lib/promotion-types.js +4 -1
  49. package/dist/lib/repository-auth.js +8 -0
  50. package/dist/lib/repository-flags.js +2 -2
  51. package/dist/lib/repository-types.js +6 -1
  52. package/dist/lib/repository-url-prefill.js +4 -0
  53. package/dist/lib/runtime-invoke-context.js +6 -0
  54. package/dist/lib/runtime-rpc.js +14 -0
  55. package/dist/lib/runtime.js +1 -1
  56. package/dist/lib/work-environment-sync-errors.js +4 -0
  57. package/dist/lib/work-environment-sync-ready.js +18 -0
  58. package/dist/lib/work-environment-sync.js +41 -0
  59. package/dist/lib/work-get.js +3 -0
  60. package/dist/lib/work-promote-deploy.js +13 -0
  61. package/dist/lib/work-promote-errors.js +5 -0
  62. package/dist/lib/work-promote.js +12 -0
  63. package/dist/lib/work-set-selection.js +2 -1
  64. package/dist/lib/work-submit-ahead-behind.js +8 -0
  65. package/dist/lib/work-types.js +2 -1
  66. package/oclif.manifest.json +1166 -605
  67. package/package.json +8 -4
  68. package/templates/skills/agentia-cicd/SKILL.md +2 -2
  69. package/templates/skills/agentia-cicd/references/promotions.md +8 -8
  70. package/templates/skills/agentia-cicd/references/work.md +16 -14
@@ -1,141 +1,137 @@
1
- import { confirm } from '@inquirer/prompts';
2
1
  import { Args, Flags } from '@oclif/core';
3
2
  import { AgentiaCommand } from '../../../lib/agentia-command.js';
4
- import { formatPromotionRunResult, isPromotionRunExecutionError, parseIgnoredMetadataJson, performPromotionRun, PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS, promotionRunErrorJson, PromotionRunValidationError, resolvePromotionIdForWorkItem, } from '../../../lib/promotion-run.js';
5
- import { resolveWorkItemId, WorkActiveResolutionError } from '../../../lib/work-active.js';
3
+ import { collectPromoteUserStoryIds, formatWorkPromoteResult, performWorkPromote, WorkPromoteConflictError, WorkPromoteValidationError, } from '../../../lib/work-promote.js';
6
4
  export default class WorkPromote extends AgentiaCommand {
7
5
  static args = {
8
- id: Args.string({
9
- description: 'User Story ID (defaults to the active work item from `work set`)',
6
+ userStoryIds: Args.string({
7
+ description: 'User story ID. Pass more than one to merge those feature branches in order. Omit when using --promotion with --continue or --abort.',
8
+ multiple: true,
10
9
  required: false,
11
10
  }),
12
11
  };
13
12
  static description = [
14
- 'Promote the explicit or active User Story through its Copado Promotion.',
15
- 'Requires --cloud and selects promote-only unless --deploy is passed.',
13
+ 'Experimental: skips Quality Gates. Requires enableLocalPromote true in .agentia/config.json.',
14
+ 'Create a promotion for one or more user stories and merge each feature/<name> branch into promotion/<promotionName>.',
15
+ 'The promotion branch is created from the destination environment branch.',
16
+ 'Without --backpromote, the stories promote forward from their source environment to the next pipeline environment.',
17
+ 'With --backpromote, pass --destination-branch. The destination environment is the pipeline environment whose connection branch matches that name, and the source is the next environment above it.',
18
+ 'Story merges stop at the first conflict and the promotion status is set to Merge Conflict.',
19
+ 'Resolve those files, then re-run with --promotion=<name-or-id> --continue to commit the merge, merge any remaining stories, and finish the promotion.',
20
+ 'To discard a conflicted merge, re-run with --promotion=<name-or-id> --abort (runs git merge --abort and sets the promotion status to Draft).',
21
+ 'That continue command repeats --validate or --deploy and --sf-alias when the original command used them.',
22
+ 'After every story merges, the promotion branch is pushed.',
23
+ 'Without --validate or --deploy, the promotion status is set to Completed.',
24
+ 'With --validate or --deploy, --sf-alias is required. The command writes a temporary package.xml and postdestructivechanges.xml from the promotion metadata and runs sf project deploy start --test-level NoTestRun -o <alias>.',
25
+ '--validate adds --dry-run, does not merge the destination branch, and sets the promotion status to Validated.',
26
+ '--deploy merges the promotion branch into the destination branch and sets the promotion status to Completed only after that deployment succeeds.',
27
+ 'User story records are not updated.',
16
28
  ].join(' ');
17
29
  static examples = [
18
- '<%= config.bin %> <%= command.id %> --cloud',
19
- '<%= config.bin %> <%= command.id %> a07XXXXXXXXXXXXXXX --cloud --promotion-id a0BXXXXXXXXXXXXXXX',
20
- '<%= config.bin %> <%= command.id %> --cloud --deploy --json',
30
+ '<%= config.bin %> <%= command.id %> a16P7000006By3pIAC',
31
+ '<%= config.bin %> <%= command.id %> a16P7000006By3pIAC a16P7000006By4qIAC',
32
+ '<%= config.bin %> <%= command.id %> a16P7000006By3pIAC --backpromote --destination-branch dev1-sfp',
33
+ '<%= config.bin %> <%= command.id %> a16P7000006By3pIAC --validate --sf-alias destOrg',
34
+ '<%= config.bin %> <%= command.id %> a16P7000006By3pIAC --deploy --sf-alias destOrg',
35
+ '<%= config.bin %> <%= command.id %> --promotion=P29354 --continue',
36
+ '<%= config.bin %> <%= command.id %> --promotion=P29354 --abort',
37
+ '<%= config.bin %> <%= command.id %> a16P7000006By3pIAC --json',
21
38
  ];
22
39
  static flags = {
23
- cloud: Flags.boolean({
40
+ abort: Flags.boolean({
24
41
  default: false,
25
- description: 'Use the Copado cloud promotion API. Required for this command.',
42
+ description: 'Abort an in-progress merge (`git merge --abort`) and set the promotion status to Draft. Requires --promotion. Exclusive with --continue.',
43
+ exclusive: ['continue'],
26
44
  }),
27
- deploy: Flags.boolean({
45
+ backpromote: Flags.boolean({
28
46
  default: false,
29
- description: 'Use merge_and_deploy instead of promote-only merge.',
47
+ description: 'Create a back promotion. Requires --destination-branch. Omit to promote forward to the next pipeline environment.',
30
48
  }),
31
- 'deployment-step-id': Flags.string({
32
- description: 'Ordered deployment-step Salesforce ID. Can be provided multiple times with --deploy.',
33
- multiple: true,
49
+ continue: Flags.boolean({
50
+ default: false,
51
+ description: 'Commit a resolved merge on promotion/<name> and finish the remaining story merges. Requires --promotion.',
52
+ exclusive: ['abort'],
34
53
  }),
35
- 'ignored-metadata-json': Flags.string({
36
- description: 'JSON array to persist through ignored-metadata before starting the promotion.',
54
+ deploy: Flags.boolean({
55
+ default: false,
56
+ description: 'Deploy the promotion metadata with sf project deploy start, then merge the promotion branch into the destination branch and set the promotion status to Completed. Requires --sf-alias.',
57
+ exclusive: ['validate'],
37
58
  }),
38
- 'promotion-id': Flags.string({
39
- description: 'Explicit 18-character Promotion ID when the User Story belongs to multiple promotions.',
59
+ 'destination-branch': Flags.string({
60
+ dependsOn: ['backpromote'],
61
+ description: 'Destination environment Git branch for --backpromote. The destination environment is the pipeline environment whose connection branch matches this name.',
40
62
  }),
41
- 'recreate-promotion-branch': Flags.boolean({
42
- description: 'Recreate the promotion branch before execution. Requires confirmation or --yes.',
63
+ 'destination-credential': Flags.string({
64
+ description: 'Credential ID posted as destinationCredentialId. Defaults to the destination environment default credential for a forward promotion, or the next/source environment default credential for --backpromote.',
43
65
  }),
44
- wait: Flags.boolean({
45
- allowNo: true,
46
- default: true,
47
- description: 'Poll promotion and deployment executions to terminal status.',
66
+ promotion: Flags.string({
67
+ description: 'Promotion Id or name for --continue after a merge conflict, or for --abort.',
48
68
  }),
49
- 'wait-timeout': Flags.integer({
50
- default: PROMOTION_RUN_DEFAULT_TIMEOUT_SECONDS,
51
- description: 'Maximum total seconds to wait for promotion and deployment executions.',
69
+ 'sf-alias': Flags.string({
70
+ description: 'Salesforce org alias or username for --validate or --deploy. Passed to sf project deploy start -o.',
52
71
  }),
53
- yes: Flags.boolean({
54
- char: 'y',
72
+ validate: Flags.boolean({
55
73
  default: false,
56
- description: 'Confirm promotion branch recreation without prompting.',
74
+ description: 'Validate the promotion metadata with sf project deploy start --dry-run. Does not merge the destination branch. Sets the promotion status to Validated. Requires --sf-alias.',
75
+ exclusive: ['deploy'],
57
76
  }),
58
77
  };
59
78
  async run() {
60
79
  const { args, flags } = await this.parse(WorkPromote);
61
- const promoteFlags = flags;
62
- if (!promoteFlags.cloud) {
63
- this.error('Only cloud promotion is supported for this command. Pass --cloud.', { exit: 2 });
64
- }
65
- if (!Number.isInteger(promoteFlags['wait-timeout']) || promoteFlags['wait-timeout'] <= 0) {
66
- this.error('--wait-timeout must be a positive integer.', { exit: 2 });
67
- }
68
- if (!promoteFlags.deploy && promoteFlags['deployment-step-id'] !== undefined) {
69
- this.error('--deployment-step-id requires --deploy.', { exit: 2 });
70
- }
71
- let workItemId;
80
+ const userStoryIds = collectPromoteUserStoryIds(args.userStoryIds);
72
81
  try {
73
- workItemId = await resolveWorkItemId(args.id);
74
- }
75
- catch (error) {
76
- if (error instanceof WorkActiveResolutionError) {
77
- this.error(error.message, {
78
- exit: 1,
79
- suggestions: [`${this.config.bin} cicd work set <id>`],
80
- });
81
- }
82
- throw error;
83
- }
84
- try {
85
- const promotionId = await this.withSpinner('Resolving User Story promotion', () => resolvePromotionIdForWorkItem(workItemId, promoteFlags['promotion-id']));
86
- if (promoteFlags['recreate-promotion-branch'] === true && !promoteFlags.yes) {
87
- if (this.jsonEnabled() || !process.stdin.isTTY) {
88
- this.error('Promotion branch recreation requires confirmation. Pass --yes for headless or JSON execution.', {
89
- exit: 2,
90
- });
91
- }
92
- const confirmed = await confirm({
93
- default: false,
94
- message: `Recreate the promotion branch for ${promotionId}? Existing promotion branch changes may be replaced.`,
95
- });
96
- if (!confirmed) {
97
- this.error('Promotion canceled.', { exit: 1 });
98
- }
99
- }
100
- const result = await performPromotionRun({
101
- deploymentStepIds: promoteFlags['deployment-step-id'],
82
+ const result = await performWorkPromote({
83
+ backpromote: flags.backpromote === true,
84
+ cliBin: this.config.bin,
102
85
  hooks: {
103
- log: (message) => this.display(() => this.log(message)),
86
+ log: (message) => {
87
+ this.display(() => {
88
+ this.log(message);
89
+ });
90
+ },
104
91
  withSpinner: (message, action) => this.withSpinner(message, action),
105
92
  },
106
- ignoredMetadata: parseIgnoredMetadataJson(promoteFlags['ignored-metadata-json']),
107
- operation: promoteFlags.deploy ? 'merge_and_deploy' : 'merge',
108
- promotionId,
109
- recreatePromotionBranch: promoteFlags['recreate-promotion-branch'],
110
- timeoutSeconds: promoteFlags['wait-timeout'],
111
- wait: promoteFlags.wait,
93
+ userStoryIds,
94
+ ...(flags.abort ? { abort: true } : {}),
95
+ ...(flags.continue ? { continue: true } : {}),
96
+ ...(flags.deploy ? { deploy: true } : {}),
97
+ ...(flags['destination-branch'] === undefined ? {} : { destinationBranch: flags['destination-branch'] }),
98
+ ...(flags['destination-credential'] === undefined
99
+ ? {}
100
+ : { destinationCredentialId: flags['destination-credential'] }),
101
+ ...(flags.promotion === undefined ? {} : { promotion: flags.promotion }),
102
+ ...(flags['sf-alias'] === undefined ? {} : { sfAlias: flags['sf-alias'] }),
103
+ ...(flags.validate ? { validate: true } : {}),
112
104
  });
113
- const workResult = { ...result, workItemId };
114
105
  this.display(() => {
115
- this.log(`User Story: ${workItemId}`);
116
- this.log(formatPromotionRunResult(result));
106
+ this.log(formatWorkPromoteResult(result));
117
107
  });
118
- return workResult;
108
+ return result;
119
109
  }
120
110
  catch (error) {
121
- if (error instanceof PromotionRunValidationError) {
122
- this.error(error.message, { exit: 2 });
111
+ if (error instanceof WorkPromoteConflictError) {
112
+ const { suggestions } = error;
113
+ const suggestionOptions = suggestions === undefined ? {} : { suggestions };
114
+ if (this.jsonEnabled()) {
115
+ const message = error.gitStatus === undefined || error.gitStatus.length === 0
116
+ ? error.message
117
+ : `${error.message}\n\n${error.gitStatus}`;
118
+ this.error(message, { exit: error.exit, ...suggestionOptions });
119
+ }
120
+ this.error(error.message, { exit: false, ...suggestionOptions });
121
+ if (error.gitStatus !== undefined && error.gitStatus.length > 0) {
122
+ this.log('');
123
+ this.log(error.gitStatus);
124
+ }
125
+ this.exit(error.exit);
123
126
  }
124
- if (isPromotionRunExecutionError(error)) {
125
- this.display(() => {
126
- if (error.result !== undefined) {
127
- this.log(`User Story: ${workItemId}`);
128
- this.log(formatPromotionRunResult(error.result));
129
- }
127
+ if (error instanceof WorkPromoteValidationError) {
128
+ this.error(error.message, {
129
+ exit: error.exit,
130
+ ...(error.suggestions === undefined ? {} : { suggestions: error.suggestions }),
130
131
  });
131
- error.oclif = { exit: 1 };
132
132
  }
133
133
  throw error;
134
134
  }
135
135
  }
136
- toErrorJson(err) {
137
- const base = super.toErrorJson(err);
138
- return promotionRunErrorJson(base, err);
139
- }
140
136
  }
141
137
  //# sourceMappingURL=promote.js.map
@@ -5,7 +5,7 @@ import { reconcileWorkSetCredential } from '../../../lib/credential-sync.js';
5
5
  import { writeLastWorkSelection } from '../../../lib/defaults-store.js';
6
6
  import { checkoutFeatureBranch, fetchOriginBranch, fetchOriginBranchIfExists, listPendingChanges, } from '../../../lib/git-worktree.js';
7
7
  import { performWorkSetNone, WorkSetNoneValidationError } from '../../../lib/work-set-none.js';
8
- import { isWorkSetWarning, parseWorkSetSelection, toWorkSetWarningResult } from '../../../lib/work-set-selection.js';
8
+ import { isWorkSetWarning, parseWorkSetSelection, toWorkSetWarningResult, writeWorkSetWarningSelection, } from '../../../lib/work-set-selection.js';
9
9
  import { featureBranchName, workSetEndpoint, } from '../../../lib/work-types.js';
10
10
  export default class WorkSet extends AgentiaCommand {
11
11
  static args = {
@@ -20,7 +20,8 @@ export default class WorkSet extends AgentiaCommand {
20
20
  'fetches the work item base branch from origin, fetches the feature branch when it',
21
21
  'exists on origin, then creates or checks out feature/<user-story-name> from the',
22
22
  'remote feature branch when present, otherwise from the base branch.',
23
- 'A gateway warning prints the message, skips git, and leaves local work context unchanged.',
23
+ 'A gateway warning prints the message, skips git, clears lastBaseBranch/lastDevOrgBranch/lastPullRequestBaseUrl,',
24
+ 'and records lastWorkItemId/lastWorkItem/lastWorkItemTitle from the returned work item.',
24
25
  'After work/set returns, compares the Story source credential with the CICD project default:',
25
26
  'warns when the default or Story credential is missing, and warns without changing the Story',
26
27
  'when they differ (shows the current credential and environment; use work update to change it).',
@@ -111,6 +112,7 @@ export default class WorkSet extends AgentiaCommand {
111
112
  this.log(setResponse.message);
112
113
  });
113
114
  if (isWorkSetWarning(setResponse)) {
115
+ await writeWorkSetWarningSelection(setResponse);
114
116
  return toWorkSetWarningResult(setResponse);
115
117
  }
116
118
  let selection;
@@ -10,6 +10,7 @@ import { openUrl } from '../../../lib/open-browser.js';
10
10
  import { pickWorkDoneFlags, runWorkDone, workDoneFlags } from '../../../lib/work-done.js';
11
11
  import { reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../../../lib/work-local-run-tests.js';
12
12
  import { performWorkPush, resolveActiveFeatureWorkItem, resolveWorkPushContext, resolveWorkPushNeed, WorkPushValidationError, } from '../../../lib/work-push.js';
13
+ import { reportSubmitUserStoriesAheadBehind } from '../../../lib/work-submit-ahead-behind.js';
13
14
  import { waitForPendingCommitJobBeforeSubmit } from '../../../lib/work-submit-wait.js';
14
15
  import { buildPullRequestCompareUrl, formatWorkCommandMessage, workSubmitEndpoint, } from '../../../lib/work-types.js';
15
16
  export default class WorkSubmit extends AgentiaCommand {
@@ -19,6 +20,7 @@ export default class WorkSubmit extends AgentiaCommand {
19
20
  'pushes and registers commits when the branch is ahead of origin, then calls headless work/submit',
20
21
  '(Promote Action with validate=true).',
21
22
  'When the last pending related job template name contains Commit, waits up to 5 minutes for that job before submitting.',
23
+ '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`).',
22
24
  'With --done or --deploy, matches Copado UI Submit when promoting (validate=false / headless work/done).',
23
25
  'cicd work done is a compatibility alias of this command with --done.',
24
26
  ].join(' ');
@@ -201,6 +203,10 @@ export default class WorkSubmit extends AgentiaCommand {
201
203
  this.log('Branch is up to date with origin; skipping push.');
202
204
  });
203
205
  }
206
+ const userStoriesAheadBehind = await reportSubmitUserStoriesAheadBehind(workItem, {
207
+ log: (message) => this.display(() => this.log(message)),
208
+ warn: (message) => this.warn(message),
209
+ });
204
210
  await waitForPendingCommitJobBeforeSubmit(this, workItem);
205
211
  const submit = await this.withSpinner('Submitting work item', () => CicdGateway.call({
206
212
  body: attachCapturedOutputLogs({ workItem }),
@@ -221,6 +227,7 @@ export default class WorkSubmit extends AgentiaCommand {
221
227
  pushed: needsPush,
222
228
  qualityGates,
223
229
  submit,
230
+ ...(userStoriesAheadBehind === undefined ? {} : { userStoriesAheadBehind }),
224
231
  workItem,
225
232
  };
226
233
  }, commandStdioCaptureOptions(this));
@@ -0,0 +1,26 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { AGENTIA_RUNTIME_DEFAULT_IDLE_MS, serveRuntimeRpc } from '../lib/runtime-rpc.js';
3
+ /** Long-lived stdio NDJSON server so the IDE can reuse one Agentia process. */
4
+ export default class Runtime extends Command {
5
+ static description = 'Start a stdio NDJSON runtime for in-process Agentia command invokes';
6
+ static enableJsonFlag = false;
7
+ static flags = {
8
+ 'idle-ms': Flags.integer({
9
+ default: AGENTIA_RUNTIME_DEFAULT_IDLE_MS,
10
+ description: 'Exit after this many idle milliseconds with no in-flight requests',
11
+ min: 1000,
12
+ }),
13
+ };
14
+ static hidden = true;
15
+ async run() {
16
+ const { flags: { 'idle-ms': idleMs } } = await this.parse(Runtime);
17
+ const { config } = this;
18
+ await serveRuntimeRpc({
19
+ cliVersion: config.version,
20
+ finder: config,
21
+ idleMs,
22
+ runCommand: (id, argv) => config.runCommand(id, argv),
23
+ });
24
+ }
25
+ }
26
+ //# sourceMappingURL=runtime.js.map
@@ -2,7 +2,7 @@ import { consumeIdeCommandError, publishIdeCommandCompleted } from '../../lib/id
2
2
  const hook = async function ({ config, error, id }) {
3
3
  try {
4
4
  const rememberedError = consumeIdeCommandError();
5
- if (id.trim().length === 0) {
5
+ if (id.trim().length === 0 || id === 'runtime') {
6
6
  return;
7
7
  }
8
8
  await publishIdeCommandCompleted({
@@ -0,0 +1,6 @@
1
+ import { createPluginHost, registerPluginHost } from '../../lib/plugin-host/index.js';
2
+ const hook = async function () {
3
+ registerPluginHost(createPluginHost({ cliVersion: this.config.version }));
4
+ };
5
+ export default hook;
6
+ //# sourceMappingURL=plugin-host.js.map
@@ -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
@@ -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};
@@ -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};
@@ -8,6 +8,7 @@ const isValidUserContext = modules["defaults-store.js"]["isValidUserContext"]
8
8
  const migrateUserSettingsFromProjectConfig = modules["defaults-store.js"]["migrateUserSettingsFromProjectConfig"]
9
9
  const readCredentialSyncReceipt = modules["defaults-store.js"]["readCredentialSyncReceipt"]
10
10
  const readDefaults = modules["defaults-store.js"]["readDefaults"]
11
+ const readEnableLocalPromote = modules["defaults-store.js"]["readEnableLocalPromote"]
11
12
  const readLastApexTestClassesSelected = modules["defaults-store.js"]["readLastApexTestClassesSelected"]
12
13
  const readLastBaseBranch = modules["defaults-store.js"]["readLastBaseBranch"]
13
14
  const readLastDevOrgBranch = modules["defaults-store.js"]["readLastDevOrgBranch"]
@@ -31,4 +32,4 @@ const writeDefaults = modules["defaults-store.js"]["writeDefaults"]
31
32
  const writeLastCommitSelections = modules["defaults-store.js"]["writeLastCommitSelections"]
32
33
  const writeLastWorkSelection = modules["defaults-store.js"]["writeLastWorkSelection"]
33
34
  const writeUserContext = modules["defaults-store.js"]["writeUserContext"]
34
- export {DEFAULT_WORK_PUSH_RETRY_TIMEOUT_SECONDS, clearCredentialSyncReceipt, clearLastKeysFromUserConfig, clearUserContext, getDefaultsStorePaths, isValidUserContext, migrateUserSettingsFromProjectConfig, readCredentialSyncReceipt, readDefaults, readLastApexTestClassesSelected, readLastBaseBranch, readLastDevOrgBranch, readLastFullMetadataSelected, readLastPermissionSelected, readLastPullRequestBaseUrl, readLastWorkItem, readLastWorkItemId, readLastWorkItemTitle, readSkipNestedMetadataDetection, readSkipPullRequest, readUserContext, readWorkPushRetryTimeoutSeconds, resetDefaultsStorePathsForTests, resolveDefaults, setDefaultsStorePathsForTests, setDefaultsStoreProjectRoot, unsetDefaults, writeCredentialSyncReceipt, writeDefaults, writeLastCommitSelections, writeLastWorkSelection, writeUserContext};
35
+ export {DEFAULT_WORK_PUSH_RETRY_TIMEOUT_SECONDS, clearCredentialSyncReceipt, clearLastKeysFromUserConfig, clearUserContext, getDefaultsStorePaths, isValidUserContext, migrateUserSettingsFromProjectConfig, readCredentialSyncReceipt, readDefaults, readEnableLocalPromote, readLastApexTestClassesSelected, readLastBaseBranch, readLastDevOrgBranch, readLastFullMetadataSelected, readLastPermissionSelected, readLastPullRequestBaseUrl, readLastWorkItem, readLastWorkItemId, readLastWorkItemTitle, readSkipNestedMetadataDetection, readSkipPullRequest, readUserContext, readWorkPushRetryTimeoutSeconds, resetDefaultsStorePathsForTests, resolveDefaults, setDefaultsStorePathsForTests, setDefaultsStoreProjectRoot, unsetDefaults, writeCredentialSyncReceipt, writeDefaults, writeLastCommitSelections, writeLastWorkSelection, writeUserContext};
@@ -0,0 +1,5 @@
1
+ import {modules} from './runtime.js';
2
+ const analyzeGitRepository = modules["git-sizer.js"]["analyzeGitRepository"]
3
+ const gitSizerRows = modules["git-sizer.js"]["gitSizerRows"]
4
+ const parseGitSizerMetrics = modules["git-sizer.js"]["parseGitSizerMetrics"]
5
+ export {analyzeGitRepository, gitSizerRows, parseGitSizerMetrics};
@@ -6,31 +6,47 @@ const checkoutFeatureBranch = modules["git-worktree.js"]["checkoutFeatureBranch"
6
6
  const checkoutPreferredBranch = modules["git-worktree.js"]["checkoutPreferredBranch"]
7
7
  const commitAllTrackedChanges = modules["git-worktree.js"]["commitAllTrackedChanges"]
8
8
  const commitAllowEmpty = modules["git-worktree.js"]["commitAllowEmpty"]
9
+ const commitCurrentMerge = modules["git-worktree.js"]["commitCurrentMerge"]
9
10
  const commitStagedChanges = modules["git-worktree.js"]["commitStagedChanges"]
10
11
  const countCommitsSince = modules["git-worktree.js"]["countCommitsSince"]
12
+ const createAndCheckoutBranch = modules["git-worktree.js"]["createAndCheckoutBranch"]
13
+ const fetchAndCheckoutBranch = modules["git-worktree.js"]["fetchAndCheckoutBranch"]
11
14
  const fetchOriginBranch = modules["git-worktree.js"]["fetchOriginBranch"]
12
15
  const fetchOriginBranchIfExists = modules["git-worktree.js"]["fetchOriginBranchIfExists"]
16
+ const formatGitExecError = modules["git-worktree.js"]["formatGitExecError"]
13
17
  const getCommitsNameStatus = modules["git-worktree.js"]["getCommitsNameStatus"]
14
18
  const getCurrentBranch = modules["git-worktree.js"]["getCurrentBranch"]
15
19
  const getFileAtRef = modules["git-worktree.js"]["getFileAtRef"]
16
20
  const getGitRepoRoot = modules["git-worktree.js"]["getGitRepoRoot"]
17
21
  const getHeadCommitId = modules["git-worktree.js"]["getHeadCommitId"]
22
+ const getHumanGitStatus = modules["git-worktree.js"]["getHumanGitStatus"]
18
23
  const getMergeBase = modules["git-worktree.js"]["getMergeBase"]
19
24
  const getRemoteUrl = modules["git-worktree.js"]["getRemoteUrl"]
20
25
  const hasUnpushedCommits = modules["git-worktree.js"]["hasUnpushedCommits"]
26
+ const isAncestor = modules["git-worktree.js"]["isAncestor"]
21
27
  const isInsideGitWorkTree = modules["git-worktree.js"]["isInsideGitWorkTree"]
28
+ const isMergeInProgress = modules["git-worktree.js"]["isMergeInProgress"]
29
+ const isSafeGitBranchName = modules["git-worktree.js"]["isSafeGitBranchName"]
30
+ const listDiffNamesVsHead = modules["git-worktree.js"]["listDiffNamesVsHead"]
22
31
  const listPendingChanges = modules["git-worktree.js"]["listPendingChanges"]
23
32
  const listStagedChanges = modules["git-worktree.js"]["listStagedChanges"]
33
+ const listUnmergedFiles = modules["git-worktree.js"]["listUnmergedFiles"]
24
34
  const localBranchExists = modules["git-worktree.js"]["localBranchExists"]
35
+ const mergeFfOnly = modules["git-worktree.js"]["mergeFfOnly"]
36
+ const mergeNoFf = modules["git-worktree.js"]["mergeNoFf"]
37
+ const mergeNoFfNoCommit = modules["git-worktree.js"]["mergeNoFfNoCommit"]
25
38
  const mergeTheirsIgnoreSpaceChange = modules["git-worktree.js"]["mergeTheirsIgnoreSpaceChange"]
26
39
  const originBranchRef = modules["git-worktree.js"]["originBranchRef"]
27
40
  const originFetchRefspec = modules["git-worktree.js"]["originFetchRefspec"]
41
+ const parseNameOnly = modules["git-worktree.js"]["parseNameOnly"]
28
42
  const parsePorcelainPaths = modules["git-worktree.js"]["parsePorcelainPaths"]
29
43
  const pullOriginBranch = modules["git-worktree.js"]["pullOriginBranch"]
30
44
  const pushOriginBranch = modules["git-worktree.js"]["pushOriginBranch"]
45
+ const pushOriginBranches = modules["git-worktree.js"]["pushOriginBranches"]
31
46
  const resetGitExecForTests = modules["git-worktree.js"]["resetGitExecForTests"]
32
47
  const resetHardHead = modules["git-worktree.js"]["resetHardHead"]
33
48
  const restoreFeatureBranch = modules["git-worktree.js"]["restoreFeatureBranch"]
49
+ const restoreHeadPaths = modules["git-worktree.js"]["restoreHeadPaths"]
34
50
  const setGitExecForTests = modules["git-worktree.js"]["setGitExecForTests"]
35
51
  const stageAndCommit = modules["git-worktree.js"]["stageAndCommit"]
36
- export {NAME_STATUS_PRETTY_FORMAT, abortMerge, checkoutBranch, checkoutFeatureBranch, checkoutPreferredBranch, commitAllTrackedChanges, commitAllowEmpty, commitStagedChanges, countCommitsSince, fetchOriginBranch, fetchOriginBranchIfExists, getCommitsNameStatus, getCurrentBranch, getFileAtRef, getGitRepoRoot, getHeadCommitId, getMergeBase, getRemoteUrl, hasUnpushedCommits, isInsideGitWorkTree, listPendingChanges, listStagedChanges, localBranchExists, mergeTheirsIgnoreSpaceChange, originBranchRef, originFetchRefspec, parsePorcelainPaths, pullOriginBranch, pushOriginBranch, resetGitExecForTests, resetHardHead, restoreFeatureBranch, 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};
@@ -0,0 +1,3 @@
1
+ import {modules} from './runtime.js';
2
+ const runOrganizationHealthChecks = modules["health-check.js"]["runOrganizationHealthChecks"]
3
+ export {runOrganizationHealthChecks};
@@ -24,6 +24,7 @@ const HYPHENATED_TOKEN_REPLACEMENTS = [
24
24
  ['preview_updates', 'preview-updates'],
25
25
  ['convert_old', 'convert-old'],
26
26
  ['get_detail', 'get-detail'],
27
+ ['health_check', 'health-check'],
27
28
  ['save_detail', 'save-detail'],
28
29
  ['stage_connection', 'stage-connection'],
29
30
  ['run_local', 'run-local'],
@@ -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',
@@ -0,0 +1,16 @@
1
+ import { runOrganizationHealthChecks } from '../health-check.js';
2
+ import { safelyHandleTool } from './result.js';
3
+ async function healthCheck() {
4
+ return runOrganizationHealthChecks();
5
+ }
6
+ export const agentiaMcpHealthCheckToolHandlers = {
7
+ healthCheck,
8
+ };
9
+ export function registerAgentiaMcpHealthCheckTools(server) {
10
+ server.registerTool('agentia_health_check', {
11
+ description: 'Run organization-scoped governance health checks via the CICD gateway.',
12
+ inputSchema: {},
13
+ title: 'Agentia Health Check',
14
+ }, () => safelyHandleTool(() => healthCheck()));
15
+ }
16
+ //# sourceMappingURL=health-check-tools.js.map