メインコンテンツまでスキップ

DeepSeek Harness:エージェントループそのものがプラグインであるエージェント

上級

DeepSeek Harness(コマンド名は dsh)は、DeepSeekが公開しているオープンソースのエージェントハーネスです。2026年8月13日にGitHubに登場し、本日時点でスターは242,626、フォークは29,081、ライセンスはMIT、実装言語はTypeScriptです。2026年10月1日に、DeepSeekが署名付きのデスクトップ版インストーラーを追加したことで、再びHacker Newsのトップページに載りました。

キャッチコピーはリポジトリの説明文にある*「Everything is a Plugin.」*の一文です。このフレーズは、これまでに公開されたほぼすべてのエージェントフレームワークのREADMEに載っていて、たいていは「プラグイン用のフォルダがあります」という意味にすぎません。ここではもっと強力で、風変わりな意味を持ちます。docs/architecture.md ではっきり述べられているとおり、モデルアダプター、ツールレジストリ、セッションログ、そしてエージェントループそのものがプラグインであり、「そのためそれぞれを設定によって置き換えられる」のです。フォークすることなく、YAMLファイルからエージェントループを削除して、自作のものに差し替えられます。

この設計には、優れた結果もあれば、高くつく結果もあります。このページでは、ランディングページを読むだけではわからない部分を扱います。

What you'll learn
  • 「すべてがプラグイン」から何が得られるのか、そしてその土台であるフレームワークCordisが実際に何を保証するのかを理解する
  • 既存のClaude Codeのhooks.jsonをdsh内で実行し、ブリッジを通ってどのサブセットが動くのかを把握する
  • dshをClaude、GPT、社内ゲートウェイに接続する方法と、OAuthによるサブスクリプションが使えない理由を知る
  • PTCモード(run_code)を、うっかりではなく意図して使う
  • 三つのサンドボックスモードを、それぞれが実際に使っているカーネルのプリミティブと照らして読む
  • 一つにつき1時間を失う五つの設定の落とし穴を避ける

60秒でわかる概要​

Guided walkthrough1 of 5
  1. `npx @deepseek-ai/dsh web` でwebプロファイルが起動し、URL(`http://127.0.0.1:3080`)が表示されてブラウザが開きます。クローンもビルドも不要です。実行したディレクトリが既定のワークスペースのルートになりますが、新規のWeb UIではワークスペースが選択されておらず、追加するまで入力欄は無効のままです。

「すべてがプラグイン」は設計を支える主張である​

dsh の下層にあるのはCordisです。これはリポジトリ内(vendor/)に同梱されているプラグインフレームワークで、プロジェクトが引用しているarXiv論文A Programming Paradigm for Spatiotemporal Composability(arXiv:2608.25512、2026年8月26日投稿、北京大学とDeepSeek-AIの著者による)で解説されています。論文の二つの考え方は、ハーネスの実行時の挙動にそのまま対応しています。

  • 時間的な合成可能性 — コンポーネントを取り除いたとき、その副作用を完全に元へ戻せること。ハーネスでは ctx.effect() がこれにあたります。プロンプトのセクション、ツールのスキーマ、モデルアダプター、プロバイダー、リスナーは、すべて元に戻せる効果としてインストールされます。そのため、プラグインをアンロードすると、登録内容が順序どおりに巻き戻され、孤立したものが残りません。
  • 空間的な合成可能性 — 依存関係がリアクティブに解決されること。プラグインは inject で必要なサービスを宣言し、Cordisは、それらのサービスが揃うまでプラグインを起動しません。維持すべき起動シーケンスはなく、読み込み順は、宣言された要件から自然に決まります。

サービスは、共有コンテキスト上の安定したキーを占有します。この名前がアーキテクチャそのものです。

サービスキー所有するもの
ctx.llmLLMアダプターのレジストリ。モデルとの接合部
ctx.toolsツールレジストリと、スコープ付きの実行パイプライン
ctx.agentLoop既定のエージェントループドライバー
ctx.agents稼働中のエージェントのレジストリ
ctx.sessions追記専用の SessionEvent ログ
ctx.systemPromptシステムプロンプトの組み立て
ctx.fsファイルシステムへのアクセス
ctx.subprocessサブプロセスの実行
ctx.sandboxサブプロセスの閉じ込め
ctx.subagentsサブエージェントへの委任
ctx.ptcRuntimerun_code のためのプログラム実行
ctx.credentials認証情報との接合部

