dsh-desktop-kit 2.2.0 → 2.7.2

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 (128) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +113 -27
  3. package/client.js +3121 -32
  4. package/docs/AGENT-HARNESS.md +144 -0
  5. package/docs/ARCHITECTURE.md +38 -7
  6. package/docs/COMPATIBILITY.md +5 -3
  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 +6 -6
  14. package/docs/TEST-2.3.0.md +49 -0
  15. package/docs/TEST-2.7.2.md +46 -0
  16. package/docs/TOKENS.md +2 -2
  17. package/docs/TROUBLESHOOTING.md +27 -0
  18. package/docs/UI-QA.md +28 -0
  19. package/docs/images/peak-toast-peak.png +0 -0
  20. package/docs/images/peak-toast-soon.png +0 -0
  21. package/docs/preview/peak-toast.html +155 -0
  22. package/doctor.ps1 +122 -0
  23. package/index.js +18 -1
  24. package/install.ps1 +99 -0
  25. package/package.json +29 -6
  26. package/plugins/dsh-agent-extensions/README.md +99 -0
  27. package/plugins/dsh-agent-extensions/index.js +167 -0
  28. package/plugins/dsh-agent-extensions/lib/agents.js +76 -0
  29. package/plugins/dsh-agent-extensions/lib/checkpoints.js +103 -0
  30. package/plugins/dsh-agent-extensions/lib/commands.js +255 -0
  31. package/plugins/dsh-agent-extensions/lib/hooks.js +182 -0
  32. package/plugins/dsh-agent-extensions/lib/policy.js +84 -0
  33. package/plugins/dsh-agent-extensions/lib/project.js +144 -0
  34. package/plugins/dsh-agent-extensions/lib/scaffold.js +151 -0
  35. package/plugins/dsh-agent-extensions/package.json +9 -0
  36. package/plugins/dsh-browser-qa/README.md +221 -0
  37. package/plugins/dsh-browser-qa/cordis.patch.yml +4 -0
  38. package/plugins/dsh-browser-qa/index.js +165 -0
  39. package/plugins/dsh-browser-qa/lib/cdp.js +224 -0
  40. package/plugins/dsh-browser-qa/lib/chrome.js +466 -0
  41. package/plugins/dsh-browser-qa/lib/pages.js +552 -0
  42. package/plugins/dsh-browser-qa/lib/qa.js +827 -0
  43. package/plugins/dsh-browser-qa/lib/ui-gate.js +256 -0
  44. package/plugins/dsh-browser-qa/package.json +31 -0
  45. package/plugins/dsh-checkpoints/README.md +22 -0
  46. package/plugins/dsh-checkpoints/cordis.patch.yml +3 -0
  47. package/plugins/dsh-checkpoints/index.js +80 -0
  48. package/plugins/dsh-checkpoints/lib/checkpoints.js +111 -0
  49. package/plugins/dsh-checkpoints/package.json +25 -0
  50. package/plugins/dsh-github-review/README.md +131 -0
  51. package/plugins/dsh-github-review/cordis.patch.yml +3 -0
  52. package/plugins/dsh-github-review/index.js +536 -0
  53. package/plugins/dsh-github-review/lib/gh.js +494 -0
  54. package/plugins/dsh-github-review/lib/normalize.js +662 -0
  55. package/plugins/dsh-github-review/package.json +28 -0
  56. package/plugins/dsh-guardrails/README.md +264 -0
  57. package/plugins/dsh-guardrails/cordis.patch.yml +5 -0
  58. package/plugins/dsh-guardrails/index.js +389 -0
  59. package/plugins/dsh-guardrails/lib/hooks.js +262 -0
  60. package/plugins/dsh-guardrails/lib/modes.js +77 -0
  61. package/plugins/dsh-guardrails/lib/policy.js +592 -0
  62. package/plugins/dsh-guardrails/lib/scan.js +451 -0
  63. package/plugins/dsh-guardrails/lib/secrets.js +274 -0
  64. package/plugins/dsh-guardrails/package.json +26 -0
  65. package/plugins/dsh-mcp-manager/README.md +78 -0
  66. package/plugins/dsh-mcp-manager/client.js +373 -0
  67. package/plugins/dsh-mcp-manager/index.js +159 -0
  68. package/plugins/dsh-mcp-manager/lib/api.js +250 -0
  69. package/plugins/dsh-mcp-manager/lib/client.js +219 -0
  70. package/plugins/dsh-mcp-manager/lib/config.js +217 -0
  71. package/plugins/dsh-mcp-manager/lib/manager.js +146 -0
  72. package/plugins/dsh-mcp-manager/package.json +18 -0
  73. package/plugins/dsh-mcp-manager/screenshots/modal-390.png +0 -0
  74. package/plugins/dsh-mcp-manager/screenshots/settings-1440.png +0 -0
  75. package/plugins/dsh-mcp-manager/screenshots/settings-390.png +0 -0
  76. package/plugins/dsh-memory-bridge/README.md +161 -0
  77. package/plugins/dsh-memory-bridge/client.js +2264 -0
  78. package/plugins/dsh-memory-bridge/cordis.patch.yml +5 -0
  79. package/plugins/dsh-memory-bridge/docs/images/conflicts.png +0 -0
  80. package/plugins/dsh-memory-bridge/docs/images/hero.png +0 -0
  81. package/plugins/dsh-memory-bridge/docs/images/settings-dark.png +0 -0
  82. package/plugins/dsh-memory-bridge/docs/images/settings-light.png +0 -0
  83. package/plugins/dsh-memory-bridge/docs/images/settings-mobile.png +0 -0
  84. package/plugins/dsh-memory-bridge/docs/images/setup.png +0 -0
  85. package/plugins/dsh-memory-bridge/icon.svg +13 -0
  86. package/plugins/dsh-memory-bridge/index.js +378 -0
  87. package/plugins/dsh-memory-bridge/lib/bridge.js +636 -0
  88. package/plugins/dsh-memory-bridge/lib/github.js +473 -0
  89. package/plugins/dsh-memory-bridge/lib/merge.js +205 -0
  90. package/plugins/dsh-memory-bridge/lib/portable.js +314 -0
  91. package/plugins/dsh-memory-bridge/lib/state.js +565 -0
  92. package/plugins/dsh-memory-bridge/lib/sync.js +984 -0
  93. package/plugins/dsh-memory-bridge/locale/en.json +6 -0
  94. package/plugins/dsh-memory-bridge/locale/ru.json +6 -0
  95. package/plugins/dsh-memory-bridge/package.json +67 -0
  96. package/plugins/dsh-peak-guard/README.md +16 -3
  97. package/plugins/dsh-peak-guard/client.js +223 -8
  98. package/plugins/dsh-peak-guard/package.json +1 -1
  99. package/plugins/dsh-plan-mode/README.md +24 -0
  100. package/plugins/dsh-plan-mode/cordis.patch.yml +3 -0
  101. package/plugins/dsh-plan-mode/index.js +103 -0
  102. package/plugins/dsh-plan-mode/lib/plan.js +89 -0
  103. package/plugins/dsh-plan-mode/package.json +18 -0
  104. package/plugins/dsh-profile-transfer/client.js +277 -17
  105. package/plugins/dsh-profile-transfer/index.js +10 -0
  106. package/plugins/dsh-profile-transfer/package.json +3 -1
  107. package/plugins/dsh-profile-transfer/transfer.js +101 -2
  108. package/plugins/dsh-project-memory/index.js +92 -2
  109. package/plugins/dsh-project-memory/package.json +1 -1
  110. package/plugins/dsh-repo-map/README.md +26 -0
  111. package/plugins/dsh-repo-map/cordis.patch.yml +3 -0
  112. package/plugins/dsh-repo-map/index.js +99 -0
  113. package/plugins/dsh-repo-map/lib/repo-map.js +170 -0
  114. package/plugins/dsh-repo-map/package.json +25 -0
  115. package/plugins/dsh-skill-autopilot/index.js +135 -11
  116. package/skills/delivery-gate/SKILL.md +31 -0
  117. package/skills/git-and-ci/SKILL.md +5 -1
  118. package/skills/manifest.json +31 -6
  119. package/skills/requirements-and-planning/SKILL.md +3 -0
  120. package/skills/research-first/SKILL.md +35 -0
  121. package/skills/research-first/references/query-patterns.md +20 -0
  122. package/skills/subagent-playbook/SKILL.md +36 -0
  123. package/skills/subagent-playbook/references/prompts.md +39 -0
  124. package/skills/ui-craft/SKILL.md +43 -0
  125. package/skills/visual-qa/SKILL.md +29 -0
  126. package/skills/visual-qa/references/commands.md +32 -0
  127. package/skills-baseline.json +246 -0
  128. package/uninstall.ps1 +74 -0
@@ -0,0 +1,155 @@
1
+ <!doctype html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>dsh-peak-guard · пример уведомления</title>
6
+ <style>
7
+ :root{
8
+ --dsw-alias-bg-base:#fff;--dsw-alias-bg-layer-1:#fff;--dsw-alias-bg-layer-2:#f6f7f9;
9
+ --dsw-alias-label-primary:#14161a;--dsw-alias-label-secondary:#6b7280;
10
+ --dsw-alias-border-l1:rgba(20,22,26,.08);--dsw-alias-border-l2:rgba(20,22,26,.14);
11
+ --dsw-alias-state-error-primary:#d64545;--dsw-alias-state-warn-primary:#b45309;
12
+ --dsw-alias-brand-primary:#2f7df6;
13
+ }
14
+ *{box-sizing:border-box}
15
+ html,body{height:100%;margin:0}
16
+ body{font-family:"Segoe UI Variable","Segoe UI",system-ui,sans-serif;color:#14161a;background:#dfe3e8;overflow:hidden}
17
+ .mock-app{position:fixed;inset:0;display:flex;background:#f4f5f7}
18
+ .mock-sidebar{width:268px;flex:none;background:#f8f9fb;border-right:1px solid #e6e8ec;padding:14px 12px;display:flex;flex-direction:column;gap:8px}
19
+ .mock-brand{display:flex;align-items:center;gap:8px;padding:5px 7px 18px;font-weight:700;font-size:15px;letter-spacing:-.02em}
20
+ .mock-logo{width:19px;height:19px;border-radius:6px;background:#101216;color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px}
21
+ .mock-tag{margin-left:auto;font-size:8px;letter-spacing:.1em;color:#8b919a;border:1px solid #d7dbe1;padding:2px 5px;border-radius:4px}
22
+ .mock-new{display:flex;align-items:center;gap:7px;background:#fff;border:1px solid #e2e5ea;border-radius:9px;padding:8px 10px;font-size:12px;color:#3a3f47;box-shadow:0 1px 2px rgba(20,22,26,.03)}
23
+ .mock-label{font-size:8.5px;letter-spacing:.12em;color:#9aa0a9;margin:12px 6px 2px;font-weight:700}
24
+ .mock-ws{display:flex;align-items:center;gap:7px;padding:7px 8px;border-radius:7px;font-size:11.5px;color:#4b515a}
25
+ .mock-ws.active{background:#eceef2;color:#14161a;font-weight:600}
26
+ .mock-dot{width:5px;height:5px;border-radius:50%;background:#8f959e;flex:none}
27
+ .mock-session{display:flex;gap:7px;align-items:center;margin-left:8px;padding:5px 8px;border-radius:6px;font-size:11px;color:#6b7280}
28
+ .mock-session.active{background:#e7eaf0;color:#14161a;font-weight:600}
29
+ .mock-session .mock-dot{background:#aab0b8}
30
+ .mock-session.active .mock-dot{background:#2f7df6}
31
+ .mock-bottom{margin-top:auto;border-top:1px solid #e6e8ec;padding-top:8px;display:flex;flex-direction:column;gap:6px}
32
+ .mock-tool{display:flex;align-items:center;gap:8px;font-size:11px;color:#6b7280;padding:5px 8px;border-radius:6px}
33
+ .mock-tools{margin-top:4px;background:#fff;border:1px solid #e6e8ec;border-radius:9px;padding:8px 9px;font-size:9.5px;line-height:15px;color:#7b818a}
34
+ .mock-tools b{display:block;color:#2e333a;font-size:10.5px;margin-bottom:2px}
35
+ .mock-main{flex:1;min-width:0;display:flex;flex-direction:column;background:#fff}
36
+ .mock-head{height:57px;flex:none;border-bottom:1px solid #eceef1;display:flex;align-items:center;gap:10px;padding:0 22px;font-size:12px;font-weight:650;color:#23262b}
37
+ .mock-tabs{display:flex;gap:16px;margin-left:16px;font-size:11px;font-weight:500;color:#8a9098;height:100%;align-items:center}
38
+ .mock-tab{padding:0 1px;height:100%;display:flex;align-items:center;border-bottom:2px solid transparent}
39
+ .mock-tab.active{color:#16181c;border-color:#16181c}
40
+ .mock-chat{flex:1;padding:24px 22px 150px;overflow:hidden;position:relative}
41
+ .mock-message{max-width:760px;margin:0 auto 14px;font-size:12px;line-height:20px;color:#3e444c}
42
+ .mock-user{background:#f1f3f6;border:1px solid #e7e9ee;border-radius:11px;padding:10px 13px}
43
+ .mock-assistant{padding:4px 2px 4px 13px;border-left:2px solid #e4e7ec}
44
+ .mock-line{height:8px;border-radius:4px;background:#eceef2;margin:7px 0}
45
+ .mock-line.w1{width:86%}.mock-line.w2{width:72%}.mock-line.w3{width:54%}.mock-line.dark{background:#dfe3e9}
46
+ .mock-composer{position:absolute;left:50%;bottom:20px;transform:translateX(-50%);width:min(850px,calc(100% - 44px));background:#fff;border:1px solid #dfe3e8;border-radius:13px;box-shadow:0 16px 40px -24px rgba(20,22,26,.28);padding:11px 13px;display:flex;align-items:center;gap:10px;font-size:11px;color:#9aa0a9}
47
+ .mock-send{margin-left:auto;width:26px;height:26px;border-radius:50%;background:#eef1f5;display:flex;align-items:center;justify-content:center;color:#8b9199}
48
+ .mock-caption{position:fixed;left:22px;top:18px;z-index:20;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:#7c838d;background:rgba(255,255,255,.82);border:1px solid #e2e5ea;border-radius:999px;padding:6px 10px;backdrop-filter:blur(8px)}
49
+ .mock-caption b{color:#2c3138;letter-spacing:.02em;text-transform:none;font-size:11px;font-weight:600}
50
+ .mock-hint{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);z-index:20;font-size:9.5px;color:#a1a7b0}
51
+ .dpg-toast-details[hidden]{display:none}
52
+ .dpg-toast, .dpg-toast-fill{animation:none!important;transition:none!important}
53
+ .dpg-dot{width:6px;height:6px;border-radius:50%;background:var(--dpg-toast-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--dpg-toast-accent) 14%,transparent);animation:none}
54
+ .dpg-chip{display:inline-flex;align-items:center;height:22px;padding:0 8px;border-radius:6px;border:1px solid color-mix(in srgb,var(--dpg-toast-accent) 24%,transparent);background:color-mix(in srgb,var(--dpg-toast-accent) 7%,transparent);color:var(--dsw-alias-label-primary,#111);font-size:10.5px;font-weight:650;font-variant-numeric:tabular-nums;white-space:nowrap}
55
+ /* corner toast: a quiet, premium alert over the whole frame */
56
+ .dpg-toast-wrap{position:fixed;right:22px;bottom:20px;z-index:1300;max-width:min(392px,calc(100vw - 24px));pointer-events:none}
57
+ .dpg-toast{--dpg-toast-accent:var(--dsw-alias-state-error-primary,#e5484d);position:relative;display:flex;flex-direction:column;gap:9px;padding:13px 13px 11px;border-radius:17px;border:1px solid color-mix(in srgb,var(--dpg-toast-accent) 24%,transparent);background:linear-gradient(155deg,color-mix(in srgb,var(--dpg-toast-accent) 6%,var(--dsw-alias-bg-layer-1,#fff)) 0%,var(--dsw-alias-bg-layer-1,#fff) 62%);box-shadow:inset 0 1px 0 color-mix(in srgb,#fff 50%,transparent),0 22px 48px -28px color-mix(in srgb,var(--dpg-toast-accent) 78%,transparent);color:var(--dsw-alias-label-primary,#111);pointer-events:auto;animation:dpg-toast-in .32s cubic-bezier(.16,1,.3,1)}
58
+ .dpg-toast[data-mode="soon"]{--dpg-toast-accent:var(--dsw-alias-state-warn-primary,#d97706)}
59
+ .dpg-toast::before{content:"";position:absolute;left:0;top:14px;bottom:14px;width:3px;border-radius:0 3px 3px 0;background:var(--dpg-toast-accent)}
60
+ .dpg-toast-head{display:flex;align-items:flex-start;gap:10px;padding-left:5px}
61
+ .dpg-toast-icon{flex:none;width:34px;height:34px;border-radius:11px;display:flex;align-items:center;justify-content:center;color:#fff;background:linear-gradient(150deg,var(--dpg-toast-accent),color-mix(in srgb,var(--dpg-toast-accent) 55%,#4a070c));box-shadow:0 7px 16px -9px color-mix(in srgb,var(--dpg-toast-accent) 95%,transparent),inset 0 1px 0 rgba(255,255,255,.3)}
62
+ .dpg-toast[data-mode="soon"] .dpg-toast-icon{background:linear-gradient(150deg,var(--dpg-toast-accent),color-mix(in srgb,var(--dpg-toast-accent) 55%,#4a2c00));color:#fff}
63
+ .dpg-toast-copy{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1;padding-top:1px}
64
+ .dpg-toast-kicker{display:flex;align-items:center;gap:6px;font-size:9.5px;font-weight:750;letter-spacing:.14em;text-transform:uppercase;color:color-mix(in srgb,var(--dpg-toast-accent) 82%,#111)}
65
+ .dpg-toast-kicker .dpg-dot{width:5px;height:5px;box-shadow:0 0 0 3px color-mix(in srgb,var(--dpg-toast-accent) 13%,transparent)}
66
+ .dpg-toast-chip{display:inline-flex;align-items:center;height:15px;padding:0 5px;border-radius:4px;border:1px solid color-mix(in srgb,var(--dpg-toast-accent) 40%,transparent);background:color-mix(in srgb,var(--dpg-toast-accent) 9%,transparent);font-size:9px;font-weight:800;letter-spacing:.03em}
67
+ .dpg-toast-title{font-size:13.5px;line-height:18px;font-weight:660;letter-spacing:-.01em}
68
+ .dpg-toast-meta{font-size:11px;line-height:15px;color:var(--dsw-alias-label-secondary,#5b6472);font-variant-numeric:tabular-nums}
69
+ .dpg-toast-close{flex:none;border:none;background:transparent;color:var(--dsw-alias-label-secondary,#6b7280);width:24px;height:24px;border-radius:7px;display:flex;align-items:center;justify-content:center;font-size:15px;line-height:1;cursor:pointer;margin:-2px -2px 0 0}
70
+ .dpg-toast-close:hover{background:color-mix(in srgb,var(--dpg-toast-accent) 9%,transparent);color:var(--dpg-toast-accent)}
71
+ .dpg-toast-close:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#2f7df6);outline-offset:1px}
72
+ .dpg-toast-track{position:relative;height:3px;border-radius:2px;background:color-mix(in srgb,var(--dpg-toast-accent) 13%,transparent);overflow:hidden;margin:0 1px}
73
+ .dpg-toast-fill{height:100%;border-radius:2px;background:linear-gradient(90deg,color-mix(in srgb,var(--dpg-toast-accent) 62%,#fff) 0%,var(--dpg-toast-accent) 100%);transition:width .9s linear}
74
+ .dpg-toast-actions{display:flex;align-items:center;gap:6px;padding-left:5px}
75
+ .dpg-toast-btn{border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.14));background:transparent;color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:10.5px;font-weight:650;line-height:14px;padding:5px 9px;border-radius:7px;cursor:pointer;transition:background .16s ease,border-color .16s ease}
76
+ .dpg-toast-btn:hover{background:color-mix(in srgb,var(--dpg-toast-accent) 7%,transparent);border-color:color-mix(in srgb,var(--dpg-toast-accent) 34%,transparent)}
77
+ .dpg-toast-btn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#2f7df6);outline-offset:1px}
78
+ .dpg-toast-btn[data-emphasis="true"]{border-color:transparent;background:var(--dpg-toast-accent);color:#fff}
79
+ .dpg-toast[data-mode="soon"] .dpg-toast-btn[data-emphasis="true"]{color:#2a1500}
80
+ .dpg-toast-details{display:grid;grid-template-columns:1fr;gap:5px;padding:7px 9px 2px;border-top:1px solid color-mix(in srgb,var(--dpg-toast-accent) 14%,transparent);font-size:10.5px;line-height:15px;color:var(--dsw-alias-label-secondary,#5b6472)}
81
+ .dpg-toast-details b{color:var(--dsw-alias-label-primary,#111);font-weight:650}
82
+ .dpg-toast-details .dpg-toast-schedule{display:flex;flex-wrap:wrap;gap:5px;margin-top:2px}
83
+ @keyframes dpg-toast-in{from{opacity:0;transform:translateY(10px) scale(.985)}to{opacity:1;transform:translateY(0) scale(1)}}
84
+ @media (max-width:520px){.dpg-toast-wrap{right:10px;left:10px;bottom:calc(10px + env(safe-area-inset-bottom,0px));max-width:none}.dpg-toast{max-height:70vh;overflow:auto;padding:12px 12px 10px}}
85
+
86
+ </style>
87
+ </head>
88
+ <body>
89
+ <div class="mock-app">
90
+ <aside class="mock-sidebar">
91
+ <div class="mock-brand"><span class="mock-logo">◈</span>deepseek<span class="mock-tag">HARNESS</span></div>
92
+ <div class="mock-new">+ Новая сессия</div>
93
+ <div class="mock-label">РАБОЧИЕ ПРОСТРАНСТВА</div>
94
+ <div class="mock-ws active"><span class="mock-dot" style="background:#6b7280"></span>Доработки</div>
95
+ <div class="mock-session active"><span class="mock-dot"></span>Доработка dsh-memory-bridge</div>
96
+ <div class="mock-session"><span class="mock-dot"></span>Nexum-core</div>
97
+ <div class="mock-session"><span class="mock-dot"></span>Доработка UI и шаблонов</div>
98
+ <div class="mock-bottom">
99
+ <div class="mock-tool">⚙ Плагины</div>
100
+ <div class="mock-tool">◷ Задачи автоматизации</div>
101
+ <div class="mock-tools"><b>НАВЫКИ · 25</b>40 запусков · 16 из 38k</div>
102
+ </div>
103
+ </aside>
104
+ <main class="mock-main">
105
+ <header class="mock-head">Доработка dsh-memory-bridge …<div class="mock-tabs"><span class="mock-tab active">Чат</span><span class="mock-tab">Траектория</span><span class="mock-tab">Статистика</span></div></header>
106
+ <section class="mock-chat">
107
+ <div class="mock-message mock-user">Сделай премиальное уведомление в углу о двойном тарифе.</div>
108
+ <div class="mock-message mock-assistant"><div class="mock-line dark w1"></div><div class="mock-line w2"></div><div class="mock-line w3"></div><div style="height:6px"></div><div class="mock-line w1"></div><div class="mock-line w2"></div></div>
109
+ <div class="mock-message mock-user" style="max-width:520px">Покажи, как это будет выглядеть в пик.</div>
110
+ <div class="mock-message mock-assistant"><div class="mock-line w1"></div><div class="mock-line w2"></div><div class="mock-line w3"></div></div>
111
+ <div class="mock-composer">+ <span>Сообщение или команда…</span><span class="mock-send">↑</span></div>
112
+ </section>
113
+ </main>
114
+ </div>
115
+ <div class="dpg-toast-wrap">
116
+ <div class="dpg-toast" data-mode="peak" role="status" aria-live="polite" aria-atomic="true" aria-label="Предупреждение о пиковом тарифе">
117
+ <div class="dpg-toast-head">
118
+ <span class="dpg-toast-icon" aria-hidden="true"><svg viewBox="0 0 20 20" width="17" height="17" fill="none"><path d="M11.2 2.6 5.8 11h4.1l-1.1 6.4 5.4-8.4H10l1.2-6.4Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round"/></svg></span>
119
+ <div class="dpg-toast-copy">
120
+ <div class="dpg-toast-kicker"><span class="dpg-dot"></span><span class="js-kicker">Пиковый тариф</span><span class="dpg-toast-chip">×2</span></div>
121
+ <div class="dpg-toast-title js-title">Токены сейчас стоят вдвое дороже</div>
122
+ <div class="dpg-toast-meta js-meta">осталось 2 ч 48 мин · 04:00–07:00 МСК</div>
123
+ </div>
124
+ <button class="dpg-toast-close" type="button" aria-label="Скрыть">×</button>
125
+ </div>
126
+ <div class="dpg-toast-track" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="38" aria-label="до конца пикового окна"><span class="dpg-toast-fill" style="display:block;width:38%"></span></div>
127
+ <div class="dpg-toast-details" hidden>
128
+ <span>В пиковые часы стоимость всех типов токенов для deepseek-flash и deepseek-v4-pro увеличивается вдвое. Вне этих часов действует скидка 50% (off-peak).</span>
129
+ <span class="dpg-toast-schedule"><b>Окна пика</b><span class="dpg-chip">04:00–07:00</span><span class="dpg-chip">09:00–13:00</span></span>
130
+ <span>Пиковые окна не действуют по выходным и в государственные праздники Китая (календарь 2026–2027 встроен); всё остальное время — off-peak.</span>
131
+ <span>Расписание проверено 2026-11-09</span>
132
+ </div>
133
+ <div class="dpg-toast-actions">
134
+ <button class="dpg-toast-btn" type="button">Подробнее</button>
135
+ <button class="dpg-toast-btn" type="button" data-emphasis="true">Скрыть</button>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ <script>
140
+ const params = new URLSearchParams(location.search);
141
+ const mode = params.get("mode") === "soon" ? "soon" : "peak";
142
+ const details = params.get("details") === "1";
143
+ const toast = document.querySelector(".dpg-toast");
144
+ toast.dataset.mode = mode;
145
+ if (mode === "soon") {
146
+ document.querySelector(".js-kicker").textContent = "Скоро пик";
147
+ document.querySelector(".js-title").textContent = "Пиковый тариф через 4 мин";
148
+ document.querySelector(".js-meta").textContent = "начнётся через 4 мин · 04:00–07:00 МСК";
149
+ document.querySelector(".dpg-toast-fill").style.width = "18%";
150
+ document.querySelector(".dpg-toast-track").setAttribute("aria-valuenow", "18");
151
+ }
152
+ if (details) document.querySelector(".dpg-toast-details")?.removeAttribute("hidden");
153
+ </script>
154
+ </body>
155
+ </html>
package/doctor.ps1 ADDED
@@ -0,0 +1,122 @@
1
+ #requires -Version 5.1
2
+ <#
3
+ .SYNOPSIS
4
+ Report whether dsh-desktop-kit is installed and enabled.
5
+ #>
6
+ param(
7
+ [string]$Profile = "desktop",
8
+ [string]$DshHome = ""
9
+ )
10
+
11
+ $ErrorActionPreference = "Continue"
12
+
13
+ if ([string]::IsNullOrWhiteSpace($DshHome)) {
14
+ if ($env:DSH_HOME) { $DshHome = $env:DSH_HOME } else { $DshHome = Join-Path $env:USERPROFILE ".dsh" }
15
+ }
16
+
17
+ $profileDir = Join-Path $DshHome "profiles\$Profile"
18
+ $profileJson = Join-Path $profileDir "package.json"
19
+
20
+ Write-Host "DSH home: $DshHome"
21
+ Write-Host "Profile: $profileDir"
22
+
23
+ $dsh = $null
24
+ $command = Get-Command dsh -ErrorAction SilentlyContinue
25
+ if ($command) { $dsh = $command.Source }
26
+ if (-not $dsh) {
27
+ $fallback = Join-Path ${env:LOCALAPPDATA} "Programs\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd"
28
+ if (Test-Path $fallback) { $dsh = $fallback }
29
+ }
30
+ if ($dsh) {
31
+ $version = & $dsh --version 2>$null
32
+ Write-Host "DSH CLI: $version"
33
+ } else {
34
+ Write-Host "DSH CLI: not found" -ForegroundColor Yellow
35
+ }
36
+
37
+ if (-not (Test-Path $profileJson)) {
38
+ Write-Host "Profile manifest not found." -ForegroundColor Red
39
+ exit 1
40
+ }
41
+
42
+ $json = Get-Content -Path $profileJson -Raw | ConvertFrom-Json
43
+ $issues = 0
44
+
45
+ $dependency = $null
46
+ if ($json.dependencies) { $dependency = $json.dependencies.'dsh-desktop-kit' }
47
+ if ($dependency) {
48
+ Write-Host "Package: $dependency" -ForegroundColor Green
49
+ } else {
50
+ Write-Host "Package: not installed" -ForegroundColor Red
51
+ $issues += 1
52
+ }
53
+
54
+ $bundles = @()
55
+ if ($json.dsh -and $json.dsh.profile -and $json.dsh.profile.bundles) { $bundles = @($json.dsh.profile.bundles) }
56
+ if ($bundles -contains "dsh-desktop-kit") {
57
+ Write-Host "Bundle: enabled" -ForegroundColor Green
58
+ } else {
59
+ Write-Host "Bundle: not enabled" -ForegroundColor Red
60
+ $issues += 1
61
+ }
62
+
63
+ $link = Join-Path $profileDir "node_modules\dsh-desktop-kit"
64
+ if (Test-Path $link) {
65
+ Write-Host "Link: $((Get-Item $link).Target)" -ForegroundColor Green
66
+ $kitPackage = Join-Path $link "package.json"
67
+ if (Test-Path $kitPackage) {
68
+ $kit = Get-Content -Path $kitPackage -Raw | ConvertFrom-Json
69
+ Write-Host "Kit: $($kit.version)" -ForegroundColor Green
70
+ }
71
+ } else {
72
+ Write-Host "Link: missing (run install.ps1 again)" -ForegroundColor Red
73
+ $issues += 1
74
+ }
75
+
76
+ $statePath = Join-Path $DshHome "skills\.dsh-kit-skills.json"
77
+ if (Test-Path $statePath) {
78
+ try {
79
+ $state = Get-Content -Path $statePath -Raw | ConvertFrom-Json
80
+ $skillNames = @()
81
+ if ($state.skills) { $skillNames = @($state.skills.PSObject.Properties | ForEach-Object { $_.Name } | Where-Object { $_ }) }
82
+ $conflictNames = @()
83
+ if ($state.conflicts) { $conflictNames = @($state.conflicts.PSObject.Properties | ForEach-Object { $_.Name } | Where-Object { $_ }) }
84
+ Write-Host "Skill sync: $($skillNames.Count) packaged, $($conflictNames.Count) conflicts, updated $($state.updatedAt)" -ForegroundColor Green
85
+ if ($conflictNames.Count -gt 0) {
86
+ Write-Host "Skill conflicts (your edits were kept): $($conflictNames -join ', ')" -ForegroundColor Yellow
87
+ Write-Host " /kit conflicts - list; /kit sync - update without overwriting"
88
+ }
89
+ } catch {
90
+ Write-Host "Skill sync: state file is unreadable ($($_.Exception.Message))" -ForegroundColor Yellow
91
+ }
92
+ } else {
93
+ Write-Host "Skill sync: not written yet (start DSH once or run /kit sync)" -ForegroundColor Yellow
94
+ }
95
+
96
+ $pinned = @()
97
+ foreach ($name in @($json.dependencies.PSObject.Properties.Name)) {
98
+ if ($name -like "@deepseek-ai/*") { $pinned += $name }
99
+ }
100
+ if ($pinned.Count -gt 0) {
101
+ Write-Host "Pinned @deepseek-ai packages (possible 'incompatible plugins' after a DSH update):" -ForegroundColor Yellow
102
+ $pinned | ForEach-Object { Write-Host " $_" }
103
+ } else {
104
+ Write-Host "Pinned packages: none" -ForegroundColor Green
105
+ }
106
+
107
+ $skillsDir = Join-Path $DshHome "skills"
108
+ if (Test-Path $skillsDir) {
109
+ $count = (Get-ChildItem $skillsDir -Directory | Measure-Object).Count
110
+ Write-Host "Skills: $count" -ForegroundColor Green
111
+ } else {
112
+ Write-Host "Skills: folder missing (the kit creates it on first start)" -ForegroundColor Yellow
113
+ }
114
+
115
+ if ($issues -eq 0) {
116
+ Write-Host ""
117
+ Write-Host "Everything is in place." -ForegroundColor Green
118
+ exit 0
119
+ }
120
+ Write-Host ""
121
+ Write-Host "$issues problem(s) found." -ForegroundColor Red
122
+ exit 1
package/index.js CHANGED
@@ -28,8 +28,17 @@ import * as peakGuard from "./plugins/dsh-peak-guard/index.js";
28
28
  import * as sessionMove from "./plugins/dsh-session-move/index.js";
29
29
  import * as profileTransfer from "./plugins/dsh-profile-transfer/index.js";
30
30
  import * as projectMemory from "./plugins/dsh-project-memory/index.js";
31
+ import * as memoryBridge from "./plugins/dsh-memory-bridge/index.js";
31
32
  import * as tokenLab from "./plugins/dsh-token-lab/lib/index.js";
32
33
  import * as skillAutopilot from "./plugins/dsh-skill-autopilot/index.js";
34
+ import * as repoMap from "./plugins/dsh-repo-map/index.js";
35
+ import * as checkpoints from "./plugins/dsh-checkpoints/index.js";
36
+ import * as planMode from "./plugins/dsh-plan-mode/index.js";
37
+ import * as browserQa from "./plugins/dsh-browser-qa/index.js";
38
+ import * as githubReview from "./plugins/dsh-github-review/index.js";
39
+ import * as guardrails from "./plugins/dsh-guardrails/index.js";
40
+ import * as agentExtensions from "./plugins/dsh-agent-extensions/index.js";
41
+ import * as mcpManager from "./plugins/dsh-mcp-manager/index.js";
33
42
 
34
43
  const here = path.dirname(fileURLToPath(import.meta.url));
35
44
  const KIT_VERSION = (() => {
@@ -48,6 +57,15 @@ const parts = [
48
57
  ["dsh-session-move", sessionMove],
49
58
  ["dsh-profile-transfer", profileTransfer],
50
59
  ["dsh-project-memory", projectMemory],
60
+ ["dsh-memory-bridge", memoryBridge],
61
+ ["dsh-repo-map", repoMap],
62
+ ["dsh-checkpoints", checkpoints],
63
+ ["dsh-plan-mode", planMode],
64
+ ["dsh-browser-qa", browserQa],
65
+ ["dsh-github-review", githubReview],
66
+ ["dsh-guardrails", guardrails],
67
+ ["dsh-agent-extensions", agentExtensions],
68
+ ["dsh-mcp-manager", mcpManager],
51
69
  ];
52
70
 
53
71
  /** The kit itself needs no service; each child declares its own. */
@@ -185,4 +203,3 @@ export function apply(ctx) {
185
203
  ctx.logger?.debug?.(`[dsh-desktop-kit] commands service unavailable: ${String(error)}`);
186
204
  }
187
205
  }
188
-
package/install.ps1 ADDED
@@ -0,0 +1,99 @@
1
+ #requires -Version 5.1
2
+ <#
3
+ .SYNOPSIS
4
+ Install dsh-desktop-kit into a DeepSeek Harness profile.
5
+
6
+ .DESCRIPTION
7
+ Copies nothing into the profile outside pnpm's own dependency install:
8
+ the kit is linked from this repository, the bundle is added to
9
+ dsh.profile.bundles, and the DSH launcher is asked to run pnpm.
10
+ Skills are copied by the kit itself on its first start.
11
+
12
+ .PARAMETER Profile
13
+ DSH profile name, default "desktop".
14
+
15
+ .PARAMETER DshHome
16
+ DSH home; defaults to $env:DSH_HOME or %USERPROFILE%\.dsh.
17
+
18
+ .PARAMETER RepoPath
19
+ Repository root; defaults to this script's folder.
20
+ #>
21
+ param(
22
+ [string]$Profile = "desktop",
23
+ [string]$DshHome = "",
24
+ [string]$RepoPath = ""
25
+ )
26
+
27
+ $ErrorActionPreference = "Stop"
28
+
29
+ function Write-Step([string]$Text) {
30
+ Write-Host ""
31
+ Write-Host "==> $Text" -ForegroundColor Cyan
32
+ }
33
+
34
+ if ([string]::IsNullOrWhiteSpace($RepoPath)) { $RepoPath = $PSScriptRoot }
35
+ if (-not (Test-Path (Join-Path $RepoPath "package.json"))) {
36
+ throw "package.json not found in $RepoPath"
37
+ }
38
+ if ([string]::IsNullOrWhiteSpace($DshHome)) {
39
+ if ($env:DSH_HOME) { $DshHome = $env:DSH_HOME } else { $DshHome = Join-Path $env:USERPROFILE ".dsh" }
40
+ }
41
+
42
+ $profileDir = Join-Path $DshHome "profiles\$Profile"
43
+ $profileJson = Join-Path $profileDir "package.json"
44
+
45
+ Write-Step "Checking the DSH environment"
46
+ $dsh = $null
47
+ $command = Get-Command dsh -ErrorAction SilentlyContinue
48
+ if ($command) { $dsh = $command.Source }
49
+ if (-not $dsh) {
50
+ $fallback = Join-Path ${env:LOCALAPPDATA} "Programs\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd"
51
+ if (Test-Path $fallback) { $dsh = $fallback }
52
+ }
53
+ if (-not $dsh) { throw "dsh CLI not found. Install DeepSeek Harness, run it once, then retry." }
54
+ if (-not (Test-Path $profileJson)) {
55
+ throw "Profile '$Profile' does not exist ($profileDir). Start DSH once, close it, then retry."
56
+ }
57
+
58
+ Write-Host "dsh: $dsh"
59
+ Write-Host "DSH home: $DshHome"
60
+ Write-Host "Profile: $Profile"
61
+ Write-Host "Repository: $RepoPath"
62
+
63
+ $running = Get-Process -Name "DeepSeek Harness" -ErrorAction SilentlyContinue
64
+ if ($running) {
65
+ Write-Host "DSH is running. Close it before installing so the profile is not written twice." -ForegroundColor Yellow
66
+ }
67
+
68
+ Write-Step "Backing up the profile manifest"
69
+ $stamp = Get-Date -Format "yyyyMMdd-HHmmss"
70
+ $backupDir = Join-Path $profileDir ("backup-kit-" + $stamp)
71
+ New-Item -ItemType Directory -Path $backupDir -Force | Out-Null
72
+ Copy-Item $profileJson (Join-Path $backupDir "package.json") -Force
73
+ $patchFile = Join-Path $profileDir "cordis.patch.yml"
74
+ if (Test-Path $patchFile) { Copy-Item $patchFile (Join-Path $backupDir "cordis.patch.yml") -Force }
75
+ Write-Host "Backup: $backupDir"
76
+
77
+ Write-Step "Installing the package through the DSH launcher (pnpm)"
78
+ & $dsh plugin --profile $Profile add $RepoPath
79
+ if ($LASTEXITCODE -ne 0) {
80
+ throw "dsh plugin add exited with code $LASTEXITCODE. See the output above."
81
+ }
82
+
83
+ Write-Step "Enabling the bundle in the profile manifest"
84
+ $json = Get-Content -Path $profileJson -Raw | ConvertFrom-Json
85
+ if ($null -eq $json.dsh) { $json | Add-Member -NotePropertyName dsh -NotePropertyValue ([pscustomobject]@{}) }
86
+ if ($null -eq $json.dsh.profile) { $json.dsh | Add-Member -NotePropertyName profile -NotePropertyValue ([pscustomobject]@{}) }
87
+ $bundles = @()
88
+ if ($json.dsh.profile.bundles) { $bundles = @($json.dsh.profile.bundles) }
89
+ if ($bundles -notcontains "dsh-desktop-kit") { $bundles += "dsh-desktop-kit" }
90
+ $json.dsh.profile | Add-Member -NotePropertyName bundles -NotePropertyValue $bundles -Force
91
+ $jsonText = $json | ConvertTo-Json -Depth 20
92
+ [System.IO.File]::WriteAllText($profileJson, $jsonText, (New-Object System.Text.UTF8Encoding($false)))
93
+
94
+ Write-Step "Done"
95
+ Write-Host "1. Start DeepSeek Harness (restart it if it was running)." -ForegroundColor Green
96
+ Write-Host "2. Settings -> Plugins: 'dsh-desktop-kit' is enabled." -ForegroundColor Green
97
+ Write-Host "3. The kit copies missing skills into $DshHome\skills on first start." -ForegroundColor Green
98
+ Write-Host ""
99
+ Write-Host "Rollback: run uninstall.ps1, or restore package.json from $backupDir." -ForegroundColor DarkGray
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-desktop-kit",
3
- "version": "2.2.0",
4
- "description": "DeepSeek Harness desktop kit 2.2: update-safe self-applying skills, live token lab, Skills Studio, self-scanning project memory, Russian UI, peak guard, chat move and profile transfer.",
3
+ "version": "2.7.2",
4
+ "description": "DeepSeek Harness desktop kit 2.7: 16 plugins and 30 skills — self-applying skills, token lab, Skills Studio, project memory, GitHub and USB memory transfer, guardrails, repo map, checkpoints, plan mode, browser QA, GitHub review, Claude Code-like hooks/agents/commands, Russian UI, peak guard, chat move and profile transfer.",
5
5
  "keywords": [
6
6
  "deepseek-harness",
7
7
  "dsh",
@@ -12,10 +12,28 @@
12
12
  "tokens",
13
13
  "context",
14
14
  "skills-studio",
15
- "token-lab"
15
+ "token-lab",
16
+ "memory-bridge",
17
+ "project-memory",
18
+ "github-sync",
19
+ "guardrails",
20
+ "repo-map",
21
+ "checkpoints",
22
+ "plan-mode",
23
+ "browser-qa",
24
+ "github-review",
25
+ "usb"
16
26
  ],
17
27
  "license": "MIT",
18
28
  "author": "DSH Desktop Kit contributors",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/Bulavackii/dsh-desktop-kit.git"
32
+ },
33
+ "homepage": "https://github.com/Bulavackii/dsh-desktop-kit#readme",
34
+ "bugs": {
35
+ "url": "https://github.com/Bulavackii/dsh-desktop-kit/issues"
36
+ },
19
37
  "type": "module",
20
38
  "main": "index.js",
21
39
  "exports": {
@@ -34,6 +52,9 @@
34
52
  "README.md",
35
53
  "CHANGELOG.md",
36
54
  "LICENSE",
55
+ "doctor.ps1",
56
+ "install.ps1",
57
+ "uninstall.ps1",
37
58
  "lib/**",
38
59
  "docs/**",
39
60
  "skills-baseline.json",
@@ -46,15 +67,17 @@
46
67
  "plugins/*/README.md",
47
68
  "plugins/*/screenshots/**",
48
69
  "skills/**",
49
- "tools/skill-cost.mjs"
70
+ "tools/skill-cost.mjs",
71
+ "plugins/*/docs/images/**"
50
72
  ],
51
73
  "scripts": {
52
74
  "build:client": "node tools/build-client.mjs",
53
75
  "build:skills": "node tools/build-skill-manifest.mjs",
54
76
  "check:client": "node tools/check-client.mjs client.js",
55
- "test": "node tools/smoke-tests.mjs && node tools/memory-tests.mjs && node tools/skills-sync-tests.mjs && node tools/kit-upgrade-tests.mjs",
77
+ "test": "node tools/smoke-tests.mjs && node tools/memory-tests.mjs && node tools/skills-sync-tests.mjs && node tools/kit-upgrade-tests.mjs && node plugins/dsh-profile-transfer/test/transfer.test.mjs && node --test plugins/dsh-memory-bridge/test/bridge.test.mjs plugins/dsh-memory-bridge/test/github.test.mjs plugins/dsh-memory-bridge/test/merge.test.mjs plugins/dsh-memory-bridge/test/user-specific.test.mjs && node tools/repo-map-tests.mjs && node tools/checkpoints-tests.mjs && node tools/plan-mode-tests.mjs && node tools/browser-qa-tests.mjs && node tools/ui-gate-tests.mjs && node tools/agent-extensions-tests.mjs && node tools/mcp-manager-tests.mjs && node tools/github-review-tests.mjs && node plugins/dsh-guardrails/tools/guardrails-tests.mjs",
56
78
  "skills:cost": "node tools/skill-cost.mjs",
57
- "skills:check": "node tools/skill-cost.mjs --check"
79
+ "skills:check": "node tools/skill-cost.mjs --check",
80
+ "release": "node tools/release.mjs"
58
81
  },
59
82
  "engines": {
60
83
  "node": ">=20"
@@ -0,0 +1,99 @@
1
+ # dsh-agent-extensions
2
+
3
+ Claude Code-like project extensions for DSH, all opt-in and project-local.
4
+
5
+ ## Auto-bootstrap
6
+
7
+ On its first start the plugin creates:
8
+
9
+ - `~/.dsh/mcp.json` (empty, valid) and `~/.dsh/mcp.README.md`;
10
+ - for each project session: `.dsh/agents/`, `.dsh/commands/`, `.dsh/rules/`, `.dsh/hooks.json`, `.dsh/verify.json`, `.dsh/mcp.json`, `.dsh/PROJECT.md`, `.dsh/README.md`, `.dsh/.gitignore`, `.dsh/.kit-scaffold.json`.
11
+
12
+ Scaffolding is idempotent and never overwrites existing files. It **does not** create `hooks.trusted` or `mcp.trusted`: running project hooks/servers stays an explicit decision.
13
+
14
+ ## Hooks — `.dsh/hooks.json`
15
+
16
+ ```json
17
+ {
18
+ "hooks": {
19
+ "PreToolUse": [{ "matcher": "write|edit", "command": "node .dsh/hooks/pre-tool.mjs", "timeoutMs": 30000 }],
20
+ "PostToolUse": [{ "matcher": "write|edit", "command": "npm run lint -- --fix" }],
21
+ "Stop": [{ "command": "node .dsh/hooks/stop.mjs" }],
22
+ "FileChanged": [{ "matcher": "\\.(html|css|tsx)$", "command": "npm run check:css" }],
23
+ "SessionStart": [{ "command": "node .dsh/hooks/session.mjs" }]
24
+ }
25
+ }
26
+ ```
27
+
28
+ Hooks do not run until you trust them:
29
+
30
+ ```text
31
+ /hooks trust
32
+ /hooks off
33
+ ```
34
+
35
+ - `PreToolUse` exit **2** blocks the tool call; other non-zero codes are reported but do not block.
36
+ - `Stop` exit **2** steers the agent with the hook output instead of closing the turn.
37
+ - `FileChanged` runs before a write/edit and can block with exit 2.
38
+ - The hook receives JSON on stdin: event, tool/file, arguments, project and session id.
39
+ - Commands run with the project cwd, `DSH_PROJECT_DIR`, `DSH_SESSION_ID`, a timeout (max 120 s) and bounded output.
40
+
41
+ ## Custom agents — `.dsh/agents/<name>.md`
42
+
43
+ ```md
44
+ ---
45
+ name: reviewer
46
+ description: Ревью диффа, тестов и рисков
47
+ model: deepseek-flash
48
+ tools: read, grep, bash
49
+ ---
50
+
51
+ Ты ревьюер. Проверяй дифф, тесты, права и секреты. Верни только findings.
52
+ ```
53
+
54
+ Use:
55
+
56
+ ```text
57
+ project_agent action=list
58
+ project_agent action=run name=reviewer task="Проверь текущий дифф"
59
+ ```
60
+
61
+ The child runs in its own context through the DSH `subagents` service and returns only its final text.
62
+
63
+ `tools`, `permission` and `model` are enforced, not just documentation:
64
+
65
+ - `tools: read, grep` — the child receives a deny for any other tool;
66
+ - `permission: read-only` — write/edit/apply_patch and mutating shell commands are denied;
67
+ - `permission: workspace-write` — writes are allowed, subject to the parent's guardrails;
68
+ - `model` — passed as the child's model option.
69
+
70
+ Enforcement is a global `tools/pre-execute` gate keyed by the reserved child
71
+ session id, so the child cannot escape it by calling another tool name.
72
+
73
+ ## Commands
74
+
75
+ Built in:
76
+
77
+ | Command | What it does |
78
+ |---|---|
79
+ | `/init` | creates `.dsh/PROJECT.md` and `.dsh/rules/project.md` |
80
+ | `/doctor` | hooks, agents, commands, trust and checkpoints |
81
+ | `/verify` | runs `.dsh/verify.json` commands or `npm test` |
82
+ | `/hooks status\|trust\|off` | manage hook trust |
83
+ | `/checkpoint [label]` | safe git checkpoint |
84
+ | `/rewind [id]` | list or restore checkpoints |
85
+ | `/project list\|<name> [args]` | project commands from `.dsh/commands/*.md` |
86
+
87
+ Project commands are intentionally behind `/project`: DSH command names are process-wide, so a direct `/deploy` alias would bind to whichever workspace was first. `.dsh/commands/deploy.md` becomes `/project deploy`.
88
+
89
+ ## Checkpoints
90
+
91
+ `/checkpoint` creates an unreachable tree under `refs/dsh-agent-extensions/<id>` using a **temporary git index**. Your staged changes and HEAD are not touched. `/rewind <id>` restores tracked files from that tree with `git restore --source=... --worktree`, so files created after the checkpoint are not deleted.
92
+
93
+ Auto-checkpoint runs before the first write in a session, at most once per 10 minutes, and skips `.dsh`, `node_modules`, `dist`, `build` and `coverage`.
94
+
95
+ ## Limits
96
+
97
+ - Hooks are arbitrary process execution: trust only repositories you control.
98
+ - Subagent model/tool restrictions depend on the DSH provider; `tools` is not enforced here.
99
+ - MCP manager is not included: the current profile has no MCP service/package to attach it to. Add it when an MCP host plugin is installed.