dsh-desktop-kit 2.2.1 → 2.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +114 -27
  3. package/client.js +3270 -32
  4. package/docs/AGENT-HARNESS.md +144 -0
  5. package/docs/ARCHITECTURE.md +38 -7
  6. package/docs/COMPATIBILITY.md +4 -2
  7. package/docs/DEVELOPMENT.md +56 -0
  8. package/docs/INSTALL.md +20 -11
  9. package/docs/LAPTOP-INSTALL.md +96 -0
  10. package/docs/ROADMAP-3.0.md +353 -0
  11. package/docs/ROADMAP.md +1 -1
  12. package/docs/SUBAGENTS.md +25 -0
  13. package/docs/TEST-0.2.2.md +5 -5
  14. package/docs/TEST-2.3.0.md +49 -0
  15. package/docs/TEST-2.7.2.md +46 -0
  16. package/docs/TEST-2.7.3.md +20 -0
  17. package/docs/TOKENS.md +2 -2
  18. package/docs/TROUBLESHOOTING.md +27 -0
  19. package/docs/UI-QA.md +28 -0
  20. package/docs/images/peak-toast-peak.png +0 -0
  21. package/docs/images/peak-toast-soon.png +0 -0
  22. package/docs/preview/peak-toast.html +155 -0
  23. package/index.js +18 -1
  24. package/package.json +26 -6
  25. package/plugins/dsh-agent-extensions/README.md +107 -0
  26. package/plugins/dsh-agent-extensions/client.js +157 -0
  27. package/plugins/dsh-agent-extensions/index.js +174 -0
  28. package/plugins/dsh-agent-extensions/lib/agents.js +76 -0
  29. package/plugins/dsh-agent-extensions/lib/api.js +53 -0
  30. package/plugins/dsh-agent-extensions/lib/checkpoints.js +103 -0
  31. package/plugins/dsh-agent-extensions/lib/commands.js +255 -0
  32. package/plugins/dsh-agent-extensions/lib/hooks.js +182 -0
  33. package/plugins/dsh-agent-extensions/lib/policy.js +84 -0
  34. package/plugins/dsh-agent-extensions/lib/project.js +144 -0
  35. package/plugins/dsh-agent-extensions/lib/scaffold.js +151 -0
  36. package/plugins/dsh-agent-extensions/package.json +20 -0
  37. package/plugins/dsh-agent-extensions/screenshots/agents-1440.png +0 -0
  38. package/plugins/dsh-agent-extensions/screenshots/agents-390.png +0 -0
  39. package/plugins/dsh-browser-qa/README.md +221 -0
  40. package/plugins/dsh-browser-qa/cordis.patch.yml +4 -0
  41. package/plugins/dsh-browser-qa/index.js +165 -0
  42. package/plugins/dsh-browser-qa/lib/cdp.js +224 -0
  43. package/plugins/dsh-browser-qa/lib/chrome.js +466 -0
  44. package/plugins/dsh-browser-qa/lib/pages.js +552 -0
  45. package/plugins/dsh-browser-qa/lib/qa.js +827 -0
  46. package/plugins/dsh-browser-qa/lib/ui-gate.js +256 -0
  47. package/plugins/dsh-browser-qa/package.json +31 -0
  48. package/plugins/dsh-checkpoints/README.md +22 -0
  49. package/plugins/dsh-checkpoints/cordis.patch.yml +3 -0
  50. package/plugins/dsh-checkpoints/index.js +80 -0
  51. package/plugins/dsh-checkpoints/lib/checkpoints.js +111 -0
  52. package/plugins/dsh-checkpoints/package.json +25 -0
  53. package/plugins/dsh-github-review/README.md +131 -0
  54. package/plugins/dsh-github-review/cordis.patch.yml +3 -0
  55. package/plugins/dsh-github-review/index.js +536 -0
  56. package/plugins/dsh-github-review/lib/gh.js +494 -0
  57. package/plugins/dsh-github-review/lib/normalize.js +662 -0
  58. package/plugins/dsh-github-review/package.json +28 -0
  59. package/plugins/dsh-guardrails/README.md +264 -0
  60. package/plugins/dsh-guardrails/cordis.patch.yml +5 -0
  61. package/plugins/dsh-guardrails/index.js +389 -0
  62. package/plugins/dsh-guardrails/lib/hooks.js +262 -0
  63. package/plugins/dsh-guardrails/lib/modes.js +77 -0
  64. package/plugins/dsh-guardrails/lib/policy.js +592 -0
  65. package/plugins/dsh-guardrails/lib/scan.js +451 -0
  66. package/plugins/dsh-guardrails/lib/secrets.js +274 -0
  67. package/plugins/dsh-guardrails/package.json +26 -0
  68. package/plugins/dsh-mcp-manager/README.md +78 -0
  69. package/plugins/dsh-mcp-manager/client.js +373 -0
  70. package/plugins/dsh-mcp-manager/index.js +159 -0
  71. package/plugins/dsh-mcp-manager/lib/api.js +250 -0
  72. package/plugins/dsh-mcp-manager/lib/client.js +219 -0
  73. package/plugins/dsh-mcp-manager/lib/config.js +217 -0
  74. package/plugins/dsh-mcp-manager/lib/manager.js +146 -0
  75. package/plugins/dsh-mcp-manager/package.json +18 -0
  76. package/plugins/dsh-mcp-manager/screenshots/modal-390.png +0 -0
  77. package/plugins/dsh-mcp-manager/screenshots/settings-1440.png +0 -0
  78. package/plugins/dsh-mcp-manager/screenshots/settings-390.png +0 -0
  79. package/plugins/dsh-memory-bridge/README.md +161 -0
  80. package/plugins/dsh-memory-bridge/client.js +2264 -0
  81. package/plugins/dsh-memory-bridge/cordis.patch.yml +5 -0
  82. package/plugins/dsh-memory-bridge/docs/images/conflicts.png +0 -0
  83. package/plugins/dsh-memory-bridge/docs/images/hero.png +0 -0
  84. package/plugins/dsh-memory-bridge/docs/images/settings-dark.png +0 -0
  85. package/plugins/dsh-memory-bridge/docs/images/settings-light.png +0 -0
  86. package/plugins/dsh-memory-bridge/docs/images/settings-mobile.png +0 -0
  87. package/plugins/dsh-memory-bridge/docs/images/setup.png +0 -0
  88. package/plugins/dsh-memory-bridge/icon.svg +13 -0
  89. package/plugins/dsh-memory-bridge/index.js +378 -0
  90. package/plugins/dsh-memory-bridge/lib/bridge.js +636 -0
  91. package/plugins/dsh-memory-bridge/lib/github.js +473 -0
  92. package/plugins/dsh-memory-bridge/lib/merge.js +205 -0
  93. package/plugins/dsh-memory-bridge/lib/portable.js +314 -0
  94. package/plugins/dsh-memory-bridge/lib/state.js +565 -0
  95. package/plugins/dsh-memory-bridge/lib/sync.js +984 -0
  96. package/plugins/dsh-memory-bridge/locale/en.json +6 -0
  97. package/plugins/dsh-memory-bridge/locale/ru.json +6 -0
  98. package/plugins/dsh-memory-bridge/package.json +67 -0
  99. package/plugins/dsh-peak-guard/README.md +16 -3
  100. package/plugins/dsh-peak-guard/client.js +223 -8
  101. package/plugins/dsh-peak-guard/package.json +1 -1
  102. package/plugins/dsh-plan-mode/README.md +24 -0
  103. package/plugins/dsh-plan-mode/cordis.patch.yml +3 -0
  104. package/plugins/dsh-plan-mode/index.js +103 -0
  105. package/plugins/dsh-plan-mode/lib/plan.js +89 -0
  106. package/plugins/dsh-plan-mode/package.json +18 -0
  107. package/plugins/dsh-profile-transfer/client.js +277 -17
  108. package/plugins/dsh-profile-transfer/index.js +10 -0
  109. package/plugins/dsh-profile-transfer/package.json +3 -1
  110. package/plugins/dsh-profile-transfer/transfer.js +101 -2
  111. package/plugins/dsh-project-memory/index.js +92 -2
  112. package/plugins/dsh-project-memory/package.json +1 -1
  113. package/plugins/dsh-repo-map/README.md +26 -0
  114. package/plugins/dsh-repo-map/cordis.patch.yml +3 -0
  115. package/plugins/dsh-repo-map/index.js +99 -0
  116. package/plugins/dsh-repo-map/lib/repo-map.js +170 -0
  117. package/plugins/dsh-repo-map/package.json +25 -0
  118. package/plugins/dsh-skill-autopilot/index.js +135 -11
  119. package/skills/delivery-gate/SKILL.md +31 -0
  120. package/skills/git-and-ci/SKILL.md +5 -1
  121. package/skills/manifest.json +31 -6
  122. package/skills/requirements-and-planning/SKILL.md +3 -0
  123. package/skills/research-first/SKILL.md +35 -0
  124. package/skills/research-first/references/query-patterns.md +20 -0
  125. package/skills/subagent-playbook/SKILL.md +36 -0
  126. package/skills/subagent-playbook/references/prompts.md +39 -0
  127. package/skills/ui-craft/SKILL.md +43 -0
  128. package/skills/visual-qa/SKILL.md +29 -0
  129. package/skills/visual-qa/references/commands.md +32 -0
  130. package/skills-baseline.json +219 -0
