purpose
Li+ Desktop を AI ランタイムではなくローカルのチャットルームとして再設計する。二体の AI エージェント(Lin / Lay)と人間が同一の部屋で会話し、機能・ツール・認証・MCP は各 CLI がそのまま持つ。アプリが持つのは部屋の壁だけ。
狙いは liplus-language が自ら未達と記している基盤層である。
Substrate caveat: physical event-driven substrate remains polling-on-input (Claude Desktop lacks --channels); judgment-layer Sheepdog reached, substrate-layer Sheepdog deferred.
判断層の Sheepdog は到達済みで、保留されているのは基盤層のみ。本 issue はそこを閉じる。
premise
検証済み
-
channel による双方向疎通を実測で確認した(2026-08-19)。 机上確認ではなく往復の実走。
- 計測値: サーバが
notifications/claude/channel を push(14:11:00.017)→ ユーザー入力を一切与えない状態でエージェントが自発的に反応し、返信用 MCP tool を呼び返した(14:11:10.059)。往復約 10 秒(モデル思考時間込み)。
- 検証環境: Claude Code CLI
2.1.209 / Windows / winpty で PTY を与えた対話セッション / 依存ライブラリなしの生 JSON-RPC で書いた最小 MCP サーバ。
- 入力路 = channel notification、出力路 = 通常の MCP tool。webhook 版の一方向 channel と異なり、会話に必要な双方向が成立する。
-
成立条件(すべて実測で確定) — 以下はいずれも外すと不通になる。
- MCP サーバは
.mcp.json 等へ 名前で正式登録が必須。--mcp-config によるファイル渡しでは channel 側が名前を解決できず no MCP server configured with that name で失敗する。
- 起動フラグは
--dangerously-load-development-channels server:<name> を 単独指定。--channels を併記すると同一サーバが二重登録され、非 dev 側のエントリが allowlist で弾かれて全体が不通になる。
- エントリはタグ必須。
server:<name> または plugin:<name>@<marketplace>。
--print(--input-format / --output-format stream-json を含む)では push が届かない。対話セッションが必須。
- ホストが initialize で申告する capability は
roots / elicitation のみで、フラグの有無に関わらず変化しない。claude/channel を宣言するのは サーバ側であり、ホストはそれを消費する側。
--channels / --dangerously-load-development-channels はいずれも --help 非掲載(2.1.209)。バイナリ内に実装が存在する。
-
対話セッションの保持に PTY が必要。 上記により --print 系の pipe 接続では channel が動かないため、アプリは各 CLI を対話モードで起動し PTY で保持する必要がある。本リポジトリの PTY 実装(spawn_pty / write_pty / resize_pty / kill_pty、実証済み)はこの用途で必要になる。
-
部屋のルールはサーバ側 instructions で全エージェントに配布できる。 実測では、当該ターンで返信を指示していないにもかかわらずエージェントが返信 tool を呼んだ。駆動源は MCP サーバが initialize 時に返す instructions 文字列。部屋の作法をアプリ側から一元的に与えられる。
-
配布には allowlist 経路が必要。 自作サーバは Anthropic の承認済み channel allowlist に載っていないため --dangerously-load-development-channels が要り、起動ごとに警告バナーが出る。同フラグはローカルの channel 開発専用と明示されている。正規経路は plugin としてマーケットプレイス経由で allowlist に載ること(plugin:<name>@<marketplace>)。組織向けには managed settings の channelsEnabled / allowedChannelPlugins がある。
-
対話を GitHub 経由にしてはならない。 rules/task/task.md が両者を別物として定義している(Issue body = judgment record / Dialogue message = history)。かつ書き込み量は実測済みの制約を持つ: 2026-08 のアカウント凍結により Liplus-Project/liplus-language の #271〜#1726、約 1,325 件が他アカウントから不可視になった。エージェント間の会話を書き込みとして流すと、この分類器に正面から当たる。
-
参照実装と本リポジトリは実装言語が異なる。 参照実装(Liplus-Project/github-webhook-mcp local-mcp/src/index.ts)は TypeScript / Node、本リポジトリは Rust + TypeScript。したがって二択になる。
- (a) Rust へ移植し MCP サーバをアプリ本体へ内蔵する。 プロセスは 1 つで済むが、参照実装は書き直しとなり、channel のプレビュー仕様が動くたびに Rust 側の改修が要る。
- (b) Node のサイドカーとして同梱する。 実証済みの実装をほぼそのまま使え、仕様追随が軽い。プロセスは増える。
- 推奨は (b)。 上記の疎通検証も Node の最小サーバで通しており、実測の裏付けがある。
未検証
なし。着手前に確認すべき技術的前提は解消済み。
constraints
- アプリは部屋であってランタイムではない。 現行
docs/0-requirements.md が掲げる「アダプター層・タスク層・オペレーション層を UI 側に内包し、CLI にはモデル層のみを渡す」方針は本 issue で撤回する。Li+ の L6 Adapter Layer は基盤を所有しないための層であり、内包は反転にあたる。所有した瞬間に MCP 管理・OAuth・設定 UI をすべて自前で抱えることになり、ニッチ化と保守費はその代償として必ず発生する。
- 単一ベンダー構成とする(Codex を対象から外す)。 二ベンダーによる独立性確保とサブスク枠の分散は取り下げる。構造を単純化し、Codex 側 channel 相当の有無という未検証前提を消すための決定。代償: 常駐する全エージェントが同一の利用枠(5 時間枠)を共有する。同時発話数と常駐エージェント数を設計側で抑えること。
- 配布形態は段階を分ける。 第一段階 = 開発者自身の環境で動かす(
--dangerously-load-development-channels)。第二段階 = plugin として allowlist に載せ、一般配布可能にする。第二段階は実装ではなく手続きのトラックであり、第一段階の完了条件には含めない。
- Claude Desktop の置き換えではない。 単独作業は Desktop、並列複数体の対話は本アプリ、と用途で分ける。同一の Li+ が両方に乗ることは L6 が保証している。
- プレビュー結合を受容する。 channel は experimental capability であり、仕様変更がアプリに波及する。早期採用の代償として明示的に受容する。
- 現行実装は動作するがバグが多く、再設計を前提とする。 PTY / config 層は実証済みかつ上記 premise により必要であるため再利用する。
stream_parser.rs および spawn_stream_pty / spawn_stream_pipe(計約 970 行)はハンドラ登録のみでフロントから未使用であり、かつ「CLI 出力をパースして channel push を検出する」という本設計とは逆向きのモデルに基づくため、引き継がない。
- 実装変更と docs 更新は同一 PR。
target files
docs/0-requirements.md — architecture 節の全面改稿(内包方針の撤回、チャットルーム構成への差し替え)
src-tauri/ — MCP サーバ実装(channel notification 送出 + 返信 tool)、および対話セッション保持のための PTY 層
src/ — チャット UI(現行のタブ / ターミナル表示からの再設計)
関連
Liplus-Project/github-webhook-mcp local-mcp/src/index.ts — channel 実装の参照元
Liplus-Project/liplus-language — 基盤層 Sheepdog 未達の記述(adapter/claude/CLAUDE.md 冒頭 Concept framing)
purpose
Li+ Desktop を AI ランタイムではなくローカルのチャットルームとして再設計する。二体の AI エージェント(Lin / Lay)と人間が同一の部屋で会話し、機能・ツール・認証・MCP は各 CLI がそのまま持つ。アプリが持つのは部屋の壁だけ。
狙いは
liplus-languageが自ら未達と記している基盤層である。判断層の Sheepdog は到達済みで、保留されているのは基盤層のみ。本 issue はそこを閉じる。
premise
検証済み
channel による双方向疎通を実測で確認した(2026-08-19)。 机上確認ではなく往復の実走。
notifications/claude/channelを push(14:11:00.017)→ ユーザー入力を一切与えない状態でエージェントが自発的に反応し、返信用 MCP tool を呼び返した(14:11:10.059)。往復約 10 秒(モデル思考時間込み)。2.1.209/ Windows / winpty で PTY を与えた対話セッション / 依存ライブラリなしの生 JSON-RPC で書いた最小 MCP サーバ。成立条件(すべて実測で確定) — 以下はいずれも外すと不通になる。
.mcp.json等へ 名前で正式登録が必須。--mcp-configによるファイル渡しでは channel 側が名前を解決できずno MCP server configured with that nameで失敗する。--dangerously-load-development-channels server:<name>を 単独指定。--channelsを併記すると同一サーバが二重登録され、非 dev 側のエントリが allowlist で弾かれて全体が不通になる。server:<name>またはplugin:<name>@<marketplace>。--print(--input-format/--output-format stream-jsonを含む)では push が届かない。対話セッションが必須。roots/elicitationのみで、フラグの有無に関わらず変化しない。claude/channelを宣言するのは サーバ側であり、ホストはそれを消費する側。--channels/--dangerously-load-development-channelsはいずれも--help非掲載(2.1.209)。バイナリ内に実装が存在する。対話セッションの保持に PTY が必要。 上記により
--print系の pipe 接続では channel が動かないため、アプリは各 CLI を対話モードで起動し PTY で保持する必要がある。本リポジトリの PTY 実装(spawn_pty/write_pty/resize_pty/kill_pty、実証済み)はこの用途で必要になる。部屋のルールはサーバ側
instructionsで全エージェントに配布できる。 実測では、当該ターンで返信を指示していないにもかかわらずエージェントが返信 tool を呼んだ。駆動源は MCP サーバが initialize 時に返すinstructions文字列。部屋の作法をアプリ側から一元的に与えられる。配布には allowlist 経路が必要。 自作サーバは Anthropic の承認済み channel allowlist に載っていないため
--dangerously-load-development-channelsが要り、起動ごとに警告バナーが出る。同フラグはローカルの channel 開発専用と明示されている。正規経路は plugin としてマーケットプレイス経由で allowlist に載ること(plugin:<name>@<marketplace>)。組織向けには managed settings のchannelsEnabled/allowedChannelPluginsがある。対話を GitHub 経由にしてはならない。
rules/task/task.mdが両者を別物として定義している(Issue body = judgment record/Dialogue message = history)。かつ書き込み量は実測済みの制約を持つ: 2026-08 のアカウント凍結によりLiplus-Project/liplus-languageの #271〜#1726、約 1,325 件が他アカウントから不可視になった。エージェント間の会話を書き込みとして流すと、この分類器に正面から当たる。参照実装と本リポジトリは実装言語が異なる。 参照実装(
Liplus-Project/github-webhook-mcplocal-mcp/src/index.ts)は TypeScript / Node、本リポジトリは Rust + TypeScript。したがって二択になる。未検証
なし。着手前に確認すべき技術的前提は解消済み。
constraints
docs/0-requirements.mdが掲げる「アダプター層・タスク層・オペレーション層を UI 側に内包し、CLI にはモデル層のみを渡す」方針は本 issue で撤回する。Li+ の L6 Adapter Layer は基盤を所有しないための層であり、内包は反転にあたる。所有した瞬間に MCP 管理・OAuth・設定 UI をすべて自前で抱えることになり、ニッチ化と保守費はその代償として必ず発生する。--dangerously-load-development-channels)。第二段階 = plugin として allowlist に載せ、一般配布可能にする。第二段階は実装ではなく手続きのトラックであり、第一段階の完了条件には含めない。stream_parser.rsおよびspawn_stream_pty/spawn_stream_pipe(計約 970 行)はハンドラ登録のみでフロントから未使用であり、かつ「CLI 出力をパースして channel push を検出する」という本設計とは逆向きのモデルに基づくため、引き継がない。target files
docs/0-requirements.md— architecture 節の全面改稿(内包方針の撤回、チャットルーム構成への差し替え)src-tauri/— MCP サーバ実装(channel notification 送出 + 返信 tool)、および対話セッション保持のための PTY 層src/— チャット UI(現行のタブ / ターミナル表示からの再設計)関連
Liplus-Project/github-webhook-mcplocal-mcp/src/index.ts— channel 実装の参照元Liplus-Project/liplus-language— 基盤層 Sheepdog 未達の記述(adapter/claude/CLAUDE.md冒頭 Concept framing)