@descent-vtt/spec-brief 0.1.0 → 0.2.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 (128) hide show
  1. package/CHANGELOG.md +264 -0
  2. package/README.md +90 -20
  3. package/dist/archive.d.ts +52 -2
  4. package/dist/archive.js +205 -37
  5. package/dist/archive.js.map +1 -1
  6. package/dist/brief.d.ts +2 -0
  7. package/dist/brief.js +5 -1
  8. package/dist/brief.js.map +1 -1
  9. package/dist/cli.d.ts +1 -1
  10. package/dist/cli.js +48 -14
  11. package/dist/cli.js.map +1 -1
  12. package/dist/collisions.d.ts +43 -12
  13. package/dist/collisions.js +90 -58
  14. package/dist/collisions.js.map +1 -1
  15. package/dist/config.d.ts +11 -0
  16. package/dist/config.js +58 -10
  17. package/dist/config.js.map +1 -1
  18. package/dist/corpus.d.ts +21 -1
  19. package/dist/corpus.js +51 -2
  20. package/dist/corpus.js.map +1 -1
  21. package/dist/engine.d.ts +33 -3
  22. package/dist/engine.js +112 -9
  23. package/dist/engine.js.map +1 -1
  24. package/dist/frontmatter.d.ts +18 -61
  25. package/dist/frontmatter.js +31 -300
  26. package/dist/frontmatter.js.map +1 -1
  27. package/dist/glob.d.ts +77 -54
  28. package/dist/glob.js +104 -433
  29. package/dist/glob.js.map +1 -1
  30. package/dist/index.d.ts +10 -8
  31. package/dist/index.js +8 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/links.d.ts +1 -1
  34. package/dist/links.js +3 -4
  35. package/dist/links.js.map +1 -1
  36. package/dist/lint.d.ts +33 -2
  37. package/dist/lint.js +9 -2
  38. package/dist/lint.js.map +1 -1
  39. package/dist/markdown.d.ts +26 -23
  40. package/dist/markdown.js +60 -237
  41. package/dist/markdown.js.map +1 -1
  42. package/dist/plugins.d.ts +14 -0
  43. package/dist/plugins.js +142 -6
  44. package/dist/plugins.js.map +1 -1
  45. package/dist/report.d.ts +40 -3
  46. package/dist/report.js +227 -11
  47. package/dist/report.js.map +1 -1
  48. package/dist/rules.d.ts +22 -4
  49. package/dist/rules.js +175 -45
  50. package/dist/rules.js.map +1 -1
  51. package/dist/scaffold.d.ts +1 -1
  52. package/dist/scaffold.js +10 -9
  53. package/dist/scaffold.js.map +1 -1
  54. package/dist/schedule.d.ts +133 -0
  55. package/dist/schedule.js +265 -0
  56. package/dist/schedule.js.map +1 -0
  57. package/dist/scope.d.ts +52 -0
  58. package/dist/scope.js +56 -0
  59. package/dist/scope.js.map +1 -0
  60. package/dist/text.d.ts +13 -0
  61. package/dist/text.js +23 -0
  62. package/dist/text.js.map +1 -1
  63. package/dist/trigger.d.ts +17 -0
  64. package/dist/trigger.js +49 -0
  65. package/dist/trigger.js.map +1 -0
  66. package/dist/types.d.ts +14 -5
  67. package/dist/types.js.map +1 -1
  68. package/dist/vendor/spec-core/markdown/frontmatter.d.ts +103 -0
  69. package/dist/vendor/spec-core/markdown/frontmatter.js +459 -0
  70. package/dist/vendor/spec-core/markdown/frontmatter.js.map +1 -0
  71. package/dist/vendor/spec-core/markdown/headings.d.ts +45 -0
  72. package/dist/vendor/spec-core/markdown/headings.js +199 -0
  73. package/dist/vendor/spec-core/markdown/headings.js.map +1 -0
  74. package/dist/vendor/spec-core/markdown/index.d.ts +5 -0
  75. package/dist/vendor/spec-core/markdown/index.js +4 -0
  76. package/dist/vendor/spec-core/markdown/index.js.map +1 -0
  77. package/dist/vendor/spec-core/markdown/layout.d.ts +39 -0
  78. package/dist/vendor/spec-core/markdown/layout.js +28 -0
  79. package/dist/vendor/spec-core/markdown/layout.js.map +1 -0
  80. package/dist/vendor/spec-core/markdown/links.d.ts +22 -0
  81. package/dist/vendor/spec-core/markdown/links.js +364 -0
  82. package/dist/vendor/spec-core/markdown/links.js.map +1 -0
  83. package/dist/vendor/spec-core/markdown/lists.d.ts +22 -0
  84. package/dist/vendor/spec-core/markdown/lists.js +127 -0
  85. package/dist/vendor/spec-core/markdown/lists.js.map +1 -0
  86. package/dist/vendor/spec-core/markdown/scan.d.ts +36 -0
  87. package/dist/vendor/spec-core/markdown/scan.js +439 -0
  88. package/dist/vendor/spec-core/markdown/scan.js.map +1 -0
  89. package/dist/vendor/spec-core/markdown/syntax.d.ts +75 -0
  90. package/dist/vendor/spec-core/markdown/syntax.js +181 -0
  91. package/dist/vendor/spec-core/markdown/syntax.js.map +1 -0
  92. package/dist/vendor/spec-core/markdown/tables.d.ts +18 -0
  93. package/dist/vendor/spec-core/markdown/tables.js +86 -0
  94. package/dist/vendor/spec-core/markdown/tables.js.map +1 -0
  95. package/dist/vendor/spec-core/markdown/types.d.ts +287 -0
  96. package/dist/vendor/spec-core/markdown/types.js +9 -0
  97. package/dist/vendor/spec-core/markdown/types.js.map +1 -0
  98. package/dist/vendor/spec-core/path/index.d.ts +1 -0
  99. package/dist/vendor/spec-core/path/index.js +2 -0
  100. package/dist/vendor/spec-core/path/index.js.map +1 -0
  101. package/dist/vendor/spec-core/path/posix.d.ts +83 -0
  102. package/dist/vendor/spec-core/path/posix.js +150 -0
  103. package/dist/vendor/spec-core/path/posix.js.map +1 -0
  104. package/dist/vendor/spec-core/pattern/automaton.d.ts +129 -0
  105. package/dist/vendor/spec-core/pattern/automaton.js +340 -0
  106. package/dist/vendor/spec-core/pattern/automaton.js.map +1 -0
  107. package/dist/vendor/spec-core/pattern/charset.d.ts +58 -0
  108. package/dist/vendor/spec-core/pattern/charset.js +116 -0
  109. package/dist/vendor/spec-core/pattern/charset.js.map +1 -0
  110. package/dist/vendor/spec-core/pattern/glob.d.ts +121 -0
  111. package/dist/vendor/spec-core/pattern/glob.js +481 -0
  112. package/dist/vendor/spec-core/pattern/glob.js.map +1 -0
  113. package/dist/vendor/spec-core/pattern/index.d.ts +6 -0
  114. package/dist/vendor/spec-core/pattern/index.js +4 -0
  115. package/dist/vendor/spec-core/pattern/index.js.map +1 -0
  116. package/dist/vendor/spec-core/pattern/regex.d.ts +67 -0
  117. package/dist/vendor/spec-core/pattern/regex.js +813 -0
  118. package/dist/vendor/spec-core/pattern/regex.js.map +1 -0
  119. package/dist/vendor/spec-core/text/index.d.ts +2 -0
  120. package/dist/vendor/spec-core/text/index.js +2 -0
  121. package/dist/vendor/spec-core/text/index.js.map +1 -0
  122. package/dist/vendor/spec-core/text/lines.d.ts +72 -0
  123. package/dist/vendor/spec-core/text/lines.js +156 -0
  124. package/dist/vendor/spec-core/text/lines.js.map +1 -0
  125. package/package.json +3 -2
  126. package/schema.json +17 -0
  127. package/src/vendor/spec-core/LICENSE +21 -0
  128. package/src/vendor/spec-core/README.md +8 -0
package/dist/glob.d.ts CHANGED
@@ -1,46 +1,41 @@
1
1
  /**
2
- * Globs: parsing, matching, and deciding whether two globs can name the same file.
2
+ * Scopes as globs: spec-core's `path` dialect, read the way spec-brief reads a
3
+ * brief.
3
4
  *
4
- * The dialect is the one people type: `**`, `*`, `?`, `[abc]`, `[!a-z]`,
5
- * `{a,b}` and `\` to escape. A pattern with no glob syntax at all names a
6
- * directory and everything beneath it, so `src/auth` covers
7
- * `src/auth/login.ts` - unless it names a file, one the tree holds or one with
8
- * an extension, which matches only itself. A trailing `/` always means a
9
- * directory. Paths
10
- * are repository-relative and POSIX, and matching is case-sensitive on every
11
- * host, because git's paths are and a result should not depend on who ran it.
12
- * `*` matches a leading dot; a scope that forgot its dotfiles is not a scope
13
- * that excludes them.
5
+ * The syntax, the automaton and the witness search are spec-core's, copied
6
+ * into `src/vendor/` and verified by hash, so the family's tools read one
7
+ * pattern the same way (spec-core ADR-0003). What is decided here is what
8
+ * spec-brief adds around it:
14
9
  *
15
- * Nothing here compiles to a `RegExp`. Matching and intersection are dynamic
16
- * programmes over the pattern and the subject, so a pattern of `*a*a*a*a*b`
17
- * against a long name costs the product of their lengths and cannot backtrack
18
- * into an exponent. The same property is why the sibling tools match their own
19
- * globs this way.
10
+ * - A pattern is relative to the repository root, so a leading `/` is refused
11
+ * rather than rooted at the filesystem; and a list entry's `!` has no list to
12
+ * belong to in a scope, so it is refused rather than read.
13
+ * - Paths compare case-sensitively on every host, as git's do.
14
+ * - A path with no glob syntax is read as the tree reads it: a file the tree
15
+ * holds is that file, a directory it holds is everything beneath it, and a
16
+ * path it does not hold is a file, unless it is written with a trailing `/`.
17
+ * The tree, not the spelling, knows that `Dockerfile` is a file and
18
+ * `docs/v1.2` a directory (ADR-0005, amended 2026-09-26).
19
+ * - A trailing `/**` is at least one segment, so `docs/**` is the directory's
20
+ * contents and a collision witness is always a file.
21
+ *
22
+ * Nothing here compiles to a `RegExp`. Matching costs at most the pattern's
23
+ * size times the path's length, and a question about two scopes that cannot be
24
+ * answered within the search's budget answers `undecided`, never a guess.
20
25
  */
21
- export type CharToken = {
22
- readonly kind: 'literal';
23
- readonly char: string;
24
- } | {
25
- readonly kind: 'any';
26
- } | {
27
- readonly kind: 'star';
28
- } | {
29
- readonly kind: 'class';
30
- readonly negated: boolean;
31
- readonly ranges: readonly (readonly [number, number])[];
32
- };
33
- export type Segment = {
34
- readonly kind: 'globstar';
35
- } | {
36
- readonly kind: 'pattern';
37
- readonly tokens: readonly CharToken[];
38
- readonly literal: boolean;
39
- };
26
+ import { isGlobSyntax, type Glob as CoreGlob, type LiteralReading, WITNESS_BUDGET, type Witness } from './vendor/spec-core/pattern/index.js';
27
+ export { isGlobSyntax, type LiteralReading, WITNESS_BUDGET, type Witness };
28
+ /** A literal path a pattern names, and how it was read. */
29
+ export interface Literal {
30
+ readonly path: string;
31
+ readonly reading: LiteralReading;
32
+ }
40
33
  export interface Glob {
41
34
  readonly source: string;
42
- /** One sequence of segments per brace alternative; a path matches when any does. */
43
- readonly alternatives: readonly (readonly Segment[])[];
35
+ /** The compiled pattern: spec-core's `path` dialect, case-sensitive. */
36
+ readonly compiled: CoreGlob;
37
+ /** Each path the pattern names with no glob syntax, one per brace alternative; empty when it has none. */
38
+ readonly literals: readonly Literal[];
44
39
  }
