asciidoclint 0.5.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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +258 -0
  3. package/assets/README.md +12 -0
  4. package/assets/icon.svg +198 -0
  5. package/assets/logo.svg +203 -0
  6. package/dist/api/fixes.d.ts +6 -0
  7. package/dist/api/fixes.js +61 -0
  8. package/dist/api/lint.d.ts +2 -0
  9. package/dist/api/lint.js +191 -0
  10. package/dist/api/rules.d.ts +33 -0
  11. package/dist/api/rules.js +115 -0
  12. package/dist/cli/index.d.ts +2 -0
  13. package/dist/cli/index.js +86 -0
  14. package/dist/cli/init-rule.d.ts +7 -0
  15. package/dist/cli/init-rule.js +74 -0
  16. package/dist/cli/install-skill.d.ts +10 -0
  17. package/dist/cli/install-skill.js +37 -0
  18. package/dist/formatters/json.d.ts +2 -0
  19. package/dist/formatters/json.js +30 -0
  20. package/dist/formatters/pretty.d.ts +2 -0
  21. package/dist/formatters/pretty.js +41 -0
  22. package/dist/index.d.ts +4 -0
  23. package/dist/index.js +3 -0
  24. package/dist/parsers/asciidoctor.d.ts +4 -0
  25. package/dist/parsers/asciidoctor.js +444 -0
  26. package/dist/parsers/tolerant.d.ts +4 -0
  27. package/dist/parsers/tolerant.js +528 -0
  28. package/dist/rules/AD001.d.ts +2 -0
  29. package/dist/rules/AD001.js +28 -0
  30. package/dist/rules/AD002.d.ts +2 -0
  31. package/dist/rules/AD002.js +30 -0
  32. package/dist/rules/AD003.d.ts +2 -0
  33. package/dist/rules/AD003.js +28 -0
  34. package/dist/rules/AD004.d.ts +2 -0
  35. package/dist/rules/AD004.js +58 -0
  36. package/dist/rules/AD005.d.ts +2 -0
  37. package/dist/rules/AD005.js +31 -0
  38. package/dist/rules/AD006.d.ts +2 -0
  39. package/dist/rules/AD006.js +53 -0
  40. package/dist/rules/AD007.d.ts +2 -0
  41. package/dist/rules/AD007.js +39 -0
  42. package/dist/rules/AD008.d.ts +2 -0
  43. package/dist/rules/AD008.js +88 -0
  44. package/dist/rules/AD010.d.ts +2 -0
  45. package/dist/rules/AD010.js +39 -0
  46. package/dist/rules/AD011.d.ts +2 -0
  47. package/dist/rules/AD011.js +31 -0
  48. package/dist/rules/AD012.d.ts +2 -0
  49. package/dist/rules/AD012.js +28 -0
  50. package/dist/rules/AD013.d.ts +2 -0
  51. package/dist/rules/AD013.js +43 -0
  52. package/dist/rules/AD016.d.ts +2 -0
  53. package/dist/rules/AD016.js +83 -0
  54. package/dist/rules/AD017.d.ts +2 -0
  55. package/dist/rules/AD017.js +53 -0
  56. package/dist/rules/AD019.d.ts +2 -0
  57. package/dist/rules/AD019.js +58 -0
  58. package/dist/rules/AD020.d.ts +2 -0
  59. package/dist/rules/AD020.js +40 -0
  60. package/dist/rules/AD022.d.ts +2 -0
  61. package/dist/rules/AD022.js +55 -0
  62. package/dist/rules/AD023.d.ts +2 -0
  63. package/dist/rules/AD023.js +59 -0
  64. package/dist/rules/AD024.d.ts +2 -0
  65. package/dist/rules/AD024.js +30 -0
  66. package/dist/rules/AD025.d.ts +2 -0
  67. package/dist/rules/AD025.js +32 -0
  68. package/dist/rules/AD026.d.ts +2 -0
  69. package/dist/rules/AD026.js +26 -0
  70. package/dist/rules/AD027.d.ts +2 -0
  71. package/dist/rules/AD027.js +31 -0
  72. package/dist/rules/AD028.d.ts +2 -0
  73. package/dist/rules/AD028.js +113 -0
  74. package/dist/rules/AD029.d.ts +2 -0
  75. package/dist/rules/AD029.js +46 -0
  76. package/dist/rules/AD030.d.ts +2 -0
  77. package/dist/rules/AD030.js +33 -0
  78. package/dist/rules/AD031.d.ts +2 -0
  79. package/dist/rules/AD031.js +66 -0
  80. package/dist/rules/AD032.d.ts +2 -0
  81. package/dist/rules/AD032.js +81 -0
  82. package/dist/rules/AD034.d.ts +2 -0
  83. package/dist/rules/AD034.js +50 -0
  84. package/dist/rules/AD035.d.ts +2 -0
  85. package/dist/rules/AD035.js +77 -0
  86. package/dist/rules/AD036.d.ts +2 -0
  87. package/dist/rules/AD036.js +34 -0
  88. package/dist/rules/AD037.d.ts +2 -0
  89. package/dist/rules/AD037.js +34 -0
  90. package/dist/rules/AD039.d.ts +2 -0
  91. package/dist/rules/AD039.js +58 -0
  92. package/dist/rules/AD040.d.ts +2 -0
  93. package/dist/rules/AD040.js +56 -0
  94. package/dist/rules/AD041.d.ts +2 -0
  95. package/dist/rules/AD041.js +66 -0
  96. package/dist/rules/AD042.d.ts +2 -0
  97. package/dist/rules/AD042.js +62 -0
  98. package/dist/rules/AD043.d.ts +2 -0
  99. package/dist/rules/AD043.js +30 -0
  100. package/dist/rules/AD044.d.ts +2 -0
  101. package/dist/rules/AD044.js +54 -0
  102. package/dist/rules/AD045.d.ts +2 -0
  103. package/dist/rules/AD045.js +66 -0
  104. package/dist/rules/builtin.d.ts +3 -0
  105. package/dist/rules/builtin.js +81 -0
  106. package/dist/rules/helpers.d.ts +2 -0
  107. package/dist/rules/helpers.js +11 -0
  108. package/dist/rules/registry.d.ts +3 -0
  109. package/dist/rules/registry.js +34 -0
  110. package/dist/rules/utils.d.ts +42 -0
  111. package/dist/rules/utils.js +274 -0
  112. package/dist/types.d.ts +166 -0
  113. package/dist/types.js +1 -0
  114. package/dist/version.d.ts +2 -0
  115. package/dist/version.js +4 -0
  116. package/package.json +70 -0
  117. package/skills/asciidoclint/SKILL.md +84 -0
  118. package/skills/asciidoclint/references/ai-fix-policy.md +11 -0
  119. package/skills/asciidoclint/references/result-schema.md +22 -0
