@promptci/core 0.2.2 → 0.4.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 (181) hide show
  1. package/dist/action-pinning.d.ts.map +1 -1
  2. package/dist/action-pinning.js +86 -55
  3. package/dist/action-pinning.js.map +1 -1
  4. package/dist/agent-practices.d.ts +5 -1
  5. package/dist/agent-practices.d.ts.map +1 -1
  6. package/dist/agent-practices.js +59 -34
  7. package/dist/agent-practices.js.map +1 -1
  8. package/dist/ai-config.d.ts +13 -6
  9. package/dist/ai-config.d.ts.map +1 -1
  10. package/dist/ai-config.js +25 -78
  11. package/dist/ai-config.js.map +1 -1
  12. package/dist/baseline.d.ts +8 -0
  13. package/dist/baseline.d.ts.map +1 -1
  14. package/dist/baseline.js +15 -0
  15. package/dist/baseline.js.map +1 -1
  16. package/dist/ci-alignment.d.ts +3 -1
  17. package/dist/ci-alignment.d.ts.map +1 -1
  18. package/dist/ci-alignment.js +8 -1
  19. package/dist/ci-alignment.js.map +1 -1
  20. package/dist/close-match.d.ts +97 -0
  21. package/dist/close-match.d.ts.map +1 -0
  22. package/dist/close-match.js +215 -0
  23. package/dist/close-match.js.map +1 -0
  24. package/dist/command-context.d.ts +67 -0
  25. package/dist/command-context.d.ts.map +1 -0
  26. package/dist/command-context.js +291 -0
  27. package/dist/command-context.js.map +1 -0
  28. package/dist/command-validity.d.ts.map +1 -1
  29. package/dist/command-validity.js +510 -32
  30. package/dist/command-validity.js.map +1 -1
  31. package/dist/context-optimizer.d.ts.map +1 -1
  32. package/dist/context-optimizer.js +9 -2
  33. package/dist/context-optimizer.js.map +1 -1
  34. package/dist/dead-references.d.ts +14 -1
  35. package/dist/dead-references.d.ts.map +1 -1
  36. package/dist/dead-references.js +264 -17
  37. package/dist/dead-references.js.map +1 -1
  38. package/dist/dependency-staleness.d.ts.map +1 -1
  39. package/dist/dependency-staleness.js +24 -38
  40. package/dist/dependency-staleness.js.map +1 -1
  41. package/dist/detectors.js +1 -1
  42. package/dist/detectors.js.map +1 -1
  43. package/dist/discovery.d.ts +138 -0
  44. package/dist/discovery.d.ts.map +1 -0
  45. package/dist/discovery.js +569 -0
  46. package/dist/discovery.js.map +1 -0
  47. package/dist/duplicates.d.ts +24 -2
  48. package/dist/duplicates.d.ts.map +1 -1
  49. package/dist/duplicates.js +313 -9
  50. package/dist/duplicates.js.map +1 -1
  51. package/dist/fix-engine.d.ts.map +1 -1
  52. package/dist/fix-engine.js +75 -1
  53. package/dist/fix-engine.js.map +1 -1
  54. package/dist/frameworks/dotnet.d.ts.map +1 -1
  55. package/dist/frameworks/dotnet.js +10 -11
  56. package/dist/frameworks/dotnet.js.map +1 -1
  57. package/dist/frameworks/go.d.ts.map +1 -1
  58. package/dist/frameworks/go.js +8 -4
  59. package/dist/frameworks/go.js.map +1 -1
  60. package/dist/frameworks/nextjs.d.ts.map +1 -1
  61. package/dist/frameworks/nextjs.js +8 -17
  62. package/dist/frameworks/nextjs.js.map +1 -1
  63. package/dist/frameworks/python.d.ts.map +1 -1
  64. package/dist/frameworks/python.js +5 -3
  65. package/dist/frameworks/python.js.map +1 -1
  66. package/dist/frameworks/rust.d.ts.map +1 -1
  67. package/dist/frameworks/rust.js +3 -3
  68. package/dist/frameworks/rust.js.map +1 -1
  69. package/dist/frameworks/unity.d.ts.map +1 -1
  70. package/dist/frameworks/unity.js +6 -5
  71. package/dist/frameworks/unity.js.map +1 -1
  72. package/dist/gitignore.d.ts +31 -2
  73. package/dist/gitignore.d.ts.map +1 -1
  74. package/dist/gitignore.js +33 -8
  75. package/dist/gitignore.js.map +1 -1
  76. package/dist/health-score.d.ts +15 -1
  77. package/dist/health-score.d.ts.map +1 -1
  78. package/dist/health-score.js +25 -2
  79. package/dist/health-score.js.map +1 -1
  80. package/dist/hooks-settings-detector.d.ts.map +1 -1
  81. package/dist/hooks-settings-detector.js +5 -1
  82. package/dist/hooks-settings-detector.js.map +1 -1
  83. package/dist/index.d.ts +10 -2
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +16 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/known-paths.d.ts +82 -0
  88. package/dist/known-paths.d.ts.map +1 -0
  89. package/dist/known-paths.js +152 -0
  90. package/dist/known-paths.js.map +1 -0
  91. package/dist/makefile.d.ts.map +1 -1
  92. package/dist/makefile.js +17 -13
  93. package/dist/makefile.js.map +1 -1
  94. package/dist/manifest-consistency.d.ts +1 -1
  95. package/dist/manifest-consistency.d.ts.map +1 -1
  96. package/dist/manifest-consistency.js +18 -8
  97. package/dist/manifest-consistency.js.map +1 -1
  98. package/dist/markdown-fences.d.ts.map +1 -1
  99. package/dist/markdown-fences.js +7 -3
  100. package/dist/markdown-fences.js.map +1 -1
  101. package/dist/mcp-config-detector.d.ts.map +1 -1
  102. package/dist/mcp-config-detector.js +5 -1
  103. package/dist/mcp-config-detector.js.map +1 -1
  104. package/dist/project-type.d.ts +2 -1
  105. package/dist/project-type.d.ts.map +1 -1
  106. package/dist/project-type.js +36 -48
  107. package/dist/project-type.js.map +1 -1
  108. package/dist/prompt-cache.d.ts.map +1 -1
  109. package/dist/prompt-cache.js +13 -2
  110. package/dist/prompt-cache.js.map +1 -1
  111. package/dist/provenance/check.d.ts +40 -0
  112. package/dist/provenance/check.d.ts.map +1 -0
  113. package/dist/provenance/check.js +157 -0
  114. package/dist/provenance/check.js.map +1 -0
  115. package/dist/provenance/index.d.ts +13 -0
  116. package/dist/provenance/index.d.ts.map +1 -0
  117. package/dist/provenance/index.js +21 -0
  118. package/dist/provenance/index.js.map +1 -0
  119. package/dist/provenance/instruction-advice.d.ts +3 -0
  120. package/dist/provenance/instruction-advice.d.ts.map +1 -0
  121. package/dist/provenance/instruction-advice.js +570 -0
  122. package/dist/provenance/instruction-advice.js.map +1 -0
  123. package/dist/provenance/repo-checks.d.ts +3 -0
  124. package/dist/provenance/repo-checks.d.ts.map +1 -0
  125. package/dist/provenance/repo-checks.js +644 -0
  126. package/dist/provenance/repo-checks.js.map +1 -0
  127. package/dist/provenance/tool-config.d.ts +3 -0
  128. package/dist/provenance/tool-config.d.ts.map +1 -0
  129. package/dist/provenance/tool-config.js +480 -0
  130. package/dist/provenance/tool-config.js.map +1 -0
  131. package/dist/provenance/types.d.ts +116 -0
  132. package/dist/provenance/types.d.ts.map +1 -0
  133. package/dist/provenance/types.js +17 -0
  134. package/dist/provenance/types.js.map +1 -0
  135. package/dist/repo-context.d.ts +9 -0
  136. package/dist/repo-context.d.ts.map +1 -1
  137. package/dist/repo-context.js +35 -41
  138. package/dist/repo-context.js.map +1 -1
  139. package/dist/repo-tree.d.ts +163 -9
  140. package/dist/repo-tree.d.ts.map +1 -1
  141. package/dist/repo-tree.js +226 -34
  142. package/dist/repo-tree.js.map +1 -1
  143. package/dist/report.d.ts.map +1 -1
  144. package/dist/report.js +6 -0
  145. package/dist/report.js.map +1 -1
  146. package/dist/sample-text.d.ts +36 -0
  147. package/dist/sample-text.d.ts.map +1 -0
  148. package/dist/sample-text.js +72 -0
  149. package/dist/sample-text.js.map +1 -0
  150. package/dist/sarif.d.ts +27 -0
  151. package/dist/sarif.d.ts.map +1 -0
  152. package/dist/sarif.js +357 -0
  153. package/dist/sarif.js.map +1 -0
  154. package/dist/scan.d.ts.map +1 -1
  155. package/dist/scan.js +8 -2
  156. package/dist/scan.js.map +1 -1
  157. package/dist/scanner.d.ts +4 -3
  158. package/dist/scanner.d.ts.map +1 -1
  159. package/dist/scanner.js +36 -77
  160. package/dist/scanner.js.map +1 -1
  161. package/dist/security-pack.d.ts.map +1 -1
  162. package/dist/security-pack.js +117 -35
  163. package/dist/security-pack.js.map +1 -1
  164. package/dist/skill-supply-chain.d.ts.map +1 -1
  165. package/dist/skill-supply-chain.js +29 -19
  166. package/dist/skill-supply-chain.js.map +1 -1
  167. package/dist/skills-detector.d.ts.map +1 -1
  168. package/dist/skills-detector.js +11 -3
  169. package/dist/skills-detector.js.map +1 -1
  170. package/dist/token-estimates.d.ts +42 -0
  171. package/dist/token-estimates.d.ts.map +1 -0
  172. package/dist/token-estimates.js +200 -0
  173. package/dist/token-estimates.js.map +1 -0
  174. package/dist/types.d.ts +99 -0
  175. package/dist/types.d.ts.map +1 -1
  176. package/dist/types.js.map +1 -1
  177. package/dist/workspace-manifests.d.ts +6 -0
  178. package/dist/workspace-manifests.d.ts.map +1 -1
  179. package/dist/workspace-manifests.js +13 -8
  180. package/dist/workspace-manifests.js.map +1 -1
  181. package/package.json +5 -2
