@g3nomaly/analyze 0.0.0-stage → 0.1.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 (130) hide show
  1. package/LICENSE +95 -0
  2. package/README.md +71 -2
  3. package/dist/THIRD_PARTY_LICENSES.txt +1904 -0
  4. package/dist/api/bundle-builder.d.ts +75 -0
  5. package/dist/api/bundle-cache.d.ts +70 -0
  6. package/dist/api/bundle-loader.d.ts +58 -0
  7. package/dist/api/create-docs.d.ts +72 -0
  8. package/dist/api/embedding.d.ts +32 -0
  9. package/dist/api/errors.d.ts +28 -0
  10. package/dist/api/list.d.ts +106 -0
  11. package/dist/api/options.d.ts +78 -0
  12. package/dist/api/refs.d.ts +133 -0
  13. package/dist/api/scan.d.ts +44 -0
  14. package/dist/api/search.d.ts +126 -0
  15. package/dist/api/services.d.ts +7 -0
  16. package/dist/api/show.d.ts +104 -0
  17. package/dist/api/site-reader.d.ts +11 -0
  18. package/dist/api/site-writer.d.ts +20 -0
  19. package/dist/api/source.d.ts +46 -0
  20. package/dist/api/target.d.ts +10 -0
  21. package/dist/api/template.d.ts +5 -0
  22. package/dist/assets/tree-sitter-c-sharp.wasm +0 -0
  23. package/dist/assets/tree-sitter-c.wasm +0 -0
  24. package/dist/assets/tree-sitter-cpp.wasm +0 -0
  25. package/dist/assets/tree-sitter-go.wasm +0 -0
  26. package/dist/assets/tree-sitter-java.wasm +0 -0
  27. package/dist/assets/tree-sitter-javascript.wasm +0 -0
  28. package/dist/assets/tree-sitter-kotlin.wasm +0 -0
  29. package/dist/assets/tree-sitter-php.wasm +0 -0
  30. package/dist/assets/tree-sitter-python.wasm +0 -0
  31. package/dist/assets/tree-sitter-ruby.wasm +0 -0
  32. package/dist/assets/tree-sitter-rust.wasm +0 -0
  33. package/dist/assets/tree-sitter-scala.wasm +0 -0
  34. package/dist/assets/tree-sitter-tsx.wasm +0 -0
  35. package/dist/assets/tree-sitter-typescript.wasm +0 -0
  36. package/dist/assets/vectors.bin +0 -0
  37. package/dist/assets/vocab.txt +33731 -0
  38. package/dist/cli.js +8885 -0
  39. package/dist/embeddings/abbreviations.d.ts +7 -0
  40. package/dist/embeddings/index-builder.d.ts +10 -0
  41. package/dist/embeddings/index.d.ts +10 -0
  42. package/dist/embeddings/model.d.ts +113 -0
  43. package/dist/embeddings/searcher.d.ts +67 -0
  44. package/dist/embeddings/vectors.d.ts +75 -0
  45. package/dist/embeddings/words.d.ts +42 -0
  46. package/dist/index.d.ts +9 -0
  47. package/dist/index.js +8329 -0
  48. package/dist/model/index.d.ts +560 -0
  49. package/dist/model/registry.d.ts +494 -0
  50. package/dist/query/graph.d.ts +66 -0
  51. package/dist/query/index.d.ts +4 -0
  52. package/dist/query/name-search.d.ts +47 -0
  53. package/dist/query/semantic.d.ts +30 -0
  54. package/dist/query/text.d.ts +22 -0
  55. package/dist/retrieval/describe.d.ts +26 -0
  56. package/dist/retrieval/filter.d.ts +17 -0
  57. package/dist/retrieval/index.d.ts +7 -0
  58. package/dist/retrieval/markdown.d.ts +16 -0
  59. package/dist/retrieval/report.d.ts +214 -0
  60. package/dist/retrieval/resolve.d.ts +27 -0
  61. package/dist/retrieval/retriever.d.ts +94 -0
  62. package/dist/retrieval/summary.d.ts +24 -0
  63. package/dist/scanner/code/doc/clean.d.ts +10 -0
  64. package/dist/scanner/code/doc/index.d.ts +6 -0
  65. package/dist/scanner/code/doc/markdown.d.ts +3 -0
  66. package/dist/scanner/code/doc/python.d.ts +3 -0
  67. package/dist/scanner/code/doc/tagged.d.ts +10 -0
  68. package/dist/scanner/code/doc/types.d.ts +22 -0
  69. package/dist/scanner/code/doc/xml.d.ts +3 -0
  70. package/dist/scanner/code/example.d.ts +36 -0
  71. package/dist/scanner/code/extract.d.ts +78 -0
  72. package/dist/scanner/code/grammar.d.ts +29 -0
  73. package/dist/scanner/code/language.d.ts +149 -0
  74. package/dist/scanner/code/languages/c-family.d.ts +5 -0
  75. package/dist/scanner/code/languages/csharp.d.ts +3 -0
  76. package/dist/scanner/code/languages/ecmascript.d.ts +7 -0
  77. package/dist/scanner/code/languages/go.d.ts +3 -0
  78. package/dist/scanner/code/languages/index.d.ts +19 -0
  79. package/dist/scanner/code/languages/java.d.ts +3 -0
  80. package/dist/scanner/code/languages/kotlin.d.ts +3 -0
  81. package/dist/scanner/code/languages/php.d.ts +3 -0
  82. package/dist/scanner/code/languages/python.d.ts +3 -0
  83. package/dist/scanner/code/languages/ruby.d.ts +3 -0
  84. package/dist/scanner/code/languages/rust.d.ts +3 -0
  85. package/dist/scanner/code/languages/scala.d.ts +3 -0
  86. package/dist/scanner/code/languages/shared.d.ts +17 -0
  87. package/dist/scanner/code/planner.d.ts +71 -0
  88. package/dist/scanner/code/symbols.d.ts +68 -0
  89. package/dist/scanner/code/types.d.ts +93 -0
  90. package/dist/scanner/content.d.ts +38 -0
  91. package/dist/scanner/decisions/parse.d.ts +28 -0
  92. package/dist/scanner/decisions/planner.d.ts +30 -0
  93. package/dist/scanner/docs.d.ts +52 -0
  94. package/dist/scanner/files.d.ts +60 -0
  95. package/dist/scanner/glossary/parse.d.ts +30 -0
  96. package/dist/scanner/glossary/planner.d.ts +42 -0
  97. package/dist/scanner/glossary/terms.d.ts +86 -0
  98. package/dist/scanner/graph/builder.d.ts +55 -0
  99. package/dist/scanner/highlight.d.ts +31 -0
  100. package/dist/scanner/index.d.ts +40 -0
  101. package/dist/scanner/markdown/frontmatter.d.ts +9 -0
  102. package/dist/scanner/markdown/links.d.ts +50 -0
  103. package/dist/scanner/markdown/outline.d.ts +27 -0
  104. package/dist/scanner/markdown/renderer.d.ts +44 -0
  105. package/dist/scanner/openapi/planner.d.ts +84 -0
  106. package/dist/scanner/reporter.d.ts +7 -0
  107. package/dist/scanner/scanner.d.ts +52 -0
  108. package/dist/scanner/schema/definitions.d.ts +69 -0
  109. package/dist/scanner/schema/describe.d.ts +79 -0
  110. package/dist/scanner/schema/planner.d.ts +46 -0
  111. package/dist/scanner/schema/registry.d.ts +61 -0
  112. package/dist/scanner/skills/classify.d.ts +20 -0
  113. package/dist/scanner/skills/layout.d.ts +28 -0
  114. package/dist/scanner/skills/planner.d.ts +46 -0
  115. package/dist/scanner/specs.d.ts +50 -0
  116. package/dist/scanner/sql/catalog.d.ts +84 -0
  117. package/dist/scanner/sql/cursor.d.ts +107 -0
  118. package/dist/scanner/sql/database.d.ts +48 -0
  119. package/dist/scanner/sql/parse.d.ts +87 -0
  120. package/dist/scanner/sql/planner.d.ts +65 -0
  121. package/dist/scanner/sql/query.d.ts +60 -0
  122. package/dist/scanner/sql/registry.d.ts +49 -0
  123. package/dist/scanner/sql/source.d.ts +9 -0
  124. package/dist/scanner/sql/statements.d.ts +36 -0
  125. package/dist/scanner/sql/tokens.d.ts +38 -0
  126. package/dist/scanner/tasks/layout.d.ts +40 -0
  127. package/dist/scanner/tasks/planner.d.ts +75 -0
  128. package/dist/scanner/tasks/schema.d.ts +88 -0
  129. package/dist/scanner/text.d.ts +14 -0
  130. package/package.json +104 -4
