From 169f490aa17273017e8672dd0043347acd8f2d8a Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Fri, 4 Sep 2026 09:00:18 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20Kiro=E8=AA=8D=E8=A8=BC=E6=83=85?= =?UTF-8?q?=E5=A0=B1=E3=81=A8tmux=E6=93=8D=E4=BD=9C=E3=82=92=E6=94=B9?= =?UTF-8?q?=E5=96=84=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- containers/base/entrypoint.sh | 11 +++ containers/base/tmux.conf | 11 +++ docs/user/container-operations.md | 12 ++- issues/kiro-auth-persistence.md | 78 +++++++++++++++++++ .../containers/test_entrypoint_ai_settings.py | 50 +++++++++++- tests/containers/test_tmux_conf.py | 17 +++- 6 files changed, 170 insertions(+), 9 deletions(-) create mode 100644 issues/kiro-auth-persistence.md diff --git a/containers/base/entrypoint.sh b/containers/base/entrypoint.sh index 86eefdba..860f0a3c 100644 --- a/containers/base/entrypoint.sh +++ b/containers/base/entrypoint.sh @@ -205,6 +205,14 @@ DEVBASE_GROUP_SETTINGS=( ".claude.json" ".claude" ".gemini" + ".local/share/kiro-cli" +) + +# 分類 B のうち、既存コンテナのホームから初回だけ取り込むもの。 +# Kiro CLI 2.x は認証状態を ~/.local/share/kiro-cli にも保存するため、symlink へ +# 張り替える前にコピーしないと、初回適用時のログイン状態を失う。 +DEVBASE_GROUP_HOME_SEED_SETTINGS=( + ".local/share/kiro-cli" ) # 分類 A のうち ~/.claude 配下にあるもの (グループ側の .claude から共通側へ張る) @@ -433,6 +441,9 @@ devbase_setup_ai_settings() { # symlink の中身へコピーしてしまう。 devbase_seed_image_claude_settings "$home_root" "$ai_root" devbase_seed_group_settings "$ai_root" "$group_root" "$group" + for entry in "${DEVBASE_GROUP_HOME_SEED_SETTINGS[@]}"; do + devbase_seed_entry "$home_root/$entry" "$group_root/$entry" + done for entry in "${DEVBASE_SHARED_SETTINGS[@]}"; do devbase_link_setting "$home_root/$entry" "$ai_root/$entry" "$owner" diff --git a/containers/base/tmux.conf b/containers/base/tmux.conf index a700d7bf..662bd016 100644 --- a/containers/base/tmux.conf +++ b/containers/base/tmux.conf @@ -13,6 +13,17 @@ # external)。ペインをまたいで選択したいときは Shift + ドラッグで端末側の選択に戻る。 set -g mouse on +# Windows の選択操作に近づける。ドラッグ終了時には選択を残し、Ctrl+C でコピーする。 +# copy-mode 中も履歴上で新しい範囲をドラッグできるよう、選択開始操作を明示する。 +unbind-key -T copy-mode MouseDragEnd1Pane +unbind-key -T copy-mode-vi MouseDragEnd1Pane +bind-key -T copy-mode MouseDown1Pane select-pane +bind-key -T copy-mode-vi MouseDown1Pane select-pane +bind-key -T copy-mode MouseDrag1Pane select-pane \; send-keys -X begin-selection +bind-key -T copy-mode-vi MouseDrag1Pane select-pane \; send-keys -X begin-selection +bind-key -T copy-mode C-c send-keys -X copy-selection-and-cancel +bind-key -T copy-mode-vi C-c send-keys -X copy-selection-and-cancel + # 既定の 2000 行はビルドログ 1 回で流れ切る。pane あたりの上限であり、実際に使った # 分だけ確保するので固定の先取りは無い。 set -g history-limit 100000 diff --git a/docs/user/container-operations.md b/docs/user/container-operations.md index 12ac6d55..8e2b249f 100644 --- a/docs/user/container-operations.md +++ b/docs/user/container-operations.md @@ -144,7 +144,7 @@ devbase のコンテナは 4 種類のボリュームを使用します。 | ボリューム名 | マウント先 | 共有範囲 | 用途 | |-------------|-----------|---------|------| | `devbase_home_ubuntu` | `/persistent/ai` | 全コンテナで共有 | 契約やテナントに紐づかない共通資産(`~/.claude/plugins` / `skills` / `commands` / `CLAUDE.md` / `settings.json`、`.codex` / `.serena` / `.kiro`、SSH 鍵、共有ファイル置き場 `share`)| -| `devbase_home_{group}` | `/persistent/group` | 同じアカウントグループのコンテナで共有 | 企業テナントに紐づくもの(Claude Code の認証と会話ログ、`.gemini`、gcloud / gws の設定ディレクトリ)| +| `devbase_home_{group}` | `/persistent/group` | 同じアカウントグループのコンテナで共有 | 企業テナントに紐づくもの(Claude Code の認証と会話ログ、`.gemini`、Kiro CLI の `.local/share/kiro-cli`、gcloud / gws の設定ディレクトリ)| | `devbase_work_{index}` | `/work` | 同じ index のコンテナで共有(プロジェクト間も共有) | プロジェクトのソースコード、作業ファイル | | `devbase_vscode_{project}_{index}` | `/home/ubuntu/.vscode-server` | 共有しない(コンテナ 1 つに 1 本)| VS Code Server 本体・拡張機能・接続トークン | @@ -270,6 +270,7 @@ AI CLI ツールの設定や認証情報は、コンテナを再生成しても | `.claude.json` | Claude Code の設定(`oauthAccount` を含む)| | `.claude` | Claude Code の認証・会話ログ・セッション状態(上表の共通資産を除く**すべて**)| | `.gemini` | Gemini CLI と Antigravity CLI の設定(`vertex-ai` は GCP プロジェクトに紐づく。Antigravity CLI は `.gemini/antigravity-cli/` 配下を使う)| +| `.local/share/kiro-cli` | Kiro CLI 2.x の認証状態・実行データ | `~/.claude` は `/persistent/group/.claude` への symlink で、**その配下の既定はグループ側**です。 共通資産だけがその中から `/persistent/ai/.claude/` へ張り直されます。既定をグループ側に @@ -455,14 +456,17 @@ OAuth のログインはコンテナを作り直しても残ります。 | 操作 | キー | |------|------| | スクロール | マウスホイール(自動で copy-mode に入る) | -| コピー | ドラッグして離す(クリップボードへ直接入る) | +| 範囲選択 | ドラッグ(ボタンを離しても選択を保持) | +| コピー | 選択中に `Ctrl+C`(クリップボードへ入れて copy-mode を抜ける) | +| 選択解除 | `q` | | copy-mode に入る | `Ctrl-b` `[` | | 履歴内を検索 | copy-mode 中に `Ctrl-r`(上方向)/`Ctrl-s`(下方向) | | copy-mode を抜ける | `q` | | ペインをまたいで選択 | `Shift` + ドラッグ(VS Code のネイティブ選択に切り替わる) | -コピーは追加設定なしで動きます。tmux の `set-clipboard`(既定 `external`)により、選択して -ボタンを離した時点で OSC 52 が送出され、VS Code がクリップボードへ書き込みます。 +ドラッグ終了後も選択範囲が残ります。`Ctrl+C` を押すと tmux が OSC 52 を送出し、VS Code の +クリップボードへ書き込んで copy-mode を抜けます。コピーせず選択を解除する場合は `q` を +押します。 上表の copy-mode のキーは tmux の `mode-keys` に従います。既定は `emacs` ですが、tmux は `EDITOR` / `VISUAL` に `vi` を含む値が入っていると `vi` へ切り替えるため、その場合の検索は diff --git a/issues/kiro-auth-persistence.md b/issues/kiro-auth-persistence.md new file mode 100644 index 00000000..cfe87420 --- /dev/null +++ b/issues/kiro-auth-persistence.md @@ -0,0 +1,78 @@ +# Kiro CLI 認証情報の永続化 + +## モード + +standard: コンテナ再生成後の Kiro CLI 認証保持という本番挙動を修正する。 + +## 目的と非目的 + +達成したい状態: +- Kiro CLI 2.20.1 が `~/.local/share/kiro-cli` に保存する状態を、アカウントグループ単位の named volume に保持する。 +- 初回適用時にホーム側に既存データがあれば、削除せず永続領域へコピーする。 + +やらないこと: +- Kiro CLI の認証方式やログイン操作は変更しない。 +- Kiro CLI のキャッシュと認証情報を分離しない(CLI が同じディレクトリで管理しているため)。 + +## 受け入れ条件 + +- [x] `~/.local/share/kiro-cli` が `/persistent/group/.local/share/kiro-cli` を指す symlink になる。 +- [x] ホーム側に既存の Kiro CLI データがある初回起動では、そのデータがグループ volume にコピーされる。 +- [x] 2 回目以降の起動で、グループ volume の新しいデータが古いホーム側データで上書きされない。 +- [x] 異なるアカウントグループ間で Kiro CLI の状態が共有されない。 + +## 代替案と採否 + +| 内容 | 採否 | 理由 | +| --- | --- | --- | +| `/persistent/group` へ symlink | 採用 | Kiro の認証状態は AWS アカウントに紐づくため | +| `/persistent/ai` へ symlink | 不採用 | 全アカウントグループで認証状態が共有されるため | +| `~/.local/share` 全体を永続化 | 不採用 | Kiro と無関係なツールのデータまで共有・永続化するため | + +## 不変条件 + +- 共通 AI 資産は `/persistent/ai`、アカウントに紐づく認証状態は `/persistent/group` に置く。 +- 既存の永続データを起動時のシードで上書きしない。 + +## 互換性 + +| 対象 | 変更 | 互換性の扱い | +| --- | --- | --- | +| 公開インタフェース | なし | 既存コマンドを変更しない | +| 永続データ | Kiro CLI 状態の保存先を追加 | 既存ホームデータを初回のみコピーする | + +## 修正対象 + +- `containers/base/entrypoint.sh` +- `tests/containers/test_entrypoint_ai_settings.py` +- `docs/user/container-operations.md` + +## タスク分解 + +### Task 1: Kiro CLI 状態を安全に永続化する +- **対象ファイル:** entrypoint とそのテスト +- **変更内容:** 入れ子パスをグループ設定へ追加し、既存ホームデータを初回のみシードする。 +- **満たす受け入れ条件:** 1〜4 +- **進め方:** 失敗するテスト → 最小実装 → 回帰テスト + +### Task 2: 永続化対象を文書化する +- **対象ファイル:** `docs/user/container-operations.md` +- **変更内容:** Kiro CLI の新しい保存先と共有範囲を追記する。 +- **満たす受け入れ条件:** 1、4 +- **進め方:** 実装と記述の一致を確認する。 + +## リスクと対処 + +| リスク | 対処 | +| --- | --- | +| 初回 symlink 化で再ログイン済みデータを失う | リンク作成前に、永続先が空の場合だけ `cp -a` する | +| AWS アカウント間で認証が混ざる | 共通 volume ではなく group volume を使う | + +## 切り戻し手順 + +- entrypoint の対象一覧からパスを外す。コピー済みデータは削除せず残すため、再適用できる。 + +## 完了の定義 + +- [x] 受け入れ条件に対応するテストがすべて成功する。 +- [x] 全体テストと静的検査が成功する。 diff --git a/tests/containers/test_entrypoint_ai_settings.py b/tests/containers/test_entrypoint_ai_settings.py index 71c14d60..e8697eb1 100644 --- a/tests/containers/test_entrypoint_ai_settings.py +++ b/tests/containers/test_entrypoint_ai_settings.py @@ -73,12 +73,60 @@ def test_group_entries_point_at_the_group_volume(roots): home, _, grp = roots setup(roots, "kkg") - for entry in (".claude.json", ".claude", ".gemini"): + for entry in (".claude.json", ".claude", ".gemini", ".local/share/kiro-cli"): link = home / entry assert link.is_symlink(), f"{entry} が symlink ではない" assert link.resolve() == (grp / entry).resolve() +def test_kiro_cli_data_points_at_the_group_volume(roots): + home, _, grp = roots + setup(roots, "kkg") + + link = home / ".local" / "share" / "kiro-cli" + assert link.is_symlink() + assert link.resolve() == (grp / ".local" / "share" / "kiro-cli").resolve() + + +def test_existing_kiro_cli_data_is_seeded_before_linking(roots): + home, _, grp = roots + source = home / ".local" / "share" / "kiro-cli" + source.mkdir(parents=True) + (source / "data.sqlite3").write_text("logged-in") + + setup(roots, "kkg") + + assert source.is_symlink() + assert (grp / ".local" / "share" / "kiro-cli" / "data.sqlite3").read_text() == "logged-in" + + +def test_existing_group_kiro_data_is_not_overwritten(roots): + home, _, grp = roots + source = home / ".local" / "share" / "kiro-cli" + target = grp / ".local" / "share" / "kiro-cli" + source.mkdir(parents=True) + target.mkdir(parents=True) + (source / "data.sqlite3").write_text("stale") + (target / "data.sqlite3").write_text("refreshed") + + setup(roots, "kkg") + + assert (target / "data.sqlite3").read_text() == "refreshed" + + +def test_kiro_cli_data_is_separate_between_groups(roots, tmp_path): + home_a, ai, group_a = roots + home_b = tmp_path / "home-b" + group_b = tmp_path / "persistent" / "kkg" + home_b.mkdir() + + setup((home_a, ai, group_a), "default") + setup((home_b, ai, group_b), "kkg") + (home_a / ".local" / "share" / "kiro-cli" / "identity").write_text("default") + + assert not (home_b / ".local" / "share" / "kiro-cli" / "identity").exists() + + def test_claude_defaults_to_the_group_volume(roots): """``~/.claude`` 配下の既定はグループ側。 diff --git a/tests/containers/test_tmux_conf.py b/tests/containers/test_tmux_conf.py index c74e0e39..4d0ae5dc 100644 --- a/tests/containers/test_tmux_conf.py +++ b/tests/containers/test_tmux_conf.py @@ -146,10 +146,19 @@ def test_dockerfile_installs_conf_as_etc_tmux_conf(): f"配置先かパーミッションが想定と違う: {copy_lines[0]}" -def test_conf_does_not_change_key_bindings(): - """条件 9: 既定値の配布に留め、利用者の既知の操作を壊さない。""" +def test_conf_provides_windows_like_copy_bindings(): + """履歴上のドラッグ選択と Ctrl+C を両モードへ設定する。""" directives = [line.strip() for line in TMUX_CONF.read_text().splitlines() if line.strip() and not line.strip().startswith("#")] assert directives, "設定が 1 行も無い" - assert all(line.startswith("set ") for line in directives), \ - f"set 以外の指示が含まれる: {[x for x in directives if not x.startswith('set ')]}" + binding_directives = [line for line in directives if not line.startswith("set ")] + assert binding_directives == [ + "unbind-key -T copy-mode MouseDragEnd1Pane", + "unbind-key -T copy-mode-vi MouseDragEnd1Pane", + "bind-key -T copy-mode MouseDown1Pane select-pane", + "bind-key -T copy-mode-vi MouseDown1Pane select-pane", + r"bind-key -T copy-mode MouseDrag1Pane select-pane \; send-keys -X begin-selection", + r"bind-key -T copy-mode-vi MouseDrag1Pane select-pane \; send-keys -X begin-selection", + "bind-key -T copy-mode C-c send-keys -X copy-selection-and-cancel", + "bind-key -T copy-mode-vi C-c send-keys -X copy-selection-and-cancel", + ] From 742f0af8e4b561d09281cf148ced541aa216f364 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Fri, 4 Sep 2026 09:42:42 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E6=8C=87=E6=91=98=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- containers/base/entrypoint.sh | 15 +++++++++++- containers/base/tmux.conf | 4 ++-- issues/kiro-auth-persistence.md | 18 +++++++++++++++ .../containers/test_entrypoint_ai_settings.py | 23 +++++++++++++++++++ 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/containers/base/entrypoint.sh b/containers/base/entrypoint.sh index 860f0a3c..aca5829d 100644 --- a/containers/base/entrypoint.sh +++ b/containers/base/entrypoint.sh @@ -391,7 +391,7 @@ devbase_seed_entry() { # 失われる。gcloud / gws はシード元が存在しないため対象外 (AC8)。 devbase_seed_group_settings() { local ai_root="$1" group_root="$2" group="$3" - local entry + local entry home_seed_entry skip if [ "$group" != "default" ]; then return 0 @@ -399,6 +399,16 @@ devbase_seed_group_settings() { echo "Seeding account group '${group}' from ${ai_root} (first run only)..." for entry in "${DEVBASE_GROUP_SETTINGS[@]}"; do + # ホームから取り込むエントリには /persistent/ai 側の旧保存先が無い。 + # 専用のホームシードへ任せ、存在しないシード元を試行しない。 + skip=0 + for home_seed_entry in "${DEVBASE_GROUP_HOME_SEED_SETTINGS[@]}"; do + if [ "$entry" = "$home_seed_entry" ]; then + skip=1 + break + fi + done + [ "$skip" = "1" ] && continue if [ "$entry" = ".claude" ]; then devbase_seed_entry "$ai_root/$entry" "$group_root/$entry" \ "${DEVBASE_SHARED_CLAUDE_SETTINGS[@]}" @@ -442,6 +452,9 @@ devbase_setup_ai_settings() { devbase_seed_image_claude_settings "$home_root" "$ai_root" devbase_seed_group_settings "$ai_root" "$group_root" "$group" for entry in "${DEVBASE_GROUP_HOME_SEED_SETTINGS[@]}"; do + # 既存リンクは以前選択したグループを指す可能性がある。リンク先を辿って + # 新しいグループへ認証状態をコピーしてはならない。 + [ -L "$home_root/$entry" ] && continue devbase_seed_entry "$home_root/$entry" "$group_root/$entry" done diff --git a/containers/base/tmux.conf b/containers/base/tmux.conf index 662bd016..c5824a8f 100644 --- a/containers/base/tmux.conf +++ b/containers/base/tmux.conf @@ -9,8 +9,8 @@ # その履歴へ実質的に手が届かないため、以下を既定にする。 # ホイール操作を tmux へ渡す。転がすと自動で copy-mode に入り履歴を遡れる。 -# 選択してボタンを離せば OSC 52 でクリップボードへ入る (set-clipboard の既定は -# external)。ペインをまたいで選択したいときは Shift + ドラッグで端末側の選択に戻る。 +# ドラッグ終了後も選択を保持し、Ctrl+C で OSC 52 経由のクリップボードへコピーする。 +# ペインをまたいで選択したいときは Shift + ドラッグで端末側の選択に戻る。 set -g mouse on # Windows の選択操作に近づける。ドラッグ終了時には選択を残し、Ctrl+C でコピーする。 diff --git a/issues/kiro-auth-persistence.md b/issues/kiro-auth-persistence.md index cfe87420..9667f100 100644 --- a/issues/kiro-auth-persistence.md +++ b/issues/kiro-auth-persistence.md @@ -9,10 +9,12 @@ standard: コンテナ再生成後の Kiro CLI 認証保持という本番挙動 達成したい状態: - Kiro CLI 2.20.1 が `~/.local/share/kiro-cli` に保存する状態を、アカウントグループ単位の named volume に保持する。 - 初回適用時にホーム側に既存データがあれば、削除せず永続領域へコピーする。 +- tmux の履歴をマウスで遡り、ドラッグ選択を保持して `Ctrl+C` でコピーできる。 やらないこと: - Kiro CLI の認証方式やログイン操作は変更しない。 - Kiro CLI のキャッシュと認証情報を分離しない(CLI が同じディレクトリで管理しているため)。 +- `Ctrl+Home` のキー割り当ては追加しない(VS Code / Windows 側の操作と競合するため)。 ## 受け入れ条件 @@ -20,6 +22,9 @@ standard: コンテナ再生成後の Kiro CLI 認証保持という本番挙動 - [x] ホーム側に既存の Kiro CLI データがある初回起動では、そのデータがグループ volume にコピーされる。 - [x] 2 回目以降の起動で、グループ volume の新しいデータが古いホーム側データで上書きされない。 - [x] 異なるアカウントグループ間で Kiro CLI の状態が共有されない。 +- [x] 同一ホームでグループを切り替えても、既存 symlink 経由で前グループの状態をコピーしない。 +- [x] tmux のホイール操作で履歴へ入り、履歴上でドラッグした選択範囲がボタンを離しても残る。 +- [x] 選択中の `Ctrl+C` が OSC 52 でコピーし、copy-mode を終了する。 ## 代替案と採否 @@ -40,11 +45,14 @@ standard: コンテナ再生成後の Kiro CLI 認証保持という本番挙動 | --- | --- | --- | | 公開インタフェース | なし | 既存コマンドを変更しない | | 永続データ | Kiro CLI 状態の保存先を追加 | 既存ホームデータを初回のみコピーする | +| tmux 操作 | マウス選択とコピー操作を追加 | `/etc/tmux.conf` の既定値であり、`~/.tmux.conf` で上書きできる | ## 修正対象 - `containers/base/entrypoint.sh` - `tests/containers/test_entrypoint_ai_settings.py` +- `containers/base/tmux.conf` +- `tests/containers/test_tmux_conf.py` - `docs/user/container-operations.md` ## タスク分解 @@ -61,18 +69,28 @@ standard: コンテナ再生成後の Kiro CLI 認証保持という本番挙動 - **満たす受け入れ条件:** 1、4 - **進め方:** 実装と記述の一致を確認する。 +### Task 3: tmux の履歴選択とコピー操作を改善する +- **対象ファイル:** `containers/base/tmux.conf`、tmux テスト、利用者向けドキュメント +- **変更内容:** mouse を有効化し、ドラッグ終了後の選択保持と `Ctrl+C` コピーを両 copy-mode に設定する。 +- **満たす受け入れ条件:** 6、7 +- **進め方:** tmux が解釈したキーテーブルをテストし、稼働中セッションで手動確認する。 + ## リスクと対処 | リスク | 対処 | | --- | --- | | 初回 symlink 化で再ログイン済みデータを失う | リンク作成前に、永続先が空の場合だけ `cp -a` する | | AWS アカウント間で認証が混ざる | 共通 volume ではなく group volume を使う | +| 同一ホームの既存 symlink から前グループの認証状態をコピーする | ホームシード時は symlink を辿らずスキップする | +| tmux のマウス操作がアプリの入力と競合する | 選択開始を copy-mode のキーテーブルに限定し、個人設定で上書き可能にする | ## 切り戻し手順 - entrypoint の対象一覧からパスを外す。コピー済みデータは削除せず残すため、再適用できる。 +- tmux の追加 binding と `mouse on` を外す。利用者の `~/.tmux.conf` は変更しない。 ## 完了の定義 - [x] 受け入れ条件に対応するテストがすべて成功する。 - [x] 全体テストと静的検査が成功する。 +- [x] 稼働中の tmux で履歴スクロール、ドラッグ選択、`Ctrl+C` コピーを確認する。 diff --git a/tests/containers/test_entrypoint_ai_settings.py b/tests/containers/test_entrypoint_ai_settings.py index e8697eb1..70bd8d67 100644 --- a/tests/containers/test_entrypoint_ai_settings.py +++ b/tests/containers/test_entrypoint_ai_settings.py @@ -127,6 +127,29 @@ def test_kiro_cli_data_is_separate_between_groups(roots, tmp_path): assert not (home_b / ".local" / "share" / "kiro-cli" / "identity").exists() +def test_switching_groups_in_the_same_home_does_not_copy_kiro_data(roots, tmp_path): + """既存 symlink 経由で前グループの認証状態を次グループへ移さない。""" + home, ai, group_a = roots + group_b = tmp_path / "persistent" / "kkg" + + setup((home, ai, group_a), "default") + (home / ".local" / "share" / "kiro-cli" / "identity").write_text("default") + + setup((home, ai, group_b), "kkg") + + assert (home / ".local" / "share" / "kiro-cli").resolve() == \ + (group_b / ".local" / "share" / "kiro-cli").resolve() + assert not (group_b / ".local" / "share" / "kiro-cli" / "identity").exists() + + +def test_kiro_home_seed_is_not_attempted_from_shared_volume(roots): + """Kiro 2.x のデータはホーム由来なので /persistent/ai を探索しない。""" + _, ai, _ = roots + result = setup(roots, "default") + + assert f"skip (シード元なし): {ai}/.local/share/kiro-cli" not in result.stdout + + def test_claude_defaults_to_the_group_volume(roots): """``~/.claude`` 配下の既定はグループ側。 From 9b04f2d935f334f9ad215041e12306f65d939b74 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Fri, 4 Sep 2026 09:55:03 +0900 Subject: [PATCH 3/4] =?UTF-8?q?docs:=20=E5=AE=9F=E8=A3=85=E8=A8=88?= =?UTF-8?q?=E7=94=BB=E3=82=92=E7=A2=BA=E5=AE=9A=E4=BB=95=E6=A7=98=E3=81=B8?= =?UTF-8?q?=E7=A7=BB=E8=A1=8C=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kiro-auth-persistence-and-tmux-copy.md | 77 +++++++++++++++ issues/kiro-auth-persistence.md | 96 ------------------- 2 files changed, 77 insertions(+), 96 deletions(-) create mode 100644 docs/specifications/kiro-auth-persistence-and-tmux-copy.md delete mode 100644 issues/kiro-auth-persistence.md diff --git a/docs/specifications/kiro-auth-persistence-and-tmux-copy.md b/docs/specifications/kiro-auth-persistence-and-tmux-copy.md new file mode 100644 index 00000000..baf0d47a --- /dev/null +++ b/docs/specifications/kiro-auth-persistence-and-tmux-copy.md @@ -0,0 +1,77 @@ +# Kiro CLI 認証永続化と tmux コピー操作 + +## 概要 + +devbase コンテナは、Kiro CLI 2.x の認証状態と実行データをアカウントグループ単位で永続化する。 +また、tmux の履歴をマウスで遡り、履歴上の文字列をドラッグ選択して `Ctrl+C` でコピーできる +既定設定を提供する。 + +## 対象範囲 + +- Kiro CLI が `~/.local/share/kiro-cli` に保存する状態 +- base イメージに `/etc/tmux.conf` として配置する tmux の既定設定 +- Kiro CLI のログイン方式と認証方式は変更しない +- `Ctrl+Home` の tmux キー割り当ては定義しない + +## 仕様 + +### Kiro CLI の状態 + +`~/.local/share/kiro-cli` は、現在のアカウントグループに対応する +`/persistent/group/.local/share/kiro-cli` へのシンボリックリンクとする。Kiro CLI の認証状態は +AWS アカウントに紐づくため、全コンテナ共通の `/persistent/ai` には保存しない。 + +初回適用時にホーム側へ既存データがあり、グループ側の保存先がまだ存在しない場合は、リンクを +作成する前に既存データをグループ側へコピーする。グループ側にデータがある場合は上書きせず、 +ホーム側が別グループへのシンボリックリンクである場合もリンク先をシード元として使用しない。 + +常に次の条件を保つ。 + +- 共通 AI 資産は `/persistent/ai`、アカウントに紐づく認証状態は `/persistent/group` に置く。 +- 既存の永続データを起動時のシードで上書きしない。 +- 異なるアカウントグループ間で Kiro CLI の状態を共有しない。 + +### tmux の履歴選択とコピー + +base イメージの tmux は `mouse on` を既定とし、マウスホイールで copy-mode に入って履歴を +遡れるようにする。copy-mode と copy-mode-vi の双方で、履歴上のドラッグ開始時に新しい選択を +開始し、ボタンを離した後も選択範囲を保持する。 + +選択中の `Ctrl+C` は `copy-selection-and-cancel` を実行する。tmux は選択内容を OSC 52 経由で +端末のクリップボードへ送り、copy-mode を終了する。コピーせずに選択を終了する場合は `q` を +使用する。ペインをまたぐ端末側の選択には `Shift` + ドラッグを使用する。 + +`Ctrl+Home` は VS Code や Windows 側の操作と競合するため、tmux では割り当てない。 + +## データ・設定 + +| 対象 | 保存先または設定 | 共有範囲 | +| --- | --- | --- | +| Kiro CLI 2.x | `/persistent/group/.local/share/kiro-cli` | 同じアカウントグループ | +| tmux 既定設定 | `/etc/tmux.conf` | base イメージから作成したコンテナ | + +tmux は `/etc/tmux.conf` の後に `~/.tmux.conf` を読むため、利用者は個人設定で既定値を上書き +できる。`~/.tmux.conf` 自体は永続化対象ではない。 + +## 運用 + +- Kiro CLI の状態はコンテナを再作成しても同じグループ volume に残る。 +- アカウントグループを切り替えると、新しいグループの保存先へリンクを張り直す。 +- tmux 設定の変更はイメージ再ビルドとコンテナ再作成後に適用される。稼働中セッションには + `tmux source-file /etc/tmux.conf` で読み込める。 +- 永続化を切り戻す場合も、コピー済みの Kiro CLI データは削除しない。 + +## テスト観点 + +- Kiro CLI のホームパスがグループ volume へのシンボリックリンクになること。 +- 初回の既存ホームデータを保存し、既存のグループデータを上書きしないこと。 +- グループ間および同一ホームでのグループ切り替え時に状態が混ざらないこと。 +- Kiro CLI のホーム由来データを `/persistent/ai` からシードしようとしないこと。 +- tmux が `mouse on` を解釈し、両copy-modeでドラッグ選択保持と `Ctrl+C` コピーを提供すること。 +- `Ctrl+Home` のbindingが追加されていないこと。 +- `~/.tmux.conf` が `/etc/tmux.conf` の既定値を上書きできること。 + +## 関連リンク + +- [コンテナ操作ガイド](../user/container-operations.md) + diff --git a/issues/kiro-auth-persistence.md b/issues/kiro-auth-persistence.md deleted file mode 100644 index 9667f100..00000000 --- a/issues/kiro-auth-persistence.md +++ /dev/null @@ -1,96 +0,0 @@ -# Kiro CLI 認証情報の永続化 - -## モード - -standard: コンテナ再生成後の Kiro CLI 認証保持という本番挙動を修正する。 - -## 目的と非目的 - -達成したい状態: -- Kiro CLI 2.20.1 が `~/.local/share/kiro-cli` に保存する状態を、アカウントグループ単位の named volume に保持する。 -- 初回適用時にホーム側に既存データがあれば、削除せず永続領域へコピーする。 -- tmux の履歴をマウスで遡り、ドラッグ選択を保持して `Ctrl+C` でコピーできる。 - -やらないこと: -- Kiro CLI の認証方式やログイン操作は変更しない。 -- Kiro CLI のキャッシュと認証情報を分離しない(CLI が同じディレクトリで管理しているため)。 -- `Ctrl+Home` のキー割り当ては追加しない(VS Code / Windows 側の操作と競合するため)。 - -## 受け入れ条件 - -- [x] `~/.local/share/kiro-cli` が `/persistent/group/.local/share/kiro-cli` を指す symlink になる。 -- [x] ホーム側に既存の Kiro CLI データがある初回起動では、そのデータがグループ volume にコピーされる。 -- [x] 2 回目以降の起動で、グループ volume の新しいデータが古いホーム側データで上書きされない。 -- [x] 異なるアカウントグループ間で Kiro CLI の状態が共有されない。 -- [x] 同一ホームでグループを切り替えても、既存 symlink 経由で前グループの状態をコピーしない。 -- [x] tmux のホイール操作で履歴へ入り、履歴上でドラッグした選択範囲がボタンを離しても残る。 -- [x] 選択中の `Ctrl+C` が OSC 52 でコピーし、copy-mode を終了する。 - -## 代替案と採否 - -| 内容 | 採否 | 理由 | -| --- | --- | --- | -| `/persistent/group` へ symlink | 採用 | Kiro の認証状態は AWS アカウントに紐づくため | -| `/persistent/ai` へ symlink | 不採用 | 全アカウントグループで認証状態が共有されるため | -| `~/.local/share` 全体を永続化 | 不採用 | Kiro と無関係なツールのデータまで共有・永続化するため | - -## 不変条件 - -- 共通 AI 資産は `/persistent/ai`、アカウントに紐づく認証状態は `/persistent/group` に置く。 -- 既存の永続データを起動時のシードで上書きしない。 - -## 互換性 - -| 対象 | 変更 | 互換性の扱い | -| --- | --- | --- | -| 公開インタフェース | なし | 既存コマンドを変更しない | -| 永続データ | Kiro CLI 状態の保存先を追加 | 既存ホームデータを初回のみコピーする | -| tmux 操作 | マウス選択とコピー操作を追加 | `/etc/tmux.conf` の既定値であり、`~/.tmux.conf` で上書きできる | - -## 修正対象 - -- `containers/base/entrypoint.sh` -- `tests/containers/test_entrypoint_ai_settings.py` -- `containers/base/tmux.conf` -- `tests/containers/test_tmux_conf.py` -- `docs/user/container-operations.md` - -## タスク分解 - -### Task 1: Kiro CLI 状態を安全に永続化する -- **対象ファイル:** entrypoint とそのテスト -- **変更内容:** 入れ子パスをグループ設定へ追加し、既存ホームデータを初回のみシードする。 -- **満たす受け入れ条件:** 1〜4 -- **進め方:** 失敗するテスト → 最小実装 → 回帰テスト - -### Task 2: 永続化対象を文書化する -- **対象ファイル:** `docs/user/container-operations.md` -- **変更内容:** Kiro CLI の新しい保存先と共有範囲を追記する。 -- **満たす受け入れ条件:** 1、4 -- **進め方:** 実装と記述の一致を確認する。 - -### Task 3: tmux の履歴選択とコピー操作を改善する -- **対象ファイル:** `containers/base/tmux.conf`、tmux テスト、利用者向けドキュメント -- **変更内容:** mouse を有効化し、ドラッグ終了後の選択保持と `Ctrl+C` コピーを両 copy-mode に設定する。 -- **満たす受け入れ条件:** 6、7 -- **進め方:** tmux が解釈したキーテーブルをテストし、稼働中セッションで手動確認する。 - -## リスクと対処 - -| リスク | 対処 | -| --- | --- | -| 初回 symlink 化で再ログイン済みデータを失う | リンク作成前に、永続先が空の場合だけ `cp -a` する | -| AWS アカウント間で認証が混ざる | 共通 volume ではなく group volume を使う | -| 同一ホームの既存 symlink から前グループの認証状態をコピーする | ホームシード時は symlink を辿らずスキップする | -| tmux のマウス操作がアプリの入力と競合する | 選択開始を copy-mode のキーテーブルに限定し、個人設定で上書き可能にする | - -## 切り戻し手順 - -- entrypoint の対象一覧からパスを外す。コピー済みデータは削除せず残すため、再適用できる。 -- tmux の追加 binding と `mouse on` を外す。利用者の `~/.tmux.conf` は変更しない。 - -## 完了の定義 - -- [x] 受け入れ条件に対応するテストがすべて成功する。 -- [x] 全体テストと静的検査が成功する。 -- [x] 稼働中の tmux で履歴スクロール、ドラッグ選択、`Ctrl+C` コピーを確認する。 From 45467d28e19689e8c6157103179769a8ca862329 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Fri, 4 Sep 2026 09:58:36 +0900 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=E4=BB=95=E6=A7=98=E6=9B=B8?= =?UTF-8?q?=E3=81=AE=E6=9C=AB=E5=B0=BE=E3=82=92=E6=95=B4=E3=81=88=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/specifications/kiro-auth-persistence-and-tmux-copy.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/specifications/kiro-auth-persistence-and-tmux-copy.md b/docs/specifications/kiro-auth-persistence-and-tmux-copy.md index baf0d47a..24247358 100644 --- a/docs/specifications/kiro-auth-persistence-and-tmux-copy.md +++ b/docs/specifications/kiro-auth-persistence-and-tmux-copy.md @@ -74,4 +74,3 @@ tmux は `/etc/tmux.conf` の後に `~/.tmux.conf` を読むため、利用者 ## 関連リンク - [コンテナ操作ガイド](../user/container-operations.md) -