@@ -0,0 +1,215 @@
1
+ /**
2
+ * pcic-oonz: the one deterministic "is this a typo for that?" test the
3
+ * mechanical fix recipes share.
4
+ *
5
+ * A fix recipe may only rewrite a name when the repository offers exactly one
6
+ * plausible replacement — otherwise the finding stays advisory and a human
7
+ * picks. "Plausible" has to be a rule, not a judgement call: detectors are
8
+ * rule-based, make no LLM call, and must produce identical output for
9
+ * identical input, so the matcher below is a pure function of the name and the
10
+ * candidate set, with no scoring heuristics, no locale and no ordering
11
+ * dependence (a tie is resolved by reporting no match at all, never by taking
12
+ * whichever candidate the manifest happened to list first).
13
+ *
14
+ * Two rules, applied in order:
15
+ *
16
+ * 1. **Separator / case equality.** The name and the candidate are equal once
17
+ * lowercased with `- _ : . /` and spaces removed, so `type-check` matches
18
+ * `typecheck` and `Build` matches `build`. Applied first because it is an
19
+ * exact correspondence, not a guess.
20
+ * 2. **Damerau-Levenshtein distance ≤ {@link CLOSE_MATCH_MAX_DISTANCE}** —
21
+ * the optimal-string-alignment variant, so a single transposition
22
+ * (`tets` → `test`, `bulid` → `build`) costs 1 rather than 2. Only for
23
+ * names of at least {@link CLOSE_MATCH_MIN_LENGTH} characters: two edits
24
+ * on a three-character name is a different word, not a typo (`dev` would
25
+ * "match" `test`).
26
+ *
27
+ * Either rule must produce exactly ONE winner — one normalised-equal
28
+ * candidate, or one candidate alone at the minimum distance. Zero candidates
29
+ * and ties both yield `undefined`.
30
+ *
31
+ * {@link closestUniqueMatch} answers "is there one plausible candidate worth
32
+ * NAMING?" and is deliberately permissive. Whether that candidate may be
33
+ * applied without a human looking is a separate, much stricter question —
34
+ * see {@link isMechanicalRename}.
35
+ */
36
+ /** Maximum edit distance between a name and the candidate that may replace it. */
37
+ export const CLOSE_MATCH_MAX_DISTANCE = 2;
38
+ /** Shortest name the distance rule will judge; shorter names use rule 1 only. */
39
+ export const CLOSE_MATCH_MIN_LENGTH = 4;
40
+ /** Lowercased with the separators naming conventions disagree about removed. */
41
+ function normalizeName(name) {
42
+ return name.toLowerCase().replace(/[-_:./\s]/g, '');
43
+ }
44
+ /** Shortest name a two-edit difference may be judged a typo rather than a different script. */
45
+ export const MECHANICAL_TWO_EDIT_MIN_LENGTH = 8;
46
+ /** Shortest differing segment that may be corrected by an arbitrary single edit. */
47
+ export const MECHANICAL_SEGMENT_MIN_LENGTH = 5;
48
+ /** True when `a` and `b` are the same characters with one adjacent pair swapped. */
49
+ function isAdjacentTransposition(a, b) {
50
+ if (a.length !== b.length)
51
+ return false;
52
+ const diff = [];
53
+ for (let i = 0; i < a.length; i++)
54
+ if (a[i] !== b[i])
55
+ diff.push(i);
56
+ return diff.length === 2 && diff[1] === diff[0] + 1 && a[diff[0]] === b[diff[1]] && a[diff[1]] === b[diff[0]];
57
+ }
58
+ /** True when `a` and `b` differ only by substituting digits for digits, position for position. */
59
+ function isDigitForDigitSubstitution(a, b) {
60
+ if (a.length !== b.length)
61
+ return false;
62
+ let changed = false;
63
+ for (let i = 0; i < a.length; i++) {
64
+ if (a[i] === b[i])
65
+ continue;
66
+ if (!/^\d$/.test(a[i]) || !/^\d$/.test(b[i]))
67
+ return false;
68
+ changed = true;
69
+ }
70
+ return changed;
71
+ }
72
+ /**
73
+ * pcic-oonz: whether replacing `missing` with `candidate` is a MECHANICAL
74
+ * rename — a misspelling of one name — rather than a plausible reference to a
75
+ * genuinely different script. Only a mechanical rename may be auto-applied;
76
+ * {@link closestUniqueMatch} alone is far too loose for that.
77
+ *
78
+ * The problem the extra rules solve: a one-edit neighbour is very often a real
79
+ * sibling script, and rewriting to it silently runs the wrong command.
80
+ * `test:api` → `test:app`, `test:unit` → `test:init`, `db:up` → `db:rm`,
81
+ * `test` → `best`, `build:v1` → `build:v2` are each a unique nearest
82
+ * neighbour, and each rewrite is wrong. So:
83
+ *
84
+ * 1. A pure case / separator difference (`type-check` → `typecheck`) is always
85
+ * mechanical: the two names denote the same thing in different styles.
86
+ * 2. Otherwise both names must have the SAME number of `:`-separated segments,
87
+ * with the difference confined to exactly one of them. A command that
88
+ * gains, loses or re-scopes a segment is a different command.
89
+ * 3. That segment pair must be within one edit, or two only when the whole
90
+ * name is at least {@link MECHANICAL_TWO_EDIT_MIN_LENGTH} characters —
91
+ * two edits on a short name reaches too far (`test` → `dist`).
92
+ * 4. A trailing-digit variant suffix is never corrected: `v1` → `v2`,
93
+ * `py2` → `py3`, `1` → `2` select a version or a target, and the digit is
94
+ * the whole point of the name.
95
+ * 5. In a differing segment shorter than
96
+ * {@link MECHANICAL_SEGMENT_MIN_LENGTH} characters, only a transposition
97
+ * or a mid-name digit swap counts. A single substituted LETTER in a short
98
+ * name usually spells another real token (`api`/`app`, `test`/`best`,
99
+ * `unit`/`init`), and no deterministic rule can tell which was meant — but
100
+ * `e3e`/`e2e` is not two words, and `bulid`/`build` is a slip of the
101
+ * fingers. (A dictionary would separate these more sharply; the repository
102
+ * has no dictionary and detectors make no network call, so the test is
103
+ * structural.)
104
+ *
105
+ * Anything this rejects is still reported — with the candidate named
106
+ * cautiously in the recommendation — just never rewritten automatically.
107
+ */
108
+ export function isMechanicalRename(missing, candidate) {
109
+ if (!missing || !candidate || missing === candidate)
110
+ return false;
111
+ // 1. Same name, different convention.
112
+ if (normalizeName(missing) === normalizeName(candidate))
113
+ return true;
114
+ // 2. One differing `:` segment.
115
+ const from = missing.split(':');
116
+ const to = candidate.split(':');
117
+ if (from.length !== to.length)
118
+ return false;
119
+ const differing = from.map((seg, i) => (seg === to[i] ? -1 : i)).filter((i) => i !== -1);
120
+ if (differing.length !== 1)
121
+ return false;
122
+ const a = from[differing[0]];
123
+ const b = to[differing[0]];
124
+ // 3. Within the edit budget for this name's length.
125
+ const distance = damerauLevenshtein(a, b);
126
+ if (distance < 1 || distance > CLOSE_MATCH_MAX_DISTANCE)
127
+ return false;
128
+ if (distance === 2 && missing.length < MECHANICAL_TWO_EDIT_MIN_LENGTH)
129
+ return false;
130
+ // 4. A trailing-digit variant is a choice, not a typo.
131
+ const stem = (seg) => seg.replace(/\d+$/, '');
132
+ if (stem(a) === stem(b))
133
+ return false;
134
+ // 5. A short segment may only be transposed, or have a mid-name digit swapped.
135
+ if (Math.max(a.length, b.length) < MECHANICAL_SEGMENT_MIN_LENGTH) {
136
+ return isAdjacentTransposition(a, b) || isDigitForDigitSubstitution(a, b);
137
+ }
138
+ return true;
139
+ }
140
+ /**
141
+ * Damerau-Levenshtein distance, optimal-string-alignment variant: insertions,
142
+ * deletions, substitutions and transpositions of ADJACENT characters each cost
143
+ * 1. OSA (rather than unrestricted Damerau-Levenshtein) is deliberate — it is
144
+ * the simpler recurrence, and no substring is edited twice in a typo short
145
+ * enough for this matcher to accept.
146
+ */
147
+ export function damerauLevenshtein(a, b) {
148
+ if (a === b)
149
+ return 0;
150
+ if (a.length === 0)
151
+ return b.length;
152
+ if (b.length === 0)
153
+ return a.length;
154
+ // Three rolling rows: the previous two plus the one being filled.
155
+ let twoBack = [];
156
+ let oneBack = Array.from({ length: b.length + 1 }, (_, j) => j);
157
+ let current = new Array(b.length + 1);
158
+ for (let i = 1; i <= a.length; i++) {
159
+ current[0] = i;
160
+ for (let j = 1; j <= b.length; j++) {
161
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
162
+ let best = Math.min(oneBack[j] + 1, // deletion
163
+ current[j - 1] + 1, // insertion
164
+ oneBack[j - 1] + cost);
165
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
166
+ best = Math.min(best, twoBack[j - 2] + 1); // transposition
167
+ }
168
+ current[j] = best;
169
+ }
170
+ twoBack = oneBack;
171
+ oneBack = current;
172
+ current = new Array(b.length + 1);
173
+ }
174
+ return oneBack[b.length];
175
+ }
176
+ /**
177
+ * The single candidate close enough to `name` to replace it mechanically, or
178
+ * `undefined` when there is none or more than one. See the module comment for
179
+ * the two rules; a candidate equal to `name` is ignored (the caller already
180
+ * established that `name` is absent, so an equal entry is a different thing
181
+ * with the same spelling, never the fix).
182
+ */
183
+ export function closestUniqueMatch(name, candidates) {
184
+ const pool = [...new Set(candidates)].filter((c) => c !== name && c.length > 0);
185
+ if (pool.length === 0 || name.length === 0)
186
+ return undefined;
187
+ // Rule 1: separator / case equality.
188
+ const normalized = normalizeName(name);
189
+ const equal = pool.filter((c) => normalizeName(c) === normalized);
190
+ if (equal.length === 1)
191
+ return equal[0];
192
+ if (equal.length > 1)
193
+ return undefined; // ambiguous: two spellings of one name
194
+ // Rule 2: a unique nearest neighbour within the distance budget.
195
+ if (name.length < CLOSE_MATCH_MIN_LENGTH)
196
+ return undefined;
197
+ let best = CLOSE_MATCH_MAX_DISTANCE + 1;
198
+ let winner;
199
+ let tied = false;
200
+ for (const candidate of pool) {
201
+ const distance = damerauLevenshtein(name, candidate);
202
+ if (distance > CLOSE_MATCH_MAX_DISTANCE)
203
+ continue;
204
+ if (distance < best) {
205
+ best = distance;
206
+ winner = candidate;
207
+ tied = false;
208
+ }
209
+ else if (distance === best) {
210
+ tied = true;
211
+ }
212
+ }
213
+ return tied ? undefined : winner;
214
+ }
215
+ //# sourceMappingURL=close-match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close-match.js","sourceRoot":"","sources":["../src/close-match.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * What the text around a documented command says about where and how it is run
3
+ * (pcic-1ik0.2, issue #157).
4
+ *
5
+ * A script the root manifest lacks is often defined in the package the text
6
+ * points at ("From `packages/docs/`:", a "Site (from `site/` directory)"
7
+ * heading). The text that counts is narrow on purpose: the command's own line,
8
+ * the sentence or list lead-in that introduces it, the `#` comment lines above
9
+ * it in its block, and the nearest heading. Anything wider silences real
10
+ * findings.
11
+ *
12
+ * Whether a script rewrite may be applied unseen is a different question and is
13
+ * default-deny: see `cautionary` and the single-package rule in command-validity.ts.
14
+ *
15
+ * Pure text work: nothing here touches the filesystem. The detector resolves the
16
+ * directory tokens against the repository.
17
+ */
18
+ /** Per-line structure of one document: where the fences are, so a `# comment` in a block is not a heading. */
19
+ export type LineStructure = {
20
+ lines: readonly string[];
21
+ /** `inFence[n - 1]`: line `n` is a fence marker or sits inside a fenced block (closed or not). */
22
+ inFence: readonly boolean[];
23
+ /** Content line number -> the line number of the opening fence of its block. */
24
+ opener: ReadonlyMap<number, number>;
25
+ };
26
+ export declare function lineStructure(content: string): LineStructure;
27
+ /** Whether line `n` (1-based) is a heading. */
28
+ export declare function isHeadingLine(s: LineStructure, n: number): boolean;
29
+ /** The nearest heading at or above line `n`, as a line number. */
30
+ export declare function nearestHeading(s: LineStructure, n: number): number | undefined;
31
+ /** The nearest heading at or above line `n` and every heading above it of a lower level (its parents), nearest first. */
32
+ export declare function headingChain(s: LineStructure, n: number): number[];
33
+ /** Straight quotes in place of the curly ones, so a marker is found whichever apostrophe the author typed. */
34
+ export declare function normalizeQuotes(text: string): string;
35
+ export type CommandContext = {
36
+ /**
37
+ * Text that may name the directory the command runs from: its own line, the
38
+ * paragraph or list lead-in that introduces it, the comment lines above it in
39
+ * its block, the nearest heading (for a command written in a heading, the
40
+ * paragraph under it), the list items that enclose it, a `<details>` summary and
41
+ * a table's header row.
42
+ */
43
+ text: string[];
44
+ /**
45
+ * A cautionary or negating marker anywhere that frames the command: its whole heading chain, whole block
46
+ * or paragraph, every enclosing list item, its table row and header, an enclosing blockquote or
47
+ * `<details>` summary, or a trailing comment on its own line. Wide on purpose (non-English cautions
48
+ * are a known gap).
49
+ */
50
+ cautionary: boolean;
51
+ /**
52
+ * The command's own sentence, or the sentence that introduces its block, says
53
+ * un-negated that it runs at the repository root and names no directory itself.
54
+ * A directory named in the same sentence wins over a root phrase.
55
+ */
56
+ explicitRoot: boolean;
57
+ };
58
+ /** Splits text into sentences (and colon clauses); a terminator counts only before whitespace or the end. */
59
+ export declare function sentencesOf(text: string): string[];
60
+ /**
61
+ * The text that frames the command at `line` (1-based; `command` is its text).
62
+ * `namesDirectory` says whether a piece of text names an existing directory.
63
+ */
64
+ export declare function commandContext(s: LineStructure, line: number, command: string, namesDirectory: (text: string) => boolean): CommandContext;
65
+ /** Candidate directory names in `texts`, in order, without duplicates. They are claims about the text, not yet checked against the repository. */
66
+ export declare function directoryTokens(texts: readonly string[]): string[];
67
+ //# sourceMappingURL=command-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-context.d.ts","sourceRoot":"","sources":["../src/command-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,8GAA8G;AAC9G,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,kGAAkG;IAClG,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;IAC5B,gFAAgF;IAChF,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAU5D;AAmBD,+CAA+C;AAC/C,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAElE;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9E;AAED,yHAAyH;AACzH,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAWlE;AAED,8GAA8G;AAC9G,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AA4EF,6GAA6G;AAC7G,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD;AAeD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,aAAa,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACxC,cAAc,CAmFhB;AAYD,kJAAkJ;AAClJ,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAWlE"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * What the text around a documented command says about where and how it is run
3
+ * (pcic-1ik0.2, issue #157).
4
+ *
5
+ * A script the root manifest lacks is often defined in the package the text
6
+ * points at ("From `packages/docs/`:", a "Site (from `site/` directory)"
7
+ * heading). The text that counts is narrow on purpose: the command's own line,
8
+ * the sentence or list lead-in that introduces it, the `#` comment lines above
9
+ * it in its block, and the nearest heading. Anything wider silences real
10
+ * findings.
11
+ *
12
+ * Whether a script rewrite may be applied unseen is a different question and is
13
+ * default-deny: see `cautionary` and the single-package rule in command-validity.ts.
14
+ *
15
+ * Pure text work: nothing here touches the filesystem. The detector resolves the
16
+ * directory tokens against the repository.
17
+ */
18
+ import { fencedBlocks } from './markdown-fences.js';
19
+ export function lineStructure(content) {
20
+ const lines = content.split(/\r?\n/);
21
+ const inFence = new Array(lines.length).fill(false);
22
+ const opener = new Map();
23
+ for (const block of fencedBlocks(content)) {
24
+ const last = block.closed ? block.contentStartLine + block.lines.length : lines.length;
25
+ for (let n = block.openLine; n <= last && n <= lines.length; n++)
26
+ inFence[n - 1] = true;
27
+ for (let n = block.contentStartLine; n < block.contentStartLine + block.lines.length; n++)
28
+ opener.set(n, block.openLine);
29
+ }
30
+ return { lines, inFence, opener };
31
+ }
32
+ const ATX_RE = /^ {0,3}(#{1,6})(?:\s|$)/;
33
+ const SETEXT_UNDERLINE_RE = /^ {0,3}(=+|-{2,})\s*$/;
34
+ const LIST_ITEM_RE = /^\s*(?:[-*+]|\d+[.)])\s/;
35
+ /** The level (1-6) of the heading at line `n`: ATX, or the text line above a setext underline. Never inside a fence. */
36
+ function headingLevel(s, n) {
37
+ if (n < 1 || n > s.lines.length || s.inFence[n - 1])
38
+ return undefined;
39
+ const text = s.lines[n - 1];
40
+ const atx = ATX_RE.exec(text);
41
+ if (atx)
42
+ return atx[1].length;
43
+ if (text.trim() === '' || LIST_ITEM_RE.test(text) || /^\s*>/.test(text))
44
+ return undefined;
45
+ const next = s.lines[n];
46
+ if (next === undefined || s.inFence[n])
47
+ return undefined;
48
+ const underline = SETEXT_UNDERLINE_RE.exec(next);
49
+ return underline ? (underline[1].startsWith('=') ? 1 : 2) : undefined;
50
+ }
51
+ /** Whether line `n` (1-based) is a heading. */
52
+ export function isHeadingLine(s, n) {
53
+ return headingLevel(s, n) !== undefined;
54
+ }
55
+ /** The nearest heading at or above line `n`, as a line number. */
56
+ export function nearestHeading(s, n) {
57
+ for (let i = Math.min(n, s.lines.length); i >= 1; i--)
58
+ if (isHeadingLine(s, i))
59
+ return i;
60
+ return undefined;
61
+ }
62
+ /** The nearest heading at or above line `n` and every heading above it of a lower level (its parents), nearest first. */
63
+ export function headingChain(s, n) {
64
+ const chain = [];
65
+ let level = 7;
66
+ for (let i = Math.min(n, s.lines.length); i >= 1 && level > 1; i--) {
67
+ const l = headingLevel(s, i);
68
+ if (l !== undefined && l < level) {
69
+ chain.push(i);
70
+ level = l;
71
+ }
72
+ }
73
+ return chain;
74
+ }
75
+ /** Straight quotes in place of the curly ones, so a marker is found whichever apostrophe the author typed. */
76
+ export function normalizeQuotes(text) {
77
+ return text.replace(/[‘’ʼ′]/g, "'").replace(/[“”]/g, '"');
78
+ }
79
+ const ROOT_RE = /\b(?:at|in|from|on|under)\s+(?:the\s+)?(?:(?:repo(?:sitory)?|project|workspace|monorepo)\s+)?root\b|\b(?:repo(?:sitory)?|project|workspace|monorepo)\s+root\b|\broot\s+(?:directory|folder|of\s+(?:the\s+)?(?:repo(?:sitory)?|project|monorepo))\b/i;
80
+ const NEGATION_RE = /\b(?:not|never|without|instead\s+of|rather\s+than|other\s+than|except|unlike)\b|n't\b/i;
81
+ /** Words and marks that say a command is shown as something not to do. Applied to text with straight quotes. */
82
+ const CAUTION_RE = /\b(?:don'?t|do\s+not|doesn'?t|never|avoid|wrong|bad|incorrect|invalid|broken|deprecated|outdated|obsolete|legacy|old|removed|renamed|anti-?pattern|typo|mistakes?|warning|should\s+not|shouldn'?t|must\s+not|can'?t|cannot|fails?|failing|instead\s+of|no\s+longer|gone|previously|dropped|not\s+(?:this|that|like\s+this|recommended|to))\b|[❌✗✘✖⚠\u{1f6ab}⛔]|~~|<\/?(?:del|s|strike)>|\bbefore\s*:/iu;
83
+ /** Up to `max` contiguous non-blank, non-heading, non-fence lines ending at line `from` (1-based). */
84
+ function paragraphEndingAt(s, from, max) {
85
+ const out = [];
86
+ for (let n = from; n >= 1 && out.length < max; n--) {
87
+ if (s.inFence[n - 1] || isHeadingLine(s, n) || s.lines[n - 1].trim() === '')
88
+ break;
89
+ out.unshift(s.lines[n - 1]);
90
+ }
91
+ return out;
92
+ }
93
+ /** The sentence that introduces the list a list item belongs to: the paragraph above the list, past its other items. */
94
+ function listLeadIn(s, line) {
95
+ for (let n = line - 1; n >= 1 && line - n <= 40; n--) {
96
+ if (s.inFence[n - 1] || isHeadingLine(s, n))
97
+ return [];
98
+ const text = s.lines[n - 1];
99
+ if (text.trim() === '' || LIST_ITEM_RE.test(text) || /^\s{2,}\S/.test(text))
100
+ continue;
101
+ return paragraphEndingAt(s, n, 3);
102
+ }
103
+ return [];
104
+ }
105
+ function indentOf(text) {
106
+ return /^\s*/.exec(text)[0].replace(/\t/g, ' ').length;
107
+ }
108
+ /** The list items that enclose line `from` (a list item, or a line or block nested under one), nearest first. */
109
+ function ancestorListItems(s, from) {
110
+ const out = [];
111
+ let indent = indentOf(s.lines[from - 1] ?? '');
112
+ for (let n = from - 1; n >= 1 && from - n <= 200 && indent > 0; n--) {
113
+ if (s.inFence[n - 1] || isHeadingLine(s, n))
114
+ continue;
115
+ const text = s.lines[n - 1];
116
+ if (LIST_ITEM_RE.test(text) && indentOf(text) < indent) {
117
+ out.push(text);
118
+ indent = indentOf(text);
119
+ }
120
+ }
121
+ return out;
122
+ }
123
+ /** Contiguous lines around `line` that satisfy `keep`, up to 60 each way (a table, a blockquote). */
124
+ function runOfLines(s, line, keep) {
125
+ let first = line;
126
+ while (first > 1 && line - first < 60 && keep(s.lines[first - 2]))
127
+ first--;
128
+ let last = line;
129
+ while (last < s.lines.length && last - line < 60 && keep(s.lines[last]))
130
+ last++;
131
+ return s.lines.slice(first - 1, last);
132
+ }
133
+ /** The `<summary>` text of the `<details>` element that encloses line `from`, if any. */
134
+ function enclosingSummary(s, from) {
135
+ let depth = 0;
136
+ for (let n = from - 1; n >= 1 && from - n <= 300; n--) {
137
+ const text = s.lines[n - 1];
138
+ if (/<\/details>/i.test(text))
139
+ depth++;
140
+ if (/<details\b/i.test(text)) {
141
+ if (depth > 0) {
142
+ depth--;
143
+ continue;
144
+ }
145
+ const block = s.lines.slice(n - 1, Math.min(s.lines.length, n + 6)).join('\n');
146
+ return /<summary[\s\S]*?<\/summary>/i.exec(block)?.slice(0, 1) ?? [text];
147
+ }
148
+ }
149
+ return [];
150
+ }
151
+ /** Splits text into sentences (and colon clauses); a terminator counts only before whitespace or the end. */
152
+ export function sentencesOf(text) {
153
+ return (text.match(/[^.!?;:]+(?:[.!?;:]+(?=\s|$)|$)/g) ?? [text]).map((x) => x.trim()).filter(Boolean);
154
+ }
155
+ /** The sentence of `lineText` that holds `command` (the whole line when it is not found in it). */
156
+ function sentenceHolding(lineText, command) {
157
+ const at = lineText.indexOf(command);
158
+ if (at === -1)
159
+ return lineText;
160
+ let cursor = 0;
161
+ for (const raw of lineText.match(/[^.!?;:]+(?:[.!?;:]+(?=\s|$)|$)/g) ?? [lineText]) {
162
+ const end = cursor + raw.length;
163
+ if (at < end)
164
+ return raw.trim();
165
+ cursor = end;
166
+ }
167
+ return lineText;
168
+ }
169
+ /**
170
+ * The text that frames the command at `line` (1-based; `command` is its text).
171
+ * `namesDirectory` says whether a piece of text names an existing directory.
172
+ */
173
+ export function commandContext(s, line, command, namesDirectory) {
174
+ const own = s.lines[line - 1] ?? '';
175
+ const text = [own];
176
+ const open = s.opener.get(line);
177
+ const rootCandidates = [];
178
+ let anchor = line;
179
+ let introduction = [];
180
+ if (open !== undefined) {
181
+ anchor = open;
182
+ for (let n = line - 1; n > open; n--) {
183
+ const above = s.lines[n - 1].trim();
184
+ if (!above.startsWith('#'))
185
+ break;
186
+ text.push(above);
187
+ }
188
+ // The blank lines between an introducing sentence and its block do not break the link.
189
+ let intro = open - 1;
190
+ while (intro >= 1 && s.lines[intro - 1].trim() === '')
191
+ intro--;
192
+ introduction = paragraphEndingAt(s, intro, 4);
193
+ // A trailing comment on the command line can say where it runs (`npm run dev # at the repo root`).
194
+ rootCandidates.push(own);
195
+ }
196
+ else if (LIST_ITEM_RE.test(own)) {
197
+ introduction = listLeadIn(s, line);
198
+ rootCandidates.push(sentenceHolding(own, command));
199
+ }
200
+ else if (!isHeadingLine(s, line)) {
201
+ introduction = paragraphEndingAt(s, line - 1, 3);
202
+ rootCandidates.push(sentenceHolding(own, command));
203
+ }
204
+ text.push(...introduction);
205
+ // What encloses the command: the list items it sits under, a <details> summary, a table's header row.
206
+ const around = [...ancestorListItems(s, anchor), ...enclosingSummary(s, anchor)];
207
+ if (own.includes('|') && open === undefined) {
208
+ const table = runOfLines(s, line, (t) => t.includes('|'));
209
+ around.push(...table.slice(0, 2));
210
+ }
211
+ text.push(...around);
212
+ const lastIntroSentence = sentencesOf(introduction.join(' ')).pop();
213
+ if (lastIntroSentence)
214
+ rootCandidates.push(lastIntroSentence);
215
+ const headingLines = headingChain(s, anchor);
216
+ const nearest = headingLines[0];
217
+ if (nearest !== undefined) {
218
+ text.push(s.lines[nearest - 1]);
219
+ rootCandidates.push(s.lines[nearest - 1]);
220
+ }
221
+ if (isHeadingLine(s, line)) {
222
+ let started = false;
223
+ for (let n = line + 1; n <= s.lines.length && n <= line + 8; n++) {
224
+ if (s.inFence[n - 1] || isHeadingLine(s, n))
225
+ break;
226
+ const below = s.lines[n - 1];
227
+ if (below.trim() === '') {
228
+ if (started)
229
+ break;
230
+ continue;
231
+ }
232
+ started = true;
233
+ text.push(below);
234
+ const first = sentencesOf(below)[0];
235
+ if (first)
236
+ rootCandidates.push(first);
237
+ }
238
+ }
239
+ // Caution is wide on purpose (RULE 2): the whole block, paragraph, table, blockquote and every ancestor heading.
240
+ const scope = [...text, ...headingLines.map((n) => s.lines[n - 1])];
241
+ if (open !== undefined) {
242
+ scope.push(s.lines[open - 1]);
243
+ let n = open + 1;
244
+ while (n <= s.lines.length && s.opener.get(n) === open)
245
+ scope.push(s.lines[n++ - 1]);
246
+ if (n <= s.lines.length && s.inFence[n - 1])
247
+ scope.push(s.lines[n - 1]);
248
+ }
249
+ else if (!isHeadingLine(s, line)) {
250
+ scope.push(...paragraphEndingAt(s, line, 30));
251
+ for (let n = line + 1; n <= s.lines.length && n <= line + 30; n++) {
252
+ if (s.inFence[n - 1] || isHeadingLine(s, n) || s.lines[n - 1].trim() === '')
253
+ break;
254
+ scope.push(s.lines[n - 1]);
255
+ }
256
+ }
257
+ if (/^\s*>/.test(own))
258
+ scope.push(...runOfLines(s, line, (t) => /^\s*>/.test(t)));
259
+ if (own.includes('|') && open === undefined)
260
+ scope.push(...runOfLines(s, line, (t) => t.includes('|')));
261
+ const cautionary = CAUTION_RE.test(normalizeQuotes(scope.join('\n')));
262
+ const explicitRoot = rootCandidates.some((sentence) => {
263
+ const plain = normalizeQuotes(sentence);
264
+ return ROOT_RE.test(plain) && !NEGATION_RE.test(plain) && !namesDirectory(sentence);
265
+ });
266
+ return { text, cautionary, explicitRoot };
267
+ }
268
+ /**
269
+ * A backticked token, a bare token ending in `/`, or the argument of `cd`: the
270
+ * ways prose names a directory. A bare `dir/` that runs into a word (`site/index.html`)
271
+ * or a glob (`packages/*`) is a path, not a directory name.
272
+ */
273
+ const DIR_TOKEN_RE = /`([^`\s]+)`|(?<![\w./@-])((?:\.{1,2}\/)?[\w@.-]+(?:\/[\w@.-]+)*\/)(?![\w@.*?[{-])|\bcd\s+(?:\.\/)?([\w@.-]+(?:\/[\w@.-]+)*)|\b(?:from|in|inside|under|within|into)\s+(?:the\s+)?([\w@.-]+(?:\/[\w@.-]+)*)/gi;
274
+ const NOT_A_DIR_RE = /[*?<>{}[\]$~%\\]/;
275
+ const MAX_TOKENS = 24;
276
+ /** Candidate directory names in `texts`, in order, without duplicates. They are claims about the text, not yet checked against the repository. */
277
+ export function directoryTokens(texts) {
278
+ const seen = new Set();
279
+ for (const text of texts) {
280
+ for (const m of text.matchAll(DIR_TOKEN_RE)) {
281
+ const token = (m[1] ?? m[2] ?? m[3] ?? m[4] ?? '').replace(/^\.\//, '').replace(/\/+$/, '');
282
+ if (!token || token === '.' || NOT_A_DIR_RE.test(token))
283
+ continue;
284
+ seen.add(token);
285
+ if (seen.size >= MAX_TOKENS)
286
+ return [...seen];
287
+ }
288
+ }
289
+ return [...seen];
290
+ }
291
+ //# sourceMappingURL=command-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-context.js","sourceRoot":"","sources":["../src/command-context.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"command-validity.d.ts","sourceRoot":"","sources":["../src/command-validity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAsQhD,8FAA8F;AAC9F,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAK3C,CAAC;AA2oBH;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CAG3E;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB;;;;;;;;OAQG;IACH,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAC5C,CAAC;AAQF,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAOrE"}
1
+ {"version":3,"file":"command-validity.d.ts","sourceRoot":"","sources":["../src/command-validity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6iBhD,8FAA8F;AAC9F,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAK3C,CAAC;AAkyBH;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CAG3E;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB;;;;;;;;OAQG;IACH,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAC5C,CAAC;AAQF,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,eAAe,CAOrE"}