@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 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../../src/cli/commands/host.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,iBAAiB,GAAG;;mHAEyF,CAAC;AAEpH,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC;IACtF,IAAI;SACD,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,0CAA0C,CAAC;SACvD,cAAc,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;SACnD,MAAM,CAAC,CAAC,IAAwB,EAAE,GAAY,EAAE,EAAE;QACjD,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAqC,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAAE,MAAM,IAAI,SAAS,CAAC,gBAAgB,EAAE,QAAQ,IAAI,CAAC,MAAM,qCAAqC,CAAC,CAAC;YAC9H,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClG,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,4DAA4D,EAAE,2DAA2D,EAAE,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzT,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,150 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { installClaudeMaterials } from '../../adapters/host/claude/index.js';
4
+ import { defaultConfig, loadConfig, saveConfig } from '../../core/config.js';
5
+ import { SboxError } from '../../core/errors.js';
6
+ import { assetsDir, sboxDir, exists, readText, today, writeText } from '../../core/paths.js';
7
+ import { DOC_CATEGORIES } from '../../core/project-docs.js';
8
+ import { WIKI_README } from '../../core/wiki.js';
9
+ import { emit, emitError } from '../output.js';
10
+ const GITIGNORE_BLOCK = ['# sbox: служебные файлы запусков', '**/.sbox/**/.lock', '**/.stop', '**/change.yaml.*.tmp', '**/runs/run.log', '**/runs/r*/packet.json'];
11
+ export function registerInit(program) {
12
+ program
13
+ .command('init')
14
+ .description('Создать .sbox/: конфиг, шаблоны проектной документации, каталог изменений; при --host сразу материалы для хоста')
15
+ .option('--adapter <name>', 'адаптер спецификаций: spec-box | openspec; при существующем конфиге меняет только его')
16
+ .option('--host <name>', 'сразу установить материалы хоста: claude')
17
+ .option('--force', 'перезаписать конфиг целиком (документация не трогается)')
18
+ .option('--reset-docs', 'перезаписать заполненную документацию шаблонами')
19
+ .action((opts, cmd) => {
20
+ const g = cmd.optsWithGlobals();
21
+ try {
22
+ const root = path.resolve(g.cwd ?? process.cwd());
23
+ const adapter = (opts.adapter ?? (exists(path.join(root, 'openspec', 'specs')) && !exists(path.join(root, '.tms.json')) ? 'openspec' : 'spec-box'));
24
+ if (adapter !== 'spec-box' && adapter !== 'openspec')
25
+ throw new SboxError('ADAPTER_UNKNOWN', `Неизвестный адаптер ${String(adapter)}; доступны spec-box и openspec.`);
26
+ const dir = sboxDir(root);
27
+ const created = [];
28
+ const notes = [];
29
+ const configFile = path.join(dir, 'config.yaml');
30
+ if (exists(configFile) && !opts.force) {
31
+ // Повторный запуск: обновляем только адаптер и связанные пути, остальное сохраняем.
32
+ const current = loadConfig(root);
33
+ if (opts.adapter && current.spec.adapter !== adapter) {
34
+ current.spec.adapter = adapter;
35
+ if (adapter === 'openspec') {
36
+ const activeChanges = exists(path.join(root, current.changes.dir)) ? fs.readdirSync(path.join(root, current.changes.dir)).filter((n) => n !== 'archive' && n !== '.gitkeep') : [];
37
+ if (activeChanges.length === 0) {
38
+ current.changes.dir = 'openspec/changes';
39
+ notes.push('changes.dir переключён на openspec/changes для совместимости с CLI OpenSpec.');
40
+ }
41
+ else {
42
+ notes.push(`В ${current.changes.dir} есть изменения (${activeChanges.join(', ')}): changes.dir оставлен; перенесите их в openspec/changes и поправьте конфиг вручную, если нужна совместимость с CLI OpenSpec.`);
43
+ }
44
+ for (const sub of ['specs', 'changes', 'changes/archive']) {
45
+ const keep = path.join(root, 'openspec', sub, '.gitkeep');
46
+ if (!exists(path.join(root, 'openspec', sub))) {
47
+ writeText(keep, '');
48
+ created.push(keep);
49
+ }
50
+ }
51
+ const staleKeep = path.join(root, 'specs', '.gitkeep');
52
+ if (exists(staleKeep) && fs.readdirSync(path.join(root, 'specs')).length === 1) {
53
+ fs.rmSync(path.join(root, 'specs'), { recursive: true, force: true });
54
+ notes.push('Удалён пустой каталог specs/, созданный для spec-box.');
55
+ }
56
+ }
57
+ saveConfig(root, current);
58
+ created.push(configFile);
59
+ notes.push(`Адаптер спецификаций переключён на ${adapter}; проверьте раздел «Истина спецификаций» в .sbox/project/overview.md.`);
60
+ }
61
+ else {
62
+ notes.push('Конфиг уже есть и не изменён: укажите --adapter для смены адаптера или --force для перезаписи.');
63
+ }
64
+ }
65
+ else {
66
+ const config = defaultConfig(adapter);
67
+ if (adapter === 'openspec') {
68
+ // Совместимость с CLI OpenSpec: изменения живут в openspec/changes, истина в openspec/specs.
69
+ config.changes.dir = 'openspec/changes';
70
+ for (const sub of ['specs', 'changes', 'changes/archive']) {
71
+ const keep = path.join(root, 'openspec', sub, '.gitkeep');
72
+ if (!exists(path.join(root, 'openspec', sub))) {
73
+ writeText(keep, '');
74
+ created.push(keep);
75
+ }
76
+ }
77
+ notes.push('Адаптер openspec: истина в openspec/specs/<capability>/spec.md, изменения в openspec/changes/<id>/ (совместимо с openspec CLI).');
78
+ }
79
+ else if (!exists(path.join(root, '.tms.json'))) {
80
+ // Нет конфига spec-box: истина будет жить в specs/*.spec-box.yml прямо в репозитории.
81
+ config.spec['spec-box'].files = ['specs/**/*.spec-box.yml'];
82
+ const keep = path.join(root, 'specs', '.gitkeep');
83
+ if (!exists(keep)) {
84
+ writeText(keep, '');
85
+ created.push(keep);
86
+ }
87
+ notes.push('Файла .tms.json нет: спецификации ожидаются в specs/**/*.spec-box.yml (поле spec.spec-box.files в конфиге).');
88
+ }
89
+ saveConfig(root, config);
90
+ created.push(configFile);
91
+ }
92
+ const date = today();
93
+ for (const category of DOC_CATEGORIES) {
94
+ const target = path.join(dir, 'project', category.file);
95
+ if (exists(target) && !opts.resetDocs)
96
+ continue;
97
+ writeText(target, readText(path.join(assetsDir(), 'project', category.file)).replace(/\{\{DATE\}\}/g, date));
98
+ created.push(target);
99
+ }
100
+ const decisionsReadme = path.join(dir, 'project', 'decisions', 'README.md');
101
+ if (!exists(decisionsReadme)) {
102
+ writeText(decisionsReadme, readText(path.join(assetsDir(), 'project', 'decisions.README.md')));
103
+ created.push(decisionsReadme);
104
+ }
105
+ const wikiReadme = path.join(dir, 'wiki', 'README.md');
106
+ if (!exists(wikiReadme)) {
107
+ writeText(wikiReadme, WIKI_README);
108
+ created.push(wikiReadme);
109
+ }
110
+ for (const sub of ['changes', 'changes/archive', 'discovery']) {
111
+ const keep = path.join(dir, sub, '.gitkeep');
112
+ if (!exists(keep)) {
113
+ fs.mkdirSync(path.dirname(keep), { recursive: true });
114
+ fs.writeFileSync(keep, '');
115
+ }
116
+ }
117
+ const gitignore = path.join(root, '.gitignore');
118
+ const current = exists(gitignore) ? readText(gitignore) : '';
119
+ const lines = new Set(current.split(/\r?\n/).map((l) => l.trim()));
120
+ const missing = GITIGNORE_BLOCK.filter((l) => !l.startsWith('#') && !lines.has(l));
121
+ if (missing.length > 0) {
122
+ const header = current.includes('# sbox:') ? '' : `${GITIGNORE_BLOCK[0]}\n`;
123
+ writeText(gitignore, `${current.trimEnd()}${current.trim() ? '\n\n' : ''}${header}${missing.join('\n')}\n`);
124
+ created.push(gitignore);
125
+ }
126
+ let hostFiles = [];
127
+ if (opts.host) {
128
+ if (opts.host !== 'claude')
129
+ throw new SboxError('HOST_NOT_READY', `Хост ${opts.host} ещё не поддержан; доступен claude.`);
130
+ hostFiles = installClaudeMaterials(root, exists(configFile) ? loadConfig(root) : undefined).map((f) => path.relative(root, f));
131
+ }
132
+ emit(g, { root, adapter, created: created.map((f) => path.relative(root, f)), host: hostFiles, notes }, (d) => [
133
+ `Инициализировано в ${d.root} (адаптер ${d.adapter})`,
134
+ ...d.created.map((f) => ` + ${f}`),
135
+ ...d.host.map((f) => ` + ${f}`),
136
+ ...d.notes.map((n) => ` ! ${n}`),
137
+ '',
138
+ 'Дальше:',
139
+ ' 1. Заполните .sbox/project/*.md (или попросите researcher: `sbox change new` и роль соберёт черновик по коду).',
140
+ ' 2. `sbox doctor` — проверка документации и спецификаций.',
141
+ ...(d.host.length ? [' 3. В Claude Code: `/sbox-run` после `sbox change new <id> --title "..." --request "..."`.'] : [' 3. `sbox host install --target claude` — скиллы и агенты для Claude Code.']),
142
+ ].join('\n'));
143
+ }
144
+ catch (e) {
145
+ emitError(g, e);
146
+ process.exitCode = 1;
147
+ }
148
+ });
149
+ }
150
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { loadChange, saveChange } from '../../core/change.js';
2
+ import { SboxError } from '../../core/errors.js';
3
+ import { allChangeDirs, changeMetrics, findChangeDir, summarize } from '../../core/metrics.js';
4
+ import { projectContext } from '../context.js';
5
+ import { emit, emitError } from '../output.js';
6
+ export function registerMetrics(program) {
7
+ program
8
+ .command('metrics')
9
+ .description('Метрики работы решателя: время, запуски, стоимость, возвраты, вмешательства, оценки')
10
+ .option('--change <id>', 'одно изменение (активное или архивное)')
11
+ .action((opts, cmd) => {
12
+ const g = cmd.optsWithGlobals();
13
+ try {
14
+ const ctx = projectContext(g.cwd);
15
+ const dirs = opts.change ? [findChangeDir(ctx.root, ctx.config, opts.change)].filter((d) => Boolean(d)) : allChangeDirs(ctx.root, ctx.config);
16
+ if (opts.change && dirs.length === 0)
17
+ throw new SboxError('NO_CHANGE', `Изменение ${opts.change} не найдено ни среди активных, ни в архиве`);
18
+ const all = dirs.map((d) => changeMetrics(d, loadChange(d)));
19
+ const summary = summarize(all);
20
+ emit(g, { changes: all, summary }, (d) => [
21
+ ...d.changes.map((m) => [
22
+ `${m.id} (${m.status}, ${m.size}): запусков ${m.runs}, агенты ${m.agent_minutes} мин, стоимость ${m.cost_usd === null ? 'н/д' : `$${m.cost_usd}`}, вмешательств ${m.interventions.total}${m.autonomous ? ' (автономно)' : ''}${m.rating ? `, оценка ${m.rating.score}/5` : ''}`,
23
+ ...Object.entries(m.phases).map(([ph, p]) => ` ${ph.padEnd(13)} запусков ${p.runs}, ${Math.round(p.agent_minutes)} мин${p.returns ? `, возвратов ${p.returns}` : ''}${p.rejections ? `, отклонений ${p.rejections}` : ''}`),
24
+ ...Object.entries(m.gates).map(([gate, x]) => ` гейт ${gate.padEnd(9)} ${x.state}${x.wait_minutes !== null ? `, ожидание ${Math.round(x.wait_minutes)} мин` : ''}${x.rejected_times ? `, отклонён ${x.rejected_times} раз` : ''}`),
25
+ ].join('\n')),
26
+ '',
27
+ `итого: изменений ${d.summary.changes}, завершено ${d.summary.finished}, автономно ${d.summary.autonomous_share === null ? 'н/д' : `${Math.round(d.summary.autonomous_share * 100)}%`}, медиана времени агентов ${d.summary.median_agent_minutes ?? 'н/д'} мин, медиана запусков ${d.summary.median_runs ?? 'н/д'}, стоимость ${d.summary.total_cost_usd === null ? 'н/д' : `$${d.summary.total_cost_usd}`}, средняя оценка ${d.summary.mean_rating ?? 'н/д'}, вмешательств на изменение ${d.summary.interventions_per_change ?? 'н/д'}`,
28
+ ].join('\n'));
29
+ }
30
+ catch (e) {
31
+ emitError(g, e);
32
+ process.exitCode = 1;
33
+ }
34
+ });
35
+ }
36
+ export function registerRate(change) {
37
+ change
38
+ .command('rate <id>')
39
+ .description('Оценка результата человеком после проверки: 1–5 и комментарий')
40
+ .requiredOption('--score <n>', '1 (переделывать) … 5 (принял без правок)', (v) => Number.parseInt(v, 10))
41
+ .option('--comment <text>')
42
+ .action((id, opts, cmd) => {
43
+ const g = cmd.optsWithGlobals();
44
+ try {
45
+ const ctx = projectContext(g.cwd);
46
+ const dir = findChangeDir(ctx.root, ctx.config, id);
47
+ if (!dir)
48
+ throw new SboxError('NO_CHANGE', `Изменение ${id} не найдено`);
49
+ if (!(opts.score >= 1 && opts.score <= 5))
50
+ throw new SboxError('BAD_SCORE', 'Оценка от 1 до 5');
51
+ const c = loadChange(dir);
52
+ c.rating = { score: opts.score, at: new Date().toISOString(), ...(opts.comment ? { comment: opts.comment } : {}) };
53
+ saveChange(dir, c, { allowTerminalReopen: true });
54
+ emit(g, { id, rating: c.rating }, (d) => `Оценка ${d.rating.score}/5 записана для ${d.id}.`);
55
+ }
56
+ catch (e) {
57
+ emitError(g, e);
58
+ process.exitCode = 1;
59
+ }
60
+ });
61
+ }
62
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { SboxError } from '../../core/errors.js';
4
+ import { assetsDir, readText } from '../../core/paths.js';
5
+ import { projectContext } from '../context.js';
6
+ import { emit, emitError } from '../output.js';
7
+ const PROMPTS = {
8
+ 'project-docs': { file: 'fill-project-docs.md', description: 'Заполнить .sbox/project/*.md по коду репозитория' },
9
+ };
10
+ /** Подстановки под адаптер спецификаций проекта. */
11
+ function substitutions(adapter) {
12
+ if (adapter === 'openspec') {
13
+ return {
14
+ SPEC_CHAIN: '«название capability › требование › сценарий» из `openspec/specs/<capability>/spec.md` (заголовки `# … Specification`, `### Requirement:`, `#### Scenario:`)',
15
+ SPEC_TRUTH: 'формат OpenSpec, файлы `openspec/specs/<capability>/spec.md`',
16
+ };
17
+ }
18
+ return {
19
+ SPEC_CHAIN: '«название фичи › группа › утверждение» из YAML spec-box (поля `feature`, ключ группы в `specs-unit`, `assert`)',
20
+ SPEC_TRUTH: 'формат spec-box, YAML-файлы по шаблонам из `.tms.json` или `spec.spec-box.files`',
21
+ };
22
+ }
23
+ export function renderPrompt(name, adapter) {
24
+ const entry = PROMPTS[name];
25
+ if (!entry)
26
+ throw new SboxError('NO_PROMPT', `Нет промпта ${name}; доступны: ${Object.keys(PROMPTS).join(', ')}`);
27
+ const subs = substitutions(adapter);
28
+ return readText(path.join(assetsDir(), 'prompts', entry.file)).replace(/\{\{(\w+)\}\}/g, (_m, key) => subs[key] ?? `{{${key}}}`);
29
+ }
30
+ export function registerPrompt(program) {
31
+ const prompt = program.command('prompt').description('Готовые промпты для хоста разработчика');
32
+ prompt
33
+ .command('list')
34
+ .description('Список промптов')
35
+ .action((_opts, cmd) => {
36
+ const g = cmd.optsWithGlobals();
37
+ emit(g, { prompts: Object.entries(PROMPTS).map(([name, p]) => ({ name, description: p.description })) }, (d) => d.prompts.map((p) => `${p.name}\t${p.description}`).join('\n'));
38
+ });
39
+ prompt
40
+ .command('show <name>')
41
+ .description('Напечатать промпт с формулировками под адаптер проекта')
42
+ .option('--adapter <name>', 'spec-box | openspec (по умолчанию из конфига проекта)')
43
+ .action((name, opts, cmd) => {
44
+ const g = cmd.optsWithGlobals();
45
+ try {
46
+ let adapter = opts.adapter;
47
+ if (!adapter) {
48
+ try {
49
+ adapter = projectContext(g.cwd).config.spec.adapter;
50
+ }
51
+ catch {
52
+ adapter = 'spec-box';
53
+ }
54
+ }
55
+ const text = renderPrompt(name, adapter);
56
+ if (g.json)
57
+ emit(g, { name, adapter, text }, () => text);
58
+ else
59
+ process.stdout.write(`${text.trimEnd()}\n`);
60
+ }
61
+ catch (e) {
62
+ emitError(g, e);
63
+ process.exitCode = 1;
64
+ }
65
+ });
66
+ }
67
+ export { fs };
68
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/cli/commands/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,OAAO,GAA0D;IACrE,cAAc,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,WAAW,EAAE,kDAAkD,EAAE;CAClH,CAAC;AAEF,oDAAoD;AACpD,SAAS,aAAa,CAAC,OAAe;IACpC,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO;YACL,UAAU,EAAE,8JAA8J;YAC1K,UAAU,EAAE,8DAA8D;SAC3E,CAAC;IACJ,CAAC;IACD,OAAO;QACL,UAAU,EAAE,gHAAgH;QAC5H,UAAU,EAAE,kFAAkF;KAC/F,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAe;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,SAAS,CAAC,WAAW,EAAE,eAAe,IAAI,eAAe,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClH,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,EAAE,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC;AAC3I,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;IAC/F,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,iBAAiB,CAAC;SAC9B,MAAM,CAAC,CAAC,KAAc,EAAE,GAAY,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAuB,CAAC;QACrD,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClL,CAAC,CAAC,CAAC;IACL,MAAM;SACH,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,wDAAwD,CAAC;SACrE,MAAM,CAAC,kBAAkB,EAAE,uDAAuD,CAAC;SACnF,MAAM,CAAC,CAAC,IAAY,EAAE,IAA0B,EAAE,GAAY,EAAE,EAAE;QACjE,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,EAAqC,CAAC;QACnE,IAAI,CAAC;YACH,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC;oBACH,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;gBACtD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,GAAG,UAAU,CAAC;gBACvB,CAAC;YACH,CAAC;YACD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,CAAC,CAAC,IAAI;gBAAE,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;;gBACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,OAAO,EAAE,EAAE,EAAE,CAAC"}
@@ -0,0 +1,151 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { nextRunId, saveChange } from '../../core/change.js';
4
+ import { GATES } from '../../core/config.js';
5
+ import { SboxError } from '../../core/errors.js';
6
+ import { buildPacket } from '../../core/packet.js';
7
+ import { exists, readText, toPosix, writeText } from '../../core/paths.js';
8
+ import { approveGate, isRoleName, nextStep, rejectGate, ROLE_BY_PHASE } from '../../core/phases.js';
9
+ import { applyReport } from '../../core/report.js';
10
+ import { artifactStates, loadWorkflow } from '../../core/schema.js';
11
+ import { changeContext } from '../context.js';
12
+ import { emit, emitError, formatDiagnostics } from '../output.js';
13
+ export function registerProtocol(program) {
14
+ program
15
+ .command('next')
16
+ .description('Следующий шаг изменения: пакет для роли, гейт, доставка или ожидание')
17
+ .option('--change <id>', 'идентификатор изменения')
18
+ .option('--brief', 'не печатать пакет целиком: только роль, фаза, путь к пакету и команда отчёта')
19
+ .action(async (opts, cmd) => {
20
+ const g = cmd.optsWithGlobals();
21
+ try {
22
+ const ctx = changeContext(g.cwd, opts.change);
23
+ const step = nextStep(ctx.change, ctx.config);
24
+ if (step.kind === 'role') {
25
+ if (ctx.change.phase === 'intake') {
26
+ ctx.change.phase = 'research';
27
+ saveChange(ctx.dir, ctx.change);
28
+ }
29
+ const truthSources = (await ctx.adapter.readTruth()).map((c) => c.source ?? c.id);
30
+ const packet = buildPacket({ ...ctx, role: step.role, phase: step.phase, truthSources });
31
+ const packetFile = path.join(ctx.dir, 'runs', packet.runId, 'packet.json');
32
+ writeText(packetFile, JSON.stringify(packet, null, 2));
33
+ const rel = toPosix(path.relative(ctx.root, packetFile));
34
+ const brief = { kind: 'role', role: step.role, phase: step.phase, runId: packet.runId, packetFile: rel, resultFile: packet.resultFile, objective: packet.objective, feedback: packet.feedback, report: packet.commands.report };
35
+ if (opts.brief) {
36
+ emit(g, brief, (d) => [`Шаг: роль ${d.role}, фаза ${d.phase}`, `Пакет: ${d.packetFile}`, `Цель: ${d.objective}`, ...(d.feedback ? [`Фидбэк: ${d.feedback.slice(0, 300)}`] : []), `Отчёт: ${d.report}`].join('\n'));
37
+ return;
38
+ }
39
+ emit(g, { ...brief, packet }, (d) => [`Шаг: роль ${d.role}, фаза ${d.phase}`, `Пакет: ${d.packetFile}`, `Цель: ${d.objective}`, `Отчёт: ${d.report}`].join('\n'));
40
+ return;
41
+ }
42
+ if (step.kind === 'gate') {
43
+ const states = artifactStates(loadWorkflow(ctx.root), ctx.change, ctx.dir);
44
+ const review = states.filter((s) => s.existing.length > 0).map((s) => ({ id: s.id, files: s.existing.map((f) => toPosix(path.relative(ctx.root, f))) }));
45
+ const questions = pendingQuestions(ctx.change);
46
+ emit(g, { kind: 'gate', gate: step.gate, phase: step.phase, review, questions, approve: `sbox approve ${step.gate} --change ${ctx.change.id} --by <user>`, reject: `sbox reject ${step.gate} --change ${ctx.change.id} --comment "<замечание>"` }, (d) => [`Гейт ${d.gate}: нужно решение человека.`, 'Посмотрите:', ...d.review.flatMap((r) => r.files.map((f) => ` ${f}`)), ...(d.questions.length ? ['Вопросы:', ...d.questions.map((q) => ` ${q}`)] : []), `Утвердить: ${d.approve}`, `Отклонить: ${d.reject}`].join('\n'));
47
+ return;
48
+ }
49
+ if (step.kind === 'deliver') {
50
+ emit(g, { kind: 'deliver', archive: `sbox archive --change ${ctx.change.id}` }, (d) => `Изменение готово к доставке. Архивация: ${d.archive}`);
51
+ return;
52
+ }
53
+ if (step.kind === 'wait') {
54
+ emit(g, { kind: 'wait', status: step.status, blocker: step.blocker }, (d) => `Ожидание: статус ${d.status}${d.blocker ? `, блокер ${d.blocker.category}: ${d.blocker.message}` : ''}`);
55
+ return;
56
+ }
57
+ emit(g, { kind: 'done' }, () => 'Изменение завершено.');
58
+ }
59
+ catch (e) {
60
+ emitError(g, e);
61
+ process.exitCode = 1;
62
+ }
63
+ });
64
+ program
65
+ .command('report')
66
+ .description('Принять ответ роли и перевести изменение дальше')
67
+ .requiredOption('--role <role>', 'роль')
68
+ .option('--file <path>', 'файл с ответом роли; по умолчанию runs/<следующий запуск>/result.md')
69
+ .option('--change <id>', 'идентификатор изменения')
70
+ .option('--phase <phase>', 'фаза, если отличается от текущей')
71
+ .option('--runner <name>', 'адаптер среды')
72
+ .option('--model <name>', 'модель')
73
+ .option('--session <id>', 'идентификатор сессии агента')
74
+ .action(async (opts, cmd) => {
75
+ const g = cmd.optsWithGlobals();
76
+ try {
77
+ const ctx = changeContext(g.cwd, opts.change);
78
+ if (!isRoleName(opts.role))
79
+ throw new SboxError('BAD_ROLE', `Неизвестная роль ${opts.role}`);
80
+ const step = nextStep(ctx.change, ctx.config);
81
+ const phase = opts.phase ?? (step.kind === 'role' ? step.phase : ctx.change.phase);
82
+ const expected = ROLE_BY_PHASE[phase];
83
+ if (expected && expected !== opts.role)
84
+ throw new SboxError('ROLE_MISMATCH', `Фаза ${phase} ожидает роль ${expected}, а не ${opts.role}.`);
85
+ const file = opts.file ? path.resolve(opts.file) : path.join(ctx.dir, 'runs', nextRunId(ctx.change), 'result.md');
86
+ if (!exists(file))
87
+ throw new SboxError('NO_FILE', `Нет файла ${file}`, 'Роль пишет ответ в resultFile из пакета; укажите --file, если ответ лежит в другом месте.');
88
+ const outcome = await applyReport({ ...ctx, role: opts.role, phase, markdown: readText(file), adapter: ctx.adapter, receipt: { runner: opts.runner, model: opts.model, session: opts.session } });
89
+ const rejected = outcome.diagnostics.some((d) => d.severity === 'error');
90
+ emit(g, { runId: outcome.runId, status: outcome.result.status, phaseCompleted: outcome.phaseCompleted, accepted: !rejected, diagnostics: outcome.diagnostics, change: { phase: ctx.change.phase, status: ctx.change.status, blocker: ctx.change.blocker }, next: outcome.next }, (d) => [`Запуск ${d.runId}: статус роли «${d.status}», ${d.accepted ? (d.phaseCompleted ? 'фаза завершена' : 'фаза не завершена') : 'отчёт не принят'}`, formatDiagnostics(d.diagnostics), `Изменение: фаза ${d.change.phase}, статус ${d.change.status}`, `Дальше: ${JSON.stringify(d.next)}`].join('\n'));
91
+ if (rejected)
92
+ process.exitCode = 1;
93
+ }
94
+ catch (e) {
95
+ emitError(g, e);
96
+ process.exitCode = 1;
97
+ }
98
+ });
99
+ program
100
+ .command('approve <gate>')
101
+ .description('Утвердить гейт (proposal | plan | tests)')
102
+ .option('--change <id>')
103
+ .option('--by <user>', 'кто утвердил', process.env.USER ?? 'human')
104
+ .option('--comment <text>')
105
+ .option('--answer <pairs...>', 'ответы на вопросы: Q1=B Q2=A')
106
+ .action((gate, opts, cmd) => {
107
+ const g = cmd.optsWithGlobals();
108
+ try {
109
+ const ctx = changeContext(g.cwd, opts.change);
110
+ assertGate(gate);
111
+ const answers = Object.fromEntries((opts.answer ?? []).map((p) => { const [k, ...v] = p.split('='); return [k, v.join('=')]; }));
112
+ approveGate(ctx.change, gate, opts.by, opts.comment, Object.keys(answers).length ? answers : undefined);
113
+ saveChange(ctx.dir, ctx.change);
114
+ emit(g, { gate, phase: ctx.change.phase, status: ctx.change.status, next: nextStep(ctx.change, ctx.config) }, (d) => `Гейт ${d.gate} утверждён. Фаза ${d.phase}, статус ${d.status}.`);
115
+ }
116
+ catch (e) {
117
+ emitError(g, e);
118
+ process.exitCode = 1;
119
+ }
120
+ });
121
+ program
122
+ .command('reject <gate>')
123
+ .description('Отклонить гейт с замечанием')
124
+ .option('--change <id>')
125
+ .option('--by <user>', 'кто отклонил', process.env.USER ?? 'human')
126
+ .requiredOption('--comment <text>', 'замечание для планировщика или тестировщика')
127
+ .action((gate, opts, cmd) => {
128
+ const g = cmd.optsWithGlobals();
129
+ try {
130
+ const ctx = changeContext(g.cwd, opts.change);
131
+ assertGate(gate);
132
+ rejectGate(ctx.change, gate, opts.by, opts.comment);
133
+ saveChange(ctx.dir, ctx.change);
134
+ emit(g, { gate, phase: ctx.change.phase, status: ctx.change.status, next: nextStep(ctx.change, ctx.config) }, (d) => `Гейт ${d.gate} отклонён. Возврат в фазу ${d.phase}.`);
135
+ }
136
+ catch (e) {
137
+ emitError(g, e);
138
+ process.exitCode = 1;
139
+ }
140
+ });
141
+ }
142
+ function assertGate(gate) {
143
+ if (!GATES.includes(gate))
144
+ throw new SboxError('BAD_GATE', `Неизвестный гейт ${gate}; допустимы: ${GATES.join(', ')}`);
145
+ }
146
+ function pendingQuestions(change) {
147
+ // Вопросы planner лежат в его последнем ответе; для человека их достаточно показать ссылкой на design.md.
148
+ return [];
149
+ }
150
+ export { fs };
151
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/cli/commands/protocol.ts"],"names":[],"mappings":"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"}