@@ -0,0 +1,60 @@
1
+ /** Directory at the root of a repository where analyze writes its site and its cache. */
2
+ export declare const OUTPUT_DIR = "analyze_out";
3
+ /** Directories and files skipped in every scan, on top of `.gitignore`. The output of analyze is one, so it never documents itself. */
4
+ export declare const DEFAULT_EXCLUDES: readonly string[];
5
+ /** A directory to read: its files, and the prefix their paths get in the bundle. */
6
+ export interface Source {
7
+ /** Absolute directory. */
8
+ readonly root: string;
9
+ /** Root-relative POSIX paths. */
10
+ readonly files: readonly string[];
11
+ /** Put in front of paths in the bundle. `''` for the repository, `name/` for a directory outside it. */
12
+ readonly prefix: string;
13
+ }
14
+ /** Lists the files of a directory tree. */
15
+ export interface FileLister {
16
+ /** Returns root-relative POSIX paths, sorted. */
17
+ list(root: string): Promise<string[]>;
18
+ }
19
+ /**
20
+ * Lists the files of a directory tree. Inside a git work tree it queries git, so
21
+ * `.gitignore` applies. Elsewhere it walks the directory. Holds the globs it
22
+ * skips: {@link DEFAULT_EXCLUDES} and the excludes it is created with.
23
+ * Created in `api/services.ts` and used by `BundleBuilder` for every source.
24
+ */
25
+ export declare class RepoFileLister implements FileLister {
26
+ private readonly excludes;
27
+ /**
28
+ * Compiles the exclude globs.
29
+ *
30
+ * @param excludes - Globs on top of {@link DEFAULT_EXCLUDES}, matched against root-relative POSIX paths.
31
+ */
32
+ constructor(excludes?: readonly string[]);
33
+ /**
34
+ * Lists the files below a directory, without the excluded ones.
35
+ *
36
+ * @param root - Absolute directory.
37
+ * @returns Root-relative POSIX paths, sorted.
38
+ */
39
+ list(root: string): Promise<string[]>;
40
+ /** Tells whether a root-relative path matches an exclude glob. */
41
+ private isExcluded;
42
+ /**
43
+ * Lists the tracked and untracked files git does not ignore.
44
+ *
45
+ * @returns Root-relative paths, or `null` when `root` is not in a git work tree or git fails.
46
+ */
47
+ private listWithGit;
48
+ /**
49
+ * Walks a directory recursively, skipping excluded directories.
50
+ *
51
+ * @param relative - Path of the directory inside `root`, `''` for `root` itself.
52
+ * @returns Root-relative paths, unsorted.
53
+ */
54
+ private walk;
55
+ }
56
+ /**
57
+ * Orders paths the way a file tree lists them: directories before files,
58
+ * then by name. A README leads the files of its directory.
59
+ */
60
+ export declare function compareTreePaths(a: string, b: string): number;
@@ -0,0 +1,30 @@
1
+ /** One term as the glossary file writes it. */
2
+ export interface ParsedTerm {
3
+ readonly name: string;
4
+ /** Text of the heading the term is listed under, or `''`. */
5
+ readonly group: string;
6
+ /** Markdown. */
7
+ readonly definition: string;
8
+ /** Words the glossary tells writers to replace with this term. */
9
+ readonly avoid: readonly string[];
10
+ }
11
+ /** A glossary file split into the text around the terms and the terms. */
12
+ export interface ParsedGlossary {
13
+ /** Markdown of everything that is not a term: the title and the text around the terms. */
14
+ readonly intro: string;
15
+ readonly terms: readonly ParsedTerm[];
16
+ }
17
+ /**
18
+ * Reads the terms of a glossary. Two layouts are recognized:
19
+ *
20
+ * - **Bold terms**: a line that opens with a bold name, followed by its
21
+ * definition. Headings group the terms.
22
+ * - **Heading terms**: when no line opens with a bold name, each heading of
23
+ * the deepest level is a term, and the headings above it are groups.
24
+ *
25
+ * In both layouts an `_Avoid_: a, b` line lists the words a term replaces.
26
+ *
27
+ * @param markdown - The glossary file without frontmatter.
28
+ * @returns The terms in file order and the text around them.
29
+ */
30
+ export declare function parseGlossary(markdown: string): ParsedGlossary;
@@ -0,0 +1,42 @@
1
+ import type { NodeRef } from '../../model';
2
+ import type { FileRenderer } from '../content';
3
+ import type { DocFile } from '../docs';
4
+ import type { GraphBuilder } from '../graph/builder';
5
+ import type { ProseResolvers } from '../markdown/links';
6
+ import type { MarkdownRenderer } from '../markdown/renderer';
7
+ import type { TermIndex } from './terms';
8
+ /**
9
+ * Adds a glossary to the graph: one node for the file and one `term` node per
10
+ * term. Used by `DocPlanner` for every `glossary.md` of the docs section. Each
11
+ * term is also registered in the term index, so prose anywhere in the scan
12
+ * can link to it.
13
+ *
14
+ * Holds the graph, the file renderer, the markdown renderer, the shared
15
+ * `TermIndex` and the prose resolvers. Created by `RepositoryScanner`, which
16
+ * hands it to `DocPlanner` and `TaskPlanner`.
17
+ *
18
+ * @example
19
+ * const terms = new TermIndex();
20
+ * const resolvers = new ProseResolvers(graph, linker, new TermLinker(terms, graph));
21
+ * const glossaries = new GlossaryPlanner(graph, files, markdown, terms, resolvers);
22
+ */
23
+ export declare class GlossaryPlanner {
24
+ private readonly graph;
25
+ private readonly files;
26
+ private readonly markdown;
27
+ private readonly terms;
28
+ private readonly resolvers;
29
+ /**
30
+ * Creates a planner.
31
+ *
32
+ * @param terms - Receives every term. Must be the index the `TermLinker` of `resolvers` reads.
33
+ */
34
+ constructor(graph: GraphBuilder, files: FileRenderer, markdown: MarkdownRenderer, terms: TermIndex, resolvers: ProseResolvers);
35
+ /**
36
+ * Reads one glossary file and adds its nodes.
37
+ *
38
+ * @param parent - Folder or section the file is in.
39
+ * @returns The node of the file.
40
+ */
41
+ plan(parent: NodeRef, { root, path, displayPath, prefix }: DocFile): Promise<NodeRef>;
42
+ }
@@ -0,0 +1,86 @@
1
+ import type { NodeRef } from '../../model';
2
+ import type { GraphBuilder } from '../graph/builder';
3
+ /** A glossary term found in a run of prose. */
4
+ export interface TermMatch {
5
+ /** Offsets of the term in the text. */
6
+ readonly start: number;
7
+ readonly end: number;
8
+ /** In-site href of the term's entry. */
9
+ readonly href: string;
10
+ /** The definition as plain text, for a tooltip. */
11
+ readonly title: string;
12
+ }
13
+ /** Finds the glossary terms of one piece of prose. */
14
+ export type TermFinder = (text: string) => TermMatch[];
15
+ /** One definition of a term in the index. */
16
+ interface TermEntry {
17
+ readonly ref: NodeRef;
18
+ /** Path of the glossary file that defines the term. */
19
+ readonly path: string;
20
+ readonly summary: string;
21
+ }
22
+ /**
23
+ * Every term of every glossary of the scan, by name, and finds uses of them
24
+ * in text.
25
+ *
26
+ * Holds the definitions of each term, keyed by its lowercased name, and one
27
+ * regex that matches any term. Created once per scan by `RepositoryScanner`,
28
+ * filled by `GlossaryPlanner` and read by `TermLinker`.
29
+ */
30
+ export declare class TermIndex {
31
+ private readonly byName;
32
+ /** Matches any term. Rebuilt after a term is added. */
33
+ private pattern;
34
+ /**
35
+ * Adds a term.
36
+ *
37
+ * @param name - The term as the glossary writes it.
38
+ * @param path - Path of the glossary file, as the site shows it.
39
+ * @param summary - The definition as plain text.
40
+ */
41
+ register(name: string, ref: NodeRef, path: string, summary: string): void;
42
+ /**
43
+ * Finds every use of a term in a text. Case is ignored and a plural ending
44
+ * is allowed. Where two terms overlap, the longer one wins.
45
+ *
46
+ * @param text - Plain prose.
47
+ * @param path - Path of the file the prose is in, or `null`. Chooses between glossaries that define the same term.
48
+ * @returns The uses in text order, each with the term it names.
49
+ */
50
+ find(text: string, path: string | null): {
51
+ start: number;
52
+ end: number;
53
+ term: TermEntry;
54
+ }[];
55
+ /** Builds one regex that matches any term, longest first, with an optional plural ending. */
56
+ private buildPattern;
57
+ /**
58
+ * Finds the definition a written term names. The glossary closest to the
59
+ * file wins when several define the term.
60
+ */
61
+ private resolve;
62
+ }
63
+ /**
64
+ * Turns the glossary terms in prose into links to their entries, and records each use as an edge.
65
+ *
66
+ * Holds the `TermIndex` and the graph. Created once per scan by
67
+ * `RepositoryScanner` and handed to `ProseResolvers`, which asks it for a
68
+ * finder per piece of prose.
69
+ */
70
+ export declare class TermLinker {
71
+ private readonly index;
72
+ private readonly graph;
73
+ /** Creates a linker that reads `index` and records edges in `graph`. */
74
+ constructor(index: TermIndex, graph: GraphBuilder);
75
+ /**
76
+ * Creates the finder for one piece of prose, such as a page or a
77
+ * description. The finder links each term once, at its first use, and
78
+ * records a `uses` edge from the owner to the term.
79
+ *
80
+ * @param from - Node that owns the prose.
81
+ * @param path - Path of the file the prose is in, or `null` when it has none.
82
+ * @returns A finder to call with each run of text of the prose.
83
+ */
84
+ finder(from: NodeRef, path: string | null): TermFinder;
85
+ }
86
+ export {};
@@ -0,0 +1,55 @@
1
+ import { type Edge, type EdgeKind, type GraphNode, type NodeKind, type NodeRef } from '../../model';
2
+ /** The fields of a node that fix its place in the tree and its route. Known when the node is added. */
3
+ type IdentityKey = 'kind' | 'name' | 'parent' | 'slug' | 'anchor';
4
+ /** The node types whose `kind` can be `K`. */
5
+ type NodeOf<K extends NodeKind, N = GraphNode> = N extends GraphNode ? (K extends N['kind'] ? N : never) : never;
6
+ /** The identity fields of a node of kind `K`, as `add` takes them. */
7
+ export type IdentityOf<K extends NodeKind> = Omit<Pick<NodeOf<K>, Extract<keyof NodeOf<K>, IdentityKey>>, 'kind'>;
8
+ /** The fields of a node of kind `K` that its `ContentSource` produces. */
9
+ export type ContentOf<K extends NodeKind> = Omit<NodeOf<K>, IdentityKey>;
10
+ /** Produces the rest of a node. Runs in `build`, when every node has its place, so it can link to any of them. */
11
+ export type ContentSource<K extends NodeKind> = (self: NodeRef) => ContentOf<K> | Promise<ContentOf<K>>;
12
+ /**
13
+ * Builds the graph in two passes.
14
+ *
15
+ * 1. The scanners `add` every node: its kind, name and parent. That fixes the
16
+ * tree, the routes and the refs.
17
+ * 2. `build` requests the content of every node. By then a link from any node to
18
+ * any other can be resolved.
19
+ *
20
+ * Holds the identity and content source of every node, the edges, the folder
21
+ * nodes by path and the file nodes by path. A node's `NodeRef` is its index.
22
+ * Created once per scan by `RepositoryScanner`, which calls `build` at the end;
23
+ * every planner (`code/`, `sql/`, `docs`, `skills/`, `tasks/`, `glossary/`,
24
+ * `decisions/`, `schema/`, `openapi/`) and `ProseResolvers` add nodes and edges to it.
25
+ */
26
+ export declare class GraphBuilder {
27
+ /** `identities[ref]` and `contents[ref]` together make the node at `ref`. */
28
+ private readonly identities;
29
+ private readonly contents;
30
+ private readonly edges;
31
+ private readonly folders;
32
+ private readonly files;
33
+ /** Adds a node. Kinds without content of their own, such as folders, take no `content`. */
34
+ add<K extends NodeKind>(kind: K, identity: IdentityOf<K>, ...content: Record<never, never> extends ContentOf<K> ? [] : [ContentSource<K>]): NodeRef;
35
+ /** The folder at `directory` below `parent`, created with its ancestors on first use. `''` is `parent` itself. */
36
+ folder(parent: NodeRef, directory: string): NodeRef;
37
+ /** Records which node shows the file at `path`, so links to that file can find it. */
38
+ registerFile(path: string, ref: NodeRef): void;
39
+ /** Finds the node registered for the file at `path`, or `undefined`. */
40
+ fileAt(path: string): NodeRef | undefined;
41
+ /** In-site href of a node. `fragment` replaces the node's own anchor, for a heading on a page. */
42
+ href(ref: NodeRef, fragment?: string): string;
43
+ /** Records an edge. The same edge recorded twice is kept once. */
44
+ link(from: NodeRef, kind: EdgeKind, to: NodeRef): void;
45
+ /**
46
+ * Runs the content source of every node and returns the finished graph.
47
+ *
48
+ * @returns Nodes in `NodeRef` order, and edges sorted by source, kind (in `EDGE_KINDS` order) and target.
49
+ */
50
+ build(): Promise<{
51
+ nodes: GraphNode[];
52
+ edges: Edge[];
53
+ }>;
54
+ }
55
+ export {};
@@ -0,0 +1,31 @@
1
+ import type { Element } from 'hast';
2
+ /** Highlights code of a language into HTML or into a HAST `<pre>` element. */
3
+ export interface CodeHighlighter {
4
+ toHtml(code: string, language: string): Promise<string>;
5
+ toHast(code: string, language: string): Promise<Element>;
6
+ }
7
+ /**
8
+ * Highlights with shiki. Colors are emitted as `var(--syntax-*)` references,
9
+ * so the page stylesheet owns the palette in light and dark mode. Holds one
10
+ * shiki highlighter, created on first use, and loads each language once; an
11
+ * unknown language falls back to plain text. Created in `api/services.ts` and
12
+ * passed to `RepositoryScanner`, which hands it to the renderers and planners.
13
+ */
14
+ export declare class ShikiHighlighter implements CodeHighlighter {
15
+ private highlighter;
16
+ private readonly loading;
17
+ /** Highlights code into an HTML string. */
18
+ toHtml(code: string, language: string): Promise<string>;
19
+ /** Highlights code into the HAST `<pre>` element shiki produces. */
20
+ toHast(code: string, language: string): Promise<Element>;
21
+ /**
22
+ * Creates the shiki highlighter on first use and loads a language.
23
+ *
24
+ * @returns The highlighter and the language name to pass to it: the lowercased `language`, or `text` when shiki lacks it.
25
+ */
26
+ private prepare;
27
+ /** Loads a language once, sharing the pending load between callers. */
28
+ private resolveLanguage;
29
+ /** Loads a bundled language into shiki, or returns `text` when it is not bundled or fails to load. */
30
+ private load;
31
+ }
@@ -0,0 +1,40 @@
1
+ export { type ExtractedFile, type RawField, type RawParameter, type RawSymbol, SymbolExtractor } from './code/extract';
2
+ export { GrammarLoader } from './code/grammar';
3
+ export type { CallStyle, DocStyle, LanguageSpec } from './code/language';
4
+ export { LANGUAGES, LanguageRegistry } from './code/languages';
5
+ export { CodePlanner, type SourceFile } from './code/planner';
6
+ export { type FileContext, SymbolPlanner } from './code/symbols';
7
+ export { CallableIndex, PROSE_SCOPE, TypeIndex, TypeLinker, type TypeScope } from './code/types';
8
+ export { FileRenderer, type RenderedFile } from './content';
9
+ export { type ParsedDecision, type ParsedDecisions, parseDecisions } from './decisions/parse';
10
+ export { DecisionPlanner } from './decisions/planner';
11
+ export { type DocFile, type DocKind, DocPlanner, docKind } from './docs';
12
+ export { compareTreePaths, DEFAULT_EXCLUDES, type FileLister, RepoFileLister, type Source } from './files';
13
+ export { type ParsedGlossary, type ParsedTerm, parseGlossary } from './glossary/parse';
14
+ export { GlossaryPlanner } from './glossary/planner';
15
+ export { type TermFinder, TermIndex, TermLinker, type TermMatch } from './glossary/terms';
16
+ export { type ContentOf, type ContentSource, GraphBuilder, type IdentityOf } from './graph/builder';
17
+ export { type CodeHighlighter, ShikiHighlighter } from './highlight';
18
+ export { type LinkOrigin, ProseResolvers } from './markdown/links';
19
+ export { joinLines, type MarkdownLine, outlineLines, plainText } from './markdown/outline';
20
+ export { type LinkResolver, MarkdownRenderer, type RenderedMarkdown } from './markdown/renderer';
21
+ export { OpenApiPlanner } from './openapi/planner';
22
+ export { type Reporter, silentReporter } from './reporter';
23
+ export { RepositoryScanner, type ScanInput, type ScannerOptions } from './scanner';
24
+ export { type DefinitionOwner, DefinitionPlanner } from './schema/definitions';
25
+ export { describeSchema, type JsonObject, refName, type SchemaDescription, type SchemaProperty, type SchemaRef, type TypeExpression, typeOf, } from './schema/describe';
26
+ export { JsonSchemaPlanner } from './schema/planner';
27
+ export { DefinitionRegistry, normalizePointer, type RefTarget } from './schema/registry';
28
+ export { classifySkillFile, type SkillFileKind } from './skills/classify';
29
+ export { isInside, SKILL_FILE, type SkillLayout, skillLayouts, skillOwnedFiles } from './skills/layout';
30
+ export { SkillPlanner } from './skills/planner';
31
+ export { type SpecKind, SpecPlanner, specKind } from './specs';
32
+ export { type CatalogFile, type CatalogPlace, CatalogPlanner } from './sql/catalog';
33
+ export { DatabasePlanner } from './sql/database';
34
+ export { type ParsedColumn, type ParsedForeignKey, type ParsedIndex, type ParsedObject, type ParsedSchema, type ParsedTable, parseSqlSchema, } from './sql/parse';
35
+ export { SqlPlanner } from './sql/planner';
36
+ export { type ParsedColumnRef, type ParsedParameter, type ParsedQuery, type ParsedQueryTable, type ParsedResultColumn, parseQueryFile, } from './sql/query';
37
+ export { type ColumnEntry, columnOf, type TableEntry, TableRegistry } from './sql/registry';
38
+ export { type SqlComment, type SqlToken, tokenizeSql } from './sql/tokens';
39
+ export { layoutTree, type PlanFiles, type PhaseFiles, type TreeFiles } from './tasks/layout';
40
+ export { TaskPlanner, type TaskTreeSource } from './tasks/planner';
@@ -0,0 +1,9 @@
1
+ /** A markdown document split into its YAML frontmatter and the rest. */
2
+ export interface Frontmatter {
3
+ readonly data: Readonly<Record<string, unknown>>;
4
+ readonly body: string;
5
+ }
6
+ /** Splits a leading YAML block from a markdown document. Invalid YAML yields empty data. */
7
+ export declare function splitFrontmatter(source: string): Frontmatter;
8
+ /** Reads a frontmatter field as trimmed text, or `null` when it is missing, blank or no string. */
9
+ export declare function stringField(data: Readonly<Record<string, unknown>>, key: string): string | null;
@@ -0,0 +1,50 @@
1
+ import type { EdgeKind, NodeRef } from '../../model';
2
+ import { type TypeLinker, type TypeScope } from '../code/types';
3
+ import type { TermLinker } from '../glossary/terms';
4
+ import type { GraphBuilder } from '../graph/builder';
5
+ import type { LinkResolver } from './renderer';
6
+ /** The markdown file whose links are resolved. */
7
+ export interface LinkOrigin {
8
+ /** The node that shows the text. Edges start here. */
9
+ readonly node: NodeRef;
10
+ /** Absolute directory `path` is relative to. */
11
+ readonly root: string;
12
+ /** Path of the file inside `root`. */
13
+ readonly path: string;
14
+ /** Prefix the bundle puts in front of paths from `root`. */
15
+ readonly prefix: string;
16
+ }
17
+ /**
18
+ * Creates the link resolver for each piece of markdown of a scan. One place
19
+ * decides what prose can link to: files, types, functions and glossary terms.
20
+ *
21
+ * Holds the graph, the type linker and the term linker. Created once per scan
22
+ * by `RepositoryScanner` and passed to every planner that renders markdown.
23
+ *
24
+ * @example
25
+ * const resolvers = new ProseResolvers(graph, linker, new TermLinker(terms, graph));
26
+ */
27
+ export declare class ProseResolvers {
28
+ private readonly graph;
29
+ private readonly linker;
30
+ private readonly terms;
31
+ /** Creates the resolver factory. */
32
+ constructor(graph: GraphBuilder, linker: TypeLinker, terms: TermLinker);
33
+ /**
34
+ * Resolver for markdown that comes from a file: a page, a term, a decision.
35
+ *
36
+ * @param relation - Kind of the edge a link to a file, type or function records.
37
+ * @returns A resolver for one render of that text.
38
+ */
39
+ forFile(origin: LinkOrigin, relation?: EdgeKind): LinkResolver;
40
+ /**
41
+ * Resolver for the description of a symbol, parameter or field. A doc
42
+ * comment has no links to files, so only inline code and terms resolve.
43
+ *
44
+ * @param from - Node the description belongs to.
45
+ * @param path - Path of the source file.
46
+ * @param scope - Decides which declaration a type name in inline code means.
47
+ * @returns A resolver for one render of that description.
48
+ */
49
+ forDescription(from: NodeRef, path: string, scope: TypeScope): LinkResolver;
50
+ }
@@ -0,0 +1,27 @@
1
+ /** One line of a markdown text. */
2
+ export interface MarkdownLine {
3
+ readonly text: string;
4
+ /** Set when the line is an ATX heading such as `## Terms`. */
5
+ readonly heading: {
6
+ readonly depth: number;
7
+ readonly text: string;
8
+ } | null;
9
+ }
10
+ /**
11
+ * Splits markdown into lines and marks the headings. A `#` line inside a
12
+ * fenced code block is code, not a heading.
13
+ *
14
+ * @param markdown - Markdown text without frontmatter.
15
+ */
16
+ export declare function outlineLines(markdown: string): MarkdownLine[];
17
+ /**
18
+ * Removes inline markdown markers from a short text such as a heading.
19
+ *
20
+ * @param markdown - Inline markdown, for example `**Lane** (_route_)`.
21
+ * @returns The text a reader sees, for example `Lane (route)`.
22
+ */
23
+ export declare function plainText(markdown: string): string;
24
+ /**
25
+ * Joins lines back into markdown and drops blank lines at both ends.
26
+ */
27
+ export declare function joinLines(lines: readonly MarkdownLine[]): string;
@@ -0,0 +1,44 @@
1
+ import type { Heading } from '../../model';
2
+ import type { TermMatch } from '../glossary/terms';
3
+ import type { CodeHighlighter } from '../highlight';
4
+ /** Turns what one document refers to into links inside the site. */
5
+ export interface LinkResolver {
6
+ /** In-site href for a relative link, or `null` when it points outside the bundle. */
7
+ link(href: string): string | null;
8
+ /** `data:` URI for a relative image, or `null` when it cannot be embedded. */
9
+ image(src: string): Promise<string | null>;
10
+ /** In-site href for inline code that names something in the bundle, such as a class. */
11
+ code?(text: string): string | null;
12
+ /** The glossary terms in one run of prose that should become links. */
13
+ terms?(text: string): TermMatch[];
14
+ }
15
+ /** The HTML of a markdown text, with its headings and title. */
16
+ export interface RenderedMarkdown {
17
+ readonly html: string;
18
+ readonly headings: Heading[];
19
+ /** Text of the first level-1 heading. */
20
+ readonly title: string | null;
21
+ }
22
+ /**
23
+ * Markdown to HTML. Raw HTML in the source is dropped, so the output is safe
24
+ * to inject into the generated page. Code blocks are highlighted, and links,
25
+ * images, inline code and glossary terms are resolved through a `LinkResolver`.
26
+ *
27
+ * Holds only the code highlighter. Created once per scan by
28
+ * `RepositoryScanner` and used by `FileRenderer` and the planners in
29
+ * `code/`, `sql/`, `schema/`, `openapi/`, `glossary/`, `decisions/` and `tasks/`.
30
+ */
31
+ export declare class MarkdownRenderer {
32
+ private readonly highlighter;
33
+ /** Creates a renderer that highlights code blocks with `highlighter`. */
34
+ constructor(highlighter: CodeHighlighter);
35
+ /**
36
+ * Renders markdown to HTML.
37
+ *
38
+ * @param resolver - Resolves links, images, inline code and terms. Without one, relative links lose their href and relative images become their alt text.
39
+ * @returns The HTML, the level-2 and level-3 headings, and the text of the first level-1 heading as title.
40
+ */
41
+ render(markdown: string, resolver?: LinkResolver): Promise<RenderedMarkdown>;
42
+ /** Replaces the content of every `<pre><code>` block with highlighted HTML. */
43
+ private highlightCode;
44
+ }
@@ -0,0 +1,84 @@
1
+ import type { NodeRef } from '../../model';
2
+ import type { DocFile } from '../docs';
3
+ import type { GraphBuilder } from '../graph/builder';
4
+ import type { ProseResolvers } from '../markdown/links';
5
+ import type { MarkdownRenderer } from '../markdown/renderer';
6
+ import type { DefinitionPlanner } from '../schema/definitions';
7
+ import { type JsonObject } from '../schema/describe';
8
+ import type { DefinitionRegistry } from '../schema/registry';
9
+ /**
10
+ * Adds an OpenAPI document to the graph: one `api` node for the document,
11
+ * one `operation` node per method on a path and per webhook, one `parameter`
12
+ * node per parameter, and one definition per entry of `components.schemas`.
13
+ *
14
+ * Holds the graph, the markdown renderer, the prose resolvers, the shared
15
+ * `DefinitionPlanner` and the `DefinitionRegistry`. Created by
16
+ * `RepositoryScanner` and used by `SpecPlanner` for every JSON or YAML file
17
+ * that is an OpenAPI 3 document.
18
+ *
19
+ * @example
20
+ * const registry = new DefinitionRegistry();
21
+ * const definitions = new DefinitionPlanner(graph, markdown, resolvers, registry);
22
+ * const apis = new OpenApiPlanner(graph, markdown, resolvers, definitions, registry);
23
+ */
24
+ export declare class OpenApiPlanner {
25
+ private readonly graph;
26
+ private readonly markdown;
27
+ private readonly resolvers;
28
+ private readonly definitions;
29
+ private readonly registry;
30
+ /**
31
+ * Creates a planner.
32
+ *
33
+ * @param resolvers - Links what descriptions refer to.
34
+ * @param definitions - Adds the schema definitions and links type expressions.
35
+ * @param registry - Receives the document, so refs to it from other files resolve.
36
+ */
37
+ constructor(graph: GraphBuilder, markdown: MarkdownRenderer, resolvers: ProseResolvers, definitions: DefinitionPlanner, registry: DefinitionRegistry);
38
+ /**
39
+ * Adds one OpenAPI document.
40
+ *
41
+ * @param parent - Folder or skill the file is in.
42
+ * @param document - The parsed file.
43
+ * @returns The node of the document.
44
+ */
45
+ plan(parent: NodeRef, file: DocFile, document: JsonObject): NodeRef;
46
+ /**
47
+ * Renders the tags a document declares, in document order, each with its description.
48
+ *
49
+ * @param node - Node of the document.
50
+ */
51
+ private tags;
52
+ /**
53
+ * Adds one operation with its parameters.
54
+ *
55
+ * @param owner - The document the operation is in.
56
+ * @param document - The parsed document, for resolving refs.
57
+ */
58
+ private planOperation;
59
+ /**
60
+ * Reads the request body of an operation.
61
+ *
62
+ * @param document - The parsed document, for resolving refs.
63
+ * @param node - Node of the operation. Schemas of the body become `type` edges from it.
64
+ * @returns The body, or `null` for an operation without one.
65
+ */
66
+ private requestBody;
67
+ /**
68
+ * Reads the responses of an operation.
69
+ *
70
+ * @param document - The parsed document, for resolving refs.
71
+ * @param node - Node of the operation. A schema of a response becomes a `returns` edge from it, or a `throws` edge for an error.
72
+ * @returns The responses in document order.
73
+ */
74
+ private responses;
75
+ /**
76
+ * Reads the media types of a request body or a response.
77
+ *
78
+ * @param content - The `content` object: media type to media type object.
79
+ * @param node - Node of the operation.
80
+ * @param relation - Kind of the edge a schema records from the operation.
81
+ * @returns One entry per media type, in document order.
82
+ */
83
+ private content;
84
+ }
@@ -0,0 +1,7 @@
1
+ /** Receives problems that should not stop a scan. */
2
+ export interface Reporter {
3
+ /** Reports one problem, as one line of plain text. */
4
+ warn(message: string): void;
5
+ }
6
+ /** A reporter that drops every warning. */
7
+ export declare const silentReporter: Reporter;
@@ -0,0 +1,52 @@
1
+ import { type DocsBundle } from '../model';
2
+ import type { Source } from './files';
3
+ import type { CodeHighlighter } from './highlight';
4
+ import { type Reporter } from './reporter';
5
+ import { type TaskTreeSource } from './tasks/planner';
6
+ /**
7
+ * The directories one scan reads. Skills and docs each have their own. The
8
+ * code section and the database section are both read from `code`: source
9
+ * files go to the one, SQL files to the other.
10
+ */
11
+ export interface ScanInput {
12
+ readonly skills: readonly Source[];
13
+ readonly docs: readonly Source[];
14
+ readonly code: readonly Source[];
15
+ /** The task-manager trees. Their files are shown in the tasks section, and nowhere else. */
16
+ readonly tasks: readonly TaskTreeSource[];
17
+ }
18
+ /** What a {@link RepositoryScanner} is built with. */
19
+ export interface ScannerOptions {
20
+ /** Directory that relative grammar paths resolve against. */
21
+ readonly grammarDir: string;
22
+ readonly highlighter: CodeHighlighter;
23
+ readonly reporter?: Reporter;
24
+ }
25
+ /**
26
+ * Turns directories into the graph of a documentation site. Holds the parts
27
+ * that outlive one scan: the language registry, the symbol extractor, the
28
+ * grammar loader and the markdown and file renderers. Each scan builds a fresh
29
+ * graph and wires up every planner for it. Created in `api/services.ts` and
30
+ * run by `BundleBuilder`.
31
+ *
32
+ * @example
33
+ * const scanner = new RepositoryScanner({ grammarDir: import.meta.dir, highlighter: new ShikiHighlighter(), reporter });
34
+ * const { nodes, edges } = await scanner.scan({ skills: [], docs: [repository], code: [repository], tasks: [] });
35
+ */
36
+ export declare class RepositoryScanner {
37
+ private readonly options;
38
+ private readonly registry;
39
+ private readonly extractor;
40
+ private readonly grammars;
41
+ private readonly markdown;
42
+ private readonly files;
43
+ /** Creates the grammar loader and the renderers the scans share. */
44
+ constructor(options: ScannerOptions);
45
+ /**
46
+ * Scans the directories of every section into one graph: skills, docs,
47
+ * code, database and tasks, in that order.
48
+ *
49
+ * @returns The nodes and edges of the bundle, without its meta and semantic index.
50
+ */
51
+ scan(input: ScanInput): Promise<Pick<DocsBundle, 'nodes' | 'edges'>>;
52
+ }