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/dist/files.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { globSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative, sep } from "node:path";
|
|
3
|
+
const MARKDOWN = [".md", ".markdown", ".mdx"];
|
|
4
|
+
/** 走査から外す。ここを通すと node_modules の README を延々と検査することになる。 */
|
|
5
|
+
const SKIP = ["node_modules", "dist", "build", "coverage", ".git", ".chaff-cache"];
|
|
6
|
+
const isMarkdown = (path) => MARKDOWN.some((ext) => path.toLowerCase().endsWith(ext));
|
|
7
|
+
const isSkipped = (path) => path.split(sep).some((part) => SKIP.includes(part));
|
|
8
|
+
const expand = (target) => {
|
|
9
|
+
const stat = statSync(target, { throwIfNoEntry: false });
|
|
10
|
+
if (stat === undefined)
|
|
11
|
+
return globSync(target).filter(isMarkdown);
|
|
12
|
+
if (stat.isFile())
|
|
13
|
+
return [target];
|
|
14
|
+
return globSync(join(target, "**", "*.{md,markdown,mdx}"));
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* 与えられたファイル・ディレクトリ・glob を、検査する Markdown の一覧にする。
|
|
18
|
+
* 0 件は成功にしない(§14)。glob が何にもマッチしないまま CI が緑になると、
|
|
19
|
+
* 「通っているが何も検証していない」状態が延々と続く。
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* ロケールを明示する。既定のロケールに任せると、同じ入力でも機械によって順序が変わる。
|
|
23
|
+
* 指摘の並びは CI のログにも baseline にも入るので、順序が揺れてはいけない。
|
|
24
|
+
*/
|
|
25
|
+
export const byPath = (left, right) => left.localeCompare(right, "en");
|
|
26
|
+
export const collectTargets = (targets) => {
|
|
27
|
+
const found = targets.flatMap(expand).filter((path) => !isSkipped(path));
|
|
28
|
+
return [...new Set(found)].sort((left, right) => byPath(relative(".", left), relative(".", right)));
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AAE9C,yDAAyD;AACzD,MAAM,IAAI,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AAEnF,MAAM,UAAU,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAEvG,MAAM,SAAS,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAEjG,MAAM,MAAM,GAAG,CAAC,MAAc,EAAY,EAAE;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnE,IAAI,IAAI,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF;;;;GAIG;AACH;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAA0B,EAAY,EAAE;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACtG,CAAC,CAAC"}
|
package/dist/genre.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type GenreGuess = {
|
|
2
|
+
readonly genre: string;
|
|
3
|
+
readonly from: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const guessGenre: (path: string, source: string, front: string | undefined) => GenreGuess | undefined;
|
|
6
|
+
/** front matter の genre / type を拾う。失敗しても落とさない。 */
|
|
7
|
+
export declare const frontMatterGenre: (source: string) => string | undefined;
|
|
8
|
+
//# sourceMappingURL=genre.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genre.d.ts","sourceRoot":"","sources":["../src/genre.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAqB3E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,GAAG,SAAS,KAAG,UAAU,GAAG,SAOjG,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,SAI1D,CAAC"}
|
package/dist/genre.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const BY_PATH = [
|
|
2
|
+
[/(^|\/)(proposals?|teian)\//iu, "business/proposal"],
|
|
3
|
+
[/(^|\/)(minutes|gijiroku)\//iu, "business/meeting-notes"],
|
|
4
|
+
[/(^|\/)(press|pr)\//iu, "business/press-release"],
|
|
5
|
+
[/(^|\/)(reports?)\//iu, "business/report"],
|
|
6
|
+
[/(^|\/)(blog|posts?|articles?)\//iu, "blog/tech"],
|
|
7
|
+
[/(^|\/)docs?\//iu, "blog/tech"],
|
|
8
|
+
];
|
|
9
|
+
/**
|
|
10
|
+
* 見出しと行頭に限る。本文中の言及では判定しない。
|
|
11
|
+
* 「決定事項」という語を説明している文書を議事録と判定してしまうため。
|
|
12
|
+
*/
|
|
13
|
+
const BY_CONTENT = [
|
|
14
|
+
[/^#{1,6}\s.*(?:報道関係者各位|For Immediate Release)/mu, "business/press-release"],
|
|
15
|
+
[/^(?:#{1,6}\s)?(?:出席者|決定事項|Attendees)\s*$/mu, "business/meeting-notes"],
|
|
16
|
+
[/^(?:拝啓|お世話になっております)/mu, "business/report"],
|
|
17
|
+
];
|
|
18
|
+
export const guessGenre = (path, source, front) => {
|
|
19
|
+
if (front !== undefined)
|
|
20
|
+
return { genre: front, from: "front matter" };
|
|
21
|
+
const byPath = BY_PATH.find(([pattern]) => pattern.test(path));
|
|
22
|
+
if (byPath !== undefined)
|
|
23
|
+
return { genre: byPath[1], from: "パス" };
|
|
24
|
+
const byContent = BY_CONTENT.find(([pattern]) => pattern.test(source));
|
|
25
|
+
if (byContent !== undefined)
|
|
26
|
+
return { genre: byContent[1], from: "内容" };
|
|
27
|
+
return undefined;
|
|
28
|
+
};
|
|
29
|
+
/** front matter の genre / type を拾う。失敗しても落とさない。 */
|
|
30
|
+
export const frontMatterGenre = (source) => {
|
|
31
|
+
const match = /^---\n([\s\S]*?)\n---/u.exec(source);
|
|
32
|
+
const line = match?.[1] === undefined ? undefined : /^(?:genre|type):\s*(\S+)\s*$/mu.exec(match[1]);
|
|
33
|
+
return line?.[1];
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=genre.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genre.js","sourceRoot":"","sources":["../src/genre.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAA2C;IACtD,CAAC,8BAA8B,EAAE,mBAAmB,CAAC;IACrD,CAAC,8BAA8B,EAAE,wBAAwB,CAAC;IAC1D,CAAC,sBAAsB,EAAE,wBAAwB,CAAC;IAClD,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;IAC3C,CAAC,mCAAmC,EAAE,WAAW,CAAC;IAClD,CAAC,iBAAiB,EAAE,WAAW,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,GAA2C;IACzD,CAAC,gDAAgD,EAAE,wBAAwB,CAAC;IAC5E,CAAC,4CAA4C,EAAE,wBAAwB,CAAC;IACxE,CAAC,uBAAuB,EAAE,iBAAiB,CAAC;CAC7C,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,MAAc,EAAE,KAAyB,EAA0B,EAAE;IAC5G,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IACvE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAClE,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxE,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,kDAAkD;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAsB,EAAE;IACrE,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpG,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { AdapterCapabilities, LanguageAdapter, LengthUnit, Segmentation, Sentence, Span, Token } from "./plugin.ts";
|
|
2
|
+
export type { LanguageGuess } from "./detect.ts";
|
|
3
|
+
export { guessLanguage } from "./detect.ts";
|
|
4
|
+
export { loadAdapter, packageFor } from "./adapter-load.ts";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzH,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AA+CA,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,EAAE,OAAO,MAAM,KAAG,MAAM,EAiB1D,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EASnC,CAAC"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const CONFIG = (genre) => `# chaff.yaml — このチームの文章規範
|
|
4
|
+
#
|
|
5
|
+
# ここに書くのは「既定から変えたもの」だけです。書かなければ既定で動きます。
|
|
6
|
+
# このファイルを消しても chaff は動きます。
|
|
7
|
+
#
|
|
8
|
+
# 値は 4 つの言葉から選びます。数字を書く必要はありません。
|
|
9
|
+
#
|
|
10
|
+
# strict きびしく見る
|
|
11
|
+
# normal ふつう(既定)
|
|
12
|
+
# relaxed ゆるく見る
|
|
13
|
+
# off 見ない
|
|
14
|
+
#
|
|
15
|
+
# コマンドでも変更できます。理由がコメントとして自動で残ります。
|
|
16
|
+
#
|
|
17
|
+
# npx chaff relax bold-density --why "図の説明で太字を多用するため"
|
|
18
|
+
# npx chaff explain bold-density そのルールの意図を読む
|
|
19
|
+
# npx chaff rules --json AI に設定を書かせるときに渡す
|
|
20
|
+
|
|
21
|
+
# この場所に置く文書の種類。
|
|
22
|
+
genre: ${genre}
|
|
23
|
+
|
|
24
|
+
# 既定から変えたものだけを書く。
|
|
25
|
+
rules:
|
|
26
|
+
`;
|
|
27
|
+
const GITIGNORE_LINE = ".chaff-cache/";
|
|
28
|
+
const writeIfAbsent = (path, body, note) => {
|
|
29
|
+
if (existsSync(path))
|
|
30
|
+
return undefined;
|
|
31
|
+
writeFileSync(path, body, "utf8");
|
|
32
|
+
return { path, note };
|
|
33
|
+
};
|
|
34
|
+
/** judge のキャッシュは commit しない。init が .gitignore に足す。 */
|
|
35
|
+
const ensureGitignore = (dir) => {
|
|
36
|
+
const path = join(dir, ".gitignore");
|
|
37
|
+
if (!existsSync(path))
|
|
38
|
+
return writeIfAbsent(path, `${GITIGNORE_LINE}\n`, "作成しました");
|
|
39
|
+
if (readFileSync(path, "utf8").includes(GITIGNORE_LINE))
|
|
40
|
+
return undefined;
|
|
41
|
+
appendFileSync(path, `${GITIGNORE_LINE}\n`, "utf8");
|
|
42
|
+
return { path, note: `${GITIGNORE_LINE} を追記しました` };
|
|
43
|
+
};
|
|
44
|
+
export const runInit = (dir, genre) => {
|
|
45
|
+
const made = [writeIfAbsent(join(dir, "chaff.yaml"), CONFIG(genre), "規範の宣言。commit してください"), ensureGitignore(dir)].filter((entry) => entry !== undefined);
|
|
46
|
+
if (made.length === 0)
|
|
47
|
+
return ["chaff.yaml は既にあります。変更していません。"];
|
|
48
|
+
return [
|
|
49
|
+
"",
|
|
50
|
+
"作成しました:",
|
|
51
|
+
...made.map((entry) => ` ${entry.path} ${entry.note}`),
|
|
52
|
+
"",
|
|
53
|
+
`ジャンルは ${genre} にしました。違う場合は chaff.yaml の genre を直してください。`,
|
|
54
|
+
" 一覧: npx chaff genres",
|
|
55
|
+
"",
|
|
56
|
+
"次:",
|
|
57
|
+
" npx chaff . この場所の Markdown を全部見る",
|
|
58
|
+
"",
|
|
59
|
+
];
|
|
60
|
+
};
|
|
61
|
+
export const GENRES = [
|
|
62
|
+
"blog/tech",
|
|
63
|
+
"blog/essay",
|
|
64
|
+
"blog/owned-media",
|
|
65
|
+
"business/proposal",
|
|
66
|
+
"business/report",
|
|
67
|
+
"business/email",
|
|
68
|
+
"business/press-release",
|
|
69
|
+
"business/meeting-notes",
|
|
70
|
+
];
|
|
71
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,MAAM,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC;;;;;;;;;;;;;;;;;;;SAmBjC,KAAK;;;;CAIb,CAAC;AAEF,MAAM,cAAc,GAAG,eAAe,CAAC;AAIvC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,IAAY,EAAuB,EAAE;IACtF,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,sDAAsD;AACtD,MAAM,eAAe,GAAG,CAAC,GAAW,EAAuB,EAAE;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,aAAa,CAAC,IAAI,EAAE,GAAG,cAAc,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnF,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1E,cAAc,CAAC,IAAI,EAAE,GAAG,cAAc,IAAI,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,cAAc,UAAU,EAAE,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,KAAa,EAAY,EAAE;IAC9D,MAAM,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CACtH,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAC/B,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC/D,OAAO;QACL,EAAE;QACF,SAAS;QACT,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QACxD,EAAE;QACF,SAAS,KAAK,2CAA2C;QACzD,wBAAwB;QACxB,EAAE;QACF,IAAI;QACJ,+CAA+C;QAC/C,EAAE;KACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAsB;IACvC,WAAW;IACX,YAAY;IACZ,kBAAkB;IAClB,mBAAmB;IACnB,iBAAiB;IACjB,gBAAgB;IAChB,wBAAwB;IACxB,wBAAwB;CACzB,CAAC"}
|
package/dist/levels.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Level, RuleDefinition } from "./plugin.ts";
|
|
2
|
+
export declare const LEVELS: readonly Level[];
|
|
3
|
+
export declare const isLevel: (value: unknown) => value is Level;
|
|
4
|
+
export type Resolved = {
|
|
5
|
+
readonly level: Level;
|
|
6
|
+
readonly limit: number;
|
|
7
|
+
readonly fellBackToNormal: boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* 4 語を数値にする。spec §18.1。
|
|
11
|
+
*
|
|
12
|
+
* 意味のある段が 2 つしかない rule がある(padded-intro は strict と normal が同値)。
|
|
13
|
+
* そういう rule は levels に 2 つだけ書き、未定義の段は normal に落ちる。
|
|
14
|
+
* 落ちたことを呼ぶ側に伝えるのは、`chaff strict` が「変えたつもりで変わっていない」
|
|
15
|
+
* 状態を作らないようにするため。
|
|
16
|
+
*/
|
|
17
|
+
export declare const resolve: (rule: RuleDefinition, level: Level) => Resolved;
|
|
18
|
+
/** その rule が実際に区別できる段だけを返す。CLI の案内に使う。 */
|
|
19
|
+
export declare const definedLevels: (rule: RuleDefinition) => Level[];
|
|
20
|
+
//# sourceMappingURL=levels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"levels.d.ts","sourceRoot":"","sources":["../src/levels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEzD,eAAO,MAAM,MAAM,EAAE,SAAS,KAAK,EAA2C,CAAC;AAE/E,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,KAA6E,CAAC;AAEhI,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7G;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,cAAc,EAAE,OAAO,KAAK,KAAG,QAO5D,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,aAAa,GAAI,MAAM,cAAc,KAAG,KAAK,EAAmF,CAAC"}
|
package/dist/levels.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const LEVELS = ["strict", "normal", "relaxed", "off"];
|
|
2
|
+
export const isLevel = (value) => typeof value === "string" && LEVELS.some((level) => level === value);
|
|
3
|
+
/**
|
|
4
|
+
* 4 語を数値にする。spec §18.1。
|
|
5
|
+
*
|
|
6
|
+
* 意味のある段が 2 つしかない rule がある(padded-intro は strict と normal が同値)。
|
|
7
|
+
* そういう rule は levels に 2 つだけ書き、未定義の段は normal に落ちる。
|
|
8
|
+
* 落ちたことを呼ぶ側に伝えるのは、`chaff strict` が「変えたつもりで変わっていない」
|
|
9
|
+
* 状態を作らないようにするため。
|
|
10
|
+
*/
|
|
11
|
+
export const resolve = (rule, level) => {
|
|
12
|
+
if (level === "off")
|
|
13
|
+
return { level, limit: 0, fellBackToNormal: false };
|
|
14
|
+
const direct = rule.levels[level];
|
|
15
|
+
if (direct !== undefined)
|
|
16
|
+
return { level, limit: direct, fellBackToNormal: false };
|
|
17
|
+
const normal = rule.levels.normal;
|
|
18
|
+
if (normal === undefined)
|
|
19
|
+
throw new Error(`rule "${rule.id}" has no normal level`);
|
|
20
|
+
return { level: "normal", limit: normal, fellBackToNormal: true };
|
|
21
|
+
};
|
|
22
|
+
/** その rule が実際に区別できる段だけを返す。CLI の案内に使う。 */
|
|
23
|
+
export const definedLevels = (rule) => LEVELS.filter((level) => level === "off" || rule.levels[level] !== undefined);
|
|
24
|
+
//# sourceMappingURL=levels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"levels.js","sourceRoot":"","sources":["../src/levels.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAc,EAAkB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AAIhI;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAoB,EAAE,KAAY,EAAY,EAAE;IACtE,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;IACzE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;IACnF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAClC,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,uBAAuB,CAAC,CAAC;IACnF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;AACpE,CAAC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAoB,EAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC"}
|
package/dist/mask.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.d.ts","sourceRoot":"","sources":["../src/mask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAsBxC,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,OAAO,SAAS,IAAI,EAAE,KAAG,MAUlE,CAAC"}
|
package/dist/mask.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 非 prose(コードブロック・インラインコード・表・見出し・URL)を、
|
|
3
|
+
* **同じ長さの空白**で覆う。改行は残す。
|
|
4
|
+
*
|
|
5
|
+
* 切り出して繋ぐのではなく覆うのは、オフセットを元文字列と一致させ続けるため。
|
|
6
|
+
* 行・列の計算も、引用して見せる範囲も、これで元の位置のまま使える。
|
|
7
|
+
*/
|
|
8
|
+
const blankOut = (text) => text.replace(/[^\n]/gu, " ");
|
|
9
|
+
const merge = (spans) => [...spans]
|
|
10
|
+
.sort((left, right) => left.start - right.start)
|
|
11
|
+
.reduce((acc, span) => {
|
|
12
|
+
const last = acc.at(-1);
|
|
13
|
+
if (last !== undefined && span.start <= last.end) {
|
|
14
|
+
return [...acc.slice(0, -1), { start: last.start, end: Math.max(last.end, span.end) }];
|
|
15
|
+
}
|
|
16
|
+
return [...acc, span];
|
|
17
|
+
}, []);
|
|
18
|
+
export const maskSpans = (source, spans) => {
|
|
19
|
+
const merged = merge(spans);
|
|
20
|
+
const { parts, cursor } = merged.reduce((acc, span) => ({
|
|
21
|
+
parts: [...acc.parts, source.slice(acc.cursor, span.start), blankOut(source.slice(span.start, span.end))],
|
|
22
|
+
cursor: span.end,
|
|
23
|
+
}), { parts: [], cursor: 0 });
|
|
24
|
+
return [...parts, source.slice(cursor)].join("");
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=mask.js.map
|
package/dist/mask.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.js","sourceRoot":"","sources":["../src/mask.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAExE,MAAM,KAAK,GAAG,CAAC,KAAsB,EAAU,EAAE,CAC/C,CAAC,GAAG,KAAK,CAAC;KACP,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;KAC/C,MAAM,CAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC,EAAE,EAAE,CAAC,CAAC;AAEX,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,KAAsB,EAAU,EAAE;IAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CACrC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACzG,MAAM,EAAE,IAAI,CAAC,GAAG;KACjB,CAAC,EACF,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CACzB,CAAC;IACF,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export type Span = {
|
|
2
|
+
readonly start: number;
|
|
3
|
+
readonly end: number;
|
|
4
|
+
};
|
|
5
|
+
export type Sentence = {
|
|
6
|
+
readonly span: Span;
|
|
7
|
+
readonly text: string;
|
|
8
|
+
};
|
|
9
|
+
/** 品詞は Universal Dependencies の UPOS に統一する。アダプタ独自の体系を露出させない。 */
|
|
10
|
+
export type Token = {
|
|
11
|
+
readonly span: Span;
|
|
12
|
+
readonly surface: string;
|
|
13
|
+
readonly pos: string;
|
|
14
|
+
readonly lemma?: string;
|
|
15
|
+
};
|
|
16
|
+
export type Segmentation = {
|
|
17
|
+
readonly sentences: readonly Sentence[];
|
|
18
|
+
readonly words?: readonly Span[];
|
|
19
|
+
readonly tokens?: readonly Token[];
|
|
20
|
+
};
|
|
21
|
+
export type LengthUnit = "char" | "word";
|
|
22
|
+
/** L2 の語彙表。detector は共通で、これだけが言語別。spec §11。 */
|
|
23
|
+
export type LexiconEntry = {
|
|
24
|
+
readonly pattern: string;
|
|
25
|
+
readonly weight?: number | undefined;
|
|
26
|
+
};
|
|
27
|
+
export type Lexicon = readonly LexiconEntry[];
|
|
28
|
+
/**
|
|
29
|
+
* rule は required な capability を宣言し、満たされなければ skip される。
|
|
30
|
+
* 日本語の品詞解析が 18MB の辞書を要することを、この一枚で吸収する。spec §16。
|
|
31
|
+
*/
|
|
32
|
+
export type AdapterCapabilities = {
|
|
33
|
+
readonly sentenceSplit: true;
|
|
34
|
+
readonly wordSplit: boolean;
|
|
35
|
+
readonly pos: boolean;
|
|
36
|
+
readonly lemma: boolean;
|
|
37
|
+
readonly lengthUnit: LengthUnit;
|
|
38
|
+
};
|
|
39
|
+
export type LanguageAdapter = {
|
|
40
|
+
readonly kind: "language";
|
|
41
|
+
/** BCP 47 の primary subtag。"ja" / "en"。 */
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly apiVersion: 1;
|
|
44
|
+
readonly capabilities: AdapterCapabilities;
|
|
45
|
+
/** この言語である確からしさ。0..1。 */
|
|
46
|
+
readonly detect: (source: string) => number;
|
|
47
|
+
readonly segment: (text: string) => Segmentation;
|
|
48
|
+
/** L2 rule が word_list で引く。アダプタが自分の言語のぶんだけを持つ。 */
|
|
49
|
+
readonly lexicons: Readonly<Record<string, Lexicon>>;
|
|
50
|
+
};
|
|
51
|
+
export type Section = {
|
|
52
|
+
/** 見出しの深さ。見出しより前の導入部は 0。 */
|
|
53
|
+
readonly depth: number;
|
|
54
|
+
readonly heading: string;
|
|
55
|
+
readonly span: Span;
|
|
56
|
+
readonly sentences: readonly Sentence[];
|
|
57
|
+
/** この節に含まれる強調(Markdown の ** **)の数。 */
|
|
58
|
+
readonly strongCount: number;
|
|
59
|
+
/** 見出し直後の最初の文。heading-echo が見る。 */
|
|
60
|
+
readonly firstSentence: Sentence | undefined;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* detector に渡る唯一の入り口。core が I/O を済ませてから呼ぶ。
|
|
64
|
+
* detector は純関数で、fs / network / clock に触れない。spec §6。
|
|
65
|
+
*/
|
|
66
|
+
export type ProseDocument = {
|
|
67
|
+
readonly path: string;
|
|
68
|
+
readonly source: string;
|
|
69
|
+
readonly language: string;
|
|
70
|
+
readonly lengthUnit: LengthUnit;
|
|
71
|
+
readonly sections: readonly Section[];
|
|
72
|
+
readonly sentences: readonly Sentence[];
|
|
73
|
+
/** アダプタが持つ語彙表。detector は言語を知らずにこれを引く。 */
|
|
74
|
+
readonly lexicons: Readonly<Record<string, Lexicon>>;
|
|
75
|
+
};
|
|
76
|
+
export type Severity = "error" | "warning" | "info";
|
|
77
|
+
export type Finding = {
|
|
78
|
+
readonly rule: string;
|
|
79
|
+
readonly severity: Severity;
|
|
80
|
+
readonly line: number;
|
|
81
|
+
readonly column: number;
|
|
82
|
+
/** 引用して見せる範囲。非エンジニア向け出力が使う。 */
|
|
83
|
+
readonly quote: string;
|
|
84
|
+
/** message のプレースホルダに入れる値。 */
|
|
85
|
+
readonly values: Readonly<Record<string, string | number>>;
|
|
86
|
+
};
|
|
87
|
+
/** rule 定義が threshold を渡す。数値は 4 語から解決済み。 */
|
|
88
|
+
export type DetectorOptions = {
|
|
89
|
+
readonly limit: number;
|
|
90
|
+
/** L2 のみ。rule 定義の word_list から解決した語彙表。 */
|
|
91
|
+
readonly lexicon?: Lexicon | undefined;
|
|
92
|
+
/** 見る範囲。opening は冒頭 2 段落、closing は最後の節、whole は全体。 */
|
|
93
|
+
readonly where?: string | undefined;
|
|
94
|
+
};
|
|
95
|
+
export type Detector = (doc: ProseDocument, options: DetectorOptions) => Finding[];
|
|
96
|
+
export type Localized = Readonly<Record<string, string>>;
|
|
97
|
+
export type Level = "strict" | "normal" | "relaxed" | "off";
|
|
98
|
+
export type LevelTable = Readonly<Partial<Record<Exclude<Level, "off">, number>>>;
|
|
99
|
+
export type RuleDefinition = {
|
|
100
|
+
readonly id: string;
|
|
101
|
+
readonly layer: "L1" | "L2" | "L3" | "L4";
|
|
102
|
+
readonly status: "experimental" | "stable" | "deprecated";
|
|
103
|
+
readonly name: Localized;
|
|
104
|
+
readonly why: Localized;
|
|
105
|
+
readonly how_to_fix: Localized;
|
|
106
|
+
readonly message: Localized;
|
|
107
|
+
/** 4 語と数値の対応。2 つ以上。未定義の段は normal に落ちる。spec §18.1。
|
|
108
|
+
* 言語別の閾値を持つ rule(max-sentence-length)は、読み込み時に言語で平坦化済み。 */
|
|
109
|
+
readonly levels: LevelTable;
|
|
110
|
+
readonly how_to_find: string;
|
|
111
|
+
readonly word_list: string | undefined;
|
|
112
|
+
readonly where: string | undefined;
|
|
113
|
+
readonly use_for: readonly string[];
|
|
114
|
+
readonly severity: Severity;
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,qBAAqB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type Place = {
|
|
2
|
+
readonly line: number;
|
|
3
|
+
readonly column: number;
|
|
4
|
+
};
|
|
5
|
+
/** 行頭のオフセット表。1 文書につき 1 度だけ作る。 */
|
|
6
|
+
export declare const lineStarts: (source: string) => number[];
|
|
7
|
+
export declare const placeOf: (starts: readonly number[], offset: number) => Place;
|
|
8
|
+
//# sourceMappingURL=position.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,iCAAiC;AACjC,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,KAAG,MAAM,EAA0G,CAAC;AAE7J,eAAO,MAAM,OAAO,GAAI,QAAQ,SAAS,MAAM,EAAE,EAAE,QAAQ,MAAM,KAAG,KAGnE,CAAC"}
|
package/dist/position.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** 行頭のオフセット表。1 文書につき 1 度だけ作る。 */
|
|
2
|
+
export const lineStarts = (source) => [...source].reduce((acc, char, index) => (char === "\n" ? [...acc, index + 1] : acc), [0]);
|
|
3
|
+
export const placeOf = (starts, offset) => {
|
|
4
|
+
const index = starts.reduce((best, start, at) => (start <= offset ? at : best), 0);
|
|
5
|
+
return { line: index + 1, column: offset - (starts[index] ?? 0) + 1 };
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=position.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AAEA,iCAAiC;AACjC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAc,EAAY,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAW,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7J,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAyB,EAAE,MAAc,EAAS,EAAE;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,OAAO,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AACxE,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RuleDefinition } from "../plugin.ts";
|
|
2
|
+
import type { RunResult } from "../run.ts";
|
|
3
|
+
/** エンジニア向け。1 件 2 行。 */
|
|
4
|
+
export declare const renderCompact: (header: string, result: RunResult, rules: readonly RuleDefinition[], language: string) => string;
|
|
5
|
+
//# sourceMappingURL=compact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/render/compact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,uBAAuB;AACvB,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,QAAQ,SAAS,EAAE,OAAO,SAAS,cAAc,EAAE,EAAE,UAAU,MAAM,KAAG,MAYrH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { messageOf } from "./text.js";
|
|
2
|
+
/** エンジニア向け。1 件 2 行。 */
|
|
3
|
+
export const renderCompact = (header, result, rules, language) => {
|
|
4
|
+
const byId = new Map(rules.map((rule) => [rule.id, rule]));
|
|
5
|
+
const lines = result.findings.flatMap((finding) => {
|
|
6
|
+
const rule = byId.get(finding.rule);
|
|
7
|
+
if (rule === undefined)
|
|
8
|
+
return [];
|
|
9
|
+
const at = `${finding.line}:${finding.column}`.padEnd(8);
|
|
10
|
+
return [` ${at}${finding.severity.padEnd(8)}${messageOf(rule, finding, language)}`, ` ${" ".repeat(8)}${finding.rule}`];
|
|
11
|
+
});
|
|
12
|
+
const tail = [`${result.findings.length} findings`, result.skipped.length > 0 ? `${result.skipped.length} rules not run` : undefined].filter((part) => part !== undefined);
|
|
13
|
+
return ["", header, "", ...lines, "", tail.join(", "), ""].join("\n");
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=compact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compact.js","sourceRoot":"","sources":["../../src/render/compact.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,uBAAuB;AACvB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,MAAiB,EAAE,KAAgC,EAAE,QAAgB,EAAU,EAAE;IAC7H,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,CAAC;QAClC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,aAAa,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACpI,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAC1I,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAC7B,CAAC;IACF,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/render/explain.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQ1D,qCAAqC;AACrC,eAAO,MAAM,aAAa,GAAI,MAAM,cAAc,EAAE,SAAS,KAAK,EAAE,UAAU,MAAM,EAAE,MAAM,MAAM,KAAG,MAmBpG,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { definedLevels, resolve } from "../levels.js";
|
|
2
|
+
import { localized } from "./text.js";
|
|
3
|
+
const levelLine = (rule, level, current) => {
|
|
4
|
+
const mark = level === current ? "\u2192" : " ";
|
|
5
|
+
const name = level.padEnd(9);
|
|
6
|
+
return level === "off" ? ` ${mark} ${name}見ない` : ` ${mark} ${name}${resolve(rule, level).limit}`;
|
|
7
|
+
};
|
|
8
|
+
/** rule の意図と根拠を読む。指摘に納得できないときの入口。 */
|
|
9
|
+
export const renderExplain = (rule, current, language, unit) => {
|
|
10
|
+
const experimental = rule.status === "experimental" ? [" このルールはまだ試験中で、既定では動きません(--experimental で動きます)。"] : [];
|
|
11
|
+
return [
|
|
12
|
+
"",
|
|
13
|
+
` ${localized(rule.name, language)} (${rule.id})`,
|
|
14
|
+
"",
|
|
15
|
+
` ${localized(rule.why, language)}`,
|
|
16
|
+
"",
|
|
17
|
+
` 直しかた: ${localized(rule.how_to_fix, language)}`,
|
|
18
|
+
"",
|
|
19
|
+
` 設定できる値(単位: ${unit}):`,
|
|
20
|
+
...definedLevels(rule).map((level) => levelLine(rule, level, current)),
|
|
21
|
+
"",
|
|
22
|
+
` いまは ${current} です。`,
|
|
23
|
+
...experimental,
|
|
24
|
+
"",
|
|
25
|
+
` 変える: npx chaff relax ${rule.id} --why "理由"`,
|
|
26
|
+
"",
|
|
27
|
+
].join("\n");
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=explain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/render/explain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,MAAM,SAAS,GAAG,CAAC,IAAoB,EAAE,KAAY,EAAE,OAAc,EAAU,EAAE;IAC/E,MAAM,IAAI,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;AACrG,CAAC,CAAC;AAEF,qCAAqC;AACrC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAoB,EAAE,OAAc,EAAE,QAAgB,EAAE,IAAY,EAAU,EAAE;IAC5G,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/G,OAAO;QACL,EAAE;QACF,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,IAAI,CAAC,EAAE,GAAG;QACpD,EAAE;QACF,KAAK,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE;QACpC,EAAE;QACF,WAAW,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;QACjD,EAAE;QACF,gBAAgB,IAAI,IAAI;QACxB,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACtE,EAAE;QACF,SAAS,OAAO,MAAM;QACtB,GAAG,YAAY;QACf,EAAE;QACF,2BAA2B,IAAI,CAAC,EAAE,aAAa;QAC/C,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RuleDefinition } from "../plugin.ts";
|
|
2
|
+
import type { RunResult } from "../run.ts";
|
|
3
|
+
export declare const renderFriendly: (header: string, result: RunResult, rules: readonly RuleDefinition[], language: string) => string;
|
|
4
|
+
//# sourceMappingURL=friendly.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"friendly.d.ts","sourceRoot":"","sources":["../../src/render/friendly.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAoC3C,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,EAAE,QAAQ,SAAS,EAAE,OAAO,SAAS,cAAc,EAAE,EAAE,UAAU,MAAM,KAAG,MAwBtH,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { MARK, localized, messageOf } from "./text.js";
|
|
2
|
+
import { tally } from "./summary.js";
|
|
3
|
+
const RULE = 60;
|
|
4
|
+
const QUOTE_LIMIT = 120;
|
|
5
|
+
const indent = (text, pad) => text.split("\n").map((line) => `${pad}${line}`);
|
|
6
|
+
const quoteOf = (finding) => {
|
|
7
|
+
const text = finding.quote.replace(/\s+/gu, " ").trim();
|
|
8
|
+
if (text.length === 0)
|
|
9
|
+
return [];
|
|
10
|
+
return ["", ...indent(text.length > QUOTE_LIMIT ? `${text.slice(0, QUOTE_LIMIT)}…` : text, " ")];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 1 件につき 4 つを出す。どれが欠けても、書いた人は動けない。
|
|
14
|
+
* 引用 / 何が起きているか / なぜ問題か / どう直すか
|
|
15
|
+
* rule の id は「ゆるめる」コマンドの中にだけ出す。最初に読むのは name。
|
|
16
|
+
*/
|
|
17
|
+
const block = (finding, rule, language) => [
|
|
18
|
+
"",
|
|
19
|
+
`─── ${finding.line} 行目 ${"─".repeat(Math.max(0, RULE - String(finding.line).length - 8))}`,
|
|
20
|
+
...quoteOf(finding),
|
|
21
|
+
"",
|
|
22
|
+
` ${MARK[finding.severity] ?? "·"} ${localized(rule.name, language)}`,
|
|
23
|
+
"",
|
|
24
|
+
...indent(messageOf(rule, finding, language), " "),
|
|
25
|
+
...indent(localized(rule.why, language), " "),
|
|
26
|
+
"",
|
|
27
|
+
...indent(`→ ${localized(rule.how_to_fix, language)}`, " "),
|
|
28
|
+
"",
|
|
29
|
+
` このルールをゆるめる: npx chaff relax ${finding.rule}`,
|
|
30
|
+
"",
|
|
31
|
+
];
|
|
32
|
+
export const renderFriendly = (header, result, rules, language) => {
|
|
33
|
+
const byId = new Map(rules.map((rule) => [rule.id, rule]));
|
|
34
|
+
const blocks = result.findings.flatMap((finding) => {
|
|
35
|
+
const rule = byId.get(finding.rule);
|
|
36
|
+
return rule === undefined ? [] : block(finding, rule, language);
|
|
37
|
+
});
|
|
38
|
+
const notes = [
|
|
39
|
+
"",
|
|
40
|
+
"─".repeat(RULE),
|
|
41
|
+
"",
|
|
42
|
+
` ${tally(result.findings)} すべて機械による判定です`,
|
|
43
|
+
" (同じ文章なら何度実行しても同じ結果になります)",
|
|
44
|
+
"",
|
|
45
|
+
" 文章は書き換えていません。直すのは書いた人です。",
|
|
46
|
+
];
|
|
47
|
+
const forced = result.forcedExperimental.length > 0
|
|
48
|
+
? ["", ` 試験中の rule を ${result.forcedExperimental.length} 件、設定により有効にしています: ${result.forcedExperimental.join(", ")}`]
|
|
49
|
+
: [];
|
|
50
|
+
const skipped = result.skipped.length > 0
|
|
51
|
+
? ["", ` ${result.skipped.length} 件の rule は動いていません:`, ...result.skipped.map((entry) => ` ${entry.rule}(${entry.why})`)]
|
|
52
|
+
: [];
|
|
53
|
+
return ["", header, ...blocks, ...notes, ...forced, ...skipped, ""].join("\n");
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=friendly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"friendly.js","sourceRoot":"","sources":["../../src/render/friendly.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Config } from "../config/load.ts";
|
|
2
|
+
import type { Level, RuleDefinition } from "../plugin.ts";
|
|
3
|
+
/** AI に設定を書かせるときの入口。推測せずに書けるだけの情報を 1 つに入れる。spec §19.3。 */
|
|
4
|
+
export declare const rulesJson: (rules: readonly RuleDefinition[], config: Config, language: string, genre: string) => string;
|
|
5
|
+
export declare const levelsForCli: () => readonly Level[];
|
|
6
|
+
//# sourceMappingURL=rules-json.d.ts.map
|