kirograph 0.15.0 → 0.16.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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -1
  3. package/dist/bin/commands/docs.js +357 -0
  4. package/dist/bin/commands/docs.js.map +7 -0
  5. package/dist/bin/installer/config-prompt.js +17 -1
  6. package/dist/bin/installer/config-prompt.js.map +2 -2
  7. package/dist/bin/installer/index.js +6 -1
  8. package/dist/bin/installer/index.js.map +2 -2
  9. package/dist/bin/installer/steering.js +21 -0
  10. package/dist/bin/installer/steering.js.map +2 -2
  11. package/dist/bin/installer/targets/index.js.map +1 -1
  12. package/dist/bin/installer/targets/kiro.js +2 -2
  13. package/dist/bin/installer/targets/kiro.js.map +2 -2
  14. package/dist/bin/kirograph.js +3 -1
  15. package/dist/bin/kirograph.js.map +3 -3
  16. package/dist/compression/naive-cost.js +19 -0
  17. package/dist/compression/naive-cost.js.map +2 -2
  18. package/dist/compression/tracker.js +11 -2
  19. package/dist/compression/tracker.js.map +2 -2
  20. package/dist/compression/types.js.map +1 -1
  21. package/dist/config.js +34 -1
  22. package/dist/config.js.map +2 -2
  23. package/dist/core/pipeline.js +23 -0
  24. package/dist/core/pipeline.js.map +2 -2
  25. package/dist/db/database.js +11 -0
  26. package/dist/db/database.js.map +2 -2
  27. package/dist/db/docs-schema.sql +50 -0
  28. package/dist/docs/formats/asciidoc.js +108 -0
  29. package/dist/docs/formats/asciidoc.js.map +7 -0
  30. package/dist/docs/formats/html.js +100 -0
  31. package/dist/docs/formats/html.js.map +7 -0
  32. package/dist/docs/formats/index.js +81 -0
  33. package/dist/docs/formats/index.js.map +7 -0
  34. package/dist/docs/formats/markdown.js +146 -0
  35. package/dist/docs/formats/markdown.js.map +7 -0
  36. package/dist/docs/formats/openapi.js +228 -0
  37. package/dist/docs/formats/openapi.js.map +7 -0
  38. package/dist/docs/formats/org.js +117 -0
  39. package/dist/docs/formats/org.js.map +7 -0
  40. package/dist/docs/formats/plaintext.js +119 -0
  41. package/dist/docs/formats/plaintext.js.map +7 -0
  42. package/dist/docs/formats/rdoc.js +105 -0
  43. package/dist/docs/formats/rdoc.js.map +7 -0
  44. package/dist/docs/formats/rst.js +121 -0
  45. package/dist/docs/formats/rst.js.map +7 -0
  46. package/dist/docs/indexer.js +340 -0
  47. package/dist/docs/indexer.js.map +7 -0
  48. package/dist/docs/linker.js +151 -0
  49. package/dist/docs/linker.js.map +7 -0
  50. package/dist/docs/lint.js +92 -0
  51. package/dist/docs/lint.js.map +7 -0
  52. package/dist/docs/queries.js +295 -0
  53. package/dist/docs/queries.js.map +7 -0
  54. package/dist/docs/section-id.js +57 -0
  55. package/dist/docs/section-id.js.map +7 -0
  56. package/dist/docs/summarizer.js +55 -0
  57. package/dist/docs/summarizer.js.map +7 -0
  58. package/dist/docs/types.js +17 -0
  59. package/dist/docs/types.js.map +7 -0
  60. package/dist/docs/vectors.js +217 -0
  61. package/dist/docs/vectors.js.map +7 -0
  62. package/dist/mcp/tool-names.js +6 -1
  63. package/dist/mcp/tool-names.js.map +2 -2
  64. package/dist/mcp/tools.js +245 -1
  65. package/dist/mcp/tools.js.map +2 -2
  66. package/package.json +1 -1
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var plaintext_exports = {};
20
+ __export(plaintext_exports, {
21
+ plaintextParser: () => plaintextParser
22
+ });
23
+ module.exports = __toCommonJS(plaintext_exports);
24
+ function isAllCaps(line) {
25
+ const trimmed = line.trim();
26
+ if (trimmed.length < 3) return false;
27
+ return /[A-Z]/.test(trimmed) && trimmed === trimmed.toUpperCase() && /^[A-Z\s\d\-_:]+$/.test(trimmed);
28
+ }
29
+ function isDashUnderline(line) {
30
+ const trimmed = line.trim();
31
+ return trimmed.length >= 3 && /^[-=~]+$/.test(trimmed);
32
+ }
33
+ function extractHeadings(content) {
34
+ const lines = content.split("\n");
35
+ const headings = [];
36
+ let byteOffset = 0;
37
+ for (let i = 0; i < lines.length; i++) {
38
+ const line = lines[i];
39
+ const lineBytes = Buffer.byteLength(line, "utf8") + 1;
40
+ const trimmed = line.trim();
41
+ if (isAllCaps(trimmed) && (i === 0 || lines[i - 1].trim() === "")) {
42
+ headings.push({
43
+ title: trimmed,
44
+ level: 1,
45
+ byteOffset
46
+ });
47
+ byteOffset += lineBytes;
48
+ continue;
49
+ }
50
+ if (trimmed.length > 0 && i + 1 < lines.length && isDashUnderline(lines[i + 1])) {
51
+ const underlineChar = lines[i + 1].trim()[0];
52
+ headings.push({
53
+ title: trimmed,
54
+ level: underlineChar === "=" ? 1 : 2,
55
+ byteOffset
56
+ });
57
+ byteOffset += lineBytes;
58
+ continue;
59
+ }
60
+ byteOffset += lineBytes;
61
+ }
62
+ return headings;
63
+ }
64
+ function buildHierarchy(headings, content) {
65
+ const contentBytes = Buffer.byteLength(content, "utf8");
66
+ if (headings.length === 0) {
67
+ return [{
68
+ title: "(document)",
69
+ level: 0,
70
+ byteStart: 0,
71
+ byteEnd: contentBytes,
72
+ content,
73
+ children: []
74
+ }];
75
+ }
76
+ const sections = [];
77
+ for (let i = 0; i < headings.length; i++) {
78
+ const start = headings[i].byteOffset;
79
+ const end = i + 1 < headings.length ? headings[i + 1].byteOffset : contentBytes;
80
+ const sectionContent = Buffer.from(content, "utf8").slice(start, end).toString("utf8");
81
+ sections.push({ ...headings[i], byteEnd: end, content: sectionContent });
82
+ }
83
+ const root = [];
84
+ const stack = [];
85
+ for (const s of sections) {
86
+ const parsed = {
87
+ title: s.title,
88
+ level: s.level,
89
+ byteStart: s.byteOffset,
90
+ byteEnd: s.byteEnd,
91
+ content: s.content,
92
+ children: []
93
+ };
94
+ while (stack.length > 0 && stack[stack.length - 1].level >= s.level) {
95
+ stack.pop();
96
+ }
97
+ if (stack.length === 0) {
98
+ root.push(parsed);
99
+ } else {
100
+ stack[stack.length - 1].section.children.push(parsed);
101
+ }
102
+ stack.push({ section: parsed, level: s.level });
103
+ }
104
+ return root;
105
+ }
106
+ const plaintextParser = {
107
+ name: "plaintext",
108
+ extensions: [".txt"],
109
+ parse(content, _filePath) {
110
+ const headings = extractHeadings(content);
111
+ const sections = buildHierarchy(headings, content);
112
+ return { sections, format: "plaintext" };
113
+ }
114
+ };
115
+ // Annotate the CommonJS export names for ESM import in node:
116
+ 0 && (module.exports = {
117
+ plaintextParser
118
+ });
119
+ //# sourceMappingURL=plaintext.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/docs/formats/plaintext.ts"],
4
+ "sourcesContent": ["/**\n * Plain Text Section Parser\n *\n * Handles: .txt\n * Parsing strategy: Paragraph-block splitting.\n * Treats blank-line-separated blocks as sections.\n * Lines that are ALL CAPS or followed by a line of dashes are treated as headings.\n */\n\nimport type { DocFormatParser, ParseResult, ParsedSection } from '../types';\n\ninterface RawHeading {\n title: string;\n level: number;\n byteOffset: number;\n}\n\nfunction isAllCaps(line: string): boolean {\n const trimmed = line.trim();\n if (trimmed.length < 3) return false;\n // Must have at least some letters and be all uppercase\n return /[A-Z]/.test(trimmed) && trimmed === trimmed.toUpperCase() && /^[A-Z\\s\\d\\-_:]+$/.test(trimmed);\n}\n\nfunction isDashUnderline(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.length >= 3 && /^[-=~]+$/.test(trimmed);\n}\n\nfunction extractHeadings(content: string): RawHeading[] {\n const lines = content.split('\\n');\n const headings: RawHeading[] = [];\n let byteOffset = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, 'utf8') + 1;\n const trimmed = line.trim();\n\n // Pattern 1: ALL CAPS line preceded by blank line (or first line)\n if (isAllCaps(trimmed) && (i === 0 || lines[i - 1].trim() === '')) {\n headings.push({\n title: trimmed,\n level: 1,\n byteOffset,\n });\n byteOffset += lineBytes;\n continue;\n }\n\n // Pattern 2: Line followed by dash/equals underline\n if (trimmed.length > 0 && i + 1 < lines.length && isDashUnderline(lines[i + 1])) {\n const underlineChar = lines[i + 1].trim()[0];\n headings.push({\n title: trimmed,\n level: underlineChar === '=' ? 1 : 2,\n byteOffset,\n });\n byteOffset += lineBytes;\n continue;\n }\n\n byteOffset += lineBytes;\n }\n\n return headings;\n}\n\nfunction buildHierarchy(headings: RawHeading[], content: string): ParsedSection[] {\n const contentBytes = Buffer.byteLength(content, 'utf8');\n\n if (headings.length === 0) {\n // No headings detected \u2014 treat as single section\n return [{\n title: '(document)',\n level: 0,\n byteStart: 0,\n byteEnd: contentBytes,\n content,\n children: [],\n }];\n }\n\n const sections: Array<RawHeading & { byteEnd: number; content: string }> = [];\n for (let i = 0; i < headings.length; i++) {\n const start = headings[i].byteOffset;\n const end = i + 1 < headings.length ? headings[i + 1].byteOffset : contentBytes;\n const sectionContent = Buffer.from(content, 'utf8').slice(start, end).toString('utf8');\n sections.push({ ...headings[i], byteEnd: end, content: sectionContent });\n }\n\n const root: ParsedSection[] = [];\n const stack: Array<{ section: ParsedSection; level: number }> = [];\n\n for (const s of sections) {\n const parsed: ParsedSection = {\n title: s.title,\n level: s.level,\n byteStart: s.byteOffset,\n byteEnd: s.byteEnd,\n content: s.content,\n children: [],\n };\n\n while (stack.length > 0 && stack[stack.length - 1].level >= s.level) {\n stack.pop();\n }\n\n if (stack.length === 0) {\n root.push(parsed);\n } else {\n stack[stack.length - 1].section.children.push(parsed);\n }\n\n stack.push({ section: parsed, level: s.level });\n }\n\n return root;\n}\n\nexport const plaintextParser: DocFormatParser = {\n name: 'plaintext',\n extensions: ['.txt'],\n\n parse(content: string, _filePath: string): ParseResult {\n const headings = extractHeadings(content);\n const sections = buildHierarchy(headings, content);\n return { sections, format: 'plaintext' };\n },\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var rdoc_exports = {};
20
+ __export(rdoc_exports, {
21
+ rdocParser: () => rdocParser
22
+ });
23
+ module.exports = __toCommonJS(rdoc_exports);
24
+ const HEADING_RE = /^(={1,6})\s+(.+)$/;
25
+ function extractHeadings(content) {
26
+ const lines = content.split("\n");
27
+ const headings = [];
28
+ let byteOffset = 0;
29
+ let inVerbatim = false;
30
+ for (let i = 0; i < lines.length; i++) {
31
+ const line = lines[i];
32
+ const lineBytes = Buffer.byteLength(line, "utf8") + 1;
33
+ if (line.startsWith(" ") && line.trim().length > 0) {
34
+ byteOffset += lineBytes;
35
+ continue;
36
+ }
37
+ const match = line.match(HEADING_RE);
38
+ if (match) {
39
+ headings.push({
40
+ title: match[2].trim(),
41
+ level: match[1].length,
42
+ lineIndex: i,
43
+ byteOffset
44
+ });
45
+ }
46
+ byteOffset += lineBytes;
47
+ }
48
+ return headings;
49
+ }
50
+ function buildHierarchy(headings, content) {
51
+ const contentBytes = Buffer.byteLength(content, "utf8");
52
+ if (headings.length === 0) {
53
+ return [{
54
+ title: "(document)",
55
+ level: 0,
56
+ byteStart: 0,
57
+ byteEnd: contentBytes,
58
+ content,
59
+ children: []
60
+ }];
61
+ }
62
+ const sections = [];
63
+ for (let i = 0; i < headings.length; i++) {
64
+ const start = headings[i].byteOffset;
65
+ const end = i + 1 < headings.length ? headings[i + 1].byteOffset : contentBytes;
66
+ const sectionContent = Buffer.from(content, "utf8").slice(start, end).toString("utf8");
67
+ sections.push({ ...headings[i], byteEnd: end, content: sectionContent });
68
+ }
69
+ const root = [];
70
+ const stack = [];
71
+ for (const s of sections) {
72
+ const parsed = {
73
+ title: s.title,
74
+ level: s.level,
75
+ byteStart: s.byteOffset,
76
+ byteEnd: s.byteEnd,
77
+ content: s.content,
78
+ children: []
79
+ };
80
+ while (stack.length > 0 && stack[stack.length - 1].level >= s.level) {
81
+ stack.pop();
82
+ }
83
+ if (stack.length === 0) {
84
+ root.push(parsed);
85
+ } else {
86
+ stack[stack.length - 1].section.children.push(parsed);
87
+ }
88
+ stack.push({ section: parsed, level: s.level });
89
+ }
90
+ return root;
91
+ }
92
+ const rdocParser = {
93
+ name: "rdoc",
94
+ extensions: [".rdoc"],
95
+ parse(content, _filePath) {
96
+ const headings = extractHeadings(content);
97
+ const sections = buildHierarchy(headings, content);
98
+ return { sections, format: "rdoc" };
99
+ }
100
+ };
101
+ // Annotate the CommonJS export names for ESM import in node:
102
+ 0 && (module.exports = {
103
+ rdocParser
104
+ });
105
+ //# sourceMappingURL=rdoc.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/docs/formats/rdoc.ts"],
4
+ "sourcesContent": ["/**\n * RDoc Section Parser\n *\n * Handles: .rdoc (Ruby documentation format)\n * Parsing strategy: = heading hierarchy (= Title, == Section, === Subsection)\n * Similar to AsciiDoc but with Ruby-specific conventions.\n */\n\nimport type { DocFormatParser, ParseResult, ParsedSection } from '../types';\n\nconst HEADING_RE = /^(={1,6})\\s+(.+)$/;\n\ninterface RawHeading {\n title: string;\n level: number;\n lineIndex: number;\n byteOffset: number;\n}\n\nfunction extractHeadings(content: string): RawHeading[] {\n const lines = content.split('\\n');\n const headings: RawHeading[] = [];\n let byteOffset = 0;\n let inVerbatim = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, 'utf8') + 1;\n\n // Track verbatim blocks (indented by 2+ spaces in RDoc)\n // Skip lines starting with spaces (code blocks in RDoc)\n if (line.startsWith(' ') && line.trim().length > 0) {\n byteOffset += lineBytes;\n continue;\n }\n\n const match = line.match(HEADING_RE);\n if (match) {\n headings.push({\n title: match[2].trim(),\n level: match[1].length,\n lineIndex: i,\n byteOffset,\n });\n }\n\n byteOffset += lineBytes;\n }\n\n return headings;\n}\n\nfunction buildHierarchy(headings: RawHeading[], content: string): ParsedSection[] {\n const contentBytes = Buffer.byteLength(content, 'utf8');\n\n if (headings.length === 0) {\n return [{\n title: '(document)',\n level: 0,\n byteStart: 0,\n byteEnd: contentBytes,\n content,\n children: [],\n }];\n }\n\n const sections: Array<RawHeading & { byteEnd: number; content: string }> = [];\n for (let i = 0; i < headings.length; i++) {\n const start = headings[i].byteOffset;\n const end = i + 1 < headings.length ? headings[i + 1].byteOffset : contentBytes;\n const sectionContent = Buffer.from(content, 'utf8').slice(start, end).toString('utf8');\n sections.push({ ...headings[i], byteEnd: end, content: sectionContent });\n }\n\n const root: ParsedSection[] = [];\n const stack: Array<{ section: ParsedSection; level: number }> = [];\n\n for (const s of sections) {\n const parsed: ParsedSection = {\n title: s.title,\n level: s.level,\n byteStart: s.byteOffset,\n byteEnd: s.byteEnd,\n content: s.content,\n children: [],\n };\n\n while (stack.length > 0 && stack[stack.length - 1].level >= s.level) {\n stack.pop();\n }\n\n if (stack.length === 0) {\n root.push(parsed);\n } else {\n stack[stack.length - 1].section.children.push(parsed);\n }\n\n stack.push({ section: parsed, level: s.level });\n }\n\n return root;\n}\n\nexport const rdocParser: DocFormatParser = {\n name: 'rdoc',\n extensions: ['.rdoc'],\n\n parse(content: string, _filePath: string): ParseResult {\n const headings = extractHeadings(content);\n const sections = buildHierarchy(headings, content);\n return { sections, format: 'rdoc' };\n },\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,MAAM,aAAa;AASnB,SAAS,gBAAgB,SAA+B;AACtD,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,WAAyB,CAAC;AAChC,MAAI,aAAa;AACjB,MAAI,aAAa;AAEjB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,YAAY,OAAO,WAAW,MAAM,MAAM,IAAI;AAIpD,QAAI,KAAK,WAAW,IAAI,KAAK,KAAK,KAAK,EAAE,SAAS,GAAG;AACnD,oBAAc;AACd;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK,MAAM,UAAU;AACnC,QAAI,OAAO;AACT,eAAS,KAAK;AAAA,QACZ,OAAO,MAAM,CAAC,EAAE,KAAK;AAAA,QACrB,OAAO,MAAM,CAAC,EAAE;AAAA,QAChB,WAAW;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAEA,kBAAc;AAAA,EAChB;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,UAAwB,SAAkC;AAChF,QAAM,eAAe,OAAO,WAAW,SAAS,MAAM;AAEtD,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,CAAC;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,MACT;AAAA,MACA,UAAU,CAAC;AAAA,IACb,CAAC;AAAA,EACH;AAEA,QAAM,WAAqE,CAAC;AAC5E,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,QAAQ,SAAS,CAAC,EAAE;AAC1B,UAAM,MAAM,IAAI,IAAI,SAAS,SAAS,SAAS,IAAI,CAAC,EAAE,aAAa;AACnE,UAAM,iBAAiB,OAAO,KAAK,SAAS,MAAM,EAAE,MAAM,OAAO,GAAG,EAAE,SAAS,MAAM;AACrF,aAAS,KAAK,EAAE,GAAG,SAAS,CAAC,GAAG,SAAS,KAAK,SAAS,eAAe,CAAC;AAAA,EACzE;AAEA,QAAM,OAAwB,CAAC;AAC/B,QAAM,QAA0D,CAAC;AAEjE,aAAW,KAAK,UAAU;AACxB,UAAM,SAAwB;AAAA,MAC5B,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,MACT,WAAW,EAAE;AAAA,MACb,SAAS,EAAE;AAAA,MACX,SAAS,EAAE;AAAA,MACX,UAAU,CAAC;AAAA,IACb;AAEA,WAAO,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO;AACnE,YAAM,IAAI;AAAA,IACZ;AAEA,QAAI,MAAM,WAAW,GAAG;AACtB,WAAK,KAAK,MAAM;AAAA,IAClB,OAAO;AACL,YAAM,MAAM,SAAS,CAAC,EAAE,QAAQ,SAAS,KAAK,MAAM;AAAA,IACtD;AAEA,UAAM,KAAK,EAAE,SAAS,QAAQ,OAAO,EAAE,MAAM,CAAC;AAAA,EAChD;AAEA,SAAO;AACT;AAEO,MAAM,aAA8B;AAAA,EACzC,MAAM;AAAA,EACN,YAAY,CAAC,OAAO;AAAA,EAEpB,MAAM,SAAiB,WAAgC;AACrD,UAAM,WAAW,gBAAgB,OAAO;AACxC,UAAM,WAAW,eAAe,UAAU,OAAO;AACjD,WAAO,EAAE,UAAU,QAAQ,OAAO;AAAA,EACpC;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var rst_exports = {};
20
+ __export(rst_exports, {
21
+ rstParser: () => rstParser
22
+ });
23
+ module.exports = __toCommonJS(rst_exports);
24
+ const ADORNMENT_CHARS = new Set("= - ` : . ' \" ~ ^ _ * + #".split(" "));
25
+ function isAdornmentLine(line) {
26
+ const trimmed = line.trim();
27
+ if (trimmed.length < 3) return false;
28
+ const char = trimmed[0];
29
+ if (!ADORNMENT_CHARS.has(char)) return false;
30
+ return trimmed.split("").every((c) => c === char);
31
+ }
32
+ function extractHeadings(content) {
33
+ const lines = content.split("\n");
34
+ const headings = [];
35
+ const adornmentOrder = [];
36
+ let byteOffset = 0;
37
+ for (let i = 0; i < lines.length; i++) {
38
+ const line = lines[i];
39
+ const lineBytes = Buffer.byteLength(line, "utf8") + 1;
40
+ if (i + 1 < lines.length && line.trim().length > 0 && !isAdornmentLine(line)) {
41
+ const nextLine = lines[i + 1];
42
+ if (isAdornmentLine(nextLine) && nextLine.trim().length >= line.trim().length) {
43
+ const adornChar = nextLine.trim()[0];
44
+ let hasOverline = false;
45
+ if (i > 0 && isAdornmentLine(lines[i - 1]) && lines[i - 1].trim()[0] === adornChar) {
46
+ hasOverline = true;
47
+ }
48
+ const key = hasOverline ? `over_${adornChar}` : adornChar;
49
+ let levelIdx = adornmentOrder.indexOf(key);
50
+ if (levelIdx === -1) {
51
+ adornmentOrder.push(key);
52
+ levelIdx = adornmentOrder.length - 1;
53
+ }
54
+ headings.push({
55
+ title: line.trim(),
56
+ level: levelIdx + 1,
57
+ lineIndex: i,
58
+ byteOffset: hasOverline ? byteOffset - (Buffer.byteLength(lines[i - 1], "utf8") + 1) : byteOffset
59
+ });
60
+ }
61
+ }
62
+ byteOffset += lineBytes;
63
+ }
64
+ return headings;
65
+ }
66
+ function buildHierarchy(headings, content) {
67
+ const contentBytes = Buffer.byteLength(content, "utf8");
68
+ if (headings.length === 0) {
69
+ return [{
70
+ title: "(document)",
71
+ level: 0,
72
+ byteStart: 0,
73
+ byteEnd: contentBytes,
74
+ content,
75
+ children: []
76
+ }];
77
+ }
78
+ const sections = [];
79
+ for (let i = 0; i < headings.length; i++) {
80
+ const start = headings[i].byteOffset;
81
+ const end = i + 1 < headings.length ? headings[i + 1].byteOffset : contentBytes;
82
+ const sectionContent = Buffer.from(content, "utf8").slice(start, end).toString("utf8");
83
+ sections.push({ ...headings[i], byteEnd: end, content: sectionContent });
84
+ }
85
+ const root = [];
86
+ const stack = [];
87
+ for (const s of sections) {
88
+ const parsed = {
89
+ title: s.title,
90
+ level: s.level,
91
+ byteStart: s.byteOffset,
92
+ byteEnd: s.byteEnd,
93
+ content: s.content,
94
+ children: []
95
+ };
96
+ while (stack.length > 0 && stack[stack.length - 1].level >= s.level) {
97
+ stack.pop();
98
+ }
99
+ if (stack.length === 0) {
100
+ root.push(parsed);
101
+ } else {
102
+ stack[stack.length - 1].section.children.push(parsed);
103
+ }
104
+ stack.push({ section: parsed, level: s.level });
105
+ }
106
+ return root;
107
+ }
108
+ const rstParser = {
109
+ name: "rst",
110
+ extensions: [".rst"],
111
+ parse(content, _filePath) {
112
+ const headings = extractHeadings(content);
113
+ const sections = buildHierarchy(headings, content);
114
+ return { sections, format: "rst" };
115
+ }
116
+ };
117
+ // Annotate the CommonJS export names for ESM import in node:
118
+ 0 && (module.exports = {
119
+ rstParser
120
+ });
121
+ //# sourceMappingURL=rst.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/docs/formats/rst.ts"],
4
+ "sourcesContent": ["/**\n * reStructuredText Section Parser\n *\n * Handles: .rst\n * Parsing strategy: Adornment-based heading detection.\n * RST headings are defined by underline (and optional overline) characters.\n * The first adornment character encountered defines level 1, the second level 2, etc.\n */\n\nimport type { DocFormatParser, ParseResult, ParsedSection } from '../types';\n\n// Characters that can be used as RST adornments\nconst ADORNMENT_CHARS = new Set('= - ` : . \\' \" ~ ^ _ * + #'.split(' '));\n\ninterface RawHeading {\n title: string;\n level: number;\n lineIndex: number;\n byteOffset: number;\n}\n\nfunction isAdornmentLine(line: string): boolean {\n const trimmed = line.trim();\n if (trimmed.length < 3) return false;\n const char = trimmed[0];\n if (!ADORNMENT_CHARS.has(char)) return false;\n return trimmed.split('').every(c => c === char);\n}\n\nfunction extractHeadings(content: string): RawHeading[] {\n const lines = content.split('\\n');\n const headings: RawHeading[] = [];\n const adornmentOrder: string[] = []; // tracks which chars map to which levels\n let byteOffset = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineBytes = Buffer.byteLength(line, 'utf8') + 1;\n\n // Check for heading pattern: title line followed by adornment line\n if (i + 1 < lines.length && line.trim().length > 0 && !isAdornmentLine(line)) {\n const nextLine = lines[i + 1];\n if (isAdornmentLine(nextLine) && nextLine.trim().length >= line.trim().length) {\n const adornChar = nextLine.trim()[0];\n\n // Also check for overline pattern (adornment above and below)\n let hasOverline = false;\n if (i > 0 && isAdornmentLine(lines[i - 1]) && lines[i - 1].trim()[0] === adornChar) {\n hasOverline = true;\n }\n\n // Determine level based on order of appearance\n const key = hasOverline ? `over_${adornChar}` : adornChar;\n let levelIdx = adornmentOrder.indexOf(key);\n if (levelIdx === -1) {\n adornmentOrder.push(key);\n levelIdx = adornmentOrder.length - 1;\n }\n\n headings.push({\n title: line.trim(),\n level: levelIdx + 1,\n lineIndex: i,\n byteOffset: hasOverline ? byteOffset - (Buffer.byteLength(lines[i - 1], 'utf8') + 1) : byteOffset,\n });\n }\n }\n\n byteOffset += lineBytes;\n }\n\n return headings;\n}\n\nfunction buildHierarchy(headings: RawHeading[], content: string): ParsedSection[] {\n const contentBytes = Buffer.byteLength(content, 'utf8');\n\n if (headings.length === 0) {\n return [{\n title: '(document)',\n level: 0,\n byteStart: 0,\n byteEnd: contentBytes,\n content,\n children: [],\n }];\n }\n\n const sections: Array<RawHeading & { byteEnd: number; content: string }> = [];\n for (let i = 0; i < headings.length; i++) {\n const start = headings[i].byteOffset;\n const end = i + 1 < headings.length ? headings[i + 1].byteOffset : contentBytes;\n const sectionContent = Buffer.from(content, 'utf8').slice(start, end).toString('utf8');\n sections.push({ ...headings[i], byteEnd: end, content: sectionContent });\n }\n\n const root: ParsedSection[] = [];\n const stack: Array<{ section: ParsedSection; level: number }> = [];\n\n for (const s of sections) {\n const parsed: ParsedSection = {\n title: s.title,\n level: s.level,\n byteStart: s.byteOffset,\n byteEnd: s.byteEnd,\n content: s.content,\n children: [],\n };\n\n while (stack.length > 0 && stack[stack.length - 1].level >= s.level) {\n stack.pop();\n }\n\n if (stack.length === 0) {\n root.push(parsed);\n } else {\n stack[stack.length - 1].section.children.push(parsed);\n }\n\n stack.push({ section: parsed, level: s.level });\n }\n\n return root;\n}\n\nexport const rstParser: DocFormatParser = {\n name: 'rst',\n extensions: ['.rst'],\n\n parse(content: string, _filePath: string): ParseResult {\n const headings = extractHeadings(content);\n const sections = buildHierarchy(headings, content);\n return { sections, format: 'rst' };\n },\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }