@copado/agentia-cli 0.115.0-alpha.0 → 0.117.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.
Files changed (73) hide show
  1. package/README.md +370 -357
  2. package/dist/commands/cicd/work/commit.d.ts +0 -5
  3. package/dist/commands/cicd/work/commit.js +18 -33
  4. package/dist/commands/cicd/work/commit.js.map +1 -1
  5. package/dist/commands/cicd/work/publish.d.ts +12 -0
  6. package/dist/commands/cicd/work/publish.js +20 -0
  7. package/dist/commands/cicd/work/publish.js.map +1 -0
  8. package/dist/commands/cicd/work/push.d.ts +4 -0
  9. package/dist/commands/cicd/work/push.js +11 -81
  10. package/dist/commands/cicd/work/push.js.map +1 -1
  11. package/dist/commands/cicd/work/set.d.ts +2 -2
  12. package/dist/commands/cicd/work/set.js +6 -2
  13. package/dist/commands/cicd/work/set.js.map +1 -1
  14. package/dist/commands/cicd/work/status.js +14 -13
  15. package/dist/commands/cicd/work/status.js.map +1 -1
  16. package/dist/commands/cicd/work/submit.d.ts +2 -0
  17. package/dist/commands/cicd/work/submit.js +11 -3
  18. package/dist/commands/cicd/work/submit.js.map +1 -1
  19. package/dist/commands/cicd/work/test/apex.d.ts +11 -0
  20. package/dist/commands/cicd/work/test/apex.js +57 -0
  21. package/dist/commands/cicd/work/test/apex.js.map +1 -0
  22. package/dist/commands/cicd/work/test.js +12 -4
  23. package/dist/commands/cicd/work/test.js.map +1 -1
  24. package/dist/lib/cicd-gateway.d.ts +3 -0
  25. package/dist/lib/cicd-gateway.js +35 -2
  26. package/dist/lib/cicd-gateway.js.map +1 -1
  27. package/dist/lib/defaults-store.d.ts +1 -1
  28. package/dist/lib/defaults-store.js +1 -1
  29. package/dist/lib/git-worktree.d.ts +13 -5
  30. package/dist/lib/git-worktree.js +49 -11
  31. package/dist/lib/git-worktree.js.map +1 -1
  32. package/dist/lib/local-quality-gates.d.ts +4 -0
  33. package/dist/lib/local-quality-gates.js +1 -1
  34. package/dist/lib/local-quality-gates.js.map +1 -1
  35. package/dist/lib/mcp/tools.d.ts +12 -2
  36. package/dist/lib/mcp/tools.js +10 -8
  37. package/dist/lib/mcp/tools.js.map +1 -1
  38. package/dist/lib/mcp/work-tools.d.ts +18 -6
  39. package/dist/lib/mcp/work-tools.js +75 -50
  40. package/dist/lib/mcp/work-tools.js.map +1 -1
  41. package/dist/lib/nested-metadata-changes.d.ts +4 -4
  42. package/dist/lib/setup-templates.d.ts +3 -3
  43. package/dist/lib/setup-templates.js +34 -29
  44. package/dist/lib/setup-templates.js.map +1 -1
  45. package/dist/lib/setup-wizard.js +1 -1
  46. package/dist/lib/setup-wizard.js.map +1 -1
  47. package/dist/lib/stock-quality-gates.d.ts +12 -0
  48. package/dist/lib/stock-quality-gates.js +67 -0
  49. package/dist/lib/stock-quality-gates.js.map +1 -0
  50. package/dist/lib/work-apex-test.d.ts +56 -0
  51. package/dist/lib/work-apex-test.js +265 -0
  52. package/dist/lib/work-apex-test.js.map +1 -0
  53. package/dist/lib/work-branch-metadata.d.ts +2 -0
  54. package/dist/lib/work-branch-metadata.js +9 -0
  55. package/dist/lib/work-branch-metadata.js.map +1 -1
  56. package/dist/lib/work-local-commit.d.ts +1 -1
  57. package/dist/lib/work-local-commit.js +1 -1
  58. package/dist/lib/work-publish-command.d.ts +26 -0
  59. package/dist/lib/work-publish-command.js +88 -0
  60. package/dist/lib/work-publish-command.js.map +1 -0
  61. package/dist/lib/work-push.d.ts +6 -5
  62. package/dist/lib/work-push.js +30 -22
  63. package/dist/lib/work-push.js.map +1 -1
  64. package/dist/lib/work-set-selection.d.ts +3 -1
  65. package/dist/lib/work-set-selection.js +19 -1
  66. package/dist/lib/work-set-selection.js.map +1 -1
  67. package/dist/lib/work-types.d.ts +12 -1
  68. package/dist/lib/work-types.js.map +1 -1
  69. package/oclif.manifest.json +2231 -2151
  70. package/package.json +4 -1
  71. package/templates/AGENTS.md +2 -2
  72. package/templates/skills/agentia-cicd/SKILL.md +4 -3
  73. package/templates/skills/agentia-cicd/references/work.md +25 -23
@@ -0,0 +1,265 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { getMcpRequestSignal } from './mcp/request-context.js';
4
+ const execFileAsync = promisify(execFile);
5
+ export const DEFAULT_APEX_TEST_WAIT_MINUTES = 60;
6
+ const APEX_TEST_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
7
+ const APEX_TEST_TIMEOUT_BUFFER_MS = 60_000;
8
+ const APEX_CLASS_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)?$/;
9
+ const ORG_ID_PATTERN = /\b00D[A-Za-z0-9]{12,15}\b/g;
10
+ const USER_ID_PATTERN = /\b005[A-Za-z0-9]{12,15}\b/g;
11
+ const FAILED_OUTCOMES = new Set(['compilefail', 'fail']);
12
+ export class WorkApexTestError extends Error {
13
+ result;
14
+ constructor(result) {
15
+ const failing = result.summary.failing ?? result.tests.filter((test) => isFailedOutcome(test.outcome)).length;
16
+ super(`Apex tests failed (${failing} failing).`);
17
+ this.name = 'WorkApexTestError';
18
+ this.result = result;
19
+ }
20
+ }
21
+ let sfApexTestExecFn = defaultSfApexTestExec;
22
+ export function buildSfApexTestArgs(classNames, waitMinutes) {
23
+ return ['apex', 'run', 'test', '--class-names', ...classNames, '-c', '--json', '--wait', String(waitMinutes)];
24
+ }
25
+ export function parseApexTestClassNames(value) {
26
+ const names = value
27
+ .split(/[,\s]+/)
28
+ .map((name) => name.trim())
29
+ .filter((name) => name.length > 0);
30
+ if (names.length === 0) {
31
+ throw new Error('Requires `--apex-test-classes`.');
32
+ }
33
+ const unique = [];
34
+ const seen = new Set();
35
+ for (const name of names) {
36
+ if (!APEX_CLASS_NAME_PATTERN.test(name)) {
37
+ throw new Error(`Invalid Apex test class name '${name}'. Use identifiers such as MyTest or Namespace.MyTest.`);
38
+ }
39
+ if (seen.has(name)) {
40
+ continue;
41
+ }
42
+ seen.add(name);
43
+ unique.push(name);
44
+ }
45
+ return unique;
46
+ }
47
+ export function validateApexTestWaitMinutes(waitMinutes) {
48
+ if (!Number.isInteger(waitMinutes) || waitMinutes < 1) {
49
+ throw new Error('`--wait` must be a positive integer number of minutes.');
50
+ }
51
+ return waitMinutes;
52
+ }
53
+ export function formatWorkApexTestHuman(result) {
54
+ const failedTests = result.tests.filter((test) => isFailedOutcome(test.outcome));
55
+ const lines = [
56
+ `Apex tests: ${result.summary.outcome ?? (failedTests.length === 0 ? 'Passed' : 'Failed')}`,
57
+ ...summaryLines(result.summary),
58
+ ];
59
+ if (failedTests.length === 0) {
60
+ return lines.join('\n');
61
+ }
62
+ return [
63
+ ...lines,
64
+ '',
65
+ 'Failed tests:',
66
+ ...failedTests.flatMap((test) => [
67
+ '',
68
+ testLabel(test),
69
+ ...(test.outcome === undefined ? [] : [` Outcome: ${test.outcome}`]),
70
+ ...(test.message === undefined ? [] : [` Message: ${test.message}`]),
71
+ ...(test.stackTrace === undefined ? [] : [` StackTrace: ${test.stackTrace}`]),
72
+ ]),
73
+ ].join('\n');
74
+ }
75
+ export async function runWorkApexTests({ classNames, waitMinutes: requestedWaitMinutes, }) {
76
+ const waitMinutes = validateApexTestWaitMinutes(requestedWaitMinutes);
77
+ const args = buildSfApexTestArgs(classNames, waitMinutes);
78
+ let stdout;
79
+ try {
80
+ const executed = await sfApexTestExecFn(args, {
81
+ maxBuffer: APEX_TEST_MAX_BUFFER_BYTES,
82
+ signal: getMcpRequestSignal(),
83
+ timeout: waitMinutes * 60 * 1000 + APEX_TEST_TIMEOUT_BUFFER_MS,
84
+ });
85
+ stdout = executed.stdout;
86
+ }
87
+ catch (error) {
88
+ throw new Error(sanitizeApexTestError(error));
89
+ }
90
+ const parsed = extractJsonObject(stdout);
91
+ if (parsed.result === undefined) {
92
+ throw new Error(sanitizeApexTestError(parsed.message ?? parsed.name ?? 'Salesforce CLI Apex test run failed.'));
93
+ }
94
+ const result = parseSfApexTestJson(stdout, classNames, waitMinutes);
95
+ if (isTestRunFailed(result)) {
96
+ throw new WorkApexTestError(result);
97
+ }
98
+ if (typeof parsed.status === 'number' && parsed.status !== 0) {
99
+ throw new Error(sanitizeApexTestError(parsed.message ?? parsed.name ?? 'Salesforce CLI Apex test run failed.'));
100
+ }
101
+ return result;
102
+ }
103
+ export function parseSfApexTestJson(raw, classNames, waitMinutes) {
104
+ const parsed = extractJsonObject(raw);
105
+ if (parsed.result === undefined) {
106
+ throw new Error(sanitizeApexTestError(parsed.message ?? parsed.name ?? 'Salesforce CLI Apex test run failed.'));
107
+ }
108
+ const tests = (parsed.result.tests ?? []).flatMap((item) => {
109
+ const mapped = mapTestMethod(item);
110
+ return mapped === undefined ? [] : [mapped];
111
+ });
112
+ const summary = mapSummary(parsed.result.summary ?? {});
113
+ return {
114
+ classNames,
115
+ summary,
116
+ tests,
117
+ waitMinutes,
118
+ };
119
+ }
120
+ export function setSfApexTestExecForTests(fn) {
121
+ sfApexTestExecFn = fn;
122
+ }
123
+ export function resetSfApexTestExecForTests() {
124
+ sfApexTestExecFn = defaultSfApexTestExec;
125
+ }
126
+ async function defaultSfApexTestExec(args, options) {
127
+ try {
128
+ const { stderr, stdout } = await execFileAsync('sf', args, {
129
+ encoding: 'utf8',
130
+ maxBuffer: options.maxBuffer,
131
+ signal: options.signal,
132
+ timeout: options.timeout,
133
+ });
134
+ return { stderr: stderr.toString(), stdout: stdout.toString() };
135
+ }
136
+ catch (error) {
137
+ if (isExecFileError(error) && typeof error.stdout === 'string' && error.stdout.trim().length > 0) {
138
+ return {
139
+ stderr: typeof error.stderr === 'string' ? error.stderr : '',
140
+ stdout: error.stdout,
141
+ };
142
+ }
143
+ throw error;
144
+ }
145
+ }
146
+ function extractJsonObject(raw) {
147
+ const start = raw.indexOf('{');
148
+ if (start === -1) {
149
+ throw new Error('Salesforce CLI returned non-JSON output.');
150
+ }
151
+ return JSON.parse(raw.slice(start));
152
+ }
153
+ function mapSummary(summary) {
154
+ return {
155
+ ...(optionalString(summary.commandTime) === undefined ? {} : { commandTime: optionalString(summary.commandTime) }),
156
+ ...(optionalString(summary.failRate) === undefined ? {} : { failRate: optionalString(summary.failRate) }),
157
+ ...(optionalNumber(summary.failing) === undefined ? {} : { failing: optionalNumber(summary.failing) }),
158
+ ...(optionalString(summary.orgWideCoverage) === undefined
159
+ ? {}
160
+ : { orgWideCoverage: optionalString(summary.orgWideCoverage) }),
161
+ ...(optionalString(summary.outcome) === undefined ? {} : { outcome: optionalString(summary.outcome) }),
162
+ ...(optionalString(summary.passRate) === undefined ? {} : { passRate: optionalString(summary.passRate) }),
163
+ ...(optionalNumber(summary.passing) === undefined ? {} : { passing: optionalNumber(summary.passing) }),
164
+ ...(optionalNumber(summary.skipped) === undefined ? {} : { skipped: optionalNumber(summary.skipped) }),
165
+ ...(optionalString(summary.testExecutionTime) === undefined
166
+ ? {}
167
+ : { testExecutionTime: optionalString(summary.testExecutionTime) }),
168
+ ...(optionalString(summary.testRunCoverage) === undefined
169
+ ? {}
170
+ : { testRunCoverage: optionalString(summary.testRunCoverage) }),
171
+ ...(optionalString(summary.testRunId) === undefined ? {} : { testRunId: optionalString(summary.testRunId) }),
172
+ ...(optionalString(summary.testStartTime) === undefined
173
+ ? {}
174
+ : { testStartTime: optionalString(summary.testStartTime) }),
175
+ ...(optionalString(summary.testTotalTime) === undefined ? {} : { testTotalTime: optionalString(summary.testTotalTime) }),
176
+ ...(optionalNumber(summary.testsRan) === undefined ? {} : { testsRan: optionalNumber(summary.testsRan) }),
177
+ };
178
+ }
179
+ function mapTestMethod(value) {
180
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
181
+ return undefined;
182
+ }
183
+ const record = value;
184
+ const apexClass = record.ApexClass !== null && typeof record.ApexClass === 'object' && !Array.isArray(record.ApexClass)
185
+ ? record.ApexClass
186
+ : undefined;
187
+ const mapped = {
188
+ ...(optionalString(apexClass?.Name) === undefined ? {} : { className: optionalString(apexClass?.Name) }),
189
+ ...(optionalString(record.FullName) === undefined ? {} : { fullName: optionalString(record.FullName) }),
190
+ ...(optionalString(record.Message) === undefined ? {} : { message: optionalString(record.Message) }),
191
+ ...(optionalString(record.MethodName) === undefined ? {} : { methodName: optionalString(record.MethodName) }),
192
+ ...(optionalString(record.Outcome) === undefined ? {} : { outcome: optionalString(record.Outcome) }),
193
+ ...(optionalString(record.StackTrace) === undefined ? {} : { stackTrace: optionalString(record.StackTrace) }),
194
+ };
195
+ return Object.keys(mapped).length === 0 ? undefined : mapped;
196
+ }
197
+ function isTestRunFailed(result) {
198
+ if (result.tests.some((test) => isFailedOutcome(test.outcome))) {
199
+ return true;
200
+ }
201
+ const outcome = result.summary.outcome?.trim().toLowerCase();
202
+ return outcome === 'failed' || (result.summary.failing ?? 0) > 0;
203
+ }
204
+ function isFailedOutcome(outcome) {
205
+ return outcome !== undefined && FAILED_OUTCOMES.has(outcome.trim().toLowerCase());
206
+ }
207
+ function testLabel(test) {
208
+ if (test.fullName !== undefined && test.fullName.length > 0) {
209
+ return test.fullName;
210
+ }
211
+ const joined = [test.className, test.methodName]
212
+ .filter((part) => part !== undefined && part.length > 0)
213
+ .join('.');
214
+ return joined.length > 0 ? joined : 'unknown test';
215
+ }
216
+ function summaryLines(summary) {
217
+ const lines = [];
218
+ pushLine(lines, 'Tests ran', summary.testsRan);
219
+ pushLine(lines, 'Passing', summary.passing);
220
+ pushLine(lines, 'Failing', summary.failing);
221
+ pushLine(lines, 'Skipped', summary.skipped);
222
+ pushLine(lines, 'Pass rate', summary.passRate);
223
+ pushLine(lines, 'Fail rate', summary.failRate);
224
+ pushLine(lines, 'Test run coverage', summary.testRunCoverage);
225
+ pushLine(lines, 'Org-wide coverage', summary.orgWideCoverage);
226
+ pushLine(lines, 'Test execution time', summary.testExecutionTime);
227
+ return lines;
228
+ }
229
+ function pushLine(lines, label, value) {
230
+ if (value === undefined || value === '') {
231
+ return;
232
+ }
233
+ lines.push(`${label}: ${value}`);
234
+ }
235
+ function optionalString(value) {
236
+ if (typeof value !== 'string') {
237
+ return undefined;
238
+ }
239
+ const sanitized = sanitizeIdentity(value).trim();
240
+ return sanitized.length === 0 ? undefined : sanitized;
241
+ }
242
+ function optionalNumber(value) {
243
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
244
+ }
245
+ function sanitizeApexTestError(error) {
246
+ if (isExecFileError(error) && error.code === 'ENOENT') {
247
+ return 'Salesforce CLI (`sf`) is not installed or is not on PATH.';
248
+ }
249
+ if (error instanceof Error && error.name === 'AbortError') {
250
+ return 'Apex test run was cancelled.';
251
+ }
252
+ const message = error instanceof Error ? error.message : String(error);
253
+ const cleaned = sanitizeIdentity(message).trim();
254
+ if (cleaned.length === 0) {
255
+ return 'Salesforce CLI Apex test run failed.';
256
+ }
257
+ return `Salesforce CLI Apex test run failed: ${cleaned}`;
258
+ }
259
+ function sanitizeIdentity(value) {
260
+ return value.replaceAll(ORG_ID_PATTERN, '<org-id>').replaceAll(USER_ID_PATTERN, '<user-id>');
261
+ }
262
+ function isExecFileError(error) {
263
+ return error instanceof Error;
264
+ }
265
+ //# sourceMappingURL=work-apex-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-apex-test.js","sourceRoot":"","sources":["../../src/lib/work-apex-test.ts"],"names":[],"mappings":"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"}
@@ -9,3 +9,5 @@ export type WorkBranchMetadataResult = {
9
9
  metadataList: WorkBranchMetadataItem[];
10
10
  };
11
11
  export declare function resolveWorkBranchMetadata(baseRef: string, moduleType?: ModuleType): Promise<WorkBranchMetadataResult>;
12
+ /** Local branch metadata when `work set` recorded lastBaseBranch; otherwise undefined. */
13
+ export declare function resolveRecordedWorkBranchMetadata(moduleType?: ModuleType): Promise<undefined | WorkBranchMetadataResult>;
@@ -1,3 +1,4 @@
1
+ import { readLastBaseBranch } from './defaults-store.js';
1
2
  import { resolvedSelectionsFromChangedFiles } from './dependency-from-changes.js';
2
3
  const NO_METADATA_MESSAGES = [
3
4
  'No changed files were found',
@@ -28,4 +29,12 @@ export async function resolveWorkBranchMetadata(baseRef, moduleType) {
28
29
  return { baseRef, metadataList: [] };
29
30
  }
30
31
  }
32
+ /** Local branch metadata when `work set` recorded lastBaseBranch; otherwise undefined. */
33
+ export async function resolveRecordedWorkBranchMetadata(moduleType) {
34
+ const baseRef = (await readLastBaseBranch())?.trim();
35
+ if (!baseRef) {
36
+ return undefined;
37
+ }
38
+ return resolveWorkBranchMetadata(baseRef, moduleType);
39
+ }
31
40
  //# sourceMappingURL=work-branch-metadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"work-branch-metadata.js","sourceRoot":"","sources":["../../src/lib/work-branch-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kCAAkC,EAAC,MAAM,8BAA8B,CAAA;AAc/E,MAAM,oBAAoB,GAAG;IAC3B,6BAA6B;IAC7B,8CAA8C;CAC/C,CAAA;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,UAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,kCAAkC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAEhF,OAAO;YACL,OAAO;YACP,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAC,UAAU,EAAE,SAAS,EAAC,EAAE,EAAE,CAAC,CAAC;gBACzD,UAAU;gBACV,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;aACrB,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAC,CAAA;IACpC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"work-branch-metadata.js","sourceRoot":"","sources":["../../src/lib/work-branch-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAC,kCAAkC,EAAC,MAAM,8BAA8B,CAAA;AAc/E,MAAM,oBAAoB,GAAG;IAC3B,6BAA6B;IAC7B,8CAA8C;CAC/C,CAAA;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,UAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,kCAAkC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAEhF,OAAO;YACL,OAAO;YACP,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAC,UAAU,EAAE,SAAS,EAAC,EAAE,EAAE,CAAC,CAAC;gBACzD,UAAU;gBACV,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;aACrB,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAC,CAAA;IACpC,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,UAAuB;IAEvB,MAAM,OAAO,GAAG,CAAC,MAAM,kBAAkB,EAAE,CAAC,EAAE,IAAI,EAAE,CAAA;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,yBAAyB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;AACvD,CAAC"}
@@ -35,7 +35,7 @@ export declare function resolveWorkLocalCommitMessage(explicitMessage?: string):
35
35
  workItem?: string;
36
36
  }>;
37
37
  /**
38
- * Runs a plain `git commit` and records the Copado selections consumed later by `cicd work push`.
38
+ * Runs a plain `git commit` and records the Copado selections consumed later by `cicd work publish`.
39
39
  * No gateway call is made.
40
40
  */
41
41
  export declare function performWorkLocalCommit(input: WorkLocalCommitInput): Promise<WorkLocalCommitResult>;
@@ -83,7 +83,7 @@ function gitFailureMessage(error) {
83
83
  return detail.length > 0 ? detail : error instanceof Error ? error.message : String(error);
84
84
  }
85
85
  /**
86
- * Runs a plain `git commit` and records the Copado selections consumed later by `cicd work push`.
86
+ * Runs a plain `git commit` and records the Copado selections consumed later by `cicd work publish`.
87
87
  * No gateway call is made.
88
88
  */
89
89
  export async function performWorkLocalCommit(input) {
@@ -0,0 +1,26 @@
1
+ import { type WorkPushResult } from './work-types.js';
2
+ export declare const WORK_PUBLISH_DESCRIPTION: string;
3
+ export declare const workPublishFlags: {
4
+ readonly 'full-metadata': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
5
+ readonly permissions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ readonly 'skip-nested-metadata-detection': import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ export type WorkPublishFlagValues = {
9
+ 'full-metadata'?: string;
10
+ permissions?: string;
11
+ 'skip-nested-metadata-detection'?: boolean;
12
+ };
13
+ export type WorkPublishHost = {
14
+ config: {
15
+ bin: string;
16
+ };
17
+ display(render: () => void): void;
18
+ error(input: Error | string, options?: {
19
+ exit?: false | number;
20
+ suggestions?: string[];
21
+ }): never;
22
+ log(message?: string, ...args: string[]): void;
23
+ logElapsed(startedAtMs: number): void;
24
+ withSpinner<T>(message: string, action: () => Promise<T>): Promise<T>;
25
+ };
26
+ export declare function runWorkPublish(command: WorkPublishHost, flags: WorkPublishFlagValues): Promise<WorkPushResult>;
@@ -0,0 +1,88 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { listPendingChanges } from './git-worktree.js';
3
+ import { performWorkPush, resolveWorkPushContext, WorkPushValidationError } from './work-push.js';
4
+ export const WORK_PUBLISH_DESCRIPTION = [
5
+ 'Publish the current feature/<lastWorkItem> branch and register commits with Copado.',
6
+ 'Requires a clean working tree, base branch, and dev org branch from `.agentia/config.user.json`.',
7
+ 'Fetches origin/<lastBaseBranch>, then registers only commits in origin/<lastBaseBranch>..HEAD and diffs nested parent XML at merge-base(origin/<lastBaseBranch>, HEAD) versus HEAD, so origin/base-only history is ignored.',
8
+ 'When there are no commits since origin/<lastBaseBranch>, or origin already has HEAD, fails with "No changes to publish" unless `--permissions` and/or `--full-metadata` is set, in which case it creates an empty commit so a tip commit id exists.',
9
+ 'Applies Copado environment-variable then yaml replacements when needed, commits both as a single follow-up commit, locks the tip commit, runs `git push origin <branch>`,',
10
+ 'reports the nested metadata changed across the branch, such as the CustomField behind a profile field-permission edit, plus the parent components it would ignore,',
11
+ 'calls headless work/push with one changeListUpdate list of Action:MetadataType:MetadataName corrections: lastPermissionSelected and --permissions plus the nested metadata of the changed profiles and permission sets as RetrieveOnly, lastFullMetadataSelected and --full-metadata plus brand-new nested parent files as fullMetadata, the ignored parents as unchanged, the nested metadata deleted on the branch as Del, and the remaining nested metadata as Add, then merges the feature branch into the recorded dev org branch.',
12
+ 'The changed profiles and permission sets themselves are never sent as corrections, so they stay in the change list and deploy only the permissions their RetrieveOnly entries select. Brand-new nested parent files are an exception: they are sent as fullMetadata so the complete file travels.',
13
+ '`cicd work push` is a compatibility alias of this command.',
14
+ ].join(' ');
15
+ export const workPublishFlags = {
16
+ 'full-metadata': Flags.string({
17
+ description: 'Comma-separated type-prefixed metadata such as Profile:Sales_User,PermissionSet:Sales_Onboarding, added for this publish and sent as headless push fullMetadata corrections. The named metadata is committed as a complete file, so it is never decomposed into nested metadata. Not stored.',
18
+ }),
19
+ permissions: Flags.string({
20
+ description: 'Comma-separated type-prefixed metadata such as CustomField:Account.SLA__c,ApexClass:AccountService, added for this publish and sent as headless push RetrieveOnly corrections. Not stored.',
21
+ }),
22
+ 'skip-nested-metadata-detection': Flags.boolean({
23
+ default: false,
24
+ description: 'Do not detect the nested metadata changed across the branch (also configurable via skipNestedMetadataDetection in .agentia/config.json or .agentia/config.user.json)',
25
+ }),
26
+ };
27
+ export async function runWorkPublish(command, flags) {
28
+ const startedAt = Date.now();
29
+ let context;
30
+ try {
31
+ context = await resolveWorkPushContext();
32
+ }
33
+ catch (error) {
34
+ if (error instanceof WorkPushValidationError) {
35
+ command.error(error.message, {
36
+ exit: error.exit,
37
+ suggestions: error.suggestions,
38
+ });
39
+ }
40
+ throw error;
41
+ }
42
+ const { baseBranch, branch, devOrgBranch, workItem, workItemId } = context;
43
+ const pendingFiles = await listPendingChanges();
44
+ if (pendingFiles.length > 0) {
45
+ command.error([
46
+ 'Uncommitted tracked changes present. Commit them, then try again:',
47
+ ...pendingFiles.map((file) => ` ${file}`),
48
+ ].join('\n'), {
49
+ exit: 2,
50
+ suggestions: ['git add -A && git commit', `${command.config.bin} cicd work publish`],
51
+ });
52
+ }
53
+ command.display(() => {
54
+ command.log(`Branch: ${branch}`);
55
+ command.log(`Work item: ${workItem}`);
56
+ command.log(`Base branch: ${baseBranch}`);
57
+ command.log(`Dev org branch: ${devOrgBranch}`);
58
+ });
59
+ try {
60
+ const result = await performWorkPush({
61
+ baseBranch,
62
+ branch,
63
+ devOrgBranch,
64
+ ...(flags['full-metadata'] === undefined ? {} : { fullMetadata: flags['full-metadata'] }),
65
+ hooks: {
66
+ display: (render) => command.display(render),
67
+ log: (message) => command.log(message),
68
+ withSpinner: (message, action) => command.withSpinner(message, action),
69
+ },
70
+ ...(flags.permissions === undefined ? {} : { permissions: flags.permissions }),
71
+ skipNestedMetadataDetection: flags['skip-nested-metadata-detection'],
72
+ workItem,
73
+ workItemId,
74
+ });
75
+ command.logElapsed(startedAt);
76
+ return result;
77
+ }
78
+ catch (error) {
79
+ if (error instanceof WorkPushValidationError) {
80
+ command.error(error.message, {
81
+ exit: error.exit,
82
+ suggestions: error.suggestions,
83
+ });
84
+ }
85
+ throw error;
86
+ }
87
+ }
88
+ //# sourceMappingURL=work-publish-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-publish-command.js","sourceRoot":"","sources":["../../src/lib/work-publish-command.ts"],"names":[],"mappings":"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"}
@@ -35,11 +35,12 @@ export type WorkPushNeed = {
35
35
  * Decide whether done/submit should push.
36
36
  *
37
37
  * Salesforce Data Set / Data Template steps only waive the empty-history error.
38
- * When HEAD has commits beyond the base branch, those steps must not skip push
39
- * or any other git validation.
38
+ * When HEAD has commits beyond origin/<lastBaseBranch>, those steps must not skip
39
+ * push or any other git validation. The local base ref is ignored: a stale local
40
+ * main must not count origin/base history as feature work.
40
41
  */
41
42
  export declare function resolveWorkPushNeed(branch: string): Promise<WorkPushNeed>;
42
- /** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work push. */
43
+ /** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work publish. */
43
44
  export declare function resolveWorkPushContext(): Promise<ResolvedWorkPushContext>;
44
45
  export type SleepFn = (ms: number) => Promise<void>;
45
46
  export declare function setSleepForTests(nextSleep: SleepFn): void;
@@ -56,8 +57,8 @@ export declare function readWorkPushRetrieveOnly(): Promise<string[]>;
56
57
  /** Metadata recorded by `cicd work commit --full-metadata`, pushed as `fullMetadata` corrections. */
57
58
  export declare function readWorkPushFullMetadata(): Promise<string[]>;
58
59
  /**
59
- * Selections recorded at commit time plus the ones passed to this push, in that order and without
60
- * duplicates. `cicd work push` never stores its own flag values, so a flag adds to the recorded
60
+ * Selections recorded at commit time plus the ones passed to this publish, in that order and without
61
+ * duplicates. `cicd work publish` never stores its own flag values, so a flag adds to the recorded
61
62
  * selection for the current invocation only.
62
63
  */
63
64
  export declare function mergeWorkPushSelections(storedSelections: readonly string[], requestedSelections: readonly string[]): string[];
@@ -1,7 +1,7 @@
1
1
  import { CicdGateway, CicdGatewayError } from './cicd-gateway.js';
2
2
  import { DEFAULT_WORK_PUSH_RETRY_TIMEOUT_SECONDS, readLastBaseBranch, readLastDevOrgBranch, readLastFullMetadataSelected, readLastPermissionSelected, readLastWorkItem, readSkipNestedMetadataDetection, readWorkPushRetryTimeoutSeconds, } from './defaults-store.js';
3
3
  import { hasSalesforceDataDeploymentStep, normalizeDeploymentSteps, userStoryDeploymentStepsEndpoint, } from './deployment-step-types.js';
4
- import { checkoutBranch, commitAllowEmpty, commitAllTrackedChanges, countCommitsSince, getCommitsNameStatus, getCurrentBranch, getFileAtRef, getGitRepoRoot, getMergeBase, hasUnpushedCommits, listPendingChanges, mergeTheirsIgnoreSpaceChange, pullOriginBranch, pushOriginBranch, restoreFeatureBranch, } from './git-worktree.js';
4
+ import { checkoutBranch, commitAllowEmpty, commitAllTrackedChanges, countCommitsSince, fetchOriginBranch, getCommitsNameStatus, getCurrentBranch, getFileAtRef, getGitRepoRoot, getMergeBase, hasUnpushedCommits, listPendingChanges, mergeTheirsIgnoreSpaceChange, originBranchRef, pullOriginBranch, pushOriginBranch, restoreFeatureBranch, } from './git-worktree.js';
5
5
  import { detectNestedMetadataChanges, formatNestedMetadataSelection, listDeletableNestedChildren, listNestedParentCandidates, } from './nested-metadata-changes.js';
6
6
  import { buildVarReplacementEntries, runVarReplacement } from './var-replacement.js';
7
7
  import { resolveWorkItemId, WorkActiveResolutionError } from './work-active.js';
@@ -41,16 +41,23 @@ export async function resolveRecordedBaseBranch() {
41
41
  }
42
42
  return baseBranch;
43
43
  }
44
+ /** Fetch `origin/<baseBranch>` and return that remote-tracking ref. */
45
+ async function fetchOriginBaseRef(baseBranch) {
46
+ await fetchOriginBranch(baseBranch);
47
+ return originBranchRef(baseBranch);
48
+ }
44
49
  /**
45
50
  * Decide whether done/submit should push.
46
51
  *
47
52
  * Salesforce Data Set / Data Template steps only waive the empty-history error.
48
- * When HEAD has commits beyond the base branch, those steps must not skip push
49
- * or any other git validation.
53
+ * When HEAD has commits beyond origin/<lastBaseBranch>, those steps must not skip
54
+ * push or any other git validation. The local base ref is ignored: a stale local
55
+ * main must not count origin/base history as feature work.
50
56
  */
51
57
  export async function resolveWorkPushNeed(branch) {
52
58
  const baseBranch = await resolveRecordedBaseBranch();
53
- const count = await countCommitsSince(baseBranch);
59
+ const originBase = await fetchOriginBaseRef(baseBranch);
60
+ const count = await countCommitsSince(originBase);
54
61
  if (count > 0) {
55
62
  return {
56
63
  needsPush: await hasUnpushedCommits(branch),
@@ -74,18 +81,18 @@ export async function resolveWorkPushNeed(branch) {
74
81
  if (hasSalesforceDataDeploymentStep(steps)) {
75
82
  return { needsPush: false, skippedForDataSteps: true };
76
83
  }
77
- throw new WorkPushValidationError(`No commits found between ${baseBranch} and HEAD.`, {
84
+ throw new WorkPushValidationError(`No commits found between ${originBase} and HEAD.`, {
78
85
  exit: 1,
79
86
  suggestions: ['Make at least one commit on the feature branch.'],
80
87
  });
81
88
  }
82
- /** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work push. */
89
+ /** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work publish. */
83
90
  export async function resolveWorkPushContext() {
84
91
  const { branch, workItem } = await resolveActiveFeatureWorkItem();
85
92
  const baseBranch = await resolveRecordedBaseBranch();
86
93
  const devOrgBranch = (await readLastDevOrgBranch())?.trim();
87
94
  if (devOrgBranch === undefined || devOrgBranch.length === 0) {
88
- throw new WorkPushValidationError('No lastDevOrgBranch recorded in `.agentia/config.user.json`. Set it before pushing.');
95
+ throw new WorkPushValidationError('No lastDevOrgBranch recorded in `.agentia/config.user.json`. Set it before publishing.');
89
96
  }
90
97
  let workItemId;
91
98
  try {
@@ -176,7 +183,7 @@ export async function registerHeadlessPush(pushBody, hooks, timeoutSeconds = DEF
176
183
  }
177
184
  const delaySeconds = resolveWorkPushRetryDelaySeconds(retryAfterSeconds, waitedSeconds);
178
185
  if (waitedSeconds + delaySeconds > timeoutSeconds) {
179
- throw new CicdGatewayError(`CICD Gateway rate limited the work push request and the retry timeout of ${timeoutSeconds}s was exceeded.`, {
186
+ throw new CicdGatewayError(`CICD Gateway rate limited the work publish request and the retry timeout of ${timeoutSeconds}s was exceeded.`, {
180
187
  categories: error.categories,
181
188
  code: error.code,
182
189
  jobId: error.jobId,
@@ -190,9 +197,9 @@ export async function registerHeadlessPush(pushBody, hooks, timeoutSeconds = DEF
190
197
  }
191
198
  hooks.display(() => {
192
199
  hooks.log(error.jobId === undefined
193
- ? `Rate limited (429). Retrying work push in ${delaySeconds}s` +
200
+ ? `Rate limited (429). Retrying work publish in ${delaySeconds}s` +
194
201
  ` (${waitedSeconds + delaySeconds}s / ${timeoutSeconds}s waited).`
195
- : `waiting for job id ${error.jobId}, Retrying work push in ${delaySeconds}s` +
202
+ : `waiting for job id ${error.jobId}, Retrying work publish in ${delaySeconds}s` +
196
203
  ` (${waitedSeconds + delaySeconds}s / ${timeoutSeconds}s waited).`);
197
204
  });
198
205
  // eslint-disable-next-line no-await-in-loop -- wait before the next retry
@@ -212,8 +219,8 @@ export async function readWorkPushFullMetadata() {
212
219
  return stored === undefined ? [] : parseCommaSeparatedList(stored);
213
220
  }
214
221
  /**
215
- * Selections recorded at commit time plus the ones passed to this push, in that order and without
216
- * duplicates. `cicd work push` never stores its own flag values, so a flag adds to the recorded
222
+ * Selections recorded at commit time plus the ones passed to this publish, in that order and without
223
+ * duplicates. `cicd work publish` never stores its own flag values, so a flag adds to the recorded
217
224
  * selection for the current invocation only.
218
225
  */
219
226
  export function mergeWorkPushSelections(storedSelections, requestedSelections) {
@@ -364,7 +371,7 @@ async function applyCopadoReplacements(options) {
364
371
  export const SKIP_NESTED_METADATA_DETECTION_CONFIG_MESSAGE = 'Nested metadata detection skipped (skipNestedMetadataDetection in .agentia/config.json or .agentia/config.user.json).';
365
372
  export const SKIP_NESTED_METADATA_DETECTION_REQUEST_MESSAGE = 'Nested metadata detection skipped by request.';
366
373
  /**
367
- * Nested metadata changed across every commit not in the base branch: the parent components whose
374
+ * Nested metadata changed across every commit not in origin/<base>: the parent components whose
368
375
  * XML changed only in nested blocks, and the child components carrying the real change.
369
376
  *
370
377
  * Children of a Profile or PermissionSet parent are sent as `RetrieveOnly` and the parent itself is
@@ -469,23 +476,24 @@ function logSelectionEntries(log, header, entries) {
469
476
  export async function performWorkPush(options) {
470
477
  const { baseBranch, branch, devOrgBranch, hooks, workItem } = options;
471
478
  const { display, log, withSpinner } = hooks;
472
- let logStdout = await withSpinner(`Collecting commits since ${baseBranch}`, () => getCommitsNameStatus(baseBranch));
479
+ const originBase = await withSpinner(`Fetching origin/${baseBranch}`, () => fetchOriginBaseRef(baseBranch));
480
+ let logStdout = await withSpinner(`Collecting commits since origin/${baseBranch}`, () => getCommitsNameStatus(originBase));
473
481
  let commits = parseNameStatusLog(logStdout, workItem);
474
482
  const hasSelectionFlags = options.fullMetadata !== undefined || options.permissions !== undefined;
475
483
  const needsEmptyCommit = commits.length === 0 || !(await hasUnpushedCommits(branch));
476
484
  if (needsEmptyCommit) {
477
485
  if (!hasSelectionFlags) {
478
- throw new WorkPushValidationError('No changes to push.', {
486
+ throw new WorkPushValidationError('No changes to publish.', {
479
487
  exit: 1,
480
488
  suggestions: [
481
- 'Make at least one commit on the feature branch before pushing.',
482
- 'Or pass --permissions and/or --full-metadata to push selection corrections with an empty commit.',
489
+ 'Make at least one commit on the feature branch before publishing.',
490
+ 'Or pass --permissions and/or --full-metadata to publish selection corrections with an empty commit.',
483
491
  ],
484
492
  });
485
493
  }
486
- const emptyCommitMessage = `${workItem}: empty commit for work push selections`;
487
- await withSpinner('Creating empty commit for selection push', () => commitAllowEmpty(emptyCommitMessage));
488
- logStdout = await withSpinner(`Collecting commits since ${baseBranch}`, () => getCommitsNameStatus(baseBranch));
494
+ const emptyCommitMessage = `${workItem}: empty commit for work publish selections`;
495
+ await withSpinner('Creating empty commit for selection publish', () => commitAllowEmpty(emptyCommitMessage));
496
+ logStdout = await withSpinner(`Collecting commits since origin/${baseBranch}`, () => getCommitsNameStatus(originBase));
489
497
  commits = parseNameStatusLog(logStdout, workItem);
490
498
  if (commits.length === 0) {
491
499
  throw new WorkPushValidationError('Unable to determine tip commit id after empty commit.', {
@@ -512,7 +520,7 @@ export async function performWorkPush(options) {
512
520
  let tipCommitToLock = tipCommitId;
513
521
  try {
514
522
  const replacementResult = await applyCopadoReplacements({
515
- baseBranch,
523
+ baseBranch: originBase,
516
524
  changedFiles,
517
525
  commits,
518
526
  devOrgBranch,
@@ -530,7 +538,7 @@ export async function performWorkPush(options) {
530
538
  const selectedPermissions = mergeWorkPushSelections(storedRetrieveOnly, options.permissions === undefined ? [] : parseCommaSeparatedList(options.permissions));
531
539
  const selectedFullMetadata = mergeWorkPushSelections(storedFullMetadata, options.fullMetadata === undefined ? [] : parseCommaSeparatedList(options.fullMetadata));
532
540
  const nestedMetadata = await reportNestedMetadataChanges({
533
- baseBranch,
541
+ baseBranch: originBase,
534
542
  commits: commitsToRegister,
535
543
  fullMetadata: selectedFullMetadata,
536
544
  hooks: { display, log, withSpinner },