@ai-matrx/content-ir 0.22.7 → 0.23.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/convert.cjs +3 -290
- package/dist/convert.cjs.map +1 -1
- package/dist/convert.js +2 -289
- package/dist/convert.js.map +1 -1
- package/dist/core.cjs +3 -290
- package/dist/core.cjs.map +1 -1
- package/dist/core.js +2 -289
- package/dist/core.js.map +1 -1
- package/dist/directives.cjs +3 -37
- package/dist/directives.cjs.map +1 -1
- package/dist/directives.js +2 -36
- package/dist/directives.js.map +1 -1
- package/dist/index.cjs +202 -309
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +194 -308
- package/dist/index.js.map +1 -1
- package/dist/json-extract.cjs +942 -0
- package/dist/json-extract.cjs.map +1 -0
- package/dist/json-extract.d.cts +176 -0
- package/dist/json-extract.d.ts +176 -0
- package/dist/json-extract.js +928 -0
- package/dist/json-extract.js.map +1 -0
- package/dist/source.cjs +199 -0
- package/dist/source.cjs.map +1 -1
- package/dist/source.d.cts +138 -1
- package/dist/source.d.ts +138 -1
- package/dist/source.js +193 -1
- package/dist/source.js.map +1 -1
- package/dist/surfaces.cjs +4 -40
- package/dist/surfaces.cjs.map +1 -1
- package/dist/surfaces.js +2 -38
- package/dist/surfaces.js.map +1 -1
- package/package.json +28 -7
- package/dist/text-case.cjs +0 -333
- package/dist/text-case.cjs.map +0 -1
- package/dist/text-case.d.cts +0 -87
- package/dist/text-case.d.ts +0 -87
- package/dist/text-case.js +0 -320
- package/dist/text-case.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var textCase = require('@ai-matrx/kit/text-case');
|
|
3
4
|
var Ajv = require('ajv');
|
|
4
5
|
|
|
5
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -2127,313 +2128,8 @@ function stripKindDeep(value) {
|
|
|
2127
2128
|
}
|
|
2128
2129
|
return value;
|
|
2129
2130
|
}
|
|
2130
|
-
|
|
2131
|
-
// text-case.ts
|
|
2132
|
-
var DEFAULT_WORD_REPLACEMENTS = {
|
|
2133
|
-
// Acronyms & initialisms
|
|
2134
|
-
"api": "API",
|
|
2135
|
-
"apis": "APIs",
|
|
2136
|
-
"ui": "UI",
|
|
2137
|
-
"ux": "UX",
|
|
2138
|
-
"id": "ID",
|
|
2139
|
-
"ids": "IDs",
|
|
2140
|
-
"qr": "QR",
|
|
2141
|
-
"ssr": "SSR",
|
|
2142
|
-
"csr": "CSR",
|
|
2143
|
-
"ssg": "SSG",
|
|
2144
|
-
"isr": "ISR",
|
|
2145
|
-
"spa": "SPA",
|
|
2146
|
-
"pwa": "PWA",
|
|
2147
|
-
"sdk": "SDK",
|
|
2148
|
-
"sdks": "SDKs",
|
|
2149
|
-
"cli": "CLI",
|
|
2150
|
-
"tty": "TTY",
|
|
2151
|
-
"repl": "REPL",
|
|
2152
|
-
"ci": "CI",
|
|
2153
|
-
"cd": "CD",
|
|
2154
|
-
"cpu": "CPU",
|
|
2155
|
-
"cpus": "CPUs",
|
|
2156
|
-
"gpu": "GPU",
|
|
2157
|
-
"gpus": "GPUs",
|
|
2158
|
-
"ram": "RAM",
|
|
2159
|
-
"rom": "ROM",
|
|
2160
|
-
"ssd": "SSD",
|
|
2161
|
-
"ssds": "SSDs",
|
|
2162
|
-
"hdd": "HDD",
|
|
2163
|
-
"hdds": "HDDs",
|
|
2164
|
-
"kpi": "KPI",
|
|
2165
|
-
"kpis": "KPIs",
|
|
2166
|
-
"sla": "SLA",
|
|
2167
|
-
"slas": "SLAs",
|
|
2168
|
-
"slo": "SLO",
|
|
2169
|
-
"slos": "SLOs",
|
|
2170
|
-
"sli": "SLI",
|
|
2171
|
-
"slis": "SLIs",
|
|
2172
|
-
"dom": "DOM",
|
|
2173
|
-
// Web, formats, protocols
|
|
2174
|
-
"url": "URL",
|
|
2175
|
-
"urls": "URLs",
|
|
2176
|
-
"uri": "URI",
|
|
2177
|
-
"uris": "URIs",
|
|
2178
|
-
"http": "HTTP",
|
|
2179
|
-
"https": "HTTPS",
|
|
2180
|
-
"html": "HTML",
|
|
2181
|
-
"css": "CSS",
|
|
2182
|
-
"json": "JSON",
|
|
2183
|
-
"yaml": "YAML",
|
|
2184
|
-
"yml": "YML",
|
|
2185
|
-
"toml": "TOML",
|
|
2186
|
-
"csv": "CSV",
|
|
2187
|
-
"pdf": "PDF",
|
|
2188
|
-
"tsv": "TSV",
|
|
2189
|
-
"jpg": "JPG",
|
|
2190
|
-
"jpeg": "JPEG",
|
|
2191
|
-
"png": "PNG",
|
|
2192
|
-
"gif": "GIF",
|
|
2193
|
-
"webp": "WebP",
|
|
2194
|
-
"heic": "HEIC",
|
|
2195
|
-
"heif": "HEIF",
|
|
2196
|
-
"bmp": "BMP",
|
|
2197
|
-
"tiff": "TIFF",
|
|
2198
|
-
"ico": "ICO",
|
|
2199
|
-
"xml": "XML",
|
|
2200
|
-
"sql": "SQL",
|
|
2201
|
-
"db": "DB",
|
|
2202
|
-
"dbs": "DBs",
|
|
2203
|
-
"nosql": "NoSQL",
|
|
2204
|
-
"graphql": "GraphQL",
|
|
2205
|
-
"grpc": "gRPC",
|
|
2206
|
-
"rest": "REST",
|
|
2207
|
-
"restful": "RESTful",
|
|
2208
|
-
"websocket": "WebSocket",
|
|
2209
|
-
"websockets": "WebSockets",
|
|
2210
|
-
"webrtc": "WebRTC",
|
|
2211
|
-
// Networking
|
|
2212
|
-
"ip": "IP",
|
|
2213
|
-
"ipv4": "IPv4",
|
|
2214
|
-
"ipv6": "IPv6",
|
|
2215
|
-
"dns": "DNS",
|
|
2216
|
-
"dhcp": "DHCP",
|
|
2217
|
-
"nat": "NAT",
|
|
2218
|
-
"tcp": "TCP",
|
|
2219
|
-
"udp": "UDP",
|
|
2220
|
-
"icmp": "ICMP",
|
|
2221
|
-
"ttl": "TTL",
|
|
2222
|
-
"lan": "LAN",
|
|
2223
|
-
"wan": "WAN",
|
|
2224
|
-
"vlan": "VLAN",
|
|
2225
|
-
"cdn": "CDN",
|
|
2226
|
-
"ftp": "FTP",
|
|
2227
|
-
"ssh": "SSH",
|
|
2228
|
-
"tls": "TLS",
|
|
2229
|
-
"ssl": "SSL",
|
|
2230
|
-
// Security & crypto
|
|
2231
|
-
"jwt": "JWT",
|
|
2232
|
-
"jws": "JWS",
|
|
2233
|
-
"jwe": "JWE",
|
|
2234
|
-
"hmac": "HMAC",
|
|
2235
|
-
"rsa": "RSA",
|
|
2236
|
-
"ecdsa": "ECDSA",
|
|
2237
|
-
"aes": "AES",
|
|
2238
|
-
"pbkdf2": "PBKDF2",
|
|
2239
|
-
"argon2": "Argon2",
|
|
2240
|
-
"scrypt": "scrypt",
|
|
2241
|
-
"totp": "TOTP",
|
|
2242
|
-
"hotp": "HOTP",
|
|
2243
|
-
"mfa": "MFA",
|
|
2244
|
-
"2fa": "2FA",
|
|
2245
|
-
"csrf": "CSRF",
|
|
2246
|
-
"xss": "XSS",
|
|
2247
|
-
"ssrf": "SSRF",
|
|
2248
|
-
"rce": "RCE",
|
|
2249
|
-
"dos": "DoS",
|
|
2250
|
-
"ddos": "DDoS",
|
|
2251
|
-
"mitm": "MITM",
|
|
2252
|
-
"csp": "CSP",
|
|
2253
|
-
"cors": "CORS",
|
|
2254
|
-
"pii": "PII",
|
|
2255
|
-
"phi": "PHI",
|
|
2256
|
-
"gdpr": "GDPR",
|
|
2257
|
-
"ccpa": "CCPA",
|
|
2258
|
-
"hipaa": "HIPAA",
|
|
2259
|
-
"rfc": "RFC",
|
|
2260
|
-
// Platforms, langs, tools (single-token)
|
|
2261
|
-
"javascript": "JavaScript",
|
|
2262
|
-
"typescript": "TypeScript",
|
|
2263
|
-
"jsx": "JSX",
|
|
2264
|
-
"tsx": "TSX",
|
|
2265
|
-
"node": "Node",
|
|
2266
|
-
// (used when tokenized alone)
|
|
2267
|
-
"deno": "Deno",
|
|
2268
|
-
"bun": "Bun",
|
|
2269
|
-
"react": "React",
|
|
2270
|
-
"nextjs": "Next.js",
|
|
2271
|
-
// if your tokenizer drops dots, keep this
|
|
2272
|
-
"nodejs": "Node.js",
|
|
2273
|
-
"postgresql": "PostgreSQL",
|
|
2274
|
-
"postgres": "Postgres",
|
|
2275
|
-
"mysql": "MySQL",
|
|
2276
|
-
"sqlite": "SQLite",
|
|
2277
|
-
"redis": "Redis",
|
|
2278
|
-
"supabase": "Supabase",
|
|
2279
|
-
"docker": "Docker",
|
|
2280
|
-
"kubernetes": "Kubernetes",
|
|
2281
|
-
"k8s": "Kubernetes",
|
|
2282
|
-
"helm": "Helm",
|
|
2283
|
-
"npm": "npm",
|
|
2284
|
-
"pnpm": "pnpm",
|
|
2285
|
-
"yarn": "Yarn",
|
|
2286
|
-
"eslint": "ESLint",
|
|
2287
|
-
"prettier": "Prettier",
|
|
2288
|
-
"vite": "Vite",
|
|
2289
|
-
"webpack": "Webpack",
|
|
2290
|
-
"babel": "Babel",
|
|
2291
|
-
// OS & vendors
|
|
2292
|
-
"macos": "macOS",
|
|
2293
|
-
"ios": "iOS",
|
|
2294
|
-
"ipados": "iPadOS",
|
|
2295
|
-
"watchos": "watchOS",
|
|
2296
|
-
"tvos": "tvOS",
|
|
2297
|
-
"windows": "Windows",
|
|
2298
|
-
"linux": "Linux",
|
|
2299
|
-
"ubuntu": "Ubuntu",
|
|
2300
|
-
"github": "GitHub",
|
|
2301
|
-
"gitlab": "GitLab",
|
|
2302
|
-
"bitbucket": "Bitbucket",
|
|
2303
|
-
// Data & analytics
|
|
2304
|
-
"etl": "ETL",
|
|
2305
|
-
"elt": "ELT",
|
|
2306
|
-
"olap": "OLAP",
|
|
2307
|
-
"oltp": "OLTP",
|
|
2308
|
-
"bi": "BI",
|
|
2309
|
-
// Time & locales
|
|
2310
|
-
"utc": "UTC",
|
|
2311
|
-
"gmt": "GMT",
|
|
2312
|
-
"pst": "PST",
|
|
2313
|
-
"pdt": "PDT",
|
|
2314
|
-
"pt": "PT",
|
|
2315
|
-
// Common “small words” to keep lowercase (unless first/last word)
|
|
2316
|
-
"or": "or",
|
|
2317
|
-
"and": "and",
|
|
2318
|
-
"the": "the",
|
|
2319
|
-
"of": "of",
|
|
2320
|
-
"in": "in",
|
|
2321
|
-
"to": "to",
|
|
2322
|
-
"with": "with",
|
|
2323
|
-
"as": "as",
|
|
2324
|
-
"by": "by",
|
|
2325
|
-
"for": "for",
|
|
2326
|
-
"on": "on",
|
|
2327
|
-
"at": "at",
|
|
2328
|
-
"up": "up",
|
|
2329
|
-
"a": "a",
|
|
2330
|
-
"an": "an",
|
|
2331
|
-
"is": "is",
|
|
2332
|
-
"are": "are",
|
|
2333
|
-
"was": "was",
|
|
2334
|
-
"were": "were",
|
|
2335
|
-
"be": "be",
|
|
2336
|
-
"but": "but",
|
|
2337
|
-
"nor": "nor",
|
|
2338
|
-
"so": "so",
|
|
2339
|
-
"yet": "yet",
|
|
2340
|
-
"per": "per",
|
|
2341
|
-
"via": "via",
|
|
2342
|
-
// Latin abbreviations (tokenized as words in some pipelines)
|
|
2343
|
-
"eg": "e.g.",
|
|
2344
|
-
"ie": "i.e.",
|
|
2345
|
-
"etc": "etc.",
|
|
2346
|
-
"aka": "aka",
|
|
2347
|
-
"vs": "vs.",
|
|
2348
|
-
"v": "v.",
|
|
2349
|
-
// Client abbreviations
|
|
2350
|
-
"CIC": "CIC",
|
|
2351
|
-
"AGR": "AGR",
|
|
2352
|
-
"AGER": "AGER",
|
|
2353
|
-
"DD": "DD",
|
|
2354
|
-
"TS": "TS",
|
|
2355
|
-
"TM": "TM",
|
|
2356
|
-
"arman": "Arman"
|
|
2357
|
-
};
|
|
2358
|
-
var DEFAULT_OPTIONS = {
|
|
2359
|
-
textCase: "title",
|
|
2360
|
-
wordReplacements: DEFAULT_WORD_REPLACEMENTS,
|
|
2361
|
-
trim: true
|
|
2362
|
-
};
|
|
2363
|
-
function formatText(text, options = {}) {
|
|
2364
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
2365
|
-
if (!text) return "";
|
|
2366
|
-
let normalized = text.replace(/_/g, " ").replace(/-/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ");
|
|
2367
|
-
if (opts.trim) {
|
|
2368
|
-
normalized = normalized.trim();
|
|
2369
|
-
}
|
|
2370
|
-
let caseTransformed = normalized;
|
|
2371
|
-
switch (opts.textCase) {
|
|
2372
|
-
case "title":
|
|
2373
|
-
caseTransformed = normalized.replace(
|
|
2374
|
-
/\w\S*/g,
|
|
2375
|
-
(word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
|
2376
|
-
);
|
|
2377
|
-
break;
|
|
2378
|
-
case "sentence":
|
|
2379
|
-
if (normalized.length > 0) {
|
|
2380
|
-
caseTransformed = normalized.charAt(0).toUpperCase() + normalized.slice(1).toLowerCase();
|
|
2381
|
-
}
|
|
2382
|
-
break;
|
|
2383
|
-
case "lower":
|
|
2384
|
-
caseTransformed = normalized.toLowerCase();
|
|
2385
|
-
break;
|
|
2386
|
-
case "upper":
|
|
2387
|
-
caseTransformed = normalized.toUpperCase();
|
|
2388
|
-
break;
|
|
2389
|
-
}
|
|
2390
|
-
let result = caseTransformed;
|
|
2391
|
-
if (opts.wordReplacements) {
|
|
2392
|
-
Object.entries(opts.wordReplacements).forEach(([key, value]) => {
|
|
2393
|
-
const regex = new RegExp(`\\b${key}\\b`, "gi");
|
|
2394
|
-
result = result.replace(regex, value);
|
|
2395
|
-
});
|
|
2396
|
-
}
|
|
2397
|
-
return result;
|
|
2398
|
-
}
|
|
2399
|
-
var IDENTIFIER_ACRONYMS = [
|
|
2400
|
-
"ID",
|
|
2401
|
-
"URL",
|
|
2402
|
-
"PDF",
|
|
2403
|
-
"HTML",
|
|
2404
|
-
"JSON",
|
|
2405
|
-
"API",
|
|
2406
|
-
"AI",
|
|
2407
|
-
"UI",
|
|
2408
|
-
"CSV",
|
|
2409
|
-
"SMS",
|
|
2410
|
-
"SEO",
|
|
2411
|
-
"LLM",
|
|
2412
|
-
"MCP",
|
|
2413
|
-
"UUID",
|
|
2414
|
-
"ISO"
|
|
2415
|
-
];
|
|
2416
|
-
var IDENTIFIER_ACRONYM_SET = new Set(IDENTIFIER_ACRONYMS.map((a) => a.toLowerCase()));
|
|
2417
|
-
function humanizeIdentifier(identifier) {
|
|
2418
|
-
const text = (identifier ?? "").trim();
|
|
2419
|
-
if (text === "") return "";
|
|
2420
|
-
if (!text.includes("_") && /\s/.test(text)) {
|
|
2421
|
-
return /^\p{Ll}/u.test(text) ? text.charAt(0).toUpperCase() + text.slice(1) : text;
|
|
2422
|
-
}
|
|
2423
|
-
return text.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)(?![A-Z]s(?![a-z]))([A-Z][a-z])/g, "$1 $2").split(/[_\-.\s]+/).filter((part) => part.length > 0).map(identifierWord).join(" ");
|
|
2424
|
-
}
|
|
2425
|
-
function identifierWord(part) {
|
|
2426
|
-
const lower = part.toLowerCase();
|
|
2427
|
-
if (IDENTIFIER_ACRONYM_SET.has(lower)) return part.toUpperCase();
|
|
2428
|
-
if (lower.length > 1 && lower.endsWith("s") && IDENTIFIER_ACRONYM_SET.has(lower.slice(0, -1))) {
|
|
2429
|
-
return `${lower.slice(0, -1).toUpperCase()}s`;
|
|
2430
|
-
}
|
|
2431
|
-
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
2432
|
-
}
|
|
2433
|
-
|
|
2434
|
-
// core/schema-structure.ts
|
|
2435
2131
|
function formatBlockLabel(key) {
|
|
2436
|
-
return formatText(key, { textCase: "title" });
|
|
2132
|
+
return textCase.formatText(key, { textCase: "title" });
|
|
2437
2133
|
}
|
|
2438
2134
|
function schemaStructureDepth(schema, allSchemas, visiting = /* @__PURE__ */ new Set()) {
|
|
2439
2135
|
if (visiting.has(schema.kind)) return 0;
|
|
@@ -5123,10 +4819,8 @@ function tryDecodeDirectiveContent(content, onError) {
|
|
|
5123
4819
|
}
|
|
5124
4820
|
return tryDecodeDirective(parsed, onError);
|
|
5125
4821
|
}
|
|
5126
|
-
|
|
5127
|
-
// directives/display.ts
|
|
5128
4822
|
function titleCaseToken(token) {
|
|
5129
|
-
return humanizeIdentifier(token) || token;
|
|
4823
|
+
return textCase.humanizeIdentifier(token) || token;
|
|
5130
4824
|
}
|
|
5131
4825
|
var ACTION_BY_CLASS = {
|
|
5132
4826
|
reference: "Reference",
|
|
@@ -8125,6 +7819,198 @@ function resolveReferenceLinks(fragment, defs) {
|
|
|
8125
7819
|
return resolved.replace(new RegExp(`${PLACEHOLDER}(\\d+)${PLACEHOLDER}`, "g"), (_m, i) => spans[Number(i)] ?? "");
|
|
8126
7820
|
}
|
|
8127
7821
|
|
|
7822
|
+
// source/delimiter-guard.ts
|
|
7823
|
+
var ZWSP = "\u200B";
|
|
7824
|
+
var ESCAPED_DOLLARS = `${ZWSP}$${ZWSP}$`;
|
|
7825
|
+
var ESCAPED_BRACKET = `${ZWSP}[`;
|
|
7826
|
+
function protectedRanges(text) {
|
|
7827
|
+
return findCodeRanges(text).map((r) => [r.start, r.end]);
|
|
7828
|
+
}
|
|
7829
|
+
function isProtected(index, ranges) {
|
|
7830
|
+
return ranges.some(([start, end]) => index >= start && index < end);
|
|
7831
|
+
}
|
|
7832
|
+
function preview(text, max = 160) {
|
|
7833
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
7834
|
+
return flat.length > max ? `${flat.slice(0, max)}\u2026` : flat;
|
|
7835
|
+
}
|
|
7836
|
+
function guardMathDelimiters(text) {
|
|
7837
|
+
if (!text.includes("$$")) return { text, violations: [] };
|
|
7838
|
+
const ranges = protectedRanges(text);
|
|
7839
|
+
const tokens = [];
|
|
7840
|
+
for (let i = 0; i < text.length - 1; i++) {
|
|
7841
|
+
if (text[i] !== "$" || text[i + 1] !== "$") continue;
|
|
7842
|
+
if (!isProtected(i, ranges)) tokens.push(i);
|
|
7843
|
+
i++;
|
|
7844
|
+
}
|
|
7845
|
+
if (tokens.length === 0) return { text, violations: [] };
|
|
7846
|
+
const violations = [];
|
|
7847
|
+
const escapeAt = [];
|
|
7848
|
+
let j = 0;
|
|
7849
|
+
while (j < tokens.length) {
|
|
7850
|
+
const open = tokens[j];
|
|
7851
|
+
const close = tokens[j + 1];
|
|
7852
|
+
if (close === void 0) {
|
|
7853
|
+
violations.push({
|
|
7854
|
+
reason: "unpaired",
|
|
7855
|
+
index: open,
|
|
7856
|
+
spanLength: 0,
|
|
7857
|
+
// An unpaired `$$` is inert to remark-math (nothing closes it), so it
|
|
7858
|
+
// is reported but NOT escaped — it already renders as literal text.
|
|
7859
|
+
preview: preview(text.slice(open, open + 120))
|
|
7860
|
+
});
|
|
7861
|
+
break;
|
|
7862
|
+
}
|
|
7863
|
+
const inner = text.slice(open + 2, close);
|
|
7864
|
+
if (isMathPlaceholder(inner)) {
|
|
7865
|
+
escapeAt.push(open, close);
|
|
7866
|
+
violations.push({ reason: "prose-span", index: open, spanLength: inner.length, preview: preview(inner) });
|
|
7867
|
+
j += 2;
|
|
7868
|
+
continue;
|
|
7869
|
+
}
|
|
7870
|
+
if (looksLikeDisplayMath(inner, opensFlowBlock(text, open))) {
|
|
7871
|
+
j += 2;
|
|
7872
|
+
continue;
|
|
7873
|
+
}
|
|
7874
|
+
escapeAt.push(open);
|
|
7875
|
+
violations.push({
|
|
7876
|
+
reason: "prose-span",
|
|
7877
|
+
index: open,
|
|
7878
|
+
spanLength: inner.length,
|
|
7879
|
+
preview: preview(inner)
|
|
7880
|
+
});
|
|
7881
|
+
j += 1;
|
|
7882
|
+
}
|
|
7883
|
+
let guarded = text;
|
|
7884
|
+
for (const index of [...escapeAt].sort((a, b) => b - a)) {
|
|
7885
|
+
guarded = `${guarded.slice(0, index)}${ESCAPED_DOLLARS}${guarded.slice(index + 2)}`;
|
|
7886
|
+
}
|
|
7887
|
+
return { text: guarded, violations };
|
|
7888
|
+
}
|
|
7889
|
+
var MAX_LINK_LABEL = 200;
|
|
7890
|
+
var LABEL_BLOCK_STRUCTURE = /\n[ \t]*\n|(?:^|\n)[ \t]*[-*+][ \t]+|#{2,6}[ \t]/;
|
|
7891
|
+
function guardRunawayLinks(text) {
|
|
7892
|
+
if (!text.includes("[")) return { text, violations: [] };
|
|
7893
|
+
const ranges = protectedRanges(text);
|
|
7894
|
+
const violations = [];
|
|
7895
|
+
const escapeAt = [];
|
|
7896
|
+
const linkRe = /\[((?:[^[\]\\]|\\.)*)\]\(([^\s)]*)/g;
|
|
7897
|
+
let m;
|
|
7898
|
+
while ((m = linkRe.exec(text)) !== null) {
|
|
7899
|
+
const open = m.index;
|
|
7900
|
+
if (isProtected(open, ranges)) continue;
|
|
7901
|
+
const label = m[1] ?? "";
|
|
7902
|
+
const runaway = label.length > MAX_LINK_LABEL || LABEL_BLOCK_STRUCTURE.test(label);
|
|
7903
|
+
if (!runaway) continue;
|
|
7904
|
+
escapeAt.push(open);
|
|
7905
|
+
violations.push({
|
|
7906
|
+
reason: "runaway-link",
|
|
7907
|
+
index: open,
|
|
7908
|
+
spanLength: label.length,
|
|
7909
|
+
preview: preview(label)
|
|
7910
|
+
});
|
|
7911
|
+
}
|
|
7912
|
+
let guarded = text;
|
|
7913
|
+
for (const index of [...escapeAt].sort((a, b) => b - a)) {
|
|
7914
|
+
guarded = `${guarded.slice(0, index)}${ESCAPED_BRACKET}${guarded.slice(index + 1)}`;
|
|
7915
|
+
}
|
|
7916
|
+
return { text: guarded, violations };
|
|
7917
|
+
}
|
|
7918
|
+
function guardMarkdownDelimiters(text) {
|
|
7919
|
+
const math = guardMathDelimiters(text);
|
|
7920
|
+
const links = guardRunawayLinks(math.text);
|
|
7921
|
+
return {
|
|
7922
|
+
text: links.text,
|
|
7923
|
+
violations: [...math.violations, ...links.violations]
|
|
7924
|
+
};
|
|
7925
|
+
}
|
|
7926
|
+
function reportDelimiterViolations(violations, context) {
|
|
7927
|
+
if (violations.length === 0) return;
|
|
7928
|
+
try {
|
|
7929
|
+
const worst = violations.find((v) => v.reason !== "unpaired") ?? violations[0];
|
|
7930
|
+
if (!worst) return;
|
|
7931
|
+
const message = worst.reason === "prose-span" ? `Malformed math delimiters: a stray "$$" would have turned ${worst.spanLength} chars of prose into a math span (KaTeX would render it as red error text). Escaped it.` : worst.reason === "runaway-link" ? `Runaway markdown link: an unclosed "[" would have turned ${worst.spanLength} chars into one link label. Escaped it.` : `Malformed math delimiters: an unpaired "$$" reached the renderer.`;
|
|
7932
|
+
console.warn(`[markdown-delimiter-guard] ${message}`, {
|
|
7933
|
+
renderPath: context.renderPath,
|
|
7934
|
+
violations
|
|
7935
|
+
});
|
|
7936
|
+
context.capture?.({
|
|
7937
|
+
source: "markdown-delimiters",
|
|
7938
|
+
message,
|
|
7939
|
+
relation: `markdown:${context.renderPath}`,
|
|
7940
|
+
details: worst.preview,
|
|
7941
|
+
conversationId: context.conversationId,
|
|
7942
|
+
callSite: "guardMarkdownDelimiters",
|
|
7943
|
+
raw: { messageId: context.messageId, violations }
|
|
7944
|
+
});
|
|
7945
|
+
} catch {
|
|
7946
|
+
}
|
|
7947
|
+
}
|
|
7948
|
+
|
|
7949
|
+
// source/thinking.ts
|
|
7950
|
+
function codeRanges2(text, live) {
|
|
7951
|
+
const ranges = findCodeRanges(text).map((r) => [r.start, r.end]);
|
|
7952
|
+
if (live) {
|
|
7953
|
+
const pending = pendingCodeSpanStart(text);
|
|
7954
|
+
if (pending >= 0 && !inCode(ranges, pending)) ranges.push([pending, text.length]);
|
|
7955
|
+
}
|
|
7956
|
+
return ranges.sort((x, y) => x[0] - y[0]);
|
|
7957
|
+
}
|
|
7958
|
+
function inCode(ranges, index) {
|
|
7959
|
+
return ranges.some(([a, b]) => index >= a && index < b);
|
|
7960
|
+
}
|
|
7961
|
+
function collapseGaps(text) {
|
|
7962
|
+
const ranges = codeRanges2(text, false);
|
|
7963
|
+
let out = "";
|
|
7964
|
+
let at = 0;
|
|
7965
|
+
for (const [a, b] of ranges) {
|
|
7966
|
+
out += text.slice(at, a).replace(/\n{3,}/g, "\n\n") + text.slice(a, b);
|
|
7967
|
+
at = b;
|
|
7968
|
+
}
|
|
7969
|
+
return out + text.slice(at).replace(/\n{3,}/g, "\n\n");
|
|
7970
|
+
}
|
|
7971
|
+
var OPEN_TAG = /<(thinking|reasoning)\b[^>]*>/gi;
|
|
7972
|
+
function removeClosedBlocks(input, live) {
|
|
7973
|
+
let text = input;
|
|
7974
|
+
for (; ; ) {
|
|
7975
|
+
const ranges = codeRanges2(text, live);
|
|
7976
|
+
OPEN_TAG.lastIndex = 0;
|
|
7977
|
+
let opener = null;
|
|
7978
|
+
for (let m = OPEN_TAG.exec(text); m; m = OPEN_TAG.exec(text)) {
|
|
7979
|
+
if (!inCode(ranges, m.index)) {
|
|
7980
|
+
opener = m;
|
|
7981
|
+
break;
|
|
7982
|
+
}
|
|
7983
|
+
}
|
|
7984
|
+
if (!opener) return { text, openAt: -1 };
|
|
7985
|
+
const closeTag = new RegExp(`</${opener[1]}\\s*>`, "gi");
|
|
7986
|
+
closeTag.lastIndex = opener.index + opener[0].length;
|
|
7987
|
+
let closer = null;
|
|
7988
|
+
for (let m = closeTag.exec(text); m; m = closeTag.exec(text)) {
|
|
7989
|
+
if (!inCode(ranges, m.index)) {
|
|
7990
|
+
closer = m;
|
|
7991
|
+
break;
|
|
7992
|
+
}
|
|
7993
|
+
}
|
|
7994
|
+
if (!closer) return { text, openAt: opener.index };
|
|
7995
|
+
text = text.slice(0, opener.index) + text.slice(closer.index + closer[0].length);
|
|
7996
|
+
}
|
|
7997
|
+
}
|
|
7998
|
+
function stripThinking(input) {
|
|
7999
|
+
if (!input) return "";
|
|
8000
|
+
return collapseGaps(removeClosedBlocks(input, false).text).trim();
|
|
8001
|
+
}
|
|
8002
|
+
function hasThinkingTags(input) {
|
|
8003
|
+
if (!input) return false;
|
|
8004
|
+
return removeClosedBlocks(input, false).text !== input;
|
|
8005
|
+
}
|
|
8006
|
+
function stripThinkingStreaming(input) {
|
|
8007
|
+
if (!input) return { visible: "", isThinking: false };
|
|
8008
|
+
const { text, openAt } = removeClosedBlocks(input, true);
|
|
8009
|
+
const isThinking = openAt !== -1;
|
|
8010
|
+
const kept = isThinking ? text.slice(0, openAt) : text;
|
|
8011
|
+
return { visible: collapseGaps(kept).replace(/^\s+/, ""), isThinking };
|
|
8012
|
+
}
|
|
8013
|
+
|
|
8128
8014
|
// source/code-range-edits.ts
|
|
8129
8015
|
function unwrapCodeSpans(text) {
|
|
8130
8016
|
if (!text.includes("`")) return text;
|
|
@@ -8630,6 +8516,10 @@ exports.findWholeTableStart = findWholeTableStart;
|
|
|
8630
8516
|
exports.fingerprintText = fingerprintText;
|
|
8631
8517
|
exports.formatBlockLabel = formatBlockLabel;
|
|
8632
8518
|
exports.getParseSession = getParseSession;
|
|
8519
|
+
exports.guardMarkdownDelimiters = guardMarkdownDelimiters;
|
|
8520
|
+
exports.guardMathDelimiters = guardMathDelimiters;
|
|
8521
|
+
exports.guardRunawayLinks = guardRunawayLinks;
|
|
8522
|
+
exports.hasThinkingTags = hasThinkingTags;
|
|
8633
8523
|
exports.hasUnclosedBacktickRun = hasUnclosedBacktickRun;
|
|
8634
8524
|
exports.indexOutsideInlineCode = indexOutsideInlineCode;
|
|
8635
8525
|
exports.initialXmlBalance = initialXmlBalance;
|
|
@@ -8709,6 +8599,7 @@ exports.rehydrateNodeOutcome = rehydrateNodeOutcome;
|
|
|
8709
8599
|
exports.rehydrateRunResult = rehydrateRunResult;
|
|
8710
8600
|
exports.removeCodeSpans = removeCodeSpans;
|
|
8711
8601
|
exports.replaceFences = replaceFences;
|
|
8602
|
+
exports.reportDelimiterViolations = reportDelimiterViolations;
|
|
8712
8603
|
exports.resetLegacyShellUses = resetLegacyShellUses;
|
|
8713
8604
|
exports.resolveReferenceLinks = resolveReferenceLinks;
|
|
8714
8605
|
exports.resolvesInContent = resolvesInContent;
|
|
@@ -8735,6 +8626,8 @@ exports.startsPipelessTable = startsPipelessTable;
|
|
|
8735
8626
|
exports.storageToKindSchema = storageToKindSchema;
|
|
8736
8627
|
exports.stripControlKeys = stripControlKeys;
|
|
8737
8628
|
exports.stripKindDeep = stripKindDeep;
|
|
8629
|
+
exports.stripThinking = stripThinking;
|
|
8630
|
+
exports.stripThinkingStreaming = stripThinkingStreaming;
|
|
8738
8631
|
exports.tableContainerIndent = tableContainerIndent;
|
|
8739
8632
|
exports.tableStartsAt = tableStartsAt;
|
|
8740
8633
|
exports.titleCaseToken = titleCaseToken;
|