@copado/agentia-cli 0.54.0-alpha.0 → 0.56.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ import { AgentiaCommand } from '../../../lib/agentia-command.js';
2
+ import { type WorkCommitResult } from '../../../lib/work-commit.js';
3
+ export default class WorkCommit extends AgentiaCommand {
4
+ static args: {
5
+ id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ action: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'base-branch': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ cloud: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ 'commit-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'execute-commit': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ message: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ 'metadata-category': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ 'metadata-message': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ 'metadata-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
20
+ 'metadata-raw-json': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ 'metadata-type': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
+ 'platform-experience': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
23
+ 'recreate-feature-branch': import("@oclif/core/interfaces").BooleanFlag<boolean>;
24
+ selection: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
26
+ wait: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
+ 'wait-timeout': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
28
+ };
29
+ run(): Promise<WorkCommitResult>;
30
+ protected toErrorJson(err: unknown): unknown;
31
+ }
@@ -0,0 +1,254 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { readFileSync } from 'node:fs';
3
+ import { AgentiaCommand } from '../../../lib/agentia-command.js';
4
+ import { resolveWorkItemId, WorkActiveResolutionError } from '../../../lib/work-active.js';
5
+ import { buildWorkCommitRequest, formatWorkCommitResult, normalizeWorkCommitInput, performWorkCommit, WORK_COMMIT_ACTIONS, WORK_COMMIT_DEFAULT_TIMEOUT_SECONDS, WORK_COMMIT_PLATFORM_EXPERIENCES, WorkCommitJobFailedError, WorkCommitTimeoutError, WorkCommitValidationError, } from '../../../lib/work-commit.js';
6
+ function readStdin() {
7
+ if (process.stdin.isTTY) {
8
+ throw new WorkCommitValidationError('Cannot read --stdin from an interactive terminal. Pipe JSON input or use --file <path>.');
9
+ }
10
+ return new Promise((resolve, reject) => {
11
+ let data = '';
12
+ process.stdin.setEncoding('utf8');
13
+ process.stdin.on('data', (chunk) => {
14
+ data += chunk;
15
+ });
16
+ process.stdin.on('end', () => resolve(data));
17
+ process.stdin.on('error', reject);
18
+ });
19
+ }
20
+ function readJsonFile(path) {
21
+ try {
22
+ return readFileSync(path, 'utf8');
23
+ }
24
+ catch (error) {
25
+ throw new WorkCommitValidationError(`Cannot read JSON request file ${path}: ${error.message}`);
26
+ }
27
+ }
28
+ function parseJsonValue(raw, label) {
29
+ try {
30
+ return JSON.parse(raw);
31
+ }
32
+ catch (error) {
33
+ throw new WorkCommitValidationError(`${label} must contain valid JSON: ${error.message}`);
34
+ }
35
+ }
36
+ function hasSimpleChangeFlags(flags) {
37
+ return (flags.action !== undefined ||
38
+ flags['metadata-category'] !== undefined ||
39
+ flags['metadata-message'] !== undefined ||
40
+ flags['metadata-name'] !== undefined ||
41
+ flags['metadata-raw-json'] !== undefined ||
42
+ flags['metadata-type'] !== undefined ||
43
+ flags.selection !== undefined);
44
+ }
45
+ function simpleInputFromFlags(flags) {
46
+ const rawJson = flags['metadata-raw-json'] === undefined
47
+ ? undefined
48
+ : parseJsonValue(flags['metadata-raw-json'], '--metadata-raw-json');
49
+ return {
50
+ baseBranch: flags['base-branch'] ?? null,
51
+ changes: [
52
+ {
53
+ ...(flags.action === undefined ? {} : { a: flags.action }),
54
+ ...(flags['metadata-category'] === undefined ? {} : { c: flags['metadata-category'] }),
55
+ ...(rawJson === undefined ? {} : { j: rawJson }),
56
+ ...(flags['metadata-message'] === undefined ? {} : { m: flags['metadata-message'] }),
57
+ n: flags['metadata-name'],
58
+ ...(flags.selection === undefined ? {} : { selections: flags.selection }),
59
+ t: flags['metadata-type'],
60
+ },
61
+ ],
62
+ commitId: flags['commit-id'],
63
+ executeCommit: flags['execute-commit'],
64
+ message: flags.message,
65
+ recreateFeatureBranch: flags['recreate-feature-branch'],
66
+ };
67
+ }
68
+ async function jsonInputFromFlags(flags) {
69
+ const raw = flags.file === undefined ? await readStdin() : readJsonFile(flags.file);
70
+ const input = normalizeWorkCommitInput(parseJsonValue(raw, flags.file === undefined ? 'stdin' : flags.file));
71
+ return {
72
+ ...input,
73
+ ...(flags['base-branch'] === undefined ? {} : { baseBranch: flags['base-branch'] }),
74
+ ...(flags['commit-id'] === undefined ? {} : { commitId: flags['commit-id'] }),
75
+ ...(flags['execute-commit'] ? {} : { executeCommit: false }),
76
+ ...(flags.message === undefined ? {} : { message: flags.message }),
77
+ ...(flags['recreate-feature-branch'] ? { recreateFeatureBranch: true } : {}),
78
+ };
79
+ }
80
+ async function commitInputFromFlags(flags) {
81
+ const jsonModes = [flags.file !== undefined, flags.stdin].filter(Boolean).length;
82
+ const simpleMode = hasSimpleChangeFlags(flags);
83
+ if (jsonModes > 1) {
84
+ throw new WorkCommitValidationError('Use only one JSON input mode: --file or --stdin.');
85
+ }
86
+ if (jsonModes > 0 && simpleMode) {
87
+ throw new WorkCommitValidationError('Use JSON input or simple metadata flags, not both.');
88
+ }
89
+ if (jsonModes > 0) {
90
+ return jsonInputFromFlags(flags);
91
+ }
92
+ if (!simpleMode) {
93
+ throw new WorkCommitValidationError('Requires simple metadata flags such as --metadata-name and --metadata-type, or JSON input with --file/--stdin.');
94
+ }
95
+ return simpleInputFromFlags(flags);
96
+ }
97
+ export default class WorkCommit extends AgentiaCommand {
98
+ static args = {
99
+ id: Args.string({
100
+ description: 'User story ID (defaults to the active work item from `work set`)',
101
+ required: false,
102
+ }),
103
+ };
104
+ static description = [
105
+ 'Create and optionally wait for a Copado cloud commit job for a user story.',
106
+ 'Preflights the story, submits POST /release/commit, and polls the job monitor by default.',
107
+ ].join(' ');
108
+ static examples = [
109
+ '<%= config.bin %> <%= command.id %> --cloud --message "Commit AccountService" --metadata-name AccountService --metadata-type ApexClass --action Add',
110
+ '<%= config.bin %> <%= command.id %> a07XXXXXXXXXXXXXXX --cloud --message "Update Aura files" --metadata-name accountEditor --metadata-type AuraDefinitionBundle --action SelectiveCommit --selection accountEditor/accountEditor.cmp --selection accountEditor/accountEditorController.js',
111
+ 'cat commit-request.json | <%= config.bin %> <%= command.id %> --cloud --stdin --json',
112
+ ];
113
+ static flags = {
114
+ action: Flags.string({
115
+ description: 'Metadata action for simple flag input. Defaults to Add.',
116
+ options: [...WORK_COMMIT_ACTIONS],
117
+ }),
118
+ 'base-branch': Flags.string({
119
+ description: 'Optional base branch to include in the commit request.',
120
+ }),
121
+ cloud: Flags.boolean({
122
+ default: false,
123
+ description: 'Use the Copado cloud commit API. Required for this command.',
124
+ }),
125
+ 'commit-id': Flags.string({
126
+ description: 'Existing local Git commit identifier to register when --no-execute-commit is used.',
127
+ }),
128
+ 'execute-commit': Flags.boolean({
129
+ allowNo: true,
130
+ default: true,
131
+ description: 'Execute the Copado commit job. Use --no-execute-commit only with --commit-id.',
132
+ }),
133
+ file: Flags.string({
134
+ char: 'f',
135
+ description: 'Path to a JSON commit request body.',
136
+ }),
137
+ message: Flags.string({
138
+ char: 'm',
139
+ description: 'Commit message. Required unless provided by JSON input.',
140
+ }),
141
+ 'metadata-category': Flags.string({
142
+ description: 'Optional metadata category for simple flag input, usually SFDX.',
143
+ }),
144
+ 'metadata-message': Flags.string({
145
+ description: 'Optional per-change message for simple flag input.',
146
+ }),
147
+ 'metadata-name': Flags.string({
148
+ description: 'Metadata full name for simple flag input.',
149
+ }),
150
+ 'metadata-raw-json': Flags.string({
151
+ description: 'Optional raw metadata JSON value for simple flag input.',
152
+ }),
153
+ 'metadata-type': Flags.string({
154
+ description: 'Metadata type for simple flag input, for example ApexClass.',
155
+ }),
156
+ 'platform-experience': Flags.string({
157
+ default: 'sfdx',
158
+ description: 'Initial platform-experience header for preflight. The preflight response wins for commit.',
159
+ options: [...WORK_COMMIT_PLATFORM_EXPERIENCES],
160
+ }),
161
+ 'recreate-feature-branch': Flags.boolean({
162
+ default: false,
163
+ description: 'Ask Copado to recreate the feature branch before committing.',
164
+ }),
165
+ selection: Flags.string({
166
+ description: 'Selected file inside a bundle for SelectiveCommit. Can be provided multiple times.',
167
+ multiple: true,
168
+ }),
169
+ stdin: Flags.boolean({
170
+ default: false,
171
+ description: 'Read a JSON commit request body from stdin.',
172
+ }),
173
+ wait: Flags.boolean({
174
+ allowNo: true,
175
+ default: true,
176
+ description: 'Poll the commit job to a terminal status when a jobExecution Id is returned.',
177
+ }),
178
+ 'wait-timeout': Flags.integer({
179
+ default: WORK_COMMIT_DEFAULT_TIMEOUT_SECONDS,
180
+ description: 'Maximum seconds to wait for the commit job.',
181
+ }),
182
+ };
183
+ async run() {
184
+ const { args, flags } = await this.parse(WorkCommit);
185
+ const commitFlags = flags;
186
+ if (!commitFlags.cloud) {
187
+ this.error('Only cloud commit is supported for now. Pass --cloud to use POST /release/commit.', { exit: 2 });
188
+ }
189
+ if (!Number.isInteger(commitFlags['wait-timeout']) || commitFlags['wait-timeout'] <= 0) {
190
+ this.error('--wait-timeout must be a positive integer.', { exit: 2 });
191
+ }
192
+ let workItemId;
193
+ try {
194
+ workItemId = await resolveWorkItemId(args.id);
195
+ }
196
+ catch (error) {
197
+ if (error instanceof WorkActiveResolutionError) {
198
+ this.error(error.message, {
199
+ exit: 1,
200
+ suggestions: [`${this.config.bin} cicd work set <id>`],
201
+ });
202
+ }
203
+ throw error;
204
+ }
205
+ try {
206
+ const input = await commitInputFromFlags(commitFlags);
207
+ const request = buildWorkCommitRequest(input, { message: commitFlags.message, userStoryId: workItemId });
208
+ const result = await performWorkCommit({
209
+ hooks: {
210
+ log: (message) => this.display(() => this.log(message)),
211
+ withSpinner: (message, action) => this.withSpinner(message, action),
212
+ },
213
+ initialPlatformExperience: commitFlags['platform-experience'],
214
+ request,
215
+ timeoutSeconds: commitFlags['wait-timeout'],
216
+ wait: commitFlags.wait,
217
+ });
218
+ this.display(() => {
219
+ this.log(formatWorkCommitResult(result));
220
+ });
221
+ return result;
222
+ }
223
+ catch (error) {
224
+ if (error instanceof WorkCommitValidationError) {
225
+ this.error(error.message, { exit: 2 });
226
+ }
227
+ if (error instanceof WorkCommitJobFailedError || error instanceof WorkCommitTimeoutError) {
228
+ this.display(() => {
229
+ if (error.result !== undefined) {
230
+ this.log(formatWorkCommitResult(error.result));
231
+ }
232
+ });
233
+ error.oclif = { exit: 1 };
234
+ throw error;
235
+ }
236
+ throw error;
237
+ }
238
+ }
239
+ toErrorJson(err) {
240
+ const base = super.toErrorJson(err);
241
+ if (err instanceof WorkCommitJobFailedError || err instanceof WorkCommitTimeoutError) {
242
+ return {
243
+ ...base,
244
+ error: {
245
+ ...(base.error && typeof base.error === 'object' ? base.error : {}),
246
+ ...(err.jobMonitor === undefined ? {} : { jobMonitor: err.jobMonitor }),
247
+ ...(err.result === undefined ? {} : { result: err.result }),
248
+ },
249
+ };
250
+ }
251
+ return base;
252
+ }
253
+ }
254
+ //# sourceMappingURL=commit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commit.js","sourceRoot":"","sources":["../../../../src/commands/cicd/work/commit.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,9 @@ export declare function toolError(error: unknown): {
13
13
  isError: boolean;
