Skip to content

feat(update): npx 起動サーバの GUI ワンクリック更新を実装 (#1395)#1397

Merged
Kewton merged 1 commit into
developfrom
feature/1395-npx-gui-selfupdate
Jul 18, 2026
Merged

feat(update): npx 起動サーバの GUI ワンクリック更新を実装 (#1395)#1397
Kewton merged 1 commit into
developfrom
feature/1395-npx-gui-selfupdate

Conversation

@Kewton

@Kewton Kewton commented Jul 18, 2026

Copy link
Copy Markdown
Owner

概要

npx commandmate で起動したサーバでも GUI「今すぐアップデート」から実際にその場更新を完了できるようにします(#1394 の「正しく案内」を「実際に更新」へ引き上げる後続)。

方式は設計 Alt A: detached オーケストレータ + npx 再取得 —「グローバル入替」ではなく「新しい npx キャッシュを取得し、旧デーモンを停止→新デーモンを起動し直す」。新旧キャッシュが別 dir のため #1194 型の共有dir破壊が構造的に起きません。

Closes #1395

設計

設計方針書(レビュー反映済み)は Issue #1395 のコメントに全文記録。骨格・不変条件はそれに準拠。

変更(P1→P5)

  • P1 src/cli/utils/npx-runner.ts(新規): warmNpxLatest/spawnNpxDaemonspawnSync 配列argv・no-shell で。sanitizeNpxEnvnpm_* 除去(CM_*/PATH 保持)。warmup timeout 3分(GUI 5分より短く)。
  • P2 src/cli/commands/update.ts: 隠しフラグ update --relaunch-npxrunNpxSelfUpdate.env確認→registry latest→warm+等値検証(停止前=ダウンタイム0 fail-fast)→stop→spawnNpxDaemon→isRunning/getStatus→起動後版検証→waitForReady。abort系で releaseUpdateLock(§5.2)。素の commandmate update(npx) は fix(cli): npx 実行時の commandmate update が誤動作する(要検証) #1319 no-op のまま。
  • P3 src/app/api/app/update/route.ts: npx を「拒否(fix(update): npx 起動時に GUI アップデートが誤って動作する(#1319 のガードが GUI 経路に未反映) #1394)」→「detached で update --yes --relaunch-npx固定argv起動して202」。ゲート順=npx最優先。
  • P4 UpdateNotificationBanner.tsx + i18n: installType:'npx' で更新ボタン+再起動注意喚起。timeout/error 案内を npx commandmate@latest に。矛盾する npxTitle/npxDescription を削除。
  • P5: docs/module-reference.md / CHANGELOG.md 更新。

⚠️ レビュー観点(P3 = セキュリティ集中)

プロセス spawn を伴う route 変更のため、マージ前に以下を重点確認してください:

  • spawnUpdate の argv は ['update','--yes','--relaunch-npx'] / ['update','--yes']2つの固定リテラル配列のみで、選択は isNpx(実行時状態)=リクエスト由来ではない。POST は無引数のまま。
  • acquireUpdateLock 取得・失敗時 releaseUpdateLock の整合。orchestrator の abort系パスでのロック解放(§5.2)。
  • 認証は middleware 任せ(/api/app/updateAUTH_EXCLUDED_PATHS に追加していない)。
  • update-lock.ts の import を @/→相対に変更(CLI build 取り込みのため)。回帰なしを確認済みだが要確認。

検証

  • npm run lint: exit 0 / npx tsc --noEmit: exit 0 / npx tsc --project tsconfig.cli.json --noEmit: exit 0(@/漏れなし)
  • npm run test:unit: 10167 passed(596 files)
  • 新規/変更/回帰テスト個別再実行: green(npx-runner 272行・update-relaunch-npx 265行の新規テスト含む)
  • npm run build は稼働サーバ足元のため未実行(CI に委譲)

制約(設計どおり)

  • 再起動後は .env+引き継ぎ env で起動。元の npx commandmate --auth/--port 等 CLI フラグは非復元(§7.2、GUI に注意喚起)。
  • 旧 npx キャッシュ dir は GC 任せ(明示クリーンアップなし)。

🤖 Generated with Claude Code

https://claude.ai/code/session_01AqhdEu33W6t3ing8ksA6J3

#1394 で「npx はその場更新不可」と正しく案内する状態にした後続として、
npx 起動サーバでも GUI「今すぐアップデート」から実際に更新を完了できる
ようにする。方式は「グローバル入替」ではなく「新しい npx キャッシュを
取得し旧デーモンを停止→新デーモンを起動し直す」(設計 Alt A)。新旧
キャッシュが別 dir のため #1194 型の共有dir破壊が構造的に起きない。

- P1 npx-runner (新規): warmNpxLatest / spawnNpxDaemon を spawnSync 配列
  argv・no-shell で実装。sanitizeNpxEnv で npm_* を除去(CM_*/PATH は保持)。
  warmup timeout 3分(GUI 5分より短く)。
- P2 update.ts: 隠しフラグ update --relaunch-npx で runNpxSelfUpdate を実行。
  .env確認→registry latest→warm+等値検証(停止前=ダウンタイム0 fail-fast)
  →stop→spawnNpxDaemon→isRunning/getStatus→起動後版検証→waitForReady。
  abort系パスで releaseUpdateLock(§5.2)。素の commandmate update(npx) は
  #1319 no-op のまま。
- P3 route: POST /api/app/update の npx を「拒否(#1394)」→「detached で
  update --yes --relaunch-npx を固定argv起動して202」。ゲート順=npx最優先。
  POST無引数・acquireUpdateLock・認証middleware任せの #1198 不変条件を維持。
- P4 banner: installType 'npx' で更新ボタン+再起動注意喚起(npxRestartNotice)
  を表示。timeout/error の案内を npx commandmate@latest に。矛盾する
  npxTitle/npxDescription を削除。i18n(en/ja)更新。
- P5 docs/module-reference.md・CHANGELOG 更新。

セキュリティ: 固定リテラル argv(リクエスト由来のコマンド構築なし)・
no-shell・ロック取得/解放の整合を維持。update-lock.ts の import を @/→相対に
変更(CLI build に取り込むため。tsc:cli green・既存33テスト無回帰)。

検証: lint exit0 / tsc --noEmit exit0 / tsc:cli --noEmit exit0 /
test:unit 10167 passed(596 files)。新規/変更/回帰テスト個別再実行も green。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AqhdEu33W6t3ing8ksA6J3
@Kewton Kewton added the feature label Jul 18, 2026
@Kewton
Kewton merged commit f131563 into develop Jul 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant