# 変更履歴 ## 未リリース ### MCP サーバー(ADR-029) - **MCP サーバー: Mercury が Model Context Protocol サーバーのツールを使えるようになりました。** ローカルサーバー(`mercury mcp add files --stdio npx -- -y @modelcontextprotocol/server-filesystem ~/Documents`)またはリモートサーバー(`--http `)を追加し、使いたいツールを許可する(`mercury mcp allow`)と、エージェントは組み込みツールと並べてそれらを呼び出せます。Ask Me モードではすべての MCP 呼び出しの前に確認が入り、Allow All は MCP ツールには適用されません。プロンプトなしで実行されるのは `autoApprove` に列挙したツールだけで、スケジュールされたタスクで実行されるのもそれらのツールだけです。シークレットは `${env:NAME}` 参照として `.env` に保持され、表示されうるすべての場所でマスクされます。ローカルサーバーには最小限の環境のみが渡され、Mercury の API キーは決して渡されません。リモートサーバーは SSRF ガードを経由します。ヘルスチェックは `mercury mcp test`、`mercury doctor --mcp`、チャットでの `/mcp`、または新しい読み取り専用の **MCP** ダッシュボードページで行えます。エージェントのファイルツールは、Allow All 下であっても、`mercury.yaml`、`permissions.yaml`、`.env` に書き込む前に必ず確認するようになりました。詳しくは [MCP Servers](https://mercuryagent.sh/docs/integrations/mcp) と ADR-029 を参照してください。 ## 1.4.2 — ちゃんと見つかる検索と、本当に望んだときだけ尋ねるリサーチプロンプト ### Web 検索 - **実際に機能する 3 つの Web ソース。** `web_search` はまず [Parallel の公開検索](https://search.parallel.ai/mcp)(エージェント向けに作られたキー不要の MCP。約 1 秒で、抜粋と日付付き)に問い合わせ、次に DuckDuckGo の html ページ、さらにその lite ページを使います。Brave、Wikipedia、Hacker News、Bing の Web フィードは Web 検索から外しました。Brave は自動リクエストを拒否し、その他は一般的な質問への回答品質が低かったためです。ニュース検索は Parallel(記事リンクのみ。セクションのトップページは除外)を残し、その後に Bing News、Google News、Hacker News を使います。 - **DuckDuckGo を正確にパース。** 両ページとも実際のマークアップから読み取ります。各結果のタイトル、DuckDuckGo のリダイレクトの裏にある実際のアドレス、スニペットを取得し、広告(`result--ad`、スポンサー行)は除外します。チャレンジが返された場合は少し待ってから 1 回だけ再試行し、結果でも "No results" でもないページは、黙って空を返すのではなく「page not recognised」と報告します。テストは両方の実ページの保存コピーに対して実行されます。 - **ニュースのリンクで記事が開くように。** ニュース検索は以前 Google News を最初に使っていましたが、そのリンクは Google のリダイレクト(`news.google.com/rss/articles/…`)で、配信元のアドレスに変換できませんでした。現在は Bing News が最初に来て、そのリンクは実際の記事に展開されます。Google News はフォールバックで、そのリンクはリダイレクトとして明示されます。 - **検索がモデルに依存しない。** 結果は Mercury 自身の検索ツールからのみ得られ、プロバイダー組み込みの Web 検索は使いません。そのため、どのモデルでも検索は同じように動作します。 - **web-search スキル(1.3.0)がソースについて説明**し、検索結果が空だった場合は、どのソースがなぜ失敗したかを報告するようモデルに指示します。 - **何が起きたか見える。** すべての結果の末尾に経路が表示されます。例: `Searched: Parallel: timed out → DuckDuckGo: 8 results`。これにより「何も見つからなかった」と「すべてブロックされた」を区別できます。 ### チャット - **リサーチプロンプトはリサーチを望んだときだけ表示。** 以前は単語("latest"、"recent"、"explain"、"today's news")で発火していたため、「最新の epub を変換して」や「ビルドの仕組みを説明して直して」でもリサーチの確認が出ていました。現在、単語は確認するかどうかを決めるだけで、詳細な複数ソースのまとめを求めたかどうかは短いモデル呼び出し 1 回で判定します。指示、ちょっとした質問、今日のニュースではプロンプトは出ず、判定が失敗したり遅かったりした場合もプロンプトは出ません。 - **「Quick answer」が先頭に。** ピッカーは「Quick answer」から始まるので、うっかり Enter を押しても長いリサーチが始まることはありません。 ## 1.4.1 — Mercury があなたの働き方を学び、自分でスキルを保存し、再び検索できるように ### Owner Model: Mercury があなたとの協働の仕方を学ぶ(ADR-026) - **メモリが根拠付きの「信念(belief)」に。** あなたに関するすべての主張は、裏付けと反証、再び観測されない限り薄れていく確信度、適用される文脈、そしてステータス(candidate → held → あなたによる confirmed、contested、retired、forgotten)を持つようになりました。あなたが明言したことは Mercury の推測より優先され、決して薄れません。あなたの知らないところで削除されることはありません。 - **学ぶのは性格タイプではなく仕事上の特性です:** 返答の長さ、行動前に確認すべきタイミング(プロジェクトや領域ごと)、選択肢の提示か推奨か、トーン、領域ごとの専門性とリスク許容度、普段いる時間帯、フィードバックの仕方。健康、宗教、政治、性的指向、性格タイプを推測することはなく、認証情報を保存することもなく、他人についてあなたが言った以上の一般化もしません。 - **2 つのループ。** 各ターンの後、厳格な抽出器がそのターンを信念操作に変換します(または何もしません。Mercury 自身の返答があなたについての根拠になることはありません)。活動中は 1 時間ごと、およびシャットダウン時に、振り返りパスがセッションをまたいであなたのメッセージと振る舞いを読み、特性を推測し、重複を統合し、矛盾を指摘し、オーナー概要を書き直します。 - **ついにモデルがそれを参照:** 「About you」と「How to work with you」がすべてのプロンプトに含まれ、さらに各メッセージに関連する信念も含まれます。反対されずに行動に使われた信念は裏付けが増え、訂正されると古い信念は retired になり新しい信念が held になります。 - **学習したことは知らされます。** 振る舞いを変える学習があると、返答の最後に 1 行 `☿ Noted: … Say "forget that" to undo.` が付きます。矛盾については一度だけ質問します。`/memory learned|beliefs|contested|confirm|correct|forget|settle`、`/forget `、「forget that」、`forget_memory` / `confirm_belief` / `correct_belief` ツール、Confirm/Forget 付きのダッシュボードビュー、そしてメモが読み戻される編集可能な `~/.mercury/soul/owner.md` が使えます。 - **衛生管理:** 旧抽出器は Mercury 自身の返答をあなたの好みとして保存していました(典型的なストアの約半分)。それらの行は削除ではなく隔離され(ダッシュボード → Quarantined、Restore 付き)、本物のメモリは信念になりました。散文によるフォールバックは廃止され、統合が機能するようになり、競合がランダムに削除されることもなくなり、あなたが編集した soul ファイルがマイグレーションで上書きされることもありません。 - **単一のソース。** `/memory`、ダッシュボード、`save_memory` / `search_memory` ツール、ボット、クラウド同期のすべてが信念ストアを読み書きするようになりました。旧 `memories` テーブルは読み取り専用のアーカイブです。名前、メールアドレス、ハンドルは `mercury.yaml` の `identity.owner` に保持され、信念として保存されることはありません。 - **チャットが読んだ内容を実際に使えるように。** メッセージごとの想起では held の信念が先に表示され、未検証の candidate(推測としてラベル付け)で補われます。そのため、Mercury が今日学んだことやアップグレードで移行されたものが、2 回目のセッションを待たずにすぐ見えます。「私について何を知ってる?」と聞くと、最も強い信念が直接挿入されます。ストップワードやチャネルの定型部分が検索を汚すことはなくなり、「About you」セクションは十分な held が揃うまで控えめな表現の candidate で補われます。 - **抽出器の 2 つの漏れを修正。** 相槌のように始まる訂正(「いやいや、イギリス綴りって言ったよね…」)が些細なものとしてスキップされなくなり、モデルが `excerpt` なしで出力した操作は破棄されずにあなたのメッセージを引用するようになりました(これだけで Haiku ではターン全体が失われていました)。 - **学習に使うモデルを選べます。** `memory.learning.provider: anthropic`(または `LEARNING_PROVIDER`)を設定すると、チャットは独自のプロバイダーのまま、抽出と振り返りを高性能なプロバイダーで実行します。未設定の場合はデフォルトにフォールバックします。 - **安全なアップグレード。** アップグレード後の最初の起動時、マイグレーション前に `second-brain.db` を `second-brain.pre-owner-model.db` にバックアップします。マイグレーションは 1 回だけ実行され、起動をクラッシュさせることはありません。以前見えていたメモリはすべて引き続き一覧に表示され(または Quarantined で待機し)、「☿ Noted」の行は各チャネルで数分に 1 回までに制限されます。 ### 自作スキル(ADR-027) - **Mercury が長い作業をスキルに変える。** 再び行うであろう複数ステップのタスク(定期レポート、変換パイプライン、デプロイ、操作するサイトやデバイス)がエンドツーエンドで成功すると、Mercury は新しい `create_skill` ツールで手順(正確なコマンド、パス、チェック、落とし穴)を保存し、1 行で知らせます。次回からは `use_skill` 1 回で実行できます。 - **あなたのスキルとは分けて管理。** 自作スキルは `~/.mercury/skills/self-made/` に置かれ、`origin: mercury` を持ち、専用の「Self-made」ラベルの下に一覧表示され、再び使われるまでは未検証として扱われます。実在し、検証済みで、認証情報を含まない手順でない限りドラフトは却下されます。自作スキルがインストール済みのスキルを覆い隠すことはありません。 - **スキルのカテゴリとインテントが再び機能。** ディスカバリーは各スキルのカテゴリ、インテント、タグを登録した後にインデックスを再構築しており、それらを消去していました。その結果、プロンプトはフラットな一覧にフォールバックし、インテントのルーティングは名前だけで照合されていました。先にインデックスを構築するよう修正しました。 - **ガラクタ置き場にしない。** `/skills self-made` は各スキルを使用回数付きで表示します。使われないスキルは 30 日後に休眠状態になり(無効化されるだけで削除はされません)、上限は 40 個です。`/skills self-made enable|disable|remove `。ボットやチャネルのメンバーはスキルを作成できません。 ### Web 検索 - **検索が再び実際の結果を返すように。引き続き無料・キー不要です。** メインエンジンだった Bing の Web RSS フィードは、自動リクエストに対してクエリと無関係なページ(TypeScript の質問に電車の時刻表)を返すようになり、DuckDuckGo、Mojeek、Startpage はボットチャレンジを返すようになりました。`web_search` はまず Brave Search に問い合わせ、次に Wikipedia、Hacker News、Bing News、Google News を使い、クエリに言及している結果だけを残します。そのため、ガラクタを返すソースは空とみなされ、次のソースが試されます。回答が薄い場合は Wikipedia で補われ、同じページが二重に表示されることはなく、Brave はレート制限を受けると毎回再試行するのではなく 1 分間休みます。新しい依存関係はありません。 - **古い DuckDuckGo スキルが失敗しなくなりました。** 検索エンジンの結果ページ(DuckDuckGo、Google、Bing、Yahoo、Brave、Startpage、Mojeek)に対する `fetch_url` は、チャレンジページを返す代わりに `web_search` でクエリを実行します。そのようなページをスクレイピングし `web_search` に言及していないインストール済みの `web-search` スキルは、起動時に組み込みのものに置き換えられ、元のファイルは `SKILL.md.replaced.bak` として保存されます。あなたが編集した、すでに `web_search` を使っているスキルはそのままです。 - 組み込みの `web-search` スキル(1.2.0)は、諦める前に一度言い換えて再検索し、検索ページを直接取得しないようモデルに指示します。 ### チャット - **通常のチャットが再びエージェントのように動作。** 指示がヘルパースクリプトやバッチ処理を禁止していた(「それぞれ個別に write_file を呼ぶこと」)ため、EPUB を Markdown に変換するようなタスクが 1 ファイルずつ手作業で行われていました。現在のチャットは、既存の最も強力なツール(pandoc、ffmpeg、Python ライブラリ)やスクリプト 1 本を使い、最適なツールがわからなければ手短に Web 検索し、完了と言う前に出力を確認します。また、Mercury Code と同様の短い作業規約も持つようになりました: 作業を実行し、複数ステップのタスクは計画し、何を確認したかを報告する。 - **アタッチされたターミナルで `/model` と `/cloud` が再び矢印キーのピッカーを表示。** ピッカーはフォアグラウンドのターミナルにしか接続されておらず、デフォルトの起動がアタッチ方式になってからは、`/model` は一覧を表示するだけで `/models use ` を入力させていました。現在は両方とも、あなた自身の画面(アタッチされたターミナルとダッシュボード)で同じ ↑↓ ピッカーを開き、Esc を押すと黙って最初の選択肢を取るのではなく現在のモデルが維持されます。 - **モデル切り替え時に何が起きるかを明示。** `/model` は以前「Saved for future sessions」と答えており、「次のセッションから有効」と読めてしまっていました。現在は `✓ Switched to (). In effect from your next message, and kept as the default.` と表示され、ステータス行にはすぐに新しいモデルが表示されます。 - **アタッチされたターミナルでのピッカーの回答がランタイムに届くように。** 回答エンドポイントはパーミッションプロンプトしか解決していなかったため、`/permissions`、`/model`、質問ピッカーで選択しても何も起きず、コマンドは「Thinking」スピナーの裏で 2 分のタイムアウトを待っていました。選択と Esc は即座に解決されるようになり、ピッカーが入力を待っている間はスピナーが非表示になります。 - **`/new` 後にアタッチされたターミナルが永遠に「Thinking」のままになる問題を修正。** `/new` や `/session ` の後、ランタイムは画面を新しいセッションに再バインドしていましたが、ターミナルは古いセッションを聞き続けていたため、返答はすべて誰も見ていない場所に送られ、`/stop` も無視されているように見えていました。現在はランタイムが画面に追従を指示し、メッセージが別のセッションにルーティングされたときもターミナルが追従します。 - **はい/いいえや「どれ?」の質問は文章ではなくピッカーで。** チャットは判断を求める質問を質問ツール(↑↓ と Enter)で尋ね、自由入力が必要な質問(名前、パス)には文章を使います。 ### パーミッション - **新しいセッションごとに再びパーミッションモードを尋ねるように。** 1.3.1 以降、デフォルトの `mercury` 起動はバックグラウンドのランタイムにアタッチしますが、そこでは「Ask Me / Allow All」プロンプトが表示されず、全員が黙って Ask Me になっていました。プロンプトはセッションが始まるあらゆる場所で復活しました: 起動時のフォアグラウンドターミナルと Mercury Code、新しいセッションを開始したり `/new` と入力したりしたときのアタッチされたターミナル。現在のモードが先頭に表示されるので、Enter でそのまま維持、↓ Enter で切り替えられます。選択は次回のデフォルトとして記憶され、すべての画面に適用されます。既存セッションを再開した場合は、代わりに有効なモードを示す薄い 1 行が表示されます。 - **`/permissions` はあなたがオーナーであるすべての場所で動作**します(フォアグラウンドのターミナルだけでなく、アタッチされたターミナルやダッシュボードでも)。`/permissions allow-all` と `/permissions ask-me` も含みます。 - **コマンドプロンプトでの「Always」は、そのチャットの残りの間そのコマンド全体に適用**されるようになりました(完全一致の文字列だけでなく、すべての `pandoc …`、`git commit …`)。インストール、`sudo`/`sh -c` のようなラッパー、リモートの Mercury Cloud リクエストは引き続き完全一致です。 - Telegram と Signal で Allow All から Ask Me に戻せるようになりました(以前は再起動まで切り替えが無視されていました)。 ### ボトムバー - **セッションピッカーが画面に収まり、新規セッションが先頭に。** `mercury` は以前、ターミナルの高さに関係なくローンチパッドの下に最大 6 つのセッションを表示していたため、24 行のターミナルでは Ink がワードマークを上から押し出していました。一覧は高さに合わせて配分されるようになり(まずヒントが消え、次にセッションが `… N more · /sessions in the chat` に折りたたまれます)、「Start a new session」は最後ではなく、事前選択された最初の行になりました。 - **ダンプではなく、役に立つ 1 行。** 入力欄の下の行はステータス専用です。左: セッション(`⚿ copper-mint-thd · hi`)。右: パーミッションモード、今日の予算メーター、モデル、Code モード、Optimus、アップデート。これらは優先度順にコンパクトな形式(`claude-haiku-4-5-20251001` ではなく `claude-haiku-4-5`、狭いときは `⚡12%`)でターミナル幅に収められるため、長いモデル名やセッション名が他を押し出すことはありません。収まらないものは優先度の低いものから省かれ、単語の途中で切られることはありません。 - **Optimus が行を優先。** Optimus が聞き取り中または作業中の間は、そのアクティビティが右側の最初のセグメントになり、収まらないときも最後まで残ります。左側のセッションは場所を空けるためにエイリアスまで縮みます。 - **行にはモデルのみ。** プロバイダー名はステータス行から削除されました(`Anthropic · claude-sonnet-4-5` ではなく `claude-sonnet-4-5`)。モデル名だけで誰が提供しているかはわかります。 - **予算メーターが行に復活。** `⚡ ██████░░ 76%` は今日のトークン使用量をバーで表示し、緑 → 黄(70 %)→ 赤(90 %)と変化します。これは完了フッターでずっと使われてきた色です。行が狭いときはモデルより優先されるため、非常に小さいターミナルでも `⚡76%` として表示され続けます。アタッチされたターミナルとフォアグラウンドの TUI は 1 つのビルダーを共有します。 - **バーがリアルタイムに更新。** アタッチされたターミナル(`mercury` が開くもの)は接続時に一度モデルを読み取るだけで、モデル切り替え、Code モード、パーミッション変更、Optimus のアクティビティが反映されることはありませんでした。現在、ランタイムはモデル切り替えのたびにステータス更新をプッシュし、その他の変化は 2 秒ごとに確認します。バーにはスレッド、モデル、Code モード、Ask Me / Allow All、今日のトークン使用量、Optimus のアクティビティが表示され、フォアグラウンドと Mercury Code のバーにはパーミッションモードも表示されます。 - ローンチパッドの予算行が再び機能するようになりました(ランタイムが送っていないフィールド名を読んでいました)。 - **チャット内で一度だけ表示。** ターンの実行中、入力欄の上の 1 行にスピナー、フェーズ(Thinking、実行中のツール、Writing)、経過時間が、完了したステップの ✓ マークの下に表示されます。色はシアンから、30 秒で黄、90 秒で赤に変わります。入力欄の下のステータス行がそれを繰り返すことはありません。パーミッションモードを選択しても確認の行は表示されなくなりました: 行にモードが表示されます。 - **行にキーのヒントは表示しない。** `↵ send · /help · ctrl+c detach` は削除されました。Enter で送信、`/help` でコマンド一覧が表示され、行の幅はステータスのために確保されます。右半分は切り詰められる 1 行になったため、見えない 2 行目に折り返して `Anthropic · ` で終わることはもうありません。 ## 1.4.0 — Pluggy Mercury: プラグイン、WhatsApp 通話、そして Optimus があなたのコンピューターを操作 1.3.8 以来初の安定版リリースです。dev チャネルでのみ配信された下記の 1.3.9 ホットフィックスも含んでいます。 ### プラグイン(#203) - **オプションのプラグイン。** `/plugins install|enable|disable|update|rollback|uninstall` で、mercuryagent.sh のチェックサム検証済みカタログから利用できます。プラグインはプロセス外で実行されるため、プラグインがクラッシュしても Mercury が落ちることはありません。また、プラグインはネットワークホスト、シークレット、パーミッションを事前に宣言します。 - **Plugin API 1.2。** プラグインはモデルに画像を返せる(チャット履歴には残りません)ほか、デスクトップアクセスを要求でき(`permissions.desktop`)、`whatsapp` や `desktop` チャネルを追加できます。 - **プラグインは Mercury 自身のプロバイダーを使用。** キーを一度設定すれば、プラグインはそれを借ります。オプションのキーが欠けている場合は、何が無効になるかとともに一度だけ説明されます。 - **ガイド付きセットアップと、よりフラットな `/plugins ` メニュー。** 設定はメニュー上に直接一覧表示され、はい/いいえの選択肢はそれぞれの回答で何が起きるかを示し、保存直後に続きの設定が表示されます。行き止まりはありません。 - 実行中の Mercury にプラグインをインストールすると、すぐに起動するようになりました(以前は再起動を待っていました)。 ### WhatsApp プラグイン 0.1.1(#202) - 予備の番号から、リンク済みデバイスとして WhatsApp で Mercury とチャットできます。 - **双方向の音声通話。** Mercury はあなたに電話をかけられ(「21 時に電話して」「終わったら電話して」)、作業中は進捗を伝え、承認を音声またはチャットで受け付け、通話中にリンク、写真、ドキュメントを送信します。 - 音声エンジン(デフォルトは OpenAI、ほかに Gemini、Grok、ElevenLabs、Azure、Qwen、または自分の Mercury モデル)、アクセスレベル(General / Extended)を選択でき、ダッシュボードからリンク・リンク解除ができます。 ### Optimus プラグイン 0.4.7(新規) - **Mercury があなたのコンピューターを操作。** 画面を見て、人と同じようにポインターを動かし、スクロールし、入力します。操作中は「Mercury is driving」オーバーレイが表示されます。macOS、Windows、Linux に対応し、開発者証明書は不要です。 - **話しかけられます。** トークキーで聞き取りモードを開始して音声で返答し、ミュートキーで作業を止めずに聞き取りだけを停止し、「stop」と言うとすべての操作が即座に停止します。無音が続くとセッションが終了するため、離席中に何かが記録されたり費用が発生したりすることはありません。 - **結果について正直。** Optimus は完了と報告する前に画面を確認し、失敗した操作は失敗として報告します。 - 重大な操作は事前に確認します。アンチチート(Vanguard、Easy Anti-Cheat、BattlEye)を使うゲームのプレイや自動化は、自動入力によってアカウントが BAN される可能性があるため Mercury は断ります。TUI のステータスバーには Optimus が聞き取り中か作業中かが表示され、作業中は柔らかなチクタク音が鳴ります。 - 音声設定は WhatsApp と共有されます。 ### その他の新機能 - **組み込みの `web_search`。** - **Mercury がチャットから写真や PDF を読み、ボイスメモを聞けるように。** - Mercury は自分が Cosmic Stack 製であることを常に認識しています。 - Web ダッシュボード: わかりやすいモデル名、名前の変更、推論レベルのピッカー、ローカルのすべての Ollama モデル、ChatGPT Plus/Pro プランのモデル。 ### 修正 - **デスクトップチャネルがブロードキャストをループしなくなりました。** 1 つの失敗したアラートが数百件の WhatsApp メッセージに膨れ上がることがありましたが、繰り返されるアラートは一度だけ送信されるようになりました。 - ChatGPT OAuth のターンがツール呼び出し後に失敗しなくなりました。 - 長いメッセージでメモリ検索が失敗しなくなりました(「Expression tree is too large」)。 - ダッシュボードの新規チャットが前の会話に入ってしまうことがなくなり、ダッシュボードのパーミッションプロンプトが表示・解決されるようになりました。 - プラグインの tar 呼び出しが Windows の GNU tar で動作するようになりました。 - **Windows のスタンドアロンバイナリで Web ダッシュボードが動作するように。** Mercury は Bun の macOS/Linux 用マーカー(`$bunfs`)しか認識せず Windows 用(`~BUN`)を認識していなかったため、バイナリの仮想ファイルシステム内で `web/` フォルダーを探してしまい、ダッシュボードが「web UI not found」と報告していました。#189 で @farena-ai が発見・修正しました。同じチェックはログインページとメモリグラフのフォールバックでも共有されるようになりました。 ## 1.3.9 — ホットフィックス: `mercury doctor` とダッシュボードでの保存が反映されるように - **`mercury doctor` が変更内容を適用。** プロバイダー、キー、チャネルは起動時に読み込まれるため、ファイルを書き換えるだけの再設定は、手動で `mercury restart` するまで何もしていないように見えていました。現在、doctor は設定が実際に変更された場合に実行中のデーモンを再起動します(Telegram/Discord のコマンドはすでにそうしていました)。 - **ダッシュボードでの保存時に「restart to apply」と表示され、Restart ボタンが提供されます**(Settings → Restart Mercury)。これはループバック専用の `POST /api/restart` によって実装されています。 ## 1.3.8 — ホットフィックス: アタッチ TUI でのライブ返答描画とスピナー - **ストリーミング中の返答の横にシアンのバーが出なくなりました。** アタッチ TUI(`mercury` が開くもの)は、ライブの返答をシアンの `│` ストリップ付きで描画しており、返答が確定すると消えていました。現在、ライブ部分は確定後のブロックとまったく同じように描画されます(同じ `MERCURY:` ヘッダー、インデント、Markdown)。 - **作業中/ステップのインジケーターがアニメーションするように。** アタッチ TUI では `⠋ working…` が止まったまま、`→` ステップも静止していましたが、メインの TUI と同様に共有の 100 ms ティッカーで動くようになりました。 ## 1.3.7 — ホットフィックス: 初回セットアップがモードメニューで終了してしまう問題 - **セットアップウィザードが「Choose your mode」で黙って終了していました**(1.3.1 – 1.3.6、全プラットフォーム、バイナリと npm の両方)。名前の質問に使われる共有 readline が 1 ティック遅れて自身を解放し、矢印キーメニューが stdin を引き継いだ*後に* stdin を一時停止していました。ターミナルを読むものが何もなくなったため、プロセスはやることがなくなり終了コード 0 で終了していました。現在、メニューは stdin を取得する前に readline を同期的に解放します。疑似ターミナル上で再現・検証済みです。 ## 1.3.6 — ホットフィックス: 最新版の場合 `mercury upgrade` は何もしない - **`mercury upgrade` / `mercury-dev upgrade` が最新ビルドでも再インストール(とデーモンの再起動)を行っていました。** 現在はまずチャネルの最新バージョンを確認し(stable は `/releases/latest`、dev はローリングの `mercury-dev-latest` リリースから)、デーモンやバイナリに触れることなく「Already on the latest version」で終了します。`--force` を付けると強制的に再インストールします。 ## 1.3.5 — ホットフィックス: Windows PowerShell 5.1 での Windows インストーラー - **`irm mercuryagent.sh/install.ps1 | iex` が「checksums.txt must contain exactly one checksum for mercury-win-x64.exe」で失敗していました**(標準の Windows PowerShell 5.1)。しかも読む前にウィンドウが閉じていました。GitHub は `checksums.txt` を `application/octet-stream` として配信しており、PowerShell 5.1 ではその場合 `Invoke-WebRequest` が `byte[]` を返します。インストーラーはこれをデコードするようになりました(PowerShell 7 は影響を受けていませんでした)。失敗時はウィンドウを閉じる前に Enter を待つようになりました(自動化には `MERCURY_NO_PAUSE=1`)。 - **保存したスクリプトの実行(`powershell -File install.ps1`)がパースに失敗していました**(PowerShell 5.1)。ファイルに UTF-8 文字が含まれ BOM がなかったため、ANSI コードページによって `✓` が引用符に変わっていました。インストーラーは ASCII のみになりました。 - CI は、`application/octet-stream` として配信されるローカルリリースに対して、PowerShell 5.1 で Windows インストーラーを実行します。 - **install.sh(1.3.4)が、デフォルトビルドがスモークテストでクラッシュしたとき、ベースラインビルドに切り替えずに「Illegal instruction」で終了していました**(失敗するコマンド置換に対する `set -e`)。修正しました。事前にベースラインを選択する CPU 検出のパスは影響を受けていませんでした。 ## 1.3.4 — ホットフィックス: AVX2 非対応 CPU 向けのバイナリ(#155) - **古い x86-64 での「Illegal instruction (core dumped)」。** Bun のデフォルトの x64 ビルドは AVX2 を使用しており、Haswell(2013 年)以前の Intel CPU や一部の VM では起動時にクラッシュします。リリースには **`mercury-linux-x64-baseline`** と **`mercury-win-x64-baseline.exe`** も含まれるようになりました。インストーラーは `/proc/cpuinfo` に `avx2` がない場合にベースラインビルドを選択し、インストール後のスモークテストでデフォルトビルドが不正命令で終了した場合は自動的にそちらに切り替えます。`MERCURY_ASSET=` でビルドを強制指定できます。 ## 1.3.3 — ホットフィックス: ボットは常に動作するプロバイダーを使うように - **応答できないプロバイダーでボットが失敗することはありません。** 新しいボット(Telegram、TUI、Web から作成)はデフォルトの LLM で動作します。設定されたデフォルトにキーがない場合やキーが拒否された場合(401)、Mercury は代わりに最初に使えるプロバイダーを使用します。キーを拒否したプロバイダーは記憶され、キーが変更されるまで(ボット、メインエージェントのフォールバックチェーン、デフォルトのいずれでも)スキップされます。不正なキーに当たったボットのターンは、デッドレターにせず別のプロバイダーで再試行するようになりました。 - **`mercury doctor` が明らかに正しくないキーを指摘**します(例: `sk-` ではなく `2sk-` で始まる OpenAI キー)。何かを試す前にチェックします。 ## 1.3.2 — ホットフィックス: デフォルト起動での /code、ローンチパッド、/stop - **`mercury` でローンチパッドを表示。** デフォルト起動はデーモンにアタッチしますが(ADR-024)、アタッチ画面ではローンチパッド(メインの TUI が起動時に表示するワードマーク、プロバイダー/スキル/Web/予算の行、ヒント)が抜け落ちていました。実際のランタイム状態をもとに、セッションピッカーの上に復活しました。 - **`/stop` の後のコマンド。** `/stop` は非同期で中断するため、ターンの巻き戻しが終わる前に入力したスラッシュコマンドには「Agent is busy…」と返答されていました。ランチャーは停止の完了を(最大 5 秒)待ってから、通常どおりコマンドを実行するようになりました。 - **`mercury` から `/code` が再び動作。** 1.3.1 以降、デフォルト起動はデーモンにアタッチしており、そこで入力した `/code` はデーモンの Web チャネル(切り替え先のターミナルを持たない)に転送されていたため、「Programming mode: Off」と表示されていました。現在、アタッチ TUI はターミナルを Mercury Code に引き渡します(`/code` または `/code `)。これは `mercury code` とまったく同じ動作で、ランタイムはバックグラウンドで動き続けます。アタッチ TUI 内での `/code plan|auto|off` は、どこで実行すべきかを説明します。 ## 1.3.1 — Steady Mercury Mercury があなたの邪魔をしなくなるリリースです。1 つのプロセスがフリートとチャネルを実行し、ターミナルはそこに瞬時にアタッチするだけです。ボットは実際の作業をこなし、見つけやすい場所にファイルを届け、トークンを浪費せずにオンラインを保ち、スマートフォンから操作できます。1.3.1「Honest Mercury」の内容(ちゃんと答えるチャット、検証済みを意味する「完了」、セキュリティ修正)は単独では公開されておらず、本リリースに含まれています。 ### アップグレード - **npm でのインストールには Node.js 22 以降が必要です。** スタンドアロンバイナリは独自のランタイムを内蔵しているため、何もする必要はありません。npm の場合: まず `node -v` を実行し、Node 20 なら `nvm install 22 && nvm alias default 22` の後に `npm i -g @cosmicstack/mercury-agent` を実行してください。`mercury upgrade` は何かを削除する前にこれを確認するようになり、パッケージは古い Node では起動しないものをインストールする代わりに、わかりやすいメッセージとともにインストールを拒否します。 - **ログインサービスは自動的に付け替えられます。** 新しいビルドの初回起動時に行われます(以前は古いインストールを起動し続けていました)。`mercury doctor` は *Login service: points at this install* と表示します。 - **初回起動時にボットの出力を移動します。** `~/.mercury/bots/outputs/` から `~/Documents/Mercury//` へ移動します(一方向のみ。古いフォルダーには移動先を記した README が置かれます)。 - 設定のマイグレーションはありません。`~/.mercury`(設定、ボット、メモリ、Telegram のペアリング)はそのまま引き継がれます。 ### 既知の制限 - `mercury` の起動はデーモンへのアタッチになりましたが(ADR-024)、アタッチ TUI にはまだボットスレッド(`/bots open`)や `/telegram`、`/discord`、`/slack` メニューがありません。シェルから `/bots send ` や `mercury telegram ...` を使うか、インプロセスの TUI には `mercury code` を使ってください。このギャップの解消が次のリリースの最優先事項です。 - ボットは引き続きデーモンのスレッドをメインエージェントと共有しています。制限(ターン上限、非同期ツール)はあるものの、分離はされていません。問題になったときは `/api/health.loopLag` でわかります。 ### 単一ランタイム(ADR-024) - **git ツールがランタイムを止めなくなりました。** `git_status/log/diff/add/commit/push`(および `/code diff`)は git を同期的に実行しており、遅い回線での push が Telegram、すべてのボット、アタッチ TUI を最大 60 秒フリーズさせていました。現在は非同期で実行され、エラーと出力は変わりません。 - **Windows サービスのずれ**も検出されるようになり(Task Scheduler の XML と Run キーを読み戻します)、古い自動起動設定はすべてのプラットフォームで付け替えられます。 - **ログインサービスがインストールに追従。** 再インストール(npm → バイナリ、stable → dev、nvm での新しい Node)の後、古い LaunchAgent / systemd ユニットがログインのたびに*古い*デーモンを復活させ続けていたため、新しいビルドがポートを取得できませんでした。Mercury は起動のたびにサービスが何を起動するかを確認し、付け替えるようになりました(先に古いジョブをアンロードします)。`mercury doctor` は **Login service: points at this install / STALE** を表示し、「port owned by another Mercury」メッセージは原因がサービスである場合にその名前を示します。 - **ターミナルが Mercury の 2 つ目のコピーを実行しなくなりました。** 以前はデーモンなしで `mercury` を起動すると、デーモンを起動した*うえで*ターミナル内でもフルランタイムを起動していました。Telegram、スケジューラー、すべてのボットが二重に動き、2 つ目のコピーはキー入力を描画するスレッド上で動いていました。これが入力の遅延と、Telegram の「terminated by other getUpdates」(409)競合の原因でした。現在、ターミナルはデーモンを起動してそこにアタッチします。稼働中のデーモンと並ぶフォアグラウンドのランタイム(`mercury code`、リカバリー)はメインエージェント専用のターミナルであり、ボット、チャネル、Web ポートは持ちません。 - **アタッチは起動中のデーモンを待つように**なりました(トークンがまだ書き込まれていない、バインド時にトークンがローテーションされた)。最初の読み取りで失敗することはありません。 - **イベントループのストールモニター**: `/api/health` は `loopLag`(直近 10 秒の p99 / 最悪のストール)を報告し、250 ms 以上のストールは警告としてログに記録されます。これで遅延は感覚ではなく数値になります。 ### 瞬時のアタッチ - **スラッシュコマンドで「Processing」が表示されなくなりました。** `/memory`、`/bots`、`/help` などはモデルを使わずに応答し、ターンインジケーターとハートビートは、コマンドが実際にモデルのターンにフォールスルーした場合にのみ表示されます。(`/memory` は使っている間ずっと開いたままのメニューを開きます。スピナーが出ているとエージェントがハングしたように見えていました。) - **`mercury` が稼働中のデーモンに瞬時にアタッチ。** デーモンは起動時に*まず* Web リスナーをバインドし(チャネルとボットはその後)、認証不要のループバック `/api/health` が pid/version/booting を返し、ランチャーは 750 ms ではなく 250 ms ごとにポーリングします。別のプロセス(古いグローバルインストール、別の Mercury)がポートを占有している場合は、15 秒待った末に無意味な再起動をする代わりに、1 行で報告されるようになりました — *Port 6174 is owned by another Mercury (PID …) — stop it or set web.port*。Web サーバーは使用中のポートを 5 秒間再試行するため、停止直後の再起動でダッシュボードが失われることもなくなりました。 ### ポケットの中のボット(ADR-023) - **Telegram からのオンボーディング。** Telegram(または Web チャット)での `/bots create "Name" "Description"` は、TUI と同じフローを実行するようになりました: 次のメッセージがペルソナになり(そのまま使うかテンプレートに変換するか)、続いてパーミッション階層、ソロかフリートか、日次予算を設定します。それぞれ Telegram のネイティブボタンをタップするだけで、その場で確定します。すべての返答は質問したチャットに届き、TUI 専用のボットスレッドに失われることはもうありません。 - **Telegram での操作。** `/bots` と `/bot` は Telegram のコマンドメニューにあり、ロスターはボタン付きで届きます。ボットごとに Stop/Start、Run、Runs、フリート全体には Cost、Outputs、Doctor、Stop all があります。タップすると、その裏にあるスラッシュコマンドを入力したのと同じように実行されます(同じパーミッション、同じ返答)。`/bots outputs` には配信済みファイルごとに 📎 ボタンが付きます。 - **パスではなくファイルを。** Telegram(または任意のリモートチャット)から依頼したタスクは、配信されたファイルが添付されて返ってきます。`/bots fetch [name|latest]` で必要なときに 1 つ送信できます。 - **`/bots doctor`** は任意のチャットからフリートのヘルスチェックを実行し、**`/bots help`** はコマンドを一覧表示します。TUI のスラッシュ補完、ビジーモードの `/help`、ドキュメントにすべての `/bots` サブコマンドが掲載されるようになりました。 ### ボットがオンラインを維持 - **アイドルにはなっても、死にはしない。** 何も生み出さない状態が続くルーティンは、停止されるのではなくクールダウンされます。6 時間から始まり 24 時間まで倍々に延び、その後自動的に再開します(`/bots start` で今すぐ再開できます)。予算による一時停止は深夜 0 時に解除され、キューに溜まった作業はその時点で流されます。 - **宣言された実行間隔を尊重。** `bot.yaml` のスケジュールは書かれたとおりに実行されます。30 分の下限は、ボットが自分で作成したルーティンにのみ適用されます。 - **Doctor の `stale` チェック**は、ルーティンが実行間隔の 2 倍の時間発火していないボットを指摘します。ロスターには、クールダウン中のルーティンがいつ再開するかが表示されます。 ### ボットのコストと実績を確認(ADR-022) - **`/bots cost [days]`** — ボットごと・フリートごとのトークン消費: 今日の消費と上限、期間内の実行数、失敗、配信、空の実行。`GET /api/bots-cost` もあります。 - **`/bots show [runId]`** — 実行が実際に何をしたか: ツールトレース、配信されたファイル、返答、そして返答がトレース以上のことを主張している場合のフラグ。`GET /api/bots/:id/runs[/:runId]` もあります。 - **キルスイッチ** — `/bots stop all` ですべてのボットを停止し、キューの作業を保留します。`/bots start all` で再開します。`POST /api/bots-stop-all` / `-start-all` もあります。 - **`/bots dlq clear [id]`** — デッドレターになったジョブを破棄します(実行記録はジャーナルに残ります)。`DELETE /api/bots-dlq` もあります。 - **オンボーディングの予算プリセット** — `light`(1M/日)、`standard`(デフォルト、5M)、`heavy`(20M)、数値、または `none`。このステップでは、ボットの成果物がどこに表示されるかも案内されます。 - `GET /api/bots/:id/tasks` はリードが委任したタスクを一覧表示します。 ### 連携するフリート(ADR-021) ボット機能の第 2 弾です: リードがどのように作業を割り振って回収するか、ボットがどのように記憶するか、そしてフリートの定型業務がステップごとにリードのターンを挟まずにどう実行されるか。 - **ファンイン付きの型付きタスク。** `fleet_delegate` は 1 回の呼び出しで複数のタスクをクルーに渡します。それぞれに目標と「完了」の定義があり、バッチが完了するか期限(デフォルト 120 分)を過ぎると、リードは**一度だけ**ダイジェスト(タスクごとのステータス、結果、配信ファイル、要約)とともに起こされます(遅れたものはそれぞれ一度ずつ報告されます)。`bot_send(task: true)` は 1 件だけのバッチになりました。`fleet_tasks` で一覧表示とキャンセル、`fleet_status` で未完了のタスクを確認できます。タスクは永続化され(`tasks.json`)、重複排除されるため、委任のターンが再実行されても二重に割り振られることはありません。 - **データとしてのパイプライン。** リードの定型業務を `bot.yaml` に記述します(`pipeline.stages`: name、bot、`{{input}}` / `{{previous}}` を使った goal、任意の `final`)。`fleet_pipeline` がそれを実行します: ステージは自動的に連鎖し、それぞれが成果物を次に渡し、間にリードのターンは挟みません。リードは最後に起こされ、`final` ステージの成果物はフリートフォルダーの最上位に昇格されます。 - **ボットが記憶する。** 実りのある実行の後、0〜3 個の永続的な事実(情報源とその質、決定事項、物の場所、避けるべきこと)がボット自身のメモリに抽出されます(`memory.learn: false` で無効化)。また、各ターンはジャーナルにある直近 5 回の実行のダイジェストと、ボット自身の作業状態メモ(`bot_state`、1500 文字以内、追記ではなく置換)から始まります。これは、以前ボットが書いていたステータスファイルの正式版です。 - **より安価なクルー。** `bots.fleets.crewProvider` は、独自のプロバイダーを持たないクルーボットをより安価なレーンに振り分けます。リードはデフォルトのままです。 - `/bots tasks ` は TUI からリードの未完了および最近のタスクを表示します。 ### 実際に働くボット(ADR-020) 実際のフリートの 11 日分を監査したところ、ボットは 6 億 1700 万の入力トークンを消費し(ターンの中央値は 75 万、最大は 660 万)、実行の 38% が失敗し、ほとんどは以前の実行についてのメモを書いているだけでした。今回の改善では、すべてのボットのターンにガバナーを、すべてのルーティンにゲートを、すべての実行に結果の判定を、そしてすべてのオーナーに見つけやすいフォルダーを用意しました。 - **ターンごとの上限。** ターンは 30 万トークンまたは 20 分で停止します(`autonomy.maxTokensPerTurn` / `maxTurnMinutes`)。打ち切りは `turn_budget` / `turn_time` としてジャーナルに記録されます。終了扱いで、デッドレターにも「needs you」にもならず、通知は 1 日 1 回です。 - **コンテキストの圧縮。** 直近 8 件より古いツール結果は各ステップでスタブ化され、個々の結果は 24KB が上限です。プロンプトがステップ数に応じて膨らむことはなくなりました。 - **予算がデフォルトで有効。** すべてのボットに日次上限があり(`/bots budget` で別途指定しない限り 500 万トークン。`none` で無制限)、フリートにも上限があります(`bots.fleetDailyTokenBudget`、2000 万)。80% で警告されます。 - **ルーティンのゲート。** ボットがビジーな間、または前回の実行から 30 分以内(`schedules[].minIntervalMinutes`)は、cron のティックはスキップされます(積み重なることはありません)。ボットが作成したルーティンは最短 30 分間隔、ボットあたり最大 3 個までで、自分でスケジュールしたフォローアップは少なくとも 10 分後になります。 - **結果の判定。** 実行が何をしたかは返答ではなくツールトレースで判定されます: `deliverable`、`action`、`delegated`、`message`、`none`。メモを書いただけの無人実行には、成果物を届けるかそれを認めるよう一度だけ促します。対応するツール呼び出しなしに配信を主張する返答はフラグが立てられます。空の実行が 3 回続くとルーティンは一時停止され、`/bots start` で再開します。 - **共有フォルダーの予算。** `_shared/` への書き込みは実行ごとに制限されます(2 ファイル / 32KB で警告、6 / 128KB で拒否)。プライベートなワークスペースは無制限です。 - **見つけやすい成果物。** 成果物は `~/Documents/Mercury//` に置かれます(Windows: Documents、Termux: 共有ストレージ、`bots.deliverablesDir` で上書き可能)。最終成果物が最上位に、クルーの作業は `work/` 以下に置かれ、README のインデックスがあり、ファイル名は `YYYY-MM-DD ` です。オンボーディング時、ロスター、そしてすべての「配信済み」メッセージに表示されます。`/bots outputs [id]` で一覧表示し、`/bots folder <id>` でフォルダーを開きます。隠しの `outputs/` 領域は一度だけ移行されます。 - **正直な失敗。** ネットワークの切断("terminated"、ソケットのクローズ、ストリームの中断)や空のストリームは、デッドレターにせず再試行します。プロバイダーの実際のエラー(無効なキー、429)が「No output generated」の代わりにジャーナルに記録されます。 - **ジャーナル v2。** 実行ごとの実際のターン開始、ステップ、ツール呼び出し、最大プロンプトサイズ、結果、配信パスに加え、実行ごとのコンパクトなトランスクリプト(直近 50 件を保持)。`/bots journal` で表示され、`mercury bots doctor` は無人実行がほとんど何も生み出さないボット、一時停止中のルーティン、ホームディレクトリ全体への書き込みアクセスを指摘します。 - ボットのファイルツールとシェルコマンドは、相対パスをデーモンの作業ディレクトリではなく、常にボットのワークスペース内で解決するようになりました。ロスターのスキャンは `sandbox/` と `outputs/` 内のプロファイルのコピーを無視します。 ### Ink 8 Mercury のターミナルレンダラーは、大量のパッチを当てた ink 5.2.1 から ink 8.0.0 に移行しました。ink 8.0.0 はその作業のほとんどを自前で行うようになっています。 - **Node.js 22 以降が必要です。** Ink 7 以降が必要とし、Node 20 は 2026 年 4 月にサポート終了を迎えました。古い Node では、最初の描画でクラッシュする代わりに、わかりやすいアップグレードメッセージとともに終了するようになりました。 - **よりスムーズな描画** — インクリメンタル描画により各行の変更部分だけが書き換えられ、すべてのフレームがアトミックに描画されます(synchronized output)。 - **Mercury に欠けていたアップストリームの修正** — CJK と絵文字の切り詰め、描画テキストからの制御文字の除去、複数のキーが同時に届いたときのキー入力の取りこぼし、Backspace と Delete の区別、Windows での古いフレームの残留、そして多数の `<Static>` の修正。 - **より小さなパッチ** — Mercury 独自の hunk は 4 つだけ残り(Static の `itemKey`、フリーズゲート、ライブ領域のガード、カーソルアンカー)、残りはアップストリームのものです。`docs/ink-patch.md` と ADR-019 を参照してください。 - React 19.3。 ### Honest Mercury — 以前の 1.3.1 の作業(単独では未公開) Mercury が取り繕うのをやめるリリースです。チャットはツールラウンドを強制せずに答え、「完了」はチェックが実際に通ったことを意味し、すべてのチャネルで同じ根拠が表示され、ターミナル UI は本物のエディターのように貼り付け、Esc、IME を扱います。全面的な監査(`ROADMAP.md`)に基づいており、以下のすべての変更は、実際のエージェントループを駆動するリプレイ評価ハーネスを含むテストでカバーされています。 #### 会話とフィードバック - **チャットがツールラウンドを強制されなくなりました** — Mercury Code のナレーションガードと検証ゲートが通常のチャットでも動いていたため、「筋トレメニューを作って」でツールのみのラウンドが最大 10 回発生し、「I couldn't get started」で終わることがありました。どちらも実行モードでのみ動作するようになりました。 - **完了は検証済みを意味する** — ビルド/テスト/型チェックは、正常終了し(タイムアウトや kill は失敗扱い)、かつ最後の編集の後に実行された場合にのみ根拠として扱われます。そうでなければ、タスクは「Task complete」ではなく「the last check didn't pass」で一時停止します。ストリーミングのターンもこのゲートに到達するようになりました(以前は終了理由を報告せず、ゲートをスキップしていました)。 - **すべてのチャネルで統一されたフィードバック規約**(`TaskSurface`)— 開始、根拠付きの完了、一時停止、失敗が、CLI、Web、Telegram、Discord、Slack、Signal で同じように振る舞います。検証メモとトレース ID がメッセージングチャネルに届き、一時停止と失敗のバナーは切り詰められるステータスカードの通知ではなく、残り続けるメッセージになります。 - **`/trace [id]`** — ターンのプロバイダー、トークン(キャッシュ分を含む)、ステップ、タイミング、検証、すべてのツール呼び出し。 - すべてのチャネルで **`/new`** — メモリは保持したまま新しい会話を開始します(#38)。 - **Telegram のプロンプト** — タイムアウト時に何がデフォルトで選ばれたかを示し、タップでカードが確定し、キーボードが削除されます(#23)。 #### コンテキスト、メモリ、速度 - **コンテキストウィンドウ v2** — 履歴はトークン単位で配分され、ターンごとのコンパクトなツールトレースを含むため、次のターンは何が読み書きされたかを把握できます。取得したメモリは偽の対話ではなく、ターンごとのシステムブロックに入ります。 - **プロンプトキャッシュ** — 安定したシステムプロンプトに Anthropic のキャッシュマーカーが付き、毎分変わることはなくなりました。 - **より速いステップ** — ステップごとのチャネル編集がエージェントループをブロックしなくなり、ニッチなツールスキーマ(Spotify)は無関係なターンから除外され、ローカルの想起が強い場合はクラウドのメモリプールをスキップします。 - **プロバイダー** — V4/reasoner モデル向けの DeepSeek thinking と、推論内容の受け渡し(#24)。プロバイダーごとの出力上限。設定されたデフォルトが常に先頭になります(フォールバックが固定されなくなりました)。 - **長いビルド** — `run_command` が進捗を報告するため、10 分のビルドが停止したプロバイダーとして kill されることはなく、ターンが中断されたときは子プロセスを停止します。 - **ツール結果** — AI SDK v6 の `output` フィールドから読み取るようになり、失敗ループの検出が機能するようになりました。 #### ターミナル UI - **貼り付け** — 複数行およびブラケットペースト。Shift+Enter で改行を挿入します。 - **Esc でターンを中断、Ctrl+C で入力をクリア**、2 回押すと終了します。 - **同時のプロンプトはキューに入り**、互いに上書きすることはありません。 - **よりスムーズなストリーミング** — コードフェンスに合わせた末尾の描画、共有の 1 つのティック、非同期の git ヘッダー、リサイズ時の正しい再描画、絵文字と CJK に対応した書記素単位のカーソル。履歴は `~/.mercury/history` に永続化されます。 #### プラットフォーム - **Windows** — Task Scheduler の XML によるサービスインストールと HKCU Run へのフォールバック(#13)。正常な停止とアップグレード。stdin が閉じていてもウィザードが黙って終了しなくなりました(#64)。アップデートの確認は HTTPS 経由。 - **Termux** — `android` で検出されます。`mercury service install` は Termux:Boot スクリプトを書き出します。 - **ボット** — 再試行されたジョブが二重に実行されることはなくなりました。フリートリードのまとめがそのスレッドに届くようになり、「needs you」は再起動後も保持されます。 #### エンジニアリング - **エージェントの分割** — コマンドハンドラーを `src/core/commands/` に移動。4 つのコピーを 1 つのステップハンドラーに統合。`agent.ts` は 8,362 行から約 5,000 行に。 - **リプレイ評価ハーネス**(`npm run eval`)を CI に導入。 - **CI** — OS ごとのバイナリのスモークテスト(ビルド、実行、破棄。公開はしません)、インストーラーとスクリプトのチェック、Node 24、linux-arm64、ESLint のラチェット(暫定ベースライン)、vendored Ink の整合性チェック。 #### セキュリティ - **argv レーンによる自動承認**(ADR-016)— 自動承認されるコマンドはシェルや `PATH` を経由しなくなりました: 単純な argv にトークン化でき、許可リストにあるプログラムを許可されたフラグの組み合わせで使用し、ワークスペース内にとどまり、固定されたシステムディレクトリから解決したバイナリに対して最小限の環境で `execFile` 経由で実行される必要があります(#103)。それ以外はすべてユーザーに承認を求めます。一部の読み取り専用のワンライナー(パイプライン、`&&` チェーン)でもプロンプトが出るようになりました。`SECURITY.md` を参照してください。 - **読み取りは実際のファイルに対して認可** — シンボリックリンクのターゲットはスコープ内である必要があり、ハードリンクされたファイルではプロンプトが出ます。また `read_file` は、開いたファイルがチェックしたファイルと同一であることを検証します(#104)。 - **git ヘルパーはシェル文字列ではなく argv で実行** — `git_status`、`git_log`、`git_diff` は、モデルが選んだ `path` からコマンド文字列を組み立て、パーミッションチェックなしで `execSync` で実行していました。現在は `--`(または `-C <resolved>`)の後の単一の argv 要素としてパスを `execFileSync('git', [...])` に渡し、`read_file` と同じ読み取りスコープのチェックに失敗するパスは拒否します。`git_push` はオプションのように見える `remote`/`branch` の値(`--receive-pack=…`、`--exec=…`)を拒否し、argv も使用します。回帰テスト: `src/capabilities/git/git-helpers.test.ts`。 - **安全な読み取りのバイパス修正(回帰テストにより対処完了)** — Ask Me モードの読み取り専用自動承認レーンは次を拒否します: `find` のアクションフラグ(`-exec`/`-execdir`/`-ok`/`-okdir`/`-delete` は 1.2.2 から、`-fprint`/`-fprintf`/`-files0-from` は 1.3.0 から — #71、#77、#101、#110)、シェルのリダイレクト(`>`、`>>`、`2>`、`<`、`&>`、1.2.2 から — #72、#82、#109)、シェルの展開(`$VAR`、`${VAR}`、`$(…)`、バッククォート、`$'…'`、`~`、1.3.0 / PR #128 から — #76、#80、#95)。`src/capabilities/permissions.test.ts` に明示的な `find -exec` のケースを追加しました。 - **サブエージェントの承認ルーティング** — `delegate_task` のワーカーが、共有のパーミッションマネージャーを `/` 書き込みスコープ付きの allow-all に切り替えることはなくなりました。シェルとファイルシステムの呼び出しは親と同じ Ask Me プロンプトを経由します(1.2.2 から — #75、#99)。`allowedTools` はプロンプト内だけでなく実行時に強制されます(1.3.0 から — #74、#97、#98)。1.3.1 では、サブエージェントは自分の子孫だけを参照・停止でき、オーケストレーションツールは付与された場合にのみ使えます(#74)。また各エージェントは独自の不変なパーミッションコンテキストで実行されるため、同時に走る内部チャネルのターンがワーカーの承認範囲を広げることはなくなりました(#75/#99 の残件)。 - **シンボリックリンクへの書き込みの正規化** — `create_file`/`write_file`/`edit_file` は、字句上のパスだけでなく、シンボリックリンクの解決後のターゲットを書き込み可能スコープと照合します(1.3.0 から — #105)。 - **SSRF ガード** — 変更なし。下記の 1.2.3 の項目を参照してください(1.3.0 で #121 と #124 により強化。対応記録は `docs/security/ssrf-108-response.md`)。 - **脆弱性開示プロセス** — `SECURITY.md` を追加しました(非公開での報告、対応目標、対象範囲)。Issue のクローズとアドバイザリーのドラフトは `docs/security/2026-10-backlog-closure.md` にあります。 #### 修正 - **スタンドアロンバイナリとツールチェーンのない環境での SQLite**(ROADMAP P1.9、#96、ADR-018)— バイナリは better-sqlite3 の JavaScript は同梱していたもののネイティブアドオンは同梱しておらず、バイナリ内ではすべての SQLite のプローブが失敗していました: Second Brain は黙って無効化され、ボット/ボードは JSON にフォールバックしていました。共有ドライバー(`src/utils/sqlite-driver.ts`)が **better-sqlite3 → bun:sqlite → node:sqlite → JSON** の順に選択するようになりました: バイナリは Bun の組み込みエンジンを使い、Node 22.13 以上の環境では `node:sqlite` によりコンパイラーなしで動作し、better-sqlite3 のパスはそのままです。Second Brain、ボットのキュー、ボード、クラウドのプール検索キャッシュはすべてこれを経由します。プールキャッシュは、エンジンが読み込めない場合に例外を投げるのではなくキャッシュなしに縮退します。新しい `mercury doctor --storage` は、アクティブなバックエンド(他が却下された理由付き)、すべてのデータベースファイル、そのサイズと行数を表示し、ストレージが JSON のみの場合は強く警告します。`MERCURY_SQLITE_BACKEND=better-sqlite3|bun:sqlite|node:sqlite|json` でバックエンドを強制指定できます。コントラクトテストは、プロセスが読み込めるすべてのエンジンに対して同じアサーションを実行します(`src/utils/sqlite-driver.test.ts`)。 - **パッチ済み ink は postinstall ではなく同梱に**(ROADMAP P2.4、ADR-017)— TUI の ink 修正は `postinstall` に依存しなくなりました: `vendor/ink`(標準の ink 5.2.1 + パッチセット、`scripts/vendor-ink.cjs` で再生成)が `dist` に同梱されるため、`--ignore-scripts` でのインストール、Termux、スタンドアロンバイナリのすべてでパッチ済みのレンダラーが動作します。`mercury doctor` は「Ink TUI patch: vendored」と報告します。hunk ごとの根拠: `docs/ink-patch.md`。 - **IME の入力が入力行に表示されるように**(#41、#66)— 実際のターミナルカーソルが毎フレーム後に入力欄のカーソル位置に置かれるようになったため、変換中のテキストと候補ウィンドウが入力している場所に表示され、カーソルが非表示の間 IME を抑制するターミナルでも再び変換できるようになりました。プロンプトや入力以外のペインにフォーカスがある間は非表示になります。`MERCURY_HW_CURSOR=0` で無効化できます。 - **狭いターミナル**(P2.8)— 幅はターミナルの列数から算出されます: 60 列未満ではスプラッシュとサイドパネルが折りたたまれ、入力ヘッダー、ヒント、Mercury Code のヒント表は、折り返してライブ領域の行を増やす代わりに切り詰められます。 ## 1.3.0 — Mercury Bots **会話の外で**動作する、永続的でペルソナ単位のエージェントです。それぞれが独自のペルソナ、ワークスペース、スキル、パーミッション、永続キューを持ちます。専門家をオンボーディングし、多階層のフリートとして連結し、あなたが Mercury と話し続けている間も 24 時間 365 日働かせられます。 ### 新機能 - **永続的なボットランタイム(P0)** — ボットは、永続的なペルソナ(`bot.yaml` + `permissions.yaml`)、`~/.mercury/bots/<id>/` にある専用のプライベートサンドボックス、再起動後も残るジャーナルを持つ長寿命のエージェントです。ウェイクで起動し、永続ジョブキューを通じて作業し、結果は**ボット自身のスレッドに**届きます。作業を依頼したセッションに結果が流し込まれることはありません。 - **永続キュー + HTTP API(P1)** — ジョブは再起動後も残り、ワーカーが死ぬとリースが期限切れになります(`timed out` 分類、`/bots replay` による非破壊的な DLQ の再実行)。フリートのヘルスはコマンド 1 つで確認できます: `mercury bots doctor`(終了コード 1 = 対応が必要)、`mercury bots list`、`mercury bots storage`。Telegram の `/pair` 形式の入口: すでに使っているチャネルからすべてのボットにアクセスできます。 - **フリート — リードボット + クルー** — ボットを**フリートリード**に昇格させると、自らクルーを募集・編成します(命令型の自己組織化)。多階層の階層構造に対応しています。クルーの結果はリードを通じて上に伝わります。フリートのオンボーディングは階層を順に進みます: **ソロ → リード自動構築 → リード手動**。 - **Web コックピット — Mercury Bots セクション** — ローカルの Web ダッシュボードにフリートのセクションが加わりました: ライブ状態付きのロスター、ボットごとのスレッド、needs-you のエスカレーションバッジ、TUI と同じフリートのステップビュー。 - **ペルソナシステム** — 2 パスのペルソナビルダーで、大きなペルソナは大きなまま保たれます。手で編集した `bot.yaml`/`permissions.yaml` はライブで適用されます。ペルソナファイルはアクセススコープ(ディレクトリごとの読み取り/書き込み/実行)を宣言するため、各ボットは必要な範囲だけを正確に得られます。それ以上はありません。 - **サンドボックス + `bot_deliver`** — すべてのボットに分離されたワークスペースが与えられ、最終成果物は `bot_deliver` を通じて出力されます。サンドボックスの保持管理ジャニターがボットごとのディスク使用量を制限します。`~/.mercury/bots/_shared` にあるフリート共有フォルダーで、暗黙の権限付与によりボット間でファイルをやり取りできます。 - **バンドル** — `/bots export` は共有可能なバンドル(マニフェスト + ペルソナ + パーミッション + スキル。リードのバンドルはクルー全体を含み、フリート全体のエクスポートにも対応)を作成します。`/bots import` でそれらを再作成します。インポートされたボットは設計上、無効の状態で開始します。サンドボックス、ジャーナル、`.env` は持ち出されません。 - **ボット向けツール** — `dispatch_bot`、`bot_schedule`(ボットが自分の将来の実行をスケジュール)、`bot_deliver`(成果物の確定)、`fleet_status`、`journal_append`。ボットのスキルアクセス: ネイティブのスキルライブラリ + 自動合成付きのボットごとのスキルライブラリ。 - **ライフサイクル + 可観測性** — 作成/編集/予算/削除の完全なライフサイクル、保留キューのセマンティクスを持つ stop/start/run(stop は保留するだけで kill はしない)、アクティブなチャネルへの needs-you アラート、開いたときにボットごとのスレッドを復元するジャーナルのハイドレーション、ロスターとコックピットに流れるライブアクティビティバス、ボットごとのトークン予算、mtime でキャッシュされたマニフェスト、末尾読み込みのジャーナル、ディスク使用量を確認する `mercury bots storage`。 - **オンボーディング時のパーミッション階層** — ボットには機能ごとに `ask` / `allow` の階層が明示的に設定されます。黙ってデフォルトになるものはありません。ボットごとのシェル許可リストは `permissions.yaml` の `autoApproveCommands` から取得されます。不正なスコープのエントリはスキップされて警告が出るだけで、ターンがクラッシュすることはありません。 ### 修正 - 再オープン時のフリートの重複を修正。`/bots` は開いたボットスレッド内にとどまります。 - ボットの思考がライブでスレッドにストリーミングされるように。フリートの速度改善(単一プロバイダーのリース待ち、ロスター取得のバッチ化)。 - Web のフリートステップが TUI のステップビュー(ソロ / 自動構築 / 手動の階層)と完全に一致するように。 - ボットスレッドで結果が 800 文字で切られなくなりました。永続的な再試行と永続的なメールボックスにより、配信規約の抜けを解消しました。 - Windows の堅牢化: SQLite バックエンドでのキュー破棄時の EBUSY、ハートビートテストのバックエンドでの EBUSY、保持期間の日付操作での EINVAL、区切り文字に依存しないトラバーサルガード。クローズ後のキュー操作はクラッシュではなく何もしない処理に縮退します。 - JSON バックエンドのリース期限切れの競合を解消。破棄時に SQLite のキューハンドルを解放。doctor は自分のキューをクローズします。 - Telegram のメンバーによるインストールで `install_skill` をブロック — このツールは安全な場所でのみ表示されます。 - `mercury bots doctor` のスケジューラー連携: スケジュールに登録されているが `bot.yaml` にないルーティンを、黙って発火しないままになる前に指摘します。 ### 内部 - 新しい `src/bots/` モジュール: `store.ts`、`queue.ts`(SQLite + JSON バックエンド)、`bot-manager.ts`、`bot-turn.ts`、`journal.ts`、`bundle.ts`、`doctor.ts`、`persona-template.ts`、`fleet-*`、`skill-synthesis.ts`、`retention.ts`、`tools/`(`dispatch-bot`、`bot_schedule`、`bot_deliver`、`fleet_status`、`journal_append`)。 - `mercury bots` — チャット内の `/bots` に対応する新しい CLI コマンドグループ(`doctor` / `list` / `storage`)。 - PR #131–#139 と PR #117 の RevShare 統合がこのリリースを構成しています。 ### 1.2.7 からの移行 破壊的変更はありません。ボットは**オプトイン**です — `/bots create <id> "Name" "Description"` で最初のボットをオンボーディングしてください。フリートを持つとすぐに doctor とフリートの機能が表示されます。既存の設定、メモリ、チャネルには影響しません。 ## 1.2.7 — Polished Mercury Mercury Code の UX を磨き上げました: オートコンプリートにすべてのコマンド、正直な完了統計、そして追加のモデル呼び出しなしに何が起きているかを表すステータス動詞。 ### 新機能 - **50/50 RevShare 統合: Mercury & AIML API**(#117)— レベニューシェアプログラムの統合。 - **動的なステータス動詞**(#119)— セッションごとに 1 回の LLM 呼び出しでライブのステータス動詞(「Compiling」「Sweeping」)を生成します。チャットは静的なままです。 - **「Did you know?」ヒント**(#120)— まだ使っていない機能について、画面ごとに分類された、まれに表示されるシステムの声のヒント。 ### 修正 - ステップのナレーションがライブ部分で別々のブロックとして描画されるように。`│` の罫線は確定したメッセージに残り、ライブ部分でのみ外れます。 - スラッシュのオートコンプリートと `/help` が、すべての画面で最近のコマンドをすべてカバーするように。 - 完了バナーのファイル変更統計が状況に応じて賢く表示されるように(文章のみのターンではノイズを出しません)。 - 実際にはインストールされていないマシンでも CLI のアンインストール検出が動作するように。 ## 1.2.6 — コマンド周りの修正 1.2.5 へのホットフィックス: スラッシュのオートコンプリートと `/help` が、すべての画面で最近のコマンドをすべて一覧表示するようになりました。ライブ部分はステップのナレーションを別々のブロックとして描画し、`│` 罫線の挙動も修正されました。 ## 1.2.5 — 復元と再公開 リカバリーリリース: 不正なマージ(40f5aea)で失われた Release/1.23 の作業を復元し、マージコンフリクトのマーカーなしで Pages の出力を再ビルドし、1.2.4 系をクリーンに再公開しました。 ## 1.2.4 — ランディングページとカード Web サイト/ブランディングのリリース: セクションとパンくずリスト付きの、より充実したページごとの OG ソーシャルカード生成、ランディングページの絵文字をインライン SVG アイコンに置き換え、そして v1.2.3 リリースページの修正がビルド済みドキュメントバンドルに含まれました。 ## 1.2.3 — Unstoppable Mercury **Mercury Code が落ちなくなり、真実を語り始める**リリースです。完了パイプラインは完了規約を軸に再構築されました: すべてのタスクは判定で終わります — 検証済みの完了か、ブロッカーを明示して再開できる正直な一時停止のどちらかです。タスクが成功を偽ったり、黙って落ちたり、永遠にループしたりすることはもうありません。 ### 新機能 - **完了規約** — すべてのタスクの終了が分類されます(`completion-verdict.ts`): 予算の枯渇は*一時停止*であり、偽の「Task complete」には決してなりません。根拠に基づく完了: 実装タスクは完了を主張する前にビルド/テスト/型チェックを実行する必要があります。正直なバナー: git に何も変更がなければ「Response delivered · no file changes」、再開可能なら「Task paused · send continue」。 - **AUTO モード** — Mercury Code の新しいデフォルト: 計画とビルドを 1 つの流れで行い、大きな変更の場合のみ `ask_user` で一度確認します。計画/実行を手動で切り替える必要はもうありません。 - **ライブの計画チェックリスト** — `update_plan` ツールが Mercury Code に見えるチェックリスト(pending / ▶ active / ☑ done)を維持するので、どのステップが実装中かが常にわかります。 - **ナレーションに固執するモデル向けのエスカレーションハーネス** — エージェントが機械的に行動を強制します: ハーネスによるグラウンディング(決定的なディレクトリ一覧)、変更系ツールのみのステップでのプロバイダー側の `toolChoice: 'required'` 強制、ガードラウンドごとのプロバイダーのローテーション、そして一時停止の前のウェイクアップコール(上限を倍にし、率直な指示を出す)。 - **圧迫時の圧縮** — OpenCode の手法を採用: メモリの圧迫時は会話をその場で圧縮して続行し、圧迫が続く場合にのみ中断します。 - **Mercury による出力サイズ制限なし** — モデル本来の制限に従います(上限 32,768)。それを拒否するプロバイダーには適応的に半減させます。大きな単一ファイルの書き込みも 1 回の呼び出しで完了します。 - **書き込みの切り詰めからの回復** — 途切れたファイル書き込みには分割書き込みのガイダンス(まず最初の約 80 行を作成し、その後 `edit_file` で追記)が与えられ、予算を全量使える再開ラウンドが行われます。 - **ストールウォッチドッグ** — 3 分間無音 → 目に見えるパルス、8 分 → 中断して再開の仕組みへ。`MERCURY_STALL_SOFT_MS` / `MERCURY_STALL_HARD_MS`。 - **自動継続** — ステップ予算の枯渇やプロバイダーの失敗は自動的に継続されます(新しい予算を 6 回まで、プロバイダーのハードデッドラインは 1 回の試行として数えます)。手動の「continue」ゲートは安全網であり、チェックポイントではありません。 - **Mercury Code でのインタラクティブな選択ピッカー** — `ask_user` のプロンプトがフルスクリーン TUI で描画されるようになり(以前は見えずにハングしていました)、キーボードを占有します。Esc で安全にキャンセルできます。 - **ライブの思考プレビュー** — モデルの推論が、52 秒間の無音の代わりに TUI で引用形式のプレビューとしてストリーミングされます。 - **Mercury Code でのトラックパッド/ホイールスクロール** — フィルタリングされた stdin プロキシにより、フルスクリーンのトランスクリプトをホイールでスクロールできます(マウスのシーケンスが入力に漏れることはありません)。 - **完了時の変更サマリー** — 完了バナーにファイルごとの +/− 統計と検証の根拠(「✓ Verified: npm test ✓」)。 - **ファイル変更のプレビュー** — 作成/編集されたすべてのファイルについて、範囲を限定したシンタックスハイライト付きの抜粋をトランスクリプトに表示。 - **`/code chat`** — Mercury Code から通常のチャットに即座に戻ります。`/chat` の後始末を修正。 ### セキュリティ - **SSRF ガード** — `fetch_url` と `install_skill` は、すべてのリダイレクトのホップでスキームとプライベートアドレス範囲(DNS 解決後)を検証します。512 KB の上限。`MERCURY_ALLOW_PRIVATE_FETCH=1` で無効化。 - **認証情報ファイルの堅牢化** — `web-config.json` / `web-sessions.json` は 0600 で書き込まれ、読み込み時に修復されます。 - **ランダムな初期 Web パスワード** — 公開リポジトリにハードコードされたデフォルトはもうありません。 - **シークレットの秘匿化** — API キーはログ(pino のエラーシリアライザー)とコマンド出力のエコーでマスクされます。 - **シェルのブロックリスト** — フラグの順序を入れ替えた `rm -fr` の変種を、決して実行しない階層に追加しました。 ### 修正 - Yoga WASM の「memory access out of bounds」クラッシュ(ink にパッチ: 解放済みノードの衛生管理 + `<Static>` の同一性による重複排除)と、メッセージが重複する描画ループ。 - 長いセッションのトリム後のスクロールの修復(`/mc scroll-set` は NaN のデルタとしてパースされるデッドコードでした)。 - 文章による質問がガードと衝突しなくなりました。AUTO モードのバナー表示条件。`not-a-git-repo` の場合の誤った「no file changes」の主張。 - Mercury Cloud のリカバリーエラーが、不透明な 401 のループではなく「run `mercury cloud connect`」と表示するように。 - チャットモードの思考インジケーターが、ライブのプロバイダー/フェーズのアクティビティを表示するように。 ## 1.1.13 — Chatty Mercury Mercury がおしゃべりになります。Discord、Slack、Signal の 3 つの新しいチャネルで、エンドツーエンド暗号化、組織向けのアクセスモデル、リアルタイムストリーミングとともに、あなたがすでにいる場所に Mercury を届けます。さらに、長時間実行ループの修正、CLI のハートビートの改善、クラッシュからの回復も含まれます。 ### 新機能 - **Discord チャネル** — スラッシュコマンド、ストリーミング応答、リッチな埋め込み、管理者ロールとペアリングコードによる組織アクセス、DM とチャンネルのサポート、レート制限を備えた完全なボット統合。設定: `DISCORD_ENABLED`、`DISCORD_BOT_TOKEN`、`DISCORD_GUILD_ID`、`DISCORD_CHANNEL_ID`、`DISCORD_ADMIN_ROLE_NAME`、`DISCORD_STREAMING`。 - **Slack チャネル** — Socket Mode のボット(公開エンドポイント不要)。スラッシュコマンド、ストリーミング編集、管理者/メンバーロールによる組織アクセス、チャンネルと DM のサポート、@メンションの認識。設定: `SLACK_ENABLED`、`SLACK_BOT_TOKEN`、`SLACK_APP_TOKEN`、`SLACK_CHANNEL_ID`、`SLACK_TEAM_ID`、`SLACK_STREAMING`。 - **Signal チャネル** — `signal-cli` ブリッジによるエンドツーエンド暗号化。グループモード(「Mercury」という名前のグループ)とプライベート DM モード。`signal-cli` バイナリを自動管理(ダウンロード、登録、起動、ヘルスチェック)。ペアリングコードによるアクセス制御。CLI 出力での電話番号の秘匿化。Linux(x64/ARM64)ではネイティブバイナリを利用可能、macOS では Java 17 以降が必要、Windows は非対応。設定: `SIGNAL_ENABLED`、`SIGNAL_PHONE_NUMBER`、`SIGNAL_MODE`、`SIGNAL_GROUP_ID`、`SIGNAL_GROUP_NAME`。 - **クラッシュからの回復** — 新しいクラッシュフラグの仕組み(`~/.mercury/.crash-flag`)が、異常終了時に JSON ファイルを書き込みます。次回起動時に Mercury はフラグを読み、何が起きたかを報告してから削除します。ウォッチドッグも再起動の上限を超えたときにクラッシュフラグを書き込み、最後の記録として stderr に同期的に書き込みます。 ### 修正 - **CLI のハートビートがその場で更新されるように** — 長時間実行されるタスクの間、CLI は新しい「⏳ Working...」メッセージを積み重ねるのではなく、同じメッセージを更新するようになりました。他のチャネル(Telegram、Discord、Slack、Signal)は引き続き個別のハートビートメッセージを送信します。 - **タスクが黙って失敗する 12 の経路をすべて解消** — すべてのループ条件、ツールの制限、ストールが、チャネルに明示的なエラーメッセージを送信するようになりました。タスクの途中で黙って消えることはもうありません。 - **ステップログの折りたたみ** — アクティブなステップログに表示されるステップは最大 3 つ(実行中 + 直近の完了 2 つ)です。全履歴は Ctrl+D または `/log` で確認できます。アイドル時はコンパクトな要約行を表示します。 - **ThinkingIndicator が「Processing」を表示** — エージェント名を中立的なラベルに置き換えました。長い処理では `/bg current` のヒントを表示します。 - **Ollama Local を OpenAI 互換経由でルーティング** — `ollamaLocal` は `useChatApi: true` 付きの `OpenAICompatProvider` を使うようになり、`ollama-ai-provider` v1 の仕様と AI SDK v6 との非互換を回避します。 - **デーモンの正常なシャットダウン** — `stopDaemon` が非同期になりました: SIGTERM を送り、最大 5 秒待ってから SIGKILL にエスカレートします。停止時に残った `signal-cli` プロセスを片付けます。 - **チャネル送信エラーをログに記録** — チャネル送信のすべての `.catch(() => {})` を `.catch((e) => logger.warn({ e }, 'channel send failed'))` に置き換えました。 ### 内部 - 新しい `src/signal/` モジュール: `binary.ts`(signal-cli のダウンロード/検証)、`jsonrpc.ts`(JSON-RPC クライアント)、`process.ts`(ライフサイクル)、`setup.ts`(登録フロー)。 - 新しい `src/core/crash-flag.ts` — クラッシュフラグの読み取り/書き込み/クリア。 - `src/types/channel.ts` — Signal、Discord、Slack のアクセスモデル用の新しい型。 - `src/utils/config.ts` — 3 つの新しいチャネルすべてに対する設定セクション、アクセス関数、レガシー設定のマイグレーション。 - `src/channels/registry.ts` — 通知の優先順位: Signal → Telegram → Discord → Slack → CLI。 - `package.json` — 新しい依存関係: `discord.js` v14、`@slack/bolt` v4。 ### 1.1.12 からの移行 破壊的変更はありません。新しいチャネルはすべて**デフォルトで無効**です — `mercury doctor` または環境変数で有効化してください。既存の設定、プロバイダー、スレッド、カンバンボード、Second Brain のデータはそのまま引き継がれます。 ## 1.1.12 — スタンドアロンバイナリのデーモン修正 1.1.11 へのホットフィックスです。1.1.11 で配布された単一ファイルのスタンドアロンバイナリはバックグラウンドで起動できず、そのため 1 行インストーラー(サーバー向けの推奨手順)で Mercury をインストールした場合、Telegram がオンラインになりませんでした。 ### 修正 - **スタンドアロンバイナリからデーモンが正しく起動するように** — `src/cli/daemon.ts` は以前、デーモンを `[process.execPath, process.argv[1], 'start', '--daemon']` として起動していました。npm インストールではこれが `node dist/index.js start --daemon` となり動作していました。`bun --compile` のスタンドアロンバイナリでは、`process.execPath` は Mercury のバイナリ自身で、`process.argv[1]` は bun の仮想パス `$bunfs/...` なので、起動コマンドは `mercury "$bunfs/..." start --daemon` になっていました — Commander は bunfs のパスを不明なサブコマンドとして扱い、子プロセスは即座に終了し、`channels.startAll()`(デーモンモードで Telegram を起動する唯一の場所)に到達することはありませんでした。 - **`mercury service install` が壊れたコマンドを保存しなくなりました** — スタンドアロンバイナリから実行した場合、LaunchAgent の plist、systemd ユニット、Windows Task Scheduler のエントリには、バイナリのみの呼び出し(スクリプトパスなし)が含まれるようになったため、起動時の自動起動がエンドツーエンドで動作します。 - **スタンドアロンバイナリのユーザーでも、バックグラウンドモードで Telegram がオンラインになるように** — デーモン修正の直接の結果です。 ### 内部 - `src/cli/daemon.ts` に新しい `isStandaloneBinary()` / `buildDaemonSpawnArgs()` ヘルパー、`src/cli/service.ts` に `getServiceLaunchArgs()` を追加し、すべての OS のインストーラーに組み込みました。検出には `process.versions.bun`、`argv[1]` 内の `$bunfs` / `~BUN` マーカー、`execPath` のベース名を使うため、`node`、`bun <script>`、スタンドアロンの `mercury` のいずれの呼び出しでも正しく動作します。 ### 1.1.11 からの移行 必要な変更はありません。アップグレード後に `mercury restart` を実行してください(1.1.11 でサービスをインストールし壊れたコマンドが保存されている場合は、`mercury service uninstall && mercury service install`)。 ## 1.1.11 — Token Saver モード、スキルシステム、スタンドアロンバイナリ 1.1.x 系が始まって以来最大のリリースです。完全な**スキルシステム**、より安価なセッションのための **Token Saver モード**、npm を使いたくないユーザー向けの**スタンドアロンバイナリ**、そしてステップごとのスピナーを備えた再設計されたボトムステータスバーを追加しました。 ### 新機能 - **Token Saver モード + ボトムステータスバーの刷新 + ステップごとのスピナー**(#69)— コンテキストを積極的に削減するオプトインのモードに加え、TUI の下部にプロバイダー/モデル/トークン使用量をライブで表示する新しい常駐ステータスバーを追加し、単一のグローバルスピナーをステップごとのスピナーに置き換えました。 - **スキルシステム**(#67)— Mercury がユーザー定義のスキルを読み込み、ルーティングできるようになりました。スキルは Markdown で定義された振る舞いで、キーワード/セマンティックの一致に基づいて必要に応じて注入されます。 - **スクリーンショットスキル** — ビューポートのサイズ指定とダーク/ライトモードの切り替えに対応した、Web サイト全体のキャプチャ。 - **スタンドアロンバイナリ + 1 行インストーラー**(#61)— `mercury` は macOS(arm64/x64)、Linux(x64/arm64)、Windows(x64)向けの単一実行ファイルとして配布されるようになりました。Node のインストールは不要です。OS ごとのドキュメントと、Web サイトのヒーローセクションにインストールウィジェットを用意しました。 - **ドメインの移行** — `mercury.cosmicstack.org` → `mercuryagent.sh`。 - README、ARCHITECTURE、CHANGELOG の**中国語訳**(#53)。 ### 修正 - **スキルの曖昧さのプロンプト**(#68)— 弱い一致で 10 個のスキルに分散することはなくなりました。ルーターが確信を持てないときは、番号付きのピッカーが表示されます。 - **キーワードの弱い重なりによる誤った曖昧さのプロンプト** — マッチャーは偶然の単語の重なりでピッカーを表示していましたが、実際のシグナルを必要とするようになりました。 - **リリースアセット名を公開バイナリと一致させました**(#63)— 誤ったファイル名を指していたインストーラースクリプトを修正します。 - **セグメントごとのシェルパターンチェック**(#48)— シェルのパーミッションガードは、単一の結合されたチェックを信頼するのではなく、シェルの各セグメントを個別に検証するようになりました。 ### メンテナンス - **`anonymous-file-uploader` スキルを削除** — 不要になりました。 - **`pino` をアップグレード** 9.14.0 → ^10.3.1(#51)。 - スピナーの磨き込みとドキュメントの更新を全体的に実施。 ### 1.1.9 からの移行 破壊的変更はありません。スキルシステムはオプトインです(`~/.mercury/skills/` に Markdown ファイルを置いてください)。Token Saver モードはデフォルトで無効です — セッションメニューまたは設定から有効にしてください。スタンドアロンバイナリは代替のインストール手段であり、`npm i -g @cosmicstack/mercury-agent` はこれまでとまったく同じように動作します。 > 注: 公開チャネル間でバージョン番号を揃えるため、`1.1.10` はスキップしました。 ## 1.1.5 — よりスムーズなオンボーディング ### 修正: Ollama がなくてもオンボーディングで行き詰まらないように オンボーディングのフローには重大な UX の問題がありました: ローカルで Ollama を実行していないか、手元に API キーがないユーザーは、スキップする手段がないまま無限ループに陥っていました。このリリースでオンボーディングはスムーズで寛容になります。 **主な変更点:** 1. **Ollama Local をスキップ可能に** — Ollama が動いていなければ、完全にスキップするか、モデル名を手動で入力できます。無限の再試行ループはもうありません。 2. **すべてのプロバイダー設定でスキップが可能に** — すべての API キーのプロンプトで、プロバイダーの API に到達できない場合はモデル名の手動入力と、わかりやすいスキップの選択肢が提供されます。エラーメッセージは、ストレスを減らすため赤(失敗)から黄(警告)に変更されました。 3. **「プロバイダーなし」の罠を解消** — 以前は、どのプロバイダーも設定できないと無限ループに陥っていました。現在は「skip」と入力して設定を保存し、後で `mercury doctor` で戻ってこられます。DeepSeek の無料 API についてのヒントも表示されます。 4. **Ollama Local のデフォルトモデルを空に** — デフォルトは `gpt-oss:20b`(非標準のモデル)でした。現在は空がデフォルトで、優先モデルの一覧には `llama3.2`、`mistral`、`phi3` などの一般的な名前を使います。 5. **初回実行時の案内をより明確に** — LLM Providers のステップで「You can skip any provider by pressing Enter」と表示し、DeepSeek が無料のキーを提供していることを案内します。 ### 変更の概要 | ファイル | 変更内容 | |------|--------| | `src/index.ts` | `promptOllamaLocalModelSelection` — ベース URL のスキップを許可し、取得失敗時にモデルを手動入力 | | `src/index.ts` | `promptApiKeyWithModelSelection` — API の取得失敗時にモデルを手動入力、スキップの選択肢 | | `src/index.ts` | `configure()` — プロバイダーが 1 つも設定されていない場合の「skip」の選択肢、無料キーについてのヒント | | `src/utils/config.ts` | Ollama Local のデフォルトモデルを `gpt-oss:20b` から空文字列に変更 | | `src/utils/provider-models.ts` | Ollama Local の優先モデルを一般的な名前に更新 | ## 1.1.4 — OpenAI Compilations とプロバイダーの可視化 ### 新機能: OpenAI Compilations プロバイダー **セルフホスト、サードパーティ、その他あらゆる OpenAI 互換 API** 向けの新しい専用プロバイダーです。自分のシステム上でも、セルフホストでも、クラウドサービスでも使えます。特定のベンダーに縛られずに任意の OpenAI 互換エンドポイントに接続する方法が、コミュニティから求められていました。 **セットアップウィザードの流れ:** 1. サーバーのベース URL を入力(必須)— 例: `http://localhost:8000/v1` や `https://my-llm.example.com/v1` 2. 任意で API キーを入力(Enter でスキップ — ローカル/セルフホストのサーバーでは不要なことが多いです) 3. Mercury が `/models` エンドポイントからモデルの取得を試みます 4. 成功した場合 — カスタム名を入力する選択肢付きのインタラクティブなモデルピッカーを表示します 5. 取得に失敗した場合 — モデル名を手動で入力するよう求めます 6. 保存前にはいつでもカスタムのモデル名を入力できます **設計上のポイント:** - API キーは**任意**です — ローカルやセルフホストのサーバーは認証なしで動くことが多いためです - Responses API(`/responses`)ではなく Chat Completions API(`/chat/completions`)を使用します - `isProviderConfigured` は `baseUrl + model` を必須とし、`apiKey` は必須としません - モデル名のフィルタリングはなく、サーバーが返すすべてのモデル ID を受け入れます - デフォルトのプロバイダーとして設定できます - 環境変数: `OPENAI_COMPAT_API_KEY`、`OPENAI_COMPAT_BASE_URL`、`OPENAI_COMPAT_MODEL`、`OPENAI_COMPAT_ENABLED` ### 新機能: セッション開始時のプロバイダーとモデルの表示 セッション開始時に、アクティブなプロバイダーとモデルが目立つように表示されるようになりました — **マゼンタのバッジ**(`⚡ Provider · Model`)で、どの LLM が使われているかがすぐにわかります。その下に `← default` マーカー付きでプロバイダーの一覧全体が表示されます。 変更前: ``` Providers: DeepSeek, OpenAI Models: DeepSeek: deepseek-chat | OpenAI: gpt-4o-mini ``` 変更後: ``` ⚡ DeepSeek · deepseek-chat Providers: DeepSeek: deepseek-chat ← default · OpenAI: gpt-4o-mini ``` ### 修正: `fetchOpenAICompatModels` での任意の API キーの扱い 内部の `fetchOpenAICompatModels` 関数は、API キーが実際に設定されている場合にのみ `Authorization: Bearer` ヘッダーを送信するようになりました — 以前は(キーが空でも)常にヘッダーを送信しており、認証ヘッダーを想定していないローカルサーバーで認証エラーを引き起こしていました。 `OpenAICompatProvider` も、空の API キーの場合にフォールバックとして `'no-key'` を `createOpenAI()` に渡すことで適切に処理するようになり、認証なしのサーバーでのクラッシュを防ぎます。 ### 変更の概要 | ファイル | 変更内容 | |------|--------| | `src/utils/config.ts` | `ProviderName`、設定インターフェース、デフォルト値、`isProviderConfigured()` に `openaiCompat` を追加 | | `src/providers/registry.ts` | `openaiCompat` を `useChatApi: true` 付きの `OpenAICompatProvider` にルーティング | | `src/providers/openai-compat.ts` | 空の API キーを `createOpenAI()` 向けの `'no-key'` フォールバックで処理 | | `src/utils/provider-models.ts` | `OPENAI_COMPAT_PREFERRED_MODELS`、モデル取得時の任意の認証ヘッダー、`openaiCompat` ではモデルをフィルタリングしない、ルーティング | | `src/index.ts` | `PROVIDER_OPTIONS` に「OpenAI Compilations」、取得→フォールバックの流れを持つ `promptOpenAICompatSetup()`、セッション開始時のマゼンタのデフォルトプロバイダーバッジ | | `.env.example` | `OPENAI_COMPAT_*` 環境変数を追加 | | `src/utils/provider-models.test.ts` | `openaiCompat` のモデルカタログのテストを 2 件追加 | ## 1.1.3 — Ollama Cloud プロバイダーの修正 ### 何が起きていたか Ollama Cloud は完全に壊れており、すべてのリクエストが `404 Not Found` を返していました。2 つの独立したバグが `ollamaCloud` の動作を妨げていました: ### バグ 1: 誤った SDK — OpenAI 互換の Chat Completions ではなくローカル Ollama の API `ollamaCloud` は、`ollama-ai-provider` パッケージを使う `OllamaProvider` を経由してルーティングされていました。このパッケージは**ローカル**の Ollama サーバー向けに設計されており、`/api/chat` と `/api/tags` エンドポイントを対象としています。Ollama Cloud は `/v1/chat/completions` と `/v1/models` で **OpenAI 互換**の API を公開しており、通信形式がまったく異なります。 - **モデル一覧**は `${baseUrl}/tags` → `https://ollama.com/api/tags` → 404 を呼んでいました - **チャット補完**は `${baseUrl}/chat` → `https://ollama.com/api/chat` → 404 を呼んでいました **修正**: `ollamaCloud` は `OpenAICompatProvider`(`@ai-sdk/openai` の `createOpenAI()` を使用)を経由してルーティングされるようになり、他のすべての OpenAI 互換クラウドプロバイダー(MiMo、Grok)と同じパターンになりました。 ### バグ 2: 誤ったデフォルトのベース URL デフォルトの `OLLAMA_CLOUD_BASE_URL` は、ローカル Ollama サーバーのパスである `https://ollama.com/api` に設定されていました。Ollama Cloud の OpenAI 互換 API の正しいベース URL は `https://ollama.com/v1` です。 **修正**: デフォルトを更新し、起動時に既存の `mercury.yaml` を `/api` から `/v1` へ自動的に更新する設定マイグレーション(`migrateLegacyOllamaCloudBaseUrl`)を追加しました。 ### バグ 3: Chat Completions API ではなく Responses API バグ 1 を修正した後、`OpenAICompatProvider` は `createOpenAI()()` を使っていましたが、これはデフォルトで OpenAI の **Responses API**(`/responses`)になります。Ollama Cloud は **Chat Completions** API(`/chat/completions`)しかサポートしていないため、`https://ollama.com/api/responses` → 404 となっていました。 **修正**: `OpenAICompatProvider` に `useChatApi` オプションを追加しました。有効な場合(`ollamaCloud` では有効)、`client(model)` ではなく `client.chat(model)` を呼び出し、`/chat/completions` を対象にします。 ### バグ 4: ollamaCloud の baseUrl の検証がない `isProviderConfigured()` と `OllamaProvider.isAvailable()` は、`ollamaCloud` について `apiKey.length > 0` しか確認していませんでした — `baseUrl` が欠けていたり空だったりしても検出されず、リクエスト時にわかりにくい失敗を引き起こしていました。 **修正**: `isProviderConfigured()` と `isAvailable()` に `ollamaCloud` 専用の分岐を追加し、`apiKey` と `baseUrl` の両方を検証するようにしました。 ### 変更の概要 | ファイル | 変更内容 | |------|--------| | `src/providers/registry.ts` | `ollamaCloud` を `useChatApi: true` 付きの `OpenAICompatProvider` にルーティング | | `src/providers/openai-compat.ts` | Chat Completions API を使うための `useChatApi` オプションを追加 | | `src/utils/config.ts` | デフォルトのベース URL を `https://ollama.com/api` → `https://ollama.com/v1` に変更。`isProviderConfigured()` に `ollamaCloud` を追加。`migrateLegacyOllamaCloudBaseUrl()` を追加 | | `src/utils/provider-models.ts` | `/models`(OpenAI 互換)を使う新しい `fetchOllamaCloudModels()`。`fetchOllamaModels` を `fetchOllamaLocalModels` に改名(ローカルの `/tags` のみ)。`ollamaCloud` を別にルーティング | | `src/providers/ollama.ts` | `isAvailable()` がローカル以外のプロバイダーでは `baseUrl` も検証 | | `.env.example` | `OLLAMA_CLOUD_BASE_URL` のデフォルトを `https://ollama.com/v1` に更新 | | `src/utils/provider-models.test.ts` | `ollamaCloud` のモデルカタログのテストを 2 件追加 | ## 1.1.2 — MiMo プロバイダーと予算管理の強化 ## 1.0.0 — Second Brain これは**メジャーリリース**です。SQLite と全文検索に支えられた永続的で構造化されたメモリシステムである Second Brain を導入し、あわせて Mercury のデータの保存方法と出力の描画方法を根本的に変更したためです。 ### なぜ 1.0.0 なのか? Mercury は 0.x リリースを通じて急速に開発されてきました。Second Brain 機能は根本的な能力の転換を表しています: Mercury は会話をまたいで**記憶する**ようになり、あなたについての事実を自動的に抽出、統合、想起します。すべてを `~/.mercury/` に置くデータアーキテクチャと CLI のライブストリーミングと合わせて、これはメジャーバージョンにふさわしい、安定した本番利用可能な基盤となります。 ### Second Brain 🧠 - **10 種類のメモリタイプ** — identity、preference、goal、project、habit、decision、constraint、relationship、episode、reflection - **自動抽出** — 各会話の後、Mercury は確信度、重要度、永続性のスコア付きで 0〜3 個の事実を抽出します - **関連する想起** — 各メッセージの前に、900 文字の予算内で一致度の高い上位 5 件のメモリを注入します - **自動統合** — 60 分ごとに、プロフィールの要約とアクティブな状態の要約を合成し、検出したパターンから振り返りのメモリを生成します - **競合の解決** — 相反するメモリは確信度の高さまたは新しさで解決されます。否定の検出により「X が好き」と「X が好きではない」を扱います - **Active → Durable への昇格** — 3 回以上補強されたメモリは、短命な `active` スコープから長寿命の `durable` スコープへ自動的に昇格します - **自動の刈り込み** — active スコープのメモリは 21 日で古くなり、推測されたメモリは減衰し、確信度の低い durable のメモリは 120 日後に破棄されます - **SQLite + FTS5** — 瞬時に想起するための全文検索。すべてのデータは `~/.mercury/memory/second-brain/second-brain.db` にローカル保存されます - **ユーザーによる操作** — CLI と Telegram の両方で、`/memory` により概要、検索、一時停止、再開、クリアができます ### CLI ストリーミングの復活 - **ライブのテキストストリーミング** — 応答の生トークンが届いた順にターミナルへストリーミングされ、その後応答全体が適切な Markdown の書式で再描画されます(見出しは `■` マーカー付きのシアン、コードブロックは黄色、リストは薄い箇条書き記号、引用は薄い罫線) - **カーソルの保存/復元** — 壊れやすい行数のカウントではなく `\x1b7`/`\x1b8` の ANSI シーケンスを使い、1 行の回答で応答が重複するバグを解消しました - **ストリーミング中のツールのフィードバック** — ツール呼び出しはストリーミング中にインラインで表示され、出力を正確に置き換えられるよう追跡されます ### データアーキテクチャ: すべて `~/.mercury/` に - **変更前**: メモリ(短期、長期、エピソード)は CWD からの相対パス `./memory/` に保存されており、あちこちのプロジェクトディレクトリにファイルが作られていました - **変更後**: すべての状態が `~/.mercury/` 以下に置かれるようになりました — 設定、soul、メモリ、パーミッション、スキル、スケジュール、トークンの追跡、デーモンの状態 - **`getMemoryDir()`** ヘルパーは `~/.mercury/memory/` を返します — `memory.dir` 設定フィールドはもうありません - **自動マイグレーション** — 初回実行時、Mercury はレガシーな `./memory/` ディレクトリを検出して `~/.mercury/memory/` に移動し、古いディレクトリを削除します - **削除された設定フィールド**: `memory.dir`、`memory.secondBrain.dbPath` — これらは `getMercuryHome()` から算出されるようになりました ### パーミッションモード - **Ask Me** — ファイルの書き込み、承認が必要なシェルコマンド、スコープの変更の前に確認します(CLI と Telegram の両方でデフォルト) - **Allow All** — セッション中はすべて(スコープ、コマンド、ループの継続)を自動承認します。再起動でリセットされます。 - CLI: セッション開始時に矢印キーのメニュー。Telegram: 最初のメッセージでインラインキーボード、変更は `/permissions` で。 ### ステップごとのツールのフィードバック - **番号付きのステップ** — 各ツール呼び出しにステップ番号が付きます(`1. read_file foo.ts`) - **スピナー** — ツールの実行中は経過時間付きのアニメーションスピナーを表示します - **結果の要約** — 各ステップの後に簡潔な結果を表示します(例: `42 lines, 3 matches`) ### その他の変更 - **改善された Markdown レンダラー** — `■` マーカー付きのシアンの見出し、黄色のインラインコード、薄い取り消し線、薄い URL 付きの青い下線リンク、罫線付きの引用、罫線付きの表 - **HTML エンティティのデコード** — marked の HTML 出力による二重エンコードを修正 - **Telegram の組織アクセス** — 承認/拒否/昇格/降格のフローを持つ管理者とメンバー - **オンボーディング中のモデル選択** — API キーの検証後、Mercury が利用可能なモデルを取得して選択させます - **Telegram の編集可能なステータスメッセージ** — ストリーミングの更新に `editMessageText` を使い、応答をライブで編集します - **スケジュールされたタスクの通知** — スケジュールされたタスクが実行されると、Mercury は依頼元のチャネルに通知します - **スケジュールされたタスク向けの完全な一時スコープ** — タスクはスコープを自動承認した Allow All モードで実行されます ### 破壊的変更 - メモリのデータパスが `./memory/` から `~/.mercury/memory/` に変更されました — 自動マイグレーションで対応されます - 設定フィールド `memory.dir` を削除しました — 対応は不要で、値は無視されます - 設定フィールド `memory.secondBrain.dbPath` を削除しました — パスは自動的に算出されるようになりました ### 全変更履歴 **0.5.4** — ストリーミングの位置ずれを修正、エージェント名の重複を削除、ブロック形式をすっきりと **0.5.3** — mercury upgrade コマンドを追加、ENOTEMPTY を修正 **0.5.2** — readline のプロンプト処理、ストリーミングの再描画、インタラクティブなループ検出、HTML エンティティのデコードを修正 **0.5.1** — バグ修正 **0.5.0** — Telegram の組織アクセス、モデル選択、ドキュメントの更新 **0.4.0** — ソーシャルメディアのスキル、GitHub コンパニオン **0.3.0** — パーミッションシステム、スキルシステム、スケジューラー **0.2.0** — Telegram のストリーミング、ファイルのアップロード、デーモンモード **0.1.0** — 初回リリース