@salesforce/graphiti 11.14.0 → 11.16.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 (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/intent/build-aggregate.js +6 -0
  3. package/dist/intent/build-aggregate.js.map +1 -1
  4. package/dist/intent/build-output.d.ts +15 -1
  5. package/dist/intent/build-output.js +15 -1
  6. package/dist/intent/build-output.js.map +1 -1
  7. package/dist/lib/errors.d.ts +54 -1
  8. package/dist/lib/errors.js +104 -8
  9. package/dist/lib/errors.js.map +1 -1
  10. package/dist/lib/introspect.js +10 -3
  11. package/dist/lib/introspect.js.map +1 -1
  12. package/dist/lib/prime-schema.d.ts +10 -0
  13. package/dist/lib/prime-schema.js +31 -4
  14. package/dist/lib/prime-schema.js.map +1 -1
  15. package/dist/lib/query-builder.d.ts +11 -0
  16. package/dist/lib/query-builder.js +174 -12
  17. package/dist/lib/query-builder.js.map +1 -1
  18. package/dist/mcp/tools/sf-gql-connect.js +1 -1
  19. package/dist/mcp/tools/sf-gql-connect.js.map +1 -1
  20. package/dist/schemas/tool-adapter.d.ts +17 -1
  21. package/dist/schemas/tool-adapter.js +29 -6
  22. package/dist/schemas/tool-adapter.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/intent/__tests__/build-aggregate.spec.ts +24 -0
  25. package/src/intent/__tests__/build-output.spec.ts +24 -1
  26. package/src/intent/build-aggregate.ts +6 -0
  27. package/src/intent/build-output.ts +15 -1
  28. package/src/lib/__tests__/query-builder.spec.ts +388 -0
  29. package/src/lib/errors.ts +125 -2
  30. package/src/lib/introspect.ts +10 -2
  31. package/src/lib/prime-schema.ts +32 -4
  32. package/src/lib/query-builder.ts +176 -11
  33. package/src/mcp/tools/__tests__/error-surface.contract.spec.ts +50 -1
  34. package/src/mcp/tools/sf-gql-connect.ts +1 -1
  35. package/src/schemas/__tests__/tool-adapter.spec.ts +162 -1
  36. package/src/schemas/tool-adapter.ts +51 -7
@@ -3,10 +3,22 @@
3
3
  * All rights reserved.
4
4
  * For full license text, see the LICENSE.txt file
5
5
  */
6
- import { GRAPHQL_NAME_RE } from "./graphql-name.js";
6
+ import { UserInputError } from "./errors.js";
7
+ import { assertGraphqlName, GRAPHQL_NAME_RE } from "./graphql-name.js";
7
8
  import { getChildren, getEffectiveArgs } from "./session.js";
8
9
  /**
9
10
  * Renders a QuerySession's selection tree into a properly formatted GraphQL query string.
11
+ *
12
+ * @throws if any emitted GraphQL Name (operation name, variable name, field
13
+ * name, alias, inline-fragment type condition, or directive name) is not a
14
+ * valid GraphQL Name, if a variable's type reference has a non-Name innermost
15
+ * NamedType, or if a `{`/`[`-prefixed argument/default value is not valid JSON
16
+ * — the W-23204027 render-layer fail-safe. This fires only on a programmer
17
+ * error (a builder/CLI path that stored a raw identifier without its own guard)
18
+ * or a hostile input that slipped past the per-builder guards; every legitimate
19
+ * value passes. Name violations throw an `Error` whose message matches
20
+ * USER_INPUT_RE; the JSON-literal violation throws a typed `UserInputError` —
21
+ * both classify as UserInput at the MCP boundary (`runTool`).
10
22
  */
11
23
  export function renderQuery(session) {
12
24
  const parts = [];
@@ -14,14 +26,41 @@ export function renderQuery(session) {
14
26
  const varDefs = session.variables.length > 0
15
27
  ? `(${session.variables
16
28
  .map((v) => {
29
+ // Fail-safe: the variable NAME is a GraphQL Name position emitted
30
+ // verbatim as `$<name>`. The TYPE is also emitted verbatim, but it
31
+ // is not a bare Name — it carries type-reference syntax (`!`, `[]`)
32
+ // — so it is guarded structurally by assertGraphqlType, which walks
33
+ // the wrappers and asserts only the innermost NamedType.
34
+ assertGraphqlName(v.name, "renderQuery", "variableName");
35
+ assertGraphqlType(v.type, "renderQuery");
17
36
  let def = `$${v.name}: ${v.type}`;
37
+ // W-23204027 (PR #694 review): the default VALUE is a value position,
38
+ // not a Name — it must be formatted like any other arg value, not
39
+ // concatenated raw. Raw emission both breaks legitimate output (a
40
+ // multi-word string default renders `= Acme Corp`, which fails to
41
+ // parse) and is a live selection-set/operation injection sink: a
42
+ // default of `5) { stolen { Id } } query Decoy($z: Int` (reachable
43
+ // via `sf_gql_raw`'s `var $x <path> '<default>'`) would otherwise
44
+ // render a second, attacker-controlled operation. formatArgValue
45
+ // quotes strings, passes through numbers/enums/bools/`$refs`, and
46
+ // routes `{`/`[` defaults through jsonToGraphQL, which either emits
47
+ // an arg-key-guarded input-object literal (valid JSON) or throws
48
+ // (invalid JSON — see Round 3 fix in jsonToGraphQL). No variant
49
+ // reaches raw emission.
18
50
  if (v.defaultValue !== undefined)
19
- def += ` = ${v.defaultValue}`;
51
+ def += ` = ${formatArgValue(v.defaultValue)}`;
20
52
  return def;
21
53
  })
22
54
  .join(", ")})`
23
55
  : "";
24
56
  const operationKeyword = session.operation === "aggregate" ? "query" : session.operation;
57
+ // Fail-safe: operationName is a GraphQL Name position emitted verbatim in the
58
+ // operation header. Guarded at every builder, but a deserialized/migrated
59
+ // session (loadSession reads it from disk with no re-validation) or a future
60
+ // builder could bypass that — so backstop it here too.
61
+ if (session.operationName) {
62
+ assertGraphqlName(session.operationName, "renderQuery", "operationName");
63
+ }
25
64
  const operationName = session.operationName ? ` ${session.operationName}` : "";
26
65
  const operationBody = renderChildren(session, null, 1);
27
66
  if (operationBody) {
@@ -34,6 +73,61 @@ export function renderQuery(session) {
34
73
  }
35
74
  return parts.join("\n");
36
75
  }
76
+ /**
77
+ * W-23204027 render-layer fail-safe for GraphQL argument KEYS. An argument key
78
+ * is emitted verbatim as `<key>: <value>` in three places — a field's argument
79
+ * names (renderField), a directive's argument names (renderDirective), and the
80
+ * keys of a nested input-object literal (valueToGraphQL). The last is
81
+ * attacker-reachable today: `sf_gql_list` / `sf_gql_aggregate` accept a `filter`
82
+ * / `orderBy` typed as `z.record(z.unknown())` (no charset on keys), the builder
83
+ * `JSON.stringify`s it into an arg value, and valueToGraphQL then emits each
84
+ * input field name / operator as a key. A key such as
85
+ * `Name: {eq:"x"} }) { edges { node { Id } } } evilAlias: accounts(where: { Industry`
86
+ * would otherwise render a fully parseable, schema-valid second connection —
87
+ * a silent selection-set injection. Keys are NOT validated at the builder or
88
+ * zod layer, so this render-layer assert is the only universal choke point
89
+ * (everything funnels through the renderer). Every legitimate key — operators
90
+ * (eq/ne/and/or/not/…), SObject field API names incl. `Custom__c`, connection
91
+ * args — is a valid GraphQL Name, so this never fires on real input.
92
+ */
93
+ function assertArgumentKey(key, emitter) {
94
+ assertGraphqlName(key, emitter, "argumentKey");
95
+ }
96
+ /**
97
+ * W-23204027 render-layer fail-safe for a variable's TYPE reference. Unlike a
98
+ * Name position, a type carries GraphQL type-reference syntax (`!` for
99
+ * non-null, `[...]` for lists) and so cannot be a bare `assertGraphqlName` —
100
+ * that would wrongly reject legitimate types like `Int!` or `[ID!]!`. Instead
101
+ * we walk the type-reference grammar structurally (October 2021 §2.11): strip a
102
+ * trailing non-null `!`, unwrap a `[ ... ]` list wrapper (recursing on the inner
103
+ * type), and finally assert the innermost NamedType is a valid GraphQL Name.
104
+ *
105
+ * This is a defense-in-depth backstop, not a live-reachable sink today: every
106
+ * `addVariable` call site derives the type from schema inference,
107
+ * `createInputTypeName`, or a hardcoded scalar — none accept a raw type from the
108
+ * agent (the CLI `var`/`define` verbs set only the NAME, never the type). It
109
+ * guards the residual paths a Name backstop would otherwise miss: a
110
+ * deserialized/migrated session (`loadSession` does no type re-validation) or a
111
+ * future builder that stores a raw type. Without it, a type such as
112
+ * `Int) { evil { id } } query Decoy($z: Int` emitted verbatim as `$v: <type>`
113
+ * breaks out into a second operation with no default value needed.
114
+ */
115
+ function assertGraphqlType(type, emitter) {
116
+ let inner = type.trim();
117
+ // Peel any number of non-null / list wrappers from the outside in.
118
+ while (true) {
119
+ if (inner.endsWith("!")) {
120
+ inner = inner.slice(0, -1).trim();
121
+ continue;
122
+ }
123
+ if (inner.startsWith("[") && inner.endsWith("]")) {
124
+ inner = inner.slice(1, -1).trim();
125
+ continue;
126
+ }
127
+ break;
128
+ }
129
+ assertGraphqlName(inner, emitter, "variableType");
130
+ }
37
131
  function renderChildren(session, parentId, depth) {
38
132
  const _indent = " ".repeat(depth);
39
133
  const lines = [];
@@ -50,15 +144,29 @@ function renderChildren(session, parentId, depth) {
50
144
  function renderField(session, node, depth) {
51
145
  const indent = " ".repeat(depth);
52
146
  let line = indent;
53
- // Alias
147
+ // W-23204027 render-layer fail-safe: assert every emitted GraphQL Name is
148
+ // valid, making "the renderer never emits an injectable identifier" a
149
+ // system-wide invariant layered UNDER the per-builder guards (W-22735537),
150
+ // not replacing them. Fires only on a programmer error — a future builder
151
+ // that calls selectLeaf/selectDottedFieldPath and forgets its assert — so
152
+ // failing loud is correct. The message matches USER_INPUT_RE, so the MCP
153
+ // path classifies it as UserInput rather than crashing. Argument *keys* are
154
+ // covered too: they are emitted verbatim as `<key>: <value>` here and in
155
+ // renderDirective/valueToGraphQL, so a malicious filter/orderBy key (a
156
+ // z.record(z.unknown()) with no charset at the schema boundary — see
157
+ // assertArgumentKey) can otherwise break out of the argument object into
158
+ // the selection set. That sink is NOT closed at the builder or zod layer.
54
159
  if (node.alias) {
160
+ assertGraphqlName(node.alias, "renderField", "alias");
55
161
  line += `${node.alias}: `;
56
162
  }
163
+ assertGraphqlName(node.fieldName, "renderField", "fieldName");
57
164
  line += node.fieldName;
58
165
  // Arguments
59
166
  const argEntries = Object.entries(getEffectiveArgs(session, node));
60
167
  if (argEntries.length > 0) {
61
168
  const argParts = argEntries.map(([name, value]) => {
169
+ assertArgumentKey(name, "renderField");
62
170
  return `${name}: ${formatArgValue(value)}`;
63
171
  });
64
172
  line += `(${argParts.join(", ")})`;
@@ -78,6 +186,9 @@ function renderField(session, node, depth) {
78
186
  }
79
187
  function renderInlineFragment(session, frag, depth) {
80
188
  const indent = " ".repeat(depth);
189
+ // W-23204027 render-layer fail-safe (see renderField): a type condition is a
190
+ // GraphQL Name position emitted verbatim after `... on `.
191
+ assertGraphqlName(frag.onType, "renderInlineFragment", "onType");
81
192
  let line = `${indent}... on ${frag.onType}`;
82
193
  for (const dir of frag.directives) {
83
194
  line += ` ${renderDirective(dir)}`;
@@ -92,11 +203,19 @@ function renderInlineFragment(session, frag, depth) {
92
203
  return line;
93
204
  }
94
205
  function renderDirective(dir) {
206
+ // W-23204027 render-layer fail-safe (see renderField): a directive name is a
207
+ // GraphQL Name position emitted verbatim after `@`. The only directive the
208
+ // declarative/MCP surface adds is `@optional` (a valid Name), so this never
209
+ // fires on legitimate output.
210
+ assertGraphqlName(dir.name, "renderDirective", "directiveName");
95
211
  const argEntries = Object.entries(dir.args);
96
212
  if (argEntries.length === 0) {
97
213
  return `@${dir.name}`;
98
214
  }
99
- const argParts = argEntries.map(([name, value]) => `${name}: ${formatArgValue(value)}`);
215
+ const argParts = argEntries.map(([name, value]) => {
216
+ assertArgumentKey(name, "renderDirective");
217
+ return `${name}: ${formatArgValue(value)}`;
218
+ });
100
219
  return `@${dir.name}(${argParts.join(", ")})`;
101
220
  }
102
221
  /**
@@ -123,9 +242,23 @@ function formatArgValue(value) {
123
242
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
124
243
  return jsonToGraphQL(trimmed);
125
244
  }
126
- // Quoted string — pass through
127
- if (trimmed.startsWith('"') && trimmed.endsWith('"'))
128
- return trimmed;
245
+ // Quoted string — pass through ONLY when it is a single, well-formed string
246
+ // literal. W-23204027 (PR #694 review): a bare `startsWith('"') && endsWith('"')`
247
+ // check is an injection hole — a payload like
248
+ // `"a") { stolen } query Y($q: String = "b"` also starts and ends with a quote
249
+ // yet breaks out of the value into a second operation. JSON.parse yielding a
250
+ // string proves the whole token is ONE literal (interior quotes are escaped);
251
+ // anything else falls through to JSON.stringify, which re-encodes it as a safe
252
+ // single literal.
253
+ if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
254
+ try {
255
+ if (typeof JSON.parse(trimmed) === "string")
256
+ return trimmed;
257
+ }
258
+ catch {
259
+ // Not a single well-formed literal — re-encode below.
260
+ }
261
+ }
129
262
  // Default: a string literal. JSON.stringify produces a spec-valid GraphQL string
130
263
  // literal — it escapes line terminators and control chars (\n \r \t \b \f) and
131
264
  // quotes/backslashes — so values like "a\nb" don't render a raw newline that
@@ -138,14 +271,34 @@ function formatArgValue(value) {
138
271
  * GraphQL uses unquoted keys: { Status: { ne: "Closed" } }
139
272
  */
140
273
  function jsonToGraphQL(jsonStr) {
274
+ let parsed;
141
275
  try {
142
- const parsed = JSON.parse(jsonStr);
143
- return valueToGraphQL(parsed);
276
+ parsed = JSON.parse(jsonStr);
144
277
  }
145
278
  catch {
146
- // If not valid JSON, return as-is (might already be in GraphQL format)
147
- return jsonStr;
279
+ // W-23204027 (PR #694 review, Round 3): REJECT do NOT return the raw
280
+ // string. `formatArgValue` only routes here when the value starts with `{`
281
+ // or `[`, so a JSON.parse failure means it is a `{`/`[`-prefixed string
282
+ // that is NOT well-formed JSON — never legitimate GraphQL. Every real
283
+ // producer of a `{`/`[` value delivers valid JSON (the builders
284
+ // `JSON.stringify` filter/orderBy; the CLI `set`/`assign` path
285
+ // JSON-validates `{`/`[` literals in `validateLiteralAssignment` before
286
+ // storing), so this rejects zero legitimate flows. Returning it verbatim
287
+ // bypassed valueToGraphQL's `assertArgumentKey`, making it a live
288
+ // selection-set/operation injection sink: a variable default of
289
+ // `{ minRevenue: 0 }) { edges { node { id } } } } query Decoy($z: Filter`
290
+ // (unquoted key ⇒ invalid JSON ⇒ this catch; reachable via `sf_gql_raw`'s
291
+ // `var $x <path> '<default>'`) rendered a second, attacker-controlled
292
+ // operation. Throw a typed UserInputError (NOT a bare Error whose text
293
+ // would miss USER_INPUT_RE and misclassify as Internal) so `runTool`
294
+ // classifies it UserInput.
295
+ throw new UserInputError(`jsonToGraphQL: value beginning with '{' or '[' is not valid JSON and cannot be rendered as a GraphQL literal: ${jsonStr.slice(0, 60)}`);
148
296
  }
297
+ // valueToGraphQL runs OUTSIDE the try: it enforces the W-23204027 arg-key
298
+ // fail-safe by throwing on a malicious input-object key, and that assertion
299
+ // must propagate — not be swallowed and fall back to emitting the raw
300
+ // (injectable) string.
301
+ return valueToGraphQL(parsed);
149
302
  }
150
303
  function valueToGraphQL(value) {
151
304
  if (value === null || value === undefined)
@@ -173,7 +326,16 @@ function valueToGraphQL(value) {
173
326
  }
174
327
  if (typeof value === "object") {
175
328
  const entries = Object.entries(value);
176
- const parts = entries.map(([k, v]) => `${k}: ${valueToGraphQL(v)}`);
329
+ const parts = entries.map(([k, v]) => {
330
+ // The live arg-key injection sink: filter/orderBy objects are
331
+ // JSON.stringify'd into an arg value by the builders, so every input
332
+ // field name / operator here is an attacker-controllable key emitted
333
+ // verbatim into a GraphQL input-object literal. Guard it (see
334
+ // assertArgumentKey). Array elements never reach this branch as keys —
335
+ // the Array case above emits `[...]` with no `<key>:`.
336
+ assertArgumentKey(k, "valueToGraphQL");
337
+ return `${k}: ${valueToGraphQL(v)}`;
338
+ });
177
339
  return `{ ${parts.join(", ")} }`;
178
340
  }
179
341
  return String(value);
@@ -1 +1 @@
1
- {"version":3,"file":"query-builder.js","sourceRoot":"","sources":["../../src/lib/query-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-builder.js","sourceRoot":"","sources":["../../src/lib/query-builder.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ import { runTool } from "../../schemas/tool-adapter.js";
9
9
  const inputSchema = CONNECT_INPUT.shape;
10
10
  export function registerSfGqlConnectTool(server, opts = {}) {
11
11
  server.registerTool("sf_gql_connect", {
12
- description: "Connect to a Salesforce org and prime its GraphQL schema cache. With forceRefresh, re-download the schema and coherently clear all caches so subsequent tools see freshly-deployed metadata. Concurrent refreshes coalesce into a single introspection. Returns { org, instanceUrl, refreshed, cached, durationMs, warnings? } — not the standard ToolOutput envelope. If a refresh fails but a usable cached schema survives, returns refreshed:false with a staleness warning instead of erroring. Error convention (all sf_gql_* tools): on failure the isError text is prefixed with a category — `UserInput:` (fix the request), `Auth:` (re-authenticate the org), `Schema:` (introspection/cache problem), or `Internal:` (unexpected) — so you can decide whether to fix inputs, re-auth, or retry.",
12
+ description: "Connect to a Salesforce org and prime its GraphQL schema cache. With forceRefresh, re-download the schema and coherently clear all caches so subsequent tools see freshly-deployed metadata. Concurrent refreshes coalesce into a single introspection. Returns { org, instanceUrl, refreshed, cached, durationMs, warnings? } — not the standard ToolOutput envelope. If a refresh fails but a usable cached schema survives, returns refreshed:false with a staleness warning instead of erroring. Error convention (all sf_gql_* tools): on failure the isError text is prefixed with a category — `UserInput:` (fix the request), `Auth:` (re-authenticate the org), `Schema:` (introspection/cache problem), or `Internal:` (unexpected) — so you can decide whether to fix inputs, re-auth, or retry. A `Schema:` error additionally ends with a retryability token: `[retry=now]` (retry immediately — e.g. a priming-lock timeout, where no live org round-trip occurred) or `[retry=backoff]` (the org was unreachable and an automatic retry already failed — wait with increasing backoff, e.g. 2^n seconds capped around 8s, and retry serially; do not fan out concurrent retries against an org that is already failing, and note some conditions such as an org API rate limit may take longer than a few seconds to clear); ABSENCE of any `[retry=...]` token means the failure is permanent (404, missing/malformed `__schema`, GraphQL errors in the body, or no cached schema) — do not retry, fix the request or re-prime via sf_gql_connect. This token convention applies to every sf_gql_* tool, not just this one. Example error text: `Schema: introspection request failed [retry=backoff]`; extract the disposition with the end-anchored regex ` /\\s\\[retry=(now|backoff)\\]$/` (no match ⇒ permanent).",
13
13
  inputSchema,
14
14
  }, async (args) => runTool(() => buildConnect(args, opts)));
15
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sf-gql-connect.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-connect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAoB,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAIxD,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC;AAExC,MAAM,UAAU,wBAAwB,CACvC,MAAiB,EACjB,OAAgC,EAAE;IAElC,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,WAAW,EACV,6wBAA6wB;QAC9wB,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CACvD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"sf-gql-connect.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-connect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAoB,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAIxD,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC;AAExC,MAAM,UAAU,wBAAwB,CACvC,MAAiB,EACjB,OAAgC,EAAE;IAElC,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,WAAW,EACV,wuDAAwuD;QACzuD,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CACvD,CAAC;AACH,CAAC"}
@@ -3,6 +3,7 @@
3
3
  * All rights reserved.
4
4
  * For full license text, see the LICENSE.txt file
5
5
  */
6
+ import { type RetryHint } from "../lib/errors.js";
6
7
  /**
7
8
  * Shared MCP tool adapter (W-22697673). Wraps an intent invocation so that any
8
9
  * throw becomes a sanitized, category-prefixed error envelope instead of leaking
@@ -20,6 +21,17 @@
20
21
  * untyped throws. The sanitized message is returned for EVERY category — not
21
22
  * just Internal — because typed Auth/Schema errors embed cache/lock paths and
22
23
  * wrapped jsforce/@salesforce/core causes embed `~/.sfdx/...` paths.
24
+ *
25
+ * Retryability hint (W-23148365): a `Schema:` error — and ONLY a `Schema:` error —
26
+ * additionally ends with a closed-set token telling the host whether to retry:
27
+ * ` [retry=now]` (retry immediately; no live org round-trip occurred — a priming-
28
+ * lock timeout, or a refresh where a usable cached schema survives), ` [retry=backoff]`
29
+ * (the introspection request failed transiently AND already exhausted the
30
+ * connection layer's one built-in retry — wait briefly), or NO token (permanent:
31
+ * 4xx, malformed/absent `__schema`, GraphQL errors in the body, no cached schema —
32
+ * don't retry; fix the request, re-auth, or re-prime). The `<Category>: ` prefix is
33
+ * unchanged. The disposition comes from the typed error's stamped `retry` field,
34
+ * with a defensive `cause`-chain fallback (`classifyCause`) for untyped throws.
23
35
  */
24
36
  export type ErrorCategory = "UserInput" | "Auth" | "Schema" | "Internal";
25
37
  interface ToolTextResult {
@@ -51,9 +63,13 @@ export declare const PATH_MARKERS: {
51
63
  * carries the `u` flag so they match (and escape) as a single code point.
52
64
  */
53
65
  export declare function neutralizeControlChars(s: string): string;
54
- /** Classify a thrown error into a category + sanitized message text. */
66
+ /**
67
+ * Classify a thrown error into a category, a Schema-only retry hint, and a
68
+ * sanitized message text. `retry` is `"no"` for every non-Schema category.
69
+ */
55
70
  export declare function classifyError(e: unknown): {
56
71
  category: ErrorCategory;
72
+ retry: RetryHint;
57
73
  text: string;
58
74
  };
59
75
  /**
@@ -4,7 +4,7 @@
4
4
  * For full license text, see the LICENSE.txt file
5
5
  */
6
6
  import os from "node:os";
7
- import { AuthError, SchemaError, UserInputError } from "../lib/errors.js";
7
+ import { AuthError, classifyCause, SchemaError, UserInputError, } from "../lib/errors.js";
8
8
  import { graphitiHome, schemaDir } from "../lib/introspect.js";
9
9
  import { SchemaRefreshError } from "../lib/prime-schema.js";
10
10
  import { MutationContextError } from "../lib/walker.js";
@@ -141,19 +141,38 @@ function categoryOf(e, message) {
141
141
  return "Schema";
142
142
  return "Internal";
143
143
  }
144
- /** Classify a thrown error into a category + sanitized message text. */
144
+ /**
145
+ * Retryability disposition for a Schema-category error (W-23148365). The typed
146
+ * SchemaError/SchemaRefreshError carry an authoritative `retry` stamped at the
147
+ * throw site; for an untyped throw that reached the Schema bucket via the
148
+ * SCHEMA_RE heuristic we fall back to inspecting its `cause`. Only ever called
149
+ * for the Schema category — Auth/UserInput/Internal are uniformly `"no"`.
150
+ */
151
+ function retryHintFor(e) {
152
+ if (e instanceof SchemaError || e instanceof SchemaRefreshError)
153
+ return e.retry;
154
+ if (typeof e === "object" && e !== null && "cause" in e) {
155
+ return classifyCause(e.cause);
156
+ }
157
+ return "no";
158
+ }
159
+ /**
160
+ * Classify a thrown error into a category, a Schema-only retry hint, and a
161
+ * sanitized message text. `retry` is `"no"` for every non-Schema category.
162
+ */
145
163
  export function classifyError(e) {
146
164
  const message = e instanceof Error ? e.message : String(e);
147
165
  const category = categoryOf(e, message);
166
+ const retry = category === "Schema" ? retryHintFor(e) : "no";
148
167
  const safeMessage = sanitizePaths(message);
149
168
  if (category !== "Internal")
150
- return { category, text: safeMessage };
169
+ return { category, retry, text: safeMessage };
151
170
  // Internal: unexpected. Attach a truncated, path-stripped stack for the host.
152
171
  const frames = truncatedStack(e);
153
172
  const text = frames.length
154
173
  ? `${safeMessage}\n${frames.map((f) => ` ${f}`).join("\n")}`
155
174
  : safeMessage;
156
- return { category, text };
175
+ return { category, retry, text };
157
176
  }
158
177
  /**
159
178
  * Run an MCP tool's intent invocation. Returns the success envelope
@@ -169,13 +188,17 @@ export async function runTool(fn) {
169
188
  return { content: [{ type: "text", text: stripLineSeparators(JSON.stringify(output)) }] };
170
189
  }
171
190
  catch (e) {
172
- const { category, text } = classifyError(e);
191
+ const { category, retry, text } = classifyError(e);
173
192
  if (category === "Internal") {
174
193
  console.error("[graphiti-mcp] Internal tool error:", e);
175
194
  }
195
+ // Append the retry hint as an end-anchored token (W-23148365). Only a
196
+ // Schema error ever carries a non-"no" hint; the `<Category>: ` prefix is
197
+ // unchanged so existing host parses (startsWith / split) still work.
198
+ const suffix = retry === "no" ? "" : ` [retry=${retry}]`;
176
199
  return {
177
200
  isError: true,
178
- content: [{ type: "text", text: stripLineSeparators(`${category}: ${text}`) }],
201
+ content: [{ type: "text", text: stripLineSeparators(`${category}: ${text}${suffix}`) }],
179
202
  };
180
203
  }
181
204
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-adapter.js","sourceRoot":"","sources":["../../src/schemas/tool-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-adapter.js","sourceRoot":"","sources":["../../src/schemas/tool-adapter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/graphiti",
3
- "version": "11.14.0",
3
+ "version": "11.16.0",
4
4
  "description": "Progressive GraphQL query builder CLI for Salesforce orgs",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "type": "module",
@@ -757,6 +757,30 @@ describe("intent/build-aggregate", () => {
757
757
  },
758
758
  );
759
759
 
760
+ // W-23204027: `aggregations[].field` was the second unguarded sink (the
761
+ // schema boundary types it as `z.string()` with no charset). It must be
762
+ // rejected at the builder layer like `alias`/`groupBy`, not just by the
763
+ // renderField fail-safe. `Amount } injectedAlias: Name { value` is the
764
+ // selection-set-breakout payload class from W-22735537.
765
+ it.each([
766
+ "Amount } injectedAlias: Name { value",
767
+ "}}__schema{types{name",
768
+ "1foo",
769
+ "foo bar",
770
+ ] as const)("aggregation field '%s' is rejected as not a valid GraphQL Name", async (field) => {
771
+ await expect(
772
+ buildAggregate(
773
+ {
774
+ org: ORG,
775
+ object: "Order",
776
+ groupBy: [],
777
+ aggregations: [{ function: "sum", field }],
778
+ },
779
+ noopPrimeDeps(),
780
+ ),
781
+ ).rejects.toThrow(/buildAggregate: field .* is not a valid GraphQL Name/);
782
+ });
783
+
760
784
  it("rejects an operationName that is not a valid GraphQL Name", async () => {
761
785
  await expect(
762
786
  buildAggregate(
@@ -6,13 +6,17 @@
6
6
 
7
7
  import { buildSchema } from "graphql";
8
8
  import { describe, expect, it } from "vitest";
9
- import { createSession, selectLeaf } from "../../lib/session.js";
9
+ import { createSession, type FieldProjectionNode, selectLeaf } from "../../lib/session.js";
10
10
  import { buildOutput } from "../build-output.js";
11
11
 
12
12
  const schema = buildSchema(`
13
13
  type Query { ping: String }
14
14
  `);
15
15
 
16
+ const argSchema = buildSchema(`
17
+ type Query { accounts(first: Int): String }
18
+ `);
19
+
16
20
  describe("intent/build-output", () => {
17
21
  it("renders query, no warnings on valid query", () => {
18
22
  const session = createSession("test", "query");
@@ -52,4 +56,23 @@ describe("intent/build-output", () => {
52
56
  expect(out.types).toMatch(/\/\/ Type generation failed:/);
53
57
  expect(out.warnings.some((w) => w.startsWith("Codegen:"))).toBe(true);
54
58
  });
59
+
60
+ // W-23204027 (PR #694 review): buildOutput's docstring no longer claims "Never
61
+ // throws". renderQuery runs OUTSIDE the try/catch and enforces the render-layer
62
+ // fail-safe, so a hostile identifier/arg-key that slipped past the per-builder
63
+ // guards throws instead of emitting an injectable name. This is caught and
64
+ // classified UserInput at the MCP boundary (runTool), but direct callers must
65
+ // be prepared for it — and it must NOT be swallowed into warnings[], which would
66
+ // let an injected selection reach the output. This test pins that contract.
67
+ it("propagates the render-layer fail-safe throw (does not swallow it into warnings)", () => {
68
+ const session = createSession("test", "query");
69
+ selectLeaf(session, ["accounts"]);
70
+ const node = session.nodes.find(
71
+ (n): n is FieldProjectionNode => n.kind === "field" && n.fieldName === "accounts",
72
+ )!;
73
+ // A raw, injectable argument key (as sf_gql_raw's `set <path> @args/<key>`
74
+ // could plant) — never a valid GraphQL Name.
75
+ node.args["first) { stolen } evil("] = "1";
76
+ expect(() => buildOutput(session, argSchema)).toThrow(/is not a valid GraphQL Name/);
77
+ });
55
78
  });
@@ -117,6 +117,12 @@ export async function buildAggregate(spec: AggregateSpec, deps?: PrimeDeps): Pro
117
117
  assertGraphqlName(agg.alias, "buildAggregate", "alias");
118
118
  }
119
119
  const field = agg.field ?? "Id";
120
+ // W-23204027: `aggregations[].field` is `z.string()` with no charset at the
121
+ // schema boundary, so guard it per-builder like `alias`/`groupBy field` —
122
+ // it flows raw into createSiblingFieldInstance → node.fieldName → rendered
123
+ // verbatim. The renderField fail-safe backstops this; this is the matching
124
+ // builder-layer defense-in-depth (parity with W-22735537).
125
+ assertGraphqlName(field, "buildAggregate", "field");
120
126
  const key = agg.alias ?? defaultKey(agg.function, field);
121
127
  if (seenKeys.has(key)) {
122
128
  throw new Error(
@@ -27,11 +27,25 @@ const OPTIONAL_DIRECTIVE_UNKNOWN_MARKER = 'Unknown directive "@optional"';
27
27
  * Render → validate → codegen → assemble. Shared finalizer for every typed
28
28
  * intent function (`buildList`, `buildDetail`, …).
29
29
  *
30
- * Never throws. Failure modes surface as entries in `warnings[]`:
30
+ * Validation and codegen never throw — their failure modes surface as entries in
31
+ * `warnings[]`:
31
32
  * - `Validation: <msg>` — non-schema-level errors from `graphql-js validate()`.
32
33
  * - `Validation: schema check skipped (<msg>)` — `validate()` itself crashed.
33
34
  * - `Codegen: <msg>` — `generateTypes()` threw; `types` becomes `// Type generation failed: <msg>`.
34
35
  *
36
+ * `renderQuery`, however, CAN throw — by design. It runs before (outside) the
37
+ * try/catch and enforces the W-23204027 render-layer fail-safe: if any emitted
38
+ * GraphQL Name (operation/variable/field name, alias, type condition, directive
39
+ * name) or argument key is not a valid GraphQL Name, it throws rather than emit
40
+ * an injectable identifier. This fires only on a programmer error or a hostile
41
+ * input that slipped past the per-builder guards (e.g. a `filter`/`orderBy` key —
42
+ * `z.record(z.unknown())` with no charset). At the MCP boundary `runTool`
43
+ * catches it and the message (`… is not a valid GraphQL Name`) is classified as
44
+ * `UserInput`, so failing loud is safe there. Direct callers (e.g. an eval
45
+ * harness) that bypass that boundary must be prepared for the throw. Do NOT move
46
+ * `renderQuery` into the try below — that would swallow the fail-safe and let an
47
+ * injected selection reach the output.
48
+ *
35
49
  * Schema-level errors (e.g. "Input Object type X must define one or more fields"
36
50
  * raised by malformed UIAPI schemas, not by the user's query) are filtered out
37
51
  * per FR-9.2.