@nitra/cursor 5.0.1 → 5.0.3
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/.pi-template/extensions/n-cursor-adr/docs/index.md +31 -178
- package/CHANGELOG.md +12 -0
- package/lib/docs/models.md +32 -0
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +17 -8
- package/rules/abie/js/docs/applies.md +12 -14
- package/rules/abie/js/docs/firebase_hosting.md +18 -13
- package/rules/abie/lib/docs/enabled.md +20 -15
- package/rules/abie/lib/docs/env-dns.md +14 -22
- package/rules/abie/lib/docs/hc-yaml.md +14 -18
- package/rules/abie/lib/docs/http-route.md +10 -30
- package/skills/docgen/js/docgen-batch-omlx.mjs +82 -0
- package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +95 -0
- package/skills/docgen/js/docgen-extract-anchors.mjs +92 -0
- package/skills/docgen/js/docgen-gen.mjs +114 -12
- package/skills/docgen/js/docgen-prompts.mjs +92 -17
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
/** @see ./docs/docgen-prompts.md */
|
|
2
2
|
|
|
3
|
+
import { anchorsToPrompt } from './docgen-extract-anchors.mjs'
|
|
4
|
+
|
|
3
5
|
export const STYLE = [
|
|
4
6
|
'Ти технічний письменник. Пишеш лаконічну ПОВЕДІНКОВУ документацію до коду українською, чистим Markdown.',
|
|
5
7
|
'Пиши ЩО і НАВІЩО, не ЯК. Без вступів і висновків. Не обгортай у ```-блок.',
|
|
6
8
|
'Заборонено: сигнатури, типи, параметри функцій; перелік stdlib-модулів; опис regex чи внутрішніх приватних імен.'
|
|
7
9
|
].join(' ')
|
|
8
10
|
|
|
11
|
+
/** Окремий блок інструкцій з анкорами — підставляється коли вони є. */
|
|
12
|
+
function anchorsBlock(anchors) {
|
|
13
|
+
if (!anchors) return ''
|
|
14
|
+
const txt = anchorsToPrompt(anchors)
|
|
15
|
+
return txt ? `\n\n${txt}` : ''
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
/**
|
|
10
19
|
* Короткий людиночитний витяг фактів (без коду).
|
|
11
20
|
* @param {object} facts факт-лист про файл
|
|
@@ -38,8 +47,9 @@ const msgs = (system, user) => [
|
|
|
38
47
|
* @param {string} src вміст файлу
|
|
39
48
|
* @returns {Array<{key:string, messages:object[], numPredict:number}>} набір секційних промптів
|
|
40
49
|
*/
|
|
41
|
-
export function sectionMessages(facts, src) {
|
|
50
|
+
export function sectionMessages(facts, src, anchors = null) {
|
|
42
51
|
const factsTxt = factsSummary(facts)
|
|
52
|
+
const anch = anchorsBlock(anchors)
|
|
43
53
|
const multi = (facts.exports?.length || 0) > 1
|
|
44
54
|
const out = []
|
|
45
55
|
|
|
@@ -48,8 +58,8 @@ export function sectionMessages(facts, src) {
|
|
|
48
58
|
key: 'overview',
|
|
49
59
|
numPredict: 220,
|
|
50
60
|
messages: msgs(
|
|
51
|
-
`${STYLE}\n\nВІДОМІ ФАКТИ:\n${factsTxt}`,
|
|
52
|
-
'Напиши вміст секції «Огляд»: 1-3 речення — що файл робить і навіщо існує (роль у системі). Без заголовка, без переліку функцій.'
|
|
61
|
+
`${STYLE}\n\nВІДОМІ ФАКТИ:\n${factsTxt}${anch}`,
|
|
62
|
+
'Напиши вміст секції «Огляд»: 1-3 речення — що файл робить і навіщо існує (роль у системі). Без заголовка, без переліку функцій. Заборонені generic-фрази типу «забезпечує перевірку», «виконує валідацію» — пиши КОНКРЕТНО що саме і за яким контрактом.'
|
|
53
63
|
)
|
|
54
64
|
})
|
|
55
65
|
|
|
@@ -58,8 +68,8 @@ export function sectionMessages(facts, src) {
|
|
|
58
68
|
key: 'behavior',
|
|
59
69
|
numPredict: 500,
|
|
60
70
|
messages: msgs(
|
|
61
|
-
`${STYLE}\n\nФАЙЛ ${facts.relPath}:\n\`\`\`\n${src}\n\`\`\`\n\nВІДОМІ ФАКТИ:\n${factsTxt}`,
|
|
62
|
-
`Напиши вміст секції «Поведінка»: ${multi ? 'для кожної публічної функції — один короткий пункт «що вона робить»' : 'нумерований алгоритм у бізнес-термінах'}. Якщо у фактах є свідомі пропуски шляхів — згадай їх там, де доречно (не вигадуй інших «не перевіряє»). НЕ пиши аргументи функцій у дужках, без regex.${facts.internalSymbols?.length ? ` НЕ згадуй за іменами службові функції: ${facts.internalSymbols.join(', ')}.` : ''} Без
|
|
71
|
+
`${STYLE}\n\nФАЙЛ ${facts.relPath}:\n\`\`\`\n${src}\n\`\`\`\n\nВІДОМІ ФАКТИ:\n${factsTxt}${anch}`,
|
|
72
|
+
`Напиши вміст секції «Поведінка»: ${multi ? 'для кожної публічної функції — один короткий пункт «що вона робить»' : 'нумерований алгоритм у бізнес-термінах'}. Якщо у фактах є свідомі пропуски шляхів — згадай їх там, де доречно (не вигадуй інших «не перевіряє»). НЕ пиши аргументи функцій у дужках, без regex.${facts.internalSymbols?.length ? ` НЕ згадуй за іменами службові функції: ${facts.internalSymbols.join(', ')}.` : ''} Без заголовка, без додаткових ## чи # підзаголовків усередині секції.`
|
|
63
73
|
)
|
|
64
74
|
})
|
|
65
75
|
|
|
@@ -70,25 +80,90 @@ export function sectionMessages(facts, src) {
|
|
|
70
80
|
key: 'api',
|
|
71
81
|
numPredict: 320,
|
|
72
82
|
messages: msgs(
|
|
73
|
-
STYLE
|
|
74
|
-
`Перепиши цей список як стислі маркери «назва — що робить», СВОЇМИ словами (не копіюй дослівно), без типів і сигнатур. Використовуй РІВНО ці назви, не додавай і не прибирай:\n${list}\nБез
|
|
83
|
+
`${STYLE}${anch}`,
|
|
84
|
+
`Перепиши цей список як стислі маркери «назва — що робить», СВОЇМИ словами (не копіюй дослівно), без типів і сигнатур. Використовуй РІВНО ці назви, не додавай і не прибирай:\n${list}\nБез заголовка. Без generic-фраз «застосовує логіку», «перевіряє коректність» — пиши конкретно ЩО саме застосовує/перевіряє.`
|
|
75
85
|
)
|
|
76
86
|
})
|
|
77
87
|
}
|
|
78
88
|
|
|
79
|
-
// Гарантії — лише markers (без коду)
|
|
80
|
-
out.push({
|
|
81
|
-
key: 'guarantees',
|
|
82
|
-
numPredict: 300,
|
|
83
|
-
messages: msgs(
|
|
84
|
-
`${STYLE}\n\nВІДОМІ ФАКТИ:\n${factsTxt}`,
|
|
85
|
-
'Напиши вміст секції «Гарантії поведінки» як маркери-інваріанти СУВОРО на основі ВІДОМИХ ФАКТІВ (read-only, fail-safe, пропуски). Згадуй кеш ЛИШЕ якщо у фактах прямо є «Кешує». Без сигнатур у дужках і без імен внутрішніх структур/Map-ів/кешів. Не вигадуй гарантій, яких немає у фактах. Без заголовка.'
|
|
86
|
-
)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
89
|
return out
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* E2-step 1 — критик. Перевіряє чорнетку секції на конкретні дефекти.
|
|
94
|
+
* Повертає messages для LLM-запиту: вихід має бути СПИСКОМ issues або словом NONE.
|
|
95
|
+
* @param {'overview'|'behavior'|'api'} sectionKey
|
|
96
|
+
* @param {string} draft вже згенерована чорнетка секції
|
|
97
|
+
* @param {object} facts факт-лист
|
|
98
|
+
* @param {ReturnType<import('./docgen-extract-anchors.mjs').extractAnchors>} anchors
|
|
99
|
+
* @returns {Array<{role:string,content:string}>}
|
|
100
|
+
*/
|
|
101
|
+
export function criticMessages(sectionKey, draft, facts, anchors) {
|
|
102
|
+
const anch = anchorsBlock(anchors)
|
|
103
|
+
const criteria = [
|
|
104
|
+
'generic-фрази без конкретики («забезпечує перевірку», «виконує валідацію», «застосовує логіку»)',
|
|
105
|
+
'пропущені обов\'язкові АНКОРИ з контексту (URLs, magic-string constants, error-маркери, конфіги, code-приклади)',
|
|
106
|
+
'граматичні помилки українською («перед їх застосування», «моделіне», англіцизми як «applys», «moduleline»)',
|
|
107
|
+
'h1/h2/h3 підзаголовки всередині секції — їх не повинно бути',
|
|
108
|
+
'дослівна копія JSDoc-сигнатури або параметрів у дужках',
|
|
109
|
+
'вигадані факти, відсутні у ВІДОМИХ ФАКТАХ і АНКОРАХ'
|
|
110
|
+
].join('\n - ')
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
role: 'system',
|
|
114
|
+
content: `Ти жорсткий редактор технічної документації українською. Знаходиш конкретні дефекти у чорнетці. ВІДОМІ ФАКТИ:\n${factsSummary(facts)}${anch}`
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
role: 'user',
|
|
118
|
+
content: `Перевір цю чорнетку секції «${sectionKey}» за критеріями:\n - ${criteria}\n\nЧЕРНЕТКА:\n${draft}\n\nВідповідь — короткий нумерований список знайдених issues (1-5 пунктів). Якщо дефектів немає — поверни одне слово: NONE.`
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* E2-step 2 — refine. Переписує чорнетку, виправляючи перелічені issues.
|
|
125
|
+
* @param {'overview'|'behavior'|'api'} sectionKey
|
|
126
|
+
* @param {string} draft
|
|
127
|
+
* @param {string} issues список issues від critic
|
|
128
|
+
* @param {object} facts
|
|
129
|
+
* @param {ReturnType<import('./docgen-extract-anchors.mjs').extractAnchors>} anchors
|
|
130
|
+
* @returns {Array<{role:string,content:string}>}
|
|
131
|
+
*/
|
|
132
|
+
export function refineMessages(sectionKey, draft, issues, facts, anchors) {
|
|
133
|
+
const anch = anchorsBlock(anchors)
|
|
134
|
+
return [
|
|
135
|
+
{
|
|
136
|
+
role: 'system',
|
|
137
|
+
content: `${STYLE}\n\nВІДОМІ ФАКТИ:\n${factsSummary(facts)}${anch}`
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
role: 'user',
|
|
141
|
+
content: `Перепиши чорнетку секції «${sectionKey}», прибравши перелічені issues. Збережи мову (українська) і формат (без додаткових ## підзаголовків, без обгортки \`\`\`). Якщо issues вимагають включення АНКОРІВ — додай їх дослівно.\n\nЧЕРНЕТКА:\n${draft}\n\nISSUES ВІД РЕДАКТОРА:\n${issues}\n\nПоверни ЛИШЕ оновлений текст секції без преамбули.`
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* E3 — детермінований шаблон секції «Гарантії поведінки» з facts.markers.
|
|
148
|
+
* НЕ використовує LLM: 0 запитів, 0 галюцинацій, 0 generic-фраз.
|
|
149
|
+
* @param {object} facts
|
|
150
|
+
* @returns {string} текст секції (без `## Гарантії` — це додає assemble())
|
|
151
|
+
*/
|
|
152
|
+
export function guaranteesFromMarkers(facts) {
|
|
153
|
+
const m = facts.markers || {}
|
|
154
|
+
const lines = []
|
|
155
|
+
if (m.readOnly) lines.push('- Read-only: файл не виконує операцій запису у файлову систему.')
|
|
156
|
+
if (m.catchesErrors) lines.push('- Перехоплює помилки і не пропускає винятків назовні (fail-safe).')
|
|
157
|
+
if (m.returnsFalsyOnFail) lines.push('- За невдалої перевірки повертає `false`/`null` замість винятку.')
|
|
158
|
+
if (m.caches) lines.push('- Кешує результати в межах одного прогону.')
|
|
159
|
+
if (m.skips?.length) {
|
|
160
|
+
lines.push(`- Свідомо пропускає шляхи: ${m.skips.map(s => '`' + s + '`').join(', ')}.`)
|
|
161
|
+
}
|
|
162
|
+
if (!m.network) lines.push('- Не звертається до мережі.')
|
|
163
|
+
if (!lines.length) return '- Поведінка детермінована: результат залежить лише від вхідних даних.'
|
|
164
|
+
return lines.join('\n')
|
|
165
|
+
}
|
|
166
|
+
|
|
92
167
|
/**
|
|
93
168
|
* One-shot messages (база для порівняння).
|
|
94
169
|
* @param {object} facts факт-лист про файл
|