@fulmenhq/tsfulmen 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/CHANGELOG.md +76 -1
  2. package/README.md +30 -1
  3. package/config/crucible-ts/taxonomy/metrics.yaml +1 -1
  4. package/dist/appidentity/index.js +9 -2209
  5. package/dist/appidentity/index.js.map +1 -1
  6. package/dist/assets/index.d.ts +184 -0
  7. package/dist/assets/index.js +4 -0
  8. package/dist/assets/index.js.map +1 -0
  9. package/dist/bin/prometheus-cli.js +15 -9139
  10. package/dist/bin/prometheus-cli.js.map +1 -1
  11. package/dist/bin/schema-cli.js +4 -6098
  12. package/dist/bin/schema-cli.js.map +1 -1
  13. package/dist/bin/signals-cli.js +15 -1910
  14. package/dist/bin/signals-cli.js.map +1 -1
  15. package/dist/chunk-24BAF63H.js +194 -0
  16. package/dist/chunk-24BAF63H.js.map +1 -0
  17. package/dist/chunk-3HISR2XI.js +36 -0
  18. package/dist/chunk-3HISR2XI.js.map +1 -0
  19. package/dist/chunk-56F2EEAG.js +328 -0
  20. package/dist/chunk-56F2EEAG.js.map +1 -0
  21. package/dist/chunk-5HZEJGZ5.js +725 -0
  22. package/dist/chunk-5HZEJGZ5.js.map +1 -0
  23. package/dist/chunk-7YWACZEJ.js +837 -0
  24. package/dist/chunk-7YWACZEJ.js.map +1 -0
  25. package/dist/chunk-BCO3FUUO.js +682 -0
  26. package/dist/chunk-BCO3FUUO.js.map +1 -0
  27. package/dist/chunk-GOTEQYAD.js +410 -0
  28. package/dist/chunk-GOTEQYAD.js.map +1 -0
  29. package/dist/chunk-HY6JQOFN.js +32 -0
  30. package/dist/chunk-HY6JQOFN.js.map +1 -0
  31. package/dist/chunk-LMNAUTW7.js +43 -0
  32. package/dist/chunk-LMNAUTW7.js.map +1 -0
  33. package/dist/chunk-LWAH2UG7.js +103 -0
  34. package/dist/chunk-LWAH2UG7.js.map +1 -0
  35. package/dist/chunk-OHE2AOH4.js +273 -0
  36. package/dist/chunk-OHE2AOH4.js.map +1 -0
  37. package/dist/chunk-P3DNOZOG.js +1488 -0
  38. package/dist/chunk-P3DNOZOG.js.map +1 -0
  39. package/dist/chunk-PQ6TKPUN.js +27 -0
  40. package/dist/chunk-PQ6TKPUN.js.map +1 -0
  41. package/dist/chunk-QCCN6POA.js +211 -0
  42. package/dist/chunk-QCCN6POA.js.map +1 -0
  43. package/dist/chunk-QGTNV4U2.js +985 -0
  44. package/dist/chunk-QGTNV4U2.js.map +1 -0
  45. package/dist/chunk-RSLFR4TO.js +631 -0
  46. package/dist/chunk-RSLFR4TO.js.map +1 -0
  47. package/dist/chunk-SNV5WG5V.js +9412 -0
  48. package/dist/chunk-SNV5WG5V.js.map +1 -0
  49. package/dist/chunk-UP2VWCW5.js +33 -0
  50. package/dist/chunk-UP2VWCW5.js.map +1 -0
  51. package/dist/chunk-VJIGX7MH.js +208 -0
  52. package/dist/chunk-VJIGX7MH.js.map +1 -0
  53. package/dist/chunk-WCCMRVZF.js +130 -0
  54. package/dist/chunk-WCCMRVZF.js.map +1 -0
  55. package/dist/chunk-WSMVLWLB.js +269 -0
  56. package/dist/chunk-WSMVLWLB.js.map +1 -0
  57. package/dist/config/index.js +6 -1220
  58. package/dist/config/index.js.map +1 -1
  59. package/dist/crucible/fulpack/index.js +2 -25
  60. package/dist/crucible/fulpack/index.js.map +1 -1
  61. package/dist/crucible/index.js +13 -1129
  62. package/dist/crucible/index.js.map +1 -1
  63. package/dist/docscribe/index.js +2 -680
  64. package/dist/docscribe/index.js.map +1 -1
  65. package/dist/errors/index.js +5 -1831
  66. package/dist/errors/index.js.map +1 -1
  67. package/dist/errors-D7KXV3QW.js +4 -0
  68. package/dist/errors-D7KXV3QW.js.map +1 -0
  69. package/dist/errors-R7ZODJXS.js +8 -0
  70. package/dist/errors-R7ZODJXS.js.map +1 -0
  71. package/dist/export-EA3RNQNS.js +6 -0
  72. package/dist/export-EA3RNQNS.js.map +1 -0
  73. package/dist/foundry/index.js +340 -3949
  74. package/dist/foundry/index.js.map +1 -1
  75. package/dist/foundry/similarity/index.js +3 -134
  76. package/dist/foundry/similarity/index.js.map +1 -1
  77. package/dist/fulencode/index.js +3 -319
  78. package/dist/fulencode/index.js.map +1 -1
  79. package/dist/fulhash/index.js +3 -611
  80. package/dist/fulhash/index.js.map +1 -1
  81. package/dist/fulpack/index.js +3 -1515
  82. package/dist/fulpack/index.js.map +1 -1
  83. package/dist/hash-YOJYVOWH.js +4 -0
  84. package/dist/hash-YOJYVOWH.js.map +1 -0
  85. package/dist/index.d.ts +1 -1
  86. package/dist/index.js +14 -4395
  87. package/dist/index.js.map +1 -1
  88. package/dist/loader-VP2ZIC4O.js +9 -0
  89. package/dist/loader-VP2ZIC4O.js.map +1 -0
  90. package/dist/logging/index.js +2 -723
  91. package/dist/logging/index.js.map +1 -1
  92. package/dist/pathfinder/index.js +18 -2341
  93. package/dist/pathfinder/index.js.map +1 -1
  94. package/dist/prom-client-PNEBGD3G.js +4801 -0
  95. package/dist/prom-client-PNEBGD3G.js.map +1 -0
  96. package/dist/reports/license-inventory.csv +1 -1
  97. package/dist/schema/index.d.ts +19 -6
  98. package/dist/schema/index.js +4 -6148
  99. package/dist/schema/index.js.map +1 -1
  100. package/dist/signals/index.js +8 -2767
  101. package/dist/signals/index.js.map +1 -1
  102. package/dist/similarity/index.js +3 -134
  103. package/dist/similarity/index.js.map +1 -1
  104. package/dist/telemetry/http/index.js +9 -930
  105. package/dist/telemetry/http/index.js.map +1 -1
  106. package/dist/telemetry/index.js +4 -1561
  107. package/dist/telemetry/index.js.map +1 -1
  108. package/dist/telemetry/prometheus/index.js +7 -8422
  109. package/dist/telemetry/prometheus/index.js.map +1 -1
  110. package/dist/validator-I3ASDVDB.js +6 -0
  111. package/dist/validator-I3ASDVDB.js.map +1 -0
  112. package/package.json +5 -1
  113. package/schemas/crucible-ts/library/module-manifest/v1.0.0/module-manifest.schema.json +1 -1
  114. package/schemas/crucible-ts/observability/logging/v1.0.0/definitions.schema.json +1 -1
  115. package/schemas/crucible-ts/observability/logging/v1.0.0/log-event.schema.json +13 -13
  116. package/schemas/crucible-ts/observability/logging/v1.0.0/logger-config.schema.json +2 -2
  117. package/schemas/crucible-ts/observability/logging/v1.0.0/logging-policy.schema.json +1 -1
  118. package/schemas/crucible-ts/observability/logging/v1.0.0/middleware-config.schema.json +2 -2
  119. package/schemas/crucible-ts/observability/logging/v1.0.0/severity-filter.schema.json +3 -3
  120. package/schemas/crucible-ts/upstream/3leaps/crucible/PROVENANCE.md +3 -3
  121. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/catalog/classifiers/README.md +1 -1
  122. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/classifiers-framework.md +1 -1
  123. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/data-sensitivity-classification.md +1 -1
@@ -0,0 +1,682 @@
1
+ import { parseDocument } from 'yaml';
2
+
3
+ // src/docscribe/frontmatter.ts
4
+
5
+ // src/docscribe/normalize.ts
6
+ var decoder = new TextDecoder("utf-8", { fatal: false, ignoreBOM: true });
7
+ function stripBom(value) {
8
+ return value.charCodeAt(0) === 65279 ? value.slice(1) : value;
9
+ }
10
+ function normalizeNewlines(value) {
11
+ return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
12
+ }
13
+ function normalizeInput(input) {
14
+ let content;
15
+ if (typeof input === "string") {
16
+ content = input;
17
+ } else if (input instanceof Uint8Array) {
18
+ content = decoder.decode(input);
19
+ } else {
20
+ content = decoder.decode(new Uint8Array(input));
21
+ }
22
+ const normalized = normalizeNewlines(stripBom(content));
23
+ return { content: normalized, original: input };
24
+ }
25
+
26
+ // src/docscribe/types.ts
27
+ var DocScribeError = class extends Error {
28
+ constructor(message, options) {
29
+ super(message, options);
30
+ Object.setPrototypeOf(this, new.target.prototype);
31
+ this.name = "DocScribeError";
32
+ }
33
+ };
34
+ var DocScribeParseError = class extends DocScribeError {
35
+ constructor(message, options) {
36
+ super(message, options);
37
+ Object.setPrototypeOf(this, new.target.prototype);
38
+ this.name = "DocScribeParseError";
39
+ }
40
+ };
41
+ var DocScribeUnsupportedFormatError = class extends DocScribeError {
42
+ constructor(message, options) {
43
+ super(message, options);
44
+ Object.setPrototypeOf(this, new.target.prototype);
45
+ this.name = "DocScribeUnsupportedFormatError";
46
+ }
47
+ };
48
+
49
+ // src/docscribe/frontmatter.ts
50
+ var FRONTMATTER_DELIMITER = "---";
51
+ var STRING_KEYS = /* @__PURE__ */ new Set([
52
+ "title",
53
+ "description",
54
+ "author",
55
+ "date",
56
+ "lastUpdated",
57
+ "status",
58
+ "version"
59
+ ]);
60
+ function parseFrontmatter(input) {
61
+ const { content } = normalizeInput(input);
62
+ const bounds = locateFrontmatter(content);
63
+ if (!bounds) {
64
+ return { metadata: null, body: content, range: null, bodyStartLine: 1 };
65
+ }
66
+ const yamlBlock = content.slice(bounds.openEnd, bounds.closingStart);
67
+ const metadata = yamlBlock.trim().length === 0 ? {} : parseYamlMetadata(yamlBlock);
68
+ const bodyRaw = content.slice(bounds.closingEnd);
69
+ const leadingNewlinesMatch = bodyRaw.match(/^\n+/);
70
+ const leadingNewlinesLength = leadingNewlinesMatch ? leadingNewlinesMatch[0].length : 0;
71
+ const bodyStartIndex = bounds.closingEnd + leadingNewlinesLength;
72
+ const prefix = content.slice(0, bodyStartIndex);
73
+ const bodyStartLine = prefix.length === 0 ? 1 : prefix.split("\n").length;
74
+ const body = bodyRaw.slice(leadingNewlinesLength);
75
+ return {
76
+ metadata,
77
+ body,
78
+ range: { start: bounds.start, end: bounds.closingEnd },
79
+ bodyStartLine
80
+ };
81
+ }
82
+ function stripFrontmatter(input) {
83
+ return parseFrontmatter(input).body;
84
+ }
85
+ function extractMetadata(input) {
86
+ return parseFrontmatter(input).metadata;
87
+ }
88
+ function locateFrontmatter(content) {
89
+ let cursor = 0;
90
+ while (cursor < content.length) {
91
+ const newlineIndex = content.indexOf("\n", cursor);
92
+ const lineEnd = newlineIndex === -1 ? content.length : newlineIndex;
93
+ const line = content.slice(cursor, lineEnd);
94
+ if (line.trim().length === 0) {
95
+ if (newlineIndex === -1) {
96
+ return null;
97
+ }
98
+ cursor = newlineIndex + 1;
99
+ continue;
100
+ }
101
+ if (line.trim() !== FRONTMATTER_DELIMITER) {
102
+ return null;
103
+ }
104
+ const openStart = cursor;
105
+ const openEnd = newlineIndex === -1 ? content.length : newlineIndex + 1;
106
+ let search = openEnd;
107
+ while (search <= content.length) {
108
+ const nextNewline = content.indexOf("\n", search);
109
+ const segmentEnd = nextNewline === -1 ? content.length : nextNewline;
110
+ const candidate = content.slice(search, segmentEnd).trim();
111
+ if (candidate === FRONTMATTER_DELIMITER) {
112
+ const closingStart = search;
113
+ const closingEnd = nextNewline === -1 ? segmentEnd : nextNewline + 1;
114
+ return {
115
+ start: openStart,
116
+ openEnd,
117
+ closingStart,
118
+ closingEnd
119
+ };
120
+ }
121
+ if (nextNewline === -1) {
122
+ break;
123
+ }
124
+ search = nextNewline + 1;
125
+ }
126
+ return null;
127
+ }
128
+ return null;
129
+ }
130
+ function parseYamlMetadata(source) {
131
+ const document = parseDocument(source, { prettyErrors: true });
132
+ if (document.errors.length > 0) {
133
+ const error = document.errors[0];
134
+ const location = error.linePos && error.linePos.length > 0 ? error.linePos[0] : null;
135
+ const position = location ? ` (line ${location.line + 1}, column ${location.col + 1})` : "";
136
+ throw new DocScribeParseError(`Invalid YAML frontmatter${position}: ${error.message}`, {
137
+ cause: error
138
+ });
139
+ }
140
+ let raw;
141
+ try {
142
+ raw = document.toJS({ mapAsMap: false });
143
+ } catch (error) {
144
+ throw new DocScribeParseError("Failed to parse YAML frontmatter", {
145
+ cause: error instanceof Error ? error : void 0
146
+ });
147
+ }
148
+ if (raw == null) {
149
+ return {};
150
+ }
151
+ if (typeof raw !== "object" || Array.isArray(raw)) {
152
+ throw new DocScribeParseError("YAML frontmatter must be a mapping at the top level");
153
+ }
154
+ return normalizeMetadata(raw);
155
+ }
156
+ function normalizeMetadata(raw) {
157
+ const normalized = {};
158
+ for (const [key, value] of Object.entries(raw)) {
159
+ normalized[key] = normalizeMetadataValue(value);
160
+ }
161
+ const base = {};
162
+ for (const [key, value] of Object.entries(normalized)) {
163
+ if (STRING_KEYS.has(key) || key === "tags" || key === "relatedDocs") {
164
+ continue;
165
+ }
166
+ base[key] = value;
167
+ }
168
+ const metadata = {
169
+ ...base,
170
+ ...normalized.title !== void 0 ? { title: ensureStringValue(normalized.title) } : {},
171
+ ...normalized.description !== void 0 ? { description: ensureStringValue(normalized.description) } : {},
172
+ ...normalized.author !== void 0 ? { author: ensureStringValue(normalized.author) } : {},
173
+ ...normalized.date !== void 0 ? { date: ensureStringValue(normalized.date) } : {},
174
+ ...normalized.lastUpdated !== void 0 ? { lastUpdated: ensureStringValue(normalized.lastUpdated) } : {},
175
+ ...normalized.status !== void 0 ? { status: ensureStringValue(normalized.status) } : {},
176
+ ...normalized.version !== void 0 ? { version: ensureStringValue(normalized.version) } : {},
177
+ ...normalized.tags !== void 0 ? (() => {
178
+ const tags = ensureStringArray(normalized.tags);
179
+ return tags.length > 0 ? { tags } : {};
180
+ })() : {},
181
+ ...normalized.relatedDocs !== void 0 ? (() => {
182
+ const related = ensureStringArray(normalized.relatedDocs);
183
+ return related.length > 0 ? { relatedDocs: related } : {};
184
+ })() : {}
185
+ };
186
+ return metadata;
187
+ }
188
+ function normalizeMetadataValue(value) {
189
+ if (value === null) {
190
+ return null;
191
+ }
192
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
193
+ return value;
194
+ }
195
+ if (value instanceof Date) {
196
+ return value.toISOString();
197
+ }
198
+ if (Array.isArray(value)) {
199
+ return value.map(
200
+ (item) => normalizeMetadataValue(item)
201
+ );
202
+ }
203
+ if (typeof value === "object") {
204
+ const result = {};
205
+ for (const [key, nested] of Object.entries(value)) {
206
+ result[key] = normalizeMetadataValue(nested);
207
+ }
208
+ return result;
209
+ }
210
+ return String(value);
211
+ }
212
+ function ensureStringValue(value) {
213
+ if (value === null) {
214
+ return "";
215
+ }
216
+ if (typeof value === "string") {
217
+ return value;
218
+ }
219
+ if (typeof value === "number" || typeof value === "boolean") {
220
+ return String(value);
221
+ }
222
+ if (Array.isArray(value)) {
223
+ return value.flatMap((item) => ensureStringArrayItem(item)).join(", ");
224
+ }
225
+ return JSON.stringify(value);
226
+ }
227
+ function ensureStringArray(value) {
228
+ return ensureStringArrayItem(value);
229
+ }
230
+ function ensureStringArrayItem(value) {
231
+ if (value === null) {
232
+ return [];
233
+ }
234
+ if (typeof value === "string") {
235
+ return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
236
+ }
237
+ if (typeof value === "number" || typeof value === "boolean") {
238
+ return [String(value)];
239
+ }
240
+ if (Array.isArray(value)) {
241
+ return value.flatMap((item) => ensureStringArrayItem(item));
242
+ }
243
+ return [JSON.stringify(value)];
244
+ }
245
+
246
+ // src/docscribe/headers.ts
247
+ var ATX_PATTERN = /^ {0,3}(#{1,6})(?:[ \t]+|$)(.*)$/;
248
+ var SETEXT_PATTERN = /^ {0,3}(=+|-+)\s*$/;
249
+ function extractHeaders(input, options) {
250
+ const { content } = normalizeInput(input);
251
+ const parsed = parseFrontmatter(content);
252
+ const body = parsed.body;
253
+ const lineOffset = parsed.bodyStartLine;
254
+ const slugify = options?.slugify ?? defaultSlugify;
255
+ const maxDepth = options?.maxDepth ?? 6;
256
+ const lines = body.split("\n");
257
+ const headers = [];
258
+ let inFence = false;
259
+ let fenceMarker = null;
260
+ for (let index = 0; index < lines.length; index += 1) {
261
+ const line = lines[index];
262
+ const trimmed = line.trimEnd();
263
+ const lineNumber = lineOffset + index;
264
+ const fenceMatch = line.match(/^ {0,3}(```+|~~~+)/);
265
+ if (fenceMatch) {
266
+ const marker = fenceMatch[1][0];
267
+ if (!inFence) {
268
+ inFence = true;
269
+ fenceMarker = marker;
270
+ } else if (fenceMarker === marker) {
271
+ inFence = false;
272
+ fenceMarker = null;
273
+ }
274
+ continue;
275
+ }
276
+ if (inFence) {
277
+ continue;
278
+ }
279
+ if (/^( {4}|\t)/.test(line)) {
280
+ continue;
281
+ }
282
+ const atxMatch = trimmed.match(ATX_PATTERN);
283
+ if (atxMatch) {
284
+ const level = atxMatch[1].length;
285
+ if (level <= maxDepth) {
286
+ const rawText = atxMatch[2].replace(/#+\s*$/, "").trim();
287
+ const text = rawText.length > 0 ? rawText : "";
288
+ const slug = ensureSlug(slugify, text, lineNumber);
289
+ headers.push({ level, text, slug, line: lineNumber });
290
+ }
291
+ continue;
292
+ }
293
+ if (trimmed.length === 0) {
294
+ continue;
295
+ }
296
+ if (index + 1 >= lines.length) {
297
+ continue;
298
+ }
299
+ const nextLine = lines[index + 1];
300
+ const setextMatch = SETEXT_PATTERN.exec(nextLine.trimEnd());
301
+ if (setextMatch) {
302
+ const underline = setextMatch[1];
303
+ const level = underline.startsWith("=") ? 1 : 2;
304
+ if (level <= maxDepth) {
305
+ const text = trimmed.trim();
306
+ if (text.length > 0 && !/^ {0,3}(```|~~~)/.test(text)) {
307
+ const slug = ensureSlug(slugify, text, lineNumber);
308
+ headers.push({ level, text, slug, line: lineNumber });
309
+ }
310
+ }
311
+ index += 1;
312
+ }
313
+ }
314
+ return headers;
315
+ }
316
+ function defaultSlugify(value) {
317
+ return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9\s-]/g, "").trim().replace(/\s+/g, "-").replace(/-+/g, "-");
318
+ }
319
+ function ensureSlug(slugify, text, lineNumber) {
320
+ const candidate = slugify(text);
321
+ if (candidate && candidate.trim().length > 0) {
322
+ return candidate;
323
+ }
324
+ return `section-${lineNumber}`;
325
+ }
326
+
327
+ // src/docscribe/format.ts
328
+ var JSON_PATTERN = /^[\s\t]*[[{]/;
329
+ var TOML_ASSIGNMENT = /^[A-Za-z0-9_"'\-.]+\s*=\s*.+$/;
330
+ var TOML_TABLE = /^\s*\[[^\]]+\]\s*$/;
331
+ var YAML_KEY_PATTERN = /^\s*[\w"'-]+\s*:\s*.+$/;
332
+ var MARKDOWN_HEADING = /(\n|^)\s{0,3}#{1,6}\s+/;
333
+ var MARKDOWN_LIST = /(\n|^)\s{0,3}(?:-|\*|\+)\s+/;
334
+ var MARKDOWN_SETEXT = /(\n|^).+\n\s{0,3}(?:=+|-+)\s*(\n|$)/;
335
+ function detectFormat(input) {
336
+ const { content } = normalizeInput(input);
337
+ return detectFormatFromContent(content);
338
+ }
339
+ function inspectDocument(input, options) {
340
+ const { content } = normalizeInput(input);
341
+ const format = detectFormatFromContent(content);
342
+ const frontmatter = parseFrontmatter(content);
343
+ const headers = extractHeaders(content, options);
344
+ const headerCount = headers.length;
345
+ const estimatedSections = headerCount > 0 ? headerCount : frontmatter.body.trim().length > 0 ? 1 : 0;
346
+ const lineCount = content.length === 0 ? 0 : content.split("\n").length;
347
+ const size = content.length;
348
+ return {
349
+ format,
350
+ hasFrontmatter: frontmatter.metadata !== null,
351
+ frontmatterRange: frontmatter.range,
352
+ metadata: frontmatter.metadata,
353
+ headerCount,
354
+ estimatedSections,
355
+ bodyStartLine: frontmatter.bodyStartLine,
356
+ lineCount,
357
+ size,
358
+ headers
359
+ };
360
+ }
361
+ function detectFormatFromContent(content) {
362
+ const trimmed = content.trim();
363
+ if (trimmed.length === 0) {
364
+ return "plain";
365
+ }
366
+ if (looksLikeJson(trimmed)) {
367
+ return "json";
368
+ }
369
+ if (looksLikeToml(trimmed)) {
370
+ return "toml";
371
+ }
372
+ const yamlSeparatorCount = countYamlSeparators(content);
373
+ if (yamlSeparatorCount >= 1 && isLikelyYamlStream(content)) {
374
+ return "yaml-stream";
375
+ }
376
+ const markdownIndicators = hasMarkdownIndicators(content);
377
+ if (looksLikeYaml(trimmed) && !markdownIndicators) {
378
+ return "yaml";
379
+ }
380
+ const frontmatter = parseFrontmatter(content);
381
+ if (frontmatter.metadata !== null) {
382
+ const body = frontmatter.body.trim();
383
+ if (markdownIndicators || MARKDOWN_HEADING.test(body) || MARKDOWN_LIST.test(body)) {
384
+ return "markdown";
385
+ }
386
+ if (!body) {
387
+ return "markdown";
388
+ }
389
+ }
390
+ if (markdownIndicators) {
391
+ return "markdown";
392
+ }
393
+ return "plain";
394
+ }
395
+ function looksLikeJson(trimmed) {
396
+ if (!JSON_PATTERN.test(trimmed)) {
397
+ return false;
398
+ }
399
+ try {
400
+ JSON.parse(trimmed);
401
+ return true;
402
+ } catch (_error) {
403
+ return false;
404
+ }
405
+ }
406
+ function looksLikeToml(content) {
407
+ const lines = content.split("\n");
408
+ let tableCount = 0;
409
+ let assignmentCount = 0;
410
+ for (const rawLine of lines) {
411
+ const line = rawLine.trim();
412
+ if (line === "" || line.startsWith("#")) {
413
+ continue;
414
+ }
415
+ if (TOML_TABLE.test(line)) {
416
+ tableCount += 1;
417
+ continue;
418
+ }
419
+ if (TOML_ASSIGNMENT.test(line)) {
420
+ assignmentCount += 1;
421
+ }
422
+ }
423
+ return tableCount > 0 || assignmentCount >= 3;
424
+ }
425
+ function looksLikeYaml(trimmed) {
426
+ if (trimmed.startsWith("%YAML")) {
427
+ return true;
428
+ }
429
+ const lines = trimmed.split("\n");
430
+ let signal = 0;
431
+ for (const raw of lines.slice(0, 20)) {
432
+ const line = raw.trim();
433
+ if (line === "" || line.startsWith("#")) {
434
+ continue;
435
+ }
436
+ if (line === "---") {
437
+ signal += 1;
438
+ continue;
439
+ }
440
+ if (YAML_KEY_PATTERN.test(line) || /^-\s/.test(line)) {
441
+ signal += 1;
442
+ }
443
+ }
444
+ return signal >= 2;
445
+ }
446
+ function countYamlSeparators(content) {
447
+ const matches = content.match(/(^|\n)---\s*(\n|$)/g);
448
+ return matches ? matches.length : 0;
449
+ }
450
+ function isLikelyYamlStream(content) {
451
+ const lines = content.split("\n");
452
+ let yamlSignals = 0;
453
+ let markdownSignals = 0;
454
+ for (const rawLine of lines) {
455
+ const line = rawLine.trim();
456
+ if (line === "" || line === "---") {
457
+ continue;
458
+ }
459
+ if (/^#/.test(line) || /^\s{0,3}(?:-|\*|\+)\s+/.test(line) || /(\[[^\]]+\]\([^)]+\))/.test(line)) {
460
+ markdownSignals += 1;
461
+ }
462
+ if (/:\s/.test(line) || /^-\s/.test(line)) {
463
+ yamlSignals += 1;
464
+ }
465
+ }
466
+ return yamlSignals >= 2 && markdownSignals === 0;
467
+ }
468
+ function hasMarkdownIndicators(content) {
469
+ return MARKDOWN_HEADING.test(content) || MARKDOWN_LIST.test(content) || MARKDOWN_SETEXT.test(content) || /(\n|^)\s{0,3}>\s+/.test(content) || /(\[[^\]]+\]\([^)]+\))/.test(content);
470
+ }
471
+ var __internal = {
472
+ detectFormatFromContent,
473
+ looksLikeJson,
474
+ looksLikeToml,
475
+ looksLikeYaml,
476
+ isLikelyYamlStream
477
+ };
478
+
479
+ // src/docscribe/split.ts
480
+ function splitDocuments(input, options) {
481
+ const { content } = normalizeInput(input);
482
+ const trimmed = content.trim();
483
+ if (trimmed.length === 0) {
484
+ return [];
485
+ }
486
+ const maxDocuments = options?.maxDocuments ?? Number.POSITIVE_INFINITY;
487
+ const format = detectFormat(content);
488
+ let splits;
489
+ if (format === "yaml-stream") {
490
+ splits = withIndices(splitYamlStream(content));
491
+ } else if (format === "markdown") {
492
+ const markdownSplits = splitMarkdownDocuments(content);
493
+ splits = markdownSplits.length > 0 ? withIndices(markdownSplits) : [withIndex(buildSingleSplit(content, format, 1), 0)];
494
+ } else {
495
+ splits = [withIndex(buildSingleSplit(content, format, 1), 0)];
496
+ }
497
+ return applyDocumentLimit(splits, maxDocuments);
498
+ }
499
+ function splitYamlStream(content) {
500
+ const lines = content.split("\n");
501
+ const docs = [];
502
+ let current = { lines: [], startLine: 1 };
503
+ let delimiterCount = 0;
504
+ const flush = () => {
505
+ if (current.lines.join("\n").trim().length === 0) {
506
+ current = { lines: [], startLine: current.startLine };
507
+ return;
508
+ }
509
+ docs.push({ ...current, lines: [...current.lines] });
510
+ current = { lines: [], startLine: current.startLine };
511
+ };
512
+ for (let index = 0; index < lines.length; index += 1) {
513
+ const lineNumber = index + 1;
514
+ const line = lines[index];
515
+ const trimmed = line.trim();
516
+ if (trimmed === "---") {
517
+ delimiterCount += 1;
518
+ flush();
519
+ current = { lines: [], startLine: lineNumber + 1 };
520
+ continue;
521
+ }
522
+ if (delimiterCount === 0) {
523
+ current.startLine = 1;
524
+ }
525
+ current.lines.push(line);
526
+ }
527
+ flush();
528
+ if (docs.length === 0) {
529
+ return [buildRawSplit(content, "yaml", null, 1, content.split("\n").length)];
530
+ }
531
+ return docs.map((doc) => {
532
+ const joined = doc.lines.join("\n");
533
+ const lineCount = doc.lines.length;
534
+ return buildRawSplit(
535
+ joined,
536
+ "yaml",
537
+ null,
538
+ doc.startLine,
539
+ doc.startLine + Math.max(lineCount - 1, 0)
540
+ );
541
+ }).filter((split) => split.content.trim().length > 0);
542
+ }
543
+ function splitMarkdownDocuments(content) {
544
+ const frontmatter = parseFrontmatter(content);
545
+ const lines = content.split("\n");
546
+ const docs = [];
547
+ const frontmatterLimit = frontmatter.metadata ? Math.max(frontmatter.bodyStartLine - 1, 0) : 0;
548
+ let current = { lines: [], startLine: 1 };
549
+ let inFence = false;
550
+ let fenceMarker = null;
551
+ const flush = () => {
552
+ if (current.lines.join("\n").trim().length === 0) {
553
+ current = { lines: [], startLine: current.startLine };
554
+ return;
555
+ }
556
+ docs.push({ ...current, lines: [...current.lines] });
557
+ current = { lines: [], startLine: current.startLine };
558
+ };
559
+ for (let index = 0; index < lines.length; index += 1) {
560
+ const lineNumber = index + 1;
561
+ const line = lines[index];
562
+ const trimmed = line.trimEnd();
563
+ const fenceMatch = line.match(/^ {0,3}(```+|~~~+)/);
564
+ if (fenceMatch) {
565
+ const marker = fenceMatch[1][0];
566
+ if (!inFence) {
567
+ inFence = true;
568
+ fenceMarker = marker;
569
+ } else if (fenceMarker === marker) {
570
+ inFence = false;
571
+ fenceMarker = null;
572
+ }
573
+ }
574
+ const isPrimaryFrontmatter = frontmatterLimit > 0 && lineNumber <= frontmatterLimit;
575
+ if (!inFence && !isPrimaryFrontmatter && trimmed === "---") {
576
+ const prev = findPrevNonEmpty(lines, index - 1);
577
+ const next = findNextNonEmpty(lines, index + 1);
578
+ const prevLooksLikeMetadata = prev ? /:\s*/.test(prev.line) : false;
579
+ const nextIsHeading = next ? next.line.trim().startsWith("#") : false;
580
+ if (next && !prevLooksLikeMetadata && nextIsHeading) {
581
+ flush();
582
+ current = { lines: [], startLine: next.lineNumber };
583
+ continue;
584
+ }
585
+ }
586
+ current.lines.push(line);
587
+ }
588
+ flush();
589
+ return docs.map((doc) => {
590
+ const contentValue = doc.lines.join("\n");
591
+ const parsed = parseFrontmatter(contentValue);
592
+ const lineCount = doc.lines.length;
593
+ return buildRawSplit(
594
+ contentValue,
595
+ "markdown",
596
+ parsed.metadata,
597
+ doc.startLine,
598
+ doc.startLine + Math.max(lineCount - 1, 0),
599
+ parsed.metadata !== null
600
+ );
601
+ }).filter((split) => split.content.trim().length > 0);
602
+ }
603
+ function buildSingleSplit(content, format, startLine) {
604
+ const parsed = parseFrontmatter(content);
605
+ const lineCount = content.length === 0 ? 0 : content.split("\n").length;
606
+ return buildRawSplit(
607
+ content,
608
+ format,
609
+ parsed.metadata,
610
+ startLine,
611
+ startLine + Math.max(lineCount - 1, 0),
612
+ parsed.metadata !== null
613
+ );
614
+ }
615
+ function buildRawSplit(content, format, metadata, startLine, endLine, hasFrontmatter = false) {
616
+ return {
617
+ content,
618
+ format,
619
+ hasFrontmatter,
620
+ metadata: metadata ?? null,
621
+ startLine,
622
+ endLine
623
+ };
624
+ }
625
+ function applyDocumentLimit(splits, maxDocuments) {
626
+ if (maxDocuments <= 0) {
627
+ return [];
628
+ }
629
+ if (splits.length <= maxDocuments) {
630
+ return splits.map((split, idx) => ({ ...split, index: idx }));
631
+ }
632
+ const cutoff = Math.max(maxDocuments - 1, 0);
633
+ const allowed = splits.slice(0, cutoff);
634
+ const remaining = splits.slice(cutoff);
635
+ const merged = mergeSplitGroup(remaining);
636
+ const combined = cutoff === 0 ? [merged] : [...allowed, merged];
637
+ return combined.map((split, idx) => ({ ...split, index: idx }));
638
+ }
639
+ function mergeSplitGroup(splits) {
640
+ const first = splits[0];
641
+ const last = splits[splits.length - 1];
642
+ const combinedContent = splits.map((split) => split.content).join("\n---\n");
643
+ return {
644
+ content: combinedContent,
645
+ format: first.format,
646
+ hasFrontmatter: first.hasFrontmatter,
647
+ metadata: first.metadata,
648
+ startLine: first.startLine,
649
+ endLine: last.endLine,
650
+ index: 0
651
+ };
652
+ }
653
+ function withIndices(rawSplits) {
654
+ return rawSplits.map((split, idx) => withIndex(split, idx));
655
+ }
656
+ function withIndex(split, index) {
657
+ return { ...split, index };
658
+ }
659
+ function findNextNonEmpty(lines, startIndex) {
660
+ for (let index = startIndex; index < lines.length; index += 1) {
661
+ const candidate = lines[index];
662
+ if (candidate.trim().length === 0) {
663
+ continue;
664
+ }
665
+ return { line: candidate, lineNumber: index + 1 };
666
+ }
667
+ return null;
668
+ }
669
+ function findPrevNonEmpty(lines, startIndex) {
670
+ for (let index = startIndex; index >= 0; index -= 1) {
671
+ const candidate = lines[index];
672
+ if (candidate.trim().length === 0) {
673
+ continue;
674
+ }
675
+ return { line: candidate, lineNumber: index + 1 };
676
+ }
677
+ return null;
678
+ }
679
+
680
+ export { DocScribeError, DocScribeParseError, DocScribeUnsupportedFormatError, __internal, detectFormat, extractHeaders, extractMetadata, inspectDocument, normalizeInput, parseFrontmatter, splitDocuments, stripFrontmatter };
681
+ //# sourceMappingURL=chunk-BCO3FUUO.js.map
682
+ //# sourceMappingURL=chunk-BCO3FUUO.js.map