14
14
  structuredContent: {
15
15
  error: {
16
+ result?: {} | null | undefined;
16
17
  message: string;
18
+ jobMonitor?: {} | null | undefined;
17
19
  };
18
20
  };
19
21
  };
@@ -31,7 +33,9 @@ export declare function safelyHandleTool(handler: () => Promise<Record<string, u
31
33
  isError: boolean;
32
34
  structuredContent: {
33
35
  error: {
36
+ result?: {} | null | undefined;
34
37
  message: string;
38
+ jobMonitor?: {} | null | undefined;
35
39
  };
36
40
  };
37
41
  }>;
@@ -12,20 +12,24 @@ export function toolResult(data) {
12
12
  };
13
13
  }
14
14
  export function toolError(error) {
15
+ const structured = error && typeof error === 'object' ? error : {};
15
16
  const payload = {
16
17
  error: {
18
+ ...(structured.jobMonitor === undefined ? {} : { jobMonitor: structured.jobMonitor }),
17
19
  message: redactErrorMessage(error),
20
+ ...(structured.result === undefined ? {} : { result: structured.result }),
18
21
  },
19
22
  };
23
+ const redacted = redactSecrets(payload);
20
24
  return {
21
25
  content: [
22
26
  {
23
- text: JSON.stringify(payload, null, 2),
27
+ text: JSON.stringify(redacted, null, 2),
24
28
  type: 'text',
25
29
  },
26
30
  ],
27
31
  isError: true,
28
- structuredContent: payload,
32
+ structuredContent: redacted,
29
33
  };
30
34
  }
