chaffjs 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +76 -0
- package/bin/chaff.js +4 -0
- package/dist/adapter-load.d.ts +9 -0
- package/dist/adapter-load.d.ts.map +1 -0
- package/dist/adapter-load.js +38 -0
- package/dist/adapter-load.js.map +1 -0
- package/dist/baseline.d.ts +23 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +41 -0
- package/dist/baseline.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +234 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/load.d.ts +13 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +26 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/write.d.ts +12 -0
- package/dist/config/write.d.ts.map +1 -0
- package/dist/config/write.js +60 -0
- package/dist/config/write.js.map +1 -0
- package/dist/detect-language.d.ts +3 -0
- package/dist/detect-language.d.ts.map +1 -0
- package/dist/detect-language.js +26 -0
- package/dist/detect-language.js.map +1 -0
- package/dist/detect.d.ts +7 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +13 -0
- package/dist/detect.js.map +1 -0
- package/dist/detectors/count-per-section.d.ts +4 -0
- package/dist/detectors/count-per-section.d.ts.map +1 -0
- package/dist/detectors/count-per-section.js +13 -0
- package/dist/detectors/count-per-section.js.map +1 -0
- package/dist/detectors/heading-echo.d.ts +3 -0
- package/dist/detectors/heading-echo.d.ts.map +1 -0
- package/dist/detectors/heading-echo.js +36 -0
- package/dist/detectors/heading-echo.js.map +1 -0
- package/dist/detectors/index.d.ts +4 -0
- package/dist/detectors/index.d.ts.map +1 -0
- package/dist/detectors/index.js +16 -0
- package/dist/detectors/index.js.map +1 -0
- package/dist/detectors/phrase-match.d.ts +7 -0
- package/dist/detectors/phrase-match.d.ts.map +1 -0
- package/dist/detectors/phrase-match.js +38 -0
- package/dist/detectors/phrase-match.js.map +1 -0
- package/dist/detectors/repeated-head.d.ts +3 -0
- package/dist/detectors/repeated-head.d.ts.map +1 -0
- package/dist/detectors/repeated-head.js +21 -0
- package/dist/detectors/repeated-head.js.map +1 -0
- package/dist/detectors/sentence-length.d.ts +3 -0
- package/dist/detectors/sentence-length.d.ts.map +1 -0
- package/dist/detectors/sentence-length.js +19 -0
- package/dist/detectors/sentence-length.js.map +1 -0
- package/dist/detectors/sentence-rhythm.d.ts +3 -0
- package/dist/detectors/sentence-rhythm.d.ts.map +1 -0
- package/dist/detectors/sentence-rhythm.js +28 -0
- package/dist/detectors/sentence-rhythm.js.map +1 -0
- package/dist/document.d.ts +3 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +138 -0
- package/dist/document.js.map +1 -0
- package/dist/files.d.ts +12 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +30 -0
- package/dist/files.js.map +1 -0
- package/dist/genre.d.ts +8 -0
- package/dist/genre.d.ts.map +1 -0
- package/dist/genre.js +35 -0
- package/dist/genre.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +71 -0
- package/dist/init.js.map +1 -0
- package/dist/levels.d.ts +20 -0
- package/dist/levels.d.ts.map +1 -0
- package/dist/levels.js +24 -0
- package/dist/levels.js.map +1 -0
- package/dist/mask.d.ts +3 -0
- package/dist/mask.d.ts.map +1 -0
- package/dist/mask.js +26 -0
- package/dist/mask.js.map +1 -0
- package/dist/plugin.d.ts +116 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -0
- package/dist/position.d.ts +8 -0
- package/dist/position.d.ts.map +1 -0
- package/dist/position.js +7 -0
- package/dist/position.js.map +1 -0
- package/dist/render/compact.d.ts +5 -0
- package/dist/render/compact.d.ts.map +1 -0
- package/dist/render/compact.js +15 -0
- package/dist/render/compact.js.map +1 -0
- package/dist/render/explain.d.ts +4 -0
- package/dist/render/explain.d.ts.map +1 -0
- package/dist/render/explain.js +29 -0
- package/dist/render/explain.js.map +1 -0
- package/dist/render/friendly.d.ts +4 -0
- package/dist/render/friendly.d.ts.map +1 -0
- package/dist/render/friendly.js +55 -0
- package/dist/render/friendly.js.map +1 -0
- package/dist/render/rules-json.d.ts +6 -0
- package/dist/render/rules-json.d.ts.map +1 -0
- package/dist/render/rules-json.js +39 -0
- package/dist/render/rules-json.js.map +1 -0
- package/dist/render/summary.d.ts +10 -0
- package/dist/render/summary.d.ts.map +1 -0
- package/dist/render/summary.js +18 -0
- package/dist/render/summary.js.map +1 -0
- package/dist/render/suppressions.d.ts +13 -0
- package/dist/render/suppressions.d.ts.map +1 -0
- package/dist/render/suppressions.js +50 -0
- package/dist/render/suppressions.js.map +1 -0
- package/dist/render/text.d.ts +6 -0
- package/dist/render/text.d.ts.map +1 -0
- package/dist/render/text.js +8 -0
- package/dist/render/text.js.map +1 -0
- package/dist/rule-load.d.ts +3 -0
- package/dist/rule-load.d.ts.map +1 -0
- package/dist/rule-load.js +68 -0
- package/dist/rule-load.js.map +1 -0
- package/dist/run.d.ts +14 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +47 -0
- package/dist/run.js.map +1 -0
- package/dist/stet.d.ts +19 -0
- package/dist/stet.d.ts.map +1 -0
- package/dist/stet.js +61 -0
- package/dist/stet.js.map +1 -0
- package/dist/watch.d.ts +12 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +40 -0
- package/dist/watch.js.map +1 -0
- package/package.json +63 -0
- package/rules/bold-density.yaml +28 -0
- package/rules/closing-cliche.yaml +30 -0
- package/rules/empty-intensifier.yaml +29 -0
- package/rules/heading-echo.yaml +30 -0
- package/rules/max-sentence-length.yaml +28 -0
- package/rules/padded-intro.yaml +30 -0
- package/rules/repeated-sentence-head.yaml +28 -0
- package/rules/sentence-rhythm.yaml +30 -0
- package/src/adapter-load.ts +31 -0
- package/src/baseline.ts +51 -0
- package/src/cli.ts +259 -0
- package/src/config/load.ts +38 -0
- package/src/config/write.ts +63 -0
- package/src/detect-language.ts +28 -0
- package/src/detect.ts +15 -0
- package/src/detectors/count-per-section.ts +15 -0
- package/src/detectors/heading-echo.ts +40 -0
- package/src/detectors/index.ts +17 -0
- package/src/detectors/phrase-match.ts +41 -0
- package/src/detectors/repeated-head.ts +29 -0
- package/src/detectors/sentence-length.ts +21 -0
- package/src/detectors/sentence-rhythm.ts +28 -0
- package/src/document.ts +154 -0
- package/src/files.ts +34 -0
- package/src/genre.ts +36 -0
- package/src/index.ts +4 -0
- package/src/init.ts +76 -0
- package/src/levels.ts +27 -0
- package/src/mask.ts +33 -0
- package/src/plugin.ts +124 -0
- package/src/position.ts +9 -0
- package/src/render/compact.ts +18 -0
- package/src/render/explain.ts +31 -0
- package/src/render/friendly.ts +62 -0
- package/src/render/rules-json.ts +46 -0
- package/src/render/summary.ts +22 -0
- package/src/render/suppressions.ts +57 -0
- package/src/render/text.ts +13 -0
- package/src/rule-load.ts +78 -0
- package/src/run.ts +61 -0
- package/src/stet.ts +79 -0
- package/src/watch.ts +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 isamu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# chaff
|
|
2
|
+
|
|
3
|
+
文章の読みにくいところを見つける道具。**文章は書き換えません。** 直すのは書いた人です。
|
|
4
|
+
|
|
5
|
+
`lint` が布の繊維くずを名前にしているのと同じで、`chaff` は籾殻。取り除くべきものの名を負っています。
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx chaffjs article.md
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
インストールも、AI の利用登録も、言語の指定も要りません。
|
|
12
|
+
|
|
13
|
+
## 何を見つけるか
|
|
14
|
+
|
|
15
|
+
誤字脱字ではなく、文章の組み立てを見ます。
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
一文が長すぎて、読んでいるうちに主語を見失う
|
|
19
|
+
太字が多すぎて、どこも目立たなくなっている
|
|
20
|
+
見出しと同じことを、その直後の文が繰り返している
|
|
21
|
+
「近年、〜が注目されています」など、どの記事にも当てはまる書き出し
|
|
22
|
+
「いかがでしたか」で終わる、読者に何も残さない結び
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 指摘のされかた
|
|
26
|
+
|
|
27
|
+
1 件につき「引用 / 何が起きているか / なぜ問題か / どう直すか」の 4 つが出ます。
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
─── 41 行目 ──────────────────────────────
|
|
31
|
+
|
|
32
|
+
ここで **重要** なのは **TTL** と **整合性** です。
|
|
33
|
+
|
|
34
|
+
⚠ 太字の使いすぎ
|
|
35
|
+
|
|
36
|
+
このセクションに太字が 6 箇所あります(2 箇所まで)
|
|
37
|
+
太字は読者の目を止める道具です。多用すると、どこも目立たなくなります。
|
|
38
|
+
|
|
39
|
+
→ 本当に強調したい 1〜2 箇所だけ残して、ほかは普通の文にしてください
|
|
40
|
+
|
|
41
|
+
このルールをゆるめる: npx chaffjs relax bold-density
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 指摘されたら、道は 3 つ
|
|
45
|
+
|
|
46
|
+
| 道 | どんなとき | やること |
|
|
47
|
+
| --- | --- | --- |
|
|
48
|
+
| 直す | 指摘がもっともなとき | 文章を書き直す |
|
|
49
|
+
| この箇所だけ黙らせる | 指摘は正しいが、ここは意図的なとき | `<!-- stet: rule-id — 理由 -->` |
|
|
50
|
+
| ルールを変える | 自分たちの方針に合わないとき | `npx chaffjs relax rule-id --why "理由"` |
|
|
51
|
+
|
|
52
|
+
## 主なコマンド
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx chaffjs . この場所の Markdown を全部
|
|
56
|
+
npx chaffjs article.md --watch 保存のたびに、変わったところだけ出す
|
|
57
|
+
npx chaffjs init chaff.yaml を作る
|
|
58
|
+
npx chaffjs explain bold-density ルールの意図と根拠を読む
|
|
59
|
+
npx chaffjs baseline docs/ 既にある指摘を棚上げする
|
|
60
|
+
npx chaffjs suppressions docs/ stet で黙らせている指摘を数える
|
|
61
|
+
npx chaffjs rules --json いまの設定を JSON で出す(AI に渡す用)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
設定は `strict` / `normal` / `relaxed` / `off` の 4 語から選ぶだけで、数字は要りません。
|
|
65
|
+
|
|
66
|
+
## 言語
|
|
67
|
+
|
|
68
|
+
日本語と英語。言語は本文から自動で判定します。アダプタ(`@chaffjs/lang-ja` / `@chaffjs/lang-en`)は同梱されているので、別に入れる必要はありません。
|
|
69
|
+
|
|
70
|
+
新しい言語のアダプタは誰でも出せます。公式は `@chaffjs/<言語>`、第三者は `chaff-lang-<言語>` と名乗ってください(`@typescript-eslint/*` と `eslint-plugin-*` の関係と同じです)。
|
|
71
|
+
|
|
72
|
+
## ドキュメント
|
|
73
|
+
|
|
74
|
+
https://github.com/isamu/lab/tree/main/text
|
|
75
|
+
|
|
76
|
+
MIT
|
package/bin/chaff.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LanguageAdapter } from "./plugin.ts";
|
|
2
|
+
export declare const packageFor: (language: string) => string | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* アダプタは「必要になったものだけ」を実行時に解決する。spec §17.2。
|
|
5
|
+
* core だけで起動し、文字種で言語を当ててから、その言語のアダプタを読む。
|
|
6
|
+
* 全言語を静的に import すると、使わない言語のぶんまで npx の初回取得が膨らむ。
|
|
7
|
+
*/
|
|
8
|
+
export declare const loadAdapter: (language: string) => Promise<LanguageAdapter>;
|
|
9
|
+
//# sourceMappingURL=adapter-load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-load.d.ts","sourceRoot":"","sources":["../src/adapter-load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAenD,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,KAAG,MAAM,GAAG,SAAsC,CAAC;AAE9F;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,eAAe,CAQ3E,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
const ADAPTER_PACKAGE = { ja: "@chaffjs/lang-ja", en: "@chaffjs/lang-en" };
|
|
10
|
+
const isAdapter = (value) => {
|
|
11
|
+
if (typeof value !== "object" || value === null)
|
|
12
|
+
return false;
|
|
13
|
+
const record = { ...value };
|
|
14
|
+
return record["kind"] === "language" && typeof record["id"] === "string" && typeof record["segment"] === "function";
|
|
15
|
+
};
|
|
16
|
+
const pickExport = (module) => {
|
|
17
|
+
const record = { ...module };
|
|
18
|
+
return isAdapter(record["adapter"]) ? record["adapter"] : record["default"];
|
|
19
|
+
};
|
|
20
|
+
export const packageFor = (language) => ADAPTER_PACKAGE[language];
|
|
21
|
+
/**
|
|
22
|
+
* アダプタは「必要になったものだけ」を実行時に解決する。spec §17.2。
|
|
23
|
+
* core だけで起動し、文字種で言語を当ててから、その言語のアダプタを読む。
|
|
24
|
+
* 全言語を静的に import すると、使わない言語のぶんまで npx の初回取得が膨らむ。
|
|
25
|
+
*/
|
|
26
|
+
export const loadAdapter = async (language) => {
|
|
27
|
+
const specifier = packageFor(language);
|
|
28
|
+
if (specifier === undefined)
|
|
29
|
+
throw new Error(`no adapter for language "${language}"`);
|
|
30
|
+
const module = await import(__rewriteRelativeImportExtension(specifier));
|
|
31
|
+
if (typeof module !== "object" || module === null)
|
|
32
|
+
throw new Error(`${specifier} did not export a module`);
|
|
33
|
+
const candidate = pickExport(module);
|
|
34
|
+
if (!isAdapter(candidate))
|
|
35
|
+
throw new Error(`${specifier} does not export a LanguageAdapter`);
|
|
36
|
+
return candidate;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=adapter-load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-load.js","sourceRoot":"","sources":["../src/adapter-load.ts"],"names":[],"mappings":";;;;;;;;AAEA,MAAM,eAAe,GAAqC,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,kBAAkB,EAAE,CAAC;AAE7G,MAAM,SAAS,GAAG,CAAC,KAAc,EAA4B,EAAE;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,MAAM,GAA4B,EAAE,GAAG,KAAK,EAAE,CAAC;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC;AACtH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,MAAc,EAAW,EAAE;IAC7C,MAAM,MAAM,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IACtD,OAAO,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC9E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAsB,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;AAE9F;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,QAAgB,EAA4B,EAAE;IAC9E,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,SAAS,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,GAAG,CAAC,CAAC;IACtF,MAAM,MAAM,GAAY,MAAM,MAAM,kCAAC,SAAS,EAAC,CAAC;IAChD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,0BAA0B,CAAC,CAAC;IAC3G,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,oCAAoC,CAAC,CAAC;IAC7F,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Finding } from "./plugin.ts";
|
|
2
|
+
export declare const BASELINE_FILE = ".chaff-baseline.json";
|
|
3
|
+
/**
|
|
4
|
+
* 行番号ではなく内容で同定する。前後に段落を 1 つ足しただけで棚上げが全部剥がれると、
|
|
5
|
+
* baseline は使い物にならない。workflow spec §8。
|
|
6
|
+
*/
|
|
7
|
+
export declare const fingerprint: (path: string, finding: Finding) => string;
|
|
8
|
+
export type Baseline = {
|
|
9
|
+
readonly version: 1;
|
|
10
|
+
readonly created: string;
|
|
11
|
+
readonly entries: readonly string[];
|
|
12
|
+
};
|
|
13
|
+
export declare const readBaseline: (path: string) => Baseline | undefined;
|
|
14
|
+
export declare const writeBaseline: (path: string, entries: readonly string[]) => void;
|
|
15
|
+
export type Split = {
|
|
16
|
+
readonly fresh: readonly Finding[];
|
|
17
|
+
readonly shelved: number;
|
|
18
|
+
};
|
|
19
|
+
/** baseline にあるものは報告しない。新しく増えたものだけを出す。 */
|
|
20
|
+
export declare const splitByBaseline: (path: string, findings: readonly Finding[], baseline: Baseline | undefined) => Split;
|
|
21
|
+
/** 直った分だけを落とす。増える方向には動かさない。 */
|
|
22
|
+
export declare const prune: (previous: Baseline, stillPresent: readonly string[]) => string[];
|
|
23
|
+
//# sourceMappingURL=baseline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,aAAa,yBAAyB,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,EAAE,SAAS,OAAO,KAAG,MAG5D,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAS9G,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,QAAQ,GAAG,SAItD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,SAAS,SAAS,MAAM,EAAE,KAAG,IAIxE,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,0CAA0C;AAC1C,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,UAAU,SAAS,OAAO,EAAE,EAAE,UAAU,QAAQ,GAAG,SAAS,KAAG,KAK5G,CAAC;AAEF,+BAA+B;AAC/B,eAAO,MAAM,KAAK,GAAI,UAAU,QAAQ,EAAE,cAAc,SAAS,MAAM,EAAE,KAAG,MAAM,EAGjF,CAAC"}
|
package/dist/baseline.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
export const BASELINE_FILE = ".chaff-baseline.json";
|
|
4
|
+
/**
|
|
5
|
+
* 行番号ではなく内容で同定する。前後に段落を 1 つ足しただけで棚上げが全部剥がれると、
|
|
6
|
+
* baseline は使い物にならない。workflow spec §8。
|
|
7
|
+
*/
|
|
8
|
+
export const fingerprint = (path, finding) => {
|
|
9
|
+
const body = [path, finding.rule, finding.quote.replace(/\s+/gu, " ").trim()].join(" ");
|
|
10
|
+
return createHash("sha256").update(body).digest("hex").slice(0, 16);
|
|
11
|
+
};
|
|
12
|
+
const isBaseline = (value) => typeof value === "object" &&
|
|
13
|
+
value !== null &&
|
|
14
|
+
"entries" in value &&
|
|
15
|
+
Array.isArray(value.entries) &&
|
|
16
|
+
value.entries.every((entry) => typeof entry === "string");
|
|
17
|
+
export const readBaseline = (path) => {
|
|
18
|
+
if (!existsSync(path))
|
|
19
|
+
return undefined;
|
|
20
|
+
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
21
|
+
return isBaseline(raw) ? raw : undefined;
|
|
22
|
+
};
|
|
23
|
+
export const writeBaseline = (path, entries) => {
|
|
24
|
+
const sorted = [...entries].sort((left, right) => left.localeCompare(right, "en"));
|
|
25
|
+
const body = { version: 1, created: new Date().toISOString().slice(0, 10), entries: sorted };
|
|
26
|
+
writeFileSync(path, `${JSON.stringify(body, null, 2)}\n`, "utf8");
|
|
27
|
+
};
|
|
28
|
+
/** baseline にあるものは報告しない。新しく増えたものだけを出す。 */
|
|
29
|
+
export const splitByBaseline = (path, findings, baseline) => {
|
|
30
|
+
if (baseline === undefined)
|
|
31
|
+
return { fresh: findings, shelved: 0 };
|
|
32
|
+
const known = new Set(baseline.entries);
|
|
33
|
+
const fresh = findings.filter((finding) => !known.has(fingerprint(path, finding)));
|
|
34
|
+
return { fresh, shelved: findings.length - fresh.length };
|
|
35
|
+
};
|
|
36
|
+
/** 直った分だけを落とす。増える方向には動かさない。 */
|
|
37
|
+
export const prune = (previous, stillPresent) => {
|
|
38
|
+
const present = new Set(stillPresent);
|
|
39
|
+
return previous.entries.filter((entry) => present.has(entry));
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGlE,MAAM,CAAC,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,OAAgB,EAAU,EAAE;IACpE,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC,CAAC;AAIF,MAAM,UAAU,GAAG,CAAC,KAAc,EAAqB,EAAE,CACvD,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,SAAS,IAAI,KAAK;IAClB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAwB,EAAE;IACjE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5D,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,OAA0B,EAAQ,EAAE;IAC9E,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7F,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpE,CAAC,CAAC;AAIF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,QAA4B,EAAE,QAA8B,EAAS,EAAE;IACnH,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;AAC5D,CAAC,CAAC;AAEF,+BAA+B;AAC/B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,QAAkB,EAAE,YAA+B,EAAY,EAAE;IACrF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAChE,CAAC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAwPA,eAAO,MAAM,IAAI,GAAU,MAAM,SAAS,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAUlE,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { loadAdapter, packageFor } from "./adapter-load.js";
|
|
5
|
+
import { CONFIG_FILE, EMPTY, loadConfig } from "./config/load.js";
|
|
6
|
+
import { applyLevel } from "./config/write.js";
|
|
7
|
+
import { buildDocument } from "./document.js";
|
|
8
|
+
import { guessLanguage } from "./detect.js";
|
|
9
|
+
import { collectTargets } from "./files.js";
|
|
10
|
+
import { BASELINE_FILE, fingerprint, readBaseline, splitByBaseline, writeBaseline } from "./baseline.js";
|
|
11
|
+
import { applySuppressions } from "./stet.js";
|
|
12
|
+
import { renderSuppressions } from "./render/suppressions.js";
|
|
13
|
+
import { clock, describeChange, snapshotOf, watchPaths } from "./watch.js";
|
|
14
|
+
import { frontMatterGenre, guessGenre } from "./genre.js";
|
|
15
|
+
import { GENRES, runInit } from "./init.js";
|
|
16
|
+
import { loadRules } from "./rule-load.js";
|
|
17
|
+
import { renderCompact } from "./render/compact.js";
|
|
18
|
+
import { renderExplain } from "./render/explain.js";
|
|
19
|
+
import { renderFriendly } from "./render/friendly.js";
|
|
20
|
+
import { rulesJson } from "./render/rules-json.js";
|
|
21
|
+
import { renderSummary } from "./render/summary.js";
|
|
22
|
+
import { runRules } from "./run.js";
|
|
23
|
+
const USAGE = `chaff — 文章の読みにくいところを見つけます。文章は書き換えません。
|
|
24
|
+
|
|
25
|
+
chaff <file|dir|glob>... 検査する(設定も API key も要りません)
|
|
26
|
+
chaff . この場所の Markdown を全部
|
|
27
|
+
chaff init chaff.yaml を作る
|
|
28
|
+
chaff explain <rule> そのルールの意図と根拠を読む
|
|
29
|
+
chaff genres ジャンルの一覧
|
|
30
|
+
chaff rules --json いまの設定を JSON で出す(AI に渡す用)
|
|
31
|
+
chaff baseline <dir> いまある指摘を棚上げする(既存の repo に入れるとき)
|
|
32
|
+
chaff suppressions <dir> stet で黙らせている指摘を数える
|
|
33
|
+
chaff relax|strict|off <rule> [--why "理由"]
|
|
34
|
+
|
|
35
|
+
--compact エンジニア向けの 1 行形式
|
|
36
|
+
--experimental 試験中の rule も動かす
|
|
37
|
+
--show-baseline 棚上げした分も含めて全部見る
|
|
38
|
+
--watch 保存のたびに見直し、変わったところだけ出す
|
|
39
|
+
|
|
40
|
+
この箇所だけ黙らせる: <!-- stet: rule-id — 理由 -->
|
|
41
|
+
|
|
42
|
+
値は strict / normal / relaxed / off の 4 つから選びます。
|
|
43
|
+
`;
|
|
44
|
+
const readConfig = () => (existsSync(join(process.cwd(), CONFIG_FILE)) ? loadConfig(join(process.cwd(), CONFIG_FILE)) : EMPTY);
|
|
45
|
+
const resolveGenre = (path, source, config) => {
|
|
46
|
+
if (config.genre !== undefined)
|
|
47
|
+
return { genre: config.genre, from: CONFIG_FILE };
|
|
48
|
+
const guess = guessGenre(path, source, frontMatterGenre(source));
|
|
49
|
+
return guess === undefined ? { genre: "blog/tech", from: "既定" } : { genre: guess.genre, from: guess.from };
|
|
50
|
+
};
|
|
51
|
+
const findRule = (rules, id) => rules.find((rule) => rule.id === id);
|
|
52
|
+
const changeSetting = (command, ruleId, why) => {
|
|
53
|
+
const config = readConfig();
|
|
54
|
+
const rule = findRule(loadRules(config.language ?? "ja"), ruleId);
|
|
55
|
+
if (rule === undefined) {
|
|
56
|
+
console.error(`${ruleId ?? "(名前なし)"} というルールはありません。npx chaff rules --json で一覧が出ます。`);
|
|
57
|
+
return 1;
|
|
58
|
+
}
|
|
59
|
+
const outcome = applyLevel(join(process.cwd(), CONFIG_FILE), rule, command, why, config.language ?? "ja", process.env["USER"] ?? "unknown");
|
|
60
|
+
console.log(outcome.message);
|
|
61
|
+
return outcome.ok ? 0 : 1;
|
|
62
|
+
};
|
|
63
|
+
const flag = (argv, name) => {
|
|
64
|
+
const at = argv.indexOf(name);
|
|
65
|
+
return at === -1 ? undefined : argv[at + 1];
|
|
66
|
+
};
|
|
67
|
+
const headerFor = (path, genre, from, language, shelved, hushed) => {
|
|
68
|
+
const shelf = shelved > 0 ? ` 棚上げ ${shelved} 件` : "";
|
|
69
|
+
const stet = hushed > 0 ? ` stet ${hushed} 件` : "";
|
|
70
|
+
return `${path} ${genre} \u00b7 ${language === "ja" ? "日本語" : "英語"} ジャンルは${from}から${shelf}${stet}`;
|
|
71
|
+
};
|
|
72
|
+
const inspect = async (path, config, argv) => {
|
|
73
|
+
const source = await readFile(path, "utf8");
|
|
74
|
+
const language = config.language ?? guessLanguage(source).language;
|
|
75
|
+
const adapter = await loadAdapter(language);
|
|
76
|
+
const { genre, from } = resolveGenre(path, source, config);
|
|
77
|
+
const doc = buildDocument(path, source, adapter);
|
|
78
|
+
const rules = loadRules(language);
|
|
79
|
+
const raw = runRules(doc, rules, config.rules, config.experimental || argv.includes("--experimental"), genre);
|
|
80
|
+
// 応答は 3 つ。stet で黙らせたものは、ここで落とす。
|
|
81
|
+
const applied = applySuppressions(source, raw.findings, doc.sections.map((section) => section.span));
|
|
82
|
+
const baseline = argv.includes("--show-baseline") ? undefined : readBaseline(join(process.cwd(), BASELINE_FILE));
|
|
83
|
+
const split = splitByBaseline(path, applied.kept, baseline);
|
|
84
|
+
const result = { ...raw, findings: split.fresh };
|
|
85
|
+
const header = headerFor(path, genre, from, language, split.shelved, applied.suppressed.length);
|
|
86
|
+
const text = argv.includes("--compact") ? renderCompact(header, result, rules, language) : renderFriendly(header, result, rules, language);
|
|
87
|
+
return {
|
|
88
|
+
text,
|
|
89
|
+
outcome: { path, findings: split.fresh, notRun: raw.skipped.length },
|
|
90
|
+
perFile: { path, suppressed: applied.suppressed, reasonless: applied.unusedReasonless },
|
|
91
|
+
all: applied.kept.map((finding) => fingerprint(path, finding)),
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
const lint = async (targets, argv) => {
|
|
95
|
+
const paths = collectTargets(targets);
|
|
96
|
+
if (paths.length === 0) {
|
|
97
|
+
// 0 件を成功にすると「CI は通っているが何も検証していない」状態が続く。§14。
|
|
98
|
+
console.error(`Markdown が 1 つも見つかりませんでした: ${targets.join(", ")}`);
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
const config = readConfig();
|
|
102
|
+
const language = config.language ?? "ja";
|
|
103
|
+
if (packageFor(language) === undefined) {
|
|
104
|
+
console.error(`言語 "${language}" のアダプタがありません。`);
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
const results = await Promise.all(paths.map((path) => inspect(path, config, argv)));
|
|
108
|
+
results.filter((result) => result.outcome.findings.length > 0 || paths.length === 1).forEach((result) => console.log(result.text));
|
|
109
|
+
renderSummary(results.map((result) => result.outcome)).forEach((line) => console.log(line));
|
|
110
|
+
return results.some((result) => result.outcome.findings.some((finding) => finding.severity === "error")) ? 1 : 0;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* 書いている最中は、全件を出し直されても何が変わったのか分からない。
|
|
114
|
+
* 差分だけを出す。workflow spec §11。
|
|
115
|
+
*/
|
|
116
|
+
const runWatch = async (targets, argv) => {
|
|
117
|
+
const paths = collectTargets(targets);
|
|
118
|
+
if (paths.length === 0) {
|
|
119
|
+
console.error(`Markdown が 1 つも見つかりませんでした: ${targets.join(", ")}`);
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
const config = readConfig();
|
|
123
|
+
const seen = new Map();
|
|
124
|
+
const once = async (path, first) => {
|
|
125
|
+
const result = await inspect(path, config, argv);
|
|
126
|
+
const after = snapshotOf(result.outcome.findings);
|
|
127
|
+
const before = seen.get(path) ?? {};
|
|
128
|
+
seen.set(path, after);
|
|
129
|
+
if (first)
|
|
130
|
+
return;
|
|
131
|
+
const change = describeChange(before, after);
|
|
132
|
+
console.log(`${clock()} ${path} ${change ?? "変わりませんでした"}`);
|
|
133
|
+
};
|
|
134
|
+
await Promise.all(paths.map((path) => once(path, true)));
|
|
135
|
+
const totals = [...seen.values()].reduce((sum, snapshot) => sum + Object.values(snapshot).reduce((inner, count) => inner + count, 0), 0);
|
|
136
|
+
console.log(`\n ${paths.length} ファイルを見ています。いまの指摘は ${totals} 件です。`);
|
|
137
|
+
console.log(" 保存するたびに、変わったところだけ出します。止めるには Ctrl-C。\n");
|
|
138
|
+
const stop = watchPaths(paths, (path) => void once(path, false));
|
|
139
|
+
process.on("SIGINT", () => {
|
|
140
|
+
stop();
|
|
141
|
+
process.exit(0);
|
|
142
|
+
});
|
|
143
|
+
return new Promise(() => undefined);
|
|
144
|
+
};
|
|
145
|
+
const explain = (ruleId) => {
|
|
146
|
+
const config = readConfig();
|
|
147
|
+
const language = config.language ?? "ja";
|
|
148
|
+
const rules = loadRules(language);
|
|
149
|
+
const rule = findRule(rules, ruleId);
|
|
150
|
+
if (rule === undefined) {
|
|
151
|
+
const list = rules.map((entry) => ` ${entry.id}`).join("\n");
|
|
152
|
+
console.error(`${ruleId ?? "(名前なし)"} というルールはありません。\n一覧:\n${list}`);
|
|
153
|
+
return 1;
|
|
154
|
+
}
|
|
155
|
+
const current = config.rules[rule.id] ?? (rule.status === "experimental" && !config.experimental ? "off" : "normal");
|
|
156
|
+
console.log(renderExplain(rule, current, language, unitOf(rule.id, language)));
|
|
157
|
+
return 0;
|
|
158
|
+
};
|
|
159
|
+
/** 閾値の単位。explain で「4 とは何の 4 か」を示すため。 */
|
|
160
|
+
const unitOf = (ruleId, language) => {
|
|
161
|
+
if (ruleId !== "max-sentence-length")
|
|
162
|
+
return "回";
|
|
163
|
+
return language === "ja" ? "文字" : "語";
|
|
164
|
+
};
|
|
165
|
+
const runBaseline = async (targets, argv) => {
|
|
166
|
+
const paths = collectTargets(targets.length > 0 ? targets : ["."]);
|
|
167
|
+
if (paths.length === 0) {
|
|
168
|
+
console.error("Markdown が 1 つも見つかりませんでした。");
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
const config = readConfig();
|
|
172
|
+
const results = await Promise.all(paths.map((path) => inspect(path, config, [...argv, "--show-baseline"])));
|
|
173
|
+
const entries = results.flatMap((result) => result.all);
|
|
174
|
+
const file = join(process.cwd(), BASELINE_FILE);
|
|
175
|
+
writeBaseline(file, entries);
|
|
176
|
+
console.log([
|
|
177
|
+
"",
|
|
178
|
+
` ${paths.length} ファイルを走査しました。`,
|
|
179
|
+
"",
|
|
180
|
+
` ${entries.length} 件の指摘を ${BASELINE_FILE} に記録しました。`,
|
|
181
|
+
" 以後、これらは報告されません。新しく増えたものだけが出ます。",
|
|
182
|
+
"",
|
|
183
|
+
` ${BASELINE_FILE} を commit してください。`,
|
|
184
|
+
"",
|
|
185
|
+
].join("\n"));
|
|
186
|
+
return 0;
|
|
187
|
+
};
|
|
188
|
+
const runSuppressions = async (targets, argv) => {
|
|
189
|
+
const paths = collectTargets(targets.length > 0 ? targets : ["."]);
|
|
190
|
+
const config = readConfig();
|
|
191
|
+
const results = await Promise.all(paths.map((path) => inspect(path, config, [...argv, "--show-baseline"])));
|
|
192
|
+
console.log(renderSuppressions(results.map((result) => result.perFile)));
|
|
193
|
+
return 0;
|
|
194
|
+
};
|
|
195
|
+
/** `--` で始まらない引数。対象のパス。 */
|
|
196
|
+
const positional = (argv) => argv.slice(1).filter((arg) => !arg.startsWith("--"));
|
|
197
|
+
const showRules = () => {
|
|
198
|
+
const config = readConfig();
|
|
199
|
+
const language = config.language ?? "ja";
|
|
200
|
+
console.log(rulesJson(loadRules(language), config, language, config.genre ?? "blog/tech"));
|
|
201
|
+
return 0;
|
|
202
|
+
};
|
|
203
|
+
const showGenres = () => {
|
|
204
|
+
console.log(["", " 使えるジャンル:", ...GENRES.map((genre) => ` ${genre}`), "", " chaff.yaml の genre に書くか、--genre で指定します。", ""].join("\n"));
|
|
205
|
+
return 0;
|
|
206
|
+
};
|
|
207
|
+
/** 分岐を数珠つなぎにせず表にする。足すときに main を太らせない。 */
|
|
208
|
+
const HANDLERS = {
|
|
209
|
+
init: (argv) => {
|
|
210
|
+
runInit(process.cwd(), flag(argv, "--genre") ?? "blog/tech").forEach((line) => console.log(line));
|
|
211
|
+
return 0;
|
|
212
|
+
},
|
|
213
|
+
genres: showGenres,
|
|
214
|
+
rules: showRules,
|
|
215
|
+
explain: (argv) => explain(argv[1]),
|
|
216
|
+
baseline: (argv) => runBaseline(positional(argv), argv),
|
|
217
|
+
suppressions: (argv) => runSuppressions(positional(argv), argv),
|
|
218
|
+
relax: (argv) => changeSetting("relaxed", argv[1], flag(argv, "--why")),
|
|
219
|
+
strict: (argv) => changeSetting("strict", argv[1], flag(argv, "--why")),
|
|
220
|
+
off: (argv) => changeSetting("off", argv[1], flag(argv, "--why")),
|
|
221
|
+
};
|
|
222
|
+
export const main = async (argv) => {
|
|
223
|
+
const first = argv[0];
|
|
224
|
+
if (first === undefined || first === "--help" || first === "-h") {
|
|
225
|
+
console.log(USAGE);
|
|
226
|
+
return first === undefined ? 1 : 0;
|
|
227
|
+
}
|
|
228
|
+
const handler = HANDLERS[first];
|
|
229
|
+
if (handler !== undefined)
|
|
230
|
+
return handler(argv);
|
|
231
|
+
const targets = (first === "lint" ? argv.slice(1) : argv).filter((arg) => !arg.startsWith("--"));
|
|
232
|
+
return argv.includes("--watch") ? runWatch(targets, argv) : lint(targets, argv);
|
|
233
|
+
};
|
|
234
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Level } from "../plugin.ts";
|
|
2
|
+
export declare const CONFIG_FILE = "chaff.yaml";
|
|
3
|
+
export type Config = {
|
|
4
|
+
readonly genre: string | undefined;
|
|
5
|
+
readonly language: string | undefined;
|
|
6
|
+
readonly rules: Readonly<Record<string, Level>>;
|
|
7
|
+
readonly experimental: boolean;
|
|
8
|
+
readonly path: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare const EMPTY: Config;
|
|
11
|
+
/** 設定ファイルが無くても動く。あっても、既定から変えたものだけが書かれている。spec §18。 */
|
|
12
|
+
export declare const loadConfig: (path: string) => Config;
|
|
13
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,MAAmG,CAAC;AAWxH,sDAAsD;AACtD,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MAUzC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { parse } from "yaml";
|
|
3
|
+
import { isLevel } from "../levels.js";
|
|
4
|
+
export const CONFIG_FILE = "chaff.yaml";
|
|
5
|
+
export const EMPTY = { genre: undefined, language: undefined, rules: {}, experimental: false, path: undefined };
|
|
6
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
|
+
const rulesOf = (raw) => {
|
|
8
|
+
if (!isRecord(raw))
|
|
9
|
+
return {};
|
|
10
|
+
return Object.entries(raw).reduce((acc, [id, value]) => (isLevel(value) ? { ...acc, [id]: value } : acc), {});
|
|
11
|
+
};
|
|
12
|
+
const str = (value) => (typeof value === "string" ? value : undefined);
|
|
13
|
+
/** 設定ファイルが無くても動く。あっても、既定から変えたものだけが書かれている。spec §18。 */
|
|
14
|
+
export const loadConfig = (path) => {
|
|
15
|
+
const raw = parse(readFileSync(path, "utf8"));
|
|
16
|
+
if (!isRecord(raw))
|
|
17
|
+
return { ...EMPTY, path };
|
|
18
|
+
return {
|
|
19
|
+
genre: str(raw["genre"]),
|
|
20
|
+
language: str(raw["language"]),
|
|
21
|
+
rules: rulesOf(raw["rules"]),
|
|
22
|
+
experimental: raw["experimental"] === true,
|
|
23
|
+
path,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC;AAUxC,MAAM,CAAC,MAAM,KAAK,GAAW,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAExH,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,OAAO,GAAG,CAAC,GAAY,EAAyB,EAAE;IACtD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAwB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;AACvI,CAAC,CAAC;AAEF,MAAM,GAAG,GAAG,CAAC,KAAc,EAAsB,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAEpG,sDAAsD;AACtD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE;IACjD,MAAM,GAAG,GAAY,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9C,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxB,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9B,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5B,YAAY,EAAE,GAAG,CAAC,cAAc,CAAC,KAAK,IAAI;QAC1C,IAAI;KACL,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Level, RuleDefinition } from "../plugin.ts";
|
|
2
|
+
export type ChangeOutcome = {
|
|
3
|
+
readonly ok: boolean;
|
|
4
|
+
readonly message: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* 設定を機械的に書き換えるが、**既存のコメントを壊さない**。
|
|
8
|
+
* 設定ファイルがチームの規範そのものである以上、コメントが失われることは規範が失われること。
|
|
9
|
+
* spec §19.4。
|
|
10
|
+
*/
|
|
11
|
+
export declare const applyLevel: (path: string, rule: RuleDefinition, level: Level, why: string | undefined, language: string, who: string) => ChangeOutcome;
|
|
12
|
+
//# sourceMappingURL=write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/config/write.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAU1D,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAc/E;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,MAAM,cAAc,EAAE,OAAO,KAAK,EAAE,KAAK,MAAM,GAAG,SAAS,EAAE,UAAU,MAAM,EAAE,KAAK,MAAM,KAAG,aA6BrI,CAAC"}
|