chaffjs 0.15.0 → 0.17.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 (528) hide show
  1. package/README.md +27 -2
  2. package/dist/address-chain.js +1 -1
  3. package/dist/address-chain.js.map +1 -1
  4. package/dist/backends/anthropic.d.ts +2 -1
  5. package/dist/backends/anthropic.d.ts.map +1 -1
  6. package/dist/backends/anthropic.js +4 -1
  7. package/dist/backends/anthropic.js.map +1 -1
  8. package/dist/backends/openai.d.ts +2 -1
  9. package/dist/backends/openai.d.ts.map +1 -1
  10. package/dist/backends/openai.js +1 -1
  11. package/dist/backends/openai.js.map +1 -1
  12. package/dist/backends/types.d.ts +2 -1
  13. package/dist/backends/types.d.ts.map +1 -1
  14. package/dist/backends/types.js +1 -1
  15. package/dist/backends/types.js.map +1 -1
  16. package/dist/baseline.js +1 -1
  17. package/dist/baseline.js.map +1 -1
  18. package/dist/calendar-number.d.ts +31 -0
  19. package/dist/calendar-number.d.ts.map +1 -0
  20. package/dist/calendar-number.js +58 -0
  21. package/dist/calendar-number.js.map +1 -0
  22. package/dist/cli-args.d.ts +0 -5
  23. package/dist/cli-args.d.ts.map +1 -1
  24. package/dist/cli-args.js +2 -2
  25. package/dist/cli-args.js.map +1 -1
  26. package/dist/cli-text.d.ts +6 -2
  27. package/dist/cli-text.d.ts.map +1 -1
  28. package/dist/cli-text.js +19 -12
  29. package/dist/cli-text.js.map +1 -1
  30. package/dist/cli.d.ts.map +1 -1
  31. package/dist/cli.js +43 -37
  32. package/dist/cli.js.map +1 -1
  33. package/dist/closing-numbers.d.ts +20 -0
  34. package/dist/closing-numbers.d.ts.map +1 -0
  35. package/dist/closing-numbers.js +56 -0
  36. package/dist/closing-numbers.js.map +1 -0
  37. package/dist/commands/cite.d.ts.map +1 -1
  38. package/dist/commands/cite.js +4 -4
  39. package/dist/commands/cite.js.map +1 -1
  40. package/dist/commands/eval.js +1 -1
  41. package/dist/commands/eval.js.map +1 -1
  42. package/dist/commands/init-ask.d.ts +19 -0
  43. package/dist/commands/init-ask.d.ts.map +1 -0
  44. package/dist/commands/init-ask.js +43 -0
  45. package/dist/commands/init-ask.js.map +1 -0
  46. package/dist/commands/test.d.ts +8 -0
  47. package/dist/commands/test.d.ts.map +1 -1
  48. package/dist/commands/test.js +78 -44
  49. package/dist/commands/test.js.map +1 -1
  50. package/dist/commands/tree.d.ts +1 -8
  51. package/dist/commands/tree.d.ts.map +1 -1
  52. package/dist/commands/tree.js +7 -6
  53. package/dist/commands/tree.js.map +1 -1
  54. package/dist/config/by-path.d.ts.map +1 -1
  55. package/dist/config/by-path.js +10 -9
  56. package/dist/config/by-path.js.map +1 -1
  57. package/dist/config/load.d.ts +4 -0
  58. package/dist/config/load.d.ts.map +1 -1
  59. package/dist/config/load.js +19 -0
  60. package/dist/config/load.js.map +1 -1
  61. package/dist/config/name-problems.d.ts +5 -0
  62. package/dist/config/name-problems.d.ts.map +1 -0
  63. package/dist/config/name-problems.js +11 -0
  64. package/dist/config/name-problems.js.map +1 -0
  65. package/dist/date-stamp.js +1 -1
  66. package/dist/date-stamp.js.map +1 -1
  67. package/dist/detectors/acronym-context.d.ts +2 -0
  68. package/dist/detectors/acronym-context.d.ts.map +1 -1
  69. package/dist/detectors/acronym-context.js +13 -0
  70. package/dist/detectors/acronym-context.js.map +1 -1
  71. package/dist/detectors/acronym-expansion.d.ts +2 -0
  72. package/dist/detectors/acronym-expansion.d.ts.map +1 -1
  73. package/dist/detectors/acronym-expansion.js +104 -1
  74. package/dist/detectors/acronym-expansion.js.map +1 -1
  75. package/dist/detectors/agreement-slip.d.ts +32 -0
  76. package/dist/detectors/agreement-slip.d.ts.map +1 -0
  77. package/dist/detectors/agreement-slip.js +137 -0
  78. package/dist/detectors/agreement-slip.js.map +1 -0
  79. package/dist/detectors/char-shape.d.ts.map +1 -1
  80. package/dist/detectors/char-shape.js +16 -6
  81. package/dist/detectors/char-shape.js.map +1 -1
  82. package/dist/detectors/content-morphemes.d.ts +4 -0
  83. package/dist/detectors/content-morphemes.d.ts.map +1 -0
  84. package/dist/detectors/content-morphemes.js +12 -0
  85. package/dist/detectors/content-morphemes.js.map +1 -0
  86. package/dist/detectors/en-shape.d.ts +0 -1
  87. package/dist/detectors/en-shape.d.ts.map +1 -1
  88. package/dist/detectors/en-shape.js +2 -143
  89. package/dist/detectors/en-shape.js.map +1 -1
  90. package/dist/detectors/enumerated-runs.d.ts.map +1 -1
  91. package/dist/detectors/enumerated-runs.js +4 -2
  92. package/dist/detectors/enumerated-runs.js.map +1 -1
  93. package/dist/detectors/gram-place.js +1 -1
  94. package/dist/detectors/gram-place.js.map +1 -1
  95. package/dist/detectors/heading-case.d.ts.map +1 -1
  96. package/dist/detectors/heading-case.js +3 -1
  97. package/dist/detectors/heading-case.js.map +1 -1
  98. package/dist/detectors/heading-echo.d.ts.map +1 -1
  99. package/dist/detectors/heading-echo.js +12 -18
  100. package/dist/detectors/heading-echo.js.map +1 -1
  101. package/dist/detectors/heading-overlap.d.ts +13 -0
  102. package/dist/detectors/heading-overlap.d.ts.map +1 -0
  103. package/dist/detectors/heading-overlap.js +52 -0
  104. package/dist/detectors/heading-overlap.js.map +1 -0
  105. package/dist/detectors/index.d.ts.map +1 -1
  106. package/dist/detectors/index.js +10 -4
  107. package/dist/detectors/index.js.map +1 -1
  108. package/dist/detectors/letter-joined-name.d.ts +13 -0
  109. package/dist/detectors/letter-joined-name.d.ts.map +1 -0
  110. package/dist/detectors/letter-joined-name.js +11 -0
  111. package/dist/detectors/letter-joined-name.js.map +1 -0
  112. package/dist/detectors/lettered-index.d.ts +9 -0
  113. package/dist/detectors/lettered-index.d.ts.map +1 -0
  114. package/dist/detectors/lettered-index.js +54 -0
  115. package/dist/detectors/lettered-index.js.map +1 -0
  116. package/dist/detectors/lexicon.d.ts +5 -1
  117. package/dist/detectors/lexicon.d.ts.map +1 -1
  118. package/dist/detectors/lexicon.js +51 -5
  119. package/dist/detectors/lexicon.js.map +1 -1
  120. package/dist/detectors/orthography.d.ts.map +1 -1
  121. package/dist/detectors/orthography.js +24 -6
  122. package/dist/detectors/orthography.js.map +1 -1
  123. package/dist/detectors/oxford-comma.d.ts +3 -0
  124. package/dist/detectors/oxford-comma.d.ts.map +1 -0
  125. package/dist/detectors/oxford-comma.js +340 -0
  126. package/dist/detectors/oxford-comma.js.map +1 -0
  127. package/dist/detectors/phrase-match.d.ts +3 -1
  128. package/dist/detectors/phrase-match.d.ts.map +1 -1
  129. package/dist/detectors/phrase-match.js +20 -15
  130. package/dist/detectors/phrase-match.js.map +1 -1
  131. package/dist/detectors/repeated-head.d.ts.map +1 -1
  132. package/dist/detectors/repeated-head.js +5 -4
  133. package/dist/detectors/repeated-head.js.map +1 -1
  134. package/dist/detectors/signals.d.ts.map +1 -1
  135. package/dist/detectors/signals.js +45 -16
  136. package/dist/detectors/signals.js.map +1 -1
  137. package/dist/detectors/stacked-hedge.d.ts +16 -0
  138. package/dist/detectors/stacked-hedge.d.ts.map +1 -0
  139. package/dist/detectors/stacked-hedge.js +67 -0
  140. package/dist/detectors/stacked-hedge.js.map +1 -0
  141. package/dist/detectors/stray-space.d.ts +7 -0
  142. package/dist/detectors/stray-space.d.ts.map +1 -0
  143. package/dist/detectors/stray-space.js +34 -0
  144. package/dist/detectors/stray-space.js.map +1 -0
  145. package/dist/detectors/structure.d.ts +3 -1
  146. package/dist/detectors/structure.d.ts.map +1 -1
  147. package/dist/detectors/structure.js +4 -2
  148. package/dist/detectors/structure.js.map +1 -1
  149. package/dist/detectors/superlative-amount.d.ts +9 -0
  150. package/dist/detectors/superlative-amount.d.ts.map +1 -0
  151. package/dist/detectors/superlative-amount.js +20 -0
  152. package/dist/detectors/superlative-amount.js.map +1 -0
  153. package/dist/detectors/superlative-clause.d.ts +18 -0
  154. package/dist/detectors/superlative-clause.d.ts.map +1 -0
  155. package/dist/detectors/superlative-clause.js +61 -0
  156. package/dist/detectors/superlative-clause.js.map +1 -0
  157. package/dist/detectors/superlative-scope.d.ts +6 -0
  158. package/dist/detectors/superlative-scope.d.ts.map +1 -1
  159. package/dist/detectors/superlative-scope.js +3 -3
  160. package/dist/detectors/superlative-scope.js.map +1 -1
  161. package/dist/detectors/team.d.ts +0 -6
  162. package/dist/detectors/team.d.ts.map +1 -1
  163. package/dist/detectors/team.js +17 -1
  164. package/dist/detectors/team.js.map +1 -1
  165. package/dist/detectors/token-shape.d.ts.map +1 -1
  166. package/dist/detectors/token-shape.js +8 -6
  167. package/dist/detectors/token-shape.js.map +1 -1
  168. package/dist/document.d.ts +3 -0
  169. package/dist/document.d.ts.map +1 -1
  170. package/dist/document.js +33 -6
  171. package/dist/document.js.map +1 -1
  172. package/dist/eval.js +1 -1
  173. package/dist/eval.js.map +1 -1
  174. package/dist/feedback/draft.js +1 -1
  175. package/dist/feedback/draft.js.map +1 -1
  176. package/dist/feedback/excerpt.d.ts +0 -1
  177. package/dist/feedback/excerpt.d.ts.map +1 -1
  178. package/dist/feedback/excerpt.js +2 -2
  179. package/dist/feedback/excerpt.js.map +1 -1
  180. package/dist/file-header.d.ts +20 -0
  181. package/dist/file-header.d.ts.map +1 -0
  182. package/dist/file-header.js +21 -0
  183. package/dist/file-header.js.map +1 -0
  184. package/dist/files.js +3 -3
  185. package/dist/files.js.map +1 -1
  186. package/dist/genre-check.js +1 -1
  187. package/dist/genre-check.js.map +1 -1
  188. package/dist/genre-load.d.ts +6 -0
  189. package/dist/genre-load.d.ts.map +1 -0
  190. package/dist/genre-load.js +22 -0
  191. package/dist/genre-load.js.map +1 -0
  192. package/dist/genre-parse.d.ts +44 -0
  193. package/dist/genre-parse.d.ts.map +1 -0
  194. package/dist/genre-parse.js +117 -0
  195. package/dist/genre-parse.js.map +1 -0
  196. package/dist/genre-suggest.d.ts +15 -0
  197. package/dist/genre-suggest.d.ts.map +1 -0
  198. package/dist/genre-suggest.js +40 -0
  199. package/dist/genre-suggest.js.map +1 -0
  200. package/dist/genre.d.ts +1 -1
  201. package/dist/genre.d.ts.map +1 -1
  202. package/dist/genre.js +3 -13
  203. package/dist/genre.js.map +1 -1
  204. package/dist/init-choice.d.ts +12 -0
  205. package/dist/init-choice.d.ts.map +1 -0
  206. package/dist/init-choice.js +41 -0
  207. package/dist/init-choice.js.map +1 -0
  208. package/dist/init.d.ts.map +1 -1
  209. package/dist/init.js +16 -5
  210. package/dist/init.js.map +1 -1
  211. package/dist/judge.d.ts +2 -1
  212. package/dist/judge.d.ts.map +1 -1
  213. package/dist/judge.js +1 -1
  214. package/dist/judge.js.map +1 -1
  215. package/dist/line-paragraphs.d.ts +4 -0
  216. package/dist/line-paragraphs.d.ts.map +1 -0
  217. package/dist/line-paragraphs.js +71 -0
  218. package/dist/line-paragraphs.js.map +1 -0
  219. package/dist/mask.d.ts.map +1 -1
  220. package/dist/mask.js +2 -10
  221. package/dist/mask.js.map +1 -1
  222. package/dist/number-name.js +1 -1
  223. package/dist/number-name.js.map +1 -1
  224. package/dist/opening-line.d.ts +3 -0
  225. package/dist/opening-line.d.ts.map +1 -0
  226. package/dist/opening-line.js +14 -0
  227. package/dist/opening-line.js.map +1 -0
  228. package/dist/orthography.d.ts +5 -1
  229. package/dist/orthography.d.ts.map +1 -1
  230. package/dist/orthography.js +7 -1
  231. package/dist/orthography.js.map +1 -1
  232. package/dist/paragraph-length.d.ts +7 -0
  233. package/dist/paragraph-length.d.ts.map +1 -0
  234. package/dist/paragraph-length.js +10 -0
  235. package/dist/paragraph-length.js.map +1 -0
  236. package/dist/plugin.d.ts +12 -0
  237. package/dist/plugin.d.ts.map +1 -1
  238. package/dist/profile/check.d.ts +28 -0
  239. package/dist/profile/check.d.ts.map +1 -0
  240. package/dist/profile/check.js +12 -0
  241. package/dist/profile/check.js.map +1 -0
  242. package/dist/profile/for-file.d.ts +2 -2
  243. package/dist/profile/for-file.d.ts.map +1 -1
  244. package/dist/profile/for-file.js +9 -2
  245. package/dist/profile/for-file.js.map +1 -1
  246. package/dist/profile/load.js +1 -1
  247. package/dist/profile/load.js.map +1 -1
  248. package/dist/profile/select.d.ts +4 -2
  249. package/dist/profile/select.d.ts.map +1 -1
  250. package/dist/profile/select.js +8 -3
  251. package/dist/profile/select.js.map +1 -1
  252. package/dist/quoted-span.d.ts +13 -3
  253. package/dist/quoted-span.d.ts.map +1 -1
  254. package/dist/quoted-span.js +16 -11
  255. package/dist/quoted-span.js.map +1 -1
  256. package/dist/reasons.d.ts +1 -0
  257. package/dist/reasons.d.ts.map +1 -1
  258. package/dist/reasons.js +4 -1
  259. package/dist/reasons.js.map +1 -1
  260. package/dist/render/compact.d.ts.map +1 -1
  261. package/dist/render/compact.js +1 -2
  262. package/dist/render/compact.js.map +1 -1
  263. package/dist/render/eval.d.ts.map +1 -1
  264. package/dist/render/eval.js +4 -3
  265. package/dist/render/eval.js.map +1 -1
  266. package/dist/render/friendly.d.ts +2 -1
  267. package/dist/render/friendly.d.ts.map +1 -1
  268. package/dist/render/friendly.js +14 -6
  269. package/dist/render/friendly.js.map +1 -1
  270. package/dist/render/genres.d.ts +5 -0
  271. package/dist/render/genres.d.ts.map +1 -0
  272. package/dist/render/genres.js +28 -0
  273. package/dist/render/genres.js.map +1 -0
  274. package/dist/render/plural.d.ts +3 -0
  275. package/dist/render/plural.d.ts.map +1 -0
  276. package/dist/render/plural.js +5 -0
  277. package/dist/render/plural.js.map +1 -0
  278. package/dist/render/rules-json.d.ts.map +1 -1
  279. package/dist/render/rules-json.js +9 -3
  280. package/dist/render/rules-json.js.map +1 -1
  281. package/dist/render/semantic.d.ts +3 -2
  282. package/dist/render/semantic.d.ts.map +1 -1
  283. package/dist/render/semantic.js +94 -34
  284. package/dist/render/semantic.js.map +1 -1
  285. package/dist/render/summary.d.ts.map +1 -1
  286. package/dist/render/summary.js +4 -3
  287. package/dist/render/summary.js.map +1 -1
  288. package/dist/render/suppressions.d.ts.map +1 -1
  289. package/dist/render/suppressions.js +3 -2
  290. package/dist/render/suppressions.js.map +1 -1
  291. package/dist/render/text.d.ts +2 -0
  292. package/dist/render/text.d.ts.map +1 -1
  293. package/dist/render/text.js +11 -3
  294. package/dist/render/text.js.map +1 -1
  295. package/dist/rule-load.d.ts.map +1 -1
  296. package/dist/rule-load.js +12 -1
  297. package/dist/rule-load.js.map +1 -1
  298. package/dist/run-semantic.d.ts +3 -1
  299. package/dist/run-semantic.d.ts.map +1 -1
  300. package/dist/run-semantic.js +9 -4
  301. package/dist/run-semantic.js.map +1 -1
  302. package/dist/run.d.ts +4 -0
  303. package/dist/run.d.ts.map +1 -1
  304. package/dist/run.js +29 -16
  305. package/dist/run.js.map +1 -1
  306. package/dist/semantic.d.ts +1 -1
  307. package/dist/semantic.d.ts.map +1 -1
  308. package/dist/semantic.js +10 -3
  309. package/dist/semantic.js.map +1 -1
  310. package/dist/sentence-shape.d.ts +0 -1
  311. package/dist/sentence-shape.d.ts.map +1 -1
  312. package/dist/sentence-shape.js +3 -5
  313. package/dist/sentence-shape.js.map +1 -1
  314. package/dist/setting-problems.d.ts +5 -0
  315. package/dist/setting-problems.d.ts.map +1 -0
  316. package/dist/setting-problems.js +15 -0
  317. package/dist/setting-problems.js.map +1 -0
  318. package/dist/span-merge.d.ts +4 -0
  319. package/dist/span-merge.d.ts.map +1 -0
  320. package/dist/span-merge.js +12 -0
  321. package/dist/span-merge.js.map +1 -0
  322. package/dist/speaker-labels.d.ts +4 -0
  323. package/dist/speaker-labels.d.ts.map +1 -0
  324. package/dist/speaker-labels.js +106 -0
  325. package/dist/speaker-labels.js.map +1 -0
  326. package/dist/stray-space.d.ts +17 -0
  327. package/dist/stray-space.d.ts.map +1 -0
  328. package/dist/stray-space.js +66 -0
  329. package/dist/stray-space.js.map +1 -0
  330. package/dist/structure/build.js +5 -5
  331. package/dist/structure/build.js.map +1 -1
  332. package/dist/structure/cite.js +1 -1
  333. package/dist/structure/cite.js.map +1 -1
  334. package/dist/structure/issues.d.ts.map +1 -1
  335. package/dist/structure/issues.js +5 -5
  336. package/dist/structure/issues.js.map +1 -1
  337. package/dist/structure/markdown-path.d.ts.map +1 -1
  338. package/dist/structure/markdown-path.js +2 -2
  339. package/dist/structure/markdown-path.js.map +1 -1
  340. package/dist/structure/numbering.d.ts.map +1 -1
  341. package/dist/structure/numbering.js +1 -1
  342. package/dist/structure/numbering.js.map +1 -1
  343. package/dist/structure/relative-find.js +1 -1
  344. package/dist/structure/relative-find.js.map +1 -1
  345. package/dist/structure/relative-resolve.d.ts.map +1 -1
  346. package/dist/structure/relative-resolve.js +26 -20
  347. package/dist/structure/relative-resolve.js.map +1 -1
  348. package/dist/structure/sexp.js +1 -1
  349. package/dist/structure/sexp.js.map +1 -1
  350. package/dist/structure/unnumbered.js +2 -2
  351. package/dist/structure/unnumbered.js.map +1 -1
  352. package/dist/team-names.d.ts +9 -0
  353. package/dist/team-names.d.ts.map +1 -0
  354. package/dist/team-names.js +31 -0
  355. package/dist/team-names.js.map +1 -0
  356. package/dist/ui.d.ts +2 -0
  357. package/dist/ui.d.ts.map +1 -1
  358. package/dist/ui.js +6 -0
  359. package/dist/ui.js.map +1 -1
  360. package/dist/version.js +1 -1
  361. package/dist/version.js.map +1 -1
  362. package/dist/watch.d.ts +2 -2
  363. package/dist/watch.d.ts.map +1 -1
  364. package/dist/watch.js +5 -5
  365. package/dist/watch.js.map +1 -1
  366. package/genres.yaml +395 -0
  367. package/package.json +4 -3
  368. package/rules/adverb-overuse.yaml +2 -2
  369. package/rules/agentless-passive.yaml +1 -1
  370. package/rules/agreement-slip.yaml +36 -0
  371. package/rules/ai-generated-composite.yaml +2 -2
  372. package/rules/ai-tell.yaml +2 -2
  373. package/rules/bold-density.yaml +2 -2
  374. package/rules/closing-cliche.yaml +1 -1
  375. package/rules/concrete-evidence-density.yaml +2 -2
  376. package/rules/contraction-consistency.yaml +1 -1
  377. package/rules/cushion-phrase-density.yaml +1 -1
  378. package/rules/dangling-reference.yaml +1 -1
  379. package/rules/date-order.yaml +1 -1
  380. package/rules/date-weekday-mismatch.yaml +1 -1
  381. package/rules/double-keigo.yaml +1 -1
  382. package/rules/doubled-word.yaml +1 -1
  383. package/rules/duplicate-definition.yaml +1 -1
  384. package/rules/emoji-density.yaml +1 -1
  385. package/rules/empty-conclusion.yaml +3 -1
  386. package/rules/empty-intensifier.yaml +1 -1
  387. package/rules/excessive-hedging.yaml +16 -6
  388. package/rules/expletive-construction.yaml +2 -2
  389. package/rules/heading-echo.yaml +2 -1
  390. package/rules/hiragana-fukushi.yaml +1 -1
  391. package/rules/internal-jargon.yaml +2 -2
  392. package/rules/latin-spacing.yaml +5 -4
  393. package/rules/max-kanji-continuous.yaml +4 -3
  394. package/rules/max-paragraph-length.yaml +18 -4
  395. package/rules/max-sentence-length.yaml +18 -2
  396. package/rules/ngram-repetition.yaml +4 -4
  397. package/rules/no-doubled-joshi.yaml +2 -2
  398. package/rules/no-em-dash.yaml +2 -2
  399. package/rules/no-mixed-desumasu.yaml +1 -1
  400. package/rules/no-nakaguro-parallel.yaml +2 -2
  401. package/rules/numbering-gap.yaml +1 -1
  402. package/rules/oxford-comma-consistency.yaml +2 -1
  403. package/rules/padded-intro.yaml +2 -1
  404. package/rules/paragraph-length-variance.yaml +1 -1
  405. package/rules/preamble-length.yaml +2 -2
  406. package/rules/preferred-term.yaml +1 -1
  407. package/rules/proper-noun-density.yaml +3 -2
  408. package/rules/repeated-conjunction.yaml +2 -2
  409. package/rules/repeated-sentence-head.yaml +2 -2
  410. package/rules/required-sections.yaml +1 -1
  411. package/rules/rule-of-three.yaml +2 -2
  412. package/rules/sasete-itadaku.yaml +3 -3
  413. package/rules/section-length-uniformity.yaml +1 -1
  414. package/rules/sentence-initial-conjunction-run.yaml +2 -2
  415. package/rules/sentence-rhythm.yaml +1 -1
  416. package/rules/stray-space.yaml +38 -0
  417. package/rules/taigen-dome-in-prose.yaml +2 -2
  418. package/rules/title-case-consistency.yaml +1 -1
  419. package/rules/total-mismatch.yaml +1 -1
  420. package/rules/undefined-acronym.yaml +5 -4
  421. package/rules/unqualified-superlative.yaml +2 -2
  422. package/skills/chaff/SKILL.md +28 -9
  423. package/src/address-chain.ts +1 -1
  424. package/src/backends/anthropic.ts +5 -1
  425. package/src/backends/openai.ts +2 -1
  426. package/src/backends/types.ts +3 -2
  427. package/src/baseline.ts +1 -1
  428. package/src/calendar-number.ts +84 -0
  429. package/src/cli-args.ts +2 -2
  430. package/src/cli-text.ts +29 -15
  431. package/src/cli.ts +42 -41
  432. package/src/closing-numbers.ts +72 -0
  433. package/src/commands/cite.ts +4 -4
  434. package/src/commands/eval.ts +1 -1
  435. package/src/commands/init-ask.ts +53 -0
  436. package/src/commands/test.ts +118 -56
  437. package/src/commands/tree.ts +7 -6
  438. package/src/config/by-path.ts +8 -9
  439. package/src/config/load.ts +24 -0
  440. package/src/config/name-problems.ts +15 -0
  441. package/src/date-stamp.ts +1 -1
  442. package/src/detectors/acronym-context.ts +16 -0
  443. package/src/detectors/acronym-expansion.ts +132 -1
  444. package/src/detectors/agreement-slip.ts +191 -0
  445. package/src/detectors/char-shape.ts +21 -9
  446. package/src/detectors/content-morphemes.ts +19 -0
  447. package/src/detectors/en-shape.ts +2 -173
  448. package/src/detectors/enumerated-runs.ts +3 -2
  449. package/src/detectors/gram-place.ts +1 -1
  450. package/src/detectors/heading-case.ts +4 -1
  451. package/src/detectors/heading-echo.ts +12 -20
  452. package/src/detectors/heading-overlap.ts +65 -0
  453. package/src/detectors/index.ts +10 -4
  454. package/src/detectors/letter-joined-name.ts +15 -0
  455. package/src/detectors/lettered-index.ts +78 -0
  456. package/src/detectors/lexicon.ts +69 -8
  457. package/src/detectors/orthography.ts +31 -7
  458. package/src/detectors/oxford-comma.ts +402 -0
  459. package/src/detectors/phrase-match.ts +23 -12
  460. package/src/detectors/repeated-head.ts +3 -4
  461. package/src/detectors/signals.ts +47 -15
  462. package/src/detectors/stacked-hedge.ts +96 -0
  463. package/src/detectors/stray-space.ts +40 -0
  464. package/src/detectors/structure.ts +10 -2
  465. package/src/detectors/superlative-amount.ts +24 -0
  466. package/src/detectors/superlative-clause.ts +82 -0
  467. package/src/detectors/superlative-scope.ts +3 -3
  468. package/src/detectors/team.ts +18 -2
  469. package/src/detectors/token-shape.ts +8 -10
  470. package/src/document.ts +54 -7
  471. package/src/eval.ts +1 -1
  472. package/src/feedback/draft.ts +1 -1
  473. package/src/feedback/excerpt.ts +2 -2
  474. package/src/file-header.ts +31 -0
  475. package/src/files.ts +3 -3
  476. package/src/genre-check.ts +1 -1
  477. package/src/genre-load.ts +24 -0
  478. package/src/genre-parse.ts +151 -0
  479. package/src/genre-suggest.ts +50 -0
  480. package/src/genre.ts +4 -13
  481. package/src/init-choice.ts +47 -0
  482. package/src/init.ts +20 -6
  483. package/src/judge.ts +3 -1
  484. package/src/line-paragraphs.ts +86 -0
  485. package/src/mask.ts +2 -12
  486. package/src/number-name.ts +1 -1
  487. package/src/opening-line.ts +17 -0
  488. package/src/orthography.ts +10 -2
  489. package/src/paragraph-length.ts +9 -0
  490. package/src/plugin.ts +12 -0
  491. package/src/profile/check.ts +34 -0
  492. package/src/profile/for-file.ts +10 -3
  493. package/src/profile/load.ts +1 -1
  494. package/src/profile/select.ts +11 -4
  495. package/src/quoted-span.ts +26 -12
  496. package/src/reasons.ts +5 -1
  497. package/src/render/compact.ts +1 -3
  498. package/src/render/eval.ts +4 -3
  499. package/src/render/friendly.ts +21 -6
  500. package/src/render/genres.ts +31 -0
  501. package/src/render/plural.ts +6 -0
  502. package/src/render/rules-json.ts +10 -3
  503. package/src/render/semantic.ts +117 -34
  504. package/src/render/summary.ts +4 -3
  505. package/src/render/suppressions.ts +3 -2
  506. package/src/render/text.ts +18 -3
  507. package/src/rule-load.ts +14 -1
  508. package/src/run-semantic.ts +29 -21
  509. package/src/run.ts +33 -16
  510. package/src/semantic.ts +11 -3
  511. package/src/sentence-shape.ts +3 -7
  512. package/src/setting-problems.ts +24 -0
  513. package/src/span-merge.ts +13 -0
  514. package/src/speaker-labels.ts +129 -0
  515. package/src/stray-space.ts +81 -0
  516. package/src/structure/build.ts +5 -5
  517. package/src/structure/cite.ts +1 -1
  518. package/src/structure/issues.ts +6 -5
  519. package/src/structure/markdown-path.ts +2 -2
  520. package/src/structure/numbering.ts +1 -1
  521. package/src/structure/relative-find.ts +1 -1
  522. package/src/structure/relative-resolve.ts +34 -19
  523. package/src/structure/sexp.ts +1 -1
  524. package/src/structure/unnumbered.ts +2 -2
  525. package/src/team-names.ts +39 -0
  526. package/src/ui.ts +7 -0
  527. package/src/version.ts +1 -1
  528. package/src/watch.ts +5 -5
