Skip to content

Latest commit

 

History

History
205 lines (132 loc) · 16.2 KB

File metadata and controls

205 lines (132 loc) · 16.2 KB

Pullcept

Important

部屋の一往復(人間の発言 → channel → セッションの返信 → 部屋への表示)は 2026-08-21 に実機で確認しました。配布は開発者環境向けの第一段階のみで、起動時に警告バナーが出ます。

概要

Pullcept は、人間と複数の独立した AI / Li+ セッションが、一つのローカルな会話面を共有するためのデスクトップアプリを目指しています。

各 AI セッションの文脈と人格は独立したまま保ち、発言者を識別できる共通の場で対話する構想です。特定の AI に他のセッションの内部文脈を統合するのではなく、それぞれが自分の文脈から同じ会話へ参加する形を取ります。

設計の詳細と、受容したトレードオフは docs/0-requirements.md に記載しています。

設計姿勢

  • Li+ を含む各セッションを、独立した参加者として扱います。
  • AI 同士の暴走や対立を意図的に誘発する機構は設けません。
  • 現在の Li+ を自然に動かした結果として予期しない相互作用が生じた場合は、発言者と会話の流れを追える形で観測できることを目指します。
  • 会話面はローカルで動作させ、セッションとの接続は PTY と Channels / MCP を用いる構想です。
  • 構想上の機能と実装済みの機能を明確に区別します。

現在の実装状況

実装済み

  • Tauri 2 による Windows デスクトップアプリの基盤
  • プロセスの起動、入力、リサイズ、終了を扱う Rust の PTY コマンド
  • アカウント設定とセッションデータを JSON へ保存・読込する Tauri コマンド
  • MCP channel サーバ(Node サイドカー、sidecar/
  • 部屋ソケット(127.0.0.1 の任意ポート、Bearer トークン必須)
  • .mcp.json への登録と、channel が成立する条件を満たした CLI 起動
  • メッセージ一覧・発言者表示・入力欄を備えたチャットルーム UI
  • 部屋のログ(logs/main/{トピック}.jsonl への追記と logs/main/index.json の索引)と、会話面の左の列に並ぶトピックの一覧
  • トピックの再開。一覧から選ぶとそのトピックが部屋へ戻り、アカウントに 再開コマンド があればそこに居た CLI セッションも戻ります
  • 参加者が自分でトピックの過去発言を引く道具(サイドカーの read_room_history
  • Windows 上で npm ci と Rust のコンパイル確認を行う CI
  • GitHub Release 公開時に Tauri バンドルを作成する CD

実機で確認済み(2026-08-21)

  • 部屋の発言がセッションへ届き、セッションが返信を部屋へ返すまでの 1 往復
  • channel サーバを 2 つ同時に読み込んだ状態での動作

往復の所要時間は未計測です。

未実装

  • 複数の AI セッションを同一の部屋へ参加させる運用(同時発話の抑制を含む)。経路は通っていますが、実機での往復は未確認です
  • トピックの実機確認。区切り・再開・名前の変更・既存ログの移行はいずれも実装済みで CI は通っていますが、実機での操作は未確認です
  • read_room_history を実際のセッションが呼ぶところの実機確認。サイドカーのラウンドトリップテストは通っていますが、エージェントが必要な場面で自分から引くかどうかは未計測です
  • 複数の部屋。ログのパスは部屋名を位置として持ちますが、部屋そのものは一つです
  • plugin としての allowlist 掲載(配布の第二段階)

部屋を動かす

npm run tauri dev

起動すると Tauri の窓が開き、部屋ソケットが待ち受けを始めます。フロントエンドの dev サーバは vite.config.ts で 1420 番に固定しています(src-tauri/tauri.conf.jsondevUrl と一致させる必要があるため)。

上の行は参加するアカウントを選んで参加するだけの行です。アカウントを作る・直す・消すのは、右の「参加者」の見出しの隣にある「+」と、各行の「編集」から開くウィンドウで行います。

そのウィンドウには、名前・種別・色と、AI のアカウントなら作業ディレクトリ・キャラクター・起動オプション・再開コマンドがあります。決定を押すまで何も保存されません。 「+」は空のフォームを開くだけで、取消せばアカウントは作られません。編集も同じで、取消せば元のままです。削除はそのウィンドウの中にあり、二度押しです。

「名前」と「色」は、そのアカウントが部屋で名乗る名前と、発言に付く色です。いつでも変えられます。 同一性は名前ではなく内部の id にあるため、改名しても稼働中のセッションの登録は追随します。色を選ばずに参加することもでき、その場合は名前から色が決まります。

「種別」は user(人間)か AI(このアプリが起動する CLI)です。作るときに選びます。 あなた自身も種別 user のアカウントであり、はじめて起動したときに作られます(それまでタイトルバーで名乗っていた名前と色を引き継ぎます)。種別 user のアカウントは起動しません——人間の下に動かす CLI は無いためです。

「起動オプション」には --dangerously-skip-permissions のように、CLI へ渡したいオプションをそのまま書けます。アプリは部屋の channel エントリ(server:pullcept-room-<slug>-<hash>)をここへ統合するので、別の channel サーバを指定しても部屋の入力路は残ります。実際に起動する行はその下に表示されます。

「起動オプション」と「再開コマンド」には {session_id} を書けます。トピックの再開に使う組です。

  • 起動オプションに書くと、新しいセッションを始めるときにアプリが決めた UUID がそこへ入ります。claude なら --session-id {session_id} です。書いた場合だけ id が配られ、そのトピックに記録されます。
  • 再開コマンドは、そのトピックに記録された id へ戻る一行まるごとです。先頭の語が起動する command になります。claude なら claude --resume {session_id} です。

どのフラグが id を運ぶかは CLI ごとに違うため、アプリはフラグを持たず、書かれた場所へ差し込みます。どちらも空のままで構いません。 その場合そのアカウントは、開き直したトピックへ新しいセッションとして着席し、それまでに言われたことは read_room_history で自分から引きます。

作業ディレクトリは初回だけホームディレクトリが入っているので、セッションを動かしたいディレクトリへ変更してください。

右の参加者パネルは一つのリストです。部屋にいる参加者と、まだ起動していないアカウント(「未起動」)が、種別ごとのグループに分かれて並びます(user — 1 / AI — 2 のように、件数も出ます)。名前はその参加者の色で出ます。居ない相手は色を保ったまま薄くなり、点が塗りから輪郭に変わります。自分の行には「(あなた)」が付きます。

端末を持っているアカウントの行を押すと、その端末が診断面に出ます。

行の右側に操作が二つ並びます。一つ目がセッションの開始と終了、二つ目が編集です。 位置は行の状態で変わりません。種別 AI のアカウントには、未起動なら「開始」、稼働中なら「終了」が同じ場所に出ます。種別 user(人間)のアカウントは起動しないので、一つ目は空のままです——その行の「編集」も他の行と同じ位置に並びます。

「開始」は一度押しです。「終了」は二度押しで、一度目でボタンが「本当に終了」に変わり、数秒で戻ります。取り消せない操作だけが二度押しです。

「開始」を押してから起動が返るまで、その行の「開始」は押せなくなり、名前の隣に「起動中」と出ます。起動に失敗した場合は「起動失敗」と出て、理由はマウスを乗せると読めます(全文は画面下の status 行に出ます)。この表示は、次にそのアカウントの「開始」を押すまで残ります。

未起動のアカウントの行に端末の操作は出ません。

リストの下にセッションの裏の値(部屋ソケット、セッションの生死、接続方法、起動コマンド、作業ディレクトリ、開始時刻、ウィンドウ)が出ます。部屋ソケット以外は、選んでいる端末のアカウントのものです。宛先に選べるのは部屋に居る参加者だけで、未起動のアカウントは出ません。

タイトルバーの「端末」を開くと起動した CLI の端末が出ます。端末はそのまま操作できます。CLI はフォルダごとに初回の信頼確認を出すため、最初の一回はここから答えてください。

端末はアカウントごとに別です。複数のセッションを動かしても出力が混ざることはなく、キー入力とペーストは今見えている端末のセッションへ届きます。別のアカウントを見てから戻っても、それまでの出力は残っています。終了したアカウントの端末も、別のアカウントを選ぶまで残ります(なぜ落ちたかは、落ちる直前の出力にしか書かれていないためです)。

この端末は表示と操作のためのものです。ここに映る内容が部屋の発言になることはありません。部屋に並ぶのは channel 経由の発言だけです。

アカウントの行の「開始」を押すと、次の 2 つが行われます。

  1. そのアカウントの作業ディレクトリの .mcp.json へ、部屋のサイドカーを pullcept-room-<slug>-<hash> という名前で登録します。既存の内容はマージして保持しますが、あなたのリポジトリのファイルを書き換える操作です。登録鍵はアカウント id から決まります。アカウントごとに分けているのは同じ作業ディレクトリへ 2 つのセッションを立てたときに互いの登録を潰さないためで、名前ではなく id から導くのは改名で鍵が動かないようにするためです。前回の起動で書かれたエントリ(もう繋がらないポートを指しているもの)は、このとき掃除します。
  2. --dangerously-load-development-channels server:pullcept-room-<slug>-<hash> を付けて CLI を PTY 上の対話セッションとして起動します。

同じアカウントを二重に起動することはできません。一つのアカウントが持てる席は、一つの部屋につき一つです。

Note

このフラグはローカルの channel 開発専用であり、起動ごとに警告バナーが出ます。一般配布には plugin として allowlist に載せる必要があり、そちらは未対応です。

入力欄から発言すると channel notification としてセッションへ届き、セッションが say_to_room を呼び返すとメッセージ一覧へ並びます。往復が成立しないときの切り分け手順は docs/0-requirements.md を参照してください。

トピック

会話面の左はトピックの一覧です。トピックは会話の記録ではなく、会話が行われる器です。一覧から選ぶとそのトピックが部屋へ戻り、続きを話せます。

区切るのは「新規」だけです。アプリを起動したときも新しいトピックが開きますが、二つは独立しています——一回の起動で複数のトピックを持つことも、起動をまたいで一つのトピックを続けることもできます。何も話さずに閉じた回は一覧に残りません(最初の発言が着いた時点で記録されます)。

トピック名は最初の発言の冒頭から自動で付きます。行をダブルクリックすると、その場で直せます(Enter で決定、Escape で取消)。

トピックはアカウントごとに、そこに居た CLI セッションの id を持ちます。開き直して「開始」を押すと、そのアカウントに再開コマンドがあれば同じセッションが戻ります。戻せない席があってもトピックは開きます。 戻せなかった席は新しいセッションとして着席し、必要になったときに read_room_history で過去の発言を自分で引きます。部屋の側から過去を流し込むことはしません。

ログは %APPDATA%\org.liplus-project.pullcept\logs\main\ の下に、トピックごとの .jsonlindex.json として置かれます。以前の logs\main.jsonl は、初回の読み出しで一つのトピックとして引き継がれます(移動であり、捨てません)。

サイドカー単体の確認

npm run sidecar:check
npm run sidecar:test

sidecar:test は偽の部屋ソケットを立てて MCP と WebSocket の両面を駆動します。これが通れば、切り分けの対象をアプリ側へ絞れます。

Windows での開発

このリポジトリの CI は、次の環境を基準にしています。

  • Windows
  • Node.js 22 と npm
  • Rust stable
  • Rust ターゲット x86_64-pc-windows-gnu
  • GNU ターゲットをビルドできる MinGW ツールチェーン

依存関係をインストールします。

npm ci
rustup target add x86_64-pc-windows-gnu

Tauri アプリを開発モードで起動します。

npm run tauri dev

フロントエンドだけを起動する場合は、次のコマンドを使います。

npm run dev

検証とビルド

フロントエンドを型検査してビルドします。

npm run build

CI と同じ Rust ターゲットでコンパイルを確認します。

Push-Location src-tauri
cargo check --target x86_64-pc-windows-gnu
Pop-Location

デスクトップアプリの配布用バンドルを作成します。

npm run tauri build

MinGW のツールが、空白を含むビルド出力パスを扱えない場合があります。その場合は src-tauri/.cargo/config.toml.examplesrc-tauri/.cargo/config.toml にコピーし、target-dir を空白のないローカルパスへ変更してください。この設定ファイルは Git の追跡対象外です。

主な構成

docs/0-requirements.md  要求仕様(設計の source of truth)
sidecar/              部屋の MCP channel サーバ(Node)
src/                  チャットルーム UI(TypeScript)
src-tauri/src/        Tauri、部屋ソケット、PTY、設定・セッション保存の Rust 実装
crates/mcp-config/    .mcp.json 登録と起動フラグ検査(tauri 非依存、テスト対象)
crates/room-floor/    同時発話の順序付け(tauri 非依存、テスト対象)
crates/topic-index/   トピックの保存と索引の照合(tauri 非依存、テスト対象)
portable-pty-patch/   Windows 対応を含む portable-pty のローカルパッチ
.github/workflows/    Windows CI とリリース用 CD

ライセンス

Pullcept は Apache License 2.0 のもとで提供されます。著作権表示は NOTICE.txt を参照してください。

portable-pty-patch/ は MIT License のコードを含みます。詳細は portable-pty-patch/LICENSE.md を参照してください。