@yegor256/dogent 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/package.json +1 -1
- package/src/rules/index.js +4 -0
- package/src/rules/punctuation.js +57 -0
- package/src/rules/token-count.js +44 -0
- package/src/violation.js +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ We respect [agent-sh/agnix](https://github.com/agent-sh/agnix)
|
|
|
23
23
|
Run it on any manifesto file, no installation required:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
npx @yegor256/dogent@0.
|
|
26
|
+
npx @yegor256/dogent@0.3.0 CLAUDE.md
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Lint several files at once:
|
|
@@ -62,7 +62,9 @@ The command exits with a non-zero status when problems are found,
|
|
|
62
62
|
- Instructions must be grouped in sections.
|
|
63
63
|
- Section names must be short, 1-3 words.
|
|
64
64
|
- Every line must be no longer than 80 symbols.
|
|
65
|
+
- The whole file must stay under 4000 tokens.
|
|
65
66
|
- Every line must sound like a command.
|
|
67
|
+
- Every sentence must start with a capital and end with a period.
|
|
66
68
|
- No articles, no noise, no bloated text.
|
|
67
69
|
- Simple grammar, no ambiguity.
|
|
68
70
|
- `SKILL.md` must open with valid frontmatter.
|
|
@@ -126,7 +128,7 @@ Reference `dogent` as a remote hook in `.pre-commit-config.yaml`:
|
|
|
126
128
|
```yaml
|
|
127
129
|
repos:
|
|
128
130
|
- repo: https://github.com/yegor256/dogent
|
|
129
|
-
rev: 0.
|
|
131
|
+
rev: 0.3.0
|
|
130
132
|
hooks:
|
|
131
133
|
- id: dogent
|
|
132
134
|
```
|
package/package.json
CHANGED
package/src/rules/index.js
CHANGED
|
@@ -6,18 +6,22 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const LineLength = require('./line-length');
|
|
9
|
+
const TokenCount = require('./token-count');
|
|
9
10
|
const ShortSections = require('./short-sections');
|
|
10
11
|
const Grouped = require('./grouped');
|
|
11
12
|
const NoArticles = require('./no-articles');
|
|
12
13
|
const Command = require('./command');
|
|
14
|
+
const Punctuation = require('./punctuation');
|
|
13
15
|
const Frontmatter = require('./frontmatter');
|
|
14
16
|
|
|
15
17
|
module.exports = () => [
|
|
16
18
|
new Grouped(),
|
|
17
19
|
new ShortSections(),
|
|
18
20
|
new LineLength(80),
|
|
21
|
+
new TokenCount(4000),
|
|
19
22
|
new NoArticles(),
|
|
20
23
|
new Command(),
|
|
24
|
+
new Punctuation(),
|
|
21
25
|
new Frontmatter(
|
|
22
26
|
'SKILL.md',
|
|
23
27
|
['name', 'description'],
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: Copyright (c) 2026 Yegor Bugayenko
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const Violation = require('../violation');
|
|
9
|
+
const Region = require('../region');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Punctuation.
|
|
13
|
+
*
|
|
14
|
+
* Demands that every instruction read as one whole sentence: opening
|
|
15
|
+
* with a capital letter and closing with a period. Headings, snippets,
|
|
16
|
+
* and frontmatter escape this rule.
|
|
17
|
+
*/
|
|
18
|
+
class Punctuation {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.id = 'punctuation';
|
|
21
|
+
}
|
|
22
|
+
violations(document) {
|
|
23
|
+
const uri = document.uri();
|
|
24
|
+
return document.walk({
|
|
25
|
+
header: () => [],
|
|
26
|
+
prose: (text, line) => this.judge(text, line, uri),
|
|
27
|
+
snippet: () => [],
|
|
28
|
+
bullets: () => [],
|
|
29
|
+
frontmatter: () => []
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
judge(text, line, uri) {
|
|
33
|
+
const [lead] = text.match(/^\s*(?:[-*+]|\d+\.)\s+/u) || text.match(/^\s*/u);
|
|
34
|
+
const sentence = text.slice(lead.length).replace(/\s+$/u, '');
|
|
35
|
+
const letter = sentence.match(/[A-Za-z]/u);
|
|
36
|
+
return [].concat(
|
|
37
|
+
sentence !== '' && letter !== null && letter[0] !== letter[0].toUpperCase()
|
|
38
|
+
? [new Violation(
|
|
39
|
+
this.id,
|
|
40
|
+
'error',
|
|
41
|
+
'sentence must start with a capital letter',
|
|
42
|
+
new Region(uri, line, lead.length + letter.index + 1)
|
|
43
|
+
)]
|
|
44
|
+
: [],
|
|
45
|
+
sentence !== '' && sentence.slice(-1) !== '.'
|
|
46
|
+
? [new Violation(
|
|
47
|
+
this.id,
|
|
48
|
+
'error',
|
|
49
|
+
'sentence must end with a period',
|
|
50
|
+
new Region(uri, line, lead.length + sentence.length)
|
|
51
|
+
)]
|
|
52
|
+
: []
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = Punctuation;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: Copyright (c) 2026 Yegor Bugayenko
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const Violation = require('../violation');
|
|
9
|
+
const Region = require('../region');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* TokenCount.
|
|
13
|
+
*
|
|
14
|
+
* Demands that a whole manifesto stay small enough to ride cheaply inside
|
|
15
|
+
* an agent context. Counts every word, number, and punctuation symbol
|
|
16
|
+
* across all fragments, frontmatter included, and complains once the sum
|
|
17
|
+
* reaches a cap.
|
|
18
|
+
*/
|
|
19
|
+
class TokenCount {
|
|
20
|
+
constructor(cap) {
|
|
21
|
+
this.id = 'token-count';
|
|
22
|
+
this.cap = cap;
|
|
23
|
+
}
|
|
24
|
+
violations(document) {
|
|
25
|
+
const count = (document.walk({
|
|
26
|
+
header: (text) => [text],
|
|
27
|
+
prose: (text) => [text],
|
|
28
|
+
snippet: (text) => [text],
|
|
29
|
+
bullets: () => [],
|
|
30
|
+
frontmatter: (pairs) => pairs.map((pair) => `${pair.key} ${pair.value}`)
|
|
31
|
+
}).join(' ').match(/[A-Za-z0-9]+|[^\sA-Za-z0-9]/gu) || []).length;
|
|
32
|
+
if (count < this.cap) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return [new Violation(
|
|
36
|
+
this.id,
|
|
37
|
+
'error',
|
|
38
|
+
`file exceeds ${this.cap} tokens, has ${count}`,
|
|
39
|
+
new Region(document.uri(), 1, 1)
|
|
40
|
+
)];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = TokenCount;
|