リポジトリはこれらをケイパビリティシーム(capability seams)と呼び、それぞれを三つの役割に分けています。サービスを宣言するパッケージ、実装するパッケージ、利用するパッケージです。ctx.sandbox は packages/sandbox/sandbox が宣言し、sandbox-local と sandbox-windows-acl が実装し、tool-bash とPTCランタイムが利用します。実装を差し替えれば、利用側のコードを一切編集しなくても、すべての利用側が追従します。

プラグイン間の通信は型付きイベントで行われ、宣言された五つのディスパッチモードがあります。このモードは、イベントの公開契約の一部です。

モードawait するか順序値を返すか
emitしない登録順返さない
waterfallしない登録順返す
parallelする全部同時返さない
serialする登録順返す
bailしない登録順、最初のbailで停止返す

waterfall が特に興味深いのは、これが周囲をラップするミドルウェアだからです。リスナーは (...args, next) を受け取り、next() を呼べば、ラップされたかもしれない結果を連鎖の次へ渡し、next() を呼ばずに返れば、そこで処理を打ち切ります。「このツールを実行してよいか?」のような、判断が一つに決まるイベントでは、打ち切ることこそが設計意図です。判断を握るポリシーのリスナーは、委譲せずに返します。一方、注釈を付けるだけのリスナーは、必ず委譲しなければなりません。denyの判定を返すClaude Codeのフックを書いたことがあるなら、この形はすでにご存じでしょう。違いは、ここではそれがシェルの呼び出しではなく、ネイティブの拡張機構であることです。