@@ -0,0 +1,31 @@
1
+ import { mergeSpans } from "./span-merge.js";
2
+ const SPACE = /\s/u;
3
+ const ESCAPE = /[.*+?^${}()|[\]\\]/gu;
4
+ const WHITESPACE_RUN = String.raw `\s+`;
5
+ const WRAP = String.raw `(?:\r?\n[ \t]*)?`;
6
+ /** 名前の中の空白は空白の並びに当て、字と字の間には折り返しの改行を許す。本文の行は好きな所で折れる。 */
7
+ const patternOf = (name) => {
8
+ const pieces = Array.from(name.trim()).reduce((acc, char) => {
9
+ const previous = acc.at(-1);
10
+ if (SPACE.test(char)) {
11
+ if (previous !== WHITESPACE_RUN)
12
+ acc.push(WHITESPACE_RUN);
13
+ return acc;
14
+ }
15
+ const escaped = char.replace(ESCAPE, "\\$&");
16
+ if (previous !== undefined && previous !== WHITESPACE_RUN)
17
+ acc.push(WRAP);
18
+ acc.push(escaped);
19
+ return acc;
20
+ }, []);
21
+ return new RegExp(pieces.join(""), "gu");
22
+ };
23
+ const occurrences = (text, name) => name.trim().length === 0 ? [] : [...text.matchAll(patternOf(name))].map((match) => ({ start: match.index, end: match.index + match[0].length }));
24
+ /**
25
+ * チームが chaff.yaml の names に並べた名前が、text のどこにあるか。綴りは書かれたとおり(Apple と apple は別)。
26
+ * 重なる出現は 1 つの範囲にまとめる。接するだけなら別の名前(並んだ 2 つの名前は 2 つと数える)。位置は text の先頭を 0 とする。
27
+ */
28
+ export const nameSpans = (text, names) => mergeSpans(names.flatMap((name) => occurrences(text, name)), false);
29
+ /** [start, end) が names の範囲のどれかと重なるか。 */
30
+ export const touchesAny = (spans, start, end) => spans.some((span) => start < span.end && span.start < end);
31
+ //# sourceMappingURL=team-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-names.js","sourceRoot":"","sources":["../src/team-names.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,KAAK,GAAG,KAAK,CAAC;AACpB,MAAM,MAAM,GAAG,sBAAsB,CAAC;AACtC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA,KAAK,CAAC;AACvC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,kBAAkB,CAAC;AAE1C,wDAAwD;AACxD,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAW,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACpE,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,IAAI,QAAQ,KAAK,cAAc;gBAAE,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1D,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,cAAc;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1E,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClB,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,IAAY,EAAU,EAAE,CACzD,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAEnJ;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,KAAwB,EAAU,EAAE,CAC1E,UAAU,CACR,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAChD,KAAK,CACN,CAAC;AAEJ,yCAAyC;AACzC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAsB,EAAE,KAAa,EAAE,GAAW,EAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC"}
package/dist/ui.d.ts CHANGED
@@ -9,6 +9,8 @@ export declare const uiLanguageOf: (language: string | undefined) => UiLanguage;
9
9
  * the language `chaff.yaml` sets, else the terminal's locale, else English. Pure: `env` is passed in.
