Skip to content

fix(cli): 稼働デーモンの版が据え置かれ、利用者が古い版だと気づけない #1337

Description

@Kewton

事象

利用者は自分が古い版を使っていることに気づけず、気づいても npx commandmate@latest では上げられない。 実際に発生した(2026-07-17)。

#1334 の修正を v0.10.3 として publish した後、利用者は npx commandmate@latest を繰り返し実行したが、サーバーは 0.10.0 のままで修正が一切届かなかった。本人も、調査した側も、その事実に到達するまでに何往復も要した。

根本原因は2つあり、重なると詰む

npx commandmate@latest は稼働中デーモンを再起動しない

src/cli/commands/quickstart.ts:110-130

async function ensureServerRunning(
  daemonManager: DaemonManager
): Promise<{ url?: string; exitCode?: ExitCode }> {
  if (await daemonManager.isRunning()) {
    // start.ts reports an already-running server as START_FAILED, so it must not be called here
    const status = await daemonManager.getStatus();
    logger.info(`Server is already running (PID: ${status?.pid})`);
    return { url: status?.url };      // ← 起動もせず、既存サーバーの URL を返すだけ
  }
  ...
}

デーモンが生きていれば、何度 @latest を叩いてもサーバーは古いコードのままでブラウザが開くだけ。版の照合は一切していない。

しかも npx は毎回最新版を取得するため、npx commandmate@latest --version0.10.3 と表示する。利用者はこれを「最新で動いている」証拠と受け取る。実際に今回そう報告された。CLI パッケージの版と稼働デーモンの版が食い違うことが、どこにも表れない。

② 稼働サーバーの版を UI から確認できない

リポジトリを1つも登録していない状態では、GUI にバージョン表示が出ない(利用者報告)。

一方で GET /api/app/update-check は正しく答えている:

{"status":"success","hasUpdate":true,"currentVersion":"0.10.0","latestVersion":"0.10.3",
 "installType":"global","updateCommand":"npm install -g commandmate@latest"}

アプリは「更新がある」と知っていた。 利用者に伝えていないだけである。

なぜ重大か

①と②は互いを隠す。

  • ① があるので、古い版が黙って据え置かれる
  • ② があるので、据え置かれたことに気づけない
  • --version は嘘ではないが別のものを指しているので、確認したつもりが誤診になる

結果、修正をリリースしても利用者に届かず、届いていないことを誰も検知できない#1334 は「新規ユーザーの最初の操作が止まる」欠陥だったが、その修正自体がこの経路で止まった。

対策案

① への対策

ensureServerRunning で既存デーモンを検出した際、稼働中サーバーの版と、これから実行しようとしている CLI の版を照合する。食い違う場合に少なくとも警告する。

Server is already running (PID: 12345) — but it is running v0.10.0 while this CLI is v0.10.3.
The running server will NOT be updated. To update:
  commandmate stop && npm install -g commandmate@latest && commandmate start --daemon

稼働サーバーの版は GET /api/app/update-checkcurrentVersionNEXT_PUBLIC_APP_VERSION)から取得できる。

自動再起動するかは要判断。 黙って再起動すると稼働中のセッションを巻き込むため、既定は警告に留め、--restart のような明示フラグを設ける案が穏当。

② への対策

リポジトリ未登録でもバージョンと更新有無を表示する。 update-check は既にデータを返しているので、表示側の問題。

  • 版の表示をリポジトリ登録状態に依存させない
  • hasUpdate: true のとき更新導線(updateCommand)を出す

補足: 更新時の順序が罠になっている

installType: "global" の環境で、稼働中に npm install -g commandmate@latest を実行するとパッケージディレクトリが置換され、稼働プロセスの cwd が削除済み inode になる。これが #1334git clone が exit 128)の実際のトリガーだった。

正しい順序は stop → install → startupdateCommand が返す文字列は npm install -g commandmate@latest のみで、この順序を伝えていないcommandmate update#1194)は停止→更新→再起動を行うので、そちらを案内する方が安全ではないか。

優先度

高。 「修正が利用者に届かない」ため、他のあらゆる修正の価値を損なう。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions