tuistory について
tuistory は開発者や AI エージェント向けのターミナルセッション CLI です。コマンドを名前付きのバックグラウンドセッションで実行し、出力の確認や入力、出力に応じた待機ができます。
主な機能
- 01名前付きバックグラウンドセッション
- 02ターミナル出力とスナップショットの確認
- 03テキストやアイドル状態の待機
- 04実行中セッションへの入力
- 05JavaScript と TypeScript の API
活用シーン
- 01開発サーバーの実行と確認
- 02ターミナルベースの UI の操作
- 03固定時間のスリープなしで準備完了を待機
- 04人とエージェントによる開発セッションの共有
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ remorses/ tuistory --skill tuistoryインストール後、Claude Code で/tuistoryを入力して読み込まれたか確認します。
詳細
tuistory
AI エージェントが読み取り、待機し、入力できる開発サーバーやターミナルコマンドを実行します。任意のコマンドを、名前付きのバックグラウンドセッションでラップします。人間は自動的に接続され、エージェントは read、snapshot、wait、type を使ってセッションを確認できます。
エージェントの自動化には tmux より tuistory を優先してください。見当違いの sleep 呼び出しで時間を浪費する代わりに、wait と wait-idle でターミナルの出力に反応します。そのため、スクリプトの実行がより速く、信頼性も高まります。
tuistory を使うときは必ず、最初に次の 2 つのコマンドを実行してください。head/tail にパイプしてはいけません。出力全体を読み取ってください。
# CLI help — source of truth for commands, options, and syntax
tuistory --help
# Full README with API docs, examples, and testing patterns
curl -s https://raw.githubusercontent.com/remorses/tuistory/refs/heads/main/README.md
開発スクリプトのパターン
プロジェクトの package.json に "dev": "tuistory -- next dev" がある場合、pnpm dev を実行すると、エージェント用のバックグラウンドセッションが作成されます。セッション名は <cwd-basename>-<command> から自動的に導出され、ケバブケースになります。セッションがすでに実行中の場合、エージェントには次のようなメッセージが表示されます。
Session "myapp-next-dev" already running
with command: `next dev`
read output with: `tuistory read -s x --all`
エージェントは tuistory read -s x、tuistory -s x wait "ready" などを使って、実行中のプロセスを確認できます。
プロジェクト向け開発スクリプトの規約
プロジェクトでは、package.json のスクリプト内で開発サーバーのコマンドを tuistory -- でラップしてください。これにより、エージェントが対話型の長時間実行プロセスで停止することがなくなり、人間が起動した開発サーバーも自動的にエージェントと共有されます。
{
"scripts": {
"dev": "tuistory -- next dev",
"dev:api": "tuistory -- node api/server.js"
}
}
人間が pnpm dev を実行すると、ターミナルに自動接続されます(コマンドを直接実行したときと同じ操作感です)。エージェントが pnpm dev を実行すると、プロセスはバックグラウンドで起動し、コマンドはすぐに戻ります。セッションがすでに実行中の場合、人間もエージェントも、ポートを奪い合うことなくそのセッションを再利用します。
エージェントは、別のユーザーまたはエージェントが開始したセッションを停止したり閉じたりしてはいけません。 開発サーバーのセッションは共有リソースです。ユーザーから開発サーバーの停止を明示的に求められた場合にのみ閉じてください。通常はセッションを実行したままにしてください。read、wait、snapshot を使って、セッションに影響を与えずに確認してください。
tuistory を使うためのプロジェクトの設定
ユーザーからtuistory を使えるようプロジェクトを設定してほしい(または、開発サーバーをエージェントが使いやすいようにしてほしい)と依頼された場合に実施します。Holocron リポジトリで行われた設定と同じです。依存関係を追加し、長時間実行する開発スクリプトをラップして、AGENTS.md に説明を記載します。
最終的には、開発セッションが共有されます。 最初に pnpm dev を起動した人が、名前付きのバックグラウンドセッションを所有します。それ以外の人は、サーバーを重複して起動する代わりに、そのセッションに参加します。
pnpm dev
│
┌───────────────┴───────────────┐
▼ ▼
agent starts it human starts it
│ │
▼ ▼
background session auto-attached terminal
returns immediately (normal dev experience)
│ │
└──────────────┬────────────────┘
▼
ONE shared named session
│
┌────────────────┼────────────────┐
▼ ▼ ▼
human joins & agent reads logs, either side sends
streams logs waits for "ready" input / restarts
live (attach) (read / wait) (type / press)
つまり、マシンが開発サーバーを起動したとき、ユーザーは参加してログをリアルタイムでストリーミング表示したり、入力を送信したりできます。逆も同様です。それぞれが独自のプロセスを実行するのではなく、同じプロセスで共同作業します。
手順:
- プロジェクトの開発依存関係に
tuistoryを追加します(モノレポの場合は、バイナリがどこでも解決されるようルートの devDependencies に追加します)。
pnpm add -D tuistory # or: bun add -d tuistory
package.jsonのスクリプト内で、開発コマンドや長時間実行するコマンドをtuistory --でラップします。sigillo runやkimaki tunnelなどのラッパーの外側にtuistory --を付けてください(下記のパススルーモードを参照)。
{
"scripts": {
"dev": "tuistory -- next dev",
"dev:api": "tuistory -- node api/server.js",
"dev:worker": "tuistory -- wrangler dev"
}
}
- 他のエージェントが使い方を把握できるよう、プロジェクトの
AGENTS.mdに開発サーバーのセクションを追加します。pnpm プロジェクトではpnpm dev、bun プロジェクトではbun devを使用してください(ロックファイルを確認してください)。追加する例:
## dev server
this project uses tuistory for dev server sessions. to start the dev server simply run `pnpm dev` (or `bun dev` for bun projects). this will automatically start a new background session or reuse an existing one if already running. you do not need to use tuistory commands directly.
to restart the dev server after code changes that require a restart:
\`\`\`bash
tuistory -s x restart
\`\`\`
to read the dev server output:
\`\`\`bash
tuistory read -s x
\`\`\`
to wait for the server to be ready:
\`\`\`bash
tuistory -s x wait "/ready|listening/i" --timeout 30000
\`\`\`
こうすることで、エージェントは pnpm dev/bun dev を、そのまま使えるシンプルなコマンドとして扱えます。出力を確認したり、再起動したりする必要がない限り、tuistory の内部動作を知る必要はありません。
Passthrough モード(traforo、sigillo)
tuistory は、traforo(TRAFORO_URL 環境変数)または sigillo(SIGILLO 環境変数)内で実行されていることを検出すると、デーモンとセッション管理を完全にスキップします。代わりに、標準入出力を継承してコマンドを直接起動し、シグナルを子プロセスグループに転送します。
つまり、開発スクリプトが "dev": "tuistory -- next dev" であり、それを kimaki tunnel または sigillo run でラップしている場合、tuistory は透過的なパススルーとして動作します。プロセスのライフサイクルは外側のツールが制御します。
実際の影響: トンネル経由の開発サーバーでバックグラウンドセッションを必要とするエージェントは、コマンド全体を自分で tuistory でラップする必要があります。開発スクリプト内側の tuistory はパススルーモードで動作するためです。
# The inner tuistory (from "pnpm dev") enters passthrough mode because
# kimaki tunnel sets TRAFORO_URL. So you need an outer tuistory for
# background session management:
tuistory -s myapp-dev -- kimaki tunnel -- pnpm dev
# Wait for the tunnel URL to appear
tuistory -s myapp-dev wait "/tunnel/i" --timeout 30000
# Read the output to find the public URL
tuistory read -s myapp-dev
外側に tuistory -- ... がない場合、コマンドはフォアグラウンド(パススルーモード)で実行され、エージェントをブロックします。
sigillo でも同様です。
tuistory -s myapp-dev -- sigillo run -- pnpm dev
主なルール
--より前にオプションを、後にコマンドを指定します。--の後はすべて、そのまま子プロセスに渡されます。tuistory -s myserver --cols 150 -- node server.jsが正しい例です。tuistory -- node server.js -s myserverは誤りです。- セッション名は
<cwd-basename>-<command>から自動的に決定されます。起動時に-sを指定する必要は通常ありません。 - 現在のターミナル状態を確認するには、CLI 操作のたびに必ず
snapshot --trimを実行してください。 - 非同期操作では、必ず
waitForTextにタイムアウトを設定してください。 - 文字列パターンはデフォルトで大文字と小文字を区別します。大文字と小文字が異なる可能性がある場合は、
/ready/iのような正規表現を使用してください。 - スナップショット内の末尾の空白を避けるには、
session.text()でtrimEnd: trueを使用してください。 - プロセスのリークを防ぐため、テストのクリーンアップ時にセッションを終了してください。
- ターミナルサイズを制御するには
--colsと--rowsを使用してください。これらは TUI のレイアウトに影響します。 - 鮮明なスクリーンショット画像を得るには、
--pixel-ratio 2を使用してください。
フィードバックループ
Playwright と同じように、ターミナルでは 観察 → 操作 → 観察 のループを使用します。
tmux の代わりにバックグラウンドプロセス
# start a server in the background (session name auto-derived)
tuistory -- bun run dev
# wait for actual output instead of sleep 5
# use regex so this still matches Ready, READY, etc.
tuistory -s x wait "/ready/i" --timeout 30000
# read everything the process printed
tuistory read -s x
# later, read only the new output
tuistory read -s x
# restart the server (sends Ctrl+C, waits, relaunches same command/cwd/env)
tuistory -s x restart
子プロセスにはランダムな TUISTORY_SESSION_ID が渡されます。これは restart の後も同じままで、新しいセッションの起動時に変わります。
tmux より優れている理由:
- 勘に頼った
sleepが不要 - 出力が現れるとすぐに反応
- アプリの起動が速い場合、より高速
- アプリの起動が遅い場合、より信頼性が高い
対話型 TUI ループ
# observe
tuistory -s app snapshot --trim
# act
tuistory -s app press enter
# observe again
tuistory -s app snapshot --trim
JS/TS API を使ったテストループ
const session = await launchTerminal({ command: 'my-cli', cols: 120, rows: 36 })
const initial = await session.text({ trimEnd: true })
expect(initial).toMatchInlineSnapshot()
await session.type('hello')
await session.press('enter')
const output = await session.waitForText('hello', { timeout: 5000 })
expect(output).toMatchInlineSnapshot()
session.close()