10
10
  */
11
11
  export declare const hostLanguage: (configLanguage: string | undefined, env: Readonly<Record<string, string | undefined>>) => UiLanguage;
12
+ /** Several documents end with one closing: in their language when they share one, else the host's. */
13
+ export declare const sharedLanguage: (languages: readonly string[], host: UiLanguage) => UiLanguage;
12
14
  /** Text in both languages. Each module keeps its own, next to where it is used. */
13
15
  export type Texts<T> = Readonly<Record<UiLanguage, T>>;
14
16
  //# sourceMappingURL=ui.d.ts.map
package/dist/ui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;AAErC,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,GAAG,SAAS,KAAG,UAA+C,CAAC;AAK5G;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,gBAAgB,MAAM,GAAG,SAAS,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KAAG,UAIpH,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;AAErC,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM,GAAG,SAAS,KAAG,UAA+C,CAAC;AAK5G;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,gBAAgB,MAAM,GAAG,SAAS,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KAAG,UAIpH,CAAC;AAEF,sGAAsG;AACtG,eAAO,MAAM,cAAc,GAAI,WAAW,SAAS,MAAM,EAAE,EAAE,MAAM,UAAU,KAAG,UAI/E,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC"}
package/dist/ui.js CHANGED
@@ -11,4 +11,10 @@ export const hostLanguage = (configLanguage, env) => {
11
11
  const locale = LOCALE_VARIABLES.map((name) => env[name]).find((value) => value !== undefined && value !== "");
12
12
  return locale !== undefined && locale.toLowerCase().startsWith("ja") ? "ja" : "en";
13
13
  };
