@spec-box/sdd 0.6.4

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 (161) hide show
  1. package/README.md +81 -0
  2. package/assets/adapters/openspec/instructions.md +47 -0
  3. package/assets/adapters/spec-box/instructions.md +44 -0
  4. package/assets/ci/Dockerfile +9 -0
  5. package/assets/ci/github-sbox-run.yml +85 -0
  6. package/assets/ci/github-tests.yml +25 -0
  7. package/assets/project/architecture.md +29 -0
  8. package/assets/project/contracts.md +29 -0
  9. package/assets/project/conventions.md +29 -0
  10. package/assets/project/decisions.README.md +3 -0
  11. package/assets/project/glossary.md +13 -0
  12. package/assets/project/overview.md +29 -0
  13. package/assets/project/testing.md +34 -0
  14. package/assets/project/workflow.md +29 -0
  15. package/assets/prompts/fill-project-docs.md +43 -0
  16. package/assets/roles/challenger.md +33 -0
  17. package/assets/roles/distiller.md +18 -0
  18. package/assets/roles/implementer.md +39 -0
  19. package/assets/roles/planner.md +58 -0
  20. package/assets/roles/researcher.md +47 -0
  21. package/assets/roles/reviewer.md +68 -0
  22. package/assets/roles/tester.md +36 -0
  23. package/assets/roles/verifier.md +57 -0
  24. package/assets/schema/default.yaml +121 -0
  25. package/assets/schema/sbox-answer.schema.json +42 -0
  26. package/assets/templates/coverage.yaml +12 -0
  27. package/assets/templates/design.md +48 -0
  28. package/assets/templates/proposal.md +27 -0
  29. package/assets/templates/tasks.md +9 -0
  30. package/assets/templates/test-plan.md +7 -0
  31. package/bin/sbox.js +5 -0
  32. package/dist/adapters/host/claude/index.js +112 -0
  33. package/dist/adapters/host/claude/index.js.map +1 -0
  34. package/dist/adapters/repo/git.js +81 -0
  35. package/dist/adapters/repo/git.js.map +1 -0
  36. package/dist/adapters/repo/github/index.js +136 -0
  37. package/dist/adapters/repo/github/index.js.map +1 -0
  38. package/dist/adapters/repo/index.js +4 -0
  39. package/dist/adapters/repo/index.js.map +1 -0
  40. package/dist/adapters/repo/local.js +47 -0
  41. package/dist/adapters/repo/local.js.map +1 -0
  42. package/dist/adapters/runner/claude.js +129 -0
  43. package/dist/adapters/runner/claude.js.map +1 -0
  44. package/dist/adapters/runner/codex.js +151 -0
  45. package/dist/adapters/runner/codex.js.map +1 -0
  46. package/dist/adapters/runner/index.js +4 -0
  47. package/dist/adapters/runner/index.js.map +1 -0
  48. package/dist/adapters/spec/index.js +4 -0
  49. package/dist/adapters/spec/index.js.map +1 -0
  50. package/dist/adapters/spec/openspec/delta.js +268 -0
  51. package/dist/adapters/spec/openspec/delta.js.map +1 -0
  52. package/dist/adapters/spec/openspec/index.js +107 -0
  53. package/dist/adapters/spec/openspec/index.js.map +1 -0
  54. package/dist/adapters/spec/openspec/parser.js +188 -0
  55. package/dist/adapters/spec/openspec/parser.js.map +1 -0
  56. package/dist/adapters/spec/spec-box/delta.js +198 -0
  57. package/dist/adapters/spec/spec-box/delta.js.map +1 -0
  58. package/dist/adapters/spec/spec-box/index.js +112 -0
  59. package/dist/adapters/spec/spec-box/index.js.map +1 -0
  60. package/dist/adapters/spec/spec-box/yaml.js +74 -0
  61. package/dist/adapters/spec/spec-box/yaml.js.map +1 -0
  62. package/dist/cli/commands/artifacts.js +86 -0
  63. package/dist/cli/commands/artifacts.js.map +1 -0
  64. package/dist/cli/commands/change.js +111 -0
  65. package/dist/cli/commands/change.js.map +1 -0
  66. package/dist/cli/commands/changeset.js +81 -0
  67. package/dist/cli/commands/changeset.js.map +1 -0
  68. package/dist/cli/commands/ci.js +45 -0
  69. package/dist/cli/commands/ci.js.map +1 -0
  70. package/dist/cli/commands/coverage.js +45 -0
  71. package/dist/cli/commands/coverage.js.map +1 -0
  72. package/dist/cli/commands/deliver.js +71 -0
  73. package/dist/cli/commands/deliver.js.map +1 -0
  74. package/dist/cli/commands/doctor.js +55 -0
  75. package/dist/cli/commands/doctor.js.map +1 -0
  76. package/dist/cli/commands/host.js +30 -0
  77. package/dist/cli/commands/host.js.map +1 -0
  78. package/dist/cli/commands/init.js +150 -0
  79. package/dist/cli/commands/init.js.map +1 -0
  80. package/dist/cli/commands/metrics.js +62 -0
  81. package/dist/cli/commands/metrics.js.map +1 -0
  82. package/dist/cli/commands/prompt.js +68 -0
  83. package/dist/cli/commands/prompt.js.map +1 -0
  84. package/dist/cli/commands/protocol.js +151 -0
  85. package/dist/cli/commands/protocol.js.map +1 -0
  86. package/dist/cli/commands/run.js +157 -0
  87. package/dist/cli/commands/run.js.map +1 -0
  88. package/dist/cli/commands/spec.js +84 -0
  89. package/dist/cli/commands/spec.js.map +1 -0
  90. package/dist/cli/commands/wiring.js +50 -0
  91. package/dist/cli/commands/wiring.js.map +1 -0
  92. package/dist/cli/context.js +18 -0
  93. package/dist/cli/context.js.map +1 -0
  94. package/dist/cli/main.js +63 -0
  95. package/dist/cli/main.js.map +1 -0
  96. package/dist/cli/output.js +31 -0
  97. package/dist/cli/output.js.map +1 -0
  98. package/dist/core/archive.js +77 -0
  99. package/dist/core/archive.js.map +1 -0
  100. package/dist/core/change.js +240 -0
  101. package/dist/core/change.js.map +1 -0
  102. package/dist/core/changeset.js +98 -0
  103. package/dist/core/changeset.js.map +1 -0
  104. package/dist/core/config.js +144 -0
  105. package/dist/core/config.js.map +1 -0
  106. package/dist/core/coverage.js +69 -0
  107. package/dist/core/coverage.js.map +1 -0
  108. package/dist/core/deliver.js +190 -0
  109. package/dist/core/deliver.js.map +1 -0
  110. package/dist/core/diagnostics.js +12 -0
  111. package/dist/core/diagnostics.js.map +1 -0
  112. package/dist/core/drift.js +44 -0
  113. package/dist/core/drift.js.map +1 -0
  114. package/dist/core/errors.js +12 -0
  115. package/dist/core/errors.js.map +1 -0
  116. package/dist/core/gates.js +76 -0
  117. package/dist/core/gates.js.map +1 -0
  118. package/dist/core/lock.js +57 -0
  119. package/dist/core/lock.js.map +1 -0
  120. package/dist/core/metrics.js +140 -0
  121. package/dist/core/metrics.js.map +1 -0
  122. package/dist/core/packet.js +172 -0
  123. package/dist/core/packet.js.map +1 -0
  124. package/dist/core/paths.js +63 -0
  125. package/dist/core/paths.js.map +1 -0
  126. package/dist/core/phases.js +203 -0
  127. package/dist/core/phases.js.map +1 -0
  128. package/dist/core/pr-body.js +64 -0
  129. package/dist/core/pr-body.js.map +1 -0
  130. package/dist/core/project-docs.js +246 -0
  131. package/dist/core/project-docs.js.map +1 -0
  132. package/dist/core/protect.js +47 -0
  133. package/dist/core/protect.js.map +1 -0
  134. package/dist/core/repo-host.js +11 -0
  135. package/dist/core/repo-host.js.map +1 -0
  136. package/dist/core/report.js +286 -0
  137. package/dist/core/report.js.map +1 -0
  138. package/dist/core/result.js +90 -0
  139. package/dist/core/result.js.map +1 -0
  140. package/dist/core/roles.js +18 -0
  141. package/dist/core/roles.js.map +1 -0
  142. package/dist/core/run.js +222 -0
  143. package/dist/core/run.js.map +1 -0
  144. package/dist/core/runner.js +40 -0
  145. package/dist/core/runner.js.map +1 -0
  146. package/dist/core/schema.js +104 -0
  147. package/dist/core/schema.js.map +1 -0
  148. package/dist/core/spec-adapter.js +12 -0
  149. package/dist/core/spec-adapter.js.map +1 -0
  150. package/dist/core/spec-model.js +8 -0
  151. package/dist/core/spec-model.js.map +1 -0
  152. package/dist/core/tasks.js +15 -0
  153. package/dist/core/tasks.js.map +1 -0
  154. package/dist/core/test-reports.js +60 -0
  155. package/dist/core/test-reports.js.map +1 -0
  156. package/dist/core/wiki.js +86 -0
  157. package/dist/core/wiki.js.map +1 -0
  158. package/dist/core/wiring.js +65 -0
  159. package/dist/core/wiring.js.map +1 -0
  160. package/docs/design.md +829 -0
  161. package/package.json +66 -0