@@ -21,8 +21,17 @@ import path from "node:path";
21
21
  export const inject = ["systemPrompt"];
22
22
 
23
23
  const STATE_FILE = "dsh-autopilot.json";
24
- const MAX_HINT_TOKENS = 140;
24
+ const MAX_HINT_TOKENS = 300;
25
25
  const SKILL_CACHE_MS = 60_000;
26
+ const AUTO_LOAD_MAX_BYTES = 4200;
27
+ const AUTO_LOAD_MAX_SKILLS = 2;
28
+ const PROJECT_RULES_MAX_BYTES = 2500;
29
+ const QUALITY_CONTRACT = [
30
+ "<quality-contract>",
31
+ "Работай как топовый агент: 1) факты, версии, цены и практики — только после web_search/web_fetch; 2) дай 2+ независимых источника, дату и ссылки; 3) для рекомендаций предложи 2–3 конкретных референса/варианта и объясни выбор; 4) UI: до правок — wow-design/ui-craft, после — browser_qa audit 390/768/1440, исправь overflow, console errors и markup (alt, labels, duplicate id, heading order), приложи скриншоты; 5) код — repo_map/checkpoint/план/тесты; 6) не заявляй «готово» без проверки; если проверить нельзя — скажи честно.",
32
+ "</quality-contract>",
33
+ ].join("\n");
34
+ let skillMetaCache = { at: 0, map: new Map() };
26
35
 
27
36
  /* ------------------------------------------------------------------ */
28
37
  /* intent rules */