45
40
  export type GlobParse = {
46
41
  readonly ok: true;
@@ -49,31 +44,59 @@ export type GlobParse = {
49
44
  readonly ok: false;
50
45
  readonly error: string;
51
46
  };
52
- /** More alternatives than this is a pattern nobody meant. */
53
- export declare const MAX_ALTERNATIVES = 256;
54
47
  export interface ParseOptions {
55
- /** Whether a literal path is a file, from the tree when it is known. */
56
- readonly isFile?: ((path: string) => boolean) | undefined;
48
+ /**
49
+ * How a path with no glob syntax is read: `file`, that path alone;
50
+ * `directory`, everything beneath it; `either`, both. A function is asked
51
+ * per literal path, as {@link readingIn} answers for a tree. `file` when
52
+ * unset: a path nothing says is a directory is not read as one.
53
+ */
54
+ readonly literal?: LiteralReading | ((path: string) => LiteralReading) | undefined;
57
55
  }
56
+ /** Parses a scope pattern, or says why it cannot. */
58
57
  export declare function parseGlob(source: string, options?: ParseOptions): GlobParse;
58
+ /**
59
+ * Whether a path matches. The path is read as a repository path: empty and
60
+ * `.` segments are dropped, so `./src//a.ts` is `src/a.ts`.
61
+ */
59
62
  export declare function matchGlob(glob: Glob, path: string): boolean;
60
63
  /**
61
- * A path both globs match, or `null` when there is none. The answer is exact
62
- * for the dialect above: a `null` means no file can be in both scopes, and a
63
- * path is a witness a reader can check by eye.
64
+ * A shortest path every glob in `include` matches and none in `exclude` does,
65
+ * `none` as a proof that there is no such path, or `undecided` when the search
66
+ * met its budget first.
64
67
  */
65
- export declare function intersectGlobs(a: Glob, b: Glob): string | null;
68
+ export declare function globWitness(include: readonly Glob[], exclude?: readonly Glob[], budget?: number): Witness;
69
+ /** Whether every path `inner` matches is matched by one of `outer`, or `undecided`. */
70
+ export declare function globCovers(outer: readonly Glob[], inner: Glob, budget?: number): boolean | 'undecided';
66
71
  /**
67
- * A non-empty string both token sequences match, or `null`.
68
- *
69
- * Complete by a shortest-witness argument: in a shortest common string, no
70
- * character is absorbed by a star on both sides at once (dropping it would
71
- * leave a shorter one), so every character advances at least one sequence,
72
- * and the five moves below are all the ways that can happen.
72
+ * A path both globs match, or `null` when there is none: the 0.1 interface,
73
+ * kept for the library's callers. It cannot say `undecided`, so a search that
74
+ * meets its budget throws; {@link globWitness} answers in three ways.
73
75
  */
74
- export declare function intersectTokens(x: readonly CharToken[], y: readonly CharToken[]): string | null;
76
+ export declare function intersectGlobs(a: Glob, b: Glob, budget?: number): string | null;
75
77
  /**
76
- * The directory a glob is rooted in: its leading literal segments. A pattern
77
- * that names a file is rooted in that file's directory.
78
+ * The directories a walk must enter to find every match, one per brace
79
+ * alternative: the leading literal segments, or a literal file's directory.
80
+ * `''` for an alternative that can match at the root.
78
81
  */
82
+ export declare function globBases(glob: Glob): readonly string[];
83
+ /** The first of {@link globBases}: the 0.1 interface, kept for the library's callers. */
79
84
  export declare function globBase(glob: Glob): string;
85
+ /** A name with an extension, `login.ts` or `.eslintrc.json`, and not a dot-name such as `.github`. */
86
+ export declare function hasExtension(name: string): boolean;
87
+ /** The files a tree holds, and every directory above one. */
88
+ export interface Tree {
89
+ readonly files: ReadonlySet<string>;
90
+ readonly directories: ReadonlySet<string>;
91
+ }
92
+ /** The tree a list of files describes. Built once per list, which every brief of a run shares. */
93
+ export declare function treeOf(files: readonly string[]): Tree;
94
+ /** What the tree holds at a path: a file, a directory, or nothing. */
95
+ export declare function held(tree: Tree, path: string): 'file' | 'directory' | null;
96
+ /**
97
+ * How a tree reads a literal path: a directory it holds is a directory, and
98
+ * anything else is a file. Without a tree nothing is known to be a directory,
99
+ * so every literal is a file; a trailing `/` says otherwise, and never reaches
100
+ * this question.
101
+ */
102
+ export declare function readingIn(files: readonly string[] | null): (path: string) => LiteralReading;