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.
- package/CHANGELOG.md +86 -0
- package/README.md +113 -27
- package/client.js +3121 -32
- package/docs/AGENT-HARNESS.md +144 -0
- package/docs/ARCHITECTURE.md +38 -7
- package/docs/COMPATIBILITY.md +5 -3
- package/docs/DEVELOPMENT.md +56 -0
- package/docs/INSTALL.md +20 -11
- package/docs/LAPTOP-INSTALL.md +96 -0
- package/docs/ROADMAP-3.0.md +353 -0
- package/docs/ROADMAP.md +1 -1
- package/docs/SUBAGENTS.md +25 -0
- package/docs/TEST-0.2.2.md +6 -6
- package/docs/TEST-2.3.0.md +49 -0
- package/docs/TEST-2.7.2.md +46 -0
- package/docs/TOKENS.md +2 -2
- package/docs/TROUBLESHOOTING.md +27 -0
- package/docs/UI-QA.md +28 -0
- package/docs/images/peak-toast-peak.png +0 -0
- package/docs/images/peak-toast-soon.png +0 -0
- package/docs/preview/peak-toast.html +155 -0
- package/doctor.ps1 +122 -0
- package/index.js +18 -1
- package/install.ps1 +99 -0
- package/package.json +29 -6
- package/plugins/dsh-agent-extensions/README.md +99 -0
- package/plugins/dsh-agent-extensions/index.js +167 -0
- package/plugins/dsh-agent-extensions/lib/agents.js +76 -0
- package/plugins/dsh-agent-extensions/lib/checkpoints.js +103 -0
- package/plugins/dsh-agent-extensions/lib/commands.js +255 -0
- package/plugins/dsh-agent-extensions/lib/hooks.js +182 -0
- package/plugins/dsh-agent-extensions/lib/policy.js +84 -0
- package/plugins/dsh-agent-extensions/lib/project.js +144 -0
- package/plugins/dsh-agent-extensions/lib/scaffold.js +151 -0
- package/plugins/dsh-agent-extensions/package.json +9 -0
- package/plugins/dsh-browser-qa/README.md +221 -0
- package/plugins/dsh-browser-qa/cordis.patch.yml +4 -0
- package/plugins/dsh-browser-qa/index.js +165 -0
- package/plugins/dsh-browser-qa/lib/cdp.js +224 -0
- package/plugins/dsh-browser-qa/lib/chrome.js +466 -0
- package/plugins/dsh-browser-qa/lib/pages.js +552 -0
- package/plugins/dsh-browser-qa/lib/qa.js +827 -0
- package/plugins/dsh-browser-qa/lib/ui-gate.js +256 -0
- package/plugins/dsh-browser-qa/package.json +31 -0
- package/plugins/dsh-checkpoints/README.md +22 -0
- package/plugins/dsh-checkpoints/cordis.patch.yml +3 -0
- package/plugins/dsh-checkpoints/index.js +80 -0
- package/plugins/dsh-checkpoints/lib/checkpoints.js +111 -0
- package/plugins/dsh-checkpoints/package.json +25 -0
- package/plugins/dsh-github-review/README.md +131 -0
- package/plugins/dsh-github-review/cordis.patch.yml +3 -0
- package/plugins/dsh-github-review/index.js +536 -0
- package/plugins/dsh-github-review/lib/gh.js +494 -0
- package/plugins/dsh-github-review/lib/normalize.js +662 -0
- package/plugins/dsh-github-review/package.json +28 -0
- package/plugins/dsh-guardrails/README.md +264 -0
- package/plugins/dsh-guardrails/cordis.patch.yml +5 -0
- package/plugins/dsh-guardrails/index.js +389 -0
- package/plugins/dsh-guardrails/lib/hooks.js +262 -0
- package/plugins/dsh-guardrails/lib/modes.js +77 -0
- package/plugins/dsh-guardrails/lib/policy.js +592 -0
- package/plugins/dsh-guardrails/lib/scan.js +451 -0
- package/plugins/dsh-guardrails/lib/secrets.js +274 -0
- package/plugins/dsh-guardrails/package.json +26 -0
- package/plugins/dsh-mcp-manager/README.md +78 -0
- package/plugins/dsh-mcp-manager/client.js +373 -0
- package/plugins/dsh-mcp-manager/index.js +159 -0
- package/plugins/dsh-mcp-manager/lib/api.js +250 -0
- package/plugins/dsh-mcp-manager/lib/client.js +219 -0
- package/plugins/dsh-mcp-manager/lib/config.js +217 -0
- package/plugins/dsh-mcp-manager/lib/manager.js +146 -0
- package/plugins/dsh-mcp-manager/package.json +18 -0
- package/plugins/dsh-mcp-manager/screenshots/modal-390.png +0 -0
- package/plugins/dsh-mcp-manager/screenshots/settings-1440.png +0 -0
- package/plugins/dsh-mcp-manager/screenshots/settings-390.png +0 -0
- package/plugins/dsh-memory-bridge/README.md +161 -0
- package/plugins/dsh-memory-bridge/client.js +2264 -0
- package/plugins/dsh-memory-bridge/cordis.patch.yml +5 -0
- package/plugins/dsh-memory-bridge/docs/images/conflicts.png +0 -0
- package/plugins/dsh-memory-bridge/docs/images/hero.png +0 -0
- package/plugins/dsh-memory-bridge/docs/images/settings-dark.png +0 -0
- package/plugins/dsh-memory-bridge/docs/images/settings-light.png +0 -0
- package/plugins/dsh-memory-bridge/docs/images/settings-mobile.png +0 -0
- package/plugins/dsh-memory-bridge/docs/images/setup.png +0 -0
- package/plugins/dsh-memory-bridge/icon.svg +13 -0
- package/plugins/dsh-memory-bridge/index.js +378 -0
- package/plugins/dsh-memory-bridge/lib/bridge.js +636 -0
- package/plugins/dsh-memory-bridge/lib/github.js +473 -0
- package/plugins/dsh-memory-bridge/lib/merge.js +205 -0
- package/plugins/dsh-memory-bridge/lib/portable.js +314 -0
- package/plugins/dsh-memory-bridge/lib/state.js +565 -0
- package/plugins/dsh-memory-bridge/lib/sync.js +984 -0
- package/plugins/dsh-memory-bridge/locale/en.json +6 -0
- package/plugins/dsh-memory-bridge/locale/ru.json +6 -0
- package/plugins/dsh-memory-bridge/package.json +67 -0
- package/plugins/dsh-peak-guard/README.md +16 -3
- package/plugins/dsh-peak-guard/client.js +223 -8
- package/plugins/dsh-peak-guard/package.json +1 -1
- package/plugins/dsh-plan-mode/README.md +24 -0
- package/plugins/dsh-plan-mode/cordis.patch.yml +3 -0
- package/plugins/dsh-plan-mode/index.js +103 -0
- package/plugins/dsh-plan-mode/lib/plan.js +89 -0
- package/plugins/dsh-plan-mode/package.json +18 -0
- package/plugins/dsh-profile-transfer/client.js +277 -17
- package/plugins/dsh-profile-transfer/index.js +10 -0
- package/plugins/dsh-profile-transfer/package.json +3 -1
- package/plugins/dsh-profile-transfer/transfer.js +101 -2
- package/plugins/dsh-project-memory/index.js +92 -2
- package/plugins/dsh-project-memory/package.json +1 -1
- package/plugins/dsh-repo-map/README.md +26 -0
- package/plugins/dsh-repo-map/cordis.patch.yml +3 -0
- package/plugins/dsh-repo-map/index.js +99 -0
- package/plugins/dsh-repo-map/lib/repo-map.js +170 -0
- package/plugins/dsh-repo-map/package.json +25 -0
- package/plugins/dsh-skill-autopilot/index.js +135 -11
- package/skills/delivery-gate/SKILL.md +31 -0
- package/skills/git-and-ci/SKILL.md +5 -1
- package/skills/manifest.json +31 -6
- package/skills/requirements-and-planning/SKILL.md +3 -0
- package/skills/research-first/SKILL.md +35 -0
- package/skills/research-first/references/query-patterns.md +20 -0
- package/skills/subagent-playbook/SKILL.md +36 -0
- package/skills/subagent-playbook/references/prompts.md +39 -0
- package/skills/ui-craft/SKILL.md +43 -0
- package/skills/visual-qa/SKILL.md +29 -0
- package/skills/visual-qa/references/commands.md +32 -0
- package/skills-baseline.json +246 -0
- 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
|
|
4
|
-
"description": "DeepSeek Harness desktop kit 2.
|
|
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.
|