@@ -0,0 +1,240 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import YAML from 'yaml';
4
+ import { z } from 'zod';
5
+ import { SboxError } from './errors.js';
6
+ import { exists, readText, today, writeText } from './paths.js';
7
+ import { headRevision, isGitRepo } from './changeset.js';
8
+ export const PHASES = [
9
+ 'intake',
10
+ 'research',
11
+ 'propose',
12
+ 'plan',
13
+ 'cover',
14
+ 'tests_review',
15
+ 'implement',
16
+ 'verify',
17
+ 'review',
18
+ 'deliver',
19
+ 'archived',
20
+ ];
21
+ export const STATUSES = [
22
+ 'active',
23
+ 'waiting_approval',
24
+ 'waiting_user',
25
+ 'waiting_peer',
26
+ 'parked',
27
+ 'blocked',
28
+ 'stopped',
29
+ 'delivery_unknown',
30
+ 'failed',
31
+ 'archived',
32
+ 'done',
33
+ ];
34
+ /** Терминальные статусы не меняются обычными командами (docs/design.md, «Файл change.yaml»). */
35
+ export const TERMINAL_STATUSES = new Set(['archived', 'done', 'stopped', 'delivery_unknown']);
36
+ export const SIZES = ['small', 'normal', 'large'];
37
+ const gateStateSchema = z.object({
38
+ state: z.enum(['pending', 'approved', 'rejected', 'skipped']),
39
+ by: z.string().optional(),
40
+ at: z.string().optional(),
41
+ comment: z.string().optional(),
42
+ reason: z.string().optional(),
43
+ promoted: z.array(z.string()).optional(),
44
+ answers: z.record(z.string(), z.string()).optional(),
45
+ posted_at: z.string().optional(),
46
+ rejected_times: z.number().int().nonnegative().optional(),
47
+ });
48
+ const runSchema = z.object({
49
+ id: z.string(),
50
+ role: z.string(),
51
+ phase: z.string(),
52
+ attempt: z.number().int().positive().default(1),
53
+ runner: z.string().optional(),
54
+ model: z.string().optional(),
55
+ session: z.string().optional(),
56
+ started: z.string().optional(),
57
+ finished: z.string().optional(),
58
+ status: z.enum(['done', 'failed', 'blocked', 'running', 'stopped']),
59
+ dir: z.string().optional(),
60
+ cost_usd: z.number().optional(),
61
+ failure: z.string().optional(),
62
+ });
63
+ const checkSchema = z.object({ id: z.string(), purpose: z.string().optional(), result: z.enum(['PASS', 'FAIL', 'PARTIAL', 'NOT_RUN']), evidence: z.string().optional() });
64
+ const gapSchema = z.object({ id: z.string(), environment: z.string().optional(), oracle: z.string().optional(), risk: z.string().optional() });
65
+ export const changeSchema = z.object({
66
+ id: z.string(),
67
+ title: z.string(),
68
+ created: z.string(),
69
+ revision: z.number().int().nonnegative().default(0),
70
+ source: z
71
+ .object({ kind: z.enum(['text', 'file', 'tracker', 'brief']), ref: z.string().optional(), brief: z.string().optional() })
72
+ .default({ kind: 'text' }),
73
+ size: z.enum(SIZES).default('normal'),
74
+ skip_specs: z.boolean().default(false),
75
+ autonomy: z.enum(['supervised', 'checkpoint', 'autonomous']).optional(),
76
+ phase: z.enum(PHASES).default('intake'),
77
+ status: z.enum(STATUSES).default('active'),
78
+ settled: z.boolean().default(true),
79
+ active_run: z.string().nullable().default(null),
80
+ stop_requested: z.boolean().default(false),
81
+ base_revision: z.string().nullable().default(null),
82
+ gates: z.record(z.string(), gateStateSchema).default({}),
83
+ complexity: z
84
+ .object({ implementation: z.enum(['обычная', 'высокая']), review: z.enum(['обычная', 'высокая']) })
85
+ .optional(),
86
+ assumptions: z.array(z.object({ question: z.string(), priority: z.string(), accepted: z.string() })).default([]),
87
+ protected: z.array(z.string()).default([]),
88
+ /** Хеши защищённых файлов на момент завершения фазы cover: путь → sha256. */
89
+ protected_snapshot: z.record(z.string(), z.string()).default({}),
90
+ blocker: z
91
+ .object({
92
+ category: z.string(),
93
+ artifact: z.string().optional(),
94
+ message: z.string(),
95
+ role: z.string().optional(),
96
+ phase: z.string().optional(),
97
+ resolution: z.string().optional(),
98
+ })
99
+ .nullable()
100
+ .default(null),
101
+ returns: z.record(z.string(), z.number().int()).default({}),
102
+ returns_limit: z.number().int().positive().nullable().default(null),
103
+ changeset: z
104
+ .object({
105
+ base: z.string(),
106
+ digest: z.string(),
107
+ paths: z.number().int(),
108
+ sealed_after: z.string().nullable(),
109
+ sealed_at: z.string(),
110
+ /** Перепривязки после ревью из-за безобидных файлов: что и когда изменилось. */
111
+ rebound: z.array(z.object({ from: z.string(), to: z.string(), files: z.array(z.string()), at: z.string() })).default([]),
112
+ })
113
+ .nullable()
114
+ .default(null),
115
+ reviewed_digest: z.string().nullable().default(null),
116
+ verification: z.object({ run: z.string(), checks: z.array(checkSchema), gaps: z.array(gapSchema) }).nullable().default(null),
117
+ accepted_gaps: z.array(z.object({ item: z.string(), reason: z.string().optional() })).default([]),
118
+ delivery: z
119
+ .object({
120
+ intent_key: z.string(),
121
+ created_at: z.string(),
122
+ state: z.enum(['intent', 'archived', 'committed', 'pushed', 'pr_created', 'done']),
123
+ commit: z.string().nullable().default(null),
124
+ pr: z.object({ number: z.number().optional(), url: z.string().optional() }).nullable().default(null),
125
+ error: z.string().nullable().default(null),
126
+ })
127
+ .nullable()
128
+ .default(null),
129
+ interventions: z.object({ resumes: z.number().int().nonnegative().default(0), user_blockers: z.number().int().nonnegative().default(0) }).prefault({}),
130
+ rating: z.object({ score: z.number().int().min(1).max(5), comment: z.string().optional(), at: z.string() }).nullable().default(null),
131
+ coordination: z.unknown().nullable().default(null),
132
+ branch: z.string().optional(),
133
+ pr: z.object({ number: z.number().optional(), url: z.string().optional(), draft: z.boolean().optional() }).optional(),
134
+ runs: z.array(runSchema).default([]),
135
+ });
136
+ export const CHANGE_FILE = 'change.yaml';
137
+ export function changesDir(root, config) {
138
+ return path.join(root, config.changes.dir);
139
+ }
140
+ export function changeDir(root, config, id) {
141
+ return path.join(changesDir(root, config), id);
142
+ }
143
+ export function archiveDir(root, config) {
144
+ return path.join(changesDir(root, config), 'archive');
145
+ }
146
+ export function isValidChangeId(id) {
147
+ return /^[a-z][a-z0-9-]{1,60}$/.test(id);
148
+ }
149
+ function parseChange(file) {
150
+ const parsed = changeSchema.safeParse(YAML.parse(readText(file)) ?? {});
151
+ if (!parsed.success) {
152
+ const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
153
+ throw new SboxError('BAD_CHANGE', `Некорректный ${file}: ${issues}`);
154
+ }
155
+ return parsed.data;
156
+ }
157
+ export function loadChange(dir) {
158
+ const file = path.join(dir, CHANGE_FILE);
159
+ if (!exists(file))
160
+ throw new SboxError('NO_CHANGE', `Нет файла ${file}`);
161
+ return parseChange(file);
162
+ }
163
+ /**
164
+ * Атомарная запись с проверкой ревизии: временный файл и переименование,
165
+ * отклонение устаревшей копии и защита терминальных статусов.
166
+ */
167
+ export function saveChange(dir, change, opts = {}) {
168
+ const file = path.join(dir, CHANGE_FILE);
169
+ if (exists(file)) {
170
+ const disk = parseChange(file);
171
+ if (disk.revision !== change.revision) {
172
+ throw new SboxError('REVISION_CONFLICT', `change.yaml изменён другим процессом: на диске ревизия ${disk.revision}, в памяти ${change.revision}.`, 'Перечитайте изменение и повторите действие.');
173
+ }
174
+ if (TERMINAL_STATUSES.has(disk.status) && change.status !== disk.status && !opts.allowTerminalReopen) {
175
+ throw new SboxError('TERMINAL_IMMUTABLE', `Статус ${disk.status} терминальный; переход в ${change.status} возможен только через \`sbox change resume\` или \`sbox change reopen\`.`);
176
+ }
177
+ }
178
+ change.revision += 1;
179
+ const tmp = `${file}.${process.pid}.tmp`;
180
+ fs.mkdirSync(dir, { recursive: true });
181
+ fs.writeFileSync(tmp, YAML.stringify(change, { lineWidth: 0 }), 'utf8');
182
+ fs.renameSync(tmp, file);
183
+ return change;
184
+ }
185
+ export function listChanges(root, config) {
186
+ const base = changesDir(root, config);
187
+ if (!exists(base))
188
+ return [];
189
+ return fs
190
+ .readdirSync(base, { withFileTypes: true })
191
+ .filter((e) => e.isDirectory() && e.name !== 'archive' && exists(path.join(base, e.name, CHANGE_FILE)))
192
+ .map((e) => ({ id: e.name, dir: path.join(base, e.name), change: loadChange(path.join(base, e.name)) }))
193
+ .sort((a, b) => a.id.localeCompare(b.id));
194
+ }
195
+ export function createChange(root, config, input) {
196
+ if (!isValidChangeId(input.id)) {
197
+ throw new SboxError('BAD_CHANGE_ID', `Идентификатор "${input.id}" должен быть в kebab-case: буквы, цифры, дефис, начинаться с буквы.`);
198
+ }
199
+ const dir = changeDir(root, config, input.id);
200
+ if (exists(dir))
201
+ throw new SboxError('CHANGE_EXISTS', `Изменение ${input.id} уже существует: ${dir}`);
202
+ const change = changeSchema.parse({
203
+ id: input.id,
204
+ title: input.title,
205
+ created: today(),
206
+ source: input.source ?? { kind: 'text' },
207
+ size: input.size ?? 'normal',
208
+ autonomy: input.autonomy,
209
+ phase: 'research',
210
+ status: 'active',
211
+ base_revision: isGitRepo(root) ? headRevision(root) : null,
212
+ });
213
+ fs.mkdirSync(path.join(dir, 'evidence'), { recursive: true });
214
+ fs.mkdirSync(path.join(dir, 'runs'), { recursive: true });
215
+ fs.mkdirSync(path.join(dir, 'specs'), { recursive: true });
216
+ writeText(path.join(dir, 'request.md'), input.request.endsWith('\n') ? input.request : `${input.request}\n`);
217
+ writeText(path.join(dir, 'log.md'), `---\nchange: ${input.id}\n---\n\n# Журнал — ${input.id}\n\n<!-- [TASK] событие | [CODE] факт о коде | [RULE] правило | [HUMAN] предпочтение -->\n`);
218
+ saveChange(dir, change);
219
+ return { dir, change };
220
+ }
221
+ /** Найти изменение по id или единственное активное. */
222
+ export function resolveChange(root, config, id) {
223
+ if (id) {
224
+ const dir = changeDir(root, config, id);
225
+ return { dir, change: loadChange(dir) };
226
+ }
227
+ const all = listChanges(root, config);
228
+ if (all.length === 1)
229
+ return { dir: all[0].dir, change: all[0].change };
230
+ if (all.length === 0)
231
+ throw new SboxError('NO_CHANGES', 'Активных изменений нет.', 'Создайте изменение: `sbox change new <id> --title "..."`.');
232
+ throw new SboxError('AMBIGUOUS_CHANGE', `Активных изменений несколько: ${all.map((c) => c.id).join(', ')}.`, 'Укажите --change <id>.');
233
+ }
234
+ export function nextRunId(change) {
235
+ return `r${change.runs.length + 1}`;
236
+ }
237
+ export function runDir(dir, runId) {
238
+ return path.join(dir, 'runs', runId);
239
+ }
240
+ //# sourceMappingURL=change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change.js","sourceRoot":"","sources":["../../src/core/change.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { execFileSync } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import picomatch from 'picomatch';
6
+ import { SboxError } from './errors.js';
7
+ import { toPosix } from './paths.js';
8
+ function git(root, args) {
9
+ return execFileSync('git', args, { cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
10
+ }
11
+ export function isGitRepo(root) {
12
+ try {
13
+ git(root, ['rev-parse', '--is-inside-work-tree']);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ export function headRevision(root) {
21
+ try {
22
+ return git(root, ['rev-parse', 'HEAD']).trim();
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ function sha256File(file) {
29
+ return createHash('sha256').update(fs.readFileSync(file)).digest('hex');
30
+ }
31
+ /**
32
+ * Изменённые файлы относительно базовой ревизии: закоммиченные в ветке, staged, unstaged и новые.
33
+ * Папка самого изменения и другие пути из exclude не учитываются.
34
+ */
35
+ export function computeChangeSet(root, base, exclude = []) {
36
+ if (!isGitRepo(root))
37
+ throw new SboxError('NO_GIT', 'Change-set требует git-репозитория.');
38
+ const skip = exclude.length > 0 ? picomatch(exclude, { dot: true }) : () => false;
39
+ const entries = new Map();
40
+ const diff = git(root, ['diff', '--name-status', '-M', base, '--']);
41
+ for (const line of diff.split('\n')) {
42
+ if (!line.trim())
43
+ continue;
44
+ const parts = line.split('\t');
45
+ const code = parts[0][0];
46
+ const file = parts[parts.length - 1];
47
+ entries.set(file, code === 'R' ? 'R' : code);
48
+ }
49
+ const untracked = git(root, ['ls-files', '--others', '--exclude-standard']);
50
+ for (const line of untracked.split('\n')) {
51
+ if (line.trim())
52
+ entries.set(line.trim(), 'A');
53
+ }
54
+ const files = [...entries.entries()]
55
+ .filter(([p]) => !skip(p))
56
+ .sort(([a], [b]) => a.localeCompare(b))
57
+ .map(([p, status]) => {
58
+ const abs = path.join(root, p);
59
+ const exists = fs.existsSync(abs) && fs.statSync(abs).isFile();
60
+ return { path: toPosix(p), status: exists ? status : 'D', sha256: exists ? sha256File(abs) : null };
61
+ });
62
+ const digest = createHash('sha256');
63
+ for (const f of files)
64
+ digest.update(`${f.status} ${f.path} ${f.sha256 ?? '-'}\n`);
65
+ return { version: 1, base, digest: `sha256:${digest.digest('hex')}`, paths: files.length, files };
66
+ }
67
+ export function sealChangeSet(root, base, exclude, sealedAfter) {
68
+ const computed = computeChangeSet(root, base, exclude);
69
+ return { ...computed, sealed_at: new Date().toISOString(), sealed_after: sealedAfter };
70
+ }
71
+ export function writeChangeSet(dir, changeset) {
72
+ const file = path.join(dir, 'changeset.json');
73
+ fs.writeFileSync(file, `${JSON.stringify(changeset, null, 2)}\n`);
74
+ return file;
75
+ }
76
+ export function readChangeSet(dir) {
77
+ const file = path.join(dir, 'changeset.json');
78
+ if (!fs.existsSync(file))
79
+ return null;
80
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
81
+ }
82
+ /** Сверка: совпадает ли текущая рабочая копия с запечатанным дайджестом. */
83
+ export function changeSetDrift(root, sealed, exclude) {
84
+ const current = computeChangeSet(root, sealed.base, exclude);
85
+ const before = new Map(sealed.files.map((f) => [f.path, f.sha256]));
86
+ const after = new Map(current.files.map((f) => [f.path, f.sha256]));
87
+ const added = [...after.keys()].filter((p) => !before.has(p));
88
+ const removed = [...before.keys()].filter((p) => !after.has(p));
89
+ const modified = [...after.keys()].filter((p) => before.has(p) && before.get(p) !== after.get(p));
90
+ return { drifted: current.digest !== sealed.digest, currentDigest: current.digest, added, removed, modified };
91
+ }
92
+ /** Делит дрейф на файлы, отменяющие вердикт, и безобидные (по шаблонам nonInvalidating). */
93
+ export function classifyDrift(drift, nonInvalidating) {
94
+ const all = [...drift.added, ...drift.removed, ...drift.modified];
95
+ const isBenign = nonInvalidating.length > 0 ? picomatch(nonInvalidating, { dot: true }) : () => false;
96
+ return { invalidating: all.filter((p) => !isBenign(p)), benign: all.filter((p) => isBenign(p)) };
97
+ }
98
+ //# sourceMappingURL=changeset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeset.js","sourceRoot":"","sources":["../../src/core/changeset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ import path from 'node:path';
2
+ import YAML from 'yaml';
3
+ import { z } from 'zod';
4
+ import { SboxError } from './errors.js';
5
+ import { SBOX_DIR, CONFIG_FILE, exists, readText, writeText } from './paths.js';
6
+ export const AUTONOMY_PROFILES = ['supervised', 'checkpoint', 'autonomous'];
7
+ export const GATES = ['proposal', 'plan', 'tests'];
8
+ const modelsSchema = z.record(z.string(), z.string());
9
+ export const configSchema = z.object({
10
+ version: z.literal(1),
11
+ spec: z.object({
12
+ adapter: z.enum(['spec-box', 'openspec']),
13
+ 'spec-box': z
14
+ .object({
15
+ config: z.string().default('.tms.json'),
16
+ files: z.array(z.string()).optional(),
17
+ newFile: z.string().default('specs/{code}.spec-box.yml'),
18
+ })
19
+ .prefault({}),
20
+ openspec: z.object({ root: z.string().default('openspec') }).prefault({}),
21
+ }),
22
+ autonomy: z.enum(AUTONOMY_PROFILES).default('supervised'),
23
+ gates: z
24
+ .object({
25
+ channels: z.array(z.enum(['cli', 'pr-comments', 'tracker', 'chat'])).default(['cli']),
26
+ /** Явный набор гейтов; если задан, имеет приоритет над профилем. */
27
+ enabled: z.array(z.enum(GATES)).optional(),
28
+ })
29
+ .prefault({}),
30
+ runner: z
31
+ .object({
32
+ default: z.enum(['claude', 'codex']).default('claude'),
33
+ models: modelsSchema.default({}),
34
+ /** Усилие модели по ролям (low | medium | high | xhigh); без записи роль получает medium, а не усилие сессии. */
35
+ efforts: z.record(z.string(), z.string()).default({}),
36
+ defaultEffort: z.string().default('medium'),
37
+ /** Каталог вне репозитория для событий и stderr запусков. */
38
+ stateDir: z.string().default('~/.sbox/runs'),
39
+ timeoutMinutes: z.number().positive().default(120),
40
+ idleTimeoutMinutes: z.number().positive().default(20),
41
+ claude: z
42
+ .object({
43
+ executable: z.string().optional(),
44
+ permissionMode: z.enum(['default', 'acceptEdits', 'bypassPermissions']).default('acceptEdits'),
45
+ allowedTools: z.array(z.string()).default(['Read', 'Grep', 'Glob', 'Bash', 'Edit', 'Write', 'MultiEdit', 'NotebookEdit']),
46
+ readOnlyTools: z.array(z.string()).default(['Read', 'Grep', 'Glob', 'Bash']),
47
+ maxBudgetUsd: z.number().positive().optional(),
48
+ maxTurns: z.number().int().positive().optional(),
49
+ })
50
+ .prefault({}),
51
+ codex: z
52
+ .object({
53
+ executable: z.string().default('codex'),
54
+ sandboxWrite: z.string().default('workspace-write'),
55
+ sandboxRead: z.string().default('read-only'),
56
+ approvalPolicy: z.string().default('on-request'),
57
+ extraConfig: z.array(z.string()).default([]),
58
+ })
59
+ .prefault({}),
60
+ })
61
+ .prefault({}),
62
+ repo: z
63
+ .object({
64
+ adapter: z.enum(['github', 'local']).default('local'),
65
+ baseBranch: z.string().default('main'),
66
+ branchPrefix: z.string().default('sbox/'),
67
+ github: z
68
+ .object({
69
+ owner: z.string().optional(),
70
+ repo: z.string().optional(),
71
+ apiUrl: z.string().default('https://api.github.com'),
72
+ tokenEnv: z.string().default('GITHUB_TOKEN'),
73
+ })
74
+ .prefault({}),
75
+ })
76
+ .prefault({}),
77
+ changeset: z
78
+ .object({
79
+ exclude: z.array(z.string()).optional(),
80
+ /** Файлы в change-set, изменение которых после verify/review не отменяет вердикт: дайджест перепривязывается с записью. */
81
+ nonInvalidating: z.array(z.string()).default(['**/*.md', '.gitignore', '.gitattributes', '.editorconfig', '.claude/**', '.codex/**', '.sbox/**']),
82
+ })
83
+ .prefault({}),
84
+ /** Проверка подключения по образцу: advisory (пункты PARTIAL для ревьюера) или strict (ошибка верификации). */
85
+ wiring: z.object({ strict: z.boolean().default(false) }).prefault({}),
86
+ changes: z.object({ dir: z.string().default('.sbox/changes') }).prefault({}),
87
+ project: z.object({ docs: z.string().default('.sbox/project'), wiki: z.string().default('.sbox/wiki') }).prefault({}),
88
+ testing: z
89
+ .object({
90
+ manualPlan: z.enum(['always', 'when-needed', 'never']).default('when-needed'),
91
+ /** Повторять ИИ-ревью тестов после доработки по замечанию человека; по умолчанию только первый прогон. */
92
+ reviewReworks: z.boolean().default(false),
93
+ protectedGlobs: z.array(z.string()).default([]),
94
+ })
95
+ .prefault({}),
96
+ limits: z
97
+ .object({
98
+ returnsPerPhase: z.number().int().positive().default(3),
99
+ rejectionsPerPhase: z.number().int().nonnegative().default(2),
100
+ maxRunsPerInvocation: z.number().int().positive().default(20),
101
+ maxCostUsdPerInvocation: z.number().positive().optional(),
102
+ packetFileChars: z.number().int().positive().default(4000),
103
+ })
104
+ .prefault({}),
105
+ context: z.string().optional(),
106
+ rules: z.record(z.string(), z.array(z.string())).prefault({}),
107
+ });
108
+ export function configPath(root) {
109
+ return path.join(root, SBOX_DIR, CONFIG_FILE);
110
+ }
111
+ export function loadConfig(root) {
112
+ const file = configPath(root);
113
+ if (!exists(file)) {
114
+ throw new SboxError('NO_CONFIG', `Нет файла ${file}`, 'Выполните `sbox init`.');
115
+ }
116
+ const raw = YAML.parse(readText(file)) ?? {};
117
+ const parsed = configSchema.safeParse(raw);
118
+ if (!parsed.success) {
119
+ const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
120
+ throw new SboxError('BAD_CONFIG', `Некорректный ${file}: ${issues}`);
121
+ }
122
+ return parsed.data;
123
+ }
124
+ export function saveConfig(root, config) {
125
+ writeText(configPath(root), YAML.stringify(config));
126
+ }
127
+ export function defaultConfig(specAdapter = 'spec-box') {
128
+ return configSchema.parse({ version: 1, spec: { adapter: specAdapter } });
129
+ }
130
+ /** Какие гейты включены: явный список из конфига, иначе профиль автономии. */
131
+ export function enabledGates(config, autonomy) {
132
+ if (config.gates.enabled)
133
+ return [...config.gates.enabled];
134
+ const profile = autonomy ?? config.autonomy;
135
+ switch (profile) {
136
+ case 'supervised':
137
+ return ['proposal', 'plan', 'tests'];
138
+ case 'checkpoint':
139
+ return ['plan'];
140
+ case 'autonomous':
141
+ return [];
142
+ }
143
+ }
144
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import YAML from 'yaml';
4
+ import { z } from 'zod';
5
+ import { SboxError } from './errors.js';
6
+ /**
7
+ * coverage.yaml: capability → группа → утверждение → tests[] | manual.
8
+ * Сопоставление с отчётом повторяет ключи spec-box: название фичи › группы › утверждения.
9
+ */
10
+ const testRefSchema = z.object({ level: z.string().optional(), file: z.string().optional(), name: z.string().min(1) });
11
+ const entrySchema = z.union([z.object({ tests: z.array(testRefSchema).min(1) }), z.object({ manual: z.string().min(1) })]);
12
+ export const coverageSchema = z.record(z.string(), z.record(z.string(), z.record(z.string(), entrySchema)));
13
+ export function readCoverage(dir) {
14
+ const file = path.join(dir, 'coverage.yaml');
15
+ if (!fs.existsSync(file))
16
+ throw new SboxError('NO_COVERAGE', `Нет файла ${file}`);
17
+ const raw = YAML.parse(fs.readFileSync(file, 'utf8')) ?? {};
18
+ const parsed = coverageSchema.safeParse(raw);
19
+ if (!parsed.success) {
20
+ const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
21
+ throw new SboxError('BAD_COVERAGE', `coverage.yaml не соответствует контракту: ${issues}`);
22
+ }
23
+ return parsed.data;
24
+ }
25
+ const norm = (s) => s.replace(/\s+/g, ' ').trim().toLowerCase();
26
+ /** Состояние каждого утверждения из дельт: покрыто зелёным тестом, падает, теста нет в отчёте, ручное, не описано в coverage. */
27
+ export function matchCoverage(coverage, deltas, report) {
28
+ const byName = new Map();
29
+ for (const t of report ?? []) {
30
+ byName.set(norm(t.fullName), t);
31
+ byName.set(norm(t.titles.join(' › ')), t);
32
+ byName.set(norm(t.titles.join(' ')), t);
33
+ }
34
+ const rows = [];
35
+ for (const delta of deltas) {
36
+ const cap = coverage[delta.capabilityId] ?? {};
37
+ for (const op of delta.ops) {
38
+ if (op.op !== 'add-requirement' && op.op !== 'modify-requirement')
39
+ continue;
40
+ const group = cap[op.requirement.title] ?? {};
41
+ for (const s of op.requirement.scenarios) {
42
+ const entry = group[s.title];
43
+ if (!entry) {
44
+ rows.push({ capability: delta.capabilityId, requirement: op.requirement.title, scenario: s.title, kind: 'automated', tests: [], state: 'unlisted' });
45
+ continue;
46
+ }
47
+ if ('manual' in entry) {
48
+ rows.push({ capability: delta.capabilityId, requirement: op.requirement.title, scenario: s.title, kind: 'manual', tests: [], manual: entry.manual, state: 'manual' });
49
+ continue;
50
+ }
51
+ const tests = entry.tests.map((t) => {
52
+ const found = report ? byName.get(norm(t.name)) : undefined;
53
+ const status = report ? (found?.status ?? 'missing') : 'pending';
54
+ return { name: t.name, ...(t.level ? { level: t.level } : {}), ...(t.file ? { file: t.file } : {}), status };
55
+ });
56
+ const state = !report ? 'missing' : tests.every((t) => t.status === 'passed') ? 'green' : tests.some((t) => t.status === 'failed') ? 'red' : 'missing';
57
+ rows.push({ capability: delta.capabilityId, requirement: op.requirement.title, scenario: s.title, kind: 'automated', tests, state });
58
+ }
59
+ }
60
+ }
61
+ return rows;
62
+ }
63
+ export function coverageSummary(rows) {
64
+ const out = { green: 0, red: 0, missing: 0, manual: 0, unlisted: 0 };
65
+ for (const r of rows)
66
+ out[r.state] += 1;
67
+ return out;
68
+ }
69
+ //# sourceMappingURL=coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/core/coverage.ts"],"names":[],"mappings":"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"}