14
+ /** Several documents end with one closing: in their language when they share one, else the host's. */
15
+ export const sharedLanguage = (languages, host) => {
16
+ const distinct = new Set(languages.map((language) => uiLanguageOf(language)));
17
+ const [only] = [...distinct];
18
+ return distinct.size === 1 && only !== undefined ? only : host;
19
+ };
14
20
  //# sourceMappingURL=ui.js.map
package/dist/ui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAA4B,EAAc,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAE5G,iEAAiE;AACjE,MAAM,gBAAgB,GAAsB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,cAAkC,EAAE,GAAiD,EAAc,EAAE;IAChI,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC,cAAc,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;IAC9G,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACrF,CAAC,CAAC"}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAA4B,EAAc,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAE5G,iEAAiE;AACjE,MAAM,gBAAgB,GAAsB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,cAAkC,EAAE,GAAiD,EAAc,EAAE;IAChI,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC,cAAc,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;IAC9G,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACrF,CAAC,CAAC;AAEF,sGAAsG;AACtG,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAA4B,EAAE,IAAgB,EAAc,EAAE;IAC3F,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC7B,OAAO,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC,CAAC"}
package/dist/version.js CHANGED
@@ -16,7 +16,7 @@ export const versionLines = (raw) => {
16
16
  const dependencies = isRecord(raw) && isRecord(raw["dependencies"]) ? raw["dependencies"] : {};
17
17
  const bundled = Object.entries(dependencies)
18
18
  .filter((entry) => BUNDLED.test(entry[0]) && typeof entry[1] === "string")
19
- .sort(([left], [right]) => left.localeCompare(right))
19
+ .toSorted(([left], [right]) => left.localeCompare(right))
20
20
  .map(([name, version]) => `${name} ${version}`);
21
21
  return [`chaffjs ${versionOf(raw)}`, ...bundled];
22
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAErF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE5I,MAAM,SAAS,GAAG,CAAC,GAAY,EAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7H,MAAM,OAAO,GAAG,mBAAmB,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAY,EAAY,EAAE;IACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;SACzC,MAAM,CAAC,CAAC,KAAK,EAA6B,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC;SACpG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;SACpD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,WAAW,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAErF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE5I,MAAM,SAAS,GAAG,CAAC,GAAY,EAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7H,MAAM,OAAO,GAAG,mBAAmB,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAY,EAAY,EAAE;IACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;SACzC,MAAM,CAAC,CAAC,KAAK,EAA6B,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC;SACpG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;SACxD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,WAAW,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC"}
package/dist/watch.d.ts CHANGED
@@ -3,9 +3,9 @@ export type Snapshot = Readonly<Record<string, number>>;
3
3
  export declare const snapshotOf: (findings: readonly Finding[]) => Snapshot;
4
4
  /**
5
5
  * 差分だけを出す。書いている最中に全件を出し直されると、何が変わったのか分からない。
6
- * workflow spec §11。
6
+ * workflow spec §11。`unit` takes the count after the change, which sets the English noun ("0 → 1 finding").
7
7
  */
8
- export declare const describeChange: (before: Snapshot, after: Snapshot, unit?: string) => string | undefined;
8
+ export declare const describeChange: (before: Snapshot, after: Snapshot, unit?: (count: number) => string) => string | undefined;
9
9
  export declare const clock: () => string;
10
10
  /** 変更が落ち着いてから 1 度だけ呼ぶ。 */
11
11
  export declare const watchPaths: (paths: readonly string[], onChange: (path: string) => void) => (() => void);
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAK3C,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAExD,eAAO,MAAM,UAAU,GAAI,UAAU,SAAS,OAAO,EAAE,KAAG,QACiE,CAAC;AAI5H;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,EAAE,aAAW,KAAG,MAAM,GAAG,SAUxF,CAAC;AAEF,eAAO,MAAM,KAAK,QAAO,MAA+C,CAAC;AAEzE,0BAA0B;AAC1B,eAAO,MAAM,UAAU,GAAI,OAAO,SAAS,MAAM,EAAE,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAmBlG,CAAC"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAK3C,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAExD,eAAO,MAAM,UAAU,GAAI,UAAU,SAAS,OAAO,EAAE,KAAG,QAC0F,CAAC;AAIrJ;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAM,CAAC,KAAK,EAAE,MAAM,KAAK,MAAmB,KAAG,MAAM,GAAG,SAUzH,CAAC;AAEF,eAAO,MAAM,KAAK,QAAO,MAA+C,CAAC;AAEzE,0BAA0B;AAC1B,eAAO,MAAM,UAAU,GAAI,OAAO,SAAS,MAAM,EAAE,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAmBlG,CAAC"}
package/dist/watch.js CHANGED
@@ -1,23 +1,23 @@
1
1
  import { watch } from "node:fs";