エージェントループはターン(ゼロ回以上のステップ)とステップ(モデルへの1回のリクエストとそのツール呼び出し)で動き、公開されている拡張シーケンスは agent/pre-step → agent/request → llm/stream → tools/* → step/end です。これらがフックポイントです。ループにパッチを当てるのではなく、ループを購読して聴くのです。

すでにClaude Codeを使っている人にとって重要な三つのこと​

1. 既存のClaude Codeの hooks.json を実行できる​

これは dsh について最も報じられていない事実です。packages/hooks には三つのパッケージが入っています。共通のエンジンである hook-protocol、hooks-claude-code、hooks-codex です。Claude Codeのブリッジを既存の hooks.json に向けると、セッションの開始、プロンプトの到着、ツールの実行、実行の停止の各タイミングで、フックが dsh の中で動きます。グループのREADMEは、できることを明記しています。モデルに見えるメッセージ付きでプロンプトやツール呼び出しをブロックする、会話にコンテキストを追加する、実行の継続を要求する、の三つです。

限界も同じくらい明記されており、移行を計画する前に確認すべき点です。各統合は、元のツールが文書化しているコマンドフックのサブセットだけをサポートします。 つまり、command タイプのフックは移植できます。そのサブセットの外にあるClaude Codeの挙動に依存するものは移植できません。信頼しているフック層があるなら(Claude Codeのフックを参照)、これは書き直しではなく、「ガードレールを持ち込む」本当の道筋になります。

2. Claudeに接続できる。ただしサブスクリプションでは使えない​

同梱のカタログに含まれるプロバイダー一覧には、anthropic と openai が名前で入っています。カタログにないもの(中継サーバー、社内ゲートウェイ、自前運用のサーバーなど)については、カスタムプロバイダーのフォームで、プロバイダーID、ベースURL、認証情報、そしてAPIプロトコルを入力します。選べるプロトコルは三つだけです。OpenAI Chat Completions、OpenAI Responses、Anthropic Messagesです。cordis.patch.yml では、それぞれ openai-completions、openai-responses、anthropic-messages として保存されます。

つまずきやすい点が二つあります。

  • 一つのプロバイダーは一つのプロトコルしか話せません。 OpenAI形式とAnthropic形式の両方を提供するゲートウェイには、一つではなく二つのプロバイダーエントリが必要です。
  • OAuthでのサインインには対応していません。 プロバイダーのガイドが、Codexを例に直接述べています。OAuthでサインインするプロバイダーは「まだここではサポートされていません」。つまり課金はAPIキーによる従量制であり、すでに支払っている席(シート)は使えません。既存のアシスタントのサブスクリプションで dsh を動かせると期待していたなら、従量課金のトークン代を見込んでください。計算方法はプロバイダー別のAIコストにあります。

モデル検出ボタンもあり、エンドポイントに、どのモデルを提供しているかを問い合わせます。便利ですが、心に留めておくべき注意点があります。組み込みのプロバイダーは、ベースURLがゲートウェイを指していても、常にインストール済みのカタログから応答されます。ゲートウェイが実際に何を提供しているかを見たければ、カスタムプロバイダーとして追加する必要があります。そうしないと、DeepSeekが同梱したリストを自分に読み返しているだけになります。

3. run_code はcodemodeであり、第一級のランタイムである​

packages/ptc-runtime は、ツールレジストリがモデルに run_code として提示するものの裏にあるケイパビリティ群です。契約は次のとおりです。モデルは一つのプログラムを書き、そのプログラムがホストの提供する関数を通常の非同期呼び出しとして呼び出します。返ってくるのは、プログラムが出力した内容と戻り値だけです。途中のツール結果ではありません。20回の往復でもありません。

詳細は次のとおりです。

  • TypeScriptバックエンドは、解決されたサンドボックスポリシーのもとで、各プログラムを新しく管理されたNodeプロセスで実行します。
  • 各実行は、以前のプログラムの状態を持たずに始まります。 頼れる暗黙のREPLセッションはありません。状態は、ファイルか戻り値で引き継いでください。
  • 失敗は例外ではなく結果として返るため、呼び出し側は診断したり、モデルに渡したりできます。
  • 実験的なPythonバックエンドもあります。NodeホストとCPythonのサブプロセスの間でfd-3のワイヤープロトコルを使い、本当にCPythonが必要なときのために用意されています。

このパターンが初めてなら、なぜこれほどコンテキストを節約できるのかを最もわかりやすく解説しているのは、Pi 1.0とcodemodeの技です。トランスクリプトに入らないツール結果は、トランスクリプトを膨らませようがありません。ここでも同じ理屈が当てはまります。違いは、dsh ではプログラムのランタイムが固定のサンドボックス選択ではなく、差し替え可能な接合部(ctx.ptcRuntime)になっていることです。

サンドボックス:三つのモード、三つのカーネルプリミティブ、そして率直な但し書き​

三つのモードは、Codexを設定したことがあるなら見覚えがあるでしょう。

モードサブプロセスがファイルに対してできること
read-only読み取りのみ
workspace-writeセッションのワークスペース配下にのみ書き込み可
danger-full-access無制限

さらに興味深いのはバックエンドの表で、あなたのマシンで実際にポリシーを強制しているものが何かがわかります。

  • Linux — bwrap、次点のフォールバックとしてLandlock。
  • macOS — Seatbelt。
  • Windows — 制限付きトークン。書き込み制限のバックエンドとして sandbox-windows-acl を使います。閉じ込められた子プロセスは、ワークスペースと専用の一時ディレクトリにしか書き込めません。

拒否された呼び出しは、ユーザーが承認する一度限りのエスカレーションを通じて再試行できます。つまりこのポリシーは、確認を挟んで先へ進む境界であり、越えられない壁ではありません。

そして但し書きです。これはパッケージのREADME自身が述べていることで、「サンドボックスされている」と言う人には、そのまま引用して伝えるべきです。閉じ込めは「同じ世界の中」だけです。 ホストのカーネルとホストのファイルシステムを共有します。コンテナ、マイクロVM、リモート実行環境のような本物の隔離は、ここには一切登録されません。代わりに、ケイパビリティ全体を置き換えます。

SAFETY.md は、24万2千スターのリポジトリとしては珍しいほど率直で、初回の実行の後ではなく前に読む価値があります。そこには、ハーネスがモデルの生成したコードを実行し、サードパーティのプラグインを読み込み、ネットワークにアクセスし、プロセス、認証情報、ファイルに触れられること、サンドボックス、承認プロンプト、権限制御が、到達可能なものへの被害を防ぐという固有の保証はないこと、そしてこのソフトウェアは「安全または本番利用可能なものとして扱ってはならない」ことが書かれています。推奨事項は、地味ですが正しいものです。使い捨てのVMまたはコンテナを使う、プロジェクトの範囲内にあるものはバックアップを取る、リスクを受け入れる場合を除いて機微な認証情報を置かない、です。ローカルで実行するどのハーネスにも同じ考え方が当てはまります。ローカルおよびハイブリッドエージェントの保護とサンドボックスと認証情報のマスキングを参照してください。

知っておく価値のある小さなガードのグループもあります。timeout-policy と repeat-tool-reminder です。後者は、モデルが同じツールをループで呼び続けるという失敗モードへの注意喚起です。

セッションログこそが製品である​

dsh は、セッションをバージョン付きのJSONLファイル(session.vN.jsonl[.zstd])として永続化し、バージョン間にはマイグレーションの連鎖があります。これは ctx.sessionPersistence という接合部を通して行われ、同梱の実装は session-persistence-jsonl です。コミットされるイベントには、turn/start、step/start、user/message、assistant/message、tool/result、turn/end があります。

その背後にある不変条件は、dsh を一度も使わない人でも真似する価値があります。「モデルに見えたものは、ログに残る」。モデルが見たすべての入力を、ログから再構成できなければなりません。ライブイベントはUIをリアルタイムで動かすために別に存在し、明示的に、真実の記録ではないとされています。

この一つのルールが、周辺のパッケージを成り立たせています。

  • session-query-sqlite — JSONLをgrepする代わりに、SQLiteからセッションを照会できます。
  • dsh-session-projection と ctx.sessionProjections — ゼロから再生するのではなく、セッションの状態を差分で畳み込みます。
  • llm-replay と token-meter(「リプレイによるトークン計測」) — 記録されたセッションを再生してそのトークンコストを計測します。二つのプロンプトやモデルの変更を、雰囲気ではなく同一の入力で比較する方法です。
  • compaction-tool-result-pruner — モデルを使わないツール結果の刈り込みと説明されています。つまり、モデルに要約させる費用を払わずに、トランスクリプトを縮めます。Claude自身のやり方とは、コンテキストのコンパクションで比較できます。

エージェントの実行をデバッグしようとして、ログに記録されていたのがモデルが受け取ったバイト列ではなく描画されたUIだった、という経験があるなら、この不変条件が多くの機能より価値がある理由はすでにおわかりでしょう。

ここでのMCPは、グローバルなレジストリではなく、サーバーごとのプラグインである​

dsh は、stdioとStreamable HTTPの両方でMCPを話し、ネゴシエーション、ディスカバリー、検証、キャンセルには公式SDKを使います。設計上の選択は、一覧にする価値があるほど変わっています。

  • サーバーはオプトインで、サーバー一つにつきプラグインのエントリが一つです。 サーバーを見せたいCordisのスコープごとに、@deepseek-ai/dsh-mcp-client のエントリを一つずつ設定します。意図的に共有の ctx.mcp サービスはありません。クライアントは接続プラグインであり、ツールレジストリの利用者です。
  • サーバーを設定しなければ、MCPのコストもかかりません。 設定済みのサーバーが一つも見えない呼び出し元には、ネイティブモードでもPTCモードでも、MCPのプロンプトテキストもMCPのツールも渡されません。「少しのセクション」ではなく、ゼロバイトです。これは思う以上に重要です。MCPツールの本当のコストを参照してください。
  • 公開されるツール名にはサーバー名が含まれるので、二つのサーバーに同名のツールがあっても区別されます。serverName は、登録スコープ内で一意でなければなりませんが、別々のエージェントスコープなら再利用できます。
  • サーバーの指示は、ログに残るシステムプロンプトに加わり、クライアントの maxInstructionBytes で上限が決まります。冗長なサーバーがこっそりプロンプトを占有することはありません。ただし、これは悪意のあるサーバーがモデルに語りかけるチャネルでもあります。その攻撃面はMCPツールポイズニングとラグプルで説明しています。
  • ツール一覧の更新に失敗しても、前の世代のツールが保持されるので、セッションの途中でツールが消えることはありません。また、プロトコルのリビジョンを強制する製品設定はなく、ネゴシエーションはSDKがサポートするリビジョンに従います。

設定:五つのレイヤーと、プロバイダーを食べてしまうオーバーライド​

プロファイルのディレクトリには、package.json と cordis.patch.yml があります。package.json には、ツリー外のプラグインの依存関係と、順序付きの bundles リストを持つ dsh.profile マニフェストが入ります。cordis.patch.yml は自分用のパッチ層です。合成されたツリーは、空のルートの上に、次の順序で構築されます。

Guided walkthrough1 of 5
  1. バンドルは、まずdshのインストール先から解決されます(`@deepseek-ai/dsh-base`、`dsh-web-app`、`dsh-headless`、`dsh-sdk-app`、`dsh-sdk-minimal`、`dsh-acp-app`)。次に、pnpmがツリー外のプラグインをインストールするプロファイル自身の `node_modules` から解決されます。`dsh-base` は共通の土台で、モデルアダプター、ツール、永続化、サンドボックスポリシーが入っています。バンドルは、`package.json` の `dsh` フィールドで自分自身を宣言します。

YAMLでHMRを有効にしていれば、dsh-hmr がプロファイルのマニフェストと二つのパッチファイルを監視し、直列化された一度のリロードで全レイヤーを再合成します。有効でなければ、変更は再起動時に反映されます。

1時間を失う五つの落とし穴​

  1. Cordisの設定オーバーライドは、エントリの設定全体を置き換えます。 プロバイダーのガイドが明記しています。既存のオーバーライドを編集するときは、他のフィールドと他のプロバイダーを自分で保持しなければなりません。一つのプロバイダーを不用意にパッチすると、残りを削除したことになります。cordis.patch.yml で起こせるミスのうち、最も高くつくものです。
  2. プロバイダーIDは変更できません。 リクエスト、保存済みセッション、モデルの既定値、認証情報への参照が、すべてこれをキーにしています。名前を変えるには、新しいプロバイダーを追加して古いものを削除します。表示名、ベースURL、プロトコル、認証情報、モデル一覧は編集できます。
  3. --dump-config-schema はプラグインのコードをインポートします。 他のdumpフラグと違い、JSON Schemaを出力するために、合成されたツリーが宣言するプラグインのスキーマを読み込みます。そのため、信頼できないプラグインに向けて実行すると、そのインポート時のコードが実行されます。CLIリファレンスにも、この点に関する専用の安全上の注意書きがあります。--help のようにではなく、サードパーティコードのレビューと同じように扱ってください。
  4. プラグインのバージョン互換性は強制され、回避手段は明示的です。 インストール時とプロファイルの起動時に、宣言されたDSHのピア範囲が、dsh --version が示すランタイムのバージョンと照合されます。互換性のないプラグインには、確認済みの厳密なバージョン例外(allow-version、revoke-version)が必要です。良い衛生管理ですが、プラグインの読み込みを初めて拒否されると驚きます。
  5. すでにリクエストを送ったセッションは、自分のログに記録されたモデルを保持し続けます。 既定のモデルを変更しても、稼働中のセッションが遡って切り替わることはありません。また、保存済みの既定値が削除されたプロバイダーを指していると、別のものを選ぶまで入力欄がブロックされます。どちらも正しい挙動ですが、午前1時にはバグに見えます。

実行する​

Web UIを起動し、続けてヘッドレスの単発実行を行う。クローンもビルドも不要

# Web UI on http://127.0.0.1:3080, workspace defaults to the invoking directory
npx @deepseek-ai/dsh web

# One persisted session, final answer to stdout, then exit — the CI shape
npx @deepseek-ai/dsh --profile headless "summarize this repo and list its main packages"

# Serve automation clients over ACP stdio (editor integrations)
npx @deepseek-ai/dsh --profile acp

# Inspect the composed config tree WITHOUT booting it
npx @deepseek-ai/dsh --profile web --dump-config

# Manage a profile's plugins (forwards to pnpm inside the profile directory)
npx @deepseek-ai/dsh plugin --profile web add some-dsh-plugin

dshをAnthropic Messagesを話すゲートウェイに接続する($DSH_HOME/profiles/web/cordis.patch.yml)

# WARNING: a Cordis config override replaces the ENTIRE entry config.
# Include every provider you want to keep, not just the new one.
- id: llm-pi-ai
config:
  providers:
    my-anthropic-gateway:
      apiKeyEnv: GATEWAY_API_KEY
      api: anthropic-messages      # or openai-completions / openai-responses
      baseURL: https://gateway.example/v1
      models:
        - id: some-text-model
        - id: some-vision-model
          input: [text, image]     # omit to inherit the catalog's input types

Claude Codeのガードレールを持ち込む

# The Claude Code hook bridge runs your existing command hooks inside dsh.
# Only the command-hook subset documented by Claude Code is supported.
# Hooks can: block a prompt or a tool call with a MODEL-VISIBLE message,
# add conversation context, or require the run to continue.
#
# Check the bridge's own README for the current config field names before
# wiring this up — the 0.2 line is a developer preview and they can move:
#   packages/hooks/hooks-claude-code/README.md
#
# Verify enforcement the same way you would in Claude Code: a hook that is
# configured but never fires is worse than no hook, because you trust it.

位置づけ​

ハーネスを研究するのではなく選ぶのであれば、率直な要約はこうです。dsh は、現在公開されているオープンなハーネスの中で、アーキテクチャの面で最も興味深く、そして、いざというときに頼れる土台としては最も準備が整っていません。これは同プロジェクト自身の安全性ファイルが述べていることです。プラグインモデルは、競合のものより確かに強力です。ctx.agentLoop を差し替えられることは、ほとんどのハーネスでは、いくら払ってもできません。そしてフックのブリッジがあるため、導入は一か八かの賭けにはなりません。

一方で、latest タグはリリース候補、セキュリティ監査は未実施、互換性を損なう変更が予告されており、プロバイダーの仕組みはAPIキーを前提としています。分野全体の比較は、コーディングエージェントCLIの比較とローカルのコーディングエージェントを参照してください。これを動かすモデルとして最も有力なものは、DeepSeek-V4.1-Flashを参照してください。

Enter キーまたはスペースキーでカードを裏返します。左右の矢印キーでカードを移動できます。用語を表示しました。
1 / 15

Check yourself

0/7
  1. DeepSeek Harnessで、設定によって置き換えられ「ない」ものはどれですか?
  2. すでに支払っているサブスクリプションを使って、dshをClaudeで動かしたいと考えています。どうなりますか?
  3. cordis.patch.ymlの `llm-pi-ai` を編集して、`providers` の下に新しいゲートウェイを一つだけ書いて追加しました。結果はどうなりますか?
  4. macOSでは、`workspace-write` は実際に何に頼っていますか?
  5. dshがセッションを再生してそのトークンコストを計測できるのはなぜですか?
  6. MCPサーバーを一つも設定しない場合、モデルには何が見えますか?
  7. 信頼できないプラグインに対して実行「すべきでない」dumpフラグはどれですか?

情報源とさらに読む​

  • deepseek-ai/deepseek-harness — リポジトリ本体:README、スター数とフォーク数、MITライセンス、dsh-plugin トピック。
  • docs/architecture.md — プラグインに関する主張、サービスキー、プロファイルとバンドル、ターン/ステップのループ、セッションログの不変条件。
  • docs/cordis-primer.md — 五つの考え方で見るCordis、五つのディスパッチモード、waterfallのセマンティクス、ローダーの設定。
  • docs/capability-seams.md — 生成されたサービスグラフ:すべての ctx.* キーと、その所有者、実装、利用者。
  • SAFETY.md — ハーネスがあなたのマシンに対して何をしうるか、そして「安全または本番利用可能ではない」という明示的な表明。
  • packages/sandbox/README.md — 三つのモード、プラットフォームごとのバックエンド、エスカレーション、「同じ世界の中だけ」。
  • packages/hooks/README.md — Claude CodeとCodexのフックブリッジ、およびコマンドフックのサブセットという制限。
  • packages/ptc-runtime/README.md — run_code の契約、新規プロセスでの実行、実験的なPythonバックエンド。
  • docs/subsystems/mcp.md — サーバーごとのクライアントプラグイン、スコープの規則、名前の名前空間化、maxInstructionBytes、プロトコルのネゴシエーション。
  • docs/user/guide/providers.md — プロバイダーID、三つのAPIプロトコル、OAuthの制限、認証情報の保存、オーバーライドの警告。
  • apps/cli/README.md — 起動モード、プロファイルの合成順序、バンドル名、dsh plugin、dumpフラグ、バージョン例外。
  • DeepSeek Harnessの製品ページ — デスクトップ版インストーラー(macOS Apple Silicon用 .dmg、Windows 64ビット用 .exe)とプレビューの位置づけ。
  • arXiv:2608.25512 — A Programming Paradigm for Spatiotemporal Composability。プロジェクトが引用しているCordisの論文。
  • awesome-dsh-plugin — dsh-plugin トピック向けの、コミュニティ製プラグインの一覧。

次に読む​