@salesforce/sfdx-agent-harness-mastra 0.29.0 → 0.31.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.
- package/CHANGELOG.md +15 -0
- package/dist/mastra-harness.js +20 -5
- package/dist/mastra-message-mapper.d.ts +13 -3
- package/dist/mastra-message-mapper.js +114 -36
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
All notable changes to `@salesforce/sfdx-agent-harness-mastra` are documented in this file.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## [0.31.0] - 2026-07-08
|
|
7
|
+
|
|
8
|
+
### Fixes
|
|
9
|
+
- **agent-sdk,harness-mastra,harness-claude**: canonical role:tool placement for completed tool calls @W-23351939 ([#649](https://github.com/forcedotcom/agentic-dx/pull/649))
|
|
10
|
+
|
|
11
|
+
## [0.30.0] - 2026-07-07
|
|
12
|
+
|
|
13
|
+
### Fixes
|
|
14
|
+
- **harness-mastra**: getMessages() round-trips the tool-call part @W-23351939 ([#648](https://github.com/forcedotcom/agentic-dx/pull/648))
|
|
15
|
+
|
|
16
|
+
### Chores
|
|
17
|
+
- **deps**: bump the mastra group across 1 directory with 5 updates ([#644](https://github.com/forcedotcom/agentic-dx/pull/644))
|
|
18
|
+
- **deps**: bump @anthropic-ai/bedrock-sdk from 0.31.0 to 0.32.0 ([#645](https://github.com/forcedotcom/agentic-dx/pull/645))
|
|
19
|
+
- **deps-dev**: bump the dev-dependencies group with 3 updates ([#642](https://github.com/forcedotcom/agentic-dx/pull/642))
|
|
20
|
+
|
|
6
21
|
## [0.29.0] - 2026-07-03
|
|
7
22
|
|
|
8
23
|
_No changes — released alongside dependent packages._
|
package/dist/mastra-harness.js
CHANGED
|
@@ -12,7 +12,7 @@ import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY, RequestContext } from '@m
|
|
|
12
12
|
import { LibSQLStore } from '@mastra/libsql';
|
|
13
13
|
import { MCPClient } from '@mastra/mcp';
|
|
14
14
|
import { AgentSDKError, AgentSDKErrorType, DEFAULT_MAX_STEPS, McpServerStatus, resolveToolApprovalMode, resolveToolApprovalPolicy, } from '@salesforce/sfdx-agent-sdk';
|
|
15
|
-
import { HarnessBusOwner, lowerStreamInput, mcpServerConfigEqual, } from '@salesforce/sfdx-agent-sdk/harness';
|
|
15
|
+
import { HarnessBusOwner, lowerStreamInput, mcpServerConfigEqual, mergeToolResultsIntoAssistant, splitToolResultsIntoToolMessages, } from '@salesforce/sfdx-agent-sdk/harness';
|
|
16
16
|
import { MastraApprovalCoordinator } from './mastra-approval-coordinator.js';
|
|
17
17
|
import { MASTRA_BUILT_IN_TOOL_POLICIES } from './mastra-built-in-policies.js';
|
|
18
18
|
import { SKILL_SEARCH_META_TOOL_NAMES, TOOL_SEARCH_META_TOOL_NAMES } from './skill-bridge.js';
|
|
@@ -1619,9 +1619,16 @@ export class MastraHarness {
|
|
|
1619
1619
|
// silently bucket null-timestamp rows at epoch and propagate
|
|
1620
1620
|
// `undefined` to consumers.
|
|
1621
1621
|
let lastFallback = this.clock.now();
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1622
|
+
const mapped = messages.filter((m) => m.role !== 'signal').map((m) => mapMastraToMessage(m, logBus));
|
|
1623
|
+
// Hoist every completed tool call's `tool-result` part onto its own
|
|
1624
|
+
// `role: 'tool'` message so the consumer-visible layout matches the
|
|
1625
|
+
// cross-harness `getMessages` contract (assistant carries the
|
|
1626
|
+
// `tool-call`; a separate tool message carries the paired result). The
|
|
1627
|
+
// shared normalizer is the single site both harnesses use so the layout
|
|
1628
|
+
// can't drift. Runs before the createdAt backfill so the synthesized tool
|
|
1629
|
+
// messages (which inherit their source's `createdAt`, possibly undefined)
|
|
1630
|
+
// still get a populated timestamp and slot correctly in the sort.
|
|
1631
|
+
return splitToolResultsIntoToolMessages(mapped)
|
|
1625
1632
|
.map((m) => {
|
|
1626
1633
|
if (m.createdAt)
|
|
1627
1634
|
return m;
|
|
@@ -1661,7 +1668,15 @@ export class MastraHarness {
|
|
|
1661
1668
|
// record (Mastra's libsql column is non-nullable). Routes through the
|
|
1662
1669
|
// shared `backfillCreatedAt` helper from `agentic-common` so the SDK
|
|
1663
1670
|
// and both harnesses can't drift on the per-position step policy.
|
|
1664
|
-
|
|
1671
|
+
// Fold any canonical `role: 'tool'` message's result back adjacent to
|
|
1672
|
+
// its `tool-call` in the preceding assistant message (the inverse of the
|
|
1673
|
+
// `splitToolResultsIntoToolMessages` hoist `getMessages` applies). This
|
|
1674
|
+
// recreates the adjacency `mapMessageToMastra` coalesces into a single
|
|
1675
|
+
// `tool-invocation(result)`, so a `getMessages()` → `addContext()`
|
|
1676
|
+
// round-trip stays lossless and never double-stores the call. A no-op for
|
|
1677
|
+
// history that carries no tool messages.
|
|
1678
|
+
const merged = mergeToolResultsIntoAssistant(messages);
|
|
1679
|
+
const filled = backfillCreatedAt(merged, this.clock);
|
|
1665
1680
|
const mapped = filled.map((m) => mapMessageToMastra(m, threadId, resourceId));
|
|
1666
1681
|
await memory.saveMessages({ messages: mapped });
|
|
1667
1682
|
}
|
|
@@ -15,13 +15,23 @@ import type { LogBus } from '@salesforce/agentic-common';
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function mapMastraToMessage(msg: MastraDBMessage, logBus?: LogBus): Message;
|
|
17
17
|
/**
|
|
18
|
-
* Converts a single Mastra message part to
|
|
19
|
-
*
|
|
18
|
+
* Converts a single Mastra message part to zero or more SDK {@link MessagePart}s.
|
|
19
|
+
*
|
|
20
|
+
* Most Mastra parts map one-to-one, but a **completed** `tool-invocation` maps to
|
|
21
|
+
* *two* SDK parts — a `tool-call` (name + args) followed by a `tool-result` — because
|
|
22
|
+
* a single Mastra object carries both halves once its `state` transitions to `'result'`.
|
|
23
|
+
* Emitting both keeps `getMessages()` history harness-agnostic: the model's original
|
|
24
|
+
* tool call (name + args) survives on read exactly as it does on the Claude harness,
|
|
25
|
+
* which stores the call and result as distinct blocks (#647). Returning an array is what
|
|
26
|
+
* lets one input part expand to two output parts without a special case in the caller.
|
|
27
|
+
*
|
|
28
|
+
* Returns an empty array for part types that exist in Mastra but have no SDK
|
|
29
|
+
* representation (e.g. `source`, `step-start`, `partial-call`, `data-*`).
|
|
20
30
|
*
|
|
21
31
|
* @param logBus - When supplied, unrecognized part types emit a `warn` log via this bus.
|
|
22
32
|
* Tests that don't care about logging can omit it.
|
|
23
33
|
*/
|
|
24
|
-
export declare function mapMastraPartToMessagePart(part: MastraMessagePart, logBus?: LogBus): MessagePart
|
|
34
|
+
export declare function mapMastraPartToMessagePart(part: MastraMessagePart, logBus?: LogBus): MessagePart[];
|
|
25
35
|
/**
|
|
26
36
|
* Converts an SDK {@link Message} into the Mastra persisted message format.
|
|
27
37
|
* The `role` field is normalised: `'tool'` role (which has no Mastra equivalent)
|
|
@@ -29,6 +29,33 @@ function formatApproxSize(base64Data) {
|
|
|
29
29
|
return `${kib.toFixed(1)} KB`;
|
|
30
30
|
return `${(kib / 1024).toFixed(1)} MB`;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Builds the single Mastra `tool-invocation` part that represents a completed
|
|
34
|
+
* tool call, carrying both the original `args` and the outcome. A successful
|
|
35
|
+
* result maps to `state: 'result'` with `result`; an errored result
|
|
36
|
+
* (`isError: true`) maps to `state: 'output-error'` — Mastra's native shape for
|
|
37
|
+
* a failed invocation. For the error case both the structured `result` AND a
|
|
38
|
+
* stringified `errorText` are written: the read mapper prefers `result` so a
|
|
39
|
+
* non-string error payload round-trips as an object, and `errorText` is Mastra's
|
|
40
|
+
* native error slot (used as the fallback for natively-persisted error
|
|
41
|
+
* invocations that carry only that). This is the write-side counterpart of the
|
|
42
|
+
* `mapMastraPartToMessagePart` expansion, so an errored tool result survives a
|
|
43
|
+
* `getMessages()` → `addContext()` round-trip with its `isError` flag and its
|
|
44
|
+
* `result` structure intact (the cross-harness `isError` contract, #647).
|
|
45
|
+
*/
|
|
46
|
+
function buildCompletedToolInvocation(toolCallId, toolName, args, result) {
|
|
47
|
+
if (result.isError === true) {
|
|
48
|
+
const errorText = typeof result.result === 'string' ? result.result : JSON.stringify(result.result);
|
|
49
|
+
return {
|
|
50
|
+
type: 'tool-invocation',
|
|
51
|
+
toolInvocation: { state: 'output-error', toolCallId, toolName, args, result: result.result, errorText },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
type: 'tool-invocation',
|
|
56
|
+
toolInvocation: { state: 'result', toolCallId, toolName, args, result: result.result },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
32
59
|
/**
|
|
33
60
|
* Converts a Mastra persisted message into the SDK's {@link Message} type.
|
|
34
61
|
*
|
|
@@ -47,10 +74,7 @@ export function mapMastraToMessage(msg, logBus) {
|
|
|
47
74
|
}
|
|
48
75
|
const parts = [];
|
|
49
76
|
for (const part of msg.content.parts) {
|
|
50
|
-
|
|
51
|
-
if (mapped) {
|
|
52
|
-
parts.push(mapped);
|
|
53
|
-
}
|
|
77
|
+
parts.push(...mapMastraPartToMessagePart(part, logBus));
|
|
54
78
|
}
|
|
55
79
|
const consolidated = consolidateAdjacentTextParts(parts);
|
|
56
80
|
const isSingleText = consolidated.length === 1 && consolidated[0].type === 'text';
|
|
@@ -85,8 +109,18 @@ function consolidateAdjacentTextParts(parts) {
|
|
|
85
109
|
return result;
|
|
86
110
|
}
|
|
87
111
|
/**
|
|
88
|
-
* Converts a single Mastra message part to
|
|
89
|
-
*
|
|
112
|
+
* Converts a single Mastra message part to zero or more SDK {@link MessagePart}s.
|
|
113
|
+
*
|
|
114
|
+
* Most Mastra parts map one-to-one, but a **completed** `tool-invocation` maps to
|
|
115
|
+
* *two* SDK parts — a `tool-call` (name + args) followed by a `tool-result` — because
|
|
116
|
+
* a single Mastra object carries both halves once its `state` transitions to `'result'`.
|
|
117
|
+
* Emitting both keeps `getMessages()` history harness-agnostic: the model's original
|
|
118
|
+
* tool call (name + args) survives on read exactly as it does on the Claude harness,
|
|
119
|
+
* which stores the call and result as distinct blocks (#647). Returning an array is what
|
|
120
|
+
* lets one input part expand to two output parts without a special case in the caller.
|
|
121
|
+
*
|
|
122
|
+
* Returns an empty array for part types that exist in Mastra but have no SDK
|
|
123
|
+
* representation (e.g. `source`, `step-start`, `partial-call`, `data-*`).
|
|
90
124
|
*
|
|
91
125
|
* @param logBus - When supplied, unrecognized part types emit a `warn` log via this bus.
|
|
92
126
|
* Tests that don't care about logging can omit it.
|
|
@@ -94,60 +128,98 @@ function consolidateAdjacentTextParts(parts) {
|
|
|
94
128
|
export function mapMastraPartToMessagePart(part, logBus) {
|
|
95
129
|
switch (part.type) {
|
|
96
130
|
case 'text':
|
|
97
|
-
return { type: 'text', text: part.text };
|
|
131
|
+
return [{ type: 'text', text: part.text }];
|
|
98
132
|
case 'reasoning':
|
|
99
|
-
return { type: 'reasoning', text: part.reasoning };
|
|
133
|
+
return [{ type: 'reasoning', text: part.reasoning }];
|
|
100
134
|
case 'tool-invocation': {
|
|
101
135
|
const inv = part.toolInvocation;
|
|
102
136
|
if (inv.state === 'partial-call') {
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
if (inv.state === 'result') {
|
|
106
|
-
return {
|
|
107
|
-
type: 'tool-result',
|
|
108
|
-
toolCallId: inv.toolCallId,
|
|
109
|
-
toolName: inv.toolName,
|
|
110
|
-
result: inv.result,
|
|
111
|
-
};
|
|
137
|
+
return [];
|
|
112
138
|
}
|
|
113
|
-
|
|
139
|
+
const toolCall = {
|
|
114
140
|
type: 'tool-call',
|
|
115
141
|
toolCallId: inv.toolCallId,
|
|
116
142
|
toolName: inv.toolName,
|
|
117
|
-
args: inv.args,
|
|
143
|
+
args: (inv.args ?? {}),
|
|
118
144
|
};
|
|
145
|
+
// A completed invocation carries both the original call (name + args)
|
|
146
|
+
// and its outcome; surface both so history round-trips the call the
|
|
147
|
+
// model made, not just its result. Mastra models a completed call in
|
|
148
|
+
// three states: `result` (success) and `output-error` / `output-denied`
|
|
149
|
+
// (failure). All three expand to a tool-call + tool-result pair; the
|
|
150
|
+
// two error states set `isError: true`, matching the SDK
|
|
151
|
+
// `ToolResultPart` shape and the cross-harness `isError` round-trip
|
|
152
|
+
// contract (#647). The shared `splitToolResultsIntoToolMessages`
|
|
153
|
+
// normalizer (run in `getMessages`) then hoists the tool-result onto
|
|
154
|
+
// its own `role: 'tool'` message.
|
|
155
|
+
//
|
|
156
|
+
// KNOWN BEHAVIOR: a completed invocation always carries `args` (the
|
|
157
|
+
// model's real call), so the expanded `tool-call` reflects what the
|
|
158
|
+
// model actually invoked. The one exception is inconsistent history a
|
|
159
|
+
// consumer hand-constructs via `addContext` — a lone `role: 'tool'`
|
|
160
|
+
// result with no matching `tool-call`. `mergeToolResultsIntoAssistant`
|
|
161
|
+
// can't fold it (no call to attach to), so it persists as a standalone
|
|
162
|
+
// `tool-invocation(result)` with `args: {}`, and this read then
|
|
163
|
+
// fabricates a `tool-call` with those empty args. The SDK never emits
|
|
164
|
+
// that shape itself; it's an accepted edge of accepting arbitrary
|
|
165
|
+
// caller-supplied history.
|
|
166
|
+
if (inv.state === 'result') {
|
|
167
|
+
return [
|
|
168
|
+
toolCall,
|
|
169
|
+
{ type: 'tool-result', toolCallId: inv.toolCallId, toolName: inv.toolName, result: inv.result },
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
if (inv.state === 'output-error' || inv.state === 'output-denied') {
|
|
173
|
+
// Prefer the structured `result` (the write path preserves it
|
|
174
|
+
// alongside `errorText`) so a non-string error payload round-trips
|
|
175
|
+
// as an object, not a JSON string; fall back to `errorText` for
|
|
176
|
+
// natively-persisted error invocations that carry only that.
|
|
177
|
+
return [
|
|
178
|
+
toolCall,
|
|
179
|
+
{
|
|
180
|
+
type: 'tool-result',
|
|
181
|
+
toolCallId: inv.toolCallId,
|
|
182
|
+
toolName: inv.toolName,
|
|
183
|
+
result: inv.result ?? inv.errorText,
|
|
184
|
+
isError: true,
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
// `call`, `approval-requested`, `approval-responded`: the call was
|
|
189
|
+
// made but has no outcome yet — surface the tool-call alone.
|
|
190
|
+
return [toolCall];
|
|
119
191
|
}
|
|
120
192
|
case 'file': {
|
|
121
193
|
// Read path: base64 data is returned verbatim from LibSQL — see ARCHITECTURE.md → "Memory Strategy"
|
|
122
194
|
// for the storage-cost caveat (no blob offloading; full encoded size per attachment per row).
|
|
123
195
|
const fileName = readSalesforceFileName(part.providerMetadata);
|
|
124
196
|
if (part.mimeType === 'image/png' || part.mimeType === 'image/jpeg') {
|
|
125
|
-
return { type: 'image', mimeType: part.mimeType, data: part.data, ...(fileName ? { fileName } : {}) };
|
|
197
|
+
return [{ type: 'image', mimeType: part.mimeType, data: part.data, ...(fileName ? { fileName } : {}) }];
|
|
126
198
|
}
|
|
127
199
|
if (part.mimeType === 'application/pdf') {
|
|
128
|
-
return { type: 'file', mimeType: part.mimeType, data: part.data, ...(fileName ? { fileName } : {}) };
|
|
200
|
+
return [{ type: 'file', mimeType: part.mimeType, data: part.data, ...(fileName ? { fileName } : {}) }];
|
|
129
201
|
}
|
|
130
202
|
logBus?.warn('Skipping file MastraMessagePart with unsupported mimeType; omitted from message history', {
|
|
131
203
|
mimeType: part.mimeType,
|
|
132
204
|
hint: 'Only image/png, image/jpeg, and application/pdf map to SDK message parts.',
|
|
133
205
|
});
|
|
134
|
-
return
|
|
206
|
+
return [];
|
|
135
207
|
}
|
|
136
208
|
// Part types that exist in Mastra but have no SDK equivalent yet.
|
|
137
209
|
case 'source':
|
|
138
210
|
case 'step-start':
|
|
139
|
-
return
|
|
211
|
+
return [];
|
|
140
212
|
default:
|
|
141
213
|
// AI SDK v5 data parts use a `data-*` type prefix for framework-specific
|
|
142
214
|
// metadata (e.g. workspace info). These are harness-internal and expected.
|
|
143
215
|
if (part.type.startsWith('data-')) {
|
|
144
|
-
return
|
|
216
|
+
return [];
|
|
145
217
|
}
|
|
146
218
|
logBus?.warn('Skipping unrecognized MastraMessagePart; omitted from message history', {
|
|
147
219
|
partType: part.type,
|
|
148
220
|
hint: 'Update mapMastraPartToMessagePart to handle this type if it should be mapped.',
|
|
149
221
|
});
|
|
150
|
-
return
|
|
222
|
+
return [];
|
|
151
223
|
}
|
|
152
224
|
}
|
|
153
225
|
/**
|
|
@@ -161,7 +233,22 @@ export function mapMessageToMastra(msg, threadId, resourceId) {
|
|
|
161
233
|
parts.push({ type: 'text', text: msg.content });
|
|
162
234
|
}
|
|
163
235
|
else {
|
|
164
|
-
|
|
236
|
+
const content = msg.content;
|
|
237
|
+
for (let i = 0; i < content.length; i++) {
|
|
238
|
+
const part = content[i];
|
|
239
|
+
const next = content[i + 1];
|
|
240
|
+
// Coalesce an adjacent tool-call + tool-result for the same toolCallId
|
|
241
|
+
// into ONE Mastra `tool-invocation(result)` carrying both `args` and
|
|
242
|
+
// `result`. This mirrors how Mastra natively persists a completed call
|
|
243
|
+
// (its MessageList merges the call and result into a single object) and
|
|
244
|
+
// is the exact inverse of the read-path expansion in
|
|
245
|
+
// `mapMastraPartToMessagePart`, so a `getMessages()` → `addContext()`
|
|
246
|
+
// round-trip is lossless and never double-counts the call (#647).
|
|
247
|
+
if (part.type === 'tool-call' && next?.type === 'tool-result' && next.toolCallId === part.toolCallId) {
|
|
248
|
+
parts.push(buildCompletedToolInvocation(part.toolCallId, part.toolName, part.args, next));
|
|
249
|
+
i++; // consumed the paired tool-result
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
165
252
|
parts.push(mapMessagePartToMastra(part));
|
|
166
253
|
}
|
|
167
254
|
}
|
|
@@ -212,16 +299,7 @@ export function mapMessagePartToMastra(part) {
|
|
|
212
299
|
},
|
|
213
300
|
};
|
|
214
301
|
case 'tool-result':
|
|
215
|
-
return {
|
|
216
|
-
type: 'tool-invocation',
|
|
217
|
-
toolInvocation: {
|
|
218
|
-
state: 'result',
|
|
219
|
-
toolCallId: part.toolCallId,
|
|
220
|
-
toolName: part.toolName,
|
|
221
|
-
args: {},
|
|
222
|
-
result: part.result,
|
|
223
|
-
},
|
|
224
|
-
};
|
|
302
|
+
return buildCompletedToolInvocation(part.toolCallId, part.toolName, {}, part);
|
|
225
303
|
case 'image':
|
|
226
304
|
case 'file':
|
|
227
305
|
// Mastra persists a single `file` UIMessage part for both. The SDK's `fileName` has no
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sfdx-agent-harness-mastra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "Mastra-backed AgentHarness implementation for @salesforce/sfdx-agent-sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,22 +29,22 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@ai-sdk/provider": "^3.0.10",
|
|
32
|
-
"@anthropic-ai/bedrock-sdk": "^0.
|
|
32
|
+
"@anthropic-ai/bedrock-sdk": "^0.32.0",
|
|
33
33
|
"@anthropic-ai/sdk": "^0.106.0",
|
|
34
|
-
"@mastra/core": "^1.
|
|
35
|
-
"@mastra/libsql": "^1.
|
|
36
|
-
"@mastra/mcp": "^1.
|
|
37
|
-
"@mastra/memory": "^1.
|
|
34
|
+
"@mastra/core": "^1.49.0",
|
|
35
|
+
"@mastra/libsql": "^1.15.0",
|
|
36
|
+
"@mastra/mcp": "^1.13.0",
|
|
37
|
+
"@mastra/memory": "^1.22.1",
|
|
38
38
|
"@mastra/schema-compat": "^1.2.11",
|
|
39
39
|
"@salesforce/agentic-common": "0.13.0",
|
|
40
40
|
"openai": "^6.0.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@salesforce/sfdx-agent-sdk": "0.
|
|
43
|
+
"@salesforce/sfdx-agent-sdk": "0.32.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@eslint/js": "^10.0.1",
|
|
47
|
-
"@salesforce/sfdx-agent-sdk": "0.
|
|
47
|
+
"@salesforce/sfdx-agent-sdk": "0.32.0",
|
|
48
48
|
"@types/node": "^22.20.0",
|
|
49
49
|
"@vitest/coverage-istanbul": "^4.1.8",
|
|
50
50
|
"@vitest/eslint-plugin": "^1.6.20",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
"eslint-plugin-n": "^18.2.1",
|
|
56
56
|
"globals": "^17.6.0",
|
|
57
57
|
"lint-staged": "^17.0.7",
|
|
58
|
-
"prettier": "^3.9.
|
|
58
|
+
"prettier": "^3.9.4",
|
|
59
59
|
"rimraf": "^6.1.3",
|
|
60
|
-
"tsx": "^4.
|
|
60
|
+
"tsx": "^4.23.0",
|
|
61
61
|
"typescript": "^6.0.3",
|
|
62
|
-
"typescript-eslint": "^8.
|
|
62
|
+
"typescript-eslint": "^8.62.1",
|
|
63
63
|
"vitest": "^4.1.8"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|