2
2
  /** 保存は 1 回でも複数イベントになる。まとめて 1 回だけ走らせる。 */
3
3
  const SETTLE_MS = 120;
4
- export const snapshotOf = (findings) => findings.reduce((acc, finding) => ({ ...acc, [finding.rule]: (acc[finding.rule] ?? 0) + 1 }), {});
4
+ export const snapshotOf = (findings) => Object.fromEntries(findings.reduce((counts, finding) => counts.set(finding.rule, (counts.get(finding.rule) ?? 0) + 1), new Map()));
5
5
  const total = (snapshot) => Object.values(snapshot).reduce((sum, count) => sum + count, 0);
6
6
  /**
7
7
  * 差分だけを出す。書いている最中に全件を出し直されると、何が変わったのか分からない。
8
- * workflow spec §11。
8
+ * workflow spec §11。`unit` takes the count after the change, which sets the English noun ("0 → 1 finding").
9
9
  */
10
- export const describeChange = (before, after, unit = " 件") => {
10
+ export const describeChange = (before, after, unit = () => " 件") => {
11
11
  const rules = [...new Set([...Object.keys(before), ...Object.keys(after)])];
12
12
  const moved = rules
13
13
  .map((rule) => ({ rule, delta: (after[rule] ?? 0) - (before[rule] ?? 0) }))
14
14
  .filter((entry) => entry.delta !== 0)
15
- .sort((left, right) => left.rule.localeCompare(right.rule, "en"));
15
+ .toSorted((left, right) => left.rule.localeCompare(right.rule, "en"));
16
16
  if (moved.length === 0)
17
17
  return undefined;
18
18
  const detail = moved.map((entry) => `${entry.delta > 0 ? "+" : ""}${entry.delta} ${entry.rule}`).join(", ");
19
19
  const mark = total(after) < total(before) ? "✓" : "✗";
20
- return `${mark} ${total(before)} → ${total(after)}${unit} (${detail})`;
20
+ return `${mark} ${total(before)} → ${total(after)}${unit(total(after))} (${detail})`;
21
21
  };
22
22
  export const clock = () => new Date().toTimeString().slice(0, 8);
23
23
  /** 変更が落ち着いてから 1 度だけ呼ぶ。 */
package/dist/watch.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
package/genres.yaml ADDED
@@ -0,0 +1,395 @@
1
+ # The genres chaff knows, in the order `chaff genres` lists them.
2
+ #
3
+ # A genre is a preset: pick the kind of document and chaff checks it the way that kind is written.
4
+ # rules: the level a rule runs at for this genre (strict / normal / relaxed / off), under chaff.yaml's rules.
5
+ # A group's rules apply to every genre in it; a genre's own rules win over its group's.
6
+ # A rule turned off here is listed under "did not run" with the genre as the reason.
7
+ # profile: the document profile (profiles/*.yaml) this genre reads with, when chaff.yaml names none.
8
+ # suggest: when no genre is set, what makes a file look like this genre, strongest first:
9
+ # paths (the file's path), then per language an opening (the body's first line, past front matter and
10
+ # headings) or a line with min_lines (how many lines must have that shape). A wrong suggestion misleads
11
+ # more than none, so a cue is added only where the corpus shows it does not fire on other kinds.
12
+ # Which genres a rule applies to at all is the rule's use_for; the numbers behind a level are the rule's by_genre.
13
+
14
+ groups:
15
+ - id: technical
16
+ name: { ja: 技術文書, en: Technical }
17
+ - id: blog
18
+ name: { ja: ブログ, en: Blog }
19
+ - id: business
20
+ name: { ja: ビジネス文書, en: Business }
21
+ # Legal drafting repeats its terms and its sentence heads on purpose, puts the actor in the passive
22
+ # (shall be deemed), and joins long noun compounds (個人情報取扱事業者). Those rules would only flag the form.
23
+ - id: legal
24
+ name: { ja: 法務, en: Legal }
25
+ rules:
26
+ agentless-passive: off
27
+ max-kanji-continuous: off
28
+ no-doubled-joshi: off
29
+ ngram-repetition: off
30
+ repeated-sentence-head: off
31
+ heading-echo: off
32
+ taigen-dome-in-prose: off
33
+ unqualified-superlative: off
34
+ excessive-hedging: off
35
+ proper-noun-density: off
36
+ expletive-construction: off
37
+ adverb-overuse: off
38
+ concrete-evidence-density: off
39
+ closing-cliche: off
40
+ padded-intro: off
41
+ preamble-length: off
42
+ cushion-phrase-density: off
43
+ sasete-itadaku: off
44
+ sentence-rhythm: off
45
+ rule-of-three: off
46
+ section-length-uniformity: off
47
+ paragraph-length-variance: off
48
+ ai-tell: off
49
+ ai-generated-composite: off
50
+ # A help page repeats its heading in its first line (To upload a file, ...) and states no claims to back up.
51
+ - id: docs
52
+ name: { ja: 説明書, en: Documentation }
53
+ rules:
54
+ heading-echo: off
55
+ agentless-passive: off
56
+ concrete-evidence-density: off
57
+ preamble-length: off
58
+ proper-noun-density: off
59
+ unqualified-superlative: off
60
+ expletive-construction: off
61
+ adverb-overuse: off
62
+ cushion-phrase-density: off
63
+ double-keigo: off
64
+ sasete-itadaku: off
65
+ sentence-initial-conjunction-run: off
66
+ closing-cliche: off
67
+ padded-intro: off
68
+ sentence-rhythm: off
69
+ rule-of-three: off
70
+ section-length-uniformity: off
71
+ paragraph-length-variance: off
72
+ ai-tell: off
73
+ ai-generated-composite: off
74
+ # Science writes in the passive, hedges its claims on purpose (may, suggest) and cites numbers as its evidence.
75
+ - id: academic
76
+ name: { ja: 学術, en: Academic }
77
+ rules:
78
+ agentless-passive: off
79
+ excessive-hedging: off
80
+ expletive-construction: off
81
+ concrete-evidence-density: off
82
+ proper-noun-density: off
83
+ adverb-overuse: off
84
+ closing-cliche: off
85
+ padded-intro: off
86
+ preamble-length: off
87
+ cushion-phrase-density: off
88
+ sasete-itadaku: off
89
+ double-keigo: off
90
+ sentence-rhythm: off
91
+ rule-of-three: off
92
+ section-length-uniformity: off
93
+ paragraph-length-variance: off
94
+ # Length, rhythm, repetition and register are the author's choices in literature, and dialogue mixes styles.
95
+ # Only what one work can hold itself to runs: consistent spacing and commas, and numbering without gaps.
96
+ - id: literature
97
+ name: { ja: 文学, en: Literature }
98
+ rules:
99
+ max-sentence-length: off
100
+ max-paragraph-length: off
101
+ ngram-repetition: off
102
+ repeated-sentence-head: off
103
+ heading-echo: off
104
+ empty-intensifier: off
105
+ no-doubled-joshi: off
106
+ no-nakaguro-parallel: off
107
+ taigen-dome-in-prose: off
108
+ max-kanji-continuous: off
109
+ hiragana-fukushi: off
110
+ no-mixed-desumasu: off
111
+ contraction-consistency: off
112
+ doubled-word: off
113
+ agreement-slip: off
114
+ agentless-passive: off
115
+ expletive-construction: off
116
+ excessive-hedging: off
117
+ unqualified-superlative: off
118
+ adverb-overuse: off
119
+ sentence-initial-conjunction-run: off
120
+ repeated-conjunction: off
121
+ undefined-acronym: off
122
+ proper-noun-density: off
123
+ concrete-evidence-density: off
124
+ closing-cliche: off
125
+ padded-intro: off
126
+ preamble-length: off
127
+ cushion-phrase-density: off
128
+ sasete-itadaku: off
129
+ double-keigo: off
130
+ no-em-dash: off
131
+ emoji-density: off
132
+ sentence-rhythm: off
133
+ rule-of-three: off
134
+ section-length-uniformity: off
135
+ paragraph-length-variance: off
136
+ ai-tell: off
137
+ ai-generated-composite: off
138
+ dangling-reference: off
139
+ duplicate-definition: off
140
+ date-order: off
141
+ date-weekday-mismatch: off
142
+ total-mismatch: off
143
+ # A speech opens with greetings and closes with thanks: that is its form, not padding.
144
+ - id: speech
145
+ name: { ja: 話し言葉, en: Speech }
146
+ rules:
147
+ agentless-passive: off
148
+ preamble-length: off
149
+ padded-intro: off
150
+ closing-cliche: off
151
+ concrete-evidence-density: off
152
+ proper-noun-density: off
153
+ sentence-rhythm: off
154
+ rule-of-three: off
155
+ section-length-uniformity: off
156
+ paragraph-length-variance: off
157
+
158
+ genres:
159
+ - id: technical/spec
160
+ name: { ja: 仕様書, en: Specification }
161
+ summary:
162
+ ja: 仕様書・RFC・設計文書。読み手に間違えさせないための文書
163
+ en: Specifications, RFCs and design documents, written so the reader cannot get it wrong
164
+ - id: technical/readme
165
+ name: { ja: README・技術文書, en: README and technical docs }
166
+ summary:
167
+ ja: README と開発者向けの説明
168
+ en: READMEs and documentation for developers
169
+ - id: blog/tech
170
+ name: { ja: 技術ブログ, en: Tech blog }
171
+ summary:
172
+ ja: 技術記事。ジャンルを決めないときはこれで見ます
173
+ en: Technical articles; the genre used when none is set
174
+ - id: blog/essay
175
+ name: { ja: エッセイ(ブログ), en: Blog essay }
176
+ summary:
177
+ ja: 自分の考えを書くブログのエッセイ
178
+ en: Personal essays posted on a blog
179
+ - id: blog/owned-media
180
+ name: { ja: オウンドメディア, en: Owned media }
181
+ summary:
182
+ ja: 会社や団体が読者に向けて出す記事
183
+ en: Articles an organisation publishes for its readers
184
+ - id: business/proposal
185
+ name: { ja: 提案書・企画書, en: Proposal }
186
+ summary:
187
+ ja: 提案書・企画書・計画書
188
+ en: Proposals, plans and pitches
189
+ - id: business/report
190
+ name: { ja: 報告書, en: Report }
191
+ summary:
192
+ ja: 報告書・白書・社内文書
193
+ en: Reports, white papers and internal documents
194
+ - id: business/email
195
+ name: { ja: メール・手紙, en: Email and letter }
196
+ summary:
197
+ ja: 仕事のメールと手紙
198
+ en: Work email and letters
199
+ # A letter is a letter even when it encloses an agreement (an offer letter), so it goes by how it opens.
200
+ # Not by an addressee line (〇〇御中, To: ...): quotes and proposals open with one too.
201
+ suggest:
202
+ ja: { opening: "^(?:拝啓|謹啓|前略)(?:\\s|$)|^件名\\s*[::]" }
203
+ en: { opening: "^(?:Dear [^\\n]{1,60}|To whom it may concern)[,:]?$|^Subject\\s*:" }
204
+ - id: business/press-release
205
+ name: { ja: プレスリリース・お知らせ, en: Press release and notice }
206
+ summary:
207
+ ja: プレスリリースと、お知らせ
208
+ en: Press releases and public notices
209
+ - id: business/meeting-notes
210
+ name: { ja: 議事録, en: Meeting notes }
211
+ summary:
212
+ ja: 議事録・議事要旨
213
+ en: Minutes and meeting notes
214
+ - id: legal/contract
215
+ name: { ja: 契約書・規約, en: Contract and terms }
216
+ summary:
217
+ ja: 契約書・利用規約・プライバシーポリシー
218
+ en: Contracts, terms of service and privacy policies
219
+ suggest:
220
+ paths: ["(^|/)(contracts?|agreements?|terms|tos|nda|keiyaku|kiyaku)(/|[-_.])", "(^|/)privacy[-_]?policy[-_.]"]
221
+ ja: { line: "本契約|本規約|本ポリシー|以下「(?:甲|乙|丙)」|^#{1,6}\\s*(?:プライバシーポリシー|個人情報保護方針|利用規約|契約書)", min_lines: 2 }
222
+ en:
223
+ {
224
+ line: "\\b(?:[Tt]his Agreement|[Tt]hese Terms|[Tt]his (?:Privacy )?Policy|the Parties)\\b|^#{1,6}\\s*(?:Terms of (?:Service|Use)|Privacy Policy)\\b",
225
+ min_lines: 3,
226
+ }
227
+ # A contract is read clause by clause against its own numbers, definitions and dates: these are its mistakes.
228
+ rules:
229
+ numbering-gap: normal
230
+ duplicate-definition: normal
231
+ dangling-reference: normal
232
+ date-weekday-mismatch: normal
233
+ total-mismatch: normal
234
+ - id: legal/statute
235
+ name: { ja: 法令・規程, en: Statute and regulation }
236
+ summary:
237
+ ja: 法令・規則・社内規程・通達
238
+ en: Statutes, regulations and internal rules
239
+ profile: statute
240
+ # Also suggested when the content has the statute profile's shape.
241
+ suggest:
242
+ paths: ["(^|/)(laws?|statutes?|regulations?|kitei|kisoku)(/|[-_.])"]
243
+ ja: { line: "(?:この|本)(?:法律|政令|省令|府令|規則|規程|条例|定款|通達)", min_lines: 2 }
244
+ en: { line: "\\b(?:[Tt]his (?:Act|[Pp]art|[Ss]ubpart|[Rr]egulation)|[Tt]hese [Rr]egulations)\\b|^§\\s?\\d", min_lines: 3 }
245
+ # A statute or an internal rule is read article by article against its own numbers, like a contract.
246
+ # The statutes in the corpus (yarn corpus) give these no findings, deleted articles (第三条 削除) and 第十条の二 included.
247
+ rules:
248
+ numbering-gap: normal
249
+ duplicate-definition: normal
250
+ dangling-reference: normal
251
+ date-weekday-mismatch: normal
252
+ total-mismatch: normal
253
+ - id: legal/judgment
254
+ name: { ja: 判決, en: Court decision }
255
+ summary:
256
+ ja: 判決文・決定
257
+ en: Court judgments and opinions
258
+ suggest:
259
+ ja: { line: "^(?:#{1,6}\\s*)?(?:主\\s*文|理\\s*由|判\\s*決)\\s*$", min_lines: 2 }
260
+ en: { line: "delivered the opinion of the Court|^(?:Reversed|Affirmed)\\.?$", min_lines: 1 }
261
+ - id: legal/patent
262
+ name: { ja: 特許明細書, en: Patent }
263
+ summary:
264
+ ja: 特許の明細書と請求項
265
+ en: Patent specifications and claims
266
+ suggest:
267
+ ja: { line: "【(?:課題|解決手段|請求項[0-90-9]+|選択図|技術分野|背景技術|発明の詳細な説明|特許請求の範囲)】", min_lines: 2 }
268
+ en: { line: "^#{1,6}\\s*(?:BACKGROUND OF THE INVENTION|SUMMARY OF THE INVENTION|Claims\\b)|\\bof claim \\d+", min_lines: 3 }
269
+ - id: docs/manual
270
+ name: { ja: マニュアル・手順書, en: Manual and how-to }
271
+ summary:
272
+ ja: 使い方の説明・手順書・ヘルプ
273
+ en: User guides, how-to pages and help
274
+ # Path only: step and procedure headings are as common in tech blogs and specifications as in manuals.
275
+ suggest:
276
+ paths: ["(^|/)(manuals?|guides?|how-?tos?|help|tutorials?|user-?guides?)(/|[-_.])"]
277
+ - id: docs/faq
278
+ name: { ja: よくある質問, en: FAQ }
279
+ summary:
280
+ ja: 問いと答えを並べたページ
281
+ en: Pages of questions and answers
282
+ suggest:
283
+ paths: ["(^|[/_-])(faqs?|q-?and-?a)([/_.-]|$)"]
284
+ ja: { line: "^(?:#{1,6}\\s*)?(?:[QQ][0-90-9]*[..::、\\s ]|問[0-90-9]+[..::\\s ])|^#{1,6}\\s*(?:よくある(?:ご)?質問|Q&A|Q&A)", min_lines: 2 }
285
+ en: { line: "^(?:#{1,6}\\s*)?Q[0-9]*[.:)]\\s|^#{1,6}\\s*(?:FAQs?|Frequently asked questions)\\b", min_lines: 2 }
286
+ - id: docs/glossary
287
+ name: { ja: 用語集, en: Glossary }
288
+ summary:
289
+ ja: 用語と、その説明を並べたページ
290
+ en: Lists of terms and what they mean
291
+ suggest:
292
+ paths: ["(^|/)(glossary|glossaries|yogo|用語集)(/|[-_.])"]
293
+ ja: { line: "^#{1,6}\\s*用語集", min_lines: 1 }
294
+ en: { line: "^#{1,6}\\s*Glossary\\b", min_lines: 1 }
295
+ # A reader looks up one entry and reads only that. A definition is a noun phrase (風の吹いてくる方向。), and sibling
296
+ # entries share one wording on purpose (Portion of labor productivity change attributed to …), which no reader sees twice.
297
+ rules:
298
+ taigen-dome-in-prose: off
299
+ ngram-repetition: off
300
+ - id: academic/paper
301
+ name: { ja: 論文, en: Academic paper }
302
+ summary:
303
+ ja: 論文と、その要旨
304
+ en: Papers and abstracts
305
+ suggest:
306
+ paths: ["(^|/)(papers?|ronbun)(/|[-_.])"]
307
+ ja: { line: "^(?:#{1,6}\\s*)?(?:要旨|抄録|参考文献|引用文献|謝辞)\\s*(?:[((].*)?$", min_lines: 2 }
308
+ en:
309
+ {
310
+ line: "^(?:#{1,6}\\s*)?(?:\\d+\\.?\\s+)?(?:Abstract|Keywords|Methods?|Methodology|Results|Discussion|Conclusions?|Related [Ww]ork|Bibliography|References)\\s*$",
311
+ min_lines: 4,
312
+ }
313
+ - id: literature/fiction
314
+ name: { ja: 小説, en: Fiction }
315
+ summary:
316
+ ja: 小説・物語
317
+ en: Novels and stories
318
+ # A line that is a spoken line (「…」, or 「…」と云った): a sentence in quotes, not a term being defined
319
+ # (「…」とは, 「…」という, 「…」とする, 「…」と定める, 「…」と称する, 「…」と呼ぶ).
320
+ suggest:
321
+ paths: ["(^|/)(novels?|fiction|stories|shosetsu)(/|[-_.])"]
322
+ ja: { line: "^「[^」]+」と(?!は|い[うい]|する|定め|称|呼)|^「[^」]*[、。?!…―][^」]*」$", min_lines: 10 }
323
+ - id: literature/essay
324
+ name: { ja: 随筆, en: Literary essay }
325
+ summary:
326
+ ja: 文学としての随筆。ブログのエッセイは blog/essay
327
+ en: Literary essays; a blog essay is blog/essay
328
+ - id: literature/poetry
329
+ name: { ja: 詩歌, en: Poetry }
330
+ summary:
331
+ ja: 詩・短歌・俳句
332
+ en: Poems and verse
333
+ # Verse lines: short lines with no sentence punctuation (a tanka's three lines; a capitalised line of English verse).
334
+ # A glossary or a list of names has short lines too, so it takes many of them.
335
+ suggest:
336
+ paths: ["(^|/)(poems?|poetry|tanka|haiku)(/|[-_.])"]
337
+ ja: { line: "^(?=.*[ぁ-ゖ])[ぁ-ゖゝゞァ-ヺー-ヾ一-鿿々〆]{3,20}$", min_lines: 40 }
338
+ en: { line: "^\\s{0,8}[A-Z][a-z’']*,? [^.#|*\\[\\]()<>:0-9]{6,50}[a-z,;!?’—-]$", min_lines: 80 }
339
+ - id: literature/play
340
+ name: { ja: 戯曲・脚本, en: Play and script }
341
+ summary:
342
+ ja: 戯曲・脚本
343
+ en: Plays and scripts
344
+ # A speaker's name before the line: 妻  あたしは… (two ideographic spaces; a statute's 第一条  has one), ALGERNON.
345
+ suggest:
346
+ paths: ["(^|/)(plays?|screenplays?|kyakuhon)(/|[-_.])"]
347
+ ja: { line: "^[^\\s○◯●※・]{1,6}  \\S", min_lines: 20 }
348
+ en: { line: "^[A-Z][A-Z '-]{2,}\\.$", min_lines: 10 }
349
+ - id: speech/address
350
+ name: { ja: スピーチ・挨拶, en: Speech }
351
+ summary:
352
+ ja: 読み上げるために書いた演説・挨拶
353
+ en: Speeches and addresses written to be read aloud
354
+ suggest:
355
+ paths: ["(^|/)(speech(es)?|addresses)(/|[-_.])"]
356
+ ja: { line: "^(?:議長|御列席の皆様|ご列席の皆様|皆様|皆さん)、|ご清聴(?:いただき)?ありがとうございました", min_lines: 2 }
357
+ en: { line: "^(?:Mr\\.|Madam) (?:President|Speaker|Chair(?:man)?),|^Ladies and gentlemen,|Thank you for (?:your attention|listening)", min_lines: 2 }
358
+ - id: speech/transcript
359
+ name: { ja: 発言録, en: Transcript }
360
+ summary:
361
+ ja: 話したことを書き起こした記録(会見・国会の会議録)
362
+ en: Verbatim records of what was said (press conferences, parliamentary debates)
363
+ suggest:
364
+ paths: ["(^|/)(transcripts?|kaigiroku)(/|[-_.])"]
365
+ ja: { line: "^○[^ \\s]{1,30} |^((?:問|答))|^【(?:記者|大臣|質問|回答)】", min_lines: 3 }
366
+ en: { line: "^(?:Mr|Ms|Mrs|Dr)\\. [A-Z][A-Z-]{2,}(?: of [A-Z][a-z]+)?\\. ", min_lines: 3 }
367
+ # A transcript records what was said: its sentences, repeats and register are the speaker's, not the writer's to fix.
368
+ rules:
369
+ max-sentence-length: off
370
+ max-paragraph-length: off
371
+ ngram-repetition: off
372
+ repeated-sentence-head: off
373
+ heading-echo: off
374
+ empty-intensifier: off
375
+ no-doubled-joshi: off
376
+ no-nakaguro-parallel: off
377
+ taigen-dome-in-prose: off
378
+ max-kanji-continuous: off
379
+ hiragana-fukushi: off
380
+ no-mixed-desumasu: off
381
+ contraction-consistency: off
382
+ doubled-word: off
383
+ agreement-slip: off
384
+ sasete-itadaku: off
385
+ double-keigo: off
386
+ cushion-phrase-density: off
387
+ excessive-hedging: off
388
+ unqualified-superlative: off
389
+ expletive-construction: off
390
+ adverb-overuse: off
391
+ sentence-initial-conjunction-run: off
392
+ repeated-conjunction: off
393
+ undefined-acronym: off
394
+ ai-tell: off
395
+ ai-generated-composite: off
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chaffjs",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Prose validation harness. Finds what is hard to read, and never rewrites it for you.",
5
5
  "keywords": [
6
6
  "chaff",
@@ -40,6 +40,7 @@
40
40
  "README.md",
41
41
  "bin",
42
42
  "dist",
43
+ "genres.yaml",
43
44
  "profiles",
44
45
  "rules",
45
46
  "skills",
@@ -54,8 +55,8 @@
54
55
  },
55
56
  "dependencies": {
56
57
  "@anthropic-ai/sdk": "^0.125.0",
57
- "@chaffjs/lang-en": "0.13.0",
58
- "@chaffjs/lang-ja": "0.14.0",
58
+ "@chaffjs/lang-en": "0.15.0",
59
+ "@chaffjs/lang-ja": "0.16.0",
59
60
  "mdast-util-from-markdown": "^2.0.3",
60
61
  "mdast-util-frontmatter": "^2.0.1",
61
62
  "mdast-util-gfm-table": "^2.0.0",
@@ -16,7 +16,7 @@ why:
16
16
 
17
17
  message:
18
18
  ja: 1000 語あたり {density} 個の -ly 副詞があります({limit} 個まで)
19
- en: "{density} -ly adverbs per 1000 words (limit {limit})"
19
+ en: "{density} -ly {density|adverb|adverbs} per 1000 words (limit {limit})"
20
20
 
21
21
  how_to_fix:
22
22
  ja: 副詞ごと動詞に畳んでください。"said loudly" を "shouted" に。
@@ -25,4 +25,4 @@ how_to_fix:
25
25
  # 1000 語あたりの個数。件数で数えると長い文書ほど当たる(bold-density と同じ)。
26
26
  levels: { strict: 10, normal: 15, relaxed: 25 }
27
27
 
28
- use_for: [blog, business]
28
+ use_for: [blog, business, legal, docs, academic, literature, speech]
@@ -25,4 +25,4 @@ how_to_fix:
25
25
  # 1 文に受け身がいくつまで許されるか。1 は「1 つでも指摘する」。
26
26
  levels: { strict: 1, normal: 1, relaxed: 2 }
27
27
 
28
- use_for: [business]
28
+ use_for: [business, legal, docs, academic, literature, speech]
@@ -0,0 +1,36 @@
1
+ id: agreement-slip
2
+ layer: L3
3
+ status: experimental
4
+ how_to_find: agreement-slip
5
+ requires: [pos]
6
+ languages: [en]
7
+ extra_word_lists: [singular-determiner, plural-determiner, invariant-noun, count-adjective, dependent-possessive, finite-auxiliary, misnumbered-phrase]
8
+ severity: warning
9
+
10
+ name:
11
+ ja: 語の形が合っていない
12
+ en: Words that do not agree
13
+
14
+ why:
15
+ ja: 「a significant changes」「these new version」のように限定詞と名詞の単数・複数が食い違う文や、「Your can check」のように所有の語が主語の位置にある文は、書き換えの途中で片方だけ直した跡です。読み手はつまずき、急いで書いた文書に見えます。解析器の読みが一通りに決まる形だけを数え、単数と複数が同じ綴りの語(series / data)、代名詞にも読める this / these の直後の語、名詞を重ねた語(a sales team)は数えていません。
16
+ en: A determiner and a noun that differ in number ("a significant changes", "these new version"), or a possessive where the subject belongs ("Your can check"), is left over from an edit that fixed one word and not the other. The reader stumbles, and the document looks rushed. Only forms with one reading are counted; nouns spelled alike in both numbers ("series", "data"), a word right after "this" or "these" (which can stand alone), and nouns that modify another noun ("a sales team") are not.
17
+
18
+ message:
19
+ ja: 「{word}」で単数と複数が合っていません
20
+ en: '"{word}" mixes singular and plural'
21
+
22
+ messages:
23
+ number:
24
+ ja: 「{word}」で単数と複数が合っていません
25
+ en: '"{word}" mixes singular and plural'
26
+ possessive:
27
+ ja: 「{word}」で、所有の語が主語の位置にあります
28
+ en: '"{word}" puts a possessive where the subject belongs'
29
+
30
+ how_to_fix:
31
+ ja: 限定詞か名詞のどちらかに揃えてください(a significant change / significant changes)。所有の語なら、主語の語に直してください(Your can → You can、their is → there is)。
32
+ en: Make the determiner and the noun agree ("a significant change" or "significant changes"). For a possessive, write the subject you meant ("Your can" becomes "You can", "their is" becomes "there is").
33
+
34
+ levels: { strict: 1, normal: 1, relaxed: 1 }
35
+
36
+ use_for: [blog, business, technical, legal, docs, academic, literature, speech]