31
35
  export async function safelyHandleTool(handler) {
@@ -1 +1 @@
1
- {"version":3,"file":"result.js","sourceRoot":"","sources":["../../../src/lib/mcp/result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAA;AAEhE,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAEpC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,MAAe;aACtB;SACF;QACD,iBAAiB,EAAE,QAAQ;KAC5B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,MAAM,OAAO,GAAG;QACd,KAAK,EAAE;YACL,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC;SACnC;KACF,CAAA;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtC,IAAI,EAAE,MAAe;aACtB;SACF;QACD,OAAO,EAAE,IAAI;QACb,iBAAiB,EAAE,OAAO;KAC3B,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA+C;IACpF,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,MAAM,OAAO,EAAE,CAAC,CAAA;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,SAAS,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../../src/lib/mcp/result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAA;AAEhE,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAEpC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,MAAe;aACtB;SACF;QACD,iBAAiB,EAAE,QAAQ;KAC5B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,MAAM,UAAU,GAAG,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAE,KAAiC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC/F,MAAM,OAAO,GAAG;QACd,KAAK,EAAE;YACL,GAAG,CAAC,UAAU,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,UAAU,EAAE,UAAU,CAAC,UAAU,EAAC,CAAC;YACnF,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC;YAClC,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,MAAM,EAAE,UAAU,CAAC,MAAM,EAAC,CAAC;SACxE;KACF,CAAA;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IAEvC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,MAAe;aACtB;SACF;QACD,OAAO,EAAE,IAAI;QACb,iBAAiB,EAAE,QAAQ;KAC5B,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA+C;IACpF,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,MAAM,OAAO,EAAE,CAAC,CAAA;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,SAAS,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;AACH,CAAC"}
@@ -419,6 +419,27 @@ declare function navigationResolve(args: {
419
419
  resourceType: (typeof NAVIGATION_RESOURCE_TYPES)[number];
420
420
  }): Promise<import("../navigation.js").NavigationTarget>;
421
421
  export declare const agentiaMcpToolHandlers: {
422
+ workCommit: (args?: {
423
+ action?: import("../work-commit.js").WorkCommitAction;
424
+ baseBranch?: null | string;
425
+ changes?: unknown[];
426
+ cloud?: boolean;
427
+ commitId?: string;
428
+ dataTemplateSyncConfig?: unknown[];
429
+ executeCommit?: boolean;
430
+ id?: string;
431
+ message?: string;
432
+ metadataCategory?: string;
433
+ metadataMessage?: string;
434
+ metadataName?: string;
435
+ metadataRawJson?: unknown;
436
+ metadataType?: string;
437
+ platformExperience?: import("../work-commit.js").WorkCommitPlatformExperience;
438
+ recreateFeatureBranch?: boolean;
439
+ selection?: string[];
440
+ wait?: boolean;
441
+ waitTimeout?: number;
442
+ }) => Promise<import("../work-commit.js").WorkCommitResult>;
422
443
  workCreate: (args?: Partial<import("../work-types.js").UserStoryMutationPayload>) => Promise<{
423
444
  userStory: import("../work-types.js").UserStory;
424
445
  }>;
@@ -1,4 +1,5 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { type WorkCommitAction, type WorkCommitPlatformExperience } from '../work-commit.js';
2
3
  import { type HeadlessCommandResult, type UserStory, type UserStoryMutationPayload, type WorkListFilters, type WorkSetResult, type WorkTestResult } from '../work-types.js';
3
4
  type WorkMutationInput = Partial<UserStoryMutationPayload>;
4
5
  type WorkListArgs = WorkListFilters & {
@@ -27,6 +28,27 @@ type WorkTestArgs = {
27
28
  apexTestClasses?: string;
28
29
  local?: boolean;
29
30
  };
31
+ type WorkCommitArgs = {
32
+ action?: WorkCommitAction;
33
+ baseBranch?: null | string;
34
+ changes?: unknown[];
35
+ cloud?: boolean;
36
+ commitId?: string;
37
+ dataTemplateSyncConfig?: unknown[];
38
+ executeCommit?: boolean;
39
+ id?: string;
40
+ message?: string;
41
+ metadataCategory?: string;
42
+ metadataMessage?: string;
43
+ metadataName?: string;
44
+ metadataRawJson?: unknown;
45
+ metadataType?: string;
46
+ platformExperience?: WorkCommitPlatformExperience;
47
+ recreateFeatureBranch?: boolean;
48
+ selection?: string[];
49
+ wait?: boolean;
50
+ waitTimeout?: number;
51
+ };
30
52
  declare function workList(args?: WorkListArgs): Promise<Record<string, unknown>>;
31
53
  declare function workGet(args?: WorkGetArgs): Promise<{
32
54
  userStory: UserStory;
@@ -52,6 +74,7 @@ declare function workSubmit(args?: WorkSubmitArgs): Promise<{
52
74
  workItem: string;
53
75
  }>;
54
76
  declare function workTest(args?: WorkTestArgs): Promise<WorkTestResult>;
77
+ declare function workCommit(args?: WorkCommitArgs): Promise<import("../work-commit.js").WorkCommitResult>;
55
78
  declare function workDone(): Promise<{
56
79
  branch: string;
57
80
  done: HeadlessCommandResult;
@@ -60,6 +83,7 @@ declare function workDone(): Promise<{
60
83
  workItem: string;
61
84
  }>;
62
85
  export declare const agentiaMcpWorkToolHandlers: {
86
+ workCommit: typeof workCommit;
63
87
  workCreate: typeof workCreate;
64
88
  workDelete: typeof workDelete;
65
89
  workDone: typeof workDone;
@@ -8,6 +8,7 @@ import { LocalQualityGatesError, runLocalQualityGates } from '../local-quality-g
8
8
  import { PROJECT_DEFAULT_KEYS } from '../project-defaults.js';
9
9
  import { getUserContext } from '../user-context.js';
10
10
  import { resolveWorkItemId } from '../work-active.js';
11
+ import { buildWorkCommitRequest, normalizeWorkCommitInput, performWorkCommit, WORK_COMMIT_ACTIONS, WORK_COMMIT_DEFAULT_TIMEOUT_SECONDS, WORK_COMMIT_PLATFORM_EXPERIENCES, } from '../work-commit.js';
11
12
  import { buildWorkCreatePayload } from '../work-defaults.js';
12
13
  import { validateNonEmptyStringFields as validateWorkNonEmptyStringFields, WORK_STRING_VALIDATION_KEYS, } from '../work-flags.js';
13
14
  import { reportLocalQualityGatesFailure, reportLocalQualityGatesOutcome, } from '../work-local-run-tests.js';
@@ -340,6 +341,70 @@ async function workTest(args = {}) {
340
341
  qualityGates,
341
342
  };
342
343
  }
344
+ function hasMcpSimpleCommitArgs(args) {
345
+ return (args.action !== undefined ||
346
+ args.metadataCategory !== undefined ||
347
+ args.metadataMessage !== undefined ||
348
+ args.metadataName !== undefined ||
349
+ args.metadataRawJson !== undefined ||
350
+ args.metadataType !== undefined ||
351
+ args.selection !== undefined);
352
+ }
353
+ async function workCommit(args = {}) {
354
+ if (args.cloud !== true) {
355
+ throw new Error('Only cloud=true is supported for now. Pass cloud: true to use POST /release/commit.');
356
+ }
357
+ if (args.changes !== undefined && hasMcpSimpleCommitArgs(args)) {
358
+ throw new Error('Use changes or simple metadata fields, not both.');
359
+ }
360
+ if (args.changes === undefined && !hasMcpSimpleCommitArgs(args)) {
361
+ throw new Error('Requires simple metadata fields such as metadataName and metadataType, or changes input.');
362
+ }
363
+ const workItemId = await resolveWorkItemId(args.id);
364
+ const input = args.changes === undefined
365
+ ? {
366
+ baseBranch: args.baseBranch ?? null,
367
+ changes: [
368
+ {
369
+ ...(args.action === undefined ? {} : { a: args.action }),
370
+ ...(args.metadataCategory === undefined ? {} : { c: args.metadataCategory }),
371
+ ...(args.metadataRawJson === undefined ? {} : { j: args.metadataRawJson }),
372
+ ...(args.metadataMessage === undefined ? {} : { m: args.metadataMessage }),
373
+ n: args.metadataName,
374
+ ...(args.selection === undefined ? {} : { selections: args.selection }),
375
+ t: args.metadataType,
376
+ },
377
+ ],
378
+ commitId: args.commitId,
379
+ executeCommit: args.executeCommit,
380
+ message: args.message,
381
+ recreateFeatureBranch: args.recreateFeatureBranch,
382
+ }
383
+ : normalizeWorkCommitInput({
384
+ baseBranch: args.baseBranch,
385
+ changes: args.changes,
386
+ commitId: args.commitId,
387
+ dataTemplateSyncConfig: args.dataTemplateSyncConfig,
388
+ executeCommit: args.executeCommit,
389
+ message: args.message,
390
+ recreateFeatureBranch: args.recreateFeatureBranch,
391
+ });
392
+ const request = buildWorkCommitRequest(input, { message: args.message, userStoryId: workItemId });
393
+ const waitTimeout = args.waitTimeout ?? WORK_COMMIT_DEFAULT_TIMEOUT_SECONDS;
394
+ if (!Number.isInteger(waitTimeout) || waitTimeout <= 0) {
395
+ throw new Error('waitTimeout must be a positive integer.');
396
+ }
397
+ return performWorkCommit({
398
+ hooks: {
399
+ log() { },
400
+ withSpinner: async (_message, action) => action(),
401
+ },
402
+ initialPlatformExperience: args.platformExperience,
403
+ request,
404
+ timeoutSeconds: waitTimeout,
405
+ wait: args.wait ?? true,
406
+ });
407
+ }
343
408
  async function workDone() {
344
409
  const { branch, workItem } = await requireFeatureBranchWorkItem();
345
410
  await requireCleanTrackedTree('work done');
@@ -372,6 +437,7 @@ async function workDone() {
372
437
  };
373
438
  }
374
439
  export const agentiaMcpWorkToolHandlers = {
440
+ workCommit,
375
441
  workCreate,
376
442
  workDelete,
377
443
  workDone,
@@ -474,6 +540,46 @@ export function registerAgentiaMcpWorkTools(server) {
474
540
  inputSchema: {},
475
541
  title: 'Agentia Work Push',
476
542
  }, () => safelyHandleTool(() => workPush()));
543
+ server.registerTool('agentia_work_commit', {
544
+ description: 'Create and optionally wait for a Copado cloud commit job. Use simple metadata fields for one change or changes for multi-change requests.',
545
+ inputSchema: {
546
+ action: z.enum(WORK_COMMIT_ACTIONS).optional().describe('Metadata action for simple input. Defaults to Add.'),
547
+ baseBranch: z.string().nullable().optional().describe('Optional base branch included in the commit request.'),
548
+ changes: z
549
+ .array(z.record(z.string(), z.unknown()))
550
+ .optional()
551
+ .describe('Commit changes using API aliases or field names. Mutually exclusive with simple metadata fields.'),
552
+ cloud: z.boolean().optional().describe('Must be true for now. Uses POST /release/commit.'),
553
+ commitId: z
554
+ .string()
555
+ .optional()
556
+ .describe('Existing local Git commit identifier to register when executeCommit is false.'),
557
+ dataTemplateSyncConfig: z
558
+ .array(z.unknown())
559
+ .optional()
560
+ .describe('Optional data-template synchronization configuration.'),
561
+ executeCommit: z.boolean().optional().describe('Execute the Copado commit job. Defaults to true.'),
562
+ id: z.string().optional().describe('User story Id. Defaults to the active work item from work set.'),
563
+ message: z.string().optional().describe('Commit message. Required unless supplied in the request body.'),
564
+ metadataCategory: z.string().optional().describe('Optional metadata category for simple input, usually SFDX.'),
565
+ metadataMessage: z.string().optional().describe('Optional per-change message for simple input.'),
566
+ metadataName: z.string().optional().describe('Metadata full name for simple input.'),
567
+ metadataRawJson: z.unknown().optional().describe('Optional raw metadata JSON value for simple input.'),
568
+ metadataType: z.string().optional().describe('Metadata type for simple input, for example ApexClass.'),
569
+ platformExperience: z
570
+ .enum(WORK_COMMIT_PLATFORM_EXPERIENCES)
571
+ .optional()
572
+ .describe('Initial platform-experience header. The preflight response wins for commit.'),
573
+ recreateFeatureBranch: z.boolean().optional().describe('Ask Copado to recreate the feature branch.'),
574
+ selection: z
575
+ .array(z.string())
576
+ .optional()
577
+ .describe('Selected files inside a bundle for SelectiveCommit simple input.'),
578
+ wait: z.boolean().optional().describe('Poll the commit job to a terminal status. Defaults to true.'),
579
+ waitTimeout: z.number().int().optional().describe('Maximum seconds to wait for the commit job. Defaults to 300.'),
580
+ },
581
+ title: 'Agentia Work Commit',
582
+ }, (args) => safelyHandleTool(() => workCommit(args || {})));
477
583
  server.registerTool('agentia_work_submit', {
478
584
  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 pushes and registers commits when the branch is ahead of origin.',
479
585
  inputSchema: {