@ai-matrx/chat 0.4.10 → 0.4.12
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 +36 -0
- package/dist/agents/components/context-items/bodies/ContextInputBody.js +1 -1
- package/dist/agents/components/context-items/bodies/GenericBody.js +1 -1
- package/dist/agents/components/conversation-actions/conversation-verbs.js +1 -1
- package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
- package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
- package/dist/agents/components/live-run/LiveRunProgress.js +1 -1
- package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
- package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +2 -2
- package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +1 -1
- package/dist/agents/components/messages-display/conversation-tools/find-in-conversation.js +1 -1
- package/dist/agents/components/messages-display/message-options/buildTaskSeedFromMessage.js +1 -1
- package/dist/agents/components/messages-display/user/AgentUserMessage.js +1 -1
- package/dist/agents/components/messages-display/user/FirstTurnVariables.js +1 -1
- package/dist/agents/components/run/AgentStatusIndicator.js +1 -1
- package/dist/agents/components/run/RunJobWorkingLine.js +1 -1
- package/dist/agents/components/shared/AgentNewRunButton.js +1 -1
- package/dist/agents/components/shared/AgentPlanningIndicator.js +1 -1
- package/dist/agents/conversation-export/conversation-transfer.js +1 -1
- package/dist/agents/conversation-export/document-markdown.js +1 -1
- package/dist/agents/hooks/useConversationRoutePromotion.js +1 -1
- package/dist/agents/hooks/useModelControls.js +1 -1
- package/dist/agents/redux/agent-definition/converters.js +1 -1
- package/dist/agents/redux/agent-definition/slice.js +1 -1
- package/dist/agents/redux/conversation-list/conversation-list.thunks.js +1 -1
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +1 -1
- package/dist/agents/redux/execution-system/instance-context/sync-canvas-item-context.thunk.js +1 -1
- package/dist/agents/redux/execution-system/thunks/process-stream.js +1 -1
- package/dist/agents/redux/execution-system/thunks/run-ai-stream.d.ts +7 -0
- package/dist/agents/redux/execution-system/thunks/run-ai-stream.js +13 -0
- package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/output-contract-guard.js +1 -1
- package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +8 -8
- package/dist/agents/utils/canvasItemContext.js +1 -1
- package/dist/canvas/workspace/ChatPanelTitleMenu.js +1 -1
- package/dist/canvas/workspace/useCanvasWorkspaceConversation.js +1 -1
- package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
- package/dist/cx-chat/components/core/ChatConversationClient.js +1 -1
- package/dist/cx-chat/components/messages/AssistantMessage.js +1 -1
- package/dist/cx-chat/hooks/useInstanceBootstrap.js +1 -1
- package/dist/cx-conversation/AssistantMessage.js +1 -1
- package/dist/mandates/llm-params.d.ts +1 -1
- package/dist/mandates/output-contract.js +1 -1
- package/dist/mandates/service.d.ts +1 -1
- package/dist/mandates/service.js +1 -1
- package/dist/mandates/test-run-core.js +1 -1
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
- package/dist/surfaces/services/surface-config.service.js +1 -1
- package/dist/tool-call-visualization/components/ToolCallBatch.js +1 -1
- package/dist/tool-call-visualization/components/ToolCallVisualization.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/collab-subtitle.js +3 -3
- package/dist/tool-call-visualization/renderers/skill/SkillInline.js +1 -1
- package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
- package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
- package/dist/tool-call-visualization/result-fields/shape.js +1 -1
- package/dist/tool-call-visualization/utils/cxToolCallToLifecycleEntry.js +2 -2
- package/dist/tool-call-visualization/utils/human-copy.js +3 -3
- package/dist/ui/mandates-storage/provision-shapes.d.ts +1 -1
- package/dist/ui/mandates-storage/provision-shapes.js +1 -1
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1 -1
- package/dist/ui/treatment-shape.d.ts +1 -1
- package/dist/ui/treatment-shape.js +1 -1
- package/dist/voice-agent/relay/useVoiceRelaySession.js +1 -1
- package/package.json +23 -6
- package/dist/agents/hooks/useWarmAgent.d.ts +0 -8
- package/dist/agents/hooks/useWarmAgent.js +0 -25
- package/dist/agents/utils/artifactId.d.ts +0 -34
- package/dist/agents/utils/artifactId.js +0 -15
- package/dist/ui/ShimmerText.d.ts +0 -5
- package/dist/ui/ShimmerText.js +0 -21
- package/dist/ui/addressWithoutNavigating.d.ts +0 -68
- package/dist/ui/addressWithoutNavigating.js +0 -60
- package/dist/utils/content-ir/decision-answers-ids.d.ts +0 -3
- package/dist/utils/content-ir/decision-answers-ids.js +0 -6
- package/dist/utils/content-ir/envelope-parity.d.ts +0 -12
- package/dist/utils/content-ir/envelope-parity.js +0 -32
- package/dist/utils/content-ir/instance-title.d.ts +0 -26
- package/dist/utils/content-ir/instance-title.js +0 -39
- package/dist/utils/content-ir/kinds/kind-markdown-utils.d.ts +0 -84
- package/dist/utils/content-ir/kinds/kind-markdown-utils.js +0 -233
- package/dist/utils/content-ir/kinds/kind-value-markdown.d.ts +0 -5
- package/dist/utils/content-ir/kinds/kind-value-markdown.js +0 -17
- package/dist/utils/content-ir/legacy-quiz-envelope.d.ts +0 -3
- package/dist/utils/content-ir/legacy-quiz-envelope.js +0 -45
- package/dist/utils/content-ir/surfaces/embedded-kind-json.d.ts +0 -140
- package/dist/utils/content-ir/surfaces/embedded-kind-json.js +0 -527
- package/dist/utils/content-ir/surfaces/json-kind-signal.d.ts +0 -307
- package/dist/utils/content-ir/surfaces/json-kind-signal.js +0 -945
- package/dist/utils/content-ir/surfaces/kind-image-alt.d.ts +0 -27
- package/dist/utils/content-ir/surfaces/kind-image-alt.js +0 -117
- package/dist/utils/content-ir/surfaces/kind-one-line.d.ts +0 -67
- package/dist/utils/content-ir/surfaces/kind-one-line.js +0 -209
- package/dist/utils/content-ir/surfaces/kind-text-label.d.ts +0 -20
- package/dist/utils/content-ir/surfaces/kind-text-label.js +0 -50
- package/dist/utils/content-ir/surfaces/kind-text-to-markdown.d.ts +0 -47
- package/dist/utils/content-ir/surfaces/kind-text-to-markdown.js +0 -399
- package/dist/utils/content-ir/surfaces/markdown-escaped-kind.d.ts +0 -54
- package/dist/utils/content-ir/surfaces/markdown-escaped-kind.js +0 -128
- package/dist/utils/content-ir/surfaces/quoted-kind-lift.d.ts +0 -61
- package/dist/utils/content-ir/surfaces/quoted-kind-lift.js +0 -215
- package/dist/utils/inline-decision/decision-options.d.ts +0 -21
- package/dist/utils/inline-decision/decision-options.js +0 -32
- package/dist/utils/json.d.ts +0 -63
- package/dist/utils/json.js +0 -22
- package/dist/utils/markdown/plain-title.d.ts +0 -25
- package/dist/utils/markdown/plain-title.js +0 -51
- package/dist/utils/rendered-find.d.ts +0 -9
- package/dist/utils/rendered-find.js +0 -68
- package/dist/utils/rich-editor/core/caret-context.d.ts +0 -24
- package/dist/utils/rich-editor/core/caret-context.js +0 -73
- package/dist/utils/rich-editor/in-place/caret-handoff.d.ts +0 -3
- package/dist/utils/rich-editor/in-place/caret-handoff.js +0 -15
|
@@ -1,527 +0,0 @@
|
|
|
1
|
-
import { readXmlTag } from "../../xml/readXmlTag.js";
|
|
2
|
-
import { fenceOpenerOf, findCodeRanges } from "@ai-matrx/content-ir/source";
|
|
3
|
-
import { frontMatterEnd, isJsonFenceLanguage, kindGrammar, quotedSourceRanges } from "./json-kind-signal.js";
|
|
4
|
-
function matchingJsonObjectEnd(source, start) {
|
|
5
|
-
if (source[start] !== "{" && source[start] !== "[") return null;
|
|
6
|
-
const stack = [source[start]];
|
|
7
|
-
let inString = false;
|
|
8
|
-
let escaped = false;
|
|
9
|
-
for (let index = start + 1; index < source.length; index++) {
|
|
10
|
-
const char = source[index];
|
|
11
|
-
if (inString) {
|
|
12
|
-
if (escaped) {
|
|
13
|
-
escaped = false;
|
|
14
|
-
} else if (char === "\\") {
|
|
15
|
-
escaped = true;
|
|
16
|
-
} else if (char === '"') {
|
|
17
|
-
inString = false;
|
|
18
|
-
}
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
if (char === '"') {
|
|
22
|
-
inString = true;
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (char === "{" || char === "[") {
|
|
26
|
-
stack.push(char);
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (char !== "}" && char !== "]") continue;
|
|
30
|
-
const opening = stack.pop();
|
|
31
|
-
if (char === "}" && opening !== "{" || char === "]" && opening !== "[") {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
if (stack.length === 0) return index + 1;
|
|
35
|
-
}
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
function balancedEnds(text) {
|
|
39
|
-
const ends = new Int32Array(text.length).fill(-1);
|
|
40
|
-
const stack = [];
|
|
41
|
-
for (let start = text.length - 1; start >= 0; start--) {
|
|
42
|
-
const open = text[start];
|
|
43
|
-
if (open !== "{" && open !== "[") continue;
|
|
44
|
-
stack.length = 0;
|
|
45
|
-
stack.push(open === "{" ? "}" : "]");
|
|
46
|
-
let inString = false;
|
|
47
|
-
for (let i = start + 1; i < text.length; i++) {
|
|
48
|
-
const ch = text[i];
|
|
49
|
-
if (inString) {
|
|
50
|
-
if (ch === "\\") i++;
|
|
51
|
-
else if (ch === '"') inString = false;
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
if (ch === '"') inString = true;
|
|
55
|
-
else if (ch === "{" || ch === "[") {
|
|
56
|
-
const end = ends[i];
|
|
57
|
-
if (end < 0) break;
|
|
58
|
-
i = end - 1;
|
|
59
|
-
} else if (ch === "}" || ch === "]") {
|
|
60
|
-
if (stack.pop() !== ch) break;
|
|
61
|
-
ends[start] = i + 1;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return ends;
|
|
67
|
-
}
|
|
68
|
-
function lazyJsonEnds(source) {
|
|
69
|
-
let table;
|
|
70
|
-
return (start) => {
|
|
71
|
-
if (source[start] !== "{" && source[start] !== "[") return null;
|
|
72
|
-
table ??= balancedEnds(source);
|
|
73
|
-
const end = table[start];
|
|
74
|
-
return end < 0 ? null : end;
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
function skipWhitespace(source, cursor) {
|
|
78
|
-
while (/\s/.test(source[cursor] ?? "")) cursor++;
|
|
79
|
-
return cursor;
|
|
80
|
-
}
|
|
81
|
-
function jsonStringEnd(source, start) {
|
|
82
|
-
if (source[start] !== '"') return null;
|
|
83
|
-
let escaped = false;
|
|
84
|
-
for (let cursor = start + 1; cursor < source.length; cursor++) {
|
|
85
|
-
const char = source[cursor];
|
|
86
|
-
if (escaped) {
|
|
87
|
-
escaped = false;
|
|
88
|
-
} else if (char === "\\") {
|
|
89
|
-
escaped = true;
|
|
90
|
-
} else if (char === '"') {
|
|
91
|
-
return cursor + 1;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
function jsonValueEnd(source, start) {
|
|
97
|
-
const char = source[start];
|
|
98
|
-
if (char === '"') return jsonStringEnd(source, start);
|
|
99
|
-
if (char === "{" || char === "[") return matchingJsonObjectEnd(source, start);
|
|
100
|
-
const end = source.slice(start).search(/[\s,}\]]/);
|
|
101
|
-
const tokenEnd = end === -1 ? source.length : start + end;
|
|
102
|
-
const token = source.slice(start, tokenEnd);
|
|
103
|
-
return /^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)$/.test(
|
|
104
|
-
token
|
|
105
|
-
) ? tokenEnd : null;
|
|
106
|
-
}
|
|
107
|
-
function malformedKindOwnerEnd(source, start, boundary = source.length) {
|
|
108
|
-
let cursor = skipWhitespace(source, start + 1);
|
|
109
|
-
let kindFound = false;
|
|
110
|
-
const ownerEnd = () => kindFound ? boundary : null;
|
|
111
|
-
while (cursor < boundary) {
|
|
112
|
-
const keyStart = cursor;
|
|
113
|
-
const keyEnd = jsonStringEnd(source, keyStart);
|
|
114
|
-
if (keyEnd === null || keyEnd > boundary) return ownerEnd();
|
|
115
|
-
let key;
|
|
116
|
-
try {
|
|
117
|
-
key = JSON.parse(source.slice(keyStart, keyEnd));
|
|
118
|
-
} catch {
|
|
119
|
-
return ownerEnd();
|
|
120
|
-
}
|
|
121
|
-
cursor = skipWhitespace(source, keyEnd);
|
|
122
|
-
if (cursor >= boundary || source[cursor] !== ":") return ownerEnd();
|
|
123
|
-
cursor = skipWhitespace(source, cursor + 1);
|
|
124
|
-
const valueStart = cursor;
|
|
125
|
-
const valueEnd = jsonValueEnd(source, valueStart);
|
|
126
|
-
if (valueEnd === null || valueEnd > boundary) return ownerEnd();
|
|
127
|
-
if (key === "__kind") {
|
|
128
|
-
try {
|
|
129
|
-
const value = JSON.parse(source.slice(valueStart, valueEnd));
|
|
130
|
-
kindFound ||= typeof value === "string" && value.trim().length > 0;
|
|
131
|
-
} catch {
|
|
132
|
-
return ownerEnd();
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
cursor = skipWhitespace(source, valueEnd);
|
|
136
|
-
if (source[cursor] === "}") return kindFound ? cursor + 1 : null;
|
|
137
|
-
if (cursor >= boundary || source[cursor] !== ",") return ownerEnd();
|
|
138
|
-
cursor = skipWhitespace(source, cursor + 1);
|
|
139
|
-
}
|
|
140
|
-
return ownerEnd();
|
|
141
|
-
}
|
|
142
|
-
function jsonStringRanges(source, start, end) {
|
|
143
|
-
const ranges = [];
|
|
144
|
-
for (let cursor = start; cursor < end; cursor++) {
|
|
145
|
-
if (source[cursor] !== '"') continue;
|
|
146
|
-
const stringEnd = jsonStringEnd(source, cursor);
|
|
147
|
-
if (stringEnd === null || stringEnd > end) break;
|
|
148
|
-
ranges.push([cursor, stringEnd]);
|
|
149
|
-
cursor = stringEnd - 1;
|
|
150
|
-
}
|
|
151
|
-
return ranges;
|
|
152
|
-
}
|
|
153
|
-
function declaredKind(candidate) {
|
|
154
|
-
try {
|
|
155
|
-
const parsed = JSON.parse(candidate);
|
|
156
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
const kind = parsed.__kind;
|
|
160
|
-
return typeof kind === "string" && kind.trim() ? kind : null;
|
|
161
|
-
} catch {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
function literalRanges(source, liftJsonFences = false) {
|
|
166
|
-
const ranges = [];
|
|
167
|
-
const code = liftJsonFences ? findCodeRanges(source).filter((range) => !isJsonFenceRange(source, range)) : findCodeRanges(source);
|
|
168
|
-
let next = 0;
|
|
169
|
-
let cursor = 0;
|
|
170
|
-
while (cursor < source.length) {
|
|
171
|
-
while (next < code.length && code[next].start < cursor) next++;
|
|
172
|
-
const range = code[next];
|
|
173
|
-
if (range && range.start === cursor) {
|
|
174
|
-
ranges.push([range.start, range.end]);
|
|
175
|
-
cursor = range.end;
|
|
176
|
-
next++;
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
if (source.startsWith("<!--", cursor)) {
|
|
180
|
-
const end = source.indexOf("-->", cursor + 4);
|
|
181
|
-
const rangeEnd = end === -1 ? source.length : end + 3;
|
|
182
|
-
ranges.push([cursor, rangeEnd]);
|
|
183
|
-
cursor = rangeEnd;
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
if (source.startsWith("<![CDATA[", cursor)) {
|
|
187
|
-
const end = source.indexOf("]]>", cursor + 9);
|
|
188
|
-
const rangeEnd = end === -1 ? source.length : end + 3;
|
|
189
|
-
ranges.push([cursor, rangeEnd]);
|
|
190
|
-
cursor = rangeEnd;
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
if (source[cursor] === "<") {
|
|
194
|
-
const tag = readXmlTag(source, cursor);
|
|
195
|
-
if (tag) {
|
|
196
|
-
const end = cursor + tag.raw.length;
|
|
197
|
-
ranges.push([cursor, end]);
|
|
198
|
-
cursor = end;
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
if (/^<[A-Za-z_][\w.:-]*\s/.test(source.slice(cursor, cursor + 64)) && !tagCloses(source, cursor)) {
|
|
202
|
-
ranges.push([cursor, source.length]);
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
cursor++;
|
|
207
|
-
}
|
|
208
|
-
return ranges;
|
|
209
|
-
}
|
|
210
|
-
function tagCloses(source, start) {
|
|
211
|
-
let quote = null;
|
|
212
|
-
for (let i = start + 1; i < source.length; i++) {
|
|
213
|
-
const ch = source[i];
|
|
214
|
-
if (quote) {
|
|
215
|
-
if (ch === quote) quote = null;
|
|
216
|
-
} else if (ch === "'" || ch === '"') quote = ch;
|
|
217
|
-
else if (ch === ">") return true;
|
|
218
|
-
}
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
function isJsonFenceRange(source, range) {
|
|
222
|
-
if (range.kind !== "fence") return false;
|
|
223
|
-
const raw = source.slice(range.start, range.end);
|
|
224
|
-
const newline = raw.indexOf("\n");
|
|
225
|
-
const opener = fenceOpenerOf((newline === -1 ? raw : raw.slice(0, newline)).trimStart());
|
|
226
|
-
return opener !== null && isJsonFenceLanguage(opener.lang);
|
|
227
|
-
}
|
|
228
|
-
function jsonFenceChromeSpans(source, regions) {
|
|
229
|
-
const spans = [];
|
|
230
|
-
for (const range of findCodeRanges(source)) {
|
|
231
|
-
if (!isJsonFenceRange(source, range)) continue;
|
|
232
|
-
const inside = regions.filter((r) => r.start >= range.start && r.end <= range.end);
|
|
233
|
-
if (inside.length !== 1) continue;
|
|
234
|
-
const region = inside[0];
|
|
235
|
-
const head = source.slice(range.start, region.start);
|
|
236
|
-
const tail = source.slice(region.end, range.end);
|
|
237
|
-
if (!/^[^\n]*\n\s*$/.test(head) || !/^\s*(?:[`~]{3,}[ \t]*)?$/.test(tail)) continue;
|
|
238
|
-
spans.push([range.start, region.start]);
|
|
239
|
-
if (region.end < range.end) spans.push([region.end, range.end]);
|
|
240
|
-
}
|
|
241
|
-
return spans;
|
|
242
|
-
}
|
|
243
|
-
import { frontMatterEnd as frontMatterEnd2 } from "./json-kind-signal.js";
|
|
244
|
-
function findEmbeddedKindJsonRegions(source, options = {}) {
|
|
245
|
-
const regions = [];
|
|
246
|
-
const endOf = lazyJsonEnds(source);
|
|
247
|
-
const excluded = [
|
|
248
|
-
...options.excludeLiteralContexts ? literalRanges(source, options.liftJsonFences === true) : [],
|
|
249
|
-
...options.excludeQuotedSource ? quotedSourceRanges(source) : []
|
|
250
|
-
].sort((a, b) => a[0] - b[0]);
|
|
251
|
-
const jsonStrings = [];
|
|
252
|
-
let excludedIndex = 0;
|
|
253
|
-
let jsonStringIndex = 0;
|
|
254
|
-
for (let start = frontMatterEnd(source); start < source.length; start++) {
|
|
255
|
-
while (excludedIndex < excluded.length && excluded[excludedIndex][1] <= start) {
|
|
256
|
-
excludedIndex++;
|
|
257
|
-
}
|
|
258
|
-
while (jsonStringIndex < jsonStrings.length && jsonStrings[jsonStringIndex][1] <= start) {
|
|
259
|
-
jsonStringIndex++;
|
|
260
|
-
}
|
|
261
|
-
if (excludedIndex < excluded.length && start >= excluded[excludedIndex][0] && start < excluded[excludedIndex][1])
|
|
262
|
-
continue;
|
|
263
|
-
if (jsonStringIndex < jsonStrings.length && start >= jsonStrings[jsonStringIndex][0] && start < jsonStrings[jsonStringIndex][1])
|
|
264
|
-
continue;
|
|
265
|
-
if (source[start] !== "{") continue;
|
|
266
|
-
const end = endOf(start);
|
|
267
|
-
if (end === null) {
|
|
268
|
-
const verdict = kindGrammar(source, "json", start);
|
|
269
|
-
const bound = verdict.status === "broken" ? verdict.cut : source.length;
|
|
270
|
-
const ownerEnd = bound > start ? malformedKindOwnerEnd(source, start, bound) : null;
|
|
271
|
-
if (ownerEnd !== null) start = ownerEnd - 1;
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
const content = source.slice(start, end);
|
|
275
|
-
const kind = declaredKind(content);
|
|
276
|
-
if (!kind) {
|
|
277
|
-
const ownerEnd = malformedKindOwnerEnd(source, start, end);
|
|
278
|
-
if (ownerEnd !== null) {
|
|
279
|
-
start = ownerEnd - 1;
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
for (const range of jsonStringRanges(source, start, end)) jsonStrings.push(range);
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
regions.push({ start, end, content, kind });
|
|
286
|
-
start = end - 1;
|
|
287
|
-
}
|
|
288
|
-
return regions;
|
|
289
|
-
}
|
|
290
|
-
function kindArrayChromeSpans(source, regions) {
|
|
291
|
-
const spans = [];
|
|
292
|
-
let first = 0;
|
|
293
|
-
while (first < regions.length) {
|
|
294
|
-
let last = first;
|
|
295
|
-
while (last + 1 < regions.length && /^\s*,\s*$/.test(source.slice(regions[last].end, regions[last + 1].start))) {
|
|
296
|
-
last++;
|
|
297
|
-
}
|
|
298
|
-
const before = source.slice(0, regions[first].start);
|
|
299
|
-
const open = /\[\s*$/.exec(before);
|
|
300
|
-
const after = source.slice(regions[last].end);
|
|
301
|
-
const close = /^\s*\]/.exec(after);
|
|
302
|
-
if (open && close) {
|
|
303
|
-
spans.push([open.index, regions[first].start]);
|
|
304
|
-
for (let k = first; k < last; k++) {
|
|
305
|
-
spans.push([regions[k].end, regions[k + 1].start]);
|
|
306
|
-
}
|
|
307
|
-
spans.push([regions[last].end, regions[last].end + close[0].length]);
|
|
308
|
-
}
|
|
309
|
-
first = last + 1;
|
|
310
|
-
}
|
|
311
|
-
return spans;
|
|
312
|
-
}
|
|
313
|
-
function isKindValue(value) {
|
|
314
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
315
|
-
return false;
|
|
316
|
-
}
|
|
317
|
-
const kind = value.__kind;
|
|
318
|
-
return typeof kind === "string" && kind.trim().length > 0;
|
|
319
|
-
}
|
|
320
|
-
function withoutKinds(value) {
|
|
321
|
-
if (Array.isArray(value)) {
|
|
322
|
-
return value.filter((item) => !isKindValue(item)).map(withoutKinds);
|
|
323
|
-
}
|
|
324
|
-
if (typeof value === "object" && value !== null) {
|
|
325
|
-
const out = {};
|
|
326
|
-
for (const [key, item] of Object.entries(value)) {
|
|
327
|
-
if (!isKindValue(item)) out[key] = withoutKinds(item);
|
|
328
|
-
}
|
|
329
|
-
return out;
|
|
330
|
-
}
|
|
331
|
-
return value;
|
|
332
|
-
}
|
|
333
|
-
function carriesData(value) {
|
|
334
|
-
if (Array.isArray(value)) return value.some(carriesData);
|
|
335
|
-
if (typeof value === "object" && value !== null) {
|
|
336
|
-
return Object.values(value).some(carriesData);
|
|
337
|
-
}
|
|
338
|
-
return true;
|
|
339
|
-
}
|
|
340
|
-
function isPureJsonStructure(span) {
|
|
341
|
-
return /^[\s{}[\],:]*$/.test(
|
|
342
|
-
span.replace(/"(?:[^"\\]|\\.)*"\s*:/g, "")
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
function wrapperPieces(source, regions) {
|
|
346
|
-
const trimmed = source.trim();
|
|
347
|
-
if (!/^[[{]/.test(trimmed)) return null;
|
|
348
|
-
let parsed;
|
|
349
|
-
try {
|
|
350
|
-
parsed = JSON.parse(trimmed);
|
|
351
|
-
} catch {
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
if (typeof parsed !== "object" || parsed === null || isKindValue(parsed)) {
|
|
355
|
-
return null;
|
|
356
|
-
}
|
|
357
|
-
const residual = withoutKinds(parsed);
|
|
358
|
-
const residualJson = carriesData(residual) ? JSON.stringify(residual, null, 2) : null;
|
|
359
|
-
const pieces = [];
|
|
360
|
-
let residualPlaced = residualJson === null;
|
|
361
|
-
const pushSpan = (content) => {
|
|
362
|
-
if (!content) return;
|
|
363
|
-
if (!residualPlaced && !isPureJsonStructure(content)) {
|
|
364
|
-
pieces.push({ type: "residual", content, json: residualJson });
|
|
365
|
-
residualPlaced = true;
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
pieces.push({ type: "chrome", content });
|
|
369
|
-
};
|
|
370
|
-
let cursor = 0;
|
|
371
|
-
for (const region of regions) {
|
|
372
|
-
pushSpan(source.slice(cursor, region.start));
|
|
373
|
-
pieces.push({ type: "kind", content: region.content, kind: region.kind });
|
|
374
|
-
cursor = region.end;
|
|
375
|
-
}
|
|
376
|
-
pushSpan(source.slice(cursor));
|
|
377
|
-
if (!residualPlaced) {
|
|
378
|
-
pieces.push({ type: "residual", content: "", json: residualJson });
|
|
379
|
-
}
|
|
380
|
-
return pieces;
|
|
381
|
-
}
|
|
382
|
-
function splitAroundEmbeddedKindJson(source, options = {}) {
|
|
383
|
-
const regions = findEmbeddedKindJsonRegions(source, options);
|
|
384
|
-
if (regions.length === 0) return [{ type: "container", content: source }];
|
|
385
|
-
const wrapped = wrapperPieces(source, regions);
|
|
386
|
-
if (wrapped) return wrapped;
|
|
387
|
-
const marks = [
|
|
388
|
-
...regions.map((r) => ({ start: r.start, end: r.end, type: "kind", kind: r.kind })),
|
|
389
|
-
...[
|
|
390
|
-
...kindArrayChromeSpans(source, regions),
|
|
391
|
-
...options.excludeLiteralContexts && options.liftJsonFences ? jsonFenceChromeSpans(source, regions) : []
|
|
392
|
-
].map(([start, end]) => ({
|
|
393
|
-
start,
|
|
394
|
-
end,
|
|
395
|
-
type: "chrome"
|
|
396
|
-
}))
|
|
397
|
-
].sort((a, b) => a.start - b.start);
|
|
398
|
-
const pieces = [];
|
|
399
|
-
let cursor = 0;
|
|
400
|
-
for (const mark of marks) {
|
|
401
|
-
if (mark.start > cursor) {
|
|
402
|
-
pieces.push({
|
|
403
|
-
type: "container",
|
|
404
|
-
content: source.slice(cursor, mark.start)
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
if (mark.end > mark.start) {
|
|
408
|
-
pieces.push(
|
|
409
|
-
mark.type === "kind" ? { type: "kind", content: source.slice(mark.start, mark.end), kind: mark.kind } : { type: "chrome", content: source.slice(mark.start, mark.end) }
|
|
410
|
-
);
|
|
411
|
-
}
|
|
412
|
-
cursor = Math.max(cursor, mark.end);
|
|
413
|
-
}
|
|
414
|
-
if (cursor < source.length) {
|
|
415
|
-
pieces.push({ type: "container", content: source.slice(cursor) });
|
|
416
|
-
}
|
|
417
|
-
return pieces;
|
|
418
|
-
}
|
|
419
|
-
function normalizeRecoveredProsePiece(content, followsKind) {
|
|
420
|
-
const start = followsKind ? content.replace(/^[ \t]*(?:\r?\n)?/, "") : content;
|
|
421
|
-
return start.trimEnd();
|
|
422
|
-
}
|
|
423
|
-
function normalizeRecoveredContainerPiece(content, containerType, followsKind) {
|
|
424
|
-
if (containerType === "text") {
|
|
425
|
-
return normalizeRecoveredProsePiece(content, followsKind);
|
|
426
|
-
}
|
|
427
|
-
if (containerType === "code") return content;
|
|
428
|
-
return content.trim();
|
|
429
|
-
}
|
|
430
|
-
function findKindCarryingJsonValues(source, options = {}) {
|
|
431
|
-
const kinds = findEmbeddedKindJsonRegions(source, options);
|
|
432
|
-
if (kinds.length === 0) return [];
|
|
433
|
-
const excluded = options.excludeLiteralContexts ? literalRanges(source) : [];
|
|
434
|
-
const inLiteral = (index) => excluded.some(([start, end]) => index >= start && index < end);
|
|
435
|
-
const ends = balancedEnds(source);
|
|
436
|
-
const regions = [];
|
|
437
|
-
let floor = frontMatterEnd(source);
|
|
438
|
-
for (const region of kinds) {
|
|
439
|
-
if (region.start < floor) continue;
|
|
440
|
-
let best = { start: region.start, end: region.end, value: JSON.parse(region.content) };
|
|
441
|
-
for (let open = floor; open < region.start; open++) {
|
|
442
|
-
const char = source[open];
|
|
443
|
-
if (char !== "{" && char !== "[" || inLiteral(open)) continue;
|
|
444
|
-
const found = ends[open];
|
|
445
|
-
if (found < 0 || found < region.end) continue;
|
|
446
|
-
const end = found;
|
|
447
|
-
try {
|
|
448
|
-
best = { start: open, end, value: JSON.parse(source.slice(open, end)) };
|
|
449
|
-
break;
|
|
450
|
-
} catch {
|
|
451
|
-
continue;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
regions.push({ ...best, content: source.slice(best.start, best.end) });
|
|
455
|
-
floor = best.end;
|
|
456
|
-
}
|
|
457
|
-
return regions;
|
|
458
|
-
}
|
|
459
|
-
const KIND_KEY_TEXT = /(?<!\\)"__kind"\s*:/;
|
|
460
|
-
const KIND_KEY_TEXT_G = /(?<!\\)"__kind"\s*:/g;
|
|
461
|
-
function findBrokenKindJsonRegions(source, options = {}) {
|
|
462
|
-
const broken = [];
|
|
463
|
-
if (!KIND_KEY_TEXT.test(source)) return broken;
|
|
464
|
-
const endOf = lazyJsonEnds(source);
|
|
465
|
-
const keys = [];
|
|
466
|
-
KIND_KEY_TEXT_G.lastIndex = 0;
|
|
467
|
-
for (let m = KIND_KEY_TEXT_G.exec(source); m; m = KIND_KEY_TEXT_G.exec(source)) keys.push(m.index);
|
|
468
|
-
let keyIndex = 0;
|
|
469
|
-
const excluded = options.excludeLiteralContexts ? literalRanges(source) : [];
|
|
470
|
-
let excludedIndex = 0;
|
|
471
|
-
for (let start = frontMatterEnd(source); start < source.length; start++) {
|
|
472
|
-
while (excludedIndex < excluded.length && excluded[excludedIndex][1] <= start) {
|
|
473
|
-
excludedIndex++;
|
|
474
|
-
}
|
|
475
|
-
if (excludedIndex < excluded.length && start >= excluded[excludedIndex][0] && start < excluded[excludedIndex][1]) {
|
|
476
|
-
start = excluded[excludedIndex][1] - 1;
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
const char = source[start];
|
|
480
|
-
if (char !== "{" && char !== "[") continue;
|
|
481
|
-
while (keyIndex < keys.length && keys[keyIndex] < start) keyIndex++;
|
|
482
|
-
if (keyIndex >= keys.length) break;
|
|
483
|
-
const key = keys[keyIndex];
|
|
484
|
-
const verdict = kindGrammar(source, "json", start);
|
|
485
|
-
if (verdict.status === "complete") {
|
|
486
|
-
try {
|
|
487
|
-
JSON.parse(source.slice(start, verdict.end));
|
|
488
|
-
start = verdict.end - 1;
|
|
489
|
-
} catch {
|
|
490
|
-
}
|
|
491
|
-
continue;
|
|
492
|
-
}
|
|
493
|
-
if (verdict.status === "prefix") {
|
|
494
|
-
broken.push({ start, end: source.length, content: source.slice(start) });
|
|
495
|
-
break;
|
|
496
|
-
}
|
|
497
|
-
if (verdict.at <= key) continue;
|
|
498
|
-
const end = endOf(start);
|
|
499
|
-
if (end !== null && lenientJson(source.slice(start, end))) {
|
|
500
|
-
broken.push({ start, end, content: source.slice(start, end) });
|
|
501
|
-
start = end - 1;
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
|
-
if (verdict.cut <= key) continue;
|
|
505
|
-
broken.push({ start, end: verdict.cut, content: source.slice(start, verdict.cut) });
|
|
506
|
-
start = verdict.cut - 1;
|
|
507
|
-
}
|
|
508
|
-
return broken;
|
|
509
|
-
}
|
|
510
|
-
function lenientJson(span) {
|
|
511
|
-
try {
|
|
512
|
-
JSON.parse(span.replace(/,(\s*[}\]])/g, "$1"));
|
|
513
|
-
return true;
|
|
514
|
-
} catch {
|
|
515
|
-
return false;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
export {
|
|
519
|
-
balancedEnds,
|
|
520
|
-
findBrokenKindJsonRegions,
|
|
521
|
-
findEmbeddedKindJsonRegions,
|
|
522
|
-
findKindCarryingJsonValues,
|
|
523
|
-
frontMatterEnd2 as frontMatterEnd,
|
|
524
|
-
normalizeRecoveredContainerPiece,
|
|
525
|
-
normalizeRecoveredProsePiece,
|
|
526
|
-
splitAroundEmbeddedKindJson
|
|
527
|
-
};
|