@g3nomaly/analyze 0.0.0-stage → 0.1.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 (133) hide show
  1. package/LICENSE +95 -0
  2. package/README.md +76 -2
  3. package/dist/THIRD_PARTY_LICENSES.txt +1904 -0
  4. package/dist/api/bundle-builder.d.ts +94 -0
  5. package/dist/api/bundle-cache.d.ts +73 -0
  6. package/dist/api/bundle-loader.d.ts +65 -0
  7. package/dist/api/create-docs.d.ts +91 -0
  8. package/dist/api/embedding.d.ts +41 -0
  9. package/dist/api/errors.d.ts +35 -0
  10. package/dist/api/list.d.ts +106 -0
  11. package/dist/api/options.d.ts +74 -0
  12. package/dist/api/refs.d.ts +136 -0
  13. package/dist/api/scan.d.ts +56 -0
  14. package/dist/api/search.d.ts +132 -0
  15. package/dist/api/services.d.ts +15 -0
  16. package/dist/api/show.d.ts +100 -0
  17. package/dist/api/site-reader.d.ts +19 -0
  18. package/dist/api/site-writer.d.ts +43 -0
  19. package/dist/api/source.d.ts +57 -0
  20. package/dist/api/target.d.ts +12 -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 +9317 -0
  39. package/dist/embeddings/abbreviations.d.ts +7 -0
  40. package/dist/embeddings/index-builder.d.ts +12 -0
  41. package/dist/embeddings/index.d.ts +10 -0
  42. package/dist/embeddings/model.d.ts +126 -0
  43. package/dist/embeddings/searcher.d.ts +84 -0
  44. package/dist/embeddings/vectors.d.ts +77 -0
  45. package/dist/embeddings/words.d.ts +46 -0
  46. package/dist/index.d.ts +9 -0
  47. package/dist/index.js +8747 -0
  48. package/dist/model/index.d.ts +788 -0
  49. package/dist/model/registry.d.ts +687 -0
  50. package/dist/query/graph.d.ts +123 -0
  51. package/dist/query/index.d.ts +4 -0
  52. package/dist/query/name-search.d.ts +65 -0
  53. package/dist/query/semantic.d.ts +38 -0
  54. package/dist/query/text.d.ts +22 -0
  55. package/dist/retrieval/describe.d.ts +33 -0
  56. package/dist/retrieval/filter.d.ts +36 -0
  57. package/dist/retrieval/index.d.ts +7 -0
  58. package/dist/retrieval/markdown.d.ts +17 -0
  59. package/dist/retrieval/report.d.ts +291 -0
  60. package/dist/retrieval/resolve.d.ts +31 -0
  61. package/dist/retrieval/retriever.d.ts +105 -0
  62. package/dist/retrieval/summary.d.ts +27 -0
  63. package/dist/scanner/code/doc/clean.d.ts +36 -0
  64. package/dist/scanner/code/doc/index.d.ts +12 -0
  65. package/dist/scanner/code/doc/markdown.d.ts +8 -0
  66. package/dist/scanner/code/doc/python.d.ts +8 -0
  67. package/dist/scanner/code/doc/tagged.d.ts +19 -0
  68. package/dist/scanner/code/doc/types.d.ts +33 -0
  69. package/dist/scanner/code/doc/xml.d.ts +8 -0
  70. package/dist/scanner/code/example.d.ts +57 -0
  71. package/dist/scanner/code/extract.d.ts +113 -0
  72. package/dist/scanner/code/grammar.d.ts +44 -0
  73. package/dist/scanner/code/language.d.ts +183 -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 +33 -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 +36 -0
  87. package/dist/scanner/code/planner.d.ts +107 -0
  88. package/dist/scanner/code/symbols.d.ts +134 -0
  89. package/dist/scanner/code/types.d.ts +126 -0
  90. package/dist/scanner/config.d.ts +42 -0
  91. package/dist/scanner/content.d.ts +73 -0
  92. package/dist/scanner/decisions/parse.d.ts +37 -0
  93. package/dist/scanner/decisions/planner.d.ts +42 -0
  94. package/dist/scanner/docs.d.ts +69 -0
  95. package/dist/scanner/files.d.ts +85 -0
  96. package/dist/scanner/glossary/parse.d.ts +40 -0
  97. package/dist/scanner/glossary/planner.d.ts +49 -0
  98. package/dist/scanner/glossary/terms.d.ts +116 -0
  99. package/dist/scanner/graph/builder.d.ts +114 -0
  100. package/dist/scanner/highlight.d.ts +54 -0
  101. package/dist/scanner/ignore.d.ts +25 -0
  102. package/dist/scanner/index.d.ts +43 -0
  103. package/dist/scanner/markdown/frontmatter.d.ts +24 -0
  104. package/dist/scanner/markdown/links.d.ts +60 -0
  105. package/dist/scanner/markdown/outline.d.ts +35 -0
  106. package/dist/scanner/markdown/renderer.d.ts +63 -0
  107. package/dist/scanner/openapi/planner.d.ts +96 -0
  108. package/dist/scanner/packages.d.ts +28 -0
  109. package/dist/scanner/reporter.d.ts +10 -0
  110. package/dist/scanner/scanner.d.ts +66 -0
  111. package/dist/scanner/schema/definitions.d.ts +79 -0
  112. package/dist/scanner/schema/describe.d.ts +105 -0
  113. package/dist/scanner/schema/planner.d.ts +49 -0
  114. package/dist/scanner/schema/registry.d.ts +68 -0
  115. package/dist/scanner/skills/classify.d.ts +21 -0
  116. package/dist/scanner/skills/layout.d.ts +46 -0
  117. package/dist/scanner/skills/planner.d.ts +61 -0
  118. package/dist/scanner/specs.d.ts +56 -0
  119. package/dist/scanner/sql/catalog.d.ts +98 -0
  120. package/dist/scanner/sql/cursor.d.ts +112 -0
  121. package/dist/scanner/sql/database.d.ts +51 -0
  122. package/dist/scanner/sql/parse.d.ts +122 -0
  123. package/dist/scanner/sql/planner.d.ts +69 -0
  124. package/dist/scanner/sql/query.d.ts +73 -0
  125. package/dist/scanner/sql/registry.d.ts +63 -0
  126. package/dist/scanner/sql/source.d.ts +10 -0
  127. package/dist/scanner/sql/statements.d.ts +42 -0
  128. package/dist/scanner/sql/tokens.d.ts +51 -0
  129. package/dist/scanner/tasks/layout.d.ts +52 -0
  130. package/dist/scanner/tasks/planner.d.ts +130 -0
  131. package/dist/scanner/tasks/schema.d.ts +88 -0
  132. package/dist/scanner/text.d.ts +14 -0
  133. package/package.json +104 -4
@@ -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
+ /**
8
+ * @brief Adds a decision log to the graph: one node for the file and one `decision`
9
+ * node per decision.
10
+ *
11
+ * Used by `DocPlanner` for every `decisions.md` of the docs section. What a decision links to or
12
+ * names in inline code becomes an `affects` edge from the decision.
13
+ *
14
+ * Holds the graph, the file renderer, the markdown renderer and the prose resolvers. Created by
15
+ * `RepositoryScanner`, which hands it to `DocPlanner`.
16
+ */
17
+ export declare class DecisionPlanner {
18
+ private readonly graph;
19
+ private readonly files;
20
+ private readonly markdown;
21
+ private readonly resolvers;
22
+ /**
23
+ * Creates a planner.
24
+ *
25
+ * @param graph - Graph the file and decision nodes are added to.
26
+ * @param files - Renders the text of the decision log around the decisions.
27
+ * @param markdown - Renders the body of each decision.
28
+ * @param resolvers - Resolves the links of the decision log and its decisions.
29
+ */
30
+ constructor(graph: GraphBuilder, files: FileRenderer, markdown: MarkdownRenderer, resolvers: ProseResolvers);
31
+ /**
32
+ * @brief Reads one decision log and adds its nodes.
33
+ *
34
+ * @param parent - Folder or section the file is in.
35
+ * @param root - Absolute directory `path` is relative to.
36
+ * @param path - Path of the file inside `root`.
37
+ * @param displayPath - Path the site shows.
38
+ * @param prefix - Prefix the bundle puts in front of paths from `root`.
39
+ * @returns The node of the file.
40
+ */
41
+ plan(parent: NodeRef, { root, path, displayPath, prefix }: DocFile): Promise<NodeRef>;
42
+ }
@@ -0,0 +1,69 @@
1
+ import type { NodeRef } from '../model';
2
+ import type { FileRenderer } from './content';
3
+ import type { DecisionPlanner } from './decisions/planner';
4
+ import { type Source } from './files';
5
+ import type { GlossaryPlanner } from './glossary/planner';
6
+ import type { GraphBuilder } from './graph/builder';
7
+ import type { ProseResolvers } from './markdown/links';
8
+ /** What a file of the docs section becomes. */
9
+ export type DocKind = 'document' | 'glossary' | 'decisions';
10
+ /**
11
+ * @brief A file of the docs section, with the paths the planners need.
12
+ *
13
+ * @property root - Absolute directory `path` is relative to.
14
+ * @property path - Path of the file inside `root`.
15
+ * @property displayPath - Path the site shows: `path` behind the prefix of its source.
16
+ * @property prefix - Prefix the bundle puts in front of paths from `root`.
17
+ */
18
+ export interface DocFile {
19
+ readonly root: string;
20
+ readonly path: string;
21
+ readonly displayPath: string;
22
+ readonly prefix: string;
23
+ }
24
+ /**
25
+ * @brief Tells what a file of the docs section becomes, from its extension and name.
26
+ *
27
+ * @param path - Path of the file.
28
+ * @returns The kind, or `null` for a file that does not belong in the docs section.
29
+ */
30
+ export declare function docKind(path: string): DocKind | null;
31
+ /**
32
+ * @brief Adds a file as a page of its own, rendered as it is, and registers its path so links can find it.
33
+ *
34
+ * @param kind - Node kind the file becomes, such as `document` or `json`.
35
+ * @param parent - Folder the page is added below.
36
+ * @param file - The file, with its root, path and display path.
37
+ * @returns Ref of the new page.
38
+ */
39
+ export declare function addFilePage(graph: GraphBuilder, files: FileRenderer, resolvers: ProseResolvers, kind: 'document' | 'json' | 'toml' | 'yaml', parent: NodeRef, { root, path, displayPath, prefix }: DocFile): NodeRef;
40
+ /**
41
+ * @brief Adds the docs section to the graph: the markdown files in the folders they are in.
42
+ *
43
+ * A `glossary.md` and a `decisions.md` go to their own planners, which add one node per term and
44
+ * per decision. Created by `RepositoryScanner` for every scan.
45
+ */
46
+ export declare class DocPlanner {
47
+ private readonly graph;
48
+ private readonly files;
49
+ private readonly resolvers;
50
+ private readonly glossaries;
51
+ private readonly decisions;
52
+ /**
53
+ * @brief Keeps the graph to add to and the renderer and planners each file goes to.
54
+ *
55
+ * @param graph - Graph the page nodes are added to.
56
+ * @param files - Renders markdown files to their pages.
57
+ * @param resolvers - Resolves the links of each page.
58
+ * @param glossaries - Plans each `glossary.md`.
59
+ * @param decisions - Plans each `decisions.md`.
60
+ */
61
+ constructor(graph: GraphBuilder, files: FileRenderer, resolvers: ProseResolvers, glossaries: GlossaryPlanner, decisions: DecisionPlanner);
62
+ /**
63
+ * @brief Adds every doc file of the sources.
64
+ *
65
+ * @param section - Node of the docs section.
66
+ * @param sources - Directories whose files are read.
67
+ */
68
+ plan(section: NodeRef, sources: readonly Source[]): Promise<void>;
69
+ }
@@ -0,0 +1,85 @@
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
+ /**
4
+ * @brief A directory to read: its files, and the prefix their paths get in the bundle.
5
+ *
6
+ * @property root - Absolute directory.
7
+ * @property files - Root-relative POSIX paths.
8
+ * @property prefix - Put in front of paths in the bundle. `''` for the repository, `name/` for a directory outside it.
9
+ * @property skillsAnywhere - Set for a directory the reader names as skills: a `SKILL.md` anywhere in it is a skill, not only inside an AI directory.
10
+ */
11
+ export interface Source {
12
+ readonly root: string;
13
+ readonly files: readonly string[];
14
+ readonly prefix: string;
15
+ readonly skillsAnywhere?: boolean;
16
+ }
17
+ /** Lists the files of a directory tree. */
18
+ export interface FileLister {
19
+ /**
20
+ * @brief Lists the files below a directory.
21
+ *
22
+ * @param root - Absolute directory.
23
+ * @returns Root-relative POSIX paths, sorted.
24
+ */
25
+ list(root: string): Promise<string[]>;
26
+ }
27
+ /**
28
+ * @brief Lists the files of a directory tree. Inside a git work tree it queries git, so
29
+ * `.gitignore` applies. Elsewhere it walks the directory.
30
+ *
31
+ * Holds the globs it skips: `analyze_out/`, `.git/` and the excludes it is created with.
32
+ * Created in `api/services.ts` with `new RepoFileLister(excludes)` and used by `BundleBuilder`
33
+ * for every source.
34
+ *
35
+ * @property excludes - Compiled globs of the files to skip.
36
+ */
37
+ export declare class RepoFileLister implements FileLister {
38
+ private readonly excludes;
39
+ /**
40
+ * @brief Compiles the exclude globs.
41
+ *
42
+ * @param excludes - Globs matched against root-relative POSIX paths, such as the ones `ignoreGlobs` makes of an
43
+ * `.analyzeignore`. Defaults to the globs of {@link DEFAULT_IGNORE_LINES}.
44
+ */
45
+ constructor(excludes?: readonly string[]);
46
+ /**
47
+ * @brief Lists the files below a directory, without the excluded ones.
48
+ *
49
+ * @param root - Absolute directory.
50
+ * @returns Root-relative POSIX paths, sorted.
51
+ */
52
+ list(root: string): Promise<string[]>;
53
+ /**
54
+ * @brief Tells whether a root-relative path matches an exclude glob.
55
+ *
56
+ * @param file - Root-relative POSIX path.
57
+ * @returns `true` when a glob matches the path.
58
+ */
59
+ private isExcluded;
60
+ /**
61
+ * @brief Lists the tracked and untracked files git does not ignore.
62
+ *
63
+ * @param root - Absolute directory.
64
+ * @returns Root-relative paths, or `null` when `root` is not in a git work tree or git fails.
65
+ */
66
+ private listWithGit;
67
+ /**
68
+ * @brief Walks a directory recursively, skipping excluded directories.
69
+ *
70
+ * @param root - Absolute directory the walk starts from.
71
+ * @param relative - Path of the directory inside `root`, `''` for `root` itself.
72
+ * @returns Root-relative paths, unsorted.
73
+ */
74
+ private walk;
75
+ }
76
+ /**
77
+ * @brief Orders paths the way a file tree lists them: directories before files, then by name.
78
+ *
79
+ * A README leads the files of its directory.
80
+ *
81
+ * @param a - Root-relative POSIX path.
82
+ * @param b - Root-relative POSIX path.
83
+ * @returns Negative when `a` lists first, positive when `b` does, zero for equal paths.
84
+ */
85
+ export declare function compareTreePaths(a: string, b: string): number;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @brief One term as the glossary file writes it.
3
+ *
4
+ * @property name - Name of the term, as written.
5
+ * @property group - Text of the heading the term is listed under, or `''`.
6
+ * @property definition - Markdown of the definition, without the `_Avoid_:` lines.
7
+ * @property avoid - Words the glossary tells writers to replace with this term.
8
+ */
9
+ export interface ParsedTerm {
10
+ readonly name: string;
11
+ readonly group: string;
12
+ readonly definition: string;
13
+ readonly avoid: readonly string[];
14
+ }
15
+ /**
16
+ * @brief A glossary file split into the text around the terms and the terms.
17
+ *
18
+ * @property intro - Markdown of everything that is not a term: the title and the text around the terms.
19
+ * @property terms - The terms in file order.
20
+ */
21
+ export interface ParsedGlossary {
22
+ readonly intro: string;
23
+ readonly terms: readonly ParsedTerm[];
24
+ }
25
+ /**
26
+ * @brief Reads the terms of a glossary.
27
+ *
28
+ * Two layouts are recognized:
29
+ *
30
+ * - **Bold terms**: a line that opens with a bold name, followed by its
31
+ * definition. Headings group the terms.
32
+ * - **Heading terms**: when no line opens with a bold name, each heading of
33
+ * the deepest level is a term, and the headings above it are groups.
34
+ *
35
+ * In both layouts an `_Avoid_: a, b` line lists the words a term replaces.
36
+ *
37
+ * @param markdown - The glossary file without frontmatter.
38
+ * @returns The terms in file order and the text around them.
39
+ */
40
+ export declare function parseGlossary(markdown: string): ParsedGlossary;
@@ -0,0 +1,49 @@
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
+ * @brief Adds a glossary to the graph: one node for the file and one `term` node per term.
10
+ *
11
+ * Used by `DocPlanner` for every `glossary.md` of the docs section. Each term is also registered
12
+ * in the term index, so prose anywhere in the scan can link to it.
13
+ *
14
+ * Holds the graph, the file renderer, the markdown renderer, the shared `TermIndex` and the prose
15
+ * resolvers. Created by `RepositoryScanner`, which hands it to `DocPlanner` and `TaskPlanner`.
16
+ *
17
+ * @example
18
+ * const terms = new TermIndex();
19
+ * const resolvers = new ProseResolvers(graph, linker, new TermLinker(terms, graph));
20
+ * const glossaries = new GlossaryPlanner(graph, files, markdown, terms, resolvers);
21
+ */
22
+ export declare class GlossaryPlanner {
23
+ private readonly graph;
24
+ private readonly files;
25
+ private readonly markdown;
26
+ private readonly terms;
27
+ private readonly resolvers;
28
+ /**
29
+ * Creates a planner.
30
+ *
31
+ * @param graph - Graph the file and term nodes are added to.
32
+ * @param files - Renders the text of the glossary around the terms.
33
+ * @param markdown - Renders the definition of each term.
34
+ * @param terms - Receives every term. Must be the index the `TermLinker` of `resolvers` reads.
35
+ * @param resolvers - Resolves the links of the glossary and its terms.
36
+ */
37
+ constructor(graph: GraphBuilder, files: FileRenderer, markdown: MarkdownRenderer, terms: TermIndex, resolvers: ProseResolvers);
38
+ /**
39
+ * @brief Reads one glossary file and adds its nodes.
40
+ *
41
+ * @param parent - Folder or section the file is in.
42
+ * @param root - Absolute directory `path` is relative to.
43
+ * @param path - Path of the file inside `root`.
44
+ * @param displayPath - Path the site shows.
45
+ * @param prefix - Prefix the bundle puts in front of paths from `root`.
46
+ * @returns The node of the file.
47
+ */
48
+ plan(parent: NodeRef, { root, path, displayPath, prefix }: DocFile): Promise<NodeRef>;
49
+ }
@@ -0,0 +1,116 @@
1
+ import type { NodeRef } from '../../model';
2
+ import type { GraphBuilder } from '../graph/builder';
3
+ /**
4
+ * @brief A glossary term found in a run of prose.
5
+ *
6
+ * @property start - Offset where the term starts in the text.
7
+ * @property end - Offset where the term ends in the text.
8
+ * @property href - In-site href of the term's entry.
9
+ * @property title - The definition as plain text, for a tooltip.
10
+ */
11
+ export interface TermMatch {
12
+ readonly start: number;
13
+ readonly end: number;
14
+ readonly href: string;
15
+ readonly title: string;
16
+ }
17
+ /**
18
+ * @brief Finds the glossary terms of one piece of prose.
19
+ *
20
+ * @param text - Plain prose to search.
21
+ * @returns The matches in text order.
22
+ */
23
+ export type TermFinder = (text: string) => TermMatch[];
24
+ /**
25
+ * @brief One definition of a term in the index.
26
+ *
27
+ * @property ref - Node of the term's entry.
28
+ * @property path - Path of the glossary file that defines the term.
29
+ * @property summary - The definition as plain text.
30
+ */
31
+ interface TermEntry {
32
+ readonly ref: NodeRef;
33
+ readonly path: string;
34
+ readonly summary: string;
35
+ }
36
+ /**
37
+ * @brief Every term of every glossary of the scan, by name, and finds uses of them in text.
38
+ *
39
+ * Holds the definitions of each term, keyed by its lowercased name, and one regex that matches any
40
+ * term. Created once per scan by `RepositoryScanner`, filled by `GlossaryPlanner` and read by
41
+ * `TermLinker`. Created with `new TermIndex()`.
42
+ *
43
+ * @property byName - Definitions of each term, keyed by its normalized name.
44
+ * @property pattern - Matches any term. `null` until built, and reset when a term is added.
45
+ */
46
+ export declare class TermIndex {
47
+ private readonly byName;
48
+ private pattern;
49
+ /**
50
+ * @brief Adds a term.
51
+ *
52
+ * @param name - The term as the glossary writes it.
53
+ * @param ref - Node of the term's entry.
54
+ * @param path - Path of the glossary file, as the site shows it.
55
+ * @param summary - The definition as plain text.
56
+ */
57
+ register(name: string, ref: NodeRef, path: string, summary: string): void;
58
+ /**
59
+ * @brief Finds every use of a term in a text.
60
+ *
61
+ * Case is ignored and a plural ending is allowed. Where two terms overlap, the longer one wins.
62
+ *
63
+ * @param text - Plain prose.
64
+ * @param path - Path of the file the prose is in, or `null`. Chooses between glossaries that define the same term.
65
+ * @returns The uses in text order, each with the term it names.
66
+ */
67
+ find(text: string, path: string | null): {
68
+ start: number;
69
+ end: number;
70
+ term: TermEntry;
71
+ }[];
72
+ /**
73
+ * @brief Builds one regex that matches any term, longest first, with an optional plural ending.
74
+ *
75
+ * @returns The regex.
76
+ */
77
+ private buildPattern;
78
+ /**
79
+ * @brief Finds the definition a written term names. The glossary closest to the file wins when
80
+ * several define the term.
81
+ *
82
+ * @param written - The term as the prose writes it.
83
+ * @param path - Path of the file the prose is in, or `null`.
84
+ * @returns The definition, or `null` when none matches.
85
+ */
86
+ private resolve;
87
+ }
88
+ /**
89
+ * @brief Turns the glossary terms in prose into links to their entries, and records each use as an edge.
90
+ *
91
+ * Holds the `TermIndex` and the graph. Created once per scan by `RepositoryScanner` and handed to
92
+ * `ProseResolvers`, which asks it for a finder per piece of prose.
93
+ */
94
+ export declare class TermLinker {
95
+ private readonly index;
96
+ private readonly graph;
97
+ /**
98
+ * Creates a linker that reads `index` and records edges in `graph`.
99
+ *
100
+ * @param index - The terms the prose is searched for.
101
+ * @param graph - Graph the `uses` edges are added to.
102
+ */
103
+ constructor(index: TermIndex, graph: GraphBuilder);
104
+ /**
105
+ * @brief Creates the finder for one piece of prose, such as a page or a description.
106
+ *
107
+ * The finder links each term once, at its first use, and records a `uses` edge from the owner to
108
+ * the term.
109
+ *
110
+ * @param from - Node that owns the prose.
111
+ * @param path - Path of the file the prose is in, or `null` when it has none.
112
+ * @returns A finder to call with each run of text of the prose.
113
+ */
114
+ finder(from: NodeRef, path: string | null): TermFinder;
115
+ }
116
+ export {};
@@ -0,0 +1,114 @@
1
+ import { type Edge, type EdgeKind, type GraphNode, type NodeType, type NodeRef } from '../../model';
2
+ import type { PackageInfo } from '../packages';
3
+ /** The fields of a node that fix its place in the tree and its route. Known when the node is added. */
4
+ type IdentityKey = 'kind' | 'name' | 'parent' | 'slug' | 'anchor';
5
+ /** The node types whose `kind` can be `K`. */
6
+ type NodeOf<K extends NodeType, N = GraphNode> = N extends GraphNode ? (K extends N['kind'] ? N : never) : never;
7
+ /** The identity fields of a node of kind `K`, as `add` takes them. */
8
+ export type IdentityOf<K extends NodeType> = Omit<Pick<NodeOf<K>, Extract<keyof NodeOf<K>, IdentityKey>>, 'kind'>;
9
+ /** The fields of a node of kind `K` that its `ContentSource` produces. */
10
+ export type ContentOf<K extends NodeType> = Omit<NodeOf<K>, IdentityKey>;
11
+ /**
12
+ * @brief Produces the rest of a node. Runs in `build`, when every node has its place, so it can link to any of them.
13
+ *
14
+ * @param self - Ref of the node being built, which the source may link from.
15
+ * @returns The fields of the node that its identity does not hold.
16
+ */
17
+ export type ContentSource<K extends NodeType> = (self: NodeRef) => ContentOf<K> | Promise<ContentOf<K>>;
18
+ /**
19
+ * @brief Builds the graph in two passes.
20
+ *
21
+ * 1. The scanners `add` every node: its kind, name and parent. That fixes the
22
+ * tree, the routes and the refs.
23
+ * 2. `build` requests the content of every node. By then a link from any node to
24
+ * any other can be resolved.
25
+ *
26
+ * A node's `NodeRef` is its index. Created once per scan by `RepositoryScanner`,
27
+ * which calls `build` at the end; every planner (`code/`, `sql/`, `docs`,
28
+ * `skills/`, `tasks/`, `glossary/`, `decisions/`, `schema/`, `openapi/`) and
29
+ * `ProseResolvers` add nodes and edges to it.
30
+ *
31
+ * @property identities - Routable identity of each node, by `NodeRef`. Together with `contents` it makes the node.
32
+ * @property contents - Content source of each node by `NodeRef`, or `null` for a node that has none.
33
+ * @property edges - Edges by `from:kind:to`, so an edge recorded twice is kept once.
34
+ * @property folders - Folder nodes by `parent/name`.
35
+ * @property files - File nodes by normalized path.
36
+ * @property packages - Packages by display path of their directory, set by `markPackages`.
37
+ * @property packageSections - Sections whose folders become `package` nodes where a package sits.
38
+ * @example
39
+ * const graph = new GraphBuilder();
40
+ */
41
+ export declare class GraphBuilder {
42
+ private readonly identities;
43
+ private readonly contents;
44
+ private readonly edges;
45
+ private readonly folders;
46
+ private readonly files;
47
+ private packages;
48
+ private readonly packageSections;
49
+ /**
50
+ * @brief Adds a node. Kinds without content of their own, such as folders, take no `content`.
51
+ *
52
+ * @param identity - Fields that place the node: its name and parent, plus the slug or anchor of kinds that have them.
53
+ * @param content - Source of the rest of the node. Omitted for a kind without content.
54
+ * @returns Ref of the new node.
55
+ */
56
+ add<K extends NodeType>(kind: K, identity: IdentityOf<K>, ...content: Record<never, never> extends ContentOf<K> ? [] : [ContentSource<K>]): NodeRef;
57
+ /**
58
+ * @brief Makes `folder` create a `package` node instead of a folder for every package directory below the given sections.
59
+ *
60
+ * @param sections - Sections whose `folder` paths are display paths of the repository, such as the code and docs sections.
61
+ * @param packages - Packages by display path of their directory, as `detectPackages` returns them.
62
+ */
63
+ markPackages(sections: readonly NodeRef[], packages: ReadonlyMap<string, PackageInfo>): void;
64
+ /**
65
+ * @brief Finds the folder at `directory` below `parent`, creating it and its ancestors on first use.
66
+ *
67
+ * Below a section passed to `markPackages`, a directory that holds a package becomes a `package` node.
68
+ *
69
+ * @param parent - Node the directory is below.
70
+ * @param directory - Slash-separated path, such as `docs/guides`. `''` names `parent` itself.
71
+ * @returns Ref of the folder at the end of the path.
72
+ */
73
+ folder(parent: NodeRef, directory: string): NodeRef;
74
+ /**
75
+ * @brief Records which node shows the file at `path`, so links to that file can find it.
76
+ *
77
+ * @param path - Display path of the file, as `DocFile.displayPath` gives it. Normalized before storing.
78
+ * @param ref - Node that shows the file.
79
+ */
80
+ registerFile(path: string, ref: NodeRef): void;
81
+ /**
82
+ * @brief Finds the node registered for the file at `path`.
83
+ *
84
+ * @param path - Display path of the file, as passed to `registerFile`.
85
+ * @returns The node, or `undefined` when no file is registered at that path.
86
+ */
87
+ fileAt(path: string): NodeRef | undefined;
88
+ /**
89
+ * @brief Builds the in-site href of a node.
90
+ *
91
+ * @param ref - Node to link to.
92
+ * @param fragment - Replaces the node's own anchor, for a heading on a page.
93
+ * @returns The href, relative to the site root.
94
+ */
95
+ href(ref: NodeRef, fragment?: string): string;
96
+ /**
97
+ * @brief Records an edge. The same edge recorded twice is kept once.
98
+ *
99
+ * @param from - Node the edge starts at.
100
+ * @param kind - Relation the edge expresses.
101
+ * @param to - Node the edge ends at.
102
+ */
103
+ link(from: NodeRef, kind: EdgeKind, to: NodeRef): void;
104
+ /**
105
+ * @brief Runs the content source of every node and returns the finished graph.
106
+ *
107
+ * @returns Nodes in `NodeRef` order, and edges sorted by source, kind (in `EDGE_KINDS` order) and target.
108
+ */
109
+ build(): Promise<{
110
+ nodes: GraphNode[];
111
+ edges: Edge[];
112
+ }>;
113
+ }
114
+ export {};
@@ -0,0 +1,54 @@
1
+ import type { Element } from 'hast';
2
+ /**
3
+ * @brief Highlights code of a language into HTML or into a HAST `<pre>` element.
4
+ *
5
+ * @property toHtml - Highlights code into an HTML string.
6
+ * @property toHast - Highlights code into the HAST `<pre>` element shiki produces.
7
+ */
8
+ export interface CodeHighlighter {
9
+ toHtml(code: string, language: string): Promise<string>;
10
+ toHast(code: string, language: string): Promise<Element>;
11
+ }
12
+ /**
13
+ * @brief Highlights with shiki. Colors are emitted as `var(--syntax-*)` references,
14
+ * so the page stylesheet owns the palette in light and dark mode. Loads each
15
+ * language once; an unknown language falls back to plain text. Created in
16
+ * `api/services.ts` and passed to `RepositoryScanner`, which hands it to the
17
+ * renderers and planners.
18
+ *
19
+ * @property highlighter - The shiki highlighter, created on first use. `null` until then.
20
+ * @property loading - Pending load of each language by name, shared between callers.
21
+ * @example
22
+ * const highlighter = new ShikiHighlighter();
23
+ */
24
+ export declare class ShikiHighlighter implements CodeHighlighter {
25
+ private highlighter;
26
+ private readonly loading;
27
+ /** Highlights code into an HTML string. */
28
+ toHtml(code: string, language: string): Promise<string>;
29
+ /** Highlights code into the HAST `<pre>` element shiki produces. */
30
+ toHast(code: string, language: string): Promise<Element>;
31
+ /**
32
+ * @brief Creates the shiki highlighter on first use and loads a language.
33
+ *
34
+ * @param language - Language name as the code block gives it, in any case.
35
+ * @returns The highlighter and the language name to pass to it: the lowercased `language`, or `text` when shiki lacks it.
36
+ */
37
+ private prepare;
38
+ /**
39
+ * @brief Loads a language once, sharing the pending load between callers.
40
+ *
41
+ * @param highlighter - The shiki highlighter the language is loaded into.
42
+ * @param language - Lowercased language name.
43
+ * @returns The name to highlight with: `language`, or `text` when it cannot be loaded.
44
+ */
45
+ private resolveLanguage;
46
+ /**
47
+ * @brief Loads a bundled language into shiki, or returns `text` when it is not bundled or fails to load.
48
+ *
49
+ * @param highlighter - The shiki highlighter the language is loaded into.
50
+ * @param language - Lowercased language name.
51
+ * @returns The language name, or `text`.
52
+ */
53
+ private load;
54
+ }
@@ -0,0 +1,25 @@
1
+ /** Name of the file at the root of a repository that lists what analyze skips. */
2
+ export declare const IGNORE_FILE = ".analyzeignore";
3
+ /** Lines of the `.analyzeignore` that analyze writes when a repository has none. */
4
+ export declare const DEFAULT_IGNORE_LINES: readonly string[];
5
+ /**
6
+ * @brief Turns the lines of an ignore file into globs that `Bun.Glob` matches against root-relative paths.
7
+ *
8
+ * A pattern without a slash matches at any depth, a leading `/` anchors it to the root, and a
9
+ * trailing `/` matches a directory. A pattern without a trailing `/` matches a file or a directory.
10
+ * Blank lines and `#` comments are skipped. Negation with `!` is not supported, so such a line is skipped too.
11
+ *
12
+ * @param text - Contents of the ignore file.
13
+ * @returns Globs, two per pattern that may name a file or a directory. `dist/` gives one: any `dist` directory and all below it.
14
+ */
15
+ export declare function ignoreGlobs(text: string): string[];
16
+ /**
17
+ * @brief Reads the `.analyzeignore` of a repository, and writes one with {@link DEFAULT_IGNORE_LINES} when it has none.
18
+ *
19
+ * @param repo - Absolute path of the repository.
20
+ * @returns The globs of the file, and whether this call created the file.
21
+ */
22
+ export declare function loadIgnoreFile(repo: string): {
23
+ globs: string[];
24
+ created: boolean;
25
+ };
@@ -0,0 +1,43 @@
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 { ConfigPlanner } from './config';
12
+ export { addFilePage, type DocFile, type DocKind, DocPlanner, docKind } from './docs';
13
+ export { compareTreePaths, type FileLister, RepoFileLister, type Source } from './files';
14
+ export { DEFAULT_IGNORE_LINES, IGNORE_FILE, ignoreGlobs, loadIgnoreFile } from './ignore';
15
+ export { type ParsedGlossary, type ParsedTerm, parseGlossary } from './glossary/parse';
16
+ export { GlossaryPlanner } from './glossary/planner';
17
+ export { type TermFinder, TermIndex, TermLinker, type TermMatch } from './glossary/terms';
18
+ export { type ContentOf, type ContentSource, GraphBuilder, type IdentityOf } from './graph/builder';
19
+ export { type CodeHighlighter, ShikiHighlighter } from './highlight';
20
+ export { type LinkOrigin, ProseResolvers } from './markdown/links';
21
+ export { joinLines, type MarkdownLine, outlineLines, plainText } from './markdown/outline';
22
+ export { type LinkResolver, MarkdownRenderer, type RenderedMarkdown } from './markdown/renderer';
23
+ export { OpenApiPlanner } from './openapi/planner';
24
+ export { detectPackages, type PackageInfo } from './packages';
25
+ export { type Reporter, silentReporter } from './reporter';
26
+ export { RepositoryScanner, type ScanInput, type ScannerOptions } from './scanner';
27
+ export { type DefinitionOwner, DefinitionPlanner } from './schema/definitions';
28
+ export { describeSchema, type JsonObject, refName, type SchemaDescription, type SchemaProperty, type SchemaRef, type TypeExpression, typeOf, } from './schema/describe';
29
+ export { JsonSchemaPlanner } from './schema/planner';
30
+ export { DefinitionRegistry, normalizePointer, type RefTarget } from './schema/registry';
31
+ export { classifySkillFile, type SkillFileKind } from './skills/classify';
32
+ export { isInside, SKILL_FILE, type SkillLayout, skillLayouts, skillOwnedFiles } from './skills/layout';
33
+ export { SkillPlanner } from './skills/planner';
34
+ export { type SpecKind, SpecPlanner, specKind } from './specs';
35
+ export { type CatalogFile, type CatalogPlace, CatalogPlanner } from './sql/catalog';
36
+ export { DatabasePlanner } from './sql/database';
37
+ export { type ParsedColumn, type ParsedForeignKey, type ParsedIndex, type ParsedObject, type ParsedSchema, type ParsedTable, parseSqlSchema, } from './sql/parse';
38
+ export { SqlPlanner } from './sql/planner';
39
+ export { type ParsedColumnRef, type ParsedParameter, type ParsedQuery, type ParsedQueryTable, type ParsedResultColumn, parseQueryFile, } from './sql/query';
40
+ export { type ColumnEntry, columnOf, type TableEntry, TableRegistry } from './sql/registry';
41
+ export { type SqlComment, type SqlToken, tokenizeSql } from './sql/tokens';
42
+ export { layoutTree, type PlanFiles, type PhaseFiles, type TreeFiles } from './tasks/layout';
43
+ export { TaskPlanner, type TaskTreeSource } from './tasks/planner';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @brief A markdown document split into its YAML frontmatter and the rest.
3
+ *
4
+ * @property data - Parsed frontmatter fields. `{}` when there is no valid frontmatter.
5
+ * @property body - The markdown after the frontmatter block, as written.
6
+ */
7
+ export interface Frontmatter {
8
+ readonly data: Readonly<Record<string, unknown>>;
9
+ readonly body: string;
10
+ }
11
+ /**
12
+ * @brief Splits a leading YAML block from a markdown document. Invalid YAML yields empty data.
13
+ *
14
+ * @param source - Markdown text, with or without frontmatter.
15
+ * @returns The parsed frontmatter and the text after it.
16
+ */
17
+ export declare function splitFrontmatter(source: string): Frontmatter;
18
+ /**
19
+ * @brief Reads a frontmatter field as trimmed text, or `null` when it is missing, blank or no string.
20
+ *
21
+ * @param data - Parsed frontmatter, as `Frontmatter.data` holds it.
22
+ * @param key - Name of the field, such as `title`.
23
+ */
24
+ export declare function stringField(data: Readonly<Record<string, unknown>>, key: string): string | null;