@acquis-consulting/asm 1.0.15 → 1.0.16

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 (43) hide show
  1. package/dist/index.js +24 -3
  2. package/dist/index.js.map +1 -1
  3. package/dist/tools/apiRequest.d.ts +70 -0
  4. package/dist/tools/apiRequest.js +67 -0
  5. package/dist/tools/apiRequest.js.map +1 -0
  6. package/dist/tools/auditTrailDownload.d.ts +57 -0
  7. package/dist/tools/auditTrailDownload.js +128 -0
  8. package/dist/tools/auditTrailDownload.js.map +1 -0
  9. package/dist/tools/auditTrailSearch.d.ts +102 -0
  10. package/dist/tools/auditTrailSearch.js +215 -0
  11. package/dist/tools/auditTrailSearch.js.map +1 -0
  12. package/dist/tools/bulkExportResults.js +49 -10
  13. package/dist/tools/bulkExportResults.js.map +1 -1
  14. package/dist/tools/bulkImportAbort.d.ts +37 -0
  15. package/dist/tools/bulkImportAbort.js +46 -0
  16. package/dist/tools/bulkImportAbort.js.map +1 -0
  17. package/dist/tools/bulkImportResults.d.ts +51 -0
  18. package/dist/tools/bulkImportResults.js +168 -0
  19. package/dist/tools/bulkImportResults.js.map +1 -0
  20. package/dist/tools/bulkImportStart.d.ts +120 -0
  21. package/dist/tools/bulkImportStart.js +183 -0
  22. package/dist/tools/bulkImportStart.js.map +1 -0
  23. package/dist/tools/bulkImportStatus.d.ts +37 -0
  24. package/dist/tools/bulkImportStatus.js +56 -0
  25. package/dist/tools/bulkImportStatus.js.map +1 -0
  26. package/dist/tools/salesforceCliLogin.d.ts +36 -0
  27. package/dist/tools/salesforceCliLogin.js +73 -0
  28. package/dist/tools/salesforceCliLogin.js.map +1 -0
  29. package/dist/tools/salesforceCliLoginStatus.d.ts +25 -0
  30. package/dist/tools/salesforceCliLoginStatus.js +66 -0
  31. package/dist/tools/salesforceCliLoginStatus.js.map +1 -0
  32. package/dist/tools/salesforceLogin.js +2 -1
  33. package/dist/tools/salesforceLogin.js.map +1 -1
  34. package/dist/utils/auditTrailCsv.d.ts +42 -0
  35. package/dist/utils/auditTrailCsv.js +165 -0
  36. package/dist/utils/auditTrailCsv.js.map +1 -0
  37. package/dist/utils/errors.d.ts +1 -0
  38. package/dist/utils/errors.js +14 -0
  39. package/dist/utils/errors.js.map +1 -1
  40. package/dist/utils/sfCliWebLogin.d.ts +56 -0
  41. package/dist/utils/sfCliWebLogin.js +208 -0
  42. package/dist/utils/sfCliWebLogin.js.map +1 -0
  43. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ /** Column order of the audit trail CSV written by salesforce_audit_trail_download. */
2
+ export declare const AUDIT_TRAIL_COLUMNS: readonly ["Id", "CreatedDate", "Username", "UserFullName", "Action", "Section", "Display", "DelegateUser"];
3
+ export type AuditTrailRow = Record<(typeof AUDIT_TRAIL_COLUMNS)[number], string>;
4
+ /** Quotes a value per RFC 4180 when it contains a comma, quote, or line break. */
5
+ export declare function escapeCsvValue(value: unknown): string;
6
+ export declare function toCsvLine(values: unknown[]): string;
7
+ /**
8
+ * Parses one complete CSV record (which may span multiple physical lines).
9
+ * Returns null if the record has an unterminated quoted field, so the caller
10
+ * can append the next physical line and retry.
11
+ */
12
+ export declare function parseCsvRecord(text: string): string[] | null;
13
+ /**
14
+ * Streams audit trail rows from a CSV file one record at a time, so the whole
15
+ * file is never held in memory. The header row is used to map columns.
16
+ */
17
+ export declare function readAuditTrailCsv(filePath: string): AsyncGenerator<AuditTrailRow>;
18
+ /**
19
+ * Normalizes a user-supplied date or datetime into a SOQL datetime literal
20
+ * (e.g. 2024-05-01T00:00:00Z). A bare date expands to the start or end of that
21
+ * UTC day depending on `boundary`. Throws on unparseable input, which also
22
+ * keeps arbitrary text out of the SOQL WHERE clause.
23
+ */
24
+ export declare function normalizeAuditDate(input: string, boundary: 'start' | 'end'): string;
25
+ /** Increments a counter in a Map and returns the map. */
26
+ export declare function countInto(map: Map<string, number>, key: string): Map<string, number>;
27
+ export interface UserActivity {
28
+ fullName: string;
29
+ count: number;
30
+ first: string;
31
+ last: string;
32
+ sections: Map<string, number>;
33
+ }
34
+ /** Adds one audit trail change to the per-user activity map (keyed by username). */
35
+ export declare function trackUserActivity(map: Map<string, UserActivity>, row: Pick<AuditTrailRow, 'Username' | 'UserFullName' | 'CreatedDate' | 'Section'>): void;
36
+ /**
37
+ * Formats per-user activity as one line per user, most active first:
38
+ * " user@example.com (Full Name): 12 changes, 2024-05-01 → 2024-05-20 — Flows 5, Apex Class 4, …"
39
+ */
40
+ export declare function formatUserActivity(map: Map<string, UserActivity>, top: number): string[];
41
+ /** Formats the top N entries of a counter as " name: count" lines, highest first. */
42
+ export declare function formatTopCounts(map: Map<string, number>, top: number): string[];
@@ -0,0 +1,165 @@
1
+ import * as fs from 'node:fs';
2
+ import * as readline from 'node:readline';
3
+ /** Column order of the audit trail CSV written by salesforce_audit_trail_download. */
4
+ export const AUDIT_TRAIL_COLUMNS = [
5
+ 'Id',
6
+ 'CreatedDate',
7
+ 'Username',
8
+ 'UserFullName',
9
+ 'Action',
10
+ 'Section',
11
+ 'Display',
12
+ 'DelegateUser',
13
+ ];
14
+ /** Quotes a value per RFC 4180 when it contains a comma, quote, or line break. */
15
+ export function escapeCsvValue(value) {
16
+ const str = value === null || value === undefined ? '' : String(value);
17
+ return /[",\r\n]/.test(str) ? `"${str.replace(/"/g, '""')}"` : str;
18
+ }
19
+ export function toCsvLine(values) {
20
+ return values.map(escapeCsvValue).join(',') + '\n';
21
+ }
22
+ /**
23
+ * Parses one complete CSV record (which may span multiple physical lines).
24
+ * Returns null if the record has an unterminated quoted field, so the caller
25
+ * can append the next physical line and retry.
26
+ */
27
+ export function parseCsvRecord(text) {
28
+ const fields = [];
29
+ let field = '';
30
+ let inQuotes = false;
31
+ for (let i = 0; i < text.length; i++) {
32
+ const ch = text[i];
33
+ if (inQuotes) {
34
+ if (ch === '"') {
35
+ if (text[i + 1] === '"') {
36
+ field += '"';
37
+ i++;
38
+ }
39
+ else {
40
+ inQuotes = false;
41
+ }
42
+ }
43
+ else {
44
+ field += ch;
45
+ }
46
+ }
47
+ else if (ch === '"') {
48
+ inQuotes = true;
49
+ }
50
+ else if (ch === ',') {
51
+ fields.push(field);
52
+ field = '';
53
+ }
54
+ else {
55
+ field += ch;
56
+ }
57
+ }
58
+ if (inQuotes)
59
+ return null;
60
+ fields.push(field);
61
+ return fields;
62
+ }
63
+ /**
64
+ * Streams audit trail rows from a CSV file one record at a time, so the whole
65
+ * file is never held in memory. The header row is used to map columns.
66
+ */
67
+ export async function* readAuditTrailCsv(filePath) {
68
+ const rl = readline.createInterface({
69
+ input: fs.createReadStream(filePath, { encoding: 'utf-8' }),
70
+ crlfDelay: Infinity,
71
+ });
72
+ let header;
73
+ let pending = '';
74
+ try {
75
+ for await (const line of rl) {
76
+ pending = pending ? `${pending}\n${line}` : line;
77
+ const fields = parseCsvRecord(pending);
78
+ if (!fields)
79
+ continue;
80
+ pending = '';
81
+ if (!header) {
82
+ header = fields;
83
+ const missing = AUDIT_TRAIL_COLUMNS.filter((c) => !header.includes(c));
84
+ if (missing.length > 0) {
85
+ throw new Error(`File is not an audit trail CSV (missing columns: ${missing.join(', ')}). ` +
86
+ `Use salesforce_audit_trail_download to create it.`);
87
+ }
88
+ continue;
89
+ }
90
+ if (fields.length === 1 && fields[0] === '')
91
+ continue;
92
+ const row = {};
93
+ for (const col of AUDIT_TRAIL_COLUMNS) {
94
+ row[col] = fields[header.indexOf(col)] ?? '';
95
+ }
96
+ yield row;
97
+ }
98
+ }
99
+ finally {
100
+ rl.close();
101
+ }
102
+ }
103
+ /**
104
+ * Normalizes a user-supplied date or datetime into a SOQL datetime literal
105
+ * (e.g. 2024-05-01T00:00:00Z). A bare date expands to the start or end of that
106
+ * UTC day depending on `boundary`. Throws on unparseable input, which also
107
+ * keeps arbitrary text out of the SOQL WHERE clause.
108
+ */
109
+ export function normalizeAuditDate(input, boundary) {
110
+ const trimmed = input.trim();
111
+ const isDateOnly = /^\d{4}-\d{2}-\d{2}$/.test(trimmed);
112
+ const date = new Date(isDateOnly ? `${trimmed}T${boundary === 'start' ? '00:00:00' : '23:59:59'}Z` : trimmed);
113
+ if (Number.isNaN(date.getTime())) {
114
+ throw new Error(`Invalid date "${input}". Use YYYY-MM-DD or an ISO 8601 datetime.`);
115
+ }
116
+ return date.toISOString().replace(/\.\d{3}Z$/, 'Z');
117
+ }
118
+ /** Increments a counter in a Map and returns the map. */
119
+ export function countInto(map, key) {
120
+ map.set(key, (map.get(key) ?? 0) + 1);
121
+ return map;
122
+ }
123
+ /** Adds one audit trail change to the per-user activity map (keyed by username). */
124
+ export function trackUserActivity(map, row) {
125
+ let activity = map.get(row.Username);
126
+ if (!activity) {
127
+ activity = { fullName: row.UserFullName, count: 0, first: row.CreatedDate, last: row.CreatedDate, sections: new Map() };
128
+ map.set(row.Username, activity);
129
+ }
130
+ activity.count++;
131
+ if (row.CreatedDate < activity.first)
132
+ activity.first = row.CreatedDate;
133
+ if (row.CreatedDate > activity.last)
134
+ activity.last = row.CreatedDate;
135
+ countInto(activity.sections, row.Section);
136
+ }
137
+ /**
138
+ * Formats per-user activity as one line per user, most active first:
139
+ * " user@example.com (Full Name): 12 changes, 2024-05-01 → 2024-05-20 — Flows 5, Apex Class 4, …"
140
+ */
141
+ export function formatUserActivity(map, top) {
142
+ const sorted = [...map.entries()].sort((a, b) => b[1].count - a[1].count);
143
+ const lines = sorted.slice(0, top).map(([username, a]) => {
144
+ const who = username ? `${username}${a.fullName ? ` (${a.fullName})` : ''}` : '(no user — automated/system changes)';
145
+ const range = `${a.first.slice(0, 10)} → ${a.last.slice(0, 10)}`;
146
+ const sections = [...a.sections.entries()]
147
+ .sort((x, y) => y[1] - x[1])
148
+ .slice(0, 3)
149
+ .map(([section, count]) => `${section || '(no section)'} ${count}`)
150
+ .join(', ');
151
+ return ` ${who}: ${a.count} change${a.count === 1 ? '' : 's'}, ${range} — ${sections}${a.sections.size > 3 ? ', …' : ''}`;
152
+ });
153
+ if (sorted.length > top)
154
+ lines.push(` … and ${sorted.length - top} more users`);
155
+ return lines;
156
+ }
157
+ /** Formats the top N entries of a counter as " name: count" lines, highest first. */
158
+ export function formatTopCounts(map, top) {
159
+ const sorted = [...map.entries()].sort((a, b) => b[1] - a[1]);
160
+ const lines = sorted.slice(0, top).map(([key, count]) => ` ${key || '(blank)'}: ${count}`);
161
+ if (sorted.length > top)
162
+ lines.push(` … and ${sorted.length - top} more`);
163
+ return lines;
164
+ }
165
+ //# sourceMappingURL=auditTrailCsv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auditTrailCsv.js","sourceRoot":"","sources":["../../src/utils/auditTrailCsv.ts"],"names":[],"mappings":"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"}
@@ -6,3 +6,4 @@ export declare function toolResponse(text: string, isError?: boolean): {
6
6
  }[];
7
7
  isError: boolean;
8
8
  };
9
+ export declare function formatToolError(error: any, sessionId?: string): string;
@@ -37,4 +37,18 @@ export function toolResponse(text, isError = false) {
37
37
  isError,
38
38
  };
39
39
  }
40
+ // jsforce surfaces Salesforce API errors with `.name`/`.errorCode` set to the
41
+ // Salesforce error code (e.g. "INVALID_SESSION_ID"). That's distinct from this
42
+ // server's own session_id concept, but looks identical to a caller once wrapped
43
+ // in a generic "Tool execution failed" message — so rewrite it to point at the
44
+ // actual fix (re-run salesforce_login) instead of leaving the raw SF error.
45
+ export function formatToolError(error, sessionId) {
46
+ const code = error?.errorCode || error?.name;
47
+ if (code === 'INVALID_SESSION_ID') {
48
+ return sessionId
49
+ ? `Your Salesforce session has expired. Call salesforce_login again to get a fresh session_id, then retry this tool with it.`
50
+ : `Salesforce session expired or invalid. Re-authenticate and retry.`;
51
+ }
52
+ return `Tool execution failed: ${error.message}`;
53
+ }
40
54
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAAC,MAAW;IAC9C,IAAI,CAAC,MAAM;QAAE,OAAO,oCAAoC,CAAC;IAEzD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;iBAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChH,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,GAAG;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAO,GAAG,KAAK;IACxD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAC1C,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAAC,MAAW;IAC9C,IAAI,CAAC,MAAM;QAAE,OAAO,oCAAoC,CAAC;IAEzD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;iBAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChH,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,GAAG;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAO,GAAG,KAAK;IACxD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAC1C,OAAO;KACR,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,KAAU,EAAE,SAAkB;IAC5D,MAAM,IAAI,GAAG,KAAK,EAAE,SAAS,IAAI,KAAK,EAAE,IAAI,CAAC;IAC7C,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;QAClC,OAAO,SAAS;YACd,CAAC,CAAC,2HAA2H;YAC7H,CAAC,CAAC,mEAAmE,CAAC;IAC1E,CAAC;IACD,OAAO,0BAA0B,KAAK,CAAC,OAAO,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,56 @@
1
+ export interface SfCliOrgInfo {
2
+ instanceUrl: string;
3
+ username: string;
4
+ orgId: string;
5
+ /** null if the org authenticated but the alias could not be set. */
6
+ alias: string | null;
7
+ }
8
+ export type SfCliLoginState = {
9
+ status: 'pending';
10
+ loginUrl: string;
11
+ startedAt: number;
12
+ } | {
13
+ status: 'success';
14
+ loginUrl: string;
15
+ startedAt: number;
16
+ org: SfCliOrgInfo;
17
+ } | {
18
+ status: 'error';
19
+ loginUrl: string;
20
+ startedAt: number;
21
+ error: string;
22
+ };
23
+ export declare function getSfCliLoginState(sessionId: string): SfCliLoginState | null;
24
+ /**
25
+ * Builds the alias for an authenticated username, e.g. `sfcli-ada@example.com.dev`.
26
+ *
27
+ * The CLI stores aliases as plain JSON keys and validates nothing — `@`, `.` and even
28
+ * spaces are accepted. Only `=` is unusable, because `sf alias set` splits name=value on
29
+ * it; whitespace is stripped too so the alias stays usable as a bare CLI argument.
30
+ */
31
+ export declare function aliasForUsername(username: string): string;
32
+ /**
33
+ * Spawns `sf org login web` and returns as soon as the browser has been launched.
34
+ *
35
+ * The login CANNOT be awaited inside the MCP request: a human browser login routinely
36
+ * outlasts the client's request timeout (~60s in Claude Desktop), and once the client
37
+ * abandons the request the login is orphaned — the CLI's loopback listener on port 1717
38
+ * dies and the Salesforce redirect lands on ERR_CONNECTION_REFUSED.
39
+ *
40
+ * So the child is spawned `detached` with no timeout, into its own process group, and
41
+ * outlives the request that started it. Completion is recorded in `loginState` and polled
42
+ * via the salesforce_cli_login_status tool.
43
+ *
44
+ * No `--alias` is passed: the username isn't known until the user has actually logged in,
45
+ * so the alias is set afterwards from the authenticated username. Aliasing by username
46
+ * keeps it stable and self-overwriting across sessions, rather than leaving one dead
47
+ * alias behind per login.
48
+ *
49
+ * The CLI writes auth to its global store in the user's home directory, never to the
50
+ * current directory, so this works from any folder — including an empty one with no
51
+ * sfdx-project.json. We still run it in a throwaway temp cwd so a stray project file
52
+ * can't influence the login and no local .sf/ directory is left in the user's folder.
53
+ *
54
+ * `--set-default` is deliberately omitted: the user's global target-org stays untouched.
55
+ */
56
+ export declare function startSfCliWebLogin(loginUrl: string, sessionId: string): Promise<void>;
@@ -0,0 +1,208 @@
1
+ import { spawn } from 'child_process';
2
+ import { mkdtempSync, rmSync } from 'fs';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ import { ensureSfCli, runSfCli } from './sfCli.js';
6
+ import { setOAuthWebFlowToken } from './oauthWebFlow.js';
7
+ // In-memory, keyed by sessionId — same lifetime rules as the OAuth web-flow token store.
8
+ const loginState = new Map();
9
+ const ALIAS_PREFIX = 'sfcli-';
10
+ const CLI_STEP_TIMEOUT_MS = 60 * 1000;
11
+ export function getSfCliLoginState(sessionId) {
12
+ return loginState.get(sessionId) ?? null;
13
+ }
14
+ /**
15
+ * Builds the alias for an authenticated username, e.g. `sfcli-ada@example.com.dev`.
16
+ *
17
+ * The CLI stores aliases as plain JSON keys and validates nothing — `@`, `.` and even
18
+ * spaces are accepted. Only `=` is unusable, because `sf alias set` splits name=value on
19
+ * it; whitespace is stripped too so the alias stays usable as a bare CLI argument.
20
+ */
21
+ export function aliasForUsername(username) {
22
+ const sanitized = username.replace(/[=\s]/g, '');
23
+ return `${ALIAS_PREFIX}${sanitized}`;
24
+ }
25
+ /**
26
+ * Spawns `sf org login web` and returns as soon as the browser has been launched.
27
+ *
28
+ * The login CANNOT be awaited inside the MCP request: a human browser login routinely
29
+ * outlasts the client's request timeout (~60s in Claude Desktop), and once the client
30
+ * abandons the request the login is orphaned — the CLI's loopback listener on port 1717
31
+ * dies and the Salesforce redirect lands on ERR_CONNECTION_REFUSED.
32
+ *
33
+ * So the child is spawned `detached` with no timeout, into its own process group, and
34
+ * outlives the request that started it. Completion is recorded in `loginState` and polled
35
+ * via the salesforce_cli_login_status tool.
36
+ *
37
+ * No `--alias` is passed: the username isn't known until the user has actually logged in,
38
+ * so the alias is set afterwards from the authenticated username. Aliasing by username
39
+ * keeps it stable and self-overwriting across sessions, rather than leaving one dead
40
+ * alias behind per login.
41
+ *
42
+ * The CLI writes auth to its global store in the user's home directory, never to the
43
+ * current directory, so this works from any folder — including an empty one with no
44
+ * sfdx-project.json. We still run it in a throwaway temp cwd so a stray project file
45
+ * can't influence the login and no local .sf/ directory is left in the user's folder.
46
+ *
47
+ * `--set-default` is deliberately omitted: the user's global target-org stays untouched.
48
+ */
49
+ export async function startSfCliWebLogin(loginUrl, sessionId) {
50
+ await ensureSfCli();
51
+ const existing = loginState.get(sessionId);
52
+ if (existing?.status === 'pending') {
53
+ throw new Error('A browser login is already in progress for this session. ' +
54
+ 'Complete it in the browser, then call salesforce_cli_login_status.');
55
+ }
56
+ const cwd = mkdtempSync(join(tmpdir(), 'sf-mcp-login-'));
57
+ const startedAt = Date.now();
58
+ const args = ['org', 'login', 'web', '--instance-url', loginUrl, '--json'];
59
+ console.error(`[sf-cli-login] spawning: sf ${args.join(' ')}`);
60
+ const child = spawn('sf', args, {
61
+ stdio: ['ignore', 'pipe', 'pipe'],
62
+ cwd,
63
+ detached: true, // own process group — survives the abandoned MCP request
64
+ });
65
+ loginState.set(sessionId, { status: 'pending', loginUrl, startedAt });
66
+ let stdout = '';
67
+ let stderr = '';
68
+ child.stdout.on('data', (d) => { stdout += d.toString(); });
69
+ child.stderr.on('data', (d) => {
70
+ const chunk = d.toString();
71
+ stderr += chunk;
72
+ process.stderr.write(chunk);
73
+ });
74
+ const fail = (error) => {
75
+ console.error(`[sf-cli-login] failed: ${error}`);
76
+ loginState.set(sessionId, { status: 'error', loginUrl, startedAt, error });
77
+ };
78
+ const cleanup = () => {
79
+ try {
80
+ rmSync(cwd, { recursive: true, force: true });
81
+ }
82
+ catch (err) {
83
+ console.error(`[sf-cli-login] failed to remove temp dir ${cwd}: ${err.message}`);
84
+ }
85
+ };
86
+ child.on('error', (err) => {
87
+ cleanup();
88
+ fail(err.code === 'ENOENT'
89
+ ? 'Salesforce CLI (sf) is not installed or not on PATH. Install it from https://developer.salesforce.com/tools/salesforcecli'
90
+ : err.message);
91
+ });
92
+ child.on('close', async (code) => {
93
+ try {
94
+ if (code !== 0) {
95
+ let msg = stderr.trim() || 'Unknown error';
96
+ try {
97
+ const parsed = JSON.parse(stdout);
98
+ if (parsed?.message)
99
+ msg = parsed.message;
100
+ }
101
+ catch { /* stdout wasn't JSON */ }
102
+ fail(`sf org login web exited with code ${code}: ${msg}`);
103
+ return;
104
+ }
105
+ const org = parseLoginPayload(stdout) ?? await readOrgFromCli(cwd);
106
+ setOAuthWebFlowToken(org.accessToken, org.instanceUrl, sessionId);
107
+ const alias = await setAlias(org.username, cwd);
108
+ console.error(`[sf-cli-login] authenticated ${org.username} (${org.instanceUrl}) alias=${alias ?? '(none)'}`);
109
+ loginState.set(sessionId, {
110
+ status: 'success',
111
+ loginUrl,
112
+ startedAt,
113
+ org: {
114
+ instanceUrl: org.instanceUrl,
115
+ username: org.username,
116
+ orgId: org.orgId,
117
+ alias,
118
+ },
119
+ });
120
+ }
121
+ catch (err) {
122
+ fail(err.message);
123
+ }
124
+ finally {
125
+ cleanup();
126
+ }
127
+ });
128
+ // Don't hold the event loop open on the child's account.
129
+ child.unref();
130
+ }
131
+ /**
132
+ * Aliases the freshly authenticated org by username. Never throws: the session is already
133
+ * usable at this point, so a failed alias is a cosmetic problem, not a failed login.
134
+ */
135
+ async function setAlias(username, cwd) {
136
+ const alias = aliasForUsername(username);
137
+ try {
138
+ const result = await runSfCli(['alias', 'set', `${alias}=${username}`, '--json'], { cwd, timeout: CLI_STEP_TIMEOUT_MS });
139
+ if (result.exitCode !== 0) {
140
+ const msg = result.jsonOutput?.message || result.stderr.trim() || 'Unknown error';
141
+ console.error(`[sf-cli-login] could not set alias ${alias}: ${msg}`);
142
+ return null;
143
+ }
144
+ return alias;
145
+ }
146
+ catch (err) {
147
+ console.error(`[sf-cli-login] could not set alias ${alias}: ${err.message}`);
148
+ return null;
149
+ }
150
+ }
151
+ /**
152
+ * `sf org login web --json` already returns the token on stdout, so in the normal case no
153
+ * second CLI call is needed. Returns null if the payload isn't the shape we expect, and the
154
+ * caller falls back to reading the org explicitly.
155
+ */
156
+ function parseLoginPayload(stdout) {
157
+ let parsed;
158
+ try {
159
+ parsed = JSON.parse(stdout);
160
+ }
161
+ catch {
162
+ return null;
163
+ }
164
+ const r = parsed?.result;
165
+ if (!r?.accessToken || !r?.instanceUrl || !r?.username)
166
+ return null;
167
+ return {
168
+ accessToken: r.accessToken,
169
+ instanceUrl: r.instanceUrl,
170
+ username: r.username,
171
+ orgId: r.orgId ?? '(unknown)',
172
+ };
173
+ }
174
+ /**
175
+ * Fallback when the login payload didn't carry the token. Without an alias the org has to
176
+ * be addressed by the username the CLI just recorded as most recently authenticated.
177
+ */
178
+ async function readOrgFromCli(cwd) {
179
+ const list = await runSfCli(['org', 'list', '--json'], { cwd, timeout: CLI_STEP_TIMEOUT_MS });
180
+ if (list.exitCode !== 0) {
181
+ const msg = list.jsonOutput?.message || list.stderr.trim() || 'Unknown error';
182
+ throw new Error(`Could not list authenticated orgs (exit ${list.exitCode}): ${msg}`);
183
+ }
184
+ const orgs = [
185
+ ...(list.jsonOutput?.result?.nonScratchOrgs ?? []),
186
+ ...(list.jsonOutput?.result?.scratchOrgs ?? []),
187
+ ];
188
+ const username = orgs[orgs.length - 1]?.username;
189
+ if (!username) {
190
+ throw new Error('The Salesforce CLI reported no authenticated orgs after login');
191
+ }
192
+ const result = await runSfCli(['org', 'display', '--target-org', username, '--json'], { cwd, timeout: CLI_STEP_TIMEOUT_MS });
193
+ if (result.exitCode !== 0) {
194
+ const msg = result.jsonOutput?.message || result.stderr.trim() || 'Unknown error';
195
+ throw new Error(`Could not read the newly authenticated org (exit ${result.exitCode}): ${msg}`);
196
+ }
197
+ const r = result.jsonOutput?.result ?? {};
198
+ if (!r.accessToken || !r.instanceUrl) {
199
+ throw new Error('The Salesforce CLI returned no accessToken or instanceUrl for the new org');
200
+ }
201
+ return {
202
+ accessToken: r.accessToken,
203
+ instanceUrl: r.instanceUrl,
204
+ username: r.username ?? username,
205
+ orgId: r.id ?? '(unknown)',
206
+ };
207
+ }
208
+ //# sourceMappingURL=sfCliWebLogin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sfCliWebLogin.js","sourceRoot":"","sources":["../../src/utils/sfCliWebLogin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acquis-consulting/asm",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "asm",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",