@@ -0,0 +1,166 @@
1
+ export type Severity = "error" | "warning" | "info";
2
+ export type ParserKind = "text" | "document" | "dependency" | "project";
3
+ export type Fixability = "safe" | "unsafe" | "no";
4
+ export type FixApplicability = Exclude<Fixability, "no">;
5
+ export interface SourcePosition {
6
+ file: string;
7
+ line: number;
8
+ column: number;
9
+ }
10
+ export interface SourceRange {
11
+ start: SourcePosition;
12
+ end?: SourcePosition;
13
+ }
14
+ export interface TextEdit {
15
+ file: string;
16
+ range: SourceRange;
17
+ replacement: string;
18
+ }
19
+ export interface Fix {
20
+ applicability: FixApplicability;
21
+ edits: TextEdit[];
22
+ }
23
+ export interface LintFinding {
24
+ ruleId: string;
25
+ alias?: string;
26
+ severity: Severity;
27
+ message: string;
28
+ range: SourceRange;
29
+ detail?: string;
30
+ context?: string;
31
+ fixHelper?: string;
32
+ fix?: Fix;
33
+ }
34
+ export interface RuleExample {
35
+ title?: string;
36
+ code: string;
37
+ }
38
+ export interface RuleDocs {
39
+ summary: string;
40
+ url?: URL;
41
+ rationale?: string;
42
+ badExamples?: RuleExample[];
43
+ goodExamples?: RuleExample[];
44
+ fixability?: Fixability;
45
+ /** Default repair guidance for all findings from this rule. */
46
+ fixHelper?: string;
47
+ }
48
+ export interface Rule {
49
+ id: string;
50
+ alias?: string;
51
+ description: string;
52
+ tags: string[];
53
+ docs?: RuleDocs;
54
+ parser: ParserKind;
55
+ configSchema?: unknown;
56
+ asynchronous?: boolean;
57
+ function: (params: RuleParams, onError: ReportFinding) => void | Promise<void>;
58
+ }
59
+ export type ReportFinding = (finding: Omit<LintFinding, "ruleId" | "alias"> & Partial<Pick<LintFinding, "ruleId" | "alias">>) => void;
60
+ export interface RuleParams {
61
+ file: string;
62
+ lines: string[];
63
+ document: NormalizedDocument;
64
+ dependencies: DependencyGraph;
65
+ parserDiagnostics: LintFinding[];
66
+ config: unknown;
67
+ version: string;
68
+ helpers: RuleHelpers;
69
+ }
70
+ export interface NormalizedDocument {
71
+ file: string;
72
+ lines: string[];
73
+ attributes: Record<string, string>;
74
+ sections: SectionNode[];
75
+ blocks: BlockNode[];
76
+ referenceTargets: ReferenceTarget[];
77
+ includes: IncludeRecord[];
78
+ dependencies: DependencyGraph;
79
+ diagnostics: LintFinding[];
80
+ sourceMap: SourceMapRecord[];
81
+ conditionals: ConditionalRecord[];
82
+ files: ParsedFile[];
83
+ }
84
+ export interface ReferenceTarget {
85
+ id: string;
86
+ file: string;
87
+ aliases?: string[];
88
+ source?: "asciidoctor" | "tolerant";
89
+ }
90
+ export interface ParsedFile {
91
+ file: string;
92
+ lines: string[];
93
+ }
94
+ export interface SectionNode {
95
+ kind: "section";
96
+ title: string;
97
+ level: number;
98
+ range: SourceRange;
99
+ titleRange: SourceRange;
100
+ parent?: SectionNode;
101
+ children: SectionNode[];
102
+ blocks: BlockNode[];
103
+ }
104
+ export interface BlockNode {
105
+ kind: "block";
106
+ type: BlockType;
107
+ style?: string;
108
+ title?: string;
109
+ attributes: Record<string, string | boolean>;
110
+ table?: TableInfo;
111
+ range: SourceRange;
112
+ contentRange?: SourceRange;
113
+ parentSection?: SectionNode;
114
+ }
115
+ export interface TableInfo {
116
+ columnCount?: number;
117
+ renderedCellCount?: number;
118
+ renderedCellSourceLines?: number[];
119
+ }
120
+ export type BlockType = "paragraph" | "listing" | "literal" | "source" | "example" | "sidebar" | "quote" | "table" | "image" | "admonition" | "passthrough" | "stem" | "diagram" | "comment" | "unknown";
121
+ export interface IncludeRecord {
122
+ target: string;
123
+ resolvedTarget?: string;
124
+ range: SourceRange;
125
+ status: "resolved" | "missing" | "skipped";
126
+ attributes: Record<string, string | boolean>;
127
+ }
128
+ export interface DependencyRecord {
129
+ type: "include" | "image" | "xref" | "attachment";
130
+ target: string;
131
+ resolvedTarget?: string;
132
+ range: SourceRange;
133
+ status: "resolved" | "missing" | "skipped";
134
+ }
135
+ export interface DependencyGraph {
136
+ records: DependencyRecord[];
137
+ }
138
+ export interface SourceMapRecord {
139
+ expandedLine: number;
140
+ source: SourcePosition;
141
+ }
142
+ export interface ConditionalRecord {
143
+ directive: "ifdef" | "ifndef";
144
+ attribute: string;
145
+ active: boolean;
146
+ range: SourceRange;
147
+ }
148
+ export interface RuleHelpers {
149
+ findSections: (document: NormalizedDocument) => SectionNode[];
150
+ findBlocks: (document: NormalizedDocument, type?: BlockType) => BlockNode[];
151
+ isSourceLikeBlock: (block: BlockNode) => boolean;
152
+ }
153
+ export interface LintOptions {
154
+ configFile?: string;
155
+ format?: "pretty" | "json";
156
+ customRules?: string[];
157
+ cwd?: string;
158
+ fix?: boolean;
159
+ unsafeFixes?: boolean;
160
+ parserDiagnostics?: boolean;
161
+ outputDiagnosticsFile?: string;
162
+ }
163
+ export interface LintResult {
164
+ files: string[];
165
+ findings: LintFinding[];
166
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare const VERSION = "0.5.0";
2
+ export declare function getVersion(): string;
@@ -0,0 +1,4 @@
1
+ export const VERSION = "0.5.0";
2
+ export function getVersion() {
3
+ return VERSION;
4
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "asciidoclint",
3
+ "version": "0.5.0",
4
+ "description": "AsciiDoc syntax, structure, and document-policy linter",
5
+ "author": "Shawn Hu",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/f33lgood/asciidoclint.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/f33lgood/asciidoclint/issues"
13
+ },
14
+ "homepage": "https://github.com/f33lgood/asciidoclint#readme",
15
+ "type": "module",
16
+ "files": [
17
+ "assets",
18
+ "dist",
19
+ "!dist/**/*.test.d.ts",
20
+ "!dist/**/*.test.js",
21
+ "!dist/compare",
22
+ "skills"
23
+ ],
24
+ "workspaces": [
25
+ "packages/*"
26
+ ],
27
+ "bin": {
28
+ "asciidoclint": "dist/cli/index.js"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js"
34
+ }
35
+ },
36
+ "scripts": {
37
+ "version:sync": "tsx scripts/sync-version.ts",
38
+ "version:check": "tsx scripts/sync-version.ts --check",
39
+ "build": "tsc -p tsconfig.json",
40
+ "build:extension": "npm run build && npm run build -w ./packages/vscode-asciidoclint",
41
+ "test": "vitest run src/api/*.test.ts src/cli/*.test.ts src/formatters/*.test.ts src/rules/*.test.ts",
42
+ "test:extension": "npm test -w ./packages/vscode-asciidoclint",
43
+ "test:coverage": "vitest run --coverage",
44
+ "lint:fixtures": "tsx src/cli/index.ts --format json \"test/fixtures/**/*.adoc\"",
45
+ "check": "npm run version:check && npm run build && npm test && npm run test:coverage && npm run build:extension && npm run test:extension",
46
+ "release:npm:dry-run": "npm run version:check && npm run build && npm pack --dry-run",
47
+ "release:npm:publish": "npm run version:check && npm run build && npm publish --access public",
48
+ "release:npm:publish:provenance": "npm run version:check && npm run build && npm publish --access public --provenance",
49
+ "release:vscode:package": "npm run version:check && npm run build:extension && npm run package -w ./packages/vscode-asciidoclint",
50
+ "release:vscode:publish": "npm run version:check && npm run build:extension && npm run publish:marketplace -w ./packages/vscode-asciidoclint",
51
+ "release:open-vsx:publish": "npm run release:vscode:package && npm run publish:open-vsx -w ./packages/vscode-asciidoclint"
52
+ },
53
+ "dependencies": {
54
+ "asciidoctor": "^3.0.4",
55
+ "commander": "^14.0.0",
56
+ "fast-glob": "^3.3.3",
57
+ "js-yaml": "^4.1.0"
58
+ },
59
+ "devDependencies": {
60
+ "@types/js-yaml": "^4.0.9",
61
+ "@types/node": "^24.0.0",
62
+ "@vitest/coverage-v8": "^3.2.4",
63
+ "tsx": "^4.19.4",
64
+ "typescript": "^5.8.3",
65
+ "vitest": "^3.1.4"
66
+ },
67
+ "engines": {
68
+ "node": ">=20"
69
+ }
70
+ }
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: asciidoclint
3
+ description: Use when linting, summarizing, or fixing AsciiDoc files with asciidoclint, including safe fixes, explicit unsafe fixes, diagnostics artifacts, and AI-assisted repairs based on asciidoclint findings.
4
+ ---
5
+
6
+ # asciidoclint
7
+
8
+ Use this skill for AsciiDoc linting and repair workflows. Prefer the workspace
9
+ `asciidoclint` install when present so project configuration and custom rules
10
+ match CI.
11
+
12
+ ## Tool Resolution
13
+
14
+ Use this order:
15
+
16
+ 1. `./node_modules/.bin/asciidoclint`
17
+ 2. `npx asciidoclint`
18
+ 3. `npx -y asciidoclint@latest`
19
+
20
+ Run from the repository or document workspace root unless the user names a
21
+ specific directory.
22
+
23
+ ## Check
24
+
25
+ For lint-only requests, run:
26
+
27
+ ```bash
28
+ npx asciidoclint --format json <targets>
29
+ ```
30
+
31
+ If no targets are provided, use the current workspace's AsciiDoc files or the
32
+ tool default. Summarize findings by severity, rule, file, and fixability. Report
33
+ safe and unsafe fix availability separately.
34
+
35
+ ## Safe Fixes
36
+
37
+ For safe-fix requests, run:
38
+
39
+ ```bash
40
+ npx asciidoclint --fix --format json <targets>
41
+ ```
42
+
43
+ Then rerun without `--fix` and summarize remaining findings. Safe fixes are
44
+ deterministic edits emitted by rules.
45
+
46
+ ## Unsafe Fixes
47
+
48
+ Only run unsafe fixes when the user explicitly asks for unsafe fixes:
49
+
50
+ ```bash
51
+ npx asciidoclint --fix --unsafe --format json <targets>
52
+ ```
53
+
54
+ Then rerun lint and summarize remaining findings. Unsafe fixes may alter
55
+ rendered structure, link semantics, or author intent.
56
+
57
+ ## Editor Diagnostics Artifact
58
+
59
+ When the user wants CLI results visible in VS Code or Cursor, write the
60
+ diagnostics artifact:
61
+
62
+ ```bash
63
+ npx asciidoclint --format json \
64
+ --output-diagnostics .asciidoclint/diagnostics.json \
65
+ <targets>
66
+ ```
67
+
68
+ The asciidoclint extension can import this artifact into editor diagnostics.
69
+
70
+ ## AI-Assisted Repairs
71
+
72
+ When the user asks for intelligent, AI, or LLM repair:
73
+
74
+ 1. Run lint with JSON output.
75
+ 2. Group findings by source file.
76
+ 3. Read only affected ranges plus nearby context.
77
+ 4. Use each finding's `ruleId`, `alias`, `message`, `detail`, `context`, and
78
+ `fixHelper` as the repair instruction.
79
+ 5. Apply focused edits.
80
+ 6. Rerun asciidoclint.
81
+ 7. Report fixed and remaining findings.
82
+
83
+ Do not invent broad prose/style rewrites unless the finding requires them. Keep
84
+ repairs scoped to the reported AsciiDoc issue.
@@ -0,0 +1,11 @@
1
+ # AI Repair Policy
2
+
3
+ Prefer deterministic fixes first:
4
+
5
+ 1. Safe automatic fixes.
6
+ 2. Explicit unsafe automatic fixes only when requested.
7
+ 3. AI-assisted edits for remaining findings.
8
+
9
+ For AI-assisted edits, treat `fixHelper` as the primary instruction. Preserve
10
+ document meaning unless the rule explicitly requires a semantic change. Rerun
11
+ `asciidoclint` after edits and report remaining findings.
@@ -0,0 +1,22 @@
1
+ # asciidoclint Result Schema
2
+
3
+ Use `--format json` for machine-readable output.
4
+
5
+ Top-level fields:
6
+
7
+ - `files`: absolute file paths linted by the engine.
8
+ - `findings`: ordered lint findings.
9
+
10
+ Finding fields:
11
+
12
+ - `ruleId`: stable rule ID such as `AD001`.
13
+ - `alias`: optional readable rule alias.
14
+ - `severity`: `error`, `warning`, or `info`.
15
+ - `message`: concise diagnostic message.
16
+ - `detail`: optional additional detail.
17
+ - `context`: optional source context.
18
+ - `fixHelper`: optional repair instruction for humans or AI agents.
19
+ - `range.start.file`, `range.start.line`, `range.start.column`: source
20
+ location.
21
+ - `fix.applicability`: `safe` or `unsafe` when an automatic edit exists.
22
+ - `fix.edits`: text edits emitted by deterministic rules.