@@ -38,8 +47,32 @@ const RULES = [
38
47
  id: "ui",
39
48
  label: "UI/дизайн",
40
49
  any: ["вёрстк", "верстк", "дизайн", "интерфейс", " ui ", "ux", "лендинг", "страниц", "компонент", "адаптив", "css", "tailwind", "макет", "красив", "темн", "светл", "кнопк", "форм"],
41
- skills: ["wow-design", "ui-design-system"],
42
- follow: { any: ["критик", "аудит", "оцен", "улучш", "передела"], skills: ["design-critique"] },
50
+ skills: ["wow-design", "ui-design-system", "ui-craft"],
51
+ follow: { any: ["критик", "аудит", "оцен", "улучш", "передела", "скриншот", "отступ", "мобил", "планшет", "overflow", "горизонт"], skills: ["design-critique", "visual-qa"] },
52
+ },
53
+ {
54
+ id: "quality",
55
+ label: "Качество UI",
56
+ any: ["отступ", "адаптив", "горизонт", "overflow", "скриншот", "мобил", "планшет", "поехал", "съехал", "вёрстк", "верстк"],
57
+ skills: ["ui-craft", "visual-qa"],
58
+ },
59
+ {
60
+ id: "markup",
61
+ label: "Разметка и доступность",
62
+ any: ["разметк", "html", "валид", "alt", "aria", "a11y", "доступн", "семант", "label", "заголовк"],
63
+ skills: ["ui-craft", "visual-qa"],
64
+ },
65
+ {
66
+ id: "subagents",
67
+ label: "Субагенты",
68
+ any: ["субагент", "subagent", "команда агентов", "параллельн", "ревьюер", "независимый аудит"],
69
+ skills: ["subagent-playbook"],
70
+ },
71
+ {
72
+ id: "orchestrate",
73
+ label: "Оркестрация",
74
+ any: ["весь проект", "все плагины", "комплексн", "рефакторинг", "архитектур", "оркестр", "workflow", "несколько задач", "параллельн", "релиз всего", "сложн"],
75
+ skills: ["subagent-playbook", "requirements-and-planning", "delivery-gate"],
43
76
  },
44
77
  {
45
78
  id: "seo",
@@ -57,14 +90,15 @@ const RULES = [
57
90
  {
58
91
  id: "research",
59
92
  label: "Актуальные факты",
60
- any: ["актуал", "новост", "цена", "курс", "верси", "закон", "документац", "сравни", "найди в интернете", "последн", "сегодня", "2026", "рынок"],
61
- skills: ["web-research"],
93
+ any: ["актуал", "новост", "цена", "курс", "верси", "закон", "документац", "сравни", "найди в интернете", "последн", "сегодня", "2026", "рынок", "лучшие практики", "best practice"],
94
+ skills: ["web-research", "research-first"],
62
95
  },
63
96
  {
64
97
  id: "plan",
65
98
  label: "Планирование",
66
99
  any: ["план", "тз", "требован", "декомпоз", "оцен", "архитектур", "вариант", "исследован", "предложи", "концепц"],
67
100
  skills: ["requirements-and-planning", "dev-workflow"],
101
+ follow: { any: ["субагент", "параллельн", "ревьюер"], skills: ["subagent-playbook"] },
68
102
  },
69
103
  {
70
104
  id: "debug",
@@ -207,6 +241,90 @@ function loadSkillCosts() {
207
241
  return map;
208
242
  }
209
243
 
244
+ /**
245
+ * Read SKILL.md metadata + body lazily. `autoLoad: true` in frontmatter lets the
246
+ * autopilot inject the core instructions instead of only naming the skill.
247
+ */
248
+ function loadSkillMeta(name) {
249
+ const now = Date.now();
250
+ if (now - skillMetaCache.at > SKILL_CACHE_MS) skillMetaCache = { at: now, map: new Map() };
251
+ if (skillMetaCache.map.has(name)) return skillMetaCache.map.get(name);
252
+ const file = path.join(dshHome(), "skills", name, "SKILL.md");
253
+ let meta = null;
254
+ try {
255
+ const text = fs.readFileSync(file, "utf8");
256
+ const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/u);
257
+ const front = match ? match[1] : "";
258
+ const autoLoad = /^autoLoad:\s*true\s*$/mu.test(front);
259
+ const body = (match ? text.slice(match[0].length) : text).trim();
260
+ meta = { autoLoad, body, bytes: Buffer.byteLength(body, "utf8") };
261
+ } catch {
262
+ meta = null;
263
+ }
264
+ skillMetaCache.map.set(name, meta);
265
+ return meta;
266
+ }
267
+
268
+ function loadAutoSkills(names) {
269
+ const blocks = [];
270
+ let used = 0;
271
+ for (const name of names) {
272
+ if (blocks.length >= AUTO_LOAD_MAX_SKILLS) break;
273
+ if (used >= AUTO_LOAD_MAX_BYTES) break;
274
+ const meta = loadSkillMeta(name);
275
+ if (!meta || !meta.autoLoad || meta.body.length === 0) continue;
276
+ const remaining = AUTO_LOAD_MAX_BYTES - used;
277
+ let body = meta.body;
278
+ if (Buffer.byteLength(body, "utf8") > remaining) {
279
+ body = body.slice(0, Math.max(0, remaining - 200)).trimEnd() + "\n…";
280
+ }
281
+ if (body.length === 0) continue;
282
+ blocks.push(`<auto-skill name="${name}">\n${body}\n</auto-skill>`);
283
+ used += Buffer.byteLength(body, "utf8");
284
+ }
285
+ return blocks;
286
+ }
287
+
288
+ /**
289
+ * Project rules: <cwd>/.dsh/rules/*.md. Rules with `always: true` or without
290
+ * `paths` are injected on every prompt; path-scoped rules are left for a
291
+ * future file-aware loader to avoid leaking irrelevant instructions.
292
+ */
293
+ function loadProjectRules(session) {
294
+ const cwd = typeof session?.header?.cwd === "string" ? session.header.cwd : "";
295
+ if (cwd.length === 0) return "";
296
+ const directory = path.join(cwd, ".dsh", "rules");
297
+ let entries = [];
298
+ try {
299
+ entries = fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md"));
300
+ } catch {
301
+ return "";
302
+ }
303
+ const blocks = [];
304
+ let used = 0;
305
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
306
+ try {
307
+ const text = fs.readFileSync(path.join(directory, entry.name), "utf8");
308
+ const front = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/u);
309
+ const metadata = front ? front[1] : "";
310
+ const hasPaths = /^paths\s*:/mu.test(metadata);
311
+ const always = /^always:\s*true\s*$/mu.test(metadata);
312
+ if (hasPaths && !always) continue;
313
+ const body = (front ? text.slice(front[0].length) : text).trim();
314
+ if (body.length === 0) continue;
315
+ const remaining = PROJECT_RULES_MAX_BYTES - used;
316
+ if (remaining <= 0) break;
317
+ const clipped = body.length > remaining ? `${body.slice(0, Math.max(0, remaining - 120)).trimEnd()}\n…` : body;
318
+ blocks.push(`### ${entry.name}\n${clipped}`);
319
+ used += Buffer.byteLength(clipped, "utf8");
320
+ } catch {
321
+ /* unreadable rule */
322
+ }
323
+ }
324
+ if (blocks.length === 0) return "";
325
+ return `<project-rules>\n${blocks.join("\n\n")}\n</project-rules>`;
326
+ }
327
+
210
328
  /** The latest durable user message of a session, read from the surface tail. */
211
329
  const lastMessageCache = new Map();
212
330
  function latestUserMessage(session) {
@@ -287,16 +405,18 @@ export function routeMessage(rawText, available = loadSkillCosts(), maxSkills =
287
405
  /* Prefer skills from the most specific (later, rarer) rules? Keep rule order:
288
406
  * it is ordered from the most common task families to the narrow ones. */
289
407
  const ordered = [];
408
+ const allNames = [];
290
409
  const seen = new Set();
291
410
  for (const hit of hits) {
292
411
  for (const name of hit.names) {
293
412
  if (seen.has(name) || !available.has(name)) continue;
294
413
  seen.add(name);
414
+ allNames.push(name);
295
415
  ordered.push({ name, tokens: available.get(name) });
296
416
  }
297
417
  }
298
418
  const skills = ordered.sort((left, right) => (right.tokens || 0) - (left.tokens || 0)).slice(0, maxSkills);
299
- return { intents: hits.map((hit) => hit.label), skills };
419
+ return { intents: hits.map((hit) => hit.label), skills, allSkills: allNames };
300
420
  }
301
421
 
302
422
  function renderHint(route) {
@@ -427,9 +547,12 @@ export function apply(ctx) {
427
547
  const message = latestUserMessage(session);
428
548
  if (!message) return "";
429
549
  const route = routeMessage(message.text, loadSkillCosts(), readState().maxSkills);
430
- if (route.skills.length === 0) return "";
431
- const hint = renderHint(route);
432
- if (hint.length > MAX_HINT_TOKENS * 4) return "";
550
+ const hint = route.skills.length > 0 ? renderHint(route) : "";
551
+ const autoSkills = loadAutoSkills(route.allSkills ?? []);
552
+ const autoBlock = autoSkills.length > 0 ? `<auto-skills>\n${autoSkills.join("\n")}\n</auto-skills>` : "";
553
+ const rules = loadProjectRules(session);
554
+ const value = [QUALITY_CONTRACT, rules, autoBlock, hint].filter((part) => part.length > 0).join("\n");
555
+ if (route.skills.length === 0) return value;
433
556
  const now = Date.now();
434
557
  lastHintAt = now;
435
558
  lastMatches.set(String(session.id), {
@@ -437,13 +560,13 @@ export function apply(ctx) {
437
560
  at: new Date(now).toISOString(),
438
561
  intents: route.intents,
439
562
  skills: route.skills,
440
- chars: hint.length,
563
+ chars: value.length,
441
564
  });
442
565
  if (lastMatches.size > 40) {
443
566
  const oldest = [...lastMatches.entries()].sort((a, b) => a[1].at.localeCompare(b[1].at))[0];
444
567
  if (oldest) lastMatches.delete(oldest[0]);
445
568
  }
446
- return hint;
569
+ return value;
447
570
  } catch (error) {
448
571
  logger?.warn?.(`[skill-autopilot] route failed: ${String(error)}`);
449
572
  return "";
@@ -459,3 +582,4 @@ export function apply(ctx) {
459
582
  };
460
583
  }, "skill-autopilot: lifecycle");
461
584
  }
585
+
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: delivery-gate
3
+ description: "Финальный гейт перед сдачей: критерии, тесты, скриншоты, безопасность, источники, отсутствие дублей. Не отдавать результат без проверки."
4
+ whenToUse: "Перед финальным ответом, релизом, публикацией, PR или после крупной правки."
5
+ user-invocable: true
6
+ autoLoad: true
7
+ ---
8
+
9
+ # Delivery Gate — сдавать только проверенное
10
+
11
+ > ≈350 токенов. Короткий чек-лист; детали — `code-review-checklist`, `testing-strategy`, `visual-qa`.
12
+
13
+ ## 1. Чек-лист
14
+ - [ ] Требование и критерий «готово» сформулированы до кода.
15
+ - [ ] `plan` согласован для крупной задачи; код не начат до approve.
16
+ - [ ] Тесты/проверки прошли; нет скрытых падений и «пока не проверял».
17
+ - [ ] UI: `browser_qa action=audit` на 1440/768/390, light/dark, нет overflow и обрезаний.
18
+ - [ ] `guardrails action=check` перед коммитом: секреты, `.env`, защищённые пути, `git diff --check`.
19
+ - [ ] Безопасность: нет секретов, публичных данных, опасных дефолтов.
20
+ - [ ] Нет дублей: один сценарий = одно место/один источник правды.
21
+ - [ ] Внешние факты — со ссылками и датами.
22
+ - [ ] Отчёт: что сделано, как проверено, риски, что дальше.
23
+
24
+ ## 2. Красные флаги
25
+ - «Должно работать» без запуска; скриншот без просмотра; источник без ссылки.
26
+ - Два экрана делают одно и то же; новый компонент копирует старый вместо переиспользования.
27
+ - Фикс без регрессионного теста/проверки, миграция без бэкапа, публикация без checksum.
28
+
29
+ ## 3. Формат отчёта
30
+ Короткий итог → проверки (команды/скриншоты) → коммиты/артефакты → ограничения → следующий шаг.
31
+
@@ -8,6 +8,7 @@ user-invocable: true
8
8
  # Git и CI (универсально)
9
9
 
10
10
  ## 0. Когда применять
11
+ - В DSH для PR используй `github_review` (status/pr/checks/comments/diff); comment — только с confirm.
11
12
  - Создаёшь репозиторий, `.gitignore`, первый коммит.
12
13
  - Коммитишь, ветвишься, мержишь, ставишь тег.
13
14
  - Настраиваешь/чинишь CI или pre-commit.
@@ -18,7 +19,8 @@ user-invocable: true
18
19
  **Репозиторий**
19
20
  - `.gitignore` до первого коммита: зависимости, сборки, `.env*`, runtime, IDE, дампы; lock-файлы — в git.
20
21
  - Перед коммитом: `git status --short`, `git diff --check`, `git diff --stat`; в индекс — только осознанные файлы.
21
- - Не коммитить: `vendor/`, `node_modules/`, `public/build`, `storage/`-рантайм, дампы, PII.
22
+ - Не коммитить: `vendor/`,
23
+ ode_modules/`, `public/build`, `storage/`-рантайм, дампы, PII.
22
24
 
23
25
  **Ветки и коммиты**
24
26
  - `main` — стабильная и защищённая; работа — в `feature/<кратко>` / `fix/<кратко>`.
@@ -58,3 +60,5 @@ CI гоняет те же команды, что локально; `main` — т
58
60
  - [ ] Линтер, статанализ, тесты зелёные; для UI — E2E.
59
61
  - [ ] Тег на проверенном коммите; CI на `main` зелёный.
60
62
  - [ ] Секрет ротирован, история очищена.
63
+
64
+
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": 1,
3
- "kitVersion": "2.2.1",
4
- "generatedAt": "2026-11-06T12:03:12.122Z",
3
+ "kitVersion": "2.7.2",
4
+ "generatedAt": "2026-11-10T05:35:22.614Z",
5
5
  "skills": {
6
6
  "code-review-checklist": {
7
7
  "hash": "e665bf72cfbfb77948a3cd6df6ebced38777f9aff543d7b9c80b2ced8cccc662",
@@ -28,6 +28,11 @@
28
28
  "files": 1,
29
29
  "bytes": 4443
30
30
  },
31
+ "delivery-gate": {
32
+ "hash": "7b76909a8d5ce099d03813533a1f935aef62d8fe11e63080961c38fd9835e47f",
33
+ "files": 1,
34
+ "bytes": 2409
35
+ },
31
36
  "design-critique": {
32
37
  "hash": "bbc6ca34b0b76798d581dcd78e83a59040dfac028b5e10d8e7a9be28225410b8",
33
38
  "files": 6,
@@ -39,9 +44,9 @@
39
44
  "bytes": 17194
40
45
  },
41
46
  "git-and-ci": {
42
- "hash": "0681041edb935da2c124265bbdacd3b6a0a96c7f163323960cff8c8ea67fd2f4",
47
+ "hash": "a2dc59c5920190bbc715a4a523f3a1592e1914e6d06385ec07341fb76897a6b6",
43
48
  "files": 1,
44
- "bytes": 4192
49
+ "bytes": 4318
45
50
  },
46
51
  "pg-upgrade-verify": {
47
52
  "hash": "d734178c5dad317fc55842215bbeeba85230cdd8e7b0ea46d74eed92910b8dea",
@@ -64,9 +69,14 @@
64
69
  "bytes": 4409
65
70
  },
66
71
  "requirements-and-planning": {
67
- "hash": "532cbccfb2d0f7eca06343927aba100bd653145ccd9b9173ca50299194631a05",
72
+ "hash": "16f3235a9dcdcd1858112806854ef03d76f77588b56434bbacab803bd204f005",
68
73
  "files": 4,
69
- "bytes": 12964
74
+ "bytes": 13078
75
+ },
76
+ "research-first": {
77
+ "hash": "3a18814f9817a6843962c1c5bdd7c5c0bc535cf864a5039d5e3ac359990579a4",
78
+ "files": 2,
79
+ "bytes": 4273
70
80
  },
71
81
  "security-review": {
72
82
  "hash": "8665b2c469de8e83aca670021d5c335fa8c9b93b8dc6bb866759e6062b1abde4",
@@ -108,16 +118,31 @@
108
118
  "files": 3,
109
119
  "bytes": 13888
110
120
  },
121
+ "subagent-playbook": {
122
+ "hash": "72d10995462d43891e7ec2d028caa0ccbca7932875410d4a0d6cfa75c5fe2df9",
123
+ "files": 2,
124
+ "bytes": 5375
125
+ },
111
126
  "testing-strategy": {
112
127
  "hash": "773fdf1e389e59841b7766862f8890a11fba4a2fce42a2022b9c4bfaae8f6ecc",
113
128
  "files": 1,
114
129
  "bytes": 4279
115
130
  },
131
+ "ui-craft": {
132
+ "hash": "0fbca80ca2ca434828b3238ecd901fce54b5dc306456cb81a4ed52f7a95921c5",
133
+ "files": 1,
134
+ "bytes": 3387
135
+ },
116
136
  "ui-design-system": {
117
137
  "hash": "19244221171995b758dbad02f2e3602859308370b50cc37d93c6f2a6d44cd6f1",
118
138
  "files": 4,
119
139
  "bytes": 19454
120
140
  },
141
+ "visual-qa": {
142
+ "hash": "97ff6c9c02bbab4bb38c8591a39792f4f51c45bfe278dd7ea839d6cad27c7cf9",
143
+ "files": 2,
144
+ "bytes": 4118
145
+ },
121
146
  "web-research": {
122
147
  "hash": "9bf4d8ba6d2a0fc39c241cdd9f5fe54835af28872473aa617941589c526387c8",
123
148
  "files": 3,
@@ -9,6 +9,7 @@ user-invocable: true
9
9
  > ≈1 600 токенов. Это ядро; детали — по ссылкам и только когда реально нужны.
10
10
 
11
11
  ## 0. Когда применять
12
+ - В DSH крупную задачу веди через `plan` (`.dsh/PLAN.md`): draft → approve → код.
12
13
  - Новая задача: фича, страница, релиз, миграция — до первой правки.
13
14
  - Запрос расплывчат: «сделай красиво», «ускорь», «почини», «улучши как-то».
14
15
  - Нужны ТЗ, оценка, сравнение вариантов, критерии «готово»; результат — выводы и план, а не осмотр.
@@ -47,3 +48,5 @@ user-invocable: true
47
48
  - [ ] План с проверками и откатом выполнен; scope не расширен молча, «потом» вынесено.
48
49
  - [ ] Подобраны скиллы (`skills-router`), пройдены их гейты: тесты/скриншоты/SEO/бэкап.
49
50
  - [ ] Отчёт «сделано / как проверено / риски / дальше»; память и версия обновлены.
51
+
52
+
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: research-first
3
+ description: "Перед задачей проверить интернет, собрать факты и лучшие практики, сравнить 2–3 варианта и только потом делать. Ссылки, даты, источник — обязательны."
4
+ whenToUse: "Почти любая задача, где есть версии, API, цены, законы, конкуренты, дизайн-референсы, «как правильно», «лучшие практики», новые технологии или риск устаревших знаний."
5
+ user-invocable: true
6
+ autoLoad: true
7
+ ---
8
+
9
+ # Research-first — сначала факты и варианты, потом код
10
+
11
+ > ≈600 токенов. Ядро; глубина — по `references/`.
12
+
13
+ ## 1. Когда поиск обязателен (по умолчанию — почти всегда)
14
+ - Версии, API, библиотеки, плагины, цены, тарифы, законы, даты, релизы.
15
+ - «Лучшие практики», архитектура, дизайн, UX, безопасность, релиз.
16
+ - Есть риск, что знания модели устарели или это спорный факт.
17
+ - Не ищи только если задача чисто локальная и проверяемая кодом/файлом.
18
+
19
+ ## 2. Протокол (до реализации)
20
+ 1. **2–4 запроса**: русский + английский, официальные термины, `site:` для docs.
21
+ 2. **2–3 независимых источника**, приоритет: официальная документация → первоисточник/paper → крупный инженерный блог. Маркетинг — только как мнение.
22
+ 3. **Открой ключевые страницы** (`web_fetch`), не ограничивайся сниппетами.
23
+ 4. Зафиксируй: дата поиска, версия/дата источника, расхождения.
24
+ 5. Сделай **матрицу вариантов**: 2–3 подхода, плюсы, минусы, риски, стоимость, рекомендация. Для мелкой задачи — 3 строки, не эссе.
25
+ 6. Только после этого — план и код. Ссылки — в ответе и в отчёте.
26
+
27
+ ## 3. Проверка качества
28
+ - Нет ссылки — нет утверждения о внешнем факте.
29
+ - Не выдавай пересказ за первоисточник; платный/закрытый источник помечай.
30
+ - Не используй данные старше ~12 месяцев без пометки (кроме исторических).
31
+ - Если поиск не дал ответа — скажи прямо и предложи, что уточнить.
32
+
33
+ ## 4. Выход
34
+ Короткий вывод (1–3 предложения) → факты с датами → матрица вариантов → рекомендация → источники.
35
+
@@ -0,0 +1,20 @@
1
+ # Query patterns
2
+
3
+ ## Свежесть
4
+ - Версии/API: `site:docs.<project> <api> <year>`, `release notes <project>`
5
+ - Цены/тарифы: `<vendor> pricing <year>`, официальная страница
6
+ - Законы: `site:gov.ru <тема>`, официальный документ
7
+ - Дизайн: `site:dribbble.com <pattern>`, `site:mobbin.com <pattern>`, `site:linear.app changelog`
8
+
9
+ ## Источники
10
+ 1. Официальная документация / спецификация / changelog.
11
+ 2. Первоисточник (paper, RFC, закон, датасет).
12
+ 3. Инженерный блог/конференция с деталями реализации.
13
+ 4. Маркетинг/обзор — только как мнение, не как факт.
14
+
15
+ ## Матрица вариантов
16
+ | Вариант | Плюсы | Минусы | Риск | Стоимость | Рекомендация |
17
+ |---|---|---|---|---|---|
18
+
19
+ ## Пометки
20
+ Актуально на: YYYY-MM-DD. Источник: URL (дата публикации). Если данные устарели — скажи явно.
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: subagent-playbook
3
+ description: "Когда и как привлекать субагентов: research-scout, ui-critic, responsive-qa, release-auditor, code-reviewer. Готовые промпты и разделение ролей."
4
+ whenToUse: "Сложная задача, много файлов, нужен независимый аудит/ресёрч/визуальная критика/релизная проверка, или параллельная работа без общего контекста."
5
+ user-invocable: true
6
+ autoLoad: true
7
+ ---
8
+
9
+ # Subagent Playbook — роли, которые усиливают
10
+
11
+ > ≈550 токенов. Промпты — `references/prompts.md`.
12
+
13
+ ## 1. Когда spawn
14
+ - Задача > ~1 часа или затрагивает несколько областей (дизайн + код + релиз).
15
+ - Нужен свежий взгляд: критика UI, security/release аудит, независимый факт-чек.
16
+ - Исследование, которое не должно съедать основной контекст.
17
+ - Если независимых потоков ≥3 — сначала план, затем `workflow`; 1–2 роли — обычный `subagent`.
18
+ - Не spawn ради количества: 1–2 роли на задачу, с чётким deliverable.
19
+
20
+ ## 2. Роли
21
+ | Роль | Что делает | Выход |
22
+ |---|---|---|
23
+ | **research-scout** | 2–4 запроса, официальные источники, даты, варианты | матрица + ссылки |
24
+ | **ui-critic** | скриншоты 1440/768/390, иерархия, отступы, состояния | 5–7 приоритетных правок |
25
+ | **responsive-qa** | overflow, переносы, тач-цели, safe-area | список багов + доказательства |
26
+ | **release-auditor** | тесты, версии, changelog, security, откат | go/no-go |
27
+ | **code-reviewer** | диффы, риски, тесты, совместимость | блокеры/ниты |
28
+
29
+ ## 3. Как формулировать
30
+ - Дай контекст, файлы/URL, ограничения, формат результата и критерий «готово».
31
+ - Запрети менять чужие файлы, если роль только читает.
32
+ - Проси ссылки/скриншоты/логи, а не мнение без доказательств.
33
+ - Результаты своди в решение сам: субагент советует, Lead отвечает за итог.
34
+
35
+ ## 4. Параллельность
36
+ Независимые роли (research + UI review) запускай одним сообщением; зависимости — через `wait_agent`/задачи. Не дублируй одну и ту же работу двумя ролями.
@@ -0,0 +1,39 @@
1
+ # Subagent prompt templates
2
+
3
+ ## research-scout
4
+ ```
5
+ Ты research-scout. Собери актуальные факты по теме: <тема>.
6
+ Сделай 2–4 запроса (RU/EN), приоритет официальной документации и первоисточникам.
7
+ Сверь ≥2 независимых источника. Для каждого факта: утверждение, источник (URL), дата,
8
+ расхождение/ограничение. В конце — матрица 2–3 вариантов решения (плюсы/минусы/риски) и
9
+ рекомендация. Не пиши код и не меняй файлы. Верни только выжимку + ссылки.
10
+ ```
11
+
12
+ ## ui-critic
13
+ ```
14
+ Ты ui-critic. Оцени интерфейс по скриншотам <пути/URL> на 1440/768/390.
15
+ Критерии: иерархия, сетка 4/8, отступы, типографика, состояния, контраст, дубли,
16
+ горизонтальный скролл, обрезания. Дай 5–7 приоритетных правок с «до/после» и
17
+ ссылками на конкретные элементы. Не меняй файлы. Верни список и вердикт go/no-go.
18
+ ```
19
+
20
+ ## responsive-qa
21
+ ```
22
+ Ты responsive-qa. Проверь <URL/HTML> на 390/768/1440: scrollWidth vs clientWidth,
23
+ overflow-элементы, переносы длинных путей, тач-цели, safe-area, модалки/тосты.
24
+ Приложи измерения и скриншоты проблем. Не меняй файлы. Верни баги по приоритету.
25
+ ```
26
+
27
+ ## release-auditor
28
+ ```
29
+ Ты release-auditor. Проверь готовность релиза <версия/репозиторий>: тесты, CI, package,
30
+ security (gitleaks/audit), миграции, откат, checksums, changelog. Верни go/no-go,
31
+ блокеры и точные команды для исправления. Файлы не меняй.
32
+ ```
33
+
34
+ ## code-reviewer
35
+ ```
36
+ Ты code-reviewer. Проверь диффы/файлы <список>. Ищи баги, регрессии, безопасность,
37
+ производительность, несовместимость API, отсутствие тестов. Дай только конкретные
38
+ замечания с файлом/строкой и severity. Не переписывай код без просьбы.
39
+ ```
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: ui-craft
3
+ description: "Инженерная дисциплина UI: сетка и шкала отступов 4/8, типографика, состояния, адаптив 1440/768/390, отсутствие случайных сдвигов и дублей. Использовать при любой вёрстке и правке стилей."
4
+ whenToUse: "Вёрстка, стили, карточки, формы, адаптив, исправление «поехавших» отступов, полировка интерфейса, дизайн-апгрейд."
5
+ user-invocable: true
6
+ autoLoad: true
7
+ ---
8
+
9
+ # UI Craft — аккуратная геометрия и адаптив
10
+
11
+ > ≈750 токенов. Дополняет `wow-design` и `ui-design-system`, не дублирует их.
12
+
13
+ ## 1. Сетка и отступы (жёстко)
14
+ - Одна шкала: **4 / 8 / 12 / 16 / 24 / 32 / 48**. Никаких 7, 13, 23 px «на глаз».
15
+ - Внешние отступы карточки = внутренние + 4/8; одинаковые интервалы по вертикали.
16
+ - Заголовок → описание: 4–6 px; описание → контрол: 12–16; контролы между собой: 8–12.
17
+ - Один контейнер = один max-width; текст не прилипает к краям (мин. 16–20 px).
18
+ - Не выравнивай «по центру» то, что должно быть по базовой линии; проверяй по левому краю.
19
+
20
+ ## 2. Типографика
21
+ - 2–3 размера текста + иерархия заголовков; line-height 1.35–1.55.
22
+ - Числа и таймеры — `font-variant-numeric: tabular-nums`.
23
+ - Не более 70–75 символов в строке; длинные пути/имена — `word-break` и `min-width:0`.
24
+
25
+ ## 3. Адаптив
26
+ - Проверяй **1440, 768, 390** и промежуточные 560/640.
27
+ - Вертикальный скролл допустим; **горизонтального быть не должно**.
28
+ - Flex/grid: `min-width:0`, `flex-wrap`, `minmax(0,1fr)`, без фиксированных ширин больше контейнера.
29
+ - Таблицы и пары ключ–значение на мобиле — в колонку, а не в обрез.
30
+ - Тач-цели ≥ 40–44 px; отступы у краёв с `env(safe-area-inset-*)`.
31
+ - Модалки/тосты: `max-height`, внутренний скролл, не перекрывают композер.
32
+
33
+ ## 4. Состояния и дубли
34
+ - default / hover / focus-visible / active / disabled / loading / empty / error.
35
+ - Фокус видимый, не только цветом; `prefers-reduced-motion`.
36
+ - Одна мысль — один компонент. Если два экрана делают одно и то же, разведи роли или удали дубль.
37
+
38
+ ## 5. Гейт сдачи
39
+ 1. Снять скриншоты 1440/768/390 (light/dark, если тема есть).
40
+ 2. Проверить `scrollWidth <= clientWidth` и отсутствие обрезанных текстов.
41
+ 3. Свериться с референсами из `wow-design`, но не копировать вслепую.
42
+ 4. Только после этого отдавать результат; см. `visual-qa`.
43
+
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: visual-qa
3
+ description: "Скриншот-проверка интерфейса: 1440/768/390, light/dark, поиск горизонтального скролла, обрезанных текстов и сдвигов; сравнение до/после."
4
+ whenToUse: "После любой правки UI, перед сдачей или релизом; при жалобах на отступы, адаптив, скролл, «поехало»."
5
+ user-invocable: true
6
+ autoLoad: true
7
+ ---
8
+
9
+ # Visual QA — снимки и объективная проверка
10
+
11
+ > ≈500 токенов. Команды и шаблоны — `references/commands.md`.
12
+
13
+ ## 1. Что проверяем
14
+ - **Горизонтальный скролл:** `document.documentElement.scrollWidth <= clientWidth` на 390/768/1440.
15
+ - **Обрезания:** текст не выходит за карточку; кнопки не наезжают; длинные пути/числа переносятся.
16
+ - **Ритм:** одинаковые отступы, выравнивание по сетке, нет «прыжков» между секциями.
17
+ - **Контраст:** текст ≥ 4.5:1, крупный ≥ 3:1; фокус видим.
18
+ - **Состояния:** loading/empty/error/disabled, тёмная тема, reduced-motion.
19
+
20
+ ## 2. Как снимать
21
+ 1. В DSH сначала инструмент `browser_qa action=audit url=... widths=[390,768,1440] outDir=...` — он сам даёт PNG, overflow и console errors.
22
+ 2. Живой DSH (если есть авторизованный URL) или preview-harness с реальным клиентским кодом.
23
+ 3. Смотреть каждый PNG глазами; сомнительные — увеличить/переснять. Для API-страниц без авторизации используй preview.
24
+ 4. Для overflow — доверяй `browser_qa`, а не угадыванию; при необходимости CDP-замер.
25
+ 5. После правок — повторный снимок и сравнение «до/после».
26
+
27
+ ## 3. Гейт
28
+ Не отдавать UI без: 3 ширин, отсутствия горизонтального скролла, проверенных текстов и фокуса. Если снять нельзя — честно сказать и запросить скриншот пользователя.
29
+
@@ -0,0 +1,32 @@
1
+ # Visual QA commands
2
+
3
+ ## Скриншоты Chrome (Windows)
4
+ ```powershell
5
+ $chrome = "C:\Program Files\Google\Chrome\Application\chrome.exe"
6
+ & $chrome --headless=new --disable-gpu --hide-scrollbars `
7
+ --window-size=1440,900 --virtual-time-budget=1500 `
8
+ --screenshot="$env:TEMP\ui-1440.png" "file:///C:/path/preview.html"
9
+ ```
10
+ Повтори для 768×1024 и 390×844. Для локального файла с кириллицей скопируй HTML в `%TEMP%` с ASCII-именем.
11
+
12
+ ## Overflow через DevTools/CDP
13
+ ```js
14
+ ({
15
+ scrollWidth: document.documentElement.scrollWidth,
16
+ clientWidth: document.documentElement.clientWidth,
17
+ overflow: document.documentElement.scrollWidth > document.documentElement.clientWidth,
18
+ });
19
+ ```
20
+ Также проверь:
21
+ ```js
22
+ [...document.querySelectorAll("*")].filter(el => el.scrollWidth > el.clientWidth + 1 && getComputedStyle(el).overflowX === "visible")
23
+ ```
24
+ — исключи намеренные скролл-контейнеры.
25
+
26
+ ## Preview-harness
27
+ - `dsh-memory-bridge/docs/preview/capture.mjs` — реальные клиентские компоненты, точные viewport, overflow-флаг.
28
+ - `dsh-desktop-kit/tools/peak-toast-preview.mjs` — пример статического превью из настоящего CSS.
29
+ - Всегда открывай итоговый PNG глазами; цифры не заменяют взгляд.
30
+
31
+ ## Приёмка
32
+ 1440×900, 768×1024, 390×844 · light/dark (если есть) · нет горизонтального скролла · нет обрезанных строк/кнопок · фокус видим · длинные пути переносятся.