resolver-cow 0.2.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 +71 -0
- package/assets/adapters/spec-box/instructions.md +44 -0
- package/assets/ci/Dockerfile +9 -0
- package/assets/ci/github-cow-run.yml +85 -0
- package/assets/ci/github-tests.yml +25 -0
- package/assets/project/architecture.md +29 -0
- package/assets/project/contracts.md +29 -0
- package/assets/project/conventions.md +29 -0
- package/assets/project/decisions.README.md +3 -0
- package/assets/project/glossary.md +13 -0
- package/assets/project/overview.md +29 -0
- package/assets/project/testing.md +33 -0
- package/assets/project/workflow.md +29 -0
- package/assets/roles/challenger.md +33 -0
- package/assets/roles/distiller.md +18 -0
- package/assets/roles/implementer.md +39 -0
- package/assets/roles/planner.md +57 -0
- package/assets/roles/researcher.md +40 -0
- package/assets/roles/reviewer.md +68 -0
- package/assets/roles/tester.md +36 -0
- package/assets/roles/verifier.md +56 -0
- package/assets/schema/cow-answer.schema.json +42 -0
- package/assets/schema/default.yaml +116 -0
- package/assets/templates/coverage.yaml +12 -0
- package/assets/templates/design.md +39 -0
- package/assets/templates/proposal.md +27 -0
- package/assets/templates/tasks.md +9 -0
- package/assets/templates/test-plan.md +7 -0
- package/bin/cow.js +5 -0
- package/dist/adapters/host/claude/index.js +94 -0
- package/dist/adapters/host/claude/index.js.map +1 -0
- package/dist/adapters/repo/git.js +81 -0
- package/dist/adapters/repo/git.js.map +1 -0
- package/dist/adapters/repo/github/index.js +136 -0
- package/dist/adapters/repo/github/index.js.map +1 -0
- package/dist/adapters/repo/index.js +4 -0
- package/dist/adapters/repo/index.js.map +1 -0
- package/dist/adapters/repo/local.js +47 -0
- package/dist/adapters/repo/local.js.map +1 -0
- package/dist/adapters/runner/claude.js +129 -0
- package/dist/adapters/runner/claude.js.map +1 -0
- package/dist/adapters/runner/codex.js +151 -0
- package/dist/adapters/runner/codex.js.map +1 -0
- package/dist/adapters/runner/index.js +4 -0
- package/dist/adapters/runner/index.js.map +1 -0
- package/dist/adapters/spec/index.js +3 -0
- package/dist/adapters/spec/index.js.map +1 -0
- package/dist/adapters/spec/spec-box/delta.js +198 -0
- package/dist/adapters/spec/spec-box/delta.js.map +1 -0
- package/dist/adapters/spec/spec-box/index.js +92 -0
- package/dist/adapters/spec/spec-box/index.js.map +1 -0
- package/dist/adapters/spec/spec-box/yaml.js +74 -0
- package/dist/adapters/spec/spec-box/yaml.js.map +1 -0
- package/dist/cli/commands/artifacts.js +86 -0
- package/dist/cli/commands/artifacts.js.map +1 -0
- package/dist/cli/commands/change.js +106 -0
- package/dist/cli/commands/change.js.map +1 -0
- package/dist/cli/commands/changeset.js +81 -0
- package/dist/cli/commands/changeset.js.map +1 -0
- package/dist/cli/commands/ci.js +45 -0
- package/dist/cli/commands/ci.js.map +1 -0
- package/dist/cli/commands/coverage.js +45 -0
- package/dist/cli/commands/coverage.js.map +1 -0
- package/dist/cli/commands/deliver.js +70 -0
- package/dist/cli/commands/deliver.js.map +1 -0
- package/dist/cli/commands/doctor.js +53 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/host.js +30 -0
- package/dist/cli/commands/host.js.map +1 -0
- package/dist/cli/commands/init.js +93 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/protocol.js +145 -0
- package/dist/cli/commands/protocol.js.map +1 -0
- package/dist/cli/commands/run.js +157 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/spec.js +84 -0
- package/dist/cli/commands/spec.js.map +1 -0
- package/dist/cli/context.js +18 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/main.js +57 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.js +31 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/core/archive.js +39 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/change.js +227 -0
- package/dist/core/change.js.map +1 -0
- package/dist/core/changeset.js +92 -0
- package/dist/core/changeset.js.map +1 -0
- package/dist/core/config.js +130 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/coverage.js +69 -0
- package/dist/core/coverage.js.map +1 -0
- package/dist/core/deliver.js +176 -0
- package/dist/core/deliver.js.map +1 -0
- package/dist/core/diagnostics.js +12 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/errors.js +12 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/gates.js +76 -0
- package/dist/core/gates.js.map +1 -0
- package/dist/core/lock.js +57 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/packet.js +162 -0
- package/dist/core/packet.js.map +1 -0
- package/dist/core/paths.js +63 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/phases.js +195 -0
- package/dist/core/phases.js.map +1 -0
- package/dist/core/pr-body.js +58 -0
- package/dist/core/pr-body.js.map +1 -0
- package/dist/core/project-docs.js +246 -0
- package/dist/core/project-docs.js.map +1 -0
- package/dist/core/protect.js +24 -0
- package/dist/core/protect.js.map +1 -0
- package/dist/core/repo-host.js +11 -0
- package/dist/core/repo-host.js.map +1 -0
- package/dist/core/report.js +262 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/result.js +90 -0
- package/dist/core/result.js.map +1 -0
- package/dist/core/roles.js +18 -0
- package/dist/core/roles.js.map +1 -0
- package/dist/core/run.js +221 -0
- package/dist/core/run.js.map +1 -0
- package/dist/core/runner.js +34 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/core/schema.js +104 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/spec-adapter.js +12 -0
- package/dist/core/spec-adapter.js.map +1 -0
- package/dist/core/spec-model.js +8 -0
- package/dist/core/spec-model.js.map +1 -0
- package/dist/core/tasks.js +15 -0
- package/dist/core/tasks.js.map +1 -0
- package/dist/core/test-reports.js +60 -0
- package/dist/core/test-reports.js.map +1 -0
- package/docs/design.md +821 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { enabledGates } from './config.js';
|
|
2
|
+
import { CowError } from './errors.js';
|
|
3
|
+
export const ROLES = ['researcher', 'planner', 'challenger', 'tester', 'implementer', 'reviewer', 'verifier', 'distiller'];
|
|
4
|
+
/** Порядок фаз (docs/design.md, раздел 4). intake выполняет CLI при создании изменения. */
|
|
5
|
+
export const PHASE_ORDER = [
|
|
6
|
+
'intake',
|
|
7
|
+
'research',
|
|
8
|
+
'propose',
|
|
9
|
+
'plan',
|
|
10
|
+
'cover',
|
|
11
|
+
'tests_review',
|
|
12
|
+
'implement',
|
|
13
|
+
'verify',
|
|
14
|
+
'review',
|
|
15
|
+
'deliver',
|
|
16
|
+
'archived',
|
|
17
|
+
];
|
|
18
|
+
export const ROLE_BY_PHASE = {
|
|
19
|
+
research: 'researcher',
|
|
20
|
+
propose: 'planner',
|
|
21
|
+
plan: 'planner',
|
|
22
|
+
cover: 'tester',
|
|
23
|
+
tests_review: 'reviewer',
|
|
24
|
+
implement: 'implementer',
|
|
25
|
+
review: 'reviewer',
|
|
26
|
+
verify: 'verifier',
|
|
27
|
+
};
|
|
28
|
+
/** Гейт стоит после фазы: пройдена фаза, ждём человека, потом следующая фаза. */
|
|
29
|
+
export const GATE_AFTER = {
|
|
30
|
+
propose: 'proposal',
|
|
31
|
+
plan: 'plan',
|
|
32
|
+
tests_review: 'tests',
|
|
33
|
+
};
|
|
34
|
+
export const PHASE_OF_GATE = {
|
|
35
|
+
proposal: 'propose',
|
|
36
|
+
plan: 'plan',
|
|
37
|
+
tests: 'tests_review',
|
|
38
|
+
};
|
|
39
|
+
/** Куда возвращает блокер каждой категории. */
|
|
40
|
+
export const RETURN_PHASE = {
|
|
41
|
+
артефакт: 'plan',
|
|
42
|
+
тесты: 'cover',
|
|
43
|
+
реализация: 'implement',
|
|
44
|
+
внешний: null,
|
|
45
|
+
пользователь: null,
|
|
46
|
+
};
|
|
47
|
+
export function nextPhase(phase) {
|
|
48
|
+
const i = PHASE_ORDER.indexOf(phase);
|
|
49
|
+
return i >= 0 && i + 1 < PHASE_ORDER.length ? PHASE_ORDER[i + 1] : null;
|
|
50
|
+
}
|
|
51
|
+
export function isRoleName(value) {
|
|
52
|
+
return ROLES.includes(value);
|
|
53
|
+
}
|
|
54
|
+
export function gateEnabled(change, config, gate) {
|
|
55
|
+
return enabledGates(config, change.autonomy).includes(gate);
|
|
56
|
+
}
|
|
57
|
+
/** Что делать дальше по состоянию изменения. Чистая функция, ничего не меняет. */
|
|
58
|
+
export function nextStep(change, config) {
|
|
59
|
+
switch (change.status) {
|
|
60
|
+
case 'waiting_approval': {
|
|
61
|
+
const pending = (Object.entries(change.gates).find(([, g]) => g.state === 'pending') ?? [])[0];
|
|
62
|
+
if (pending)
|
|
63
|
+
return { kind: 'gate', gate: pending, phase: PHASE_OF_GATE[pending] };
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'waiting_user':
|
|
67
|
+
case 'waiting_peer':
|
|
68
|
+
case 'parked':
|
|
69
|
+
case 'blocked':
|
|
70
|
+
case 'stopped':
|
|
71
|
+
case 'delivery_unknown':
|
|
72
|
+
case 'failed':
|
|
73
|
+
return { kind: 'wait', status: change.status, blocker: change.blocker };
|
|
74
|
+
case 'archived':
|
|
75
|
+
case 'done':
|
|
76
|
+
return { kind: 'done' };
|
|
77
|
+
case 'active':
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
const phase = change.phase === 'intake' ? 'research' : change.phase;
|
|
81
|
+
if (phase === 'deliver')
|
|
82
|
+
return { kind: 'deliver' };
|
|
83
|
+
if (phase === 'archived')
|
|
84
|
+
return { kind: 'done' };
|
|
85
|
+
const role = ROLE_BY_PHASE[phase];
|
|
86
|
+
if (!role)
|
|
87
|
+
throw new CowError('BAD_PHASE', `Для фазы ${phase} не задана роль`);
|
|
88
|
+
return { kind: 'role', role, phase };
|
|
89
|
+
}
|
|
90
|
+
/** Фаза завершена успешно: либо гейт, либо следующая фаза. Мутирует change. */
|
|
91
|
+
export function completePhase(change, config, phase) {
|
|
92
|
+
change.blocker = null;
|
|
93
|
+
const gate = GATE_AFTER[phase];
|
|
94
|
+
if (gate) {
|
|
95
|
+
const state = change.gates[gate];
|
|
96
|
+
if (gateEnabled(change, config, gate) && state?.state !== 'approved') {
|
|
97
|
+
change.gates[gate] = { state: 'pending' };
|
|
98
|
+
change.status = 'waiting_approval';
|
|
99
|
+
change.phase = phase;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!gateEnabled(change, config, gate) && state?.state !== 'approved') {
|
|
103
|
+
change.gates[gate] = { state: 'skipped', reason: 'autonomy' };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
advance(change, phase);
|
|
107
|
+
}
|
|
108
|
+
export function advance(change, from) {
|
|
109
|
+
const next = nextPhase(from);
|
|
110
|
+
if (!next) {
|
|
111
|
+
change.status = 'done';
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
change.phase = next;
|
|
115
|
+
change.status = next === 'archived' ? 'archived' : 'active';
|
|
116
|
+
}
|
|
117
|
+
export function approveGate(change, gate, by, comment, answers) {
|
|
118
|
+
const state = change.gates[gate];
|
|
119
|
+
if (!state || state.state !== 'pending') {
|
|
120
|
+
throw new CowError('GATE_NOT_PENDING', `Гейт ${gate} не ожидает решения (состояние: ${state?.state ?? 'нет'}).`);
|
|
121
|
+
}
|
|
122
|
+
change.gates[gate] = { state: 'approved', by, at: new Date().toISOString(), ...(comment ? { comment } : {}), ...(answers ? { answers } : {}) };
|
|
123
|
+
change.status = 'active';
|
|
124
|
+
advance(change, PHASE_OF_GATE[gate]);
|
|
125
|
+
}
|
|
126
|
+
export function rejectGate(change, gate, by, comment) {
|
|
127
|
+
const state = change.gates[gate];
|
|
128
|
+
if (!state || state.state !== 'pending') {
|
|
129
|
+
throw new CowError('GATE_NOT_PENDING', `Гейт ${gate} не ожидает решения (состояние: ${state?.state ?? 'нет'}).`);
|
|
130
|
+
}
|
|
131
|
+
change.gates[gate] = { state: 'rejected', by, at: new Date().toISOString(), comment };
|
|
132
|
+
change.status = 'active';
|
|
133
|
+
// Возврат на фазу, которая производит утверждаемый артефакт.
|
|
134
|
+
change.phase = gate === 'tests' ? 'cover' : PHASE_OF_GATE[gate];
|
|
135
|
+
change.blocker = { category: 'пользователь', message: comment, phase: change.phase };
|
|
136
|
+
}
|
|
137
|
+
/** Маршрутизация блокера. Возвращает фазу возврата или null, если запуск останавливается. */
|
|
138
|
+
export function routeBlocker(change, config, input) {
|
|
139
|
+
change.blocker = { category: input.category, message: input.message, role: input.role, phase: input.phase, ...(input.artifact ? { artifact: input.artifact } : {}) };
|
|
140
|
+
const target = RETURN_PHASE[input.category] ?? null;
|
|
141
|
+
if (input.category === 'пользователь') {
|
|
142
|
+
change.status = 'waiting_user';
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
if (!target) {
|
|
146
|
+
change.status = 'blocked';
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const limit = change.returns_limit ?? config.limits.returnsPerPhase;
|
|
150
|
+
const count = (change.returns[target] ?? 0) + 1;
|
|
151
|
+
change.returns[target] = count;
|
|
152
|
+
if (count > limit) {
|
|
153
|
+
change.status = 'parked';
|
|
154
|
+
change.blocker.message = `Лимит возвратов в фазу ${target} (${limit}) исчерпан. Последний блокер: ${input.message}`;
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
change.phase = target;
|
|
158
|
+
change.status = 'active';
|
|
159
|
+
return target;
|
|
160
|
+
}
|
|
161
|
+
export const RESUMABLE_STATUSES = new Set(['parked', 'blocked', 'failed', 'waiting_user', 'stopped', 'delivery_unknown']);
|
|
162
|
+
/**
|
|
163
|
+
* Явное продолжение человеком (docs/design.md, «Возвраты»): снимает parked/blocked,
|
|
164
|
+
* при необходимости поднимает бюджет возвратов и записывает ответ на блокер как фидбэк.
|
|
165
|
+
*/
|
|
166
|
+
export function resumeChange(change, config, opts = {}) {
|
|
167
|
+
if (!RESUMABLE_STATUSES.has(change.status)) {
|
|
168
|
+
throw new CowError('NOT_RESUMABLE', `Статус ${change.status} не требует продолжения.`);
|
|
169
|
+
}
|
|
170
|
+
const category = change.blocker?.category;
|
|
171
|
+
const target = category ? (RETURN_PHASE[category] ?? null) : null;
|
|
172
|
+
if (change.status === 'parked' && target) {
|
|
173
|
+
const used = change.returns[target] ?? 0;
|
|
174
|
+
const current = change.returns_limit ?? config.limits.returnsPerPhase;
|
|
175
|
+
if (opts.returns === undefined) {
|
|
176
|
+
throw new CowError('RETURNS_REQUIRED', `Бюджет возвратов в фазу ${target} исчерпан (${used} из ${current}).`, 'Укажите --returns N с числом больше использованного.');
|
|
177
|
+
}
|
|
178
|
+
if (opts.returns <= used)
|
|
179
|
+
throw new CowError('RETURNS_TOO_SMALL', `--returns ${opts.returns} не больше использованных ${used}.`);
|
|
180
|
+
change.returns_limit = opts.returns;
|
|
181
|
+
change.phase = target;
|
|
182
|
+
}
|
|
183
|
+
else if (opts.returns !== undefined) {
|
|
184
|
+
change.returns_limit = opts.returns;
|
|
185
|
+
}
|
|
186
|
+
if (change.status === 'delivery_unknown') {
|
|
187
|
+
change.phase = 'deliver';
|
|
188
|
+
}
|
|
189
|
+
if (change.blocker && opts.comment)
|
|
190
|
+
change.blocker.resolution = opts.comment;
|
|
191
|
+
change.stop_requested = false;
|
|
192
|
+
change.status = 'active';
|
|
193
|
+
return change.phase;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=phases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phases.js","sourceRoot":"","sources":["../../src/core/phases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { exists, readText } from './paths.js';
|
|
3
|
+
/**
|
|
4
|
+
* Текст пул-реквеста собирается только из delivery_narrative ревьюера, отчёта верификатора,
|
|
5
|
+
* сводки дельт и чеклиста готовности (docs/design.md, «Правила ревьюера»).
|
|
6
|
+
*/
|
|
7
|
+
export function renderPullRequestBody(input) {
|
|
8
|
+
const { change, narrative, deltas, dod } = input;
|
|
9
|
+
const lines = [];
|
|
10
|
+
lines.push(`## ${narrative.title}`, '');
|
|
11
|
+
lines.push(narrative.delta, '');
|
|
12
|
+
lines.push('### Почему это работает', '', narrative.why, '');
|
|
13
|
+
if (narrative.preserved)
|
|
14
|
+
lines.push('### Что сохранено', '', narrative.preserved, '');
|
|
15
|
+
if (narrative.rollout || narrative.rollback) {
|
|
16
|
+
lines.push('### Выкатка и откат', '');
|
|
17
|
+
if (narrative.rollout)
|
|
18
|
+
lines.push(`- Выкатка: ${narrative.rollout}`);
|
|
19
|
+
if (narrative.rollback)
|
|
20
|
+
lines.push(`- Откат: ${narrative.rollback}`);
|
|
21
|
+
lines.push('');
|
|
22
|
+
}
|
|
23
|
+
if (deltas.length > 0) {
|
|
24
|
+
lines.push('### Спецификации', '');
|
|
25
|
+
for (const d of deltas) {
|
|
26
|
+
const ops = d.ops.map((op) => (op.op === 'add-requirement' ? `+ ${op.requirement.title}` : op.op === 'modify-requirement' ? `~ ${op.requirement.title}` : op.op === 'remove-requirement' ? `- ${op.requirementTitle}` : `→ ${op.from} ⇒ ${op.to}`));
|
|
27
|
+
lines.push(`- \`${d.capabilityId}\`${d.isNew ? ' (новая)' : ''}: ${ops.join('; ')}`);
|
|
28
|
+
}
|
|
29
|
+
lines.push('');
|
|
30
|
+
}
|
|
31
|
+
if (change.verification) {
|
|
32
|
+
const v = change.verification;
|
|
33
|
+
const counts = { PASS: 0, FAIL: 0, PARTIAL: 0, NOT_RUN: 0 };
|
|
34
|
+
for (const c of v.checks)
|
|
35
|
+
counts[c.result] += 1;
|
|
36
|
+
lines.push('### Верификация', '', `Проверок: ${v.checks.length} (PASS ${counts.PASS}, PARTIAL ${counts.PARTIAL}, NOT_RUN ${counts.NOT_RUN}).`);
|
|
37
|
+
for (const c of v.checks)
|
|
38
|
+
lines.push(`- ${c.id} ${c.result}${c.purpose ? ` — ${c.purpose}` : ''}${c.evidence ? `: ${c.evidence}` : ''}`);
|
|
39
|
+
if (change.accepted_gaps.length > 0) {
|
|
40
|
+
lines.push('', 'Принятые пробелы (ручная или CI-проверка):');
|
|
41
|
+
for (const g of change.accepted_gaps) {
|
|
42
|
+
const gap = v.gaps.find((x) => x.id === g.item);
|
|
43
|
+
lines.push(`- ${g.item}${gap?.environment ? ` (${gap.environment})` : ''}${g.reason ? `: ${g.reason}` : ''}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
lines.push('');
|
|
47
|
+
}
|
|
48
|
+
const testPlan = path.join(input.dir, 'test-plan.md');
|
|
49
|
+
if (exists(testPlan)) {
|
|
50
|
+
lines.push('### План ручного тестирования', '', readText(testPlan).trim(), '');
|
|
51
|
+
}
|
|
52
|
+
lines.push('### Готовность к влитию', '');
|
|
53
|
+
for (const item of dod)
|
|
54
|
+
lines.push(`- [${item.ok ? 'x' : ' '}] ${item.id}. ${item.text}${item.detail ? ` (${item.detail})` : ''}`);
|
|
55
|
+
lines.push('', `<sub>cow: изменение \`${change.id}\`, change-set \`${change.changeset?.digest ?? '—'}\`</sub>`);
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=pr-body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-body.js","sourceRoot":"","sources":["../../src/core/pr-body.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS9C;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAMrC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,EAAE,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,IAAI,SAAS,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,EAAE,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACtF,IAAI,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,SAAS,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,IAAI,SAAS,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,iBAAiB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACpP,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;QAC9B,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;YAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,MAAM,UAAU,MAAM,CAAC,IAAI,aAAa,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QAC/I,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzI,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,4CAA4C,CAAC,CAAC;YAC7D,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;gBAChD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChH,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,+BAA+B,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,yBAAyB,MAAM,CAAC,EAAE,oBAAoB,MAAM,CAAC,SAAS,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC;IAChH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import YAML from 'yaml';
|
|
4
|
+
import { diag } from './diagnostics.js';
|
|
5
|
+
import { exists, readText, toPosix } from './paths.js';
|
|
6
|
+
export const DOC_CATEGORIES = [
|
|
7
|
+
{
|
|
8
|
+
id: 'product',
|
|
9
|
+
file: 'overview.md',
|
|
10
|
+
title: 'Продукт и границы',
|
|
11
|
+
questions: 'Что за продукт, кто пользователи, какие системы рядом, где живёт код, где истина спецификаций',
|
|
12
|
+
sections: ['Что за продукт', 'Пользователи', 'Системы рядом', 'Где живёт код', 'Истина спецификаций'],
|
|
13
|
+
readers: ['researcher', 'planner', 'challenger'],
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 'architecture',
|
|
18
|
+
file: 'architecture.md',
|
|
19
|
+
title: 'Архитектура и карта кода',
|
|
20
|
+
questions: 'Какие пакеты и модули есть, точки входа, поток данных, где что лежит, границы модулей, генерируемый код',
|
|
21
|
+
sections: ['Карта пакетов и модулей', 'Точки входа', 'Поток данных', 'Границы модулей', 'Генерируемый код'],
|
|
22
|
+
readers: ['researcher', 'planner', 'implementer', 'challenger'],
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'conventions',
|
|
27
|
+
file: 'conventions.md',
|
|
28
|
+
title: 'Соглашения по коду',
|
|
29
|
+
questions: 'Язык кода и комментариев, стиль, запрещённые конструкции, именование, правила коммитов',
|
|
30
|
+
sections: ['Язык', 'Стиль', 'Запрещено', 'Именование', 'Коммиты'],
|
|
31
|
+
readers: ['implementer', 'reviewer', 'tester'],
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'testing',
|
|
36
|
+
file: 'testing.md',
|
|
37
|
+
title: 'Тестирование и проверки',
|
|
38
|
+
questions: 'Уровни тестов, команды узкого и полного прогона, пути отчётов, правило именования тестов по сценариям, среда e2e, что нельзя автоматизировать',
|
|
39
|
+
sections: ['Уровни тестов', 'Команды', 'Отчёты', 'Именование тестов по сценариям', 'Среда e2e', 'Не автоматизируется'],
|
|
40
|
+
readers: ['tester', 'implementer', 'verifier', 'reviewer'],
|
|
41
|
+
required: true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'workflow',
|
|
45
|
+
file: 'workflow.md',
|
|
46
|
+
title: 'Рабочий процесс',
|
|
47
|
+
questions: 'Ветки, пул-реквесты, обязательные проверки CI, что запрещено без человека, разрешённые команды для агентов',
|
|
48
|
+
sections: ['Ветки', 'Пул-реквесты', 'Проверки CI', 'Запрещено без человека', 'Разрешённые команды'],
|
|
49
|
+
readers: ['implementer', 'tester', 'verifier'],
|
|
50
|
+
required: true,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'glossary',
|
|
54
|
+
file: 'glossary.md',
|
|
55
|
+
title: 'Словарь домена',
|
|
56
|
+
questions: 'Термины в формулировках, которыми пишутся спецификации и тесты',
|
|
57
|
+
sections: ['Термины'],
|
|
58
|
+
readers: ['researcher', 'planner', 'tester', 'implementer', 'reviewer', 'verifier', 'challenger'],
|
|
59
|
+
required: true,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 'contracts',
|
|
63
|
+
file: 'contracts.md',
|
|
64
|
+
title: 'Интеграции и контракты',
|
|
65
|
+
questions: 'Внешние API, события, схемы, кто потребитель, где лежат машиночитаемые контракты, репозитории-партнёры',
|
|
66
|
+
sections: ['Внешние API', 'События', 'Схемы', 'Потребители', 'Машиночитаемые контракты'],
|
|
67
|
+
readers: ['planner', 'tester', 'challenger'],
|
|
68
|
+
required: false,
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
export const DOC_FRONTMATTER_FIELDS = ['id', 'summary', 'read_when', 'updated', 'verification'];
|
|
72
|
+
const VERIFICATION_VALUES = new Set(['verified', 'needs-review']);
|
|
73
|
+
const PLACEHOLDER = /(\bTODO\b|\bTBD\b|\bFIXME\b|\{\{[^}]+\}\}|<заполн[^>]*>|<fill[^>]*>)/iu;
|
|
74
|
+
export function parseDoc(text) {
|
|
75
|
+
let frontmatter = {};
|
|
76
|
+
let body = text;
|
|
77
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
|
78
|
+
if (m) {
|
|
79
|
+
try {
|
|
80
|
+
frontmatter = YAML.parse(m[1]) ?? {};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
frontmatter = { __invalid: true };
|
|
84
|
+
}
|
|
85
|
+
body = text.slice(m[0].length);
|
|
86
|
+
}
|
|
87
|
+
const headings = [];
|
|
88
|
+
body.split(/\r?\n/).forEach((line, i) => {
|
|
89
|
+
const h = line.match(/^(#{1,6})\s+(.+?)\s*#*\s*$/);
|
|
90
|
+
if (h)
|
|
91
|
+
headings.push({ level: h[1].length, text: h[2].trim(), line: i + 1 });
|
|
92
|
+
});
|
|
93
|
+
return { frontmatter, body, headings };
|
|
94
|
+
}
|
|
95
|
+
export function docsDir(root, config) {
|
|
96
|
+
return path.join(root, config.project.docs);
|
|
97
|
+
}
|
|
98
|
+
export function docsForRole(role) {
|
|
99
|
+
return DOC_CATEGORIES.filter((c) => c.readers.includes(role));
|
|
100
|
+
}
|
|
101
|
+
const norm = (s) => s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, ' ').trim();
|
|
102
|
+
/** Структурный уровень `cow doctor`: наличие, фронтматтер, разделы, заглушки, ссылки на пути и команды, правила. */
|
|
103
|
+
export function doctorDocs(root, config) {
|
|
104
|
+
const out = [];
|
|
105
|
+
const dir = docsDir(root, config);
|
|
106
|
+
if (!exists(dir)) {
|
|
107
|
+
out.push(diag('error', 'DOCS_DIR_MISSING', `Нет каталога проектной документации ${toPosix(path.relative(root, dir))}`, undefined, 'Выполните `cow init`.'));
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
const scripts = readPackageScripts(root);
|
|
111
|
+
for (const category of DOC_CATEGORIES) {
|
|
112
|
+
const file = path.join(dir, category.file);
|
|
113
|
+
const target = toPosix(path.relative(root, file));
|
|
114
|
+
if (!exists(file)) {
|
|
115
|
+
if (category.required)
|
|
116
|
+
out.push(diag('error', 'DOC_MISSING', `Нет файла категории «${category.title}»`, target, `Создайте ${category.file} с разделами: ${category.sections.join(', ')}.`));
|
|
117
|
+
else
|
|
118
|
+
out.push(diag('info', 'DOC_OPTIONAL_MISSING', `Необязательная категория «${category.title}» не заполнена`, target));
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const text = readText(file);
|
|
122
|
+
const doc = parseDoc(text);
|
|
123
|
+
if (doc.frontmatter.__invalid)
|
|
124
|
+
out.push(diag('error', 'DOC_FRONTMATTER_INVALID', 'Фронтматтер не разбирается как YAML', target));
|
|
125
|
+
for (const field of DOC_FRONTMATTER_FIELDS) {
|
|
126
|
+
if (doc.frontmatter[field] === undefined || doc.frontmatter[field] === '') {
|
|
127
|
+
out.push(diag('error', 'DOC_FRONTMATTER_FIELD', `В фронтматтере нет поля ${field}`, target));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const verification = doc.frontmatter.verification;
|
|
131
|
+
if (typeof verification === 'string' && !VERIFICATION_VALUES.has(verification)) {
|
|
132
|
+
out.push(diag('error', 'DOC_VERIFICATION_VALUE', `verification должно быть verified или needs-review, а не «${verification}»`, target));
|
|
133
|
+
}
|
|
134
|
+
const h2 = doc.headings.filter((h) => h.level === 2).map((h) => norm(h.text));
|
|
135
|
+
for (const section of category.sections) {
|
|
136
|
+
if (!h2.includes(norm(section))) {
|
|
137
|
+
out.push(diag('error', 'DOC_SECTION_MISSING', `Нет раздела «## ${section}»`, target, `Категория «${category.title}» отвечает на: ${category.questions}.`));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
doc.body.split(/\r?\n/).forEach((line, i) => {
|
|
141
|
+
if (PLACEHOLDER.test(line)) {
|
|
142
|
+
out.push(diag('error', 'DOC_PLACEHOLDER', `Заглушка в строке ${i + 1}: ${line.trim().slice(0, 80)}`, target));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
if (wordCount(doc.body) < 40) {
|
|
146
|
+
out.push(diag('warning', 'DOC_TOO_SHORT', 'Содержимое короче 40 слов: категория вряд ли закрыта', target));
|
|
147
|
+
}
|
|
148
|
+
for (const ref of pathRefs(doc.body)) {
|
|
149
|
+
if (!exists(path.join(root, ref))) {
|
|
150
|
+
out.push(diag('warning', 'DOC_PATH_MISSING', `Упомянутый путь не найден в репозитории: ${ref}`, target));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (category.id === 'testing' && scripts) {
|
|
154
|
+
for (const cmd of scriptRefs(doc.body)) {
|
|
155
|
+
if (!(cmd in scripts))
|
|
156
|
+
out.push(diag('warning', 'DOC_SCRIPT_MISSING', `Скрипт «${cmd}» упомянут, но его нет в package.json`, target));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
out.push(...doctorDecisions(root, config));
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
function wordCount(text) {
|
|
164
|
+
return text.split(/\s+/).filter(Boolean).length;
|
|
165
|
+
}
|
|
166
|
+
/** Пути в обратных кавычках: содержат «/», без пробелов, не URL, не глоб. */
|
|
167
|
+
function pathRefs(body) {
|
|
168
|
+
const refs = new Set();
|
|
169
|
+
for (const m of body.matchAll(/`([^`\s]+)`/g)) {
|
|
170
|
+
const v = m[1];
|
|
171
|
+
if (!v.includes('/') || /^[a-z]+:\/\//i.test(v) || /[*?{}[\]]/.test(v) || v.startsWith('/') || v.startsWith('-'))
|
|
172
|
+
continue;
|
|
173
|
+
if (/^[A-Za-z0-9_.@-][A-Za-z0-9_./@-]*$/.test(v))
|
|
174
|
+
refs.add(v.replace(/\/$/, ''));
|
|
175
|
+
}
|
|
176
|
+
return [...refs];
|
|
177
|
+
}
|
|
178
|
+
/** Команды вида `pnpm test:unit`, `npm run lint`, `yarn e2e` → имя скрипта. */
|
|
179
|
+
function scriptRefs(body) {
|
|
180
|
+
const refs = new Set();
|
|
181
|
+
for (const m of body.matchAll(/`(?:pnpm|npm run|yarn)\s+([a-z][\w:-]*)`/g))
|
|
182
|
+
refs.add(m[1]);
|
|
183
|
+
return [...refs];
|
|
184
|
+
}
|
|
185
|
+
function readPackageScripts(root) {
|
|
186
|
+
const file = path.join(root, 'package.json');
|
|
187
|
+
if (!exists(file))
|
|
188
|
+
return null;
|
|
189
|
+
try {
|
|
190
|
+
return JSON.parse(readText(file)).scripts ?? {};
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export function decisionsDir(root, config) {
|
|
197
|
+
return path.join(docsDir(root, config), 'decisions');
|
|
198
|
+
}
|
|
199
|
+
export function loadDecisions(root, config) {
|
|
200
|
+
const dir = decisionsDir(root, config);
|
|
201
|
+
if (!exists(dir))
|
|
202
|
+
return [];
|
|
203
|
+
return fs
|
|
204
|
+
.readdirSync(dir)
|
|
205
|
+
.filter((f) => /^ADR-\d+.*\.md$/i.test(f))
|
|
206
|
+
.sort()
|
|
207
|
+
.map((f) => {
|
|
208
|
+
const doc = parseDoc(readText(path.join(dir, f)));
|
|
209
|
+
const fm = doc.frontmatter;
|
|
210
|
+
const ruleSection = doc.body.match(/##\s*Правило\s*\n([\s\S]*?)(?=\n##\s|$)/);
|
|
211
|
+
return {
|
|
212
|
+
id: String(fm.id ?? f),
|
|
213
|
+
title: String(fm.title ?? f),
|
|
214
|
+
status: fm.status ?? 'accepted',
|
|
215
|
+
scope: Array.isArray(fm.scope) ? fm.scope.map(String) : [],
|
|
216
|
+
rule: (ruleSection?.[1] ?? '').trim(),
|
|
217
|
+
file: toPosix(path.relative(root, path.join(dir, f))),
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
function doctorDecisions(root, config) {
|
|
222
|
+
const out = [];
|
|
223
|
+
const seen = new Set();
|
|
224
|
+
for (const d of loadDecisions(root, config)) {
|
|
225
|
+
if (!/^ADR-\d{4}$/.test(d.id))
|
|
226
|
+
out.push(diag('error', 'ADR_ID', `Идентификатор правила должен быть вида ADR-0001, а не «${d.id}»`, d.file));
|
|
227
|
+
if (seen.has(d.id))
|
|
228
|
+
out.push(diag('error', 'ADR_DUPLICATE', `Идентификатор ${d.id} повторяется`, d.file));
|
|
229
|
+
seen.add(d.id);
|
|
230
|
+
if (!['accepted', 'superseded'].includes(d.status))
|
|
231
|
+
out.push(diag('error', 'ADR_STATUS', `status должен быть accepted или superseded`, d.file));
|
|
232
|
+
if (!d.rule)
|
|
233
|
+
out.push(diag('error', 'ADR_RULE', 'Нет раздела «## Правило» с формулировкой', d.file));
|
|
234
|
+
if (d.scope.length === 0)
|
|
235
|
+
out.push(diag('warning', 'ADR_SCOPE', 'Не задана область действия scope', d.file));
|
|
236
|
+
}
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
239
|
+
/** Действующие правила, чья область пересекается с затронутыми путями (или все, если пути неизвестны). */
|
|
240
|
+
export function applicableDecisions(decisions, paths) {
|
|
241
|
+
const accepted = decisions.filter((d) => d.status === 'accepted');
|
|
242
|
+
if (!paths || paths.length === 0)
|
|
243
|
+
return accepted;
|
|
244
|
+
return accepted.filter((d) => d.scope.length === 0 || d.scope.some((s) => paths.some((p) => p.startsWith(s) || s.startsWith(p))));
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=project-docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-docs.js","sourceRoot":"","sources":["../../src/core/project-docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import picomatch from 'picomatch';
|
|
3
|
+
/** Изменённые файлы рабочей копии относительно HEAD (git). Пустой список, если git недоступен. */
|
|
4
|
+
export function changedFiles(root) {
|
|
5
|
+
try {
|
|
6
|
+
const out = execFileSync('git', ['status', '--porcelain', '--untracked-files=all'], { cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
7
|
+
return out
|
|
8
|
+
.split('\n')
|
|
9
|
+
.filter(Boolean)
|
|
10
|
+
.map((line) => line.slice(3).trim())
|
|
11
|
+
.map((p) => (p.includes(' -> ') ? p.split(' -> ')[1] : p));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Файлы, которые нарушают защиту: изменены и попадают под защищённые шаблоны. */
|
|
18
|
+
export function protectedViolations(changed, protectedGlobs) {
|
|
19
|
+
if (protectedGlobs.length === 0)
|
|
20
|
+
return [];
|
|
21
|
+
const isMatch = picomatch(protectedGlobs, { dot: true });
|
|
22
|
+
return changed.filter((f) => isMatch(f));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=protect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/core/protect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,kGAAkG;AAClG,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1J,OAAO,GAAG;aACP,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,mBAAmB,CAAC,OAAiB,EAAE,cAAwB;IAC7E,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const registry = new Map();
|
|
2
|
+
export function registerRepoHost(name, factory) {
|
|
3
|
+
registry.set(name, factory);
|
|
4
|
+
}
|
|
5
|
+
export function createRepoHost(root, config, name = config.repo.adapter) {
|
|
6
|
+
const factory = registry.get(name);
|
|
7
|
+
if (!factory)
|
|
8
|
+
throw new Error(`Адаптер репозитория "${name}" не зарегистрирован`);
|
|
9
|
+
return factory(root, config);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=repo-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-host.js","sourceRoot":"","sources":["../../src/core/repo-host.ts"],"names":[],"mappings":"AAwDA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,OAAwB;IACrE,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,MAAc,EAAE,IAAI,GAAW,MAAM,CAAC,IAAI,CAAC,OAAO;IAC7F,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,sBAAsB,CAAC,CAAC;IAClF,OAAO,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|