@acquis-consulting/asm 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/README.md +0 -0
  2. package/dist/apps/gitDiffReview/gitDiffParser.d.ts +6 -0
  3. package/dist/apps/gitDiffReview/gitDiffParser.js +1 -0
  4. package/dist/apps/gitDiffReview/packageXml.d.ts +8 -0
  5. package/dist/apps/gitDiffReview/packageXml.js +1 -0
  6. package/dist/apps/gitDiffReview/tools.d.ts +42 -0
  7. package/dist/apps/gitDiffReview/tools.js +1 -0
  8. package/dist/apps/gitDiffReview/types.d.ts +19 -0
  9. package/dist/apps/gitDiffReview/types.js +1 -0
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.js +193 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/metadata-diff.html +98 -0
  14. package/dist/tools/aggregateQuery.d.ts +85 -0
  15. package/dist/tools/aggregateQuery.js +110 -0
  16. package/dist/tools/aggregateQuery.js.map +1 -0
  17. package/dist/tools/bulkExportAbort.d.ts +37 -0
  18. package/dist/tools/bulkExportAbort.js +44 -0
  19. package/dist/tools/bulkExportAbort.js.map +1 -0
  20. package/dist/tools/bulkExportResults.d.ts +51 -0
  21. package/dist/tools/bulkExportResults.js +76 -0
  22. package/dist/tools/bulkExportResults.js.map +1 -0
  23. package/dist/tools/bulkExportStart.d.ts +61 -0
  24. package/dist/tools/bulkExportStart.js +68 -0
  25. package/dist/tools/bulkExportStart.js.map +1 -0
  26. package/dist/tools/bulkExportStatus.d.ts +37 -0
  27. package/dist/tools/bulkExportStatus.js +54 -0
  28. package/dist/tools/bulkExportStatus.js.map +1 -0
  29. package/dist/tools/crossObjectSearch.d.ts +155 -0
  30. package/dist/tools/crossObjectSearch.js +145 -0
  31. package/dist/tools/crossObjectSearch.js.map +1 -0
  32. package/dist/tools/debugLogs.d.ts +106 -0
  33. package/dist/tools/debugLogs.js +189 -0
  34. package/dist/tools/debugLogs.js.map +1 -0
  35. package/dist/tools/deployMetadata.d.ts +60 -0
  36. package/dist/tools/deployMetadata.js +106 -0
  37. package/dist/tools/deployMetadata.js.map +1 -0
  38. package/dist/tools/deployPackage.d.ts +49 -0
  39. package/dist/tools/deployPackage.js +1 -0
  40. package/dist/tools/dml.d.ts +70 -0
  41. package/dist/tools/dml.js +105 -0
  42. package/dist/tools/dml.js.map +1 -0
  43. package/dist/tools/dmlDelete.d.ts +51 -0
  44. package/dist/tools/dmlDelete.js +71 -0
  45. package/dist/tools/dmlDelete.js.map +1 -0
  46. package/dist/tools/executeAnonymous.d.ts +63 -0
  47. package/dist/tools/executeAnonymous.js +77 -0
  48. package/dist/tools/executeAnonymous.js.map +1 -0
  49. package/dist/tools/fieldManagement.d.ts +222 -0
  50. package/dist/tools/fieldManagement.js +234 -0
  51. package/dist/tools/fieldManagement.js.map +1 -0
  52. package/dist/tools/fieldPermissions.d.ts +94 -0
  53. package/dist/tools/fieldPermissions.js +191 -0
  54. package/dist/tools/fieldPermissions.js.map +1 -0
  55. package/dist/tools/getDependencies.d.ts +58 -0
  56. package/dist/tools/getDependencies.js +105 -0
  57. package/dist/tools/getDependencies.js.map +1 -0
  58. package/dist/tools/listUserPermissions.d.ts +36 -0
  59. package/dist/tools/listUserPermissions.js +59 -0
  60. package/dist/tools/listUserPermissions.js.map +1 -0
  61. package/dist/tools/metadataDescribe.d.ts +37 -0
  62. package/dist/tools/metadataDescribe.js +35 -0
  63. package/dist/tools/metadataDescribe.js.map +1 -0
  64. package/dist/tools/metadataDiff.d.ts +66 -0
  65. package/dist/tools/metadataDiff.js +215 -0
  66. package/dist/tools/metadataDiff.js.map +1 -0
  67. package/dist/tools/metadataDiffFileDetail.d.ts +44 -0
  68. package/dist/tools/metadataDiffFileDetail.js +84 -0
  69. package/dist/tools/metadataDiffFileDetail.js.map +1 -0
  70. package/dist/tools/metadataDiffFiles.d.ts +37 -0
  71. package/dist/tools/metadataDiffFiles.js +72 -0
  72. package/dist/tools/metadataDiffFiles.js.map +1 -0
  73. package/dist/tools/metadataDiffGeneratePackage.d.ts +73 -0
  74. package/dist/tools/metadataDiffGeneratePackage.js +122 -0
  75. package/dist/tools/metadataDiffGeneratePackage.js.map +1 -0
  76. package/dist/tools/metadataImport.d.ts +63 -0
  77. package/dist/tools/metadataImport.js +122 -0
  78. package/dist/tools/metadataImport.js.map +1 -0
  79. package/dist/tools/metadataJobStatus.d.ts +44 -0
  80. package/dist/tools/metadataJobStatus.js +101 -0
  81. package/dist/tools/metadataJobStatus.js.map +1 -0
  82. package/dist/tools/metadataList.d.ts +44 -0
  83. package/dist/tools/metadataList.js +49 -0
  84. package/dist/tools/metadataList.js.map +1 -0
  85. package/dist/tools/metadataRead.d.ts +47 -0
  86. package/dist/tools/metadataRead.js +52 -0
  87. package/dist/tools/metadataRead.js.map +1 -0
  88. package/dist/tools/metadataTypeSchema.d.ts +44 -0
  89. package/dist/tools/metadataTypeSchema.js +101 -0
  90. package/dist/tools/metadataTypeSchema.js.map +1 -0
  91. package/dist/tools/metadataWsdl.d.ts +19 -0
  92. package/dist/tools/metadataWsdl.js +1 -0
  93. package/dist/tools/objectManagement.d.ts +107 -0
  94. package/dist/tools/objectManagement.js +123 -0
  95. package/dist/tools/objectManagement.js.map +1 -0
  96. package/dist/tools/objectPermissions.d.ts +101 -0
  97. package/dist/tools/objectPermissions.js +157 -0
  98. package/dist/tools/objectPermissions.js.map +1 -0
  99. package/dist/tools/objectSchema.d.ts +37 -0
  100. package/dist/tools/objectSchema.js +66 -0
  101. package/dist/tools/objectSchema.js.map +1 -0
  102. package/dist/tools/objectSearch.d.ts +37 -0
  103. package/dist/tools/objectSearch.js +44 -0
  104. package/dist/tools/objectSearch.js.map +1 -0
  105. package/dist/tools/packageStatus.d.ts +24 -0
  106. package/dist/tools/packageStatus.js +1 -0
  107. package/dist/tools/permissionSetAssignment.d.ts +39 -0
  108. package/dist/tools/permissionSetAssignment.js +1 -0
  109. package/dist/tools/readApexClasses.d.ts +50 -0
  110. package/dist/tools/readApexClasses.js +83 -0
  111. package/dist/tools/readApexClasses.js.map +1 -0
  112. package/dist/tools/readApexTriggers.d.ts +50 -0
  113. package/dist/tools/readApexTriggers.js +82 -0
  114. package/dist/tools/readApexTriggers.js.map +1 -0
  115. package/dist/tools/recordPicker.d.ts +48 -0
  116. package/dist/tools/recordPicker.js +1 -0
  117. package/dist/tools/recordQuery.d.ts +68 -0
  118. package/dist/tools/recordQuery.js +131 -0
  119. package/dist/tools/recordQuery.js.map +1 -0
  120. package/dist/tools/retrieveJobStatus.d.ts +51 -0
  121. package/dist/tools/retrieveJobStatus.js +192 -0
  122. package/dist/tools/retrieveJobStatus.js.map +1 -0
  123. package/dist/tools/retrieveMetadata.d.ts +79 -0
  124. package/dist/tools/retrieveMetadata.js +225 -0
  125. package/dist/tools/retrieveMetadata.js.map +1 -0
  126. package/dist/tools/retrievePackage.d.ts +37 -0
  127. package/dist/tools/retrievePackage.js +1 -0
  128. package/dist/tools/salesforceLogin.d.ts +36 -0
  129. package/dist/tools/salesforceLogin.js +75 -0
  130. package/dist/tools/salesforceLogin.js.map +1 -0
  131. package/dist/tools/selectOrg.d.ts +25 -0
  132. package/dist/tools/selectOrg.js +91 -0
  133. package/dist/tools/selectOrg.js.map +1 -0
  134. package/dist/tools/toolingQuery.d.ts +37 -0
  135. package/dist/tools/toolingQuery.js +54 -0
  136. package/dist/tools/toolingQuery.js.map +1 -0
  137. package/dist/tools/userPermissions.d.ts +76 -0
  138. package/dist/tools/userPermissions.js +130 -0
  139. package/dist/tools/userPermissions.js.map +1 -0
  140. package/dist/tools/versionMetadataComplete.d.ts +45 -0
  141. package/dist/tools/versionMetadataComplete.js +1 -0
  142. package/dist/tools/versionMetadataStart.d.ts +25 -0
  143. package/dist/tools/versionMetadataStart.js +1 -0
  144. package/dist/tools/versionMetadataStatus.d.ts +25 -0
  145. package/dist/tools/versionMetadataStatus.js +1 -0
  146. package/dist/tools/writeApexClasses.d.ts +64 -0
  147. package/dist/tools/writeApexClasses.js +79 -0
  148. package/dist/tools/writeApexClasses.js.map +1 -0
  149. package/dist/tools/writeApexTriggers.d.ts +71 -0
  150. package/dist/tools/writeApexTriggers.js +96 -0
  151. package/dist/tools/writeApexTriggers.js.map +1 -0
  152. package/dist/types/connection.d.ts +20 -0
  153. package/dist/types/connection.js +9 -0
  154. package/dist/types/connection.js.map +1 -0
  155. package/dist/types/index.d.ts +3 -0
  156. package/dist/types/index.js +4 -0
  157. package/dist/types/index.js.map +1 -0
  158. package/dist/types/metadata.d.ts +44 -0
  159. package/dist/types/metadata.js +2 -0
  160. package/dist/types/metadata.js.map +1 -0
  161. package/dist/types/salesforce.d.ts +38 -0
  162. package/dist/types/salesforce.js +2 -0
  163. package/dist/types/salesforce.js.map +1 -0
  164. package/dist/utils/apexContainer.d.ts +18 -0
  165. package/dist/utils/apexContainer.js +79 -0
  166. package/dist/utils/apexContainer.js.map +1 -0
  167. package/dist/utils/connection.d.ts +3 -0
  168. package/dist/utils/connection.js +135 -0
  169. package/dist/utils/connection.js.map +1 -0
  170. package/dist/utils/decomposePermissions.d.ts +16 -0
  171. package/dist/utils/decomposePermissions.js +188 -0
  172. package/dist/utils/decomposePermissions.js.map +1 -0
  173. package/dist/utils/dxPathMapper.d.ts +16 -0
  174. package/dist/utils/dxPathMapper.js +217 -0
  175. package/dist/utils/dxPathMapper.js.map +1 -0
  176. package/dist/utils/errors.d.ts +8 -0
  177. package/dist/utils/errors.js +40 -0
  178. package/dist/utils/errors.js.map +1 -0
  179. package/dist/utils/index.d.ts +2 -0
  180. package/dist/utils/index.js +3 -0
  181. package/dist/utils/index.js.map +1 -0
  182. package/dist/utils/oauthWebFlow.d.ts +8 -0
  183. package/dist/utils/oauthWebFlow.js +172 -0
  184. package/dist/utils/oauthWebFlow.js.map +1 -0
  185. package/dist/utils/packageJobs.d.ts +17 -0
  186. package/dist/utils/packageJobs.js +1 -0
  187. package/dist/utils/packageXml.d.ts +18 -0
  188. package/dist/utils/packageXml.js +1 -0
  189. package/dist/utils/permissionSetResolver.d.ts +14 -0
  190. package/dist/utils/permissionSetResolver.js +1 -0
  191. package/dist/utils/preSelectMatcher.d.ts +18 -0
  192. package/dist/utils/preSelectMatcher.js +1 -0
  193. package/dist/utils/profileCleanup.d.ts +18 -0
  194. package/dist/utils/profileCleanup.js +1 -0
  195. package/dist/utils/retrieveStore.d.ts +12 -0
  196. package/dist/utils/retrieveStore.js +1 -0
  197. package/dist/utils/sfCli.d.ts +18 -0
  198. package/dist/utils/sfCli.js +130 -0
  199. package/dist/utils/sfCli.js.map +1 -0
  200. package/dist/utils/tokenBroker.d.ts +13 -0
  201. package/dist/utils/tokenBroker.js +73 -0
  202. package/dist/utils/tokenBroker.js.map +1 -0
  203. package/package.json +54 -0
@@ -0,0 +1,82 @@
1
+ import { z } from 'zod/v4';
2
+ import { toolResponse } from '../utils/index.js';
3
+ export const readApexTriggersTool = {
4
+ name: 'salesforce_read_apex_trigger',
5
+ description: 'Read Apex trigger source code or list triggers by name pattern. Use exact triggerName for full source, or namePattern with wildcards to list.',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ triggerName: {
10
+ type: 'string',
11
+ description: 'Exact trigger name to retrieve full source code.',
12
+ },
13
+ namePattern: {
14
+ type: 'string',
15
+ description: 'Pattern to match trigger names. * = multi-char, ? = single-char. Without wildcards, does substring match.',
16
+ },
17
+ includeMetadata: {
18
+ type: 'boolean',
19
+ description: 'Include API version, object, status, last modified date. Default: false.',
20
+ },
21
+ },
22
+ },
23
+ };
24
+ function convertPattern(pattern) {
25
+ if (pattern.includes('*') || pattern.includes('?')) {
26
+ return pattern.replace(/\*/g, '%').replace(/\?/g, '_');
27
+ }
28
+ return `%${pattern}%`;
29
+ }
30
+ export async function handleReadApexTriggers(conn, args) {
31
+ const { triggerName, namePattern, includeMetadata } = args;
32
+ try {
33
+ if (triggerName) {
34
+ const result = await conn.tooling.query(`SELECT Id, Name, Body, ApiVersion, TableEnumOrId, Status, LastModifiedDate FROM ApexTrigger WHERE Name = '${triggerName.replace(/'/g, "\\'")}'`);
35
+ if (!result.records || result.records.length === 0) {
36
+ return toolResponse(`Apex trigger "${triggerName}" not found.`);
37
+ }
38
+ const trg = result.records[0];
39
+ let output = `## ${trg.Name} (on ${trg.TableEnumOrId})\n\n`;
40
+ if (includeMetadata) {
41
+ output += `API Version: ${trg.ApiVersion} | Status: ${trg.Status} | Last Modified: ${trg.LastModifiedDate}\n\n`;
42
+ }
43
+ output += '```apex\n' + trg.Body + '\n```';
44
+ return toolResponse(output);
45
+ }
46
+ let whereClause = '';
47
+ if (namePattern) {
48
+ const likePattern = convertPattern(namePattern);
49
+ whereClause = ` WHERE Name LIKE '${likePattern.replace(/'/g, "\\'")}'`;
50
+ }
51
+ const fields = includeMetadata
52
+ ? 'Id, Name, ApiVersion, TableEnumOrId, Status, LastModifiedDate'
53
+ : 'Id, Name, TableEnumOrId';
54
+ const result = await conn.tooling.query(`SELECT ${fields} FROM ApexTrigger${whereClause} ORDER BY Name LIMIT 200`);
55
+ if (!result.records || result.records.length === 0) {
56
+ return toolResponse(`No Apex triggers found${namePattern ? ` matching "${namePattern}"` : ''}.`);
57
+ }
58
+ if (includeMetadata) {
59
+ const header = '| Name | Object | API Version | Status | Last Modified |';
60
+ const separator = '|------|--------|-------------|--------|---------------|';
61
+ const rows = result.records.map((r) => `| ${r.Name} | ${r.TableEnumOrId} | ${r.ApiVersion} | ${r.Status} | ${r.LastModifiedDate} |`);
62
+ return toolResponse(`${result.records.length} trigger(s) found:\n\n${header}\n${separator}\n${rows.join('\n')}`);
63
+ }
64
+ const items = result.records.map((r) => `${r.Name} (on ${r.TableEnumOrId})`);
65
+ return toolResponse(`${items.length} trigger(s) found:\n\n${items.join('\n')}`);
66
+ }
67
+ catch (error) {
68
+ return toolResponse(`Failed to read Apex triggers: ${error.message}`, true);
69
+ }
70
+ }
71
+ export const readApexTriggersSchema = {
72
+ triggerName: z.string().describe('Exact trigger name to retrieve full source code.').optional(),
73
+ namePattern: z.string().describe('Pattern to match trigger names. * = multi-char, ? = single-char. Without wildcards, does substring match.').optional(),
74
+ includeMetadata: z.boolean().describe('Include API version, object, status, last modified date. Default: false.').optional(),
75
+ };
76
+ export const readApexTriggersDescriptor = {
77
+ name: 'salesforce_read_apex_trigger',
78
+ description: readApexTriggersTool.description,
79
+ schema: readApexTriggersSchema,
80
+ handler: handleReadApexTriggers,
81
+ };
82
+ //# sourceMappingURL=readApexTriggers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readApexTriggers.js","sourceRoot":"","sources":["../../src/tools/readApexTriggers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,8BAA8B;IACpC,WAAW,EAAE,+IAA+I;IAC5J,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kDAAkD;aAChE;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,2GAA2G;aACzH;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,0EAA0E;aACxF;SACF;KACF;CACF,CAAC;AAQF,SAAS,cAAc,CAAC,OAAe;IACrC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,OAAO,GAAG,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAgB,EAAE,IAA0B;IACvF,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAE3D,IAAI,CAAC;QACH,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CACrC,6GAA6G,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CACjJ,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnD,OAAO,YAAY,CAAC,iBAAiB,WAAW,cAAc,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAQ,CAAC;YACrC,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,aAAa,OAAO,CAAC;YAC5D,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,IAAI,gBAAgB,GAAG,CAAC,UAAU,cAAc,GAAG,CAAC,MAAM,qBAAqB,GAAG,CAAC,gBAAgB,MAAM,CAAC;YAClH,CAAC;YACD,MAAM,IAAI,WAAW,GAAG,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC;YAE3C,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;YAChD,WAAW,GAAG,qBAAqB,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;QACzE,CAAC;QAED,MAAM,MAAM,GAAG,eAAe;YAC5B,CAAC,CAAC,+DAA+D;YACjE,CAAC,CAAC,yBAAyB,CAAC;QAE9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CACrC,UAAU,MAAM,oBAAoB,WAAW,0BAA0B,CAC1E,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO,YAAY,CAAC,yBAAyB,WAAW,CAAC,CAAC,CAAC,cAAc,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnG,CAAC;QAED,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,0DAA0D,CAAC;YAC1E,MAAM,SAAS,GAAG,0DAA0D,CAAC;YAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CACzC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,UAAU,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,gBAAgB,IAAI,CAC7F,CAAC;YACF,OAAO,YAAY,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,yBAAyB,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnH,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC;QAClF,OAAO,YAAY,CAAC,GAAG,KAAK,CAAC,MAAM,yBAAyB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,YAAY,CAAC,iCAAiC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC,CAAC,QAAQ,EAAE;IAC/F,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2GAA2G,CAAC,CAAC,QAAQ,EAAE;IACxJ,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,0EAA0E,CAAC,CAAC,QAAQ,EAAE;CAC7H,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,8BAA8B;IACpC,WAAW,EAAE,oBAAoB,CAAC,WAAW;IAC7C,MAAM,EAAE,sBAAsB;IAC9B,OAAO,EAAE,sBAAsB;CAChC,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { Connection } from 'jsforce';
2
+ import { z } from 'zod/v4';
3
+ export declare const recordPickerTool: {
4
+ name: string;
5
+ description: string;
6
+ inputSchema: {
7
+ type: "object";
8
+ properties: {
9
+ query: {
10
+ type: string;
11
+ description: string;
12
+ };
13
+ };
14
+ required: string[];
15
+ };
16
+ };
17
+ export interface RecordPickerArgs {
18
+ query: string;
19
+ }
20
+ export declare function handleRecordPicker(conn: Connection, args: RecordPickerArgs): Promise<{
21
+ content: {
22
+ type: "text";
23
+ text: string;
24
+ }[];
25
+ isError: boolean;
26
+ } | {
27
+ content: {
28
+ type: "text";
29
+ text: string;
30
+ }[];
31
+ structuredContent: {
32
+ records: Record<string, unknown>[];
33
+ totalSize: any;
34
+ fields: string[];
35
+ query: string;
36
+ };
37
+ }>;
38
+ export declare const recordPickerSchema: {
39
+ query: z.ZodString;
40
+ };
41
+ export declare const recordPickerDescriptor: {
42
+ name: string;
43
+ description: string;
44
+ schema: {
45
+ query: z.ZodString;
46
+ };
47
+ handler: typeof handleRecordPicker;
48
+ };
@@ -0,0 +1 @@
1
+ import{z as e}from"zod/v4";import{toolResponse as r}from"../utils/index.js";export const recordPickerTool={name:"salesforce_record_picker",description:"Query Salesforce records and display them in an interactive table with checkboxes. Users can select records and submit their selection back to the conversation. Accepts a raw SOQL query string.",inputSchema:{type:"object",properties:{query:{type:"string",description:'A full SOQL query string, e.g. "SELECT Id, Name FROM Account LIMIT 10".'}},required:["query"]}};export async function handleRecordPicker(e,t){const{query:o}=t;try{const r=await e.query(o),t=r.records||[];if(0===t.length)return{content:[{type:"text",text:`No records found.\n\nSOQL: ${o}`}],structuredContent:{records:[],totalSize:0,fields:[],query:o}};const n=Object.keys(t[0]).filter(e=>"attributes"!==e),c=t.map(e=>{const r={};for(const t of n)r[t]=e[t];return r}),s=c.map((e,r)=>`Record ${r+1}:\n ${n.map(r=>`${r}: ${e[r]??"(null)"}`).join("\n ")}`);return{content:[{type:"text",text:`Found ${r.totalSize} record(s)${c.length<r.totalSize?` (showing ${c.length})`:""}:\n\n${s.join("\n\n")}\n\nSOQL: ${o}`}],structuredContent:{records:c,totalSize:r.totalSize,fields:n,query:o}}}catch(e){return r(`Query failed: ${e.message}\n\nSOQL: ${o}`,!0)}}export const recordPickerSchema={query:e.string().describe('A full SOQL query string, e.g. "SELECT Id, Name FROM Account LIMIT 10".')};export const recordPickerDescriptor={name:"salesforce_record_picker",description:recordPickerTool.description,schema:recordPickerSchema,handler:handleRecordPicker};
@@ -0,0 +1,68 @@
1
+ import { Connection } from 'jsforce';
2
+ import { z } from 'zod/v4';
3
+ export declare const recordQueryTool: {
4
+ name: string;
5
+ description: string;
6
+ inputSchema: {
7
+ type: "object";
8
+ properties: {
9
+ objectName: {
10
+ type: string;
11
+ description: string;
12
+ };
13
+ fields: {
14
+ type: string;
15
+ items: {
16
+ type: string;
17
+ };
18
+ description: string;
19
+ };
20
+ whereClause: {
21
+ type: string;
22
+ description: string;
23
+ };
24
+ orderBy: {
25
+ type: string;
26
+ description: string;
27
+ };
28
+ limit: {
29
+ type: string;
30
+ description: string;
31
+ };
32
+ };
33
+ required: string[];
34
+ };
35
+ };
36
+ export interface RecordQueryArgs {
37
+ objectName: string;
38
+ fields: string[];
39
+ whereClause?: string;
40
+ orderBy?: string;
41
+ limit?: number;
42
+ }
43
+ export declare function handleRecordQuery(conn: Connection, args: RecordQueryArgs): Promise<{
44
+ content: {
45
+ type: "text";
46
+ text: string;
47
+ }[];
48
+ isError: boolean;
49
+ }>;
50
+ export declare const recordQuerySchema: {
51
+ objectName: z.ZodString;
52
+ fields: z.ZodArray<z.ZodString>;
53
+ whereClause: z.ZodOptional<z.ZodString>;
54
+ orderBy: z.ZodOptional<z.ZodString>;
55
+ limit: z.ZodOptional<z.ZodNumber>;
56
+ };
57
+ export declare const recordQueryDescriptor: {
58
+ name: string;
59
+ description: string;
60
+ schema: {
61
+ objectName: z.ZodString;
62
+ fields: z.ZodArray<z.ZodString>;
63
+ whereClause: z.ZodOptional<z.ZodString>;
64
+ orderBy: z.ZodOptional<z.ZodString>;
65
+ limit: z.ZodOptional<z.ZodNumber>;
66
+ };
67
+ handler: typeof handleRecordQuery;
68
+ };
@@ -0,0 +1,131 @@
1
+ import { z } from 'zod/v4';
2
+ import { toolResponse } from '../utils/index.js';
3
+ export const recordQueryTool = {
4
+ name: 'salesforce_query_records',
5
+ description: 'Query Salesforce records using SOQL with full relationship support. Supports parent-to-child subqueries like "(SELECT Id, Name FROM Contacts)" and child-to-parent dot notation like "Account.Name". For GROUP BY / aggregate queries, use salesforce_aggregate_query instead.',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ objectName: {
10
+ type: 'string',
11
+ description: 'The Salesforce object API name to query.',
12
+ },
13
+ fields: {
14
+ type: 'array',
15
+ items: { type: 'string' },
16
+ description: 'Fields to select. Supports dot notation (Account.Name) and subqueries ((SELECT Id FROM Contacts)).',
17
+ },
18
+ whereClause: {
19
+ type: 'string',
20
+ description: 'Optional WHERE clause without the WHERE keyword. Example: "Name LIKE \'Acme%\'"',
21
+ },
22
+ orderBy: {
23
+ type: 'string',
24
+ description: 'Optional ORDER BY clause without the ORDER BY keywords. Example: "Name ASC"',
25
+ },
26
+ limit: {
27
+ type: 'number',
28
+ description: 'Maximum number of records to return.',
29
+ },
30
+ },
31
+ required: ['objectName', 'fields'],
32
+ },
33
+ };
34
+ function validateFields(fields) {
35
+ for (const field of fields) {
36
+ if (field.startsWith('(')) {
37
+ if (!/^\(SELECT\s+.+\s+FROM\s+\w+\)$/i.test(field)) {
38
+ return `Invalid subquery format: "${field}". Expected: (SELECT fields FROM RelationshipName)`;
39
+ }
40
+ continue;
41
+ }
42
+ if (field.includes('.')) {
43
+ const segments = field.split('.');
44
+ if (segments.some(s => s.trim() === '')) {
45
+ return `Invalid dot notation: "${field}". Found empty segment.`;
46
+ }
47
+ if (segments.length > 5) {
48
+ return `Dot notation too deep: "${field}". Maximum 5 levels supported.`;
49
+ }
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ function resolveNestedValue(record, fieldPath) {
55
+ const segments = fieldPath.split('.');
56
+ let current = record;
57
+ for (const segment of segments) {
58
+ if (current === null || current === undefined)
59
+ return null;
60
+ current = current[segment];
61
+ }
62
+ return current;
63
+ }
64
+ function formatRecord(record, fields) {
65
+ const parts = [];
66
+ for (const field of fields) {
67
+ if (field.startsWith('(')) {
68
+ const match = field.match(/FROM\s+(\w+)\)/i);
69
+ const relName = match ? match[1] : 'Subquery';
70
+ const subRecords = record[relName];
71
+ if (subRecords && subRecords.records) {
72
+ parts.push(`${relName}: ${JSON.stringify(subRecords.records, null, 2)}`);
73
+ }
74
+ else {
75
+ parts.push(`${relName}: (none)`);
76
+ }
77
+ }
78
+ else if (field.includes('.')) {
79
+ const value = resolveNestedValue(record, field);
80
+ parts.push(`${field}: ${value ?? '(null)'}`);
81
+ }
82
+ else {
83
+ parts.push(`${field}: ${record[field] ?? '(null)'}`);
84
+ }
85
+ }
86
+ return parts.join('\n ');
87
+ }
88
+ export async function handleRecordQuery(conn, args) {
89
+ const { objectName, fields, whereClause, orderBy, limit } = args;
90
+ const validationError = validateFields(fields);
91
+ if (validationError) {
92
+ return toolResponse(validationError, true);
93
+ }
94
+ let soql = `SELECT ${fields.join(', ')} FROM ${objectName}`;
95
+ if (whereClause)
96
+ soql += ` WHERE ${whereClause}`;
97
+ if (orderBy)
98
+ soql += ` ORDER BY ${orderBy}`;
99
+ if (limit)
100
+ soql += ` LIMIT ${limit}`;
101
+ try {
102
+ const result = await conn.query(soql);
103
+ const records = result.records || [];
104
+ if (records.length === 0) {
105
+ return toolResponse(`No records found.\n\nSOQL: ${soql}`);
106
+ }
107
+ const formatted = records.map((r, i) => `Record ${i + 1}:\n ${formatRecord(r, fields)}`);
108
+ return toolResponse(`Found ${result.totalSize} record(s)${records.length < result.totalSize ? ` (showing ${records.length})` : ''}:\n\n${formatted.join('\n\n')}\n\nSOQL: ${soql}`);
109
+ }
110
+ catch (error) {
111
+ let msg = error.message || String(error);
112
+ if (msg.includes('INVALID_FIELD')) {
113
+ msg += '\n\nTips:\n- Check the relationship name is correct\n- For custom relationships, use __r suffix (e.g., MyRelation__r.Name)\n- Verify field-level security allows access to this field';
114
+ }
115
+ return toolResponse(`Query failed: ${msg}\n\nSOQL: ${soql}`, true);
116
+ }
117
+ }
118
+ export const recordQuerySchema = {
119
+ objectName: z.string().describe('The Salesforce object API name to query.'),
120
+ fields: z.array(z.string()).describe('Fields to select. Supports dot notation (Account.Name) and subqueries ((SELECT Id FROM Contacts)).'),
121
+ whereClause: z.string().describe('Optional WHERE clause without the WHERE keyword. Example: "Name LIKE \'Acme%\'"').optional(),
122
+ orderBy: z.string().describe('Optional ORDER BY clause without the ORDER BY keywords. Example: "Name ASC"').optional(),
123
+ limit: z.number().describe('Maximum number of records to return.').optional(),
124
+ };
125
+ export const recordQueryDescriptor = {
126
+ name: 'salesforce_query_records',
127
+ description: recordQueryTool.description,
128
+ schema: recordQuerySchema,
129
+ handler: handleRecordQuery,
130
+ };
131
+ //# sourceMappingURL=recordQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordQuery.js","sourceRoot":"","sources":["../../src/tools/recordQuery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { Connection } from 'jsforce';
2
+ import { z } from 'zod/v4';
3
+ export declare const retrieveJobStatusTool: {
4
+ name: "salesforce_retrieve_job_status";
5
+ description: string;
6
+ inputSchema: {
7
+ type: "object";
8
+ properties: {
9
+ jobDir: {
10
+ type: string;
11
+ description: string;
12
+ };
13
+ tag: {
14
+ type: string;
15
+ enum: string[];
16
+ description: string;
17
+ };
18
+ };
19
+ required: string[];
20
+ };
21
+ };
22
+ export interface RetrieveJobStatusArgs {
23
+ jobDir: string;
24
+ tag?: 'source' | 'target';
25
+ }
26
+ export declare function handleRetrieveJobStatus(_conn: Connection, args: RetrieveJobStatusArgs): Promise<{
27
+ content: {
28
+ type: "text";
29
+ text: string;
30
+ }[];
31
+ isError: boolean;
32
+ }>;
33
+ export declare const retrieveJobStatusSchema: {
34
+ jobDir: z.ZodString;
35
+ tag: z.ZodDefault<z.ZodEnum<{
36
+ source: "source";
37
+ target: "target";
38
+ }>>;
39
+ };
40
+ export declare const retrieveJobStatusDescriptor: {
41
+ name: string;
42
+ description: string;
43
+ schema: {
44
+ jobDir: z.ZodString;
45
+ tag: z.ZodDefault<z.ZodEnum<{
46
+ source: "source";
47
+ target: "target";
48
+ }>>;
49
+ };
50
+ handler: typeof handleRetrieveJobStatus;
51
+ };
@@ -0,0 +1,192 @@
1
+ import { z } from 'zod/v4';
2
+ import { readFileSync, existsSync, statSync, readdirSync } from 'fs';
3
+ import { join, relative } from 'path';
4
+ import { execSync } from 'child_process';
5
+ import { toolResponse } from '../utils/index.js';
6
+ import { walkDir } from './retrieveMetadata.js';
7
+ import { decomposeProfilesAndPermSets } from '../utils/decomposePermissions.js';
8
+ export const retrieveJobStatusTool = {
9
+ name: 'salesforce_retrieve_job_status',
10
+ description: 'Check every 5 seconds the status of a background metadata retrieve job. ' +
11
+ 'Use after salesforce_retrieve_metadata returns an output directory.',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ jobDir: {
16
+ type: 'string',
17
+ description: 'The output directory from the original retrieve command',
18
+ },
19
+ tag: {
20
+ type: 'string',
21
+ enum: ['source', 'target'],
22
+ description: 'The tag used in the original retrieve (defaults to "source")',
23
+ },
24
+ },
25
+ required: ['jobDir'],
26
+ },
27
+ };
28
+ export async function handleRetrieveJobStatus(_conn, args) {
29
+ const { jobDir, tag = 'source' } = args;
30
+ const taggedDir = join(jobDir, tag);
31
+ // Discover the latest timestamped log files in the tagged subfolder
32
+ let resultFile = '';
33
+ let logFile = '';
34
+ try {
35
+ const mdDir = join(taggedDir, '.metadata-diff');
36
+ const entries = readdirSync(mdDir);
37
+ const resultFiles = entries.filter(f => /^\.retrieve-result-\d+\.json$/.test(f)).sort();
38
+ const logFiles = entries.filter(f => /^\.retrieve-log-\d+\.txt$/.test(f)).sort();
39
+ if (resultFiles.length > 0)
40
+ resultFile = join(mdDir, resultFiles[resultFiles.length - 1]);
41
+ if (logFiles.length > 0)
42
+ logFile = join(mdDir, logFiles[logFiles.length - 1]);
43
+ }
44
+ catch { /* directory may not exist yet */ }
45
+ // Check if result file exists and has content
46
+ if (!resultFile || !existsSync(resultFile)) {
47
+ return toolResponse('Retrieve in progress (result file not yet created).\n\nPoll again with salesforce_retrieve_job_status.');
48
+ }
49
+ let fileSize;
50
+ try {
51
+ fileSize = statSync(resultFile).size;
52
+ }
53
+ catch {
54
+ return toolResponse('Retrieve in progress (cannot read result file).\n\nPoll again with salesforce_retrieve_job_status.');
55
+ }
56
+ if (fileSize === 0) {
57
+ return toolResponse('Retrieve in progress (waiting for CLI output).\n\nPoll again with salesforce_retrieve_job_status.');
58
+ }
59
+ // File has content — try to parse JSON
60
+ let raw;
61
+ try {
62
+ raw = readFileSync(resultFile, 'utf-8').trim();
63
+ }
64
+ catch {
65
+ return toolResponse('Retrieve in progress (cannot read result file).\n\nPoll again with salesforce_retrieve_job_status.');
66
+ }
67
+ let json;
68
+ try {
69
+ json = JSON.parse(raw);
70
+ }
71
+ catch {
72
+ // File has content but isn't valid JSON yet — CLI may still be writing
73
+ return toolResponse('Retrieve in progress (output file partially written).\n\nPoll again with salesforce_retrieve_job_status.');
74
+ }
75
+ const status = json?.result?.status;
76
+ // Terminal success
77
+ if (status === 'Succeeded' || status === 'SucceededPartial') {
78
+ let retrievedFiles = [];
79
+ try {
80
+ retrievedFiles = walkDir(taggedDir)
81
+ .filter(f => !f.endsWith('sfdx-project.json') &&
82
+ !f.includes('/.sf/') &&
83
+ !f.includes('/.sfdx/') &&
84
+ !f.includes('/.git/') &&
85
+ !f.includes('/.metadata-diff/') &&
86
+ !f.endsWith('/package.xml') &&
87
+ !f.endsWith('.gitignore'))
88
+ .map(f => relative(taggedDir, f));
89
+ }
90
+ catch { /* directory may be empty */ }
91
+ const components = json?.result?.files || [];
92
+ const componentCount = Array.isArray(components) ? components.length : 0;
93
+ // Decompose monolithic profile/permission-set XML files into per-permission sub-files
94
+ let decomposeMessage = '';
95
+ try {
96
+ decomposeMessage = decomposeProfilesAndPermSets(taggedDir);
97
+ }
98
+ catch { /* best-effort */ }
99
+ // Auto-commit retrieved files for diff tracking (each tagged subfolder is its own git repo)
100
+ let gitMessage = '';
101
+ try {
102
+ gitMessage = autoGitCommit(taggedDir);
103
+ }
104
+ catch { /* git commit is best-effort */ }
105
+ const lines = [
106
+ `Retrieve ${status === 'SucceededPartial' ? 'partially completed' : 'completed successfully'}.`,
107
+ `Components: ${componentCount}`,
108
+ `Files: ${retrievedFiles.length}`,
109
+ `Output directory: ${jobDir}`,
110
+ `Tagged subfolder: ${taggedDir}`,
111
+ ...(decomposeMessage ? ['', decomposeMessage] : []),
112
+ ...(gitMessage ? ['', gitMessage] : []),
113
+ '',
114
+ 'Retrieved files:',
115
+ ...retrievedFiles.slice(0, 200).map(f => ` ${f}`),
116
+ ...(retrievedFiles.length > 200 ? [` ... and ${retrievedFiles.length - 200} more`] : []),
117
+ ];
118
+ return toolResponse(lines.join('\n'));
119
+ }
120
+ // Terminal failure
121
+ if (status === 'Failed') {
122
+ let stderrLog = '';
123
+ try {
124
+ if (existsSync(logFile)) {
125
+ stderrLog = readFileSync(logFile, 'utf-8').trim();
126
+ }
127
+ }
128
+ catch { /* ignore */ }
129
+ const msg = json?.result?.message || json?.message || stderrLog || 'Unknown error';
130
+ return toolResponse(`Retrieve failed.\nStatus: ${status}\n${msg}`, true);
131
+ }
132
+ // CLI exited with an error (non-zero exit, no Succeeded status)
133
+ if (json?.status !== 0 && json?.message) {
134
+ let stderrLog = '';
135
+ try {
136
+ if (existsSync(logFile)) {
137
+ stderrLog = readFileSync(logFile, 'utf-8').trim();
138
+ }
139
+ }
140
+ catch { /* ignore */ }
141
+ const detail = stderrLog ? `\n\nStderr:\n${stderrLog}` : '';
142
+ return toolResponse(`Retrieve failed: ${json.message}${detail}`, true);
143
+ }
144
+ // Still in progress or unknown status
145
+ return toolResponse(`Retrieve in progress.\nStatus: ${status || 'Unknown'}\n\nPoll again with salesforce_retrieve_job_status.`);
146
+ }
147
+ /**
148
+ * Auto-initialize git repo and commit retrieved files.
149
+ * First retrieve: git init + commit as baseline.
150
+ * Subsequent retrieves: commit changes (if any).
151
+ */
152
+ function autoGitCommit(jobDir) {
153
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
154
+ const gitOpts = { cwd: jobDir, encoding: 'utf-8', stdio: 'pipe' };
155
+ let isGitRepo = false;
156
+ try {
157
+ execSync('git rev-parse --git-dir', { ...gitOpts, stdio: 'pipe' });
158
+ isGitRepo = true;
159
+ }
160
+ catch { /* not a git repo */ }
161
+ if (!isGitRepo) {
162
+ // First retrieve — init repo and commit baseline
163
+ execSync('git init', gitOpts);
164
+ execSync('git add -A', gitOpts);
165
+ execSync(`git commit -m "baseline: ${timestamp}" --allow-empty`, gitOpts);
166
+ return `Git: initialized repo and committed baseline (${timestamp})`;
167
+ }
168
+ // Subsequent retrieve — commit if there are changes
169
+ execSync('git add -A', gitOpts);
170
+ // Check if there are staged changes
171
+ try {
172
+ execSync('git diff --cached --quiet', { ...gitOpts, stdio: 'pipe' });
173
+ // No changes
174
+ return 'Git: no changes to commit';
175
+ }
176
+ catch {
177
+ // There are changes — commit them
178
+ execSync(`git commit -m "retrieve: ${timestamp}"`, gitOpts);
179
+ return `Git: committed retrieve changes (${timestamp})`;
180
+ }
181
+ }
182
+ export const retrieveJobStatusSchema = {
183
+ jobDir: z.string().describe('The output directory from the original retrieve command'),
184
+ tag: z.enum(['source', 'target']).describe('The tag used in the original retrieve').default('source'),
185
+ };
186
+ export const retrieveJobStatusDescriptor = {
187
+ name: 'salesforce_retrieve_job_status',
188
+ description: retrieveJobStatusTool.description,
189
+ schema: retrieveJobStatusSchema,
190
+ handler: handleRetrieveJobStatus,
191
+ };
192
+ //# sourceMappingURL=retrieveJobStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieveJobStatus.js","sourceRoot":"","sources":["../../src/tools/retrieveJobStatus.ts"],"names":[],"mappings":"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"}