@ai-matrx/content-ir 0.22.6 → 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 +21 -0
- package/dist/convert.cjs +36 -292
- package/dist/convert.cjs.map +1 -1
- package/dist/convert.js +35 -291
- 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 +235 -311
- 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 +227 -310
- 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;
|
|
@@ -3296,7 +2992,7 @@ function buildAgentSchemaWithRenderBlockSupport(input, rootKindSlug, arrayBindin
|
|
|
3296
2992
|
}
|
|
3297
2993
|
function resolveRef(ref, ctx) {
|
|
3298
2994
|
if (ref === "#" || ref === "#/") {
|
|
3299
|
-
return { slug: ctx.schemaName, node: ctx.rootSchema };
|
|
2995
|
+
return { slug: ctx.schemaName, node: ctx.rootSchema, declaresKind: true };
|
|
3300
2996
|
}
|
|
3301
2997
|
const match = /^#\/(?:\$defs|definitions)\/(.+)$/.exec(ref);
|
|
3302
2998
|
if (!match) return null;
|
|
@@ -3306,7 +3002,11 @@ function resolveRef(ref, ctx) {
|
|
|
3306
3002
|
const node = ctx.defs[name];
|
|
3307
3003
|
if (!isRecord4(node)) return null;
|
|
3308
3004
|
const declared = isRecord4(node.properties) ? readBlockKindFromProperties(node.properties) : null;
|
|
3309
|
-
return { slug: declared ?? name, node };
|
|
3005
|
+
return { slug: declared ?? name, node, declaresKind: declared !== null };
|
|
3006
|
+
}
|
|
3007
|
+
function inlineRefNode(refNode, resolved) {
|
|
3008
|
+
const { $ref: _ref, ...beside } = refNode;
|
|
3009
|
+
return { ...resolved.node, ...beside };
|
|
3310
3010
|
}
|
|
3311
3011
|
function refToObjectField(resolved, path, ctx) {
|
|
3312
3012
|
if (ctx.refsInProgress.has(resolved.slug)) return;
|
|
@@ -3376,6 +3076,29 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
|
|
|
3376
3076
|
});
|
|
3377
3077
|
return null;
|
|
3378
3078
|
}
|
|
3079
|
+
if (!resolved.declaresKind) {
|
|
3080
|
+
const guard = `$def:${node.$ref}`;
|
|
3081
|
+
if (ctx.refsInProgress.has(guard)) {
|
|
3082
|
+
ctx.problems.push({
|
|
3083
|
+
severity: "info",
|
|
3084
|
+
path,
|
|
3085
|
+
message: `Self-referencing structure "${node.$ref}" \u2014 carried as any JSON value (json).`
|
|
3086
|
+
});
|
|
3087
|
+
return { ...requiredNullableFlags(required), type: "json" };
|
|
3088
|
+
}
|
|
3089
|
+
ctx.refsInProgress.add(guard);
|
|
3090
|
+
try {
|
|
3091
|
+
return convertPropertyCore(
|
|
3092
|
+
fieldName,
|
|
3093
|
+
inlineRefNode(node, resolved),
|
|
3094
|
+
required,
|
|
3095
|
+
path,
|
|
3096
|
+
ctx
|
|
3097
|
+
);
|
|
3098
|
+
} finally {
|
|
3099
|
+
ctx.refsInProgress.delete(guard);
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3379
3102
|
refToObjectField(resolved, path, ctx);
|
|
3380
3103
|
return {
|
|
3381
3104
|
...requiredNullableFlags(required),
|
|
@@ -3407,6 +3130,10 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
|
|
|
3407
3130
|
unsupported = true;
|
|
3408
3131
|
continue;
|
|
3409
3132
|
}
|
|
3133
|
+
if (!resolvedVariant.declaresKind) {
|
|
3134
|
+
anonymousObjects.push(inlineRefNode(variant, resolvedVariant));
|
|
3135
|
+
continue;
|
|
3136
|
+
}
|
|
3410
3137
|
refToObjectField(resolvedVariant, path, ctx);
|
|
3411
3138
|
memberKinds.push(resolvedVariant.slug);
|
|
3412
3139
|
continue;
|
|
@@ -5092,10 +4819,8 @@ function tryDecodeDirectiveContent(content, onError) {
|
|
|
5092
4819
|
}
|
|
5093
4820
|
return tryDecodeDirective(parsed, onError);
|
|
5094
4821
|
}
|
|
5095
|
-
|
|
5096
|
-
// directives/display.ts
|
|
5097
4822
|
function titleCaseToken(token) {
|
|
5098
|
-
return humanizeIdentifier(token) || token;
|
|
4823
|
+
return textCase.humanizeIdentifier(token) || token;
|
|
5099
4824
|
}
|
|
5100
4825
|
var ACTION_BY_CLASS = {
|
|
5101
4826
|
reference: "Reference",
|
|
@@ -8094,6 +7819,198 @@ function resolveReferenceLinks(fragment, defs) {
|
|
|
8094
7819
|
return resolved.replace(new RegExp(`${PLACEHOLDER}(\\d+)${PLACEHOLDER}`, "g"), (_m, i) => spans[Number(i)] ?? "");
|
|
8095
7820
|
}
|
|
8096
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
|
+
|
|
8097
8014
|
// source/code-range-edits.ts
|
|
8098
8015
|
function unwrapCodeSpans(text) {
|
|
8099
8016
|
if (!text.includes("`")) return text;
|
|
@@ -8599,6 +8516,10 @@ exports.findWholeTableStart = findWholeTableStart;
|
|
|
8599
8516
|
exports.fingerprintText = fingerprintText;
|
|
8600
8517
|
exports.formatBlockLabel = formatBlockLabel;
|
|
8601
8518
|
exports.getParseSession = getParseSession;
|
|
8519
|
+
exports.guardMarkdownDelimiters = guardMarkdownDelimiters;
|
|
8520
|
+
exports.guardMathDelimiters = guardMathDelimiters;
|
|
8521
|
+
exports.guardRunawayLinks = guardRunawayLinks;
|
|
8522
|
+
exports.hasThinkingTags = hasThinkingTags;
|
|
8602
8523
|
exports.hasUnclosedBacktickRun = hasUnclosedBacktickRun;
|
|
8603
8524
|
exports.indexOutsideInlineCode = indexOutsideInlineCode;
|
|
8604
8525
|
exports.initialXmlBalance = initialXmlBalance;
|
|
@@ -8678,6 +8599,7 @@ exports.rehydrateNodeOutcome = rehydrateNodeOutcome;
|
|
|
8678
8599
|
exports.rehydrateRunResult = rehydrateRunResult;
|
|
8679
8600
|
exports.removeCodeSpans = removeCodeSpans;
|
|
8680
8601
|
exports.replaceFences = replaceFences;
|
|
8602
|
+
exports.reportDelimiterViolations = reportDelimiterViolations;
|
|
8681
8603
|
exports.resetLegacyShellUses = resetLegacyShellUses;
|
|
8682
8604
|
exports.resolveReferenceLinks = resolveReferenceLinks;
|
|
8683
8605
|
exports.resolvesInContent = resolvesInContent;
|
|
@@ -8704,6 +8626,8 @@ exports.startsPipelessTable = startsPipelessTable;
|
|
|
8704
8626
|
exports.storageToKindSchema = storageToKindSchema;
|
|
8705
8627
|
exports.stripControlKeys = stripControlKeys;
|
|
8706
8628
|
exports.stripKindDeep = stripKindDeep;
|
|
8629
|
+
exports.stripThinking = stripThinking;
|
|
8630
|
+
exports.stripThinkingStreaming = stripThinkingStreaming;
|
|
8707
8631
|
exports.tableContainerIndent = tableContainerIndent;
|
|
8708
8632
|
exports.tableStartsAt = tableStartsAt;
|
|
8709
8633
|
exports.titleCaseToken = titleCaseToken;
|