dsh-capability-panel 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PureCraft
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ # Multilingual consistency record: the git blob hash of each side as of the last
2
+ # confirmed-consistent state. All languages carry equal authority; after editing
3
+ # any side, bring the others along and re-record with:
4
+ # git hash-object README.md README.zh.md README.ja.md README.ko.md
5
+ README.md: ca1f0521a3609fed95b9b8200956df8c80340d27
6
+ README.zh.md: 73c764569b4a07744934b1b87061b08b5a160a94
7
+ README.ja.md: 9cd021cc996ce51331888f0df4c34731febcab68
8
+ README.ko.md: 435a742d333af455dbf2d9a934c3054939c7ef07
package/README.ja.md ADDED
@@ -0,0 +1,110 @@
1
+ # dsh-capability-panel
2
+
3
+ [English](README.md) | [中文](README.zh.md) | 日本語 | [한국어](README.ko.md)
4
+
5
+ **DeepSeek Harness のエージェントが今まさに到達できるものを可視化し、セッション単位・プリセット単位で切り替える。**
6
+
7
+ 現在の会話の能力面を表示するパネル:すべてのスキル・MCP サーバー・システムツールについて、実際にコンテキスト内にあるかどうかの状態と、次のモデルステップから即座に効くスイッチを備えます。
8
+
9
+ ![ライブセッションの能力パネル:ロード状態ピル付きスキル、サーバーごとの MCP、行ごとのスイッチ](docs/images/panel-session.png)
10
+
11
+ ---
12
+
13
+ ## 速見(エージェント向けクイックリファレンス)
14
+
15
+ | | |
16
+ |---|---|
17
+ | 概要 | [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh`)の web プラグイン。現在のセッションのスキル・MCP サーバー・システムツールと、その真のコンテキスト内状態を一覧し、個別に切り替えるパネル |
18
+ | 用途 | 「なぜエージェントはこのスキルを知らないのか」の解明。ロード済みスキルがプルーニング/コンパクションを生き残ったかの確認。特定のツールや MCP サーバーをこのセッションだけで無効化。プリセットごとのデフォルト能力セットの設定。無効化後にブロックされた呼び出し回数の計測 |
19
+ | インストール | `dsh plugin --profile web add dsh-capability-panel`(その後 dsh を再起動) |
20
+ | 要件 | dsh web プロファイル、dsh ≥ 0.1.2-rc.1。`@deepseek-ai/*` の peer はすべてホストが提供 |
21
+ | データ | `$DSH_HOME/settings.yaml` の `capability-panel` 名前空間。統計は `$DSH_HOME/capability-panel/stats.jsonl`。loopback API `/api/capability-panel` |
22
+ | パッケージ | npm の `dsh-capability-panel`。bundle id は `capability-panel` |
23
+
24
+ ## なぜ
25
+
26
+ スキルが*インストールされている*ことと、*今モデルのコンテキストに入っている*ことは別の事実です——そして「なぜエージェントがこれを知らないのか」に答えるのは後者だけです。その間にはコンテキスト管理が挟まります:ツール結果プルーナーは長いペイロードを切り詰め、コンパクションは歴史の区間を要約に置き換えます。5 分前にロードされたスキルは、モデルの視野から部分的にも完全にも消えているかもしれません。
27
+
28
+ また、ある会話でモデルに特定のツールを使わせたくないだけ、ということもあります——プラグインをアンインストールするのではなく、設定ファイルを編集して再起動するのでもなく。ただこのセッションで、次のステップから。
29
+
30
+ ## 機能
31
+
32
+ - **正確なロード状態。** 各スキルは、モデルが次のリクエストで実際に見るものを報告します:`loaded`(完全な指示がコンテキスト内)/ `truncated`(プルーナーが首尾を残し中間を削除)/ `evicted`(コンパクションが完全に除去)/ `not loaded`。累計ロード回数付きで、除去後に再ロードされたスキルは `loaded ×2` と読めます。
33
+ - **再起動しても消えないセッション単位のスイッチ。** 現在の会話でスキル・ツール・MCP サーバーまるごとをオフに。次のプロンプト組み立てから適用され、dsh の再起動後もそのセッションに紐づいたまま復元されます。他のセッションや会話履歴には一切触れません。
34
+ - **プリセットのデフォルト。** 設定 → 能力パネル で、エージェントプリセットごとのデフォルト能力セットを保存。以後に作成・復元されるセッションがそれを継承します。プリセットのデフォルトはあくまで起点で、セッション内で上書きできます。
35
+ - **MCP をサーバーごとにグループ化。** 2 つのサーバーに 200 個のツールがあっても見通せます。サーバーごと 1 行に畳み、1 回の書き込みで全体を切り替え。
36
+ - **ブロック回数。** オフにした後もモデルがその能力を呼び続けた場合、パネルがカウントします——モデルが記憶から行動しているシグナルです。
37
+ - **ワンクリックでコマンド入力。** スキル行の紙飛行機ボタンが `/skill-name` を入力欄に入れます。あなたの Enter を待つだけです。
38
+ - **高速フィルタ。** 名前・説明・状態ラベルで絞り込めます("truncated" や "已截断" でも可)。ヒットした説明は自動展開。
39
+ - **UI 言語に追従。** パネル文言はホストに合わせて中国語と英語を切り替えます。
40
+ - **軽量。** ランタイム依存ゼロ、ゼロコピー読み取り、バックグラウンド処理なし——パネルは開いたときだけ読みます。
41
+
42
+ ## プロダクション品質
43
+
44
+ - **充実したテスト**: 390+ のテスト。typecheck・型認識 lint・100% カバレッジゲート(ステートメント/分岐/関数/行)を CI で push と PR のたびに強制。
45
+ - **失敗をごまかさない**: いずれかの読み取り(スキルレジストリ、セッションビュー、設定ストア)が失敗しても、パネルは部分データと明確なデグレード通知を表示——読み取り失敗を空リストに見せかけません。
46
+ - **書き込み競合なし**: プリセットのデフォルトとセッションスイッチは 1 つの直列化書き込みキューを共有し、2 つのパネルが同時に書いても互いを上書きしません。
47
+ - **ホストの足を引っ張らない**: agent 作成リスナーは完全に失敗を隔離——プラグインのどんな例外もセッション開始を止めません。
48
+ - **ローカルファースト、ネットワーク不要**: データルートは loopback のみを受け付け、プラグインは外部呼び出し・テレメトリ・サードパーティサービスを一切使いません——すべての状態はローカルの settings.yaml と 1 つの JSONL に留まります。
49
+ - **巨大なセッションでも瞬時に開く**: 6 万イベント・数十 MB のログを持つセッションでも、パネルは即座に開きます——ゼロコピーの surface 読み取り、開いたときの 1 回だけ、ポーリングもバックグラウンド処理もなし。
50
+ - **履歴を保全するスイッチ**: スイッチは会話履歴を決して書き換えません——無効化された能力はログにそのまま残り、「これらはオフ」のノートは組み立てごとに再計算されます。すべてのスイッチは元に戻せる決定であり、不可逆な手術ではありません。
51
+ - **公式の拡張ポイントのみ**: すべての能力は dsh の正式な接缝(`tools.restrict`、`system-prompt/assemble`、settings 名前空間、UI slots)から来ており、モンキーパッチはなし——ホストのアップグレードで壊れにくい構造です。
52
+ - **テーマはタダ**: 色はすべてホストの design token、アイコンはホストのアイコンセット——ライト/ダークや言語切り替えはホストに自動追従し、テーマコードの保守は不要です。
53
+ - **i18n フレンドリー**: パネル文言はホストの UI 言語(中国語/英語)に追従し、ドキュメントは 4 言語で章立てを揃えています。
54
+
55
+ ## インストール
56
+
57
+ ```bash
58
+ dsh plugin --profile web add dsh-capability-panel
59
+ # または
60
+ dsh plugin --profile web add github:pure-craft/dsh-capability-panel
61
+ ```
62
+
63
+ インストール後は dsh の再起動が必要です。
64
+
65
+ ## 使い方
66
+
67
+ 会話を開き、入力欄右側のコンテキストアイコンをクリックすると、パネルが上に開きます。
68
+
69
+ - 上部の 3 つのタブ:**Skills N** / **MCP N** / **Tools N**
70
+ - 各行右側のスイッチは即時反映——リフレッシュも再起動も不要
71
+ - 行をクリックすると説明を展開
72
+ - 上部のフィルタは名前・説明・状態ラベルを検索
73
+ - オフにした行は淡色表示になり、モデルのシステムプロンプトにも「オフにした能力」が明示されます
74
+
75
+ `run_code` は予約された Code Mode トランスポートで、レジストリがマスクを禁止しているため、スイッチはオンのまま固定です。
76
+
77
+ 2 つのスコープ、同じスイッチ:**入力欄のパネル**は目の前のセッションに紐づき(再起動後もそのセッションと共に復元)、**設定 → 能力パネル**は以後のすべてのセッションの起点を決めます。
78
+
79
+ ![設定 → 能力パネル:プリセットごとのデフォルト能力](docs/images/panel-settings.png)
80
+
81
+ ## 仕組み
82
+
83
+ **構造的に軽量。** プラグインはランタイム依存を一切持たず——React・UI プリミティブ・すべての `@deepseek-ai/*` はホストが提供——読み取りもゼロコピーです。ロード状態は live セッションのインメモリ surface(モデルが次に見るもの)から来ており、永続ログを毎回折り畳み直すことはありません。
84
+
85
+ スイッチは次のプロンプト組み立てへの薄いオーバーレイ(スキルは同名シャドウ、ツールはレジストリマスク)と、組み立てごとに再計算される告知ノートだけです。セッションの切り替えはセッション自身の id でプラグインの設定名前空間に保存されるため、復元されたセッションは自分のスイッチだけを正確に取り戻し、会話ログには何も書き込まれません。
86
+
87
+ ## データの保存場所
88
+
89
+ - プリセットのデフォルトとセッション単位のスイッチ位置:`$DSH_HOME/settings.yaml` の `capability-panel` 名前空間(セッション単位のスイッチは `sessions.<sessionId>` 配下、最大 200 セッション、古いものから eviction)。ハーネスはロードされていないプラグインのセクションを決して削除しないため、アンインストール後も残ります。
90
+ - ブロック統計:`$DSH_HOME/capability-panel/stats.jsonl`。`curl 'http://127.0.0.1:3080/api/capability-panel/stats'` で直接読めます。
91
+
92
+ データルートは loopback 呼び出しのみを受け付けます。
93
+
94
+ ## 開発
95
+
96
+ ```bash
97
+ pnpm install
98
+ pnpm dev # watch ビルド
99
+ pnpm build # ホスト側とクライアント側の両方をビルド
100
+ pnpm test # テスト
101
+ pnpm typecheck # 型チェック
102
+ pnpm lint # oxlint(type-aware ルール含む)
103
+ pnpm check # typecheck + lint + test(100% カバレッジゲート)
104
+ ```
105
+
106
+ ホスト側の変更は dsh の再起動が必要です。クライアント側は `dsh web` と watch ビルドの併用でホットスワップします。
107
+
108
+ ## ライセンス
109
+
110
+ [MIT](LICENSE)
package/README.ko.md ADDED
@@ -0,0 +1,110 @@
1
+ # dsh-capability-panel
2
+
3
+ [English](README.md) | [中文](README.zh.md) | [日本語](README.ja.md) | 한국어
4
+
5
+ **DeepSeek Harness 에이전트가 지금 실제로 도달할 수 있는 것을 확인하고, 세션 단위 또는 프리셋 단위로 전환하세요.**
6
+
7
+ 현재 대화의 capability 표면을 보여주는 패널: 모든 스킬, MCP 서버, 시스템 도구의 실제 인컨텍스트 상태와, 다음 모델 스텝부터 바로 적용되는 스위치를 제공합니다.
8
+
9
+ ![라이브 세션의 capability 패널: 로드 상태 필이 붙은 스킬, 서버별 MCP, 행별 스위치](docs/images/panel-session.png)
10
+
11
+ ---
12
+
13
+ ## 한눈에 보기 (에이전트 빠른 참조)
14
+
15
+ | | |
16
+ |---|---|
17
+ | 무엇 | [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh`) 웹 플러그인: 현재 세션의 스킬·MCP 서버·시스템 도구와 그 실제 인컨텍스트 상태를 나열하고 개별 전환하는 패널 |
18
+ | 용도 | "왜 에이전트가 이 스킬을 모르지?" 해결. 로드된 스킬이 프루닝/컴팩션에서 살아남았는지 확인. 특정 도구나 MCP 서버를 이 세션에서만 끄기. 프리셋별 기본 capability 세트 설정. 비활성화 후 차단된 호출 횟수 계측 |
19
+ | 설치 | `dsh plugin --profile web add dsh-capability-panel`(설치 후 dsh 재시작) |
20
+ | 요구 사항 | dsh web 프로필, dsh ≥ 0.1.2-rc.1. `@deepseek-ai/*` peer는 모두 호스트가 제공 |
21
+ | 데이터 | `$DSH_HOME/settings.yaml`의 `capability-panel` 네임스페이스. 통계는 `$DSH_HOME/capability-panel/stats.jsonl`. loopback API `/api/capability-panel` |
22
+ | 패키지 | npm의 `dsh-capability-panel`. bundle id는 `capability-panel` |
23
+
24
+ ## 왜
25
+
26
+ 스킬이 *설치되어 있다*는 것과 *지금 모델의 컨텍스트에 있다*는 것은 서로 다른 사실입니다. 그리고 "왜 에이전트가 이것을 모를까?"에 답하는 것은 후자뿐입니다. 그 사이에는 컨텍스트 관리가 있습니다: 도구 결과 프루너는 긴 페이로드를 잘라내고, 컴팩션은 히스토리 구간을 요약으로 대체합니다. 5분 전에 로드된 스킬은 모델의 시야에서 부분적으로 또는 완전히 사라졌을 수 있습니다.
27
+
28
+ 또는 그저 이 대화에서 모델이 특정 도구를 사용하지 않았으면 할 때도 있습니다——플러그인을 제거하거나 설정 파일을 수정하고 재시작하는 것이 아니라, 그냥 이 세션에서, 다음 스텝부터요.
29
+
30
+ ## 기능
31
+
32
+ - **정확한 로드 상태.** 각 스킬은 다음 요청에서 모델이 실제로 보는 것을 보고합니다: `loaded`(전체 지시문이 컨텍스트에 있음) / `truncated`(프루너가 앞뒤를 남기고 중간을 잘라냄) / `evicted`(컴팩션이 완전히 제거) / `not loaded`. 누적 로드 횟수 포함——제거 후 다시 로드된 스킬은 `loaded ×2`로 읽힙니다.
33
+ - **재시작해도 유지되는 세션 단위 스위치.** 현재 대화에서 스킬·도구·MCP 서버 전체를 끕니다. 다음 프롬프트 조립부터 적용되며, dsh 재시작 후에도 해당 세션에 바인딩된 채 복원됩니다. 다른 세션이나 대화 히스토리는 건드리지 않습니다.
34
+ - **프리셋 기본값.** 설정 → capability 패널에서 에이전트 프리셋별 기본 capability 세트를 저장합니다. 이후 생성되거나 복원되는 세션이 이를 상속합니다. 프리셋 기본값은 시작점일 뿐, 세션에서 언제든 재정의할 수 있습니다.
35
+ - **서버별 MCP 그룹화.** 두 서버에 200개의 도구가 있어도 한눈에 볼 수 있습니다. 서버당 한 행으로 접고, 한 번의 쓰기로 전체를 전환합니다.
36
+ - **차단 횟수.** 끈 후에도 모델이 해당 capability를 계속 호출하면 패널이 카운트합니다——모델이 기억에서 행동하고 있다는 신호입니다.
37
+ - **원클릭 명령 입력.** 스킬 행의 종이비행기 버튼이 `/skill-name`을 입력창에 넣습니다. Enter만 누르면 됩니다.
38
+ - **빠른 필터링.** 이름, 설명 또는 상태 라벨로 검색("truncated" / "已截断" 모두 가능). 일치하는 설명은 자동으로 펼쳐집니다.
39
+ - **UI 언어 추종.** 패널 문구는 호스트에 따라 중국어와 영어로 전환됩니다.
40
+ - **경량.** 런타임 의존성 제로, 제로카피 읽기, 백그라운드 작업 없음——패널은 열릴 때만 읽습니다.
41
+
42
+ ## 프로덕션 등급
43
+
44
+ - **철저한 테스트**: 390+ 테스트. typecheck, 타입 인식 lint, 100% 커버리지 게이트(문/분기/함수/행)를 CI에서 모든 push와 PR에 강제합니다.
45
+ - **정직한 실패**: 읽기(스킬 레지스트리, 세션 뷰, 설정 저장소) 중 하나라도 실패하면 패널은 부분 데이터와 명시적인 degraded 안내를 표시합니다——읽기 실패를 빈 목록으로 위장하지 않습니다.
46
+ - **쓰기 경합 없음**: 프리셋 기본값과 세션 스위치는 하나의 직렬화된 쓰기 큐를 공유하므로, 두 패널이 동시에 써도 서로를 덮어쓰지 않습니다.
47
+ - **호스트에 부담 없음**: agent 생성 리스너는 실패를 완전히 격리——플러그인의 어떤 예외도 세션 시작을 막지 못합니다.
48
+ - **로컬 퍼스트, 네트워크 제로**: 데이터 라우트는 loopback 호출만 허용하고, 플러그인은 외부 호출·텔레메트리·서드파티 서비스를 전혀 사용하지 않습니다——모든 상태는 로컬 settings.yaml과 하나의 JSONL에만 남습니다.
49
+ - **거대한 세션에서도 즉시 열림**: 6만 이벤트, 수십 MB 로그의 세션에서도 패널은 바로 열립니다——제로카피 surface 읽기, 열릴 때 한 번만 읽고, 폴이나 백그라운드 작업 없음.
50
+ - **히스토리를 보존하는 스위치**: 스위치는 대화 히스토리를 절대 다시 쓰지 않습니다——비활성화된 capability는 로그에 그대로 남고, "이것들은 꺼짐" 노트는 조립할 때마다 재계산됩니다. 모든 스위치는 되돌릴 수 있는 결정이지, 돌이킬 수 없는 수술이 아닙니다.
51
+ - **공식 확장 포인트만 사용**: 모든 capability는 dsh의 공식 이음새(`tools.restrict`, `system-prompt/assemble`, settings 네임스페이스, UI slots)에서 옵니다——몽키 패칭이 없어 호스트 업그레이드에 훨씬 강합니다.
52
+ - **테마는 공짜**: 모든 색상은 호스트 design token이고 모든 아이콘은 호스트 아이콘 세트——라이트/다크와 언어 전환이 호스트를 자동으로 따르며, 유지할 테마 코드가 없습니다.
53
+ - **i18n 친화**: 패널 문구는 호스트 UI 언어(中文/English)를 따르고, 문서는 4개 언어로 섹션을 맞춰 유지합니다.
54
+
55
+ ## 설치
56
+
57
+ ```bash
58
+ dsh plugin --profile web add dsh-capability-panel
59
+ # 또는
60
+ dsh plugin --profile web add github:pure-craft/dsh-capability-panel
61
+ ```
62
+
63
+ 설치 후 dsh를 재시작해야 적용됩니다.
64
+
65
+ ## 사용법
66
+
67
+ 대화를 열고 입력창 오른쪽의 컨텍스트 아이콘을 클릭하면 패널이 위로 열립니다.
68
+
69
+ - 상단의 세 탭: **Skills N** / **MCP N** / **Tools N**
70
+ - 각 행 오른쪽의 스위치는 즉시 적용——새로고침도 재시작도 불필요
71
+ - 행을 클릭하면 설명이 펼쳐집니다
72
+ - 상단 필터는 이름, 설명, 상태 라벨을 검색
73
+ - 꺼진 행은 흐리게 표시되고, 모델의 시스템 프롬프트에도 "사용자가 끈 capability"가 명시됩니다
74
+
75
+ `run_code`는 예약된 Code Mode 트랜스포트로, 레지스트리가 마스킹을 금지하므로 스위치가 켜진 채로 고정됩니다.
76
+
77
+ 두 스코프, 같은 스위치: **입력창의 패널**은 눈앞의 세션에 바인딩되고(재시작 후에도 함께 복원), **설정 → capability 패널**은 이후 모든 세션의 시작점을 결정합니다.
78
+
79
+ ![설정 → capability 패널: 프리셋별 기본 capability](docs/images/panel-settings.png)
80
+
81
+ ## 작동 원리
82
+
83
+ **구조적으로 경량.** 플러그인은 런타임 의존성이 전혀 없고——React, UI 프리미티브, 모든 `@deepseek-ai/*`는 호스트가 제공——읽기도 제로카피입니다. 로드 상태는 live 세션의 인메모리 surface(모델이 다음에 볼 내용)에서 가져오며, 영구 로그를 매번 다시 접지 않습니다.
84
+
85
+ 스위치는 다음 프롬프트 조립 위의 얇은 오버레이(스킬은 동명 섀도우, 도구는 레지스트리 마스크)와 조립 시마다 재계산되는 안내 노트뿐입니다. 세션 전환은 세션 고유 id로 플러그인 설정 네임스페이스에 저장되므로, 복원된 세션은 자신의 스위치만 정확히 되찾고, 대화 로그에는 아무것도 기록되지 않습니다.
86
+
87
+ ## 데이터 저장 위치
88
+
89
+ - 프리셋 기본값과 세션 바인딩 스위치 위치: `$DSH_HOME/settings.yaml`의 `capability-panel` 네임스페이스(세션 스위치는 `sessions.<sessionId>` 아래, 최대 200개 세션, 오래된 것부터 eviction). 하니스는 로드되지 않은 플러그인의 섹션을 절대 삭제하지 않으므로, 제거 후에도 직접 지우기 전까지 유지됩니다.
90
+ - 차단 통계: `$DSH_HOME/capability-panel/stats.jsonl`. `curl 'http://127.0.0.1:3080/api/capability-panel/stats'`로 직접 읽을 수 있습니다.
91
+
92
+ 데이터 라우트는 loopback 호출만 허용합니다.
93
+
94
+ ## 개발
95
+
96
+ ```bash
97
+ pnpm install
98
+ pnpm dev # watch 빌드
99
+ pnpm build # 호스트와 클라이언트 양쪽 빌드
100
+ pnpm test # 테스트
101
+ pnpm typecheck # 타입 체크
102
+ pnpm lint # oxlint(type-aware 규칙 포함)
103
+ pnpm check # typecheck + lint + test(100% 커버리지 게이트)
104
+ ```
105
+
106
+ 호스트 측 변경은 dsh 재시작이 필요하고, 클라이언트 측은 `dsh web`과 watch 빌드가 함께 실행 중일 때 핫스왑됩니다.
107
+
108
+ ## 라이선스
109
+
110
+ [MIT](LICENSE)
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # dsh-capability-panel
2
+
3
+ English | [中文](README.zh.md) | [日本語](README.ja.md) | [한국어](README.ko.md)
4
+
5
+ **See what your DeepSeek Harness agent can actually reach right now — and switch it, per session or per preset.**
6
+
7
+ A panel for the live conversation's capability surface: every skill, MCP server, and system tool, with its real in-context state and a switch that takes effect on the very next model step.
8
+
9
+ ![The capability panel in a live session: skills with load-state pills, MCP servers grouped, per-row switches](docs/images/panel-session.png)
10
+
11
+ ---
12
+
13
+ ## At a glance (agent quick reference)
14
+
15
+ | | |
16
+ |---|---|
17
+ | What | A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`) web plugin: a panel that lists the live session's skills, MCP servers, and system tools with their true in-context state, plus switches to toggle them |
18
+ | Use it to | answer "why doesn't the agent know this skill"; see whether a loaded skill survived pruning/compaction; turn a tool or MCP server off for one session only; set per-preset default capabilities; count blocked tool calls after a disable |
19
+ | Install | `dsh plugin --profile web add dsh-capability-panel` (then restart dsh) |
20
+ | Requires | dsh web profile, dsh ≥ 0.1.2-rc.1; all `@deepseek-ai/*` peers provided by the host |
21
+ | Data | `$DSH_HOME/settings.yaml` namespace `capability-panel`; stats at `$DSH_HOME/capability-panel/stats.jsonl`; loopback API `/api/capability-panel` |
22
+ | Package | `dsh-capability-panel` on npm; bundle id `capability-panel` |
23
+
24
+ ## Why
25
+
26
+ A skill being *installed* and a skill being *in the model's context right now* are two different facts — and only the second one answers "why doesn't my agent know this?" Between them sits context management: the tool-result pruner truncates long payloads, and compaction replaces whole spans of history with a summary. A skill you watched load five minutes ago may be partially or fully gone from the model's view, while its load record sits in the durable log forever, pretending otherwise.
27
+
28
+ And sometimes you simply want the model to stop reaching for one tool in one conversation — not uninstall a plugin, not edit a config file and restart. Just this session, from the next step on.
29
+
30
+ This plugin turns both into one panel at the right of the composer.
31
+
32
+ ## Features
33
+
34
+ - **Ground-truth load states.** Every skill reports what the model actually sees on the next request: `loaded` (full instructions in context), `truncated` (the pruner kept head & tail, cut the middle), `evicted` (compaction took it entirely), or `not loaded` — plus a cumulative load count, so a skill reloaded after eviction reads `loaded ×2`.
35
+ - **Per-session switches that survive restarts.** Turn a skill, tool, or whole MCP server off for the current conversation. The switch applies from the next prompt assembly, stays bound to that session across a dsh restart, and never touches another session or the conversation history.
36
+ - **Preset defaults.** Settings → Capability Panel stores the default capability set per agent preset; sessions created or resumed afterward inherit it. Same filter, same grouping, same switches as the session panel — a preset default is a starting point the session can still override.
37
+ - **MCP grouped by server.** Two hundred tools behind two servers stay scannable: collapse to one row per server, flip the whole server in one write.
38
+ - **Blocked-attempt counts.** If the model still calls a capability after you turned it off, the panel counts it — the signal that the model is acting from memory and the switch needs a louder story.
39
+ - **One-click command fill.** A skill row's paper-plane button drops `/skill-name` into the composer, ready for your Enter.
40
+ - **Fast filtering.** Match on name, description, or the visible state pill ("truncated" / "已截断" both work), with matching descriptions auto-expanded.
41
+ - **Lightweight.** Zero runtime dependencies, zero-copy reads, no background work — the panel only reads when open.
42
+ - **Follows the UI language.** Panel copy switches between 中文 and English with the host.
43
+
44
+ ## Production-grade by default
45
+
46
+ - **Thoroughly tested**: 390+ tests with typecheck, type-aware lint, and 100% coverage gates (statements/branches/functions/lines) enforced in CI on every push and PR.
47
+ - **Honest failures**: when any one read fails (skill registry, session view, settings store), the panel shows partial data plus an explicit degraded note — a read failure never masquerades as an empty list.
48
+ - **Race-free writes**: preset defaults and session switches share one serialized write queue, so two panels writing at once cannot clobber each other.
49
+ - **Never a drag on the host**: the agent-created listener is fully failure-isolated — no plugin error can stop your session from starting.
50
+ - **Local-first, zero network**: the data route accepts loopback callers only, and the plugin makes no outbound calls, sends no telemetry, and talks to no third-party service — all state stays in the local settings.yaml and one JSONL file.
51
+ - **Instant even on huge sessions**: on a 60k-event, tens-of-MB session log the panel still opens instantly — zero-copy surface reads, one read per open, no polling, no background work.
52
+ - **History-preserving switches**: a switch never rewrites conversation history — disabled capabilities stay intact in the log, and the "these are off" note is recomputed at every assembly. Every switch is a reversible decision, not irreversible surgery.
53
+ - **Sanctioned seams only**: every capability comes from dsh's official extension points (`tools.restrict`, `system-prompt/assemble`, the settings namespace, UI slots) — no monkey-patching, so host upgrades are far less likely to break it.
54
+ - **Theme comes free**: all colors are host design tokens and all icons come from the host's own set — light/dark and language switches follow the host automatically, no theme code to maintain.
55
+ - **i18n-friendly**: panel copy follows the host's UI language (中文/English), and the docs are kept section-aligned across four languages.
56
+
57
+ ## Install
58
+
59
+ From the marketplace or straight from the repo:
60
+
61
+ ```bash
62
+ dsh plugin --profile web add dsh-capability-panel
63
+ # or
64
+ dsh plugin --profile web add github:pure-craft/dsh-capability-panel
65
+ ```
66
+
67
+ Restart dsh for the install to take effect.
68
+
69
+ Requires a DeepSeek Harness web profile (`dsh web`). All `@deepseek-ai/*` runtime pieces are provided by the host as peer dependencies — there is nothing else to install.
70
+
71
+ ## Usage
72
+
73
+ Open any conversation and click the context icon at the right of the composer; the panel opens upward.
74
+
75
+ - Three tabs across the top: **Skills N** / **MCP N** / **Tools N**, each with its live count
76
+ - The switch at the right of each row takes effect immediately — no refresh, no restart
77
+ - Click the row itself to expand its description
78
+ - The filter box at the top matches name, description, or state label, with an `X / Y` matched count
79
+ - A disabled row renders dimmed, and the model is told in its system prompt that you turned the capability off
80
+
81
+ `run_code` is the reserved Code Mode transport — the registry forbids masking it, so its switch is locked on.
82
+
83
+ Two scopes, same switches: **the composer panel** is bound to the session in front of you (and restored with it after a restart); **Settings → Capability Panel** decides what every later session starts from. Preset defaults are read when a session agent is created — they do not rewrite preset files and do not change agents that are already running.
84
+
85
+ ![Settings → Capability Panel: per-preset default capabilities](docs/images/panel-settings.png)
86
+
87
+ ## How it works
88
+
89
+ **Lightweight by construction.** The plugin ships zero runtime dependencies — React, the UI primitives, and every `@deepseek-ai/*` piece are provided by the host — and its reads are zero-copy: load states come from the live session's in-memory surface (what the model will see next), never re-folded from the durable log, so opening the panel costs a scan of references, not a parse of history.
90
+
91
+ Switches are thin overlays on the next prompt assembly — a same-name shadow for skills, a registry mask for tools — plus a per-assembly note telling the model what you turned off. Session toggles persist under the session's own id in the plugin's settings namespace, so a restored session gets exactly its own switches back, and nothing ever writes to the conversation log.
92
+
93
+ ## Where data lives
94
+
95
+ - Preset defaults and session-bound switch positions: the `capability-panel` namespace in `$DSH_HOME/settings.yaml` (session switches under `sessions.<sessionId>`, kept for up to 200 sessions, oldest evicted first). The harness never drops a section whose plugin is not loaded, so uninstalling keeps these until you delete the section.
96
+ - Blocked-attempt stats: `$DSH_HOME/capability-panel/stats.jsonl`, readable directly at `curl 'http://127.0.0.1:3080/api/capability-panel/stats'`.
97
+
98
+ The data route accepts loopback callers only, keyed on the connection's peer address.
99
+
100
+ ## Development
101
+
102
+ ```bash
103
+ pnpm install
104
+ pnpm dev # watch build
105
+ pnpm build # build both the host and client halves
106
+ pnpm test # run the tests
107
+ pnpm typecheck # typecheck
108
+ pnpm lint # oxlint, including its type-aware rules
109
+ pnpm check # typecheck + lint + test (100% coverage gates)
110
+ ```
111
+
112
+ A change to the host half needs a dsh restart; the client half hot-swaps while `dsh web` and the watch build run together.
113
+
114
+ ## License
115
+
116
+ [MIT](LICENSE)
package/README.zh.md ADDED
@@ -0,0 +1,116 @@
1
+ # dsh-capability-panel
2
+
3
+ [English](README.md) | 中文 | [日本語](README.ja.md) | [한국어](README.ko.md)
4
+
5
+ **看清你的 DeepSeek Harness agent 此刻真正能触达什么——并且随时开关,按会话或按 preset。**
6
+
7
+ 一个面向当前对话能力面的面板:每个技能、每个 MCP 服务器、每个系统工具,都有真实的"在不在上下文里"状态,和一个从下一步模型调用就生效的开关。
8
+
9
+ ![会话中的能力面板:技能带加载状态、MCP 按服务器分组、每行一个开关](docs/images/panel-session.png)
10
+
11
+ ---
12
+
13
+ ## 速查(agent 快速参考)
14
+
15
+ | | |
16
+ |---|---|
17
+ | 是什么 | [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh`)的 web 插件:一个面板,列出当前会话的技能、MCP 服务器、系统工具及其真实的在不在上下文状态,并能逐项开关 |
18
+ | 什么时候用 | 回答"为什么 agent 不知道这个技能";看一个加载过的技能是否挺过了剪枝/压缩;只在当前会话里关掉某个工具或 MCP 服务器;为 preset 设置默认能力集合;统计关闭后被拦截的调用次数 |
19
+ | 安装 | `dsh plugin --profile web add dsh-capability-panel`(然后重启 dsh) |
20
+ | 要求 | dsh web profile,dsh ≥ 0.1.2-rc.1;`@deepseek-ai/*` peer 全部由宿主提供 |
21
+ | 数据 | `$DSH_HOME/settings.yaml` 的 `capability-panel` 命名空间;统计在 `$DSH_HOME/capability-panel/stats.jsonl`;loopback API `/api/capability-panel` |
22
+ | 包 | npm 上的 `dsh-capability-panel`;bundle id `capability-panel` |
23
+
24
+ ## 为什么
25
+
26
+ 技能"装好了"和技能"此刻在模型的上下文里"是两件事——而只有后者能回答"为什么 agent 不知道这个"。两者之间隔着上下文管理:工具结果剪枝器会截断过长的返回,压缩会把整段历史换成一条摘要。你眼看着五分钟前加载过的技能,可能已经部分或全部离开了模型的视野,而它的加载记录还永久躺在日志里,假装一切如常。
27
+
28
+ 有时你也只是想让模型在这一个对话里别再碰某个工具——不是卸载插件,不是改配置文件重启,就只是这一个会话、从下一步开始。
29
+
30
+ 这个插件把这两件事变成输入框右侧的一个面板。
31
+
32
+ ## 功能
33
+
34
+ - **真实的加载状态。** 每个技能报告的是模型在下一次请求里实际能看到什么:`已加载`(完整指令在上下文里)/ `已截断`(剪枝器留下首尾、挖掉中间)/ `已挤出`(被压缩整体吞掉)/ `未加载`——外加累计加载次数,被挤出后重新加载的技能读作"已加载 ×2"。
35
+ - **重启不丢的会话级开关。** 关掉当前会话里的一个技能、一个工具或一整个 MCP 服务器:从下一次提示组装生效,重启 dsh 后随该会话恢复,且绝不碰其他会话、绝不动对话历史。
36
+ - **Preset 默认。** 设置 → 能力面板,为每个 agent preset 存一份默认能力集合;之后新建或恢复的会话继承它。与会话面板同一套筛选、分组和开关——preset 默认只是起点,会话里仍然可以覆盖。
37
+ - **MCP 按服务器分组。** 两个服务器挂着两百个工具也能扫得过来:折叠成每服务器一行,一次开关整组。
38
+ - **拦截计数。** 模型在你关掉某项之后仍然尝试调用,面板会计数——这是"模型在凭记忆行动、开关需要更响亮的告知"的信号。
39
+ - **一键填入命令。** 技能行上的纸飞机按钮把 `/skill-name` 放进输入框,等你自己的回车。
40
+ - **快速筛选。** 按名称、描述或状态文案匹配(搜"已截断"或"truncated"都可以),命中时描述自动展开。
41
+ - **轻量。** 零运行时依赖、零拷贝读取、无后台工作——面板只在打开时读一次。
42
+ - **跟随界面语言。** 面板文案随宿主在中英文之间切换。
43
+
44
+ ## 工程品质
45
+
46
+ - **测试完备**:390+ 测试,typecheck + 类型感知 lint + 100% 覆盖率门槛(语句/分支/函数/行)在 CI 上对每次 push 和 PR 强制执行。
47
+ - **失败诚实**:任何一环读不到(技能注册表、会话视图、设置存储),面板显示部分数据加明确的降级提示——绝不把"读失败"伪装成"列表为空"。
48
+ - **写入不竞态**:preset 默认和会话开关共享一条串行写队列,两个面板同时写也互不覆盖。
49
+ - **不拖累宿主**:agent 创建监听做了完整的失败隔离——插件的任何异常都不会阻止你的会话启动。
50
+ - **本地优先,零网络**:数据路由只接受 loopback,插件没有外呼、没有遥测、没有第三方服务——所有状态只留在本机的 settings.yaml 和一个 JSONL 里。
51
+ - **长会话依然秒开**:6 万事件、几十 MB 日志的会话上,面板即点即开:零拷贝 surface 直读,打开时才读一次,没有轮询和后台任务。
52
+ - **历史保留式开关**:开关永不改写对话历史——被关掉的能力在日志里原样保留,"已关闭"告知在每次组装时现算。每个开关都是可后悔的决定,不是不可逆的手术。
53
+ - **只走官方扩展点**:全部能力来自 dsh 的正式接缝(`tools.restrict`、`system-prompt/assemble`、settings 命名空间、UI slots),没有猴子补丁,宿主升级时更不容易碎。
54
+ - **主题免费**:颜色全部走宿主 design token,图标用宿主图标库——浅色/深色、语言切换都自动跟随,不需要自己维护主题。
55
+ - **国际化友好**:面板文案跟随宿主界面语言(中/英),文档四种语言逐节对齐。
56
+
57
+ ## 安装
58
+
59
+ 从插件市场,或直接从仓库安装:
60
+
61
+ ```bash
62
+ dsh plugin --profile web add dsh-capability-panel
63
+ # 或
64
+ dsh plugin --profile web add github:pure-craft/dsh-capability-panel
65
+ ```
66
+
67
+ 安装后需要重启 dsh 才生效。
68
+
69
+ 要求 DeepSeek Harness 的 web profile(`dsh web`),dsh ≥ 0.1.2-rc.1。所有 `@deepseek-ai/*` 运行时件都由宿主以 peer 依赖形式提供——没有别的要装。
70
+
71
+ ## 使用
72
+
73
+ 打开任意对话,点输入框右侧的上下文图标,面板向上展开。
74
+
75
+ - 顶部三个分区:**技能 N** / **MCP N** / **工具 N**,各带实时计数
76
+ - 每行右侧的开关立即生效——不刷新、不重启
77
+ - 点击行本身展开描述
78
+ - 顶部筛选框匹配名称、描述或状态文案,下方有 `X / Y` 命中计数
79
+ - 被关闭的行变暗,同时模型的系统提示里会被告知"用户关闭了这些能力"
80
+
81
+ `run_code` 是保留的 Code Mode 传输通道——注册表禁止遮罩它,所以它的开关锁定为开。
82
+
83
+ 两个作用域,同一组开关:**输入框里的面板**绑定你眼前的会话(重启后随它恢复);**设置 → 能力面板**决定之后每个会话从什么状态开始。Preset 默认在会话 agent 创建时读取——不改写 preset 文件,也不改变已经在运行的 agent。
84
+
85
+ ![设置 → 能力面板:每个 preset 的默认能力集合](docs/images/panel-settings.png)
86
+
87
+ ## 工作原理
88
+
89
+ **生而轻量。** 插件零运行时依赖——React、UI 组件和全部 `@deepseek-ai/*` 都由宿主提供——读取也是零拷贝:加载状态来自 live session 的内存 surface(模型下一次将看到的内容),从不对持久日志重新折叠,打开面板的代价是一次引用扫描,而不是解析历史。
90
+
91
+ 开关是下一次提示组装上的薄覆盖层——技能用同名影子、工具用注册表遮罩——外加一条组装时现算的"你关了什么"的告知。会话开关以会话自己的 id 持久化在插件设置命名空间里,恢复的会话恰好拿回自己的开关,对话日志永不被写入。
92
+
93
+ ## 数据存放
94
+
95
+ - Preset 默认值与会话绑定的开关位置:`$DSH_HOME/settings.yaml` 的 `capability-panel` 命名空间(会话开关在 `sessions.<sessionId>` 下,最多保留 200 个会话、最旧的先淘汰)。宿主从不丢弃未加载插件的分节,所以卸载后它们还在,直到你手动删除该段。
96
+ - 拦截统计:`$DSH_HOME/capability-panel/stats.jsonl`,可直接读取:`curl 'http://127.0.0.1:3080/api/capability-panel/stats'`。
97
+
98
+ 数据路由只接受 loopback 请求,判定依据是连接对端地址。
99
+
100
+ ## 开发
101
+
102
+ ```bash
103
+ pnpm install
104
+ pnpm dev # watch 构建
105
+ pnpm build # 构建 host 与 client 两半
106
+ pnpm test # 跑测试
107
+ pnpm typecheck # 类型检查
108
+ pnpm lint # oxlint(含 type-aware 规则)
109
+ pnpm check # typecheck + lint + test(100% 覆盖率门槛)
110
+ ```
111
+
112
+ 改动 host 半需要重启 dsh;client 半在 `dsh web` 与 watch 构建同时运行时热替换。
113
+
114
+ ## 许可证
115
+
116
+ [MIT](LICENSE)
@@ -0,0 +1,10 @@
1
+ # dsh-capability-panel bundle patch: mounts this plugin into the composition.
2
+ #
3
+ # Both halves resolve through the official bundle flow: the host entry (data
4
+ # route) comes from `main`, the client entry (__ModuleLoader__ UI) from
5
+ # `dsh.client` in package.json, so no manual dual-entry wiring is needed here.
6
+ #
7
+ # Install: dsh plugin --profile web add <this package, path or git URL>
8
+ - insert:
9
+ - id: capability-panel
10
+ name: 'dsh-capability-panel'