Read in English
Shelly
ChatGPT に自分の Android スマホを使わせる。操作の承認は、いつも自分の手で。
スマホの中で動く、オープンソースの AI ターミナル兼エージェント実行環境。PC 不要。Termux 不要。クラウドランナー不要。
「Spotify にグランジのプレイリストを保存して」→ スマホで 1 タップ承認 → Spotify は見えない画面で動く → ChatGPT が「完了」→ 本当に入っている。(早送りあり)
3 ステップで試せます:
① Releases から APK をインストール
② Shelly で shelly codex pair を実行し、ChatGPT アプリ(Codex)でペアリング
③ ChatGPT にスマホでやってほしいことを頼む (動画のようなアプリ操作には ClosePaw の Shelly 用ビルドが必要)
役に立ちそう・面白いと思ったら、⭐ を付けてもらえると他の人にも届きやすくなります。
Shelly は自分のアラームで起きて、画面が消えたまま、あなた自身の AI アカウントとローカル LLM、本物のターミナルの上で予約したエージェントを動かすこともできます。下にあるのは、アプリ自身の JNI PTY で動く Codex CLI、APK 同梱の bash / git / Python 3 / Node.js、その隣の API ベースの AI ペインです。
無人での一連のサイクルは、Galaxy Z Fold6 の実機で最後まで検証済み(N=1)です。何が検証済みかはステータスの表で追跡しています。ほかの端末で動かした方は、shelly doctor --report の結果を端末レポートに貼ってください。
スケジュール済みエージェントが端末上で作ったブリーフィング: Perplexity で調査 → ローカル LLM で要約 → すべての項目に出典が付いた markdown ファイル。
デモ ·
クイックスタート ·
マニュアル ·
なぜ Shelly か ·
機能 ·
アーキテクチャ ·
リリースの完全性 ·
ステータス ·
コントリビューション ·
サポート
---
## 動作デモ
**ChatGPT からスマホを動かす ―― Shelly がその橋渡し**
https://github.com/user-attachments/assets/2fe4de3b-1c8f-4171-b61e-a88ddf8664b6
1. ChatGPT アプリ(Codex。`shelly codex pair` で Shelly に接続)で「下北沢の評価の高い古着屋を、Google マップの新しいリストに保存して」と頼むと、ChatGPT がスマホ上で `shelly closepaw --wait ""` を実行します。
2. Shelly が**あなたに**承認を求めます ―― スマホで 1 回だけ(通知か Shelly のチャット)。ChatGPT 自身がスマホ操作を承認することはできません。
3. Shelly がタスクを [ClosePaw](https://github.com/RYOITABASHI/closepaw/releases) に渡し、ClosePaw が裏の仮想ディスプレイで Google マップを操作します。スマホの前面はあなたのまま(ClosePaw のビューアに実行の様子が映ります。クリップでは 4 倍速)。
4. Shelly が ClosePaw の結果を ChatGPT に返し、Google マップにも本当にリストができています。
Shelly 用 ClosePaw 変種(Shelly の署名にピン留め)を使用。キャプション付きで、一部を早送りしています。
**ChatGPT から毎日動くエージェントを登録 ―― あとはスマホが勝手に働く**
https://github.com/user-attachments/assets/bceec161-e5e3-46f1-bc28-35819f09961a
1. ChatGPT から: `shelly agent add "Every day at 16:27, collect the latest AI research papers from arXiv and Hugging Face, pick 3 notable ones and summarize them. Write the summaries in English."`
2. Shelly で 1 回確認するだけ。
3. 16:27 になると ―― ChatGPT もタップも無しで ―― Shelly が起動し、Perplexity で調べ、出典付きのノートを Obsidian(`20_Literature/AI_Papers/<日付>/`)に保存します。翌日以降も毎日。
登録から予約時刻までの待ち時間はカットしています(「3 minutes later」)。画面右上の時計は実時刻です。
**あなたが作業している間に働くエージェント**
https://github.com/user-attachments/assets/ac89f1a9-fecc-4e58-bb37-b33421e862d2
1. 普通の言葉でエージェントをスケジュール: *「In 3 minutes, first search the web with Perplexity for the top 3 on-device AI news stories. Then summarize them with the local LLM. Finally, write a markdown briefing.」*
2. その間に、ターミナルで Python の `JSONDecodeError`。長押し → **Ask AI** で AI ペインに引用し、端末上のモデル(Qwen3.5-2B)が直し方を説明します。
3. `shelly teach start` → 手で直す → `shelly teach stop` で、その手順が再利用可能なワークフローとして保存されます(`shelly workflow run `)。
4. エージェントが自分で発火 ―― Perplexity → ローカル LLM → markdown(クリップでは 16 倍速)―― し、各ステップの受け渡しを自分のチャットスレッドに書き込みます。
5. ブリーフィングを開く: すべての項目に出典が付き、末尾に `## Sources` の一覧が追加されています。
キャプション付きで、一部を早送りしています(エージェントの実行部分は 16 倍速)。
**自律エージェントを、ホーム画面のウィジェットから登録する ―― アプリを開く必要すらない**
https://github.com/user-attachments/assets/fbda309f-ad12-4a6d-a5b8-96b6ee4d4e57
Scouter ウィジェットの ASK ボックスに `@agent ...` と直接打つ(または話しかける)だけ。AI ペインに直接打ったときとまったく同じ確認フロー ―― 同じパース、同じ確認カード ―― に合流し、登録が終わるとスケジュール済みエージェント一覧に次回実行時刻付きで表示されます。
**その下にあるターミナル: 本物の AI コーディング CLI が Android 上でネイティブに動く**
https://github.com/user-attachments/assets/c87ea206-12f8-4b21-9089-0a373b0e8a2a
Termux なし。proot なし。リモート開発サーバーなし。OpenAI Codex ――本物のフル機能コーディング CLI ―― が、Shelly 自前の JNI PTY ―― 手で開いて操作できるのと同じネイティブターミナル ―― の上で直接起動します。
**Ask AI: エラーを長押しして、端末上の AI に引用する**
ターミナルの出力を選択し、選択メニューの **Ask AI** をタップすると、そのテキストが AI ペインの入力欄に下書きとして引用されます。質問を書き足して送信するまで、何も送られません。ローカルモデルを動かしていれば、エラーはスマホの外に一切出ません。
---
## なぜShellyなのか
いま存在するものの多くは、この課題の一部分しかカバーしていません。ターミナルアプリ(Termux など)はシェルをくれますが、AI は載っていません。AI チャットアプリは賢いアシスタントをくれますが、その下にシェルはなく、ファイルにも触れません。クラウド開発環境(Replit など)は両方くれますが、それは手元の端末から遠く離れた「借り物のコンピュータ」の上の話です。クラウド「エージェント」も同じで、どこか別の場所で、自分のものではないファイルに対して動いています。
Shelly の賭けはこうです。ポケットの中のスマホは、あなたが所有している中で最良のエージェントホストである。常に電源が入っていて、常に一緒にいて、しかもあなたのファイル・アカウント・文脈をすでに抱えている。Shelly はそれを自己完結型のエージェントマシンに変え、さらにそのエージェントを本物のターミナル IDE に接地させます。だから、エージェントが勝手にやったことを、あなたは目で見て、検証して、手で動かし直せます。
**2 つのレイヤー、1 本の信頼の鎖:**
- **エージェント層** — やってほしいことを普通の言葉で言うと、Shelly はスケジュール済みエージェントとして登録します。AlarmManager のアラームで、画面が消えたまま起き、あなた自身のキーとローカルモデルで動き、実行したことを報告します。([詳細](#自律エージェント) と、それに付随する[ステータス](#ステータス)の注意書き)
- **ターミナル層** — エージェントにできることはすべて、あなたが対話的に使っているのと同じ端末上のシェルとツールチェーンを通ります。アプリ所有のネイティブ PTY、本物の Codex CLI、同梱の bash / git / Python / Node。エージェントは「信じるしかないクラウドサンドボックス」ではなく、トランスクリプトのレベルまで覗ける、あなた自身のマシンです。
### コピペ問題
ターミナルで AI コーディングツール――Codex でも、ほかの AI CLI でも――を動かしているとします。エラーが出る。コピーする。ChatGPT に切り替える。貼り付ける。「何が悪いの?」と聞く。答えを読む。修正をコピーする。戻る。貼り付ける。実行する。
**7 ステップ。毎回です。**
CLI ベースの AI ツールを使っている開発者には見慣れたワークフローでしょう。ターミナルと AI は別々の世界に住んでいて、その間をつなぐコピペのブリッジは*あなた自身*です。
**Shelly はターミナルと AI を横に並べます。AI はターミナルの出力を自動で読みます。**
**「右側のエラーを直して」** と言えば、Shelly がターミナル出力を読み、エラーを説明し、実行可能なコマンドを生成します。**[Run]** をタップすれば、修正はそのままターミナルペインに着地します。
コピーなし。ペーストなし。タブの行き来なし。
**価値は 4 段階あります:**
- **単一ペイン:** Termux 単体より速く、賢く、使いやすいネイティブターミナル。コンテンツブロック、シンタックスハイライト、タップできるエラー付き。
- **分割ペイン:** ターミナルと AI を横並びに。AI がターミナルの表示内容を読み、ワンタップで修正を実行します。コピペのブリッジは不要です。
- **フルレイアウト:** サイドバー + 最大 4 つのライブペイン + エージェントバー、つまりモバイル IDE。ブラウザペインでドキュメントを見て、右側でコードや Markdown をプレビューし、バックグラウンドで API ベースのエージェントを走らせつつ、ターミナルは常に中心に置いておけます。
- **無人運用:** 普通の言葉でスケジュール済みエージェントを登録すれば、スマホがポケットの中にある間も同じ仕組みが動き、実行結果を知らせてくれます。
**折りたたみ端末では、そのフルレイアウトは「理想」ではなく「初期状態」です。** 折りたたんでいるときの Shelly は単一ペインのターミナル。開けば、同じライブシェルがセッションを再起動することなく、サイドバー + 2×2 グリッドの最大 4 ペイン(ターミナル・AI・ブラウザ・プレビュー)に広がります。Shelly は Galaxy Z Fold6 上で毎日開発されているので、開いた状態のレイアウトは後付けではなく設計上のターゲットです。(CLI のストリーミング中に素早く折り曲げ ↔ 展開を繰り返すケースは、いまも[既知の制限](#既知の制限)に挙げてあります。)
---
## Android 固有の注意点
- **APK は約 800 MB あります。** シムではなく本物のツールを同梱しているからです。bash、
Node.js、Python 3、git、curl、ripgrep、jq、tmux、vim、less、sqlite3、
make、ssh――加えて OpenAI Codex CLI ランタイムまでが APK の中に入っています。
Termux もリポジトリサーバーもパッケージマネージャのブートストラップもありません。
初回起動時に、バイナリをアプリ専用領域へ展開します。
- **全ファイルアクセス権限**を初回起動で要求します。デスクトップのターミナルと同じ感覚で
`/sdcard` を扱う(`cd /sdcard/Download`、そこのファイルを編集する、など)ために必要です。
この権限がないと Scoped Storage が書き込みを黙って弾きます。拒否しても構いません――
Shelly は自分のサンドボックス内では動きますが、`/sdcard` 以下のパスは `Permission denied` になります。
- **LD_PRELOAD + /system/bin/linker64** が、Linux レイアウトのバイナリを Android の bionic 上で
動かす仕組みです(SELinux はアプリ専用領域の ELF に対する直接の execve を禁止しています)。
ラッパーが `/bin/X` と `/usr/bin/X` を `/system/bin/X` に書き換え、アプリ同梱の ELF は
`linker64` 経由に流します。ソースは
`modules/terminal-emulator/android/src/main/jni/exec-wrapper.c` にあります。
- **設計として Termux 互換ではありません。** Shelly は Termux のパッケージも、Termux のパスも、
Termux の prefix 前提も使いません。すでに Termux を入れていても、Shelly は自前のコピーを
すべて同梱します。競合はしませんが、共有もしません。
---
## クイックスタート
### インストール
最新の Android APK は [**GitHub Releases**](https://github.com/RYOITABASHI/Shelly/releases) から入手できます。ローリング更新される `android-latest` リリースが最新ビルドの正となり、タグ付きの `vX.Y.Z` リリース APK も同じビルドから切り出されています。正確な `versionCode`・コミット・SHA-256 は [`android-latest/latest.json`](https://github.com/RYOITABASHI/Shelly/releases/download/android-latest/latest.json) で公開しています。
アプリストアのような更新管理を使いたい場合は、[Obtainium](https://github.com/ImranR98/Obtainium) で GitHub から Shelly を入れて、新しいバージョンの通知を受け取れます。スマホでバッジをタップするか、Obtainium に `https://github.com/RYOITABASHI/Shelly` を追加してください。追いかけるのはタグ付きの `vX.Y.Z` リリース(それぞれタグのコミットからビルドした APK を添付)なので、`android-latest` の全ビルドを追うアプリ内更新よりも更新の頻度は少なめです。
一度インストールすれば、あとはアプリ内から自己更新できます。上部バーのクラウドダウンロードボタン、または **Settings → Updates** を開いてください。Shelly は公開されている `android-latest/latest.json` マニフェストを読み、Android の `versionCode` を比較し、Android DownloadManager で `/sdcard/Download/shelly-update-/` に APK をキューイングし、SHA-256 を検証してから Android のパッケージインストーラを開きます。システム側のダウンロードは、Shelly をバックグラウンドに回しても再起動しても継続します。Play ストア外配布なので、インストールの確認は Android が改めて求めてきます。
リリース APK では Expo OTA を無効にしています。JS・ネイティブ・同梱ツールの変更は新しい APK としてまとめて配布され、インストール済みバイナリとアプリコードのズレが起きないようにしています。
### ソースからビルド
```bash
git clone https://github.com/RYOITABASHI/Shelly.git && cd Shelly
pnpm install && pnpm android
```
**必要なもの:**
- Android 端末
- Node.js 22 以上(CI は現在 Node 22 でビルドしています)
- pnpm
- Android NDK 26.1.10909125(またはこの固定 NDK を解決できる Android SDK / Gradle 環境)
Expo Go には対応していません。Shelly はネイティブの Kotlin / C モジュールを使っています。
Termux は不要です。bash、Node.js、Python 3、git、curl、ssh、sqlite3、tmux、vim、less、jq、make、ripgrep を同梱しています。同梱セット以外のツールが必要なら、Termux を Shelly と併用してください。
### 初回起動
初回起動時、Shelly は **全ファイルアクセス**を要求します。`/sdcard/Download` などスマホのどこにあるスクリプトでもターミナルから読めるようにするためです。**許可**をタップすれば準備完了、`source /sdcard/Download/foo.sh` がそのまま動きます。配布は当面 GitHub Releases のみで、Play ストア / F-Droid への申請はこれからの作業です。
### AI の設定
そのあと **Settings → API Keys** を開く(またはターミナルペインで `shelly config` を実行する)と、Gemini・Cerebras・Groq・Perplexity・OpenRouter・OpenAI 互換のローカルサーバーなど、明示的な API プロバイダのキーを貼り付けられます。キーは `expo-secure-store` に保存され、ログには一切書き出されません。
### サインイン
Shelly のフォアグラウンド AI CLI は **Codex** です。それ以外はすべて、キーを設定して使う API プロバイダです。
| 対象 | サインイン方法 | 補足 |
|---|---|---|
| **Codex CLI**(ChatGPT サブスクリプション) | `codex` を実行、または `codex-login --open` を直接実行 | 唯一サポートされているフォアグラウンド CLI です。`~/.codex/auth.json` が無い、または無効な場合、`codex` ラッパーが Shelly のデバイスコードログインを開始し、OpenAI のデバイスコードページをアプリ内ブラウザペインで開き、成功したら `~/.codex/auth.json` をパーミッション `0600` で書き込んでから、通常の Codex TUI を起動します。OpenAI API キーは不要で、ChatGPT サブスクリプションに乗ります。 |
| **API プロバイダ**(Gemini・Cerebras・Groq・Perplexity・OpenRouter・ローカル) | **Settings → API Keys** または `shelly config` | AI ペイン / `@mention` / `@team` / バックグラウンドエージェント用に、プロバイダごとにキーを貼り付けます(OpenRouter は有人時のみ)。キーは `expo-secure-store` に保存されます。ローカル / OpenAI 互換サーバーはベース URL だけで動きます。 |
> **Codex ログインについて。** REPL 内の `codex /login` は Shelly でのサポート対象パスではありません。素の `codex` を実行して Shelly のラッパーにデバイスコード認証を任せるか、bash から `codex-login --open` を実行してください。
### 同梱の Shelly コマンド
| コマンド | 用途 |
|---|---|
| `codex` | ネイティブターミナル内でフォアグラウンドの Codex TUI を起動。認証が無い場合は、先にデバイスコードログインを開始します。 |
| `codex-login --open` | ChatGPT サブスクリプションのデバイスコード認証を開始し、Shelly のブラウザペインで検証ページを開きます。 |
| `shelly-doctor` | シェル / ネイティブバイナリの有無、同梱 Codex バイナリ、JS ディスパッチャ、ローカル LLM エンドポイント、Codex 認証ファイルの有無をチェック。 |
| `shelly-codex-diagnose` | Codex のスモーク / カナリア / 編集 / パッチのより深い診断を実行。 |
| `shelly-update-clis codex --check-only` | 現在の Codex ランタイムをプローブ。ランタイムのインストールは通常 Updates UI から行います。 |
| `shelly-cs` / `cs` | GitHub Codespaces のヘルパーコマンド。 |
| `shelly teach start [name]` / `stop` / `cancel` / `status` | 実行したコマンドを再利用可能なワークフローとして記録します([学習ループ](#学習ループ)参照)。 |
| `shelly install ` / `shelly install --list` / `shelly uninstall ` | 追加ツールパック(`dev-tools`: python3, sqlite3, jq, make, gh / `editor-tools`: vim, tmux, nano, less, unzip, rg)。各リリースビルドがパックアーカイブの sha256 を固定しており、ダウンロード後に検証してから展開します。インストールしたツールはオフラインでも、開いたままのタブでもすぐ使えます。パックのツールが無いときは ` is available: shelly install ` と表示され、コマンドを実行しない限り何もダウンロードしません。現状これらのツールは APK にも同梱されているため、パックが意味を持つのはコピーが欠けている場合だけです。 |
| `shelly workflow list` / `show ` / `run ` / `delete ` | 保存済みワークフローの一覧・表示・現在のターミナルでの再生・削除。 |
| `shelly device ` | スクリプト・エージェント・Codex から使えるスマホ機能。バッテリーと端末情報(JSON)、クリップボード、通知、トースト、バイブ、読み上げ、共有シート([シェルからスマホの機能を使う](#シェルからスマホの機能を使う)参照)。 |
**まず試すなら:** プロバイダのキーを 1 つ設定したら、任意のペインで `@agent` に続けて普通の言葉の指示と時刻を書いてみてください。例: `@agent 月・火・水・木・金の朝8時に、最新の STEAM×AI 教育に関する論文とニュースを集めて、要約して Obsidian に保存して`(曜日は「平日」とまとめず区切って並べ、直後に時刻を続けるのがコツです)。Shelly はこれを端末上のスケジュール済みエージェントに変換します([上のデモ](#動作デモ)がまさにこれです)。
### シェルからスマホの機能を使う
`shelly device` を使うと、スクリプト・エージェント・Codex が、別のアドオンアプリを入れなくてもスマホの機能をいくつか使えます。よく使われる Termux:API コマンドの一部を Shelly に組み込んだものです。*実装済み、実機では未検証。*
| コマンド | 内容 |
|---|---|
| `shelly device battery` | バッテリー残量、充電状態、給電の種類、状態、温度、電圧を JSON で表示 |
| `shelly device info` | メーカー、機種、Android のバージョン、画面サイズと密度、ロケール、タイムゾーン、ネットワークの種類(wifi / cellular / none)、Shelly のバージョンを JSON で表示。IMEI・シリアル番号・Android ID・IP/MAC アドレスなどの識別子は含めません |
| `shelly device clipboard get [--json]` | クリップボードの文字列を表示。Android はフォーカス中のアプリにしかクリップボードを読ませないため、Shelly が画面に出ているときだけ動き、それ以外は exit 3。読み取るたびにスマホに「スクリプトがクリップボードを読み取りました」と表示されます |
| `shelly device clipboard set [--sensitive] ` | クリップボードに設定。文字列を渡すか、`-` で標準入力から読みます(`date \| shelly device clipboard set -`)。どちらも無いと拒否するので、うっかりクリップボードを空にすることはありません。`--sensitive` はクリップボードのプレビューに内容を出しません |
| `shelly device notify [--title T] [--id N] ` | Shelly 専用の **スクリプト** チャンネルに通知を出します(Android の設定でミュート可)。同じ id(0〜9999、既定 0)で出すと置き換わります。`notify --remove N` で消去 |
| `shelly device toast ` | 短いトーストを表示。システムのメッセージと見分けられるよう「スクリプト:」を先頭に付けます |
| `shelly device vibrate [ms]` | バイブ(既定 300ms、上限 2000ms) |
| `shelly device tts [--lang en-US] ` | Android の読み上げ(TTS)。`--lang` を指定しなければスマホの言語で読み上げます |
| `shelly device share --file <パス>` / `--text <テキスト>` | Android の共有シートを開きます。共有先のアプリは自分で選びます。Shelly がバックグラウンドのときは、Android がバックグラウンドからの画面表示を禁止しているため、代わりにファイル名入りの「タップして共有」通知が出ます。ファイルは Shelly のホームか共有ストレージ(`/sdcard`)内で、隠しファイルや隠しフォルダ(`.` で始まるもの)の中にないものだけ。`~/.ssh`、`~/.codex`、`~/.shelly`、`.env` などは拒否します。共有するのはその時点のコピーで(30分後に削除)、元のファイルではありません。スクリプトでは必ず `--file` か `--text` を付けてください。付けない場合、既存ファイル名の引数はファイルとして共有されます |
```bash
$ shelly device battery
{
"level": 83,
"charging": true,
"plugged": "usb",
"status": "charging",
"health": "good",
"temperatureC": 31.5,
"voltageMv": 4123
}
$ make && shelly device notify --title Build "ビルド完了" || shelly device vibrate 800
```
- **終了コード:** 0 成功、1 失敗、2 使い方の誤り、3 権限が無い・今はできない(通知オフ、バックグラウンドでのクリップボード読み取り、TTS の音声が無い)、4 レート制限、124 Shelly から応答なし(操作は実行されている可能性があるので、再実行の前に確認してください)。エラーは標準エラー出力に出ます。`shelly device --help` と `shelly device --help` は使い方を表示するだけで、何も実行しません。
- **レート制限:** notify は 1 分に 30 回、toast・vibrate・tts は 10 回、share は 5 回まで。ループするスクリプトやエージェントがスマホを通知などで埋め尽くさないようにするためです。
- **クリップボードのプライバシー:** `clipboard get` は、コピーしたもの(パスワードやワンタイムコード)を、実行したプログラムにそのまま渡します。ChatGPT アプリから操作している Codex も含みます。エージェントのコマンドゲートは、引用符の付け方に関係なくこれを秘密ファイルの読み取りと同じに扱い、必ず先に確認を求め、最も自律度の高いレベルでは拒否します。橋渡し用のファイルを直接読むことも同じく扱います。読み取るたびに「スクリプトがクリップボードを読み取りました」のトーストと通知が出て、応答ファイルは15秒以内に削除されます。Android 自身も「Shelly がクリップボードから貼り付けました」と表示することがあります。
- **仕組み:** コマンドは Shelly のホームにリクエストファイルを書き、アプリがネイティブで応答します(`shelly closepaw` と同じファイルの橋渡し)。アプリが動いていれば、Shelly がバックグラウンドでも動きます。
- このバージョンに含まれないもの: 位置情報、カメラ、マイク、SMS、連絡先、通話履歴。どれも先に明示的な権限の確認フローが必要です。
---
## ランタイムモデル
エージェントの下にあるのが Shelly の構造的な強みです。ランタイムそのもの――あなたのファイルと同じ端末上のシェルで動くネイティブ PTY と、管理された Codex CLI。そしてその上に重なる API ベースのエージェント。WebView ターミナルでも、リモート IDE クライアントでもありません。
Termux や proot、あるいは別の Android ターミナル環境で AI コーディング CLI のワークフローが行き詰まったなら、Shelly は実機 Android の制約(bionic libc、`linker64` の exec ルール、`app_data_file` に対する SELinux)を前提に組んだ、メンテナンス済みの端末内環境を提供します。
壊れやすいターミナルスタックなし。WebView ターミナルのクラッシュなし。コピペ駆動のワークフローなし。
- **ネイティブ実行パス** — Codex はリモートブリッジやソケットターミナルではなく、Shelly がアプリとして所有するネイティブ PTY(JNI `forkpty`)上で動きます。
- **「最新」を盲信せず、管理する** — 各 APK には固定バージョンの Codex ランタイムが同梱されており、Updates UI からはローリングの `codex-runtime-latest` リリースにある検証済みの新しいランタイムを、次の APK を待たずにインストールできます。
- **状態が見える** — 直近のターミナルログをアプリ側で表示できるので、バージョンのズレや起動失敗を端末上でそのままデバッグできます。
- **コンプライアンス境界** — Codex はフォアグラウンドの、ユーザーが操作するターミナル CLI です。AI ペインやバックグラウンド自動化は明示的な API プロバイダを使い、隠れたサブスクリプションワーカーは動かしません。
ここが Shelly を「ターミナルの皮」以上のものにしている部分です。動きの速い CLI を Android 上で配布しつつ、更新作業をユーザーに押し付けずに済んでいる理由でもあります。
### リリースサーフェス
| 対象 | 状態 | 意味 |
|---|---|---|
| **Codex CLI** | サポート対象 | フォアグラウンド CLI。素の `codex` は、Shelly がアプリ内デバイスコード認証で `~/.codex/auth.json` を検証・作成したあと、ネイティブ PTY 上で通常の Codex TUI を起動します。 |
| **AI ペイン / バックグラウンドエージェント** | API 経由でサポート | 設定済みプロバイダ(Gemini API・Cerebras・Groq・Perplexity・OpenRouter〈有人の AI ペイン利用のみ〉・ローカルの OpenAI 互換サーバー)を使います。プロバイダキーベースで、サブスクリプションの隠れた再利用はありません。 |
| **Gemini API** | 設定済みなら利用可 | Gemini API キーを設定すると、AI ペイン、`@gemini` ルーティング、`@team`、マルチモーダル / API ベースのタスク、バックグラウンドエージェントで使えます。(これは API プロバイダとしての話で、Gemini CLI は同梱していません。) |
---
## Shelly ではないもの
Shelly は Termux の皮でも、WebView ターミナルでも、リモート IDE クライアントでもありません。Android のターミナルスタックをアプリ内で自前で持ち、あなたのファイルと同じシェルで Codex を端末上に動かし、そのターミナルの隣に API ベースのエージェントを並べます。コピペやクラウドワークスペースを経由させることはしません。
クラウドエージェントサービスでもありません。スケジュール済みエージェントは端末上で、あなたのキーで動きます。サーバー側のコンポーネントもサブスクリプションのランナーもありません。スマホの電源が切れていれば何も動かないし、そのことを取り繕いもしません。実行漏れは隠さず表に出します。
メッセージングプラットフォームの公式ボット運営者でもありません。Discord bot も Slack app も WhatsApp/Signal Business API 連携もなく、作る予定もありません――それは Hermes のようなサービスが採る、サーバーを前提としたサーバー常駐ボットのモデルで、Shelly にはそのサーバーがありません。代わりに用意しているのは端末上で完結する代替手段です。通知トリガーのエージェント経路(`lib/notification-inbound.ts`)はどのアプリの Android 通知にも反応します――パッケージ許可リスト、送信者名の完全一致、そしてトリガーとなったテキストは常に「信頼できないデータ」で指示としては扱わない、という条件つきで。この仕組みなら LINE・Discord・Slack・WhatsApp・Signal、あるいは通知を出すものなら何でもカバーでき、プラットフォームごとのボット登録や審査は一切不要です。
Termux のインストールなし。proot なし。ttyd なし。リモートブリッジなし。クラウドランナーなし。
---
## 機能
> 以下は現行ビルドで実装済みのパスについての記述です。実機での検証が限定的な項目(無人でのエージェント発火、TTS 再生、メーカー横断での信頼性など)は、この節と[ステータス](#ステータス) / [今後の予定](#今後の予定)の両方に注意書きを付けています。
### ハイライト
| | |
|---|---|
| **出典付きの多段ブリーフィング** | 調査 → 要約 → 執筆のエージェントは、Perplexity が返した出典を全ステップに引き継ぎます。出典で裏付けられない主張は落とされ、各項目は `[n]` の番号を保ち、保存される markdown の末尾には `## Sources` の一覧が追加されます。ステップ間の受け渡しは、エージェント自身のチャットスレッドに短い行として書き込まれます。*実機検証済み(Galaxy Z Fold6、N=1)。* |
| **端末上で動く自律エージェント** | 普通の言葉で言えば、スケジュール済みエージェントがスマホの上で*自分だけで*(画面が消えた状態で)動き、あなた自身のキーとツールを使い、実行したことを知らせます。クラウドエージェントが届かない場所――あなたのファイル、ターミナル、ローカル LLM、端末そのもの――で動くのが強みです。*現時点では N=1 の検証です。[ステータス](#ステータス)を参照してください。* ([詳細](#自律エージェント)) |
| **Shellyコンパニオン** | 既定のローカル人格のAIペインは、プロバイダー名を冠したフォームではなく、**Shelly**という一人の常駐する相棒です――どの返信にもプロバイダータグは付きません。会話はAIペインや分割をまたいで続き、プロバイダーを切り替えるたびに会話内容を自動でShelly自身のメモリへ蒸留し(Settingsから閲覧/編集可能)、確認して覚えた好みはShelly自身とすべてのバックグラウンドエージェントで共有され、完了したエージェントの結果も同じスレッドへ自動で入ります。明示的なプロバイダールートはペインごとの独立した履歴を保ち、そこへ切り替える/そこから抜けるときには直近のコンテキストを短く引き継ぎます。 |
| **マルチプラットフォーム配信** | エージェントの成果物は通知や Obsidian の下書きに限りません。Bluesky・Discord・Slack・Telegram・Mastodon・Misskey・WordPress・X に直接投稿したり、Webhook を叩いたりできます。プラットフォームごとのキーを一度保存すれば、あとは普通の言葉でエージェントに向き先を指示するだけ。*Bluesky はライブで端から端まで検証済みです。* |
| **通知トリガーのエージェント** | エージェントはスケジュールだけでなく、他アプリ(LINE、Discord、Slackなど、許可リストに入れたもの)が条件に合う通知を出したときにも発火できます。まずパッケージの許可リストで絞り込み、次に送信者名の完全一致でさらに絞ります(未設定なら fail-closed)。トリガーとなったテキストは常に「信頼できないデータ」として注入され、指示としては扱われません。これとは別に、オプトインの **Telegram inbound gateway**(既定OFF)は認可した1つのチャットから`@agent`メッセージを受け取り確認カードをキューします。認可・サニタイズのコアはテスト済みですが、実bot tokenによるlong-poll → 確認の通し動作はライブ未検証です。 |
| **エージェントによるブラウザ自動操作** | エージェントは Browser ペインで既に開いているページに対して click / fill / テキスト抽出ができます。意図的に狭いアクション集合(ナビゲーションも任意スクリプト注入もなし)で、明示的なページURL許可リストとアクションごとの承認タップでゲートされます。ページ由来の出力は次のケイパビリティ境界で常に「信頼できない」扱いです。 |
| **ペインをまたぐ知能** | 「エラーを直して」と言うだけ。AI がターミナルを読み、修正を提案し、ワンタップで実行。コピペはゼロです。 |
| **Ask AI(AI への引用)** | ターミナル出力を長押し → 選択メニューの **Ask AI** で、AI ペインの入力欄に引用されます(1 行なら引用ブロック、複数行ならフェンス付きブロック)。あくまで下書きで、あなたが送信するまで何も送られず、伏字の秘密入力欄には決して引用されません。*実機検証済み(Galaxy Z Fold6、N=1)。* |
| **ティーチモード** | `shelly teach start ` でターミナルで実行したコマンドを記録し、`shelly teach stop` で保存済みワークフロー(`~/.shelly/workflows/.sh`)に変換します。失敗したコマンドや秘密情報らしき行は除外し、その場では何も実行しません。変換は既定で端末上の LLM を使い(クラウドはオプトインした場合のみ)、ルールベースのフォールバック付き。`shelly workflow run ` で再生できます。*実機検証済み(Galaxy Z Fold6、N=1)。* |
| **AI→ターミナル挿入** | AIチャットの返信内にある ` ```bash ` のフェンス付きコードブロックには、Copyの隣に**挿入**ボタンが付きます。タップするとフォーカス中のTerminalペインの入力行にコードが入ります(自動Enterなし、実行前に確認可能)。ターミナルペインが開いていなければ新規に開いて挿入をキューします。*2026-08-31に実機検証済み。* |
| **Nacre Bridge** | Shellyが前面表示中、現在のディレクトリ・gitブランチ・安全な直近コマンド用語(生コマンドや秘密情報は含まない)の一部を、著者自身が開発しているAndroid IME [Nacre](https://github.com/RYOITABASHI/Nacre) と共有し、かな漢字変換の候補が実際の作業内容に寄るようにします。コンテキストファイルはShellyが前面から外れた瞬間に削除されます。Nacre側でも、Shellyにフォーカスがあることを検出する「Dev Mode」が自動変換の誤変換を抑制し、記号パネルをプログラミング向けタブにデフォルトで開きます。Nacreのインストールが必要。設定 → Nacre連携でON/OFF切り替え可能(デフォルトON)。*2026-08-31に実機検証済み。* |
| **AI Edit のゴールデンパス** | サイドバーでファイルをタップ → プレビュー → `[✨ AI]` → 変更内容を説明 → hunk 単位で承認 → ディスク上のファイルが書き換わり、プレビューが自動でリロードされます。 |
| **端末上での Codex apply_patch** | Codex のファイル編集は、シェル頼みのフォールバックではなく、エージェントのネイティブ patch ツール経由で Android 上に着地します。 |
| **ネイティブ PTY(JNI forkpty)** | Kotlin + C、PTY の fd を直接扱い、TCP / ソケットのブリッジなし。WebView ターミナルではなく、組み込みのネイティブターミナルです。 |
| **バッテリー同梱** | bash、Node.js、Python 3、git、curl、ssh、sqlite3、tmux、vim、less、make、ripgrep、jq が APK の中に入っています。Termux は不要です。 |
| **9 種類のペイン** | Terminal、Agent Chat、AI、Browser(+ バックグラウンド再生)、Markdown、Preview、Ask、Agent Runs、Memory Workbench。最大 4 つまで自由に分割できます。 |
| **マルチエージェント AI** | API ベースの Gemini・Cerebras・Groq・Perplexity・OpenRouter・ローカル LLM に加え、フォアグラウンドの Codex ターミナル CLI。自動ルーティング、または対応するものは `@mention` で指定できます。 |
| **ローカル LLM(端末上、llama.cpp)** | Qwen3.5 系モデルを同梱の llama.cpp / llama-server フローで端末上で動かします。実際のデフォルトはQwen3.5-0.8B(バックグラウンド/自律実行でも常駐できる軽さ)、RAM・バッテリーに余裕があるオンデマンド用途にはQwen3.5-2Bへのアップグレードを推奨、Qwen3 1.7Bはその中間、4B以上は短時間の品質確認に限定しています。llama.cpp のダウンロードはリリース b11433 に固定し、sha256 で検証します。MiniCPM5-2B は **Experimental** として載せているだけで、Fold6 で評価したうえで不採用としました([ステータス](#ステータス)参照)。 |
| **Android 上の Codex** | 上流を盲信せずに Codex を「管理された最新」に保ちます。各 APK は固定ランタイムを同梱し、Updates UI は検証済みランタイムリリースへ昇格でき、Reset で同梱ランタイムに戻せます。Codex は Shelly 自前のデバイスコードログインラッパーとともに、ネイティブ PTY 上で動きます。proot も root も不要です。 |
| **Scouter ホームウィジェット** | ホーム画面のエージェント起動パッド兼ヘルス一覧です。アプリを開かずに、直近実行予定のエージェント最大3件をそれぞれのステータスグリフ(前回実行の成功 / 失敗 / スキップ)と次回発火時刻つきで表示します。しかも操作可能で、**RUN** は登録済みエージェントを無人実行のゲートを通して起動し、**ASK** は新規エージェントの登録にも使えます——`@agent ...` と打つ(または話す)と、AI ペインに直接打ったときと同じ確認フローに合流します。 |
| **カラーテーマ** | **Case File**(新規インストール時の既定。クリーム色の紙と黒インクのレトロ端末風パレット。専用の DotGothic16 ビットマップフォント〈任意〉、タイプライター風に一文字ずつ現れる AI 返信、ブート風の切り替え演出付き)と Blue / Red / Purple / Green――5 つのプリセットは既存のプリセット ID の上で動くので、実行中に切り替えても設定のマイグレーションなしでシェルが生き残ります。切り替えはライブで、ペイン・設定・モーダル・サイドバー・ターミナル自身の ANSI パレットまで、再起動なしで新しいプリセットに追従します。アプリのフォントはカラープリセットとは別のピッカーになったので、どのテーマでもどちらのフォントでも使えます。この README のスクリーンショットは Case File です。 |
| **音声入力** | コマンドや AI プロンプトを話しかけられます。Groq キーがあれば Groq Whisper が文字起こしを担当し、無ければ Android の端末内音声認識(キー不要、API 31 以上)にフォールバックします(Settings → Voice Input で端末内に固定すれば、音声はネットワークに出ません)。そのテキストを VoiceChain がキーボードと同じ入力ルーターに流します。*端末内の経路は実装済みですが、実機では未検証です。* |
| **リアルタイム音声(Gemini Live)** | オプトインの全二重音声モード。録音 → 文字起こし → 送信を繰り返すターン制ではなく、話しかけると音声で返答が返り、割り込みはサーバー側で処理されます。通常の音声入力とは別のトグルです(Settings → Realtime Voice、既定 OFF)。テキストと違い、Gemini Live API 経由の音声は無料枠のキーでもトークン課金される点に注意してください。 |
| **A2A サーバー(Agent2Agent)** | オプトインのローカル HTTP サーバー(Settings → A2A Server、既定 OFF)。標準の [A2A プロトコル](https://a2a-protocol.org/) の Agent Card と `list_agents` スキルを公開し、同じネットワーク上の A2A 対応エージェント / ツールから Shelly に登録済みのものが見えるようにします。現時点では読み取り専用で、実行や書き込みのスキルは公開していません。 |
| **MCP サーバー** | オプトインのローカル [Model Context Protocol](https://modelcontextprotocol.io/) サーバー(Settings → MCP Server、既定 OFF、bearer トークン認証)。`read_terminal_output`・`git_status`・`list_agents`・`list_repos` の 4 つの読み取り専用ツールを公開し、Claude Code や Claude Desktop のようなデスクトップの MCP クライアントからスマホ上で動いているものを覗けるようにします。ほかに `run_command` と `write_file` の 2 つがありますが、Settings → Agents →「MCP: Allow exec/write」をオンにしない限り無効で、オンにしても呼び出しのたびにスマホでの承認タップが必要です。旧来の仕様リビジョン(セッションのハンドシェイク)と、ステートレスな 2026-07-28 リビジョンの両方を話します。*2026-07-28 の経路は実装・テスト済みですが、実機では未検証です。* |
| **エージェントの安全ルール(ベータ、既定 OFF)** | POLICY-001: 普通の言葉でルールを伝えられます(「お金が絡む操作は必ず聞いて」「Xへの投稿は下書きまで」)。復唱されたうえで、あなたが確認したときだけ保存され、一覧表示や取り消しも同じく言葉で行えます。あなたが起動したのではない実行(スケジュール・ウィジェット・通知・起動時)は読み取り / 下書き / 通知に限定され、同じ種類のアクションを何度も問題なく承認すると、以後は聞かずに実行するかを提案することがあります(支払い・投稿・ネットワーク送信・高リスクのコマンドには決して提案しません)。既定 OFF(Settings → Agent Safety Rules (beta))。*実装済み、実機では未検証です。* |
| **実行中の常駐通知** | スケジュールまたは手動で起動したエージェントは、実行結果の通知だけでなく、実行中ずっと「▶ 実行中」の常駐通知を出します。実行中の状態が、終わってから初めて分かるのではなく通知シェードから見えます。 |
### 自律エージェント
やってほしいことを普通の言葉で言うと、Shelly はスケジュール済みエージェントとして登録します。エージェントは**端末上で、単独で**動きます――画面が消えていても。Android の **AlarmManager**(`setExactAndAllowWhileIdle`。Termux 上の cron と違い、Doze 下でも発火するよう設計されています)で起き、**あなた自身のキーとツール**で端末上で動き、**実行したことを知らせます**(通知 + エージェントごとの次回 / 前回実行の表示。想定された実行が記録されていなければ実行漏れの警告も出ます)。
売りは「クラウドエージェントより賢い」ことではありません。**クラウドエージェントが届かない場所で動く**ことです。あなたのファイル、あなたのターミナルとスクリプト、あなたのローカル LLM、そしてスマホそのもの。
これは決まりきった機能ではなく、**自分のツールに向けて使う能力**です。私自身の例を 1 つ挙げます:
```
@agent every day at 8am, collect the latest STEAM×AI education papers and news,
and write the primary-source links + a short summary to my Obsidian vault
```
このスケジュールで登録されたエージェントは、発火するとスマホを起こし、Perplexity で調査し、日付とソース付きのサマリを Obsidian に落とします。無人で、上のデモと同じ実行です。スケジュールもソースも出力先も、自分のものに置き換えてください。
スケジュール指定は繰り返しだけでなく、相対的な*開始時点*も理解します。「来週から毎朝ニュースをチェックして」と言えば、エージェントはいま登録されつつ、最初の発火は解決された日付まで保留され、うっかり明日動き出すことはありません。(登録 / 確認カードのパスは実機で確認済みです。)
スケジュールは **1 回きり**にもできます。「5分後に」「今日の14時55分」「明日の朝8時」、"in 5 minutes"、"at 14:55" と言えば、正確なアラームで 1 回だけ発火し、そのあとは退役するエージェントとして登録されます(実行ログ付きで一覧には残ります)。相対的な遅延はあなたが確認をタップした時点から数え、繰り返しを表す語のない時刻だけの指定は、登録前に必ず「1 回きり」という解釈として提示されます。再起動をまたいだ場合、取りこぼした 1 回きりの実行は 10 分の猶予内なら追いつき実行し、それを過ぎたものは「実行漏れ」として記録します――遅れて発火することはありません。("in 5 minutes"、"at 14:55"、「5分後に」で実機検証済み。)
**出典付きブリーフィング。** 多段チェーンに Web 調査(Perplexity のステップ、または明示的な Web / ニュースの手がかり)が含まれる場合、Perplexity が返した出典は、後続の要約 / 執筆ステップまで引き継がれます。エージェントのアクションが走る前に、各項目は出典を引用している必要があり、その中の数値・名前・固有名詞は出典の本文に現れていなければなりません。そうでなければ、その項目は調査結果自身の言い回しに書き直されるか、落とされます。出典のない前置きや締めの文は落とされ、`## Sources` の一覧(タイトル・リンク・日付)が末尾に追加されます。取得した出典テキストは「信頼できないデータ」として囲われます。検証できるものが何も残らなければ、出典なしのブリーフィングを保存するのではなく fail-closed で止まります。ステップ間の受け渡し(「調査役 → 要約役: 3件の項目を渡しました…」)はエージェント自身のチャットスレッドに短い行として書き込まれるので、ログを開かなくても実行の流れを追えます。
無人実行のうち、アクションがローカルの `draft` ファイル(スコープされた出力フォルダ内)か `notify` だけのものは、手動承認のタップを待たなくなりました――どちらも端末の外に出ないからです。それ以外のアクション(webhook、CLI、SNS 投稿など)は引き続き承認が必要で、安全ルールを有効にしている場合はそちらが優先されます。
**ClosePaw への引き継ぎ(Experimental)。** エージェントから、オープンソース(Apache-2.0)の Android スマホ操作エージェント [ClosePaw](https://github.com/imoonkey/closepaw) にタスクを引き継げます。「ClosePawでChromeを開いて東京の天気を検索して」("have ClosePaw open Chrome and search the weather in Tokyo")のように言うだけです。実行のたびにまず Shelly の Review で「ClosePaw に引き継ぎ: <ゴール>」を確認し(自動承認はされません)、さらに ClosePaw 側でも「External Goal」の確認が出てから動きます。ClosePaw は結果を返さないため、実行は結果つきの成功ではなく **「ClosePaw に引き継ぎ済み」** で終わります。ClosePaw は GitHub のリリースから各自でインストールし、API キー / OpenAI 互換エンドポイントで設定してください(Shelly の小型オンデバイスモデルでは ClosePaw を動かせません)。Shelly のターミナル(その中で動く Codex セッションを含む)からは `shelly closepaw "Chromeを開いて東京の天気を検索して"` で直接引き継げます(同意は ClosePaw 側の Run 確認。5 秒に 1 回まで、30 秒より古い要求は破棄)。Shelly がバックグラウンドのとき(ChatGPT アプリから Codex を操作している時など)も動きます。Android はバックグラウンドのアプリから別アプリを開かせないため、その場合は「ClosePaw に引き継ぎ」通知が出るので、タップして続行してください。*実機未検証です。* **バックグラウンド実行(Shelly 用 ClosePaw ビルド v0.1.0-4 以降):** [shelly-v0.1.0-4](https://github.com/RYOITABASHI/closepaw/releases/tag/shelly-v0.1.0-4) 以降の Shelly 用ビルドでは、承認済みの引き継ぎで ClosePaw が前面に出なくなります。Shelly は ClosePaw のバックグラウンド入口に依頼を送り、ClosePaw は自分の仮想ディスプレイ上で作業します(Shizuku の起動が必要)。その間もスマホはそのまま使えます(ClosePaw が操作中のアプリだけは避けてください)。結果はターミナル・エージェント実行結果・チャットに「バックグラウンドで作業中」と表示され、失敗時は対処法(Shizuku を起動、ClosePaw のユーザー補助をオン、重ねて表示の許可、認証情報の追加、ClosePaw が実行中)を具体的に示します。Shelly が ClosePaw にメイン画面の操作を求めることはありません。古い ClosePaw ビルドでは従来どおりの起動になります。*実機未検証です。*
そもそもリクエストが曖昧すぎて動きようがない場合――目的語もドメインもない「なんか手伝って」のような場合――Shelly は空のタスクでエージェントを登録したりせず、いつ動かすかを聞く*前に*、実際に何をしてほしいのかを尋ねます。
**正直な注意点:** 無人での発火は Android のバックグラウンド制限に依存し、これはメーカーによって差があります(Samsung / Xiaomi / Oppo / OnePlus のバッテリー凍結機能)。Shelly は上に挙げた Android の最優先アラームパスを使い、実行漏れも表に出しますが、あらゆる端末での発火を*保証*することはできません。バッテリー最適化の除外を許可したうえで、エージェントの実行ビューを確認してください。
### 学習ループ
エージェント登録は決まりきったフォームではありません。依頼が曖昧なとき、固定パイプラインではなく**LLM自身が**会話の続きを自分の言葉で主導し、1問ずつ聞き返し、十分な情報が集まったと判断したときだけ最終登録を提案します(**LLM-Led Agent Registration**、デフォルトON、設定 → Agents でトグル可能。設定済みならまず高速なクラウドプロバイダを試し、次にオンデバイスモデル、それも届かなければShellyの固定の1問ずつの質問へ――何もかも繋がらなくても会話が行き詰まらず段階的に降格する設計です)。複数の手順に分かれる依頼(「調べて→要約して→投稿して」)は、1本のpromptに潰されず、決定論的な登録が使うのと同じオーケストレーションエンジンで実際のチェーンとして登録されます。モデルが提案する値は、どの経路であっても必ず独立に再検証されます: スケジュール表現は他の全経路と同じ決定論的cronロジックで再パースされ、投稿先は実際に登録済みの接続先としか一致せず、webhook URLやシェルコマンドはその会話であなた自身が実際にタイプした文字列と一字一句完全に一致する場合にしか採用されません――モデルが考え出したものは決して採用されません。人間による最終確認タップは、どの経路で作られた下書きであっても一切省略されません。
エージェントはサーバー無しで、使うたびにオンデバイスで賢くなっていきます:
- **スキル蒸留** — 実行が成功すると、Shellyはそれを再利用可能な「スキルレシピ」(markdownファイル、特定のエージェントに紐付かないGLOBALな存在)として蒸留し、保存するかどうかを尋ねます。後で似たタスクが来たときは、ゼロから解くのではなくこのレシピが呼び出されて再利用されます。無断で保存されることはなく、保存内容は必ず表示されます。
- **ティーチモード** — `shelly teach start fix-config` を実行し、ターミナルで手作業をして、`shelly teach stop`。Shelly は実行したものを保存済みのワークフロースクリプトに変換します。成功したコマンドと `cd` は残し、失敗した試行や秘密情報らしき行は落とし、LLM による書き換えは実際に実行したプログラムに接地させます。クラウドプロバイダを許可しない限り、変換は端末上の LLM で完結します。`shelly workflow run fix-config` で、すべてのステップを表示しながら現在のターミナルで再生します。
- **スキルカタログ** — Sidebarの **Browse Catalog** からShelly公式の配布スキルレシピを取得し、ダウンロードを検証したうえで、ローカル取り込みと同じ隔離・レビュー経路へ追加できます。利用可否は公開済みの`skills-catalog-latest`リリースに依存します。
- **永続メモリ** — エージェントは実行をまたいで小さな事実を書き込み・想起できます(「〜を覚えておいて」)。エージェント別の書き込みは既定で暗号化されたMEMORY-001ストアを使い、旧markdown/Obsidian経路はフォールバックとして残っています。共有`_global`の書き込みは現在も旧経路です。保存状態と検証上の制約は[プライバシー](#プライバシー)を参照してください。
### コンパニオン
Shellyは自分専用の日誌をつけています。ペインがその会話から切り替わるたびに、自分自身のために要約を書き残し、あなたが覚えておいてと頼んだことはコンパニオン自身とすべてのバックグラウンドエージェントに想起されます——その全てを**Settings → Companion Memory** または **Memory Workbench** ペインから閲覧・編集・削除できます。登録済みのエージェントが1つも無い段階でも到達可能です。会話の途中でペインを明示的なプロバイダーへ切り替えても、Shellyは直近のメッセージを一緒に運ぶので、新しいプロバイダーは最初の返信からもうそのスレッドの文脈を踏まえています——同じコンパニオンが、別の脳で考えているだけです。
### Scouter ウィジェット
Scouter は Shelly のホーム画面エージェント起動パッド兼ヘルス一覧です。直近実行予定の
エージェント最大3件(名前・前回実行のステータスグリフ・次回発火時刻)を表示し、アプリを開かずに
実行したり、ASK 経由で新規登録したりできます。以前のバージョンはライブの Codex セッション HUD
(状態 / DOING 行・トークン / コンテキスト / レートリミットのセル・ローカル LLM の健全性行)と、
フォアグラウンドの Codex PTY に直接書き込む Allow / Deny・番号選択のピルも搭載していましたが、
2026-07-18 の再設計でウィジェットを「ランチャー」に絞るため意図的に削除されました。承認や選択は
引き続き Codex の通知チャンネルとアプリ内の Agent Chat ペイン([docs/FEATURES.ja.md](docs/FEATURES.ja.md)参照)から行えます。
[docs/FEATURES.ja.md](docs/FEATURES.ja.md)に、機能ごとの詳細な内訳(Scouterウィジェット内部、レイアウトシステム、ペインをまたぐ知能、Agent Chat、AI Edit、ターミナルの拡張、AIペイン、ブラウザペイン、ファイルツリー、プレビューペイン、サイドバー、コマンドパレット、テーマとフォント、Git連携、設定/APIキー/バックグラウンドエージェント)をまとめています。
### Codex ランタイム
- **ネイティブランタイム** — npm の `@openai/codex` パッケージは JS ディスパッチャ側の話の一部にすぎません。リリース APK には `.ci-versions/` の固定された Android ネイティブの統合 `codex_tui` バイナリが同梱され、ランタイム更新も同じ形のものを `~/.shelly-runtime/codex/current` にインストールします。
- **管理された昇格** — 新しいランタイム候補は、ダウンロード・SHA-256 検証・展開・実行可能性チェック・`codex_tui --version` / `codex_tui exec --help` のスモークチェックをすべて通ってから初めて昇格します。
- **修復 / リセットのパス** — アプリデータ側のランタイムが壊れている、あるいは不要な場合は、Updates UI から最新のランタイムリリースで修復するか、APK 同梱の Codex ランタイムにリセットできます。
---
## ステータス
日付・デバイス・証跡付きの全領域の検証ログ: **[docs/STATUS.ja.md](docs/STATUS.ja.md)**。コアターミナル・レイアウト・AI Edit・エージェント登録の各パスは広く出荷済みで、複数回にわたり実機で再検証されています。以下は、何かに依存する前に特に知っておく価値のある項目です。
| 領域 | 状態 |
|---|---|
| コアターミナル — ネイティブPTY、マルチペインレイアウト、AI Editのゴールデンパス、FileTree/git、コマンドパレット | ✅ 出荷済み、広く実機検証済み |
| バックグラウンド/自律エージェント — `@agent`登録 → AlarmManagerによる無人発火 → 通知 | ✅ 結線済み。無人発火はZ Fold6(N=1)で端から端まで実機確認済み。メーカー横断の信頼性はまだ広くテストできていません |
| サブエージェントのファンアウト(`parallelGroup`) — 分離されたブランチコンテキスト、無人での並行ディスパッチ | ✅ 2026-08-17に実際の3ブランチ並行AlarmManager発火で実機検証済み |
| Nacre Bridge — 著者自身のNacre IMEとのライブ端末コンテキスト共有、Nacre側のDev Mode | ✅ 2026-08-31に実機検証済み |
| エージェントのSNS投稿コネクタ — Bluesky、Discord、Slack、Telegram、Mastodon、Misskey、WordPress、X | ✅ Blueskyはライブで端から端まで検証済み。Xは統合テスト済みだが課金有効化済みの実アカウントでの発火は未実施。残りは同じコードパスに乗っているがそれぞれ実アカウントに対して発火させていません |
| Ask AI — ターミナルの選択範囲を AI ペインの入力欄に引用 | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| ティーチモード — `shelly teach start/stop` → 保存済みワークフロー → `shelly workflow run` | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| 出典付きブリーフィングを作る多段エージェント — Perplexity の出典を引き継ぎ、出典のない主張は落とし、`## Sources` を追加 | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| 1 回きりのスケジュール — "in 5 minutes"、"at 14:55"、「5分後に」 | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| エージェントのチャットスレッドへの受け渡しナレーション行 | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| キーボード / IME を考慮したペインレイアウト — 実際の IME の重なり分だけを確保 | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| テーマのライブ切り替え — Case File ほかのプリセットを再起動なしで適用、ターミナルの配色も含む | ✅ 実機検証済み(Galaxy Z Fold6、N=1) |
| エージェントの安全ルール(POLICY-001)— 自然言語ルール、自分で起動していない実行の読み取り専用の床、trust ramp | 🟡 実装済み、実機では未検証。フラグは既定 OFF |
| MCP サーバーの仕様 2026-07-28(ステートレス)対応、旧リビジョンと併存 | 🟡 実装済み、実機では未検証 |
| 端末内音声認識(キー不要、Android SpeechRecognizer) | 🟡 実装済み、実機では未検証 |
| ローカルモデル MiniCPM5-2B | 🟡 Experimental。評価したうえで不採用: Fold6 でルーティングは Qwen3.5-2B の 100% に対し 83%、ネイティブのツール呼び出しは 88% に対し 50% |
| ChatGPT からのスマホアプリ操作 — Codex が `shelly closepaw --wait "<ゴール>"` を実行 → 持ち主がスマホで承認 → Shelly 用 ClosePaw ビルドがバックグラウンドの仮想ディスプレイで操作 → 結果が ChatGPT に返る | ✅ 実機検証済み(Galaxy Z Fold6、N=1)。例: Spotify のプレイリスト保存、Google マップのリストへの保存。長い多段のゴールはまだ不安定 |
| ClosePaw への引き継ぎ — ゴールを ClosePaw(スマホ操作アプリ)へ渡すエージェントアクション(明示 Intent、実行ごとの Review、「引き継ぎ済み」で終了) | 🟡 Experimental。実装済み・実機未検証。ClosePaw からの結果受け取りは未対応(Phase 2 は上流の変更が必要) |
| llama.cpp を b11433 に固定し sha256 で検証 | 🟡 実装済み、実機では未検証 |
| 追加ツールパック — `shelly install ` / `--list` / `uninstall`、ビルドごとの sha256 固定、アトミックなインストール、未導入コマンドの案内 | 🟡 `dev-tools` のダウンロード→展開→実行は実機検証済み(2026-08-29、Galaxy Z Fold6、N=1)。2026-10-29 の sha256 固定・アトミック差し替え・オフライン時のエラー・`--list`・`uninstall` は実装・テスト済みだが実機未検証。パックのツールは今も APK に同梱されているため、APK はまだ小さくなっていない |
| `shelly device` — シェルから battery / info / clipboard / notify / toast / vibrate / tts / share(Termux:API の一部を組み込み、レート制限あり、エージェントのクリップボード読み取りは要承認) | ✅ 実機検証済み(Galaxy Z Fold6、N=1、2026-10-29): battery、info、clipboard set/get(読み取り通知とバックグラウンドでの拒否を含む)、notify と削除、toast、vibrate、tts、前面での共有シート、隠しファイルの共有拒否、回数制限。バックグラウンド時の「タップして共有」通知はまだ未確認 |
| 配布 | 🟡 GitHub Releases(`android-latest`)のみ。Playストア/F-Droidへの掲載はまだありません |
---
## 今後の予定
アプリの一部は書かれてはいるものの、まだ検証できていません。以下は短期のロードマップであって、現行ビルドに入っているものではありません:
- **Play ストア / F-Droid での配布** — APK の公開は GitHub Releases 経由のみで、ストアへの申請フローはまだ済んでいません
- **メーカー横断での自律エージェントの信頼性** — 無人でのスケジュール発火は Z Fold6 で観測済み(N=1)ですが、Android のバックグラウンド制限はメーカーによって異なります(Samsung / Xiaomi / Oppo / OnePlus のバッテリー凍結機能)。幅広い端末での信頼性検証と、端末の健全性 / 権限チェックリストはまだできていません
- **スニペット作成 UI** — コマンドパレットはスニペットストアの先頭 20 件を表示してターミナルにディスパッチしますが、アプリ内での作成 / インポート / 編集のフローは以前の整理で削除されました。スニペットは平文ファイルではなく Android の AsyncStorage(`store/snippet-store.ts`)に保存されており、(削除済みの)アプリ内 UI 以外での一括追加手段は現状ありません。
---
## ストーリー
### コードは自分の手では書いていません。
私は Creative Director であって、訓練を受けたエンジニアではありません。このリポジトリの全行は、私のディレクションのもと AI が生成したものです。Samsung Galaxy Z Fold6 の上で AI コーディングエージェントと会話しながら――デスクトップもラップトップも使わずに――書かせ、レビューし、実機でテストして出荷しています。アーキテクチャ上の判断はすべて私のものです。キーストロークは違います。私が持ち込んでいるのは、「画面に何を置き、何を置かないか」についての 20 年分のプロダクト判断で、結局のところそれが仕事の大半でした。
これは成り立ちの話であって、意図的に**信頼の話ではありません**。「AI が書いた」というのは、コードを *より高い* 検証基準にさらす理由であって、下げる理由ではありません。あなたはこのアプリにシェルの実行権限と広いストレージアクセスと API キーを渡すかどうかを判断しているわけですから、「なぜ信頼できるのか」への誠実な答えは、コードのまわりにある規律です。そのすべてがこのリポジトリで監査できます:
- **「完了」の前に実機で検証する。** 実機で動くのを観測するまで機能を出荷済みにはしませんし、検証した端末が 1 台だけならそう明記します。この README の[ステータス](#ステータス)表にある N=1 の注記は、そのポリシーを公開しているものです。
- **本物のコードを実行するテスト。** エージェントパイプラインのリグレッションテストは、実際に生成されるスクリプトを本物のプロセスで走らせます――本物の bash 実行、本物の HTTP 失敗面。出荷されるものから静かに乖離しうる手書きの再実装ではありません。
- **リスクの高いマージの前に敵対的レビュー。** ネイティブ、OAuth、IPC、セキュリティ境界に関わる変更は、着地前に別エージェントによるレビューを明示的に一段挟みます。署名付き承認チャンネルと自律エージェントの実行ゲートは、専用のセキュリティレビューを通しました。
- **雰囲気ではなくエンジニアリング台帳。** [`docs/superpowers/DEFERRED.md`](docs/superpowers/DEFERRED.md) が、何が出荷済みで、何がフラグで OFF にされていて、何が壊れていると分かっているのかについての唯一の真実の情報源です。理由と優先度付きで書いてあります。この README が言葉を濁しているときは、その濁りの出どころはここです。
- **エージェントスタックは、大きな音を立てて閉じる方向に倒れるよう作ってあります。** 無人実行はローカルとクラウドのバックエンドをまたぐエスカレーションラダー(`lib/agent-escalation-ladder.ts`)を登り、品質ゲートは「やった」と宣言するだけで実際には作業していない完了を弾き、承認が必要な無人アクションは未レビューのまま走るのではなく fail-closed で止まります。
スクリーンショットに写っているキーボード? あれも私が作りました。[Nacre](https://github.com/RYOITABASHI/Nacre) といって、Kotlin で書いた Android の IME です。これも全部 AI との会話だけで作りました。いままさに Shelly の中でそれを使って打ちながら、両方のアプリを同時に改善しています。
これはポートフォリオ用のプロジェクトではありません。私が毎日ものづくりに使っている道具です。もっと良くできるところを見つけたら、そのための issue トラッカーです。
### そもそも、なぜこれが存在するのか
モバイル開発は結局のところ普及しませんでした。スマホの計算能力が足りなかったからではなく、**入力**と**インターフェース**が「作ること」向けに設計されていなかったからです。
チャットアプリ(ChatGPT、Claude、Gemini)はコードについて*話す*ことはできても、*実行*できません。ターミナルエミュレータ(Termux)は何でも*実行*できますが、すでに開発者である人以外には冷たすぎます。
Shelly はその隙間を埋めます。AI ペインに「ポートフォリオサイトを作って」と打てば、本物のシェルがコマンドを実行し、ファイルを生成し、その結果を――それを生み出したターミナルのすぐ隣に――見せてくれます。
そして、その仕組みができてしまえば次の一歩は明らかです。見ていなくても動くようにすればいい。繰り返しのタスクを一度説明しておけば、スマホが自分のアラームで実行します。つけっぱなしのノート PC も、クラウドランナーのサブスクリプションも要りません。
### すべての設計判断が「問い」の形をしている理由
Shelly のあらゆる機能は、既存ツールへの私の不満から始まっています:
- ペイン間の仕組みは *「なんで片方のウィンドウからエラーをコピーして、もう片方に貼らなきゃいけないんだ?」*
- ネイティブターミナルは *「なんでアプリを切り替えるたびにターミナルが死ぬんだ?」*
- Codex の通知チャンネルと Agent Chat の Approve / Deny バブルは *「AI CLI が英語で承認を求めてくる。意味が分からない。」*
- VoiceChain は *「スマホのキーボードでは、思いつく速度に打鍵が追いつかない。」*
- レイアウトシステムは *「なんでブラウザとターミナルと AI を同じ画面に同時に置けないんだ?」*
- カラーテーマのプリセットは *「なんで使いやすい UI と、見ていて面白い UI のどちらかを選ばされるんだ?」*
制約はすべて、エンジニアにとっても同じくらい必要な工夫に変わりました。
### なぜネイティブなのか — WebView からの転回
初期バージョンは ttyd と WebView を使っていました。WebSocket 接続は切れる。Android の Phantom Process Killer がバックグラウンドプロセスを殺す。アプリを切り替えるたびにターミナルは死んでいました。
そこで私は AI に、全部捨ててネイティブに行けと指示しました。いまの Shelly はネイティブのターミナルエミュレータを内蔵しています――Termux 自身の `terminal-emulator` ライブラリから派生した Kotlin コードを、JNI の C レイヤー経由でアプリ所有の PTY につないだものです。TCP のターミナルサーバーなし。WebSocket の境界なし。落ちる ttyd プロセスもなし。
React Native アプリとしては珍しいアーキテクチャです。WebView でも外部ターミナルサーバーへのソケットブリッジでもなく、JNI `forkpty` によるアプリ所有の PTY を背後に持つ、組み込みのネイティブターミナルエミュレータなのですから。
### 誰のためのものか
- **自分のハードウェアの上でエージェントを動かしたい人** — 自分のアラーム、自分のキー、自分のファイルの上で動くスケジュール済みの無人タスク。シェルのトランスクリプトのレベルまで監査できます
- **Vibe Coder** — Lovable / Bolt / Replit Agent のようなものを、本物のターミナルを下に敷いた状態でスマホの上に
- **モバイルファーストの開発者** — Codex CLI ユーザーや、CLI ファーストの AI コーディングワークフローを本気でやりたい人で、本物のローカルターミナルを囲むちゃんとしたマルチペイン IDE が欲しい人
- **アイデアを持つ非エンジニア** — Shelly がすべてを翻訳します。危険な操作は実行前に説明と承認ステップとともに提示されます
---
## アーキテクチャ
### システム構成
```mermaid
flowchart TB
U["Android 上のユーザー"] --> UI["Shelly UI\nReact Native ペイン"]
subgraph P["ペインランタイム"]
TP["ターミナルペイン\nCodex フォアグラウンド CLI"]
AP["AI ペイン\nAPI とローカルのプロバイダ"]
BP["ブラウザペイン\nドキュメントと localhost"]
PP["プレビューペイン\nコード、Markdown、画像"]
end
UI --> TP
UI --> AP
UI --> BP
UI --> PP
subgraph N["ネイティブ Android ブリッジ"]
KT["Expo Kotlin モジュール"]
JNI["JNI C レイヤー\nforkpty と exec"]
TV["ターミナルレンダラ\nTermux 派生エミュレータ"]
end
TP --> KT --> JNI
JNI --> SH["アプリ所有のシェル\nbash, git, node, python"]
JNI --> WR["exec ラッパー\nlinker64 と LD_PRELOAD"]
SH --> CX["Codex ランタイム\n統合 codex_tui"]
TP --> TV
subgraph A["エージェントのコンテキスト"]
LOG["ターミナルのトランスクリプト"]
CTX["コンテキストビルダー\n秘匿化と圧縮"]
ACT["ユーザーが承認したアクション\nコマンド実行 / diff 適用"]
end
TP --> LOG --> CTX --> AP
AP --> ACT --> TP
subgraph R["リリースパイプライン"]
CI["GitHub Actions\nlint, typecheck, tests, APK build"]
APK["android-latest\nAPK と latest.json"]
CRT["codex-runtime-latest\nランタイム tarball とマニフェスト"]
end
CI --> APK
CI --> CRT
APK --> UP["Updates UI\nSHA-256 検証、インストーラへ引き渡し"]
CRT --> RU["ランタイムアップデータ\n検証、スモークテスト、昇格、リセット"]
UP --> UI
RU --> CX
```
Shelly の核は、普段は別々になっている 3 つのシステム――Android ネイティブのターミナルランタイム、
フォアグラウンドの Codex CLI、コンテキストを理解する AI ペイン――のつながりにあります。
ターミナルは WebView でもリモートブリッジでもなく、Kotlin が JNI 経由で読むアプリ所有の PTY です。
更新の仕組みも 2 系統に分かれていて、APK リリースがアプリとネイティブのペイロードを更新する一方、
Codex ランタイムのレーンは SHA-256 検証とスモークテストを経てより速く動けます。
### ペインをまたぐ知能
```mermaid
flowchart LR
subgraph AIPANE["AI ペイン"]
U["ユーザー:「エラーを直して」"]
R["AI: import のパスが違います..."]
RUN["▶ 修正を実行"]
end
subgraph TERMPANE["ターミナルペイン"]
CMD["$ npm run build"]
ERR["Error: Cannot find './utils'"]
FIX["$ mv util.ts utils.ts"]
end
ERR -- "トランスクリプトを注入" --> R
RUN -- "実行" --> FIX
U --> R
```
AI がターミナルを読む。ターミナルが AI を実行する。ユーザーはただ話すだけ。
画面レイアウト図、AI Editのゴールデンパス、ネイティブPTY(JNI forkpty)、実行中のテーマ切り替えの内部実装は[docs/ARCHITECTURE.ja.md](docs/ARCHITECTURE.ja.md)を参照してください。
---
## リリースの完全性
ここに挙げるのは、意図的に人工的な指標ではなく運用上の実態です。薄いクライアントではなく
本物の Android ネイティブなツールチェーンを配布することのコストが表れています。ビルドごとの
正確な数値(`versionCode`、コミット、アセット名、バイトサイズ、SHA-256)はリリースマニフェストに
あり、アプリ内アップデータがそれを直接読むので、このページと乖離することはありません:
- **Android APK** — [`android-latest/latest.json`](https://github.com/RYOITABASHI/Shelly/releases/download/android-latest/latest.json): `versionCode`、`versionName`、`gitSha`、`apkAssetName`、`apkSizeBytes`、`sha256`。
- **Codex ランタイム** — [`codex-runtime-latest/codex-runtime.json`](https://github.com/RYOITABASHI/Shelly/releases/download/codex-runtime-latest/codex-runtime.json): `codexVersion`、アセット名、`sha256`。
| 対象 | 実態 | なぜそのコストになるか |
|---|---|---|
| APK サイズ | 約 800 MB | bash / Node.js / Python 3 / git / ripgrep …に加え、Codex ランタイムをシムではない実バイナリとして同梱しているため |
| Codex ランタイム | 同梱 + 独立レーンで管理(約 160 MB) | APK より速く動けるよう、別に昇格させているため |
| リリースの検証 | インストーラに渡す前に SHA-256 を検証 | マニフェストとハッシュが一致しない APK をアップデータは拒否します |
| ランタイムの検証 | SHA-256 + `codex_tui --version` / `codex_tui exec --help` のスモークテスト | ランタイム候補は、実際に動いてから初めて昇格します |
| リリースごとの CI | lint · typecheck · ユニットテスト · ネイティブリリースビルド · 署名済み APK + マニフェストの公開 | すべてのリリース成果物を GitHub Actions がビルドし検証します |
要するに、大きな APK と、別建てで管理される Codex ランタイムと、端末に何かが届く前に
ネイティブのリリース成果物をビルドして検証済みの更新マニフェストを生成する CI パイプライン、
ということです。正確で最新の数値は、古くなりがちなこのページにコピーするのではなく、
上にリンクしたマニフェストに置いてあります。
---
## 技術スタック
| レイヤー | 技術 |
|-------|-----------|
| フレームワーク | Expo 54 / React Native 0.81 |
| 言語 | TypeScript (strict) + Kotlin + C |
| UI | NativeWind (TailwindCSS 3) |
| 状態管理 | Zustand |
| ナビゲーション | expo-router v6 |
| ターミナル | ネイティブエミュレータ(Kotlin、Termux 派生)+ JNI forkpty(C、アプリ所有の PTY) |
| フォント | アプリ / ターミナルの可読性のための JetBrains Mono。互換性のためレガシーのピクセルフォントも同梱 |
| i18n | expo-localization + Zustand(900 キー超、EN / JA) |
---
## コントリビューション
これは個人的な道具として始まりました。コミュニティからの貢献が、それを本当の OSS プロジェクトへと形づくりつつあります。
**最初の一歩を探しているなら** [`good first issue`](https://github.com/RYOITABASHI/Shelly/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) ラベルを見てください。ユニットテストはすでに Jest で結線してあります。ルーティング、更新マニフェスト、コマンドの安全性、ネイティブブリッジのヘルパーまわりを狙ったテストは特に助かります。
**まず見るべきファイル:**
- `lib/input-router.ts` — 頭脳。自然言語をシェルコマンド、AI へのリクエスト、`@mention` に分類します
- `lib/command-safety.ts` — リスク評価エンジン。5 段階の深刻度で危険なコマンドをブロックします
- `lib/auto-savepoint.ts` — ファイル変更を監視して自動コミット。いわゆる「ゲームのセーブ」システム
- `lib/ai-edit.ts` — ステージ中のファイルに対する unified diff のステージ / 適用 / ファジー再アンカー
- `lib/theme-presets.ts` — パレット + 実行中のプリセット切り替え + Text.render のモンキーパッチ
- `components/panes/InlineDiff.tsx` — hunk 単位の Accept / Reject と書き戻し
- `modules/terminal-view/android/.../ShellyTerminalView.kt` — ネイティブのターミナルレンダラ(Kotlin + Android Canvas)
- `modules/terminal-emulator/android/src/main/jni/shelly-pty.c` — JNI forkpty のレイヤー
もっと良くできるもの――きれいなパターン、パフォーマンス改善、バグ修正――を見つけたら、**ぜひ issue か PR を上げてください**。オープンソースにしているのは、まさにそのためです。
コントリビューションガイド: **[CONTRIBUTING.md](CONTRIBUTING.md)**
---
## ビジョン
2 年後、スマホは AI チャットを動かすだけでなく、あなたが見ていない間に働くエージェントを動かしているはずです。ハードウェアはもう揃っています――40 TOPS を超える NPU、12 GB の RAM、実用速度で端末上を走る数十億パラメータのモデル。足りなかったのは計算能力ではありませんでした。本物のターミナルと、本物のツールチェーンと、本物のスケジューラを、すでに持ち歩いている 1 つの場所にまとめて置けるインターフェースです。
ローカル LLM の推論が外に問い合わせなくてよくなり、スケジュールされたタスクがスマホ自身を起こせるようになると、クラウドランナーが届かない場所から、自分のキーで動くエージェントが手に入ります。つけっぱなしのノート PC も、支払うサーバーも、結果をどこかへ送るまでは Wi-Fi さえ要りません。Wi-Fi のない飛行機の中から、本物の無人作業を最初に出荷する人は、こういうものを使っているはずです。
Shelly はその未来のために、エージェント前提で作られています。ローカルとクラウドのバックエンドをまたぐエスカレーションラダーはすでに結線され、スケジューラと品質ゲートは実機テストの中で固まりつつあり、その下にはネイティブのターミナルがあります。スケジュール済みエージェントが使う環境は、あなたが開いて手で動かせる環境そのものです。
問いは「無人で端末上の AI が実現するかどうか」ではありません。誰が先にそのための道具を作るのか、そしてその道具が「実際に何を検証できたのか」について正直でいられるかどうかです。
---
## 作者について
**RYO ITABASHI** — [Rebuild Factoryz](https://rebuildfactoryz.com/) の Creative Director。ブランディングとデザインが本業で、コードは本業ではありません。それが実際にどう成り立っていて、なぜ出荷物の基準を下げないのかは、上の[ストーリー](#ストーリー)に書いてあります。
スクリーンショットに写っているキーボードは **Nacre** ――モバイルの入力問題を解くために(これも AI との会話だけで)作った、分割レイアウトの Android IME です。Shelly がインターフェースを担当し、Nacre が入力を担当する。この 2 つで、スマホだけの開発が現実になります。
**どちらも、デスクトップに一度も触れることなく、Samsung Galaxy Z Fold6 の上だけで開発されました。**
---
## サポート
Shelly は個人による自己資金のプロジェクトです。Termux のセットアップを 1 回省けたとか、スマホでの開発が現実になったとか、そういうことがあればコーヒー 1 杯がとても効きます。(Z Fold8 でも構いません――もちろん検証目的に限りますが。)
ほかにもこんな応援の仕方があります:
- ⭐ このリポジトリに Star を付ける
- 🐛 [バグを報告する](https://github.com/RYOITABASHI/Shelly/issues)
- 🔧 PR を送る — [コントリビューション](#コントリビューション)を参照
- 💬 Shelly で作ったものをシェアする
- 👍 [AlternativeTo](https://alternativeto.net/software/shelly-terminal/about/) で Like やレビューをする
このリポジトリ上部の「Sponsor」ボタンから GitHub Sponsors も利用できます。
---
## 既知の制限
Shelly はリリース前の Android ソフトウェアです。まだ完璧でないと分かっていることを書いておきます。
- **実機検証は 1 台だけです** — 「検証済み」と書いてあるものは、すべて実機の Galaxy Z Fold6(N=1)で確認したものです。ほかの端末で Shelly を動かした方は、`shelly doctor --report` の出力を貼って[端末レポート](https://github.com/RYOITABASHI/Shelly/issues/new?template=device-report.yml)を送ってください。その端末で何が動き、何が壊れるかが分かります。詳しくは [docs/device-testing.md](docs/device-testing.md)。
- **デフォルトではオフラインモードがありません** — クラウド AI 機能にはインターネット接続が必要です。`@local` によるローカル LLM は、同梱カタログと llama.cpp / llama-server のコントロールでオフラインでも動きます。実際のデフォルトは Qwen3.5-0.8B Q4_K_M、オンデマンド用途への推奨アップグレードが Qwen3.5-2B Q4_K_M、Qwen3 1.7B はその中間、4B / 9B は短時間の品質確認用です。
- **同梱セット以外のツール** — Shelly には bash、Node.js、Python 3、git、curl、ssh、sqlite3、tmux、vim、less、jq、make、および GNU coreutils 一式が入っています。**入っていない**主なものは `busybox`、`watch`(procps-ng)、`htop`、そしてほとんどのネットワークデーモンです。`watch`が必要な場合は回避策`while true; do clear; ; sleep 1; done`を使う(bug #34として追跡中)か、Termuxを併用してください。それ以外が必要なら、`modules/terminal-emulator/android/src/main/jniLibs/` にバイナリを追加する PR を送ってください。
- **`busybox` は同梱していません** — `busybox httpd`、`busybox nc` などの applet は `command not found` になります。使える範囲で単体版(`curl`、同梱の `nc`、`python3 -m http.server`)を使うか、自分で `busybox-static` を同梱してください。bug #35 として追跡中です。
- **`@team` は複数の API に同時にルーティングします** — 実行前の確認ステップなしに、すべてのプロバイダのクレジットを一度に消費します。意識して使ってください。
- **一部編集済みのファイルに対する複数 hunk の Accept** — hunk 単位の Accept はファジー再アンカーを使うので後続の hunk も着地しますが、AI の diff がすでに別内容へ編集済みのコンテキストを参照している場合、その hunk は拒否され、再生成を促すトーストが出ます。
- **ターミナルフォントの不一致** — アップグレード後に保存済みのレガシーテーマの表示が崩れる場合は、Settings → Display → Theme で 3 つのカラープリセットのいずれかに切り替えてください。
- **Codex CLI は Shelly が管理するランタイムルーティングを通ります** — Shelly はまず `~/.shelly-runtime/codex/current` の健全なアプリデータ側ランタイムを優先し、次に APK 同梱ランタイムにフォールバックします。`codex --version` が失敗する場合は `shelly-doctor`、`shelly-update-clis codex --check-only` を実行するか、**Settings → Updates → Repair Codex / Reset** を使ってください。
- **Codex のログインはアプリ内デバイスコード OAuth フローです** — 任意のターミナルペインで素の `codex` か `codex-login --open` を実行します。Shelly は `~/.codex/auth.json` を検証し、無い / 無効なら OpenAI の検証ページをアプリ内ブラウザペインで開き、成功したら `~/.codex/auth.json` をパーミッション `0600` で書き込んでから、通常の Codex TUI を起動します。OpenAI API キーは不要で、ChatGPT の Plus / Pro / Business / Enterprise サブスクリプションに乗ります。デバイスコードには 15 分のタイムアウトがあるので、切れたら再実行してください。確認は `shelly-doctor` で行えます(`~/.codex/auth.json` の有無を報告します)。
- **`/sdcard` へのアクセスには MANAGE_EXTERNAL_STORAGE が必要です** — Android 11 以降の Scoped Storage は、この権限なしでは `/sdcard` 配下への直接の `open(2)` をブロックします。Shelly は初回起動時に要求しますが、拒否すると `source /sdcard/Download/foo.sh` は `Permission denied` で失敗します。あとから付与する場合はシステムの 設定 → アプリ → Shelly → 権限 → ファイルとメディア → すべてのファイルの管理を許可 から。
- **Gemini は API のみです** — Gemini はキーを設定した API プロバイダとして利用できます(AI ペイン、`@gemini`、`@team`、バックグラウンドエージェント)。このリリースには Gemini CLI の同梱も、対話的な `gemini` ログインフローもありません。
- **非常に大きなペーストやバイナリのペースト** — ペースト経路は PTY への一発書き込みです。数 MB のクリップボードペイロードは目に見えて時間がかかり、UI が一瞬止まることがあります。バイナリ内容(非 UTF-8 バイト、ヌル文字)はサポートされた転送手段ではなく、シェルのバッファを壊す可能性があります。バイナリ転送には `curl -O` / `scp` / `/sdcard/Download/` の受け渡しを使ってください。
- **CLI セッション中の折りたたみ / 回転 / 画面分割** — Shelly はレイアウト変更を生き延びますが、Android の Activity 再生成をまたいでターミナル状態が常に保持されるわけではありません。激しいマルチタスク(素早い折り曲げ ↔ 展開、フォアグラウンドジョブ実行中の画面分割ドラッグ)の前に、保存やコミットを済ませてください。特に AI CLI のストリーミングは、回転させる前に完了させるか Ctrl-C で中断するのが安全です。
## 権限
Shelly はシェルコマンドを実行し、ファイルを編集し、AI API を呼び、資格情報を保存するターミナルアプリです。この組み合わせには、一般的なアプリより多くの Android 権限が必要になります。それぞれの理由、拒否した場合に何が起きるか、代替手段を書いておきます。
| 権限 | 理由 | 拒否した場合 | 代替 |
|---|---|---|---|
| **MANAGE_EXTERNAL_STORAGE** | ターミナルが `/sdcard/Download` などの共有ディレクトリのスクリプトを読むため。「adb push でファイルを送り、シェルから source する」という定番のワークフローにはこれが必要です。 | `source /sdcard/Download/*.sh` が `Permission denied` で失敗します。`$HOME`(アプリの専用データディレクトリ)内はすべて従来どおり動きます。 | SAF ベースのファイル単位インポート UI を Play ストア配布向けに計画中です(DEFERRED P3)。当面は 設定 → アプリ → Shelly → 権限 → ファイルとメディア → すべてのファイルの管理を許可 から付与してください。 |
| **INTERNET** | AI API の呼び出し(Gemini、Groq、Perplexity、Cerebras、OpenRouter、OpenAI 互換 / ローカルサーバー)と、CLI のアカウント / デバイス認証フロー。CLI 更新のランタイムチェックにも使います。 | クラウド AI 機能とログイン / 更新フローが動かなくなります。ローカル LLM(`@local`)とターミナル機能はすべて動きます。 | 完全に端末上で推論するなら `@local` を使ってください。 |
| **POST_NOTIFICATIONS** | CLI の完了通知(長時間かかるコマンドがシステム通知を出す)。 | 「コマンドが終わった」という通知が出なくなります。 | — |
| **FOREGROUND_SERVICE** | アプリをバックグラウンドに回してもターミナルを生かし続けるため。 | アプリを切り替えたときに、シェルプロセスが OS に殺される可能性があります。 | — |
| **RECORD_AUDIO** | 音声入力(VoiceChat + VoiceChain)。 | 音声機能が無効になります。入力は通常どおり打てます。 | — |
Shelly の配布は当面 GitHub Releases 経由で、Google Play や F-Droid ではまだありません。`MANAGE_EXTERNAL_STORAGE` 権限は Play ストアの全ファイルアクセス審査を必要とするため、フォールバックとして SAF ベースのインポート経路が用意できるまで、Play ストアでの配布は先送りしています。
---
## セキュリティ
Shelly はあなたの端末上でコマンドを実行します。安全機構はベストエフォートの層であって、保証ではありません。
- **セキュリティモデル** — Shelly は堅牢化された VM ではなく、通常の Android アプリサンドボックスです。ターミナルのコマンドと承認済みの AI エージェントのアクションは、アプリの uid として動き、アプリがアクセスできるものは読み書きできます。
- **コマンドの安全性は正規表現ベースです** — 5 段階のリスク評価はパターンマッチングで動きます。よくある危険なパターン(`rm -rf /`、`dd if=` など)は捕まえますが、サンドボックスではありません。ファイアウォールではなくシートベルトだと考えてください。
- **APK は CI のリリース APK で配布しています** — GitHub Actions がリリース APK をビルドし、ローリングの `android-latest` リリースに公開します。本番相当の署名保証が必要なら、リポジトリを clone して自分の keystore でビルドしてください。[ソースからビルド](#ソースからビルド)を参照。
- **自律エージェントはゲートされていて、自由に動き回りません** — AI ペインとバックグラウンドエージェントは、隠れたサブスクリプションの再利用ではなく明示的な API プロバイダを使います。シェルコマンドの実行やリスクのあるアクションは、引き続き Shelly の承認 / コマンド安全性のパスを通ります。エージェントが無人で動いていて承認が必要なアクションに当たった場合は、未レビューのまま走るのではなく fail-closed で止まります。隠れたサブスクリプションワーカーは存在しません。
- **API キーは SecureStore に保存されます** — キーがログやデバッグ出力に書き出されることはありません。SecureStore は対応端末では Android Keystore の暗号化を使います。
- **`shelly-doctor`** — シェル / ネイティブバイナリの有無、同梱 Codex バイナリ、JS ディスパッチャ、ローカル LLM エンドポイント、`~/.codex/auth.json` の有無を報告します。何かおかしいと感じたら実行してください。
- **ログの秘匿化** — Shelly はアプリのデバッグログを書く前に、よくある API キーやトークンのパターンを伏せ字にします。これはガードレールであって、シークレットをプロンプトやターミナル出力に貼ってよいという意味ではありません。
- **利便性 ≠ セキュリティ** — Shelly はシェルの実行、AI のディスパッチ、ファイル編集、API キーの保管、広いストレージアクセスを 1 つのアプリに束ねています。強力ですが、どれか 1 層が破られると他の層にも影響しうるということでもあります。ソースを読み、自分の keystore でビルドし、Shelly は開発ツールとして扱ってください。本番のサーバー環境としてではなく。
脅威モデルと非公開の脆弱性報告手順については [SECURITY.md](./SECURITY.md) を参照してください。
ChatGPT リモート操作、ClosePaw への引き渡し、MCP サーバー、定期実行エージェント、保存したキーを止める・取り消す方法は [docs/revoke-access.ja.md](./docs/revoke-access.ja.md) を参照してください。
---
## プライバシー
- **ユーザープロファイルの学習** — Shelly はあなたのコマンドの傾向と AI の使い方を観察して、提案をパーソナライズします(`lib/user-profile.ts`)。このデータは AsyncStorage に端末内で保持されます。Profile Learningが有効な状態でクラウドAIへメッセージを送ると、応答品質を上げるためにプロファイルのコンテキストがAPIリクエストに含まれます。設定 → AgentsにはProfile LearningトグルとReset Profileアクションがあります。
- **永続エージェントメモリ** — `MEMORY_ENABLED`は`true`で、エージェント別の想起・書き込み・一覧は既定でMEMORY-001を使います。このJSONレコードはAES-256-GCMと端末のSecureStoreに保管した鍵で保存時暗号化されますが、新ストアが失敗すると旧G2 markdown/Obsidian経路へフォールバックし、共有`_global`の書き込みも現在はG2を直接使います。旧平文ファイルが実機に一切残らないこと、アンインストール後に旧レコードを復号できないことは未検証です。また`touchesPii`分類シグナルは生成されますがmodel eligibilityをまだ制御しないため、secret patternではない機微な文章がcloud routingから除外されるとは仮定しないでください。
- **テレメトリなし** — Shelly は外部に情報を送りません。アナリティクスも、クラッシュレポートも、利用状況のトラッキングもありません。ネットワーク通信が発生するのは、あなたが起こしたことだけです――AI API の呼び出し、Codex の認証、更新チェック / ダウンロード、ブラウザペインの利用、そしてあなたが設定したローカル / API のエンドポイント。
- **ローカル LLM モード** — 完全にプライベートに使いたい場合は、llama.cpp 経由でローカルの GGUF モデルを設定してください。実際のデフォルトは Qwen3.5-0.8B Q4_K_M、メモリに余裕があるときの推奨アップグレードが Qwen3.5-2B Q4_K_M、Qwen3 1.7B はその中間、4B / 9B は短時間の品質確認用に用意しています。処理はすべて端末上で完結します。
---
レビュアー・ライター向けの事実資料(作者による記述、検証手順つき): [docs/press-kit.md](./docs/press-kit.md)
---
## ライセンス
[GPLv3](./LICENSE) — Copyright (c) 2026 RYO ITABASHI
このプロジェクトには [Termux](https://github.com/termux/termux-app)(GPLv3)由来のコード、具体的にはターミナルエミュレータの描画層が含まれています。