sift-light 1.0.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 +0 -0
- package/CONTRIBUTING.md +19 -0
- package/LICENSE +661 -0
- package/README.md +177 -0
- package/README.zh-CN.md +177 -0
- package/SECURITY.md +25 -0
- package/package.json +142 -0
- package/plugins/sift-light/.claude-plugin/plugin.json +10 -0
- package/plugins/sift-light/.codex-plugin/plugin.json +20 -0
- package/plugins/sift-light/.mcp.json +24 -0
- package/plugins/sift-light/LICENSE +661 -0
- package/plugins/sift-light/concept-worker.mjs +567 -0
- package/plugins/sift-light/hooks/THIRD_PARTY_NOTICES.txt +70 -0
- package/plugins/sift-light/hooks/hooks.json +16 -0
- package/plugins/sift-light/hooks/search-policy.mjs +4113 -0
- package/plugins/sift-light/hooks/tree-sitter-bash.wasm +0 -0
- package/plugins/sift-light/hooks/tree-sitter-powershell.wasm +0 -0
- package/plugins/sift-light/hooks/tree-sitter.wasm +0 -0
- package/plugins/sift-light/kimi.plugin.json +36 -0
- package/plugins/sift-light/mcp-server.mjs +1 -0
- package/plugins/sift-light/omp-extension.mjs +20914 -0
- package/plugins/sift-light/package.json +11 -0
- package/plugins/sift-light/syntax-worker.mjs +280 -0
- package/plugins/sift-light/syntax-worker.toml +2 -0
- package/src/analysis-evidence.ts +43 -0
- package/src/analysis-limits.ts +27 -0
- package/src/analysis-store.ts +559 -0
- package/src/analysis-term-pages.ts +73 -0
- package/src/analysis-types.ts +162 -0
- package/src/audit-search.ts +391 -0
- package/src/capped-lines.ts +112 -0
- package/src/concept-embedding-cache.ts +186 -0
- package/src/concept-inference.ts +218 -0
- package/src/concept-model.ts +96 -0
- package/src/concept-search.ts +577 -0
- package/src/concept-setup.ts +75 -0
- package/src/concept-source-generation.ts +268 -0
- package/src/concept-worker.mjs +567 -0
- package/src/concept-worker.ts +210 -0
- package/src/config-reader.ts +283 -0
- package/src/config.ts +37 -0
- package/src/context-budget.ts +26 -0
- package/src/discovery-errors.ts +2 -0
- package/src/errors.ts +95 -0
- package/src/evidence-candidates.ts +344 -0
- package/src/evidence-ranking.ts +48 -0
- package/src/evidence-service.ts +1047 -0
- package/src/evidence-validation.ts +466 -0
- package/src/evidence-validity.ts +33 -0
- package/src/excerpt.ts +53 -0
- package/src/file-discovery.ts +150 -0
- package/src/file-metadata-filter.ts +46 -0
- package/src/format.ts +407 -0
- package/src/git-diff.ts +195 -0
- package/src/git-process.ts +189 -0
- package/src/git-repository.ts +367 -0
- package/src/git-source.ts +385 -0
- package/src/historical-paths.ts +205 -0
- package/src/hybrid-search.ts +340 -0
- package/src/import-model.ts +611 -0
- package/src/import-navigation.ts +100 -0
- package/src/import-resolution.ts +240 -0
- package/src/index.ts +97 -0
- package/src/inspect-batch.ts +265 -0
- package/src/inspect.ts +271 -0
- package/src/language-capabilities.ts +157 -0
- package/src/language-capability-definitions.ts +204 -0
- package/src/literal-search.ts +25 -0
- package/src/mcp-cli.ts +21 -0
- package/src/mcp-model-output.ts +120 -0
- package/src/mcp-output.ts +9 -0
- package/src/mcp-semantic-judge.ts +39 -0
- package/src/mcp-server.mjs +14064 -0
- package/src/mcp-server.ts +157 -0
- package/src/mcp-stdio.ts +114 -0
- package/src/mcp.ts +631 -0
- package/src/model-error.ts +120 -0
- package/src/multi-term-search.ts +122 -0
- package/src/omp-index.ts +277 -0
- package/src/omp-marketplace-entry.ts +7 -0
- package/src/operation-lifecycle.ts +413 -0
- package/src/operation-output.ts +100 -0
- package/src/owned-parallel.ts +22 -0
- package/src/owned-process.ts +102 -0
- package/src/owned-task-queue.ts +38 -0
- package/src/package-version.ts +3 -0
- package/src/path-policy.ts +203 -0
- package/src/pi-search-policy.ts +33 -0
- package/src/prompt-guidelines.ts +54 -0
- package/src/python-outline.ts +231 -0
- package/src/record-value.ts +3 -0
- package/src/redaction.ts +95 -0
- package/src/request-contract-catalog.ts +215 -0
- package/src/request-contract-error.ts +96 -0
- package/src/request-contract.ts +481 -0
- package/src/request.ts +132 -0
- package/src/result-statistics.ts +178 -0
- package/src/rg.ts +574 -0
- package/src/ripgrep-diagnostics.ts +122 -0
- package/src/ripgrep-executable.ts +43 -0
- package/src/runtime.ts +53 -0
- package/src/scan-revisions.ts +148 -0
- package/src/script-runtime.ts +11 -0
- package/src/search-policy-commands.ts +170 -0
- package/src/search-policy-hook.ts +61 -0
- package/src/search-policy-recovery.ts +388 -0
- package/src/search-policy-shell.ts +280 -0
- package/src/search-policy.ts +102 -0
- package/src/search-retention.ts +77 -0
- package/src/semantic-judge-batches.ts +135 -0
- package/src/semantic-judge.ts +519 -0
- package/src/service.ts +945 -0
- package/src/session-summary.ts +100 -0
- package/src/snapshot-store.ts +203 -0
- package/src/source-access.ts +288 -0
- package/src/source-continuations.ts +168 -0
- package/src/source-document.ts +277 -0
- package/src/source-inspection.ts +731 -0
- package/src/source-pages.ts +112 -0
- package/src/source.ts +286 -0
- package/src/structural-search.ts +125 -0
- package/src/structure.ts +259 -0
- package/src/summary-previews.ts +96 -0
- package/src/summary.ts +79 -0
- package/src/syntax-facts.ts +464 -0
- package/src/syntax-fields.ts +161 -0
- package/src/syntax-search.ts +361 -0
- package/src/syntax-tree.ts +30 -0
- package/src/syntax-types.ts +72 -0
- package/src/syntax-worker.mjs +280 -0
- package/src/syntax-worker.toml +2 -0
- package/src/syntax-worker.ts +143 -0
- package/src/syntax.ts +259 -0
- package/src/test-navigation-facts.ts +261 -0
- package/src/test-navigation.ts +543 -0
- package/src/tool-schema.ts +321 -0
- package/src/tui/dashboard.ts +107 -0
- package/src/tui/layout.ts +291 -0
- package/src/tui/palette.ts +73 -0
- package/src/tui/presentation.ts +240 -0
- package/src/tui/renderers.ts +106 -0
- package/src/types.ts +368 -0
- package/src/validation-output.ts +148 -0
- package/src/validation-types.ts +48 -0
- package/src/workspace-files.ts +142 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { MAX_PAGE_SIZE } from "./types.js";
|
|
2
|
+
import type { SiftLightInput } from "./service.js";
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_LANGUAGE_CAPABILITIES,
|
|
5
|
+
outlineExtension as languageOutlineExtension,
|
|
6
|
+
} from "./language-capability-definitions.js";
|
|
7
|
+
|
|
8
|
+
export const SIFT_LIGHT_MODES = [
|
|
9
|
+
"audit",
|
|
10
|
+
"auto",
|
|
11
|
+
"summary",
|
|
12
|
+
"matches",
|
|
13
|
+
"inspect",
|
|
14
|
+
"outline",
|
|
15
|
+
"imports",
|
|
16
|
+
"tests",
|
|
17
|
+
"files",
|
|
18
|
+
"structure",
|
|
19
|
+
"concept",
|
|
20
|
+
"hybrid",
|
|
21
|
+
"validate",
|
|
22
|
+
"capabilities",
|
|
23
|
+
"await",
|
|
24
|
+
"cancel",
|
|
25
|
+
] as const;
|
|
26
|
+
|
|
27
|
+
export type SiftLightMode = (typeof SIFT_LIGHT_MODES)[number];
|
|
28
|
+
export type RequestField = keyof SiftLightInput;
|
|
29
|
+
|
|
30
|
+
const commonFields = ["mode", "redact"] as const satisfies readonly RequestField[];
|
|
31
|
+
const sourceFilters = [
|
|
32
|
+
"path",
|
|
33
|
+
"glob",
|
|
34
|
+
"exclude",
|
|
35
|
+
"hidden",
|
|
36
|
+
] as const satisfies readonly RequestField[];
|
|
37
|
+
const ordinaryFields = [
|
|
38
|
+
...commonFields,
|
|
39
|
+
"pattern",
|
|
40
|
+
...sourceFilters,
|
|
41
|
+
"ignorePolicy",
|
|
42
|
+
"literal",
|
|
43
|
+
"ignoreCase",
|
|
44
|
+
"context",
|
|
45
|
+
"limit",
|
|
46
|
+
"scope",
|
|
47
|
+
"wholeWord",
|
|
48
|
+
"modifiedAfter",
|
|
49
|
+
"modifiedBefore",
|
|
50
|
+
"anyOf",
|
|
51
|
+
"allOf",
|
|
52
|
+
"within",
|
|
53
|
+
"roles",
|
|
54
|
+
"changes",
|
|
55
|
+
"maxFilesToParse",
|
|
56
|
+
"cursor",
|
|
57
|
+
"matchIndex",
|
|
58
|
+
] as const satisfies readonly RequestField[];
|
|
59
|
+
|
|
60
|
+
export const MODE_FIELDS_BY_MODE: Record<SiftLightMode, readonly RequestField[]> = {
|
|
61
|
+
audit: [...commonFields, "patterns", ...sourceFilters, "ignorePolicy"],
|
|
62
|
+
auto: ordinaryFields,
|
|
63
|
+
summary: ordinaryFields,
|
|
64
|
+
matches: ordinaryFields,
|
|
65
|
+
inspect: [...commonFields, "path", "line", "cursor", "matchIndex", "matchIndices", "targets"],
|
|
66
|
+
outline: [...commonFields, "path", "line", "symbol", "cursor", "matchIndex", "maxFilesToParse"],
|
|
67
|
+
imports: [
|
|
68
|
+
...commonFields,
|
|
69
|
+
...sourceFilters,
|
|
70
|
+
"line",
|
|
71
|
+
"symbol",
|
|
72
|
+
"cursor",
|
|
73
|
+
"matchIndex",
|
|
74
|
+
"maxFilesToParse",
|
|
75
|
+
],
|
|
76
|
+
tests: [
|
|
77
|
+
...commonFields,
|
|
78
|
+
...sourceFilters,
|
|
79
|
+
"line",
|
|
80
|
+
"symbol",
|
|
81
|
+
"cursor",
|
|
82
|
+
"matchIndex",
|
|
83
|
+
"maxFilesToParse",
|
|
84
|
+
],
|
|
85
|
+
files: [...commonFields, "query", ...sourceFilters, "modifiedAfter", "modifiedBefore"],
|
|
86
|
+
structure: [...commonFields, "pattern", ...sourceFilters, "maxFilesToParse"],
|
|
87
|
+
concept: [...commonFields, "query", ...sourceFilters, "maxFilesToParse"],
|
|
88
|
+
hybrid: [...commonFields, "query", ...sourceFilters, "conceptLimit", "maxFilesToParse"],
|
|
89
|
+
validate: [...commonFields, "cursor", "matchIndex"],
|
|
90
|
+
capabilities: [...commonFields, ...sourceFilters],
|
|
91
|
+
await: ["mode", "operationId"],
|
|
92
|
+
cancel: ["mode", "operationId"],
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const SAFE_DROP_FIELDS: Partial<Record<SiftLightMode, readonly RequestField[]>> = {
|
|
96
|
+
files: ["scope"],
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const SUPPORTED_OUTLINE_EXTENSIONS = new Set(
|
|
100
|
+
DEFAULT_LANGUAGE_CAPABILITIES.flatMap((descriptor) =>
|
|
101
|
+
descriptor.capabilities.some((capability) => capability.name === "outline")
|
|
102
|
+
? descriptor.extensions
|
|
103
|
+
: [],
|
|
104
|
+
),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
export function modeFields(mode: SiftLightMode): readonly RequestField[] {
|
|
108
|
+
return MODE_FIELDS_BY_MODE[mode];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Prose field list for one mode. It deliberately avoids `name={a,b,c}`, whose
|
|
113
|
+
* shape mimics the call syntax a host would accept and can be copied into the
|
|
114
|
+
* arguments as a nonexistent nested field.
|
|
115
|
+
*/
|
|
116
|
+
export function modeFieldSummary(mode: SiftLightMode): string {
|
|
117
|
+
return `${mode}: ${modeFields(mode).join(",")}`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Compact schema-facing summary derived from the runtime field catalog. */
|
|
121
|
+
const MODE_SUMMARY_MODES = [
|
|
122
|
+
"audit",
|
|
123
|
+
"files",
|
|
124
|
+
"concept",
|
|
125
|
+
"hybrid",
|
|
126
|
+
"inspect",
|
|
127
|
+
"outline",
|
|
128
|
+
"capabilities",
|
|
129
|
+
"await",
|
|
130
|
+
"cancel",
|
|
131
|
+
] as const satisfies readonly SiftLightMode[];
|
|
132
|
+
|
|
133
|
+
export const MODE_FIELD_SUMMARY = MODE_SUMMARY_MODES.map((mode) => modeFieldSummary(mode)).join(
|
|
134
|
+
"; ",
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
/** Short field semantics shared by tools/list and the model-facing guidance. */
|
|
138
|
+
export const REQUEST_FIELD_GUIDANCE: Partial<Record<RequestField, string>> = {
|
|
139
|
+
pattern: "pattern is regex by default; literal=true matches source text exactly",
|
|
140
|
+
literal:
|
|
141
|
+
"literal=true makes pattern exact source text; anyOf/allOf already use literal semantics",
|
|
142
|
+
path: "path must be an existing exact file or root; use mode=files+query for unknown names",
|
|
143
|
+
query:
|
|
144
|
+
"files+query matches known filename/path text (not glob patterns); omit files query to list every file under path; concept/hybrid query is natural language",
|
|
145
|
+
anyOf:
|
|
146
|
+
"anyOf is case-sensitive exact-literal OR; omit pattern, allOf, literal, ignoreCase, roles",
|
|
147
|
+
allOf:
|
|
148
|
+
"allOf is case-sensitive exact-literal AND; omit pattern, anyOf, literal, ignoreCase, roles",
|
|
149
|
+
context: "context is an output-context budget and is never silently dropped",
|
|
150
|
+
limit: "limit is an output/page budget and is never silently dropped",
|
|
151
|
+
scope:
|
|
152
|
+
"scope applies to ordinary content search; mode=files rejects this field because its scope is fixed strict, and only redundant strict may be removed",
|
|
153
|
+
ignorePolicy:
|
|
154
|
+
"respect keeps repository ignore rules; include searches ignored files but always excludes .git internals and protected paths",
|
|
155
|
+
patterns: "audit accepts named exact-literal patterns and returns one closure receipt",
|
|
156
|
+
maxFilesToParse:
|
|
157
|
+
"concept/hybrid automatically batch the requested scope; this optional field sets an advanced hard file ceiling",
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export function fieldGuidance(field: RequestField): string {
|
|
161
|
+
return REQUEST_FIELD_GUIDANCE[field] ?? `${field} is accepted only by its cataloged modes`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const GUIDANCE_FIELDS = [
|
|
165
|
+
"pattern",
|
|
166
|
+
"literal",
|
|
167
|
+
"path",
|
|
168
|
+
"query",
|
|
169
|
+
"anyOf",
|
|
170
|
+
"allOf",
|
|
171
|
+
"context",
|
|
172
|
+
"limit",
|
|
173
|
+
"scope",
|
|
174
|
+
] as const satisfies readonly RequestField[];
|
|
175
|
+
|
|
176
|
+
const SEARCH_GUIDANCE_FIELDS = ["pattern", "literal", "path", "query"] as const;
|
|
177
|
+
const VARIANT_GUIDANCE_FIELDS = ["anyOf", "allOf"] as const;
|
|
178
|
+
const BUDGET_GUIDANCE_FIELDS = ["limit", "context"] as const;
|
|
179
|
+
|
|
180
|
+
export const REQUEST_USAGE_GUIDANCE = [
|
|
181
|
+
// Each guidance sentence already names its field, so prefixing it again
|
|
182
|
+
// produced `pattern=pattern is regex…` and `literal=literal=true makes…`.
|
|
183
|
+
`search: ${SEARCH_GUIDANCE_FIELDS.map((field) => fieldGuidance(field)).join("; ")}`,
|
|
184
|
+
`variants: ${VARIANT_GUIDANCE_FIELDS.map((field) => fieldGuidance(field)).join("; ")}`,
|
|
185
|
+
`budgets: ${BUDGET_GUIDANCE_FIELDS.map((field) => fieldGuidance(field)).join("; ")}`,
|
|
186
|
+
`selectors: ${modeFieldSummary("inspect")}; ${modeFieldSummary("hybrid")}; ${modeFieldSummary("files")}; ${modeFieldSummary("capabilities")}`,
|
|
187
|
+
"use only the advertised names: exact, any-of and max_results are not parameters",
|
|
188
|
+
].join("; ");
|
|
189
|
+
|
|
190
|
+
export const MODEL_USAGE_GUIDANCE = [
|
|
191
|
+
"pattern is regex by default; literal=true matches source text exactly",
|
|
192
|
+
"path is an existing exact file or root; use files+query for an unknown name",
|
|
193
|
+
"anyOf/allOf are exact-literal OR/AND variants and exclude pattern/literal",
|
|
194
|
+
`limit/context are ordinary-search output budgets; limit <= ${String(MAX_PAGE_SIZE)}; omit both for hybrid/concept/outline/structure/inspect`,
|
|
195
|
+
"outline requires a concrete source file, not a directory; structure requires a nonempty AST pattern and JS/TS/TSX/Go sources, no lang field; use capabilities before unfamiliar language operations",
|
|
196
|
+
"outline supports JS/TS/TSX and bounded Python syntax; imports/tests are static candidates for JS/TS/TSX",
|
|
197
|
+
`selectors: ${modeFieldSummary("inspect")}; ${modeFieldSummary("hybrid")}; ${modeFieldSummary("capabilities")}`,
|
|
198
|
+
"exact, any-of and max_results are not parameters",
|
|
199
|
+
].join("; ");
|
|
200
|
+
|
|
201
|
+
/** A single concise capability statement shared by schema and model-facing descriptions. */
|
|
202
|
+
export const MODE_CONTRACT_DESCRIPTION = [
|
|
203
|
+
`fields: ${MODE_FIELD_SUMMARY}`,
|
|
204
|
+
`rules: ${GUIDANCE_FIELDS.map((field) => `${field} — ${fieldGuidance(field)}`).join("; ")}`,
|
|
205
|
+
"inspect uses cursor+matchIndex or explicit targets; imports/tests report static syntax candidates",
|
|
206
|
+
"capabilities performs a bounded names-only project inventory and reports per-language modes with lazy loading; it does not start a parser, compiler, model or language server",
|
|
207
|
+
"outline follows declared syntax capabilities; unavailable languages appear in capabilities",
|
|
208
|
+
"there are no exact, any-of or max_results fields; use literal, anyOf or limit",
|
|
209
|
+
"context 0–20 is never clamped",
|
|
210
|
+
].join("; ");
|
|
211
|
+
|
|
212
|
+
export function outlineExtension(path: unknown): string | undefined {
|
|
213
|
+
if (typeof path !== "string") return undefined;
|
|
214
|
+
return languageOutlineExtension(path);
|
|
215
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SiftLightError,
|
|
3
|
+
type SiftLightDiagnosticDetails,
|
|
4
|
+
type SiftLightDiagnosticIssue,
|
|
5
|
+
type SiftLightDiagnosticRecovery,
|
|
6
|
+
type SiftLightRecoveryAction,
|
|
7
|
+
} from "./errors.js";
|
|
8
|
+
|
|
9
|
+
/** One bounded protocol budget shared by the typed error and its projections. */
|
|
10
|
+
export const MAX_REQUEST_RECOVERY_BYTES = 64 * 1024;
|
|
11
|
+
const MAX_REQUEST_DISPLAY_CHARACTERS = 256;
|
|
12
|
+
|
|
13
|
+
export function boundedDisplay(value: string, maximum = MAX_REQUEST_DISPLAY_CHARACTERS): string {
|
|
14
|
+
const normalized = value.toWellFormed();
|
|
15
|
+
return normalized.length <= maximum ? normalized : `${normalized.slice(0, maximum - 1)}…`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type RequestIssue = SiftLightDiagnosticIssue;
|
|
19
|
+
export type RequestRecoveryAction = SiftLightRecoveryAction;
|
|
20
|
+
export type RequestRecovery = SiftLightDiagnosticRecovery;
|
|
21
|
+
export type RequestContractDetails = SiftLightDiagnosticDetails;
|
|
22
|
+
|
|
23
|
+
/** A typed boundary error; callers can project it without parsing message text. */
|
|
24
|
+
export class RequestContractError extends SiftLightError {
|
|
25
|
+
readonly #details: RequestContractDetails;
|
|
26
|
+
|
|
27
|
+
constructor(details: RequestContractDetails, message: string) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "RequestContractError";
|
|
30
|
+
this.#details = details;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get code(): string {
|
|
34
|
+
return this.#details.code;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get mode(): string | undefined {
|
|
38
|
+
return this.#details.mode;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get issues(): readonly RequestIssue[] {
|
|
42
|
+
return this.#details.issues;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get recovery(): RequestRecovery {
|
|
46
|
+
return this.#details.recovery;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get details(): RequestContractDetails {
|
|
50
|
+
return boundedRequestContractDetails(this.#details);
|
|
51
|
+
}
|
|
52
|
+
toJSON(): RequestContractDetails & { name: string } {
|
|
53
|
+
return { name: this.name, ...this.details };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function isSiftLightDiagnosticError(
|
|
58
|
+
error: unknown,
|
|
59
|
+
): error is import("./errors.js").SiftLightDiagnosticError {
|
|
60
|
+
if (!(error instanceof Error)) return false;
|
|
61
|
+
const details = "details" in error ? error.details : undefined;
|
|
62
|
+
return typeof details === "object" && details !== null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Bound every machine-readable projection before it reaches a host. If an
|
|
67
|
+
* exact request or diagnostic cannot fit, omit recovery instead of emitting a
|
|
68
|
+
* truncated JSON object that appears copyable.
|
|
69
|
+
*/
|
|
70
|
+
export function boundedRequestContractDetails(
|
|
71
|
+
details: RequestContractDetails,
|
|
72
|
+
): RequestContractDetails {
|
|
73
|
+
let serialized: string | undefined;
|
|
74
|
+
try {
|
|
75
|
+
serialized = JSON.stringify(details);
|
|
76
|
+
} catch {
|
|
77
|
+
serialized = undefined;
|
|
78
|
+
}
|
|
79
|
+
if (serialized !== undefined && Buffer.byteLength(serialized) <= MAX_REQUEST_RECOVERY_BYTES)
|
|
80
|
+
return details;
|
|
81
|
+
return {
|
|
82
|
+
code: boundedDisplay(details.code, 128),
|
|
83
|
+
...(details.mode ? { mode: boundedDisplay(details.mode, 128) } : {}),
|
|
84
|
+
issues: [
|
|
85
|
+
{
|
|
86
|
+
field: "<payload>",
|
|
87
|
+
reason: "The request-contract diagnostic exceeded the bounded payload budget.",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
recovery: {
|
|
91
|
+
action: "manual",
|
|
92
|
+
reason:
|
|
93
|
+
"Exact recovery was omitted because the request-contract payload exceeded its bounded budget; preserve valid selectors and filters and correct the request explicitly.",
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|