ring-cli 0.10.0__tar.gz → 0.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {ring_cli-0.10.0 → ring_cli-0.11.1}/PKG-INFO +27 -2
  2. {ring_cli-0.10.0 → ring_cli-0.11.1}/README.en.md +26 -1
  3. {ring_cli-0.10.0 → ring_cli-0.11.1}/pyproject.toml +1 -1
  4. ring_cli-0.11.1/src/ring/locale/en/LC_MESSAGES/ring.mo +0 -0
  5. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/locale/en/LC_MESSAGES/ring.po +42 -0
  6. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/locale/ring.pot +111 -42
  7. ring_cli-0.11.1/src/ring/permission.py +334 -0
  8. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/registry.py +137 -19
  9. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/sources/__init__.py +5 -0
  10. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/tui.py +152 -3
  11. ring_cli-0.10.0/src/ring/locale/en/LC_MESSAGES/ring.mo +0 -0
  12. {ring_cli-0.10.0 → ring_cli-0.11.1}/LICENSE +0 -0
  13. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/__init__.py +0 -0
  14. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/__main__.py +0 -0
  15. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/cli.py +0 -0
  16. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/__init__.py +0 -0
  17. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/_args.py +0 -0
  18. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/completion.py +0 -0
  19. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/digest.py +0 -0
  20. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/doctor.py +0 -0
  21. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/focus.py +0 -0
  22. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/gc.py +0 -0
  23. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/hook.py +0 -0
  24. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/commands/stats.py +0 -0
  25. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/config.py +0 -0
  26. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/__init__.py +0 -0
  27. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/applescript.py +0 -0
  28. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/base.py +0 -0
  29. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/iterm2.py +0 -0
  30. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/linux_wm.py +0 -0
  31. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/neovim.py +0 -0
  32. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/terminal.py +0 -0
  33. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/focus/tmux.py +0 -0
  34. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/gc.py +0 -0
  35. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/hook.py +0 -0
  36. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/hook_protocol.py +0 -0
  37. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/i18n.py +0 -0
  38. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/ipc.py +0 -0
  39. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/labels.py +0 -0
  40. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/__init__.py +0 -0
  41. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/base.py +0 -0
  42. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/command.py +0 -0
  43. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/notify_send.py +0 -0
  44. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/ntfy.py +0 -0
  45. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/osascript_notifier.py +0 -0
  46. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/terminal_notifier.py +0 -0
  47. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/notify/webhook.py +0 -0
  48. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/osascript.py +0 -0
  49. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/plugins.py +0 -0
  50. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/sources/base.py +0 -0
  51. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/sources/claude_code.py +0 -0
  52. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/sources/codex.py +0 -0
  53. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/sources/hook_registry.py +0 -0
  54. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/stats.py +0 -0
  55. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/transcript.py +0 -0
  56. {ring_cli-0.10.0 → ring_cli-0.11.1}/src/ring/watcher.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ring-cli
3
- Version: 0.10.0
3
+ Version: 0.11.1
4
4
  Summary: RiNG — Realtime Instance Notification Grid for active agent CLI sessions.
5
5
  Keywords: claude-code,codex,tui,dashboard,session,monitor,rich
6
6
  Author: Wei Lee
@@ -59,6 +59,7 @@ RiNG puts them on one board, with sessions waiting for you sorted first.
59
59
  - **Waiting first**: sessions that need your response are highlighted and sorted above the rest.
60
60
  - **Jump back to the terminal**: in the TUI, select a session and press `Enter` / `Space` to focus tmux, iTerm2, Terminal.app (macOS), or a Linux X11 window (`wmctrl`).
61
61
  - **Notifies you without the board open**: with hooks installed, the moment a session turns 🔴 waiting it beeps and fires a system notification — even with no RiNG board running. With `terminal-notifier`, clicking the notification jumps back.
62
+ - **Reply to permission requests in place**: with the cursor on a 🔴 waiting row, press `p` — RiNG reads the permission dialog from that session's terminal screen, pops the numbered options in a modal, and presses your choice for you, so you don't have to jump over one by one (sessions inside tmux, plus plain iTerm2 tabs on macOS).
62
63
  - **Name your sessions**: press `n` in the TUI to name a session, e.g. "auth refactor"; once named, the board and notifications show the name instead of the workspace directory.
63
64
  - **See what it is waiting for**: in hook mode, a 🔴 waiting session carries the concrete pending item (the command to run, the question asked) — shown in the TUI and in the notification body.
64
65
  - **Fits your status bar**: `ring --format oneline` prints a `🔴2 🟢1 🟡3` one-liner for tmux / SwiftBar / waybar; `--format json` feeds scripts.
@@ -153,7 +154,7 @@ Completes subcommands, flags, and `config set` keys; `ring focus` prompts for a
153
154
  ## Watch Mode
154
155
 
155
156
  - With **Textual** (`[tui]` extra) in a real terminal: interactive TUI.
156
- Use `↑/↓` to select, `Enter` / `Space` to jump, `n` to name a session, `a` to toggle ended sessions, `dd` to hide a session (it reappears automatically once it has new activity), `r` to refresh, and `q` to quit.
157
+ Use `↑/↓` to select, `Enter` / `Space` to jump, `p` to reply to a permission request in place, `n` to name a session, `a` to toggle ended sessions, `dd` to hide a session (it reappears automatically once it has new activity), `r` to refresh, and `q` to quit.
157
158
  If you have vim muscle memory like I do, `j/k` move up/down and `g/G` jump to the first/last row.
158
159
  When the selected row is 🔴 waiting, a line under the table shows **what it is concretely waiting for** (the command to run, the question asked; hook mode only).
159
160
  - Otherwise: Rich polling; without Rich, plain text.
@@ -172,6 +173,30 @@ hands the request to the TUI so it selects that session; otherwise it focuses th
172
173
  TTY matching is most accurate in hook mode. Without hooks, Codex falls back to zero-config matching:
173
174
  one live Codex session per cwd can jump correctly; multiple live Codex sessions in the same cwd are shown conservatively to avoid focusing the wrong tab.
174
175
 
176
+ ### Reply To Permission Requests In Place (`p`)
177
+
178
+ With the cursor on a 🔴 waiting row, press `p`. RiNG reads that session's screen, parses the
179
+ permission dialog (Claude Code's "Do you want to proceed?" box, including background-subagent
180
+ ones with a "from the … agent" header), and lists the numbered options verbatim in a modal.
181
+ After you pick one, RiNG **captures the screen again** to confirm the dialog is still there and
182
+ unchanged (it may have been answered while you were deciding), only then sends that single
183
+ digit, and re-checks that the dialog actually disappeared.
184
+
185
+ - **Sessions inside tmux**: reads the screen with `tmux capture-pane` and sends keys with
186
+ `tmux send-keys`.
187
+ - **Sessions in a plain iTerm2 tab on macOS** (no tmux): locates the matching iTerm2 session by
188
+ its `tty` via AppleScript, and both reads the screen and sends keys through `osascript`. The
189
+ first use triggers the macOS Automation permission prompt ("allow control of iTerm2") — allow
190
+ it once.
191
+
192
+ Safety first: if no recognizable dialog can be parsed (missing markers, numbering, or cursor),
193
+ RiNG only shows a toast and **never sends a key** — without the dialog, keystrokes would land in
194
+ the chat input box as text. If the dialog happens to vanish in the instant the digit is sent and
195
+ the digit lands in the input box, RiNG sends a Backspace to clean it up and warns you.
196
+
197
+ **Limits**: reading the screen requires a tmux pane coordinate, or (on macOS) an iTerm2 session
198
+ with a detectable tty; for other sessions, press `Enter` to jump over and reply there.
199
+
175
200
  ### Notifications
176
201
 
177
202
  Default behavior: with hooks installed, the moment a session changes to 🔴 waiting, the hook beeps
@@ -34,6 +34,7 @@ RiNG puts them on one board, with sessions waiting for you sorted first.
34
34
  - **Waiting first**: sessions that need your response are highlighted and sorted above the rest.
35
35
  - **Jump back to the terminal**: in the TUI, select a session and press `Enter` / `Space` to focus tmux, iTerm2, Terminal.app (macOS), or a Linux X11 window (`wmctrl`).
36
36
  - **Notifies you without the board open**: with hooks installed, the moment a session turns 🔴 waiting it beeps and fires a system notification — even with no RiNG board running. With `terminal-notifier`, clicking the notification jumps back.
37
+ - **Reply to permission requests in place**: with the cursor on a 🔴 waiting row, press `p` — RiNG reads the permission dialog from that session's terminal screen, pops the numbered options in a modal, and presses your choice for you, so you don't have to jump over one by one (sessions inside tmux, plus plain iTerm2 tabs on macOS).
37
38
  - **Name your sessions**: press `n` in the TUI to name a session, e.g. "auth refactor"; once named, the board and notifications show the name instead of the workspace directory.
38
39
  - **See what it is waiting for**: in hook mode, a 🔴 waiting session carries the concrete pending item (the command to run, the question asked) — shown in the TUI and in the notification body.
39
40
  - **Fits your status bar**: `ring --format oneline` prints a `🔴2 🟢1 🟡3` one-liner for tmux / SwiftBar / waybar; `--format json` feeds scripts.
@@ -128,7 +129,7 @@ Completes subcommands, flags, and `config set` keys; `ring focus` prompts for a
128
129
  ## Watch Mode
129
130
 
130
131
  - With **Textual** (`[tui]` extra) in a real terminal: interactive TUI.
131
- Use `↑/↓` to select, `Enter` / `Space` to jump, `n` to name a session, `a` to toggle ended sessions, `dd` to hide a session (it reappears automatically once it has new activity), `r` to refresh, and `q` to quit.
132
+ Use `↑/↓` to select, `Enter` / `Space` to jump, `p` to reply to a permission request in place, `n` to name a session, `a` to toggle ended sessions, `dd` to hide a session (it reappears automatically once it has new activity), `r` to refresh, and `q` to quit.
132
133
  If you have vim muscle memory like I do, `j/k` move up/down and `g/G` jump to the first/last row.
133
134
  When the selected row is 🔴 waiting, a line under the table shows **what it is concretely waiting for** (the command to run, the question asked; hook mode only).
134
135
  - Otherwise: Rich polling; without Rich, plain text.
@@ -147,6 +148,30 @@ hands the request to the TUI so it selects that session; otherwise it focuses th
147
148
  TTY matching is most accurate in hook mode. Without hooks, Codex falls back to zero-config matching:
148
149
  one live Codex session per cwd can jump correctly; multiple live Codex sessions in the same cwd are shown conservatively to avoid focusing the wrong tab.
149
150
 
151
+ ### Reply To Permission Requests In Place (`p`)
152
+
153
+ With the cursor on a 🔴 waiting row, press `p`. RiNG reads that session's screen, parses the
154
+ permission dialog (Claude Code's "Do you want to proceed?" box, including background-subagent
155
+ ones with a "from the … agent" header), and lists the numbered options verbatim in a modal.
156
+ After you pick one, RiNG **captures the screen again** to confirm the dialog is still there and
157
+ unchanged (it may have been answered while you were deciding), only then sends that single
158
+ digit, and re-checks that the dialog actually disappeared.
159
+
160
+ - **Sessions inside tmux**: reads the screen with `tmux capture-pane` and sends keys with
161
+ `tmux send-keys`.
162
+ - **Sessions in a plain iTerm2 tab on macOS** (no tmux): locates the matching iTerm2 session by
163
+ its `tty` via AppleScript, and both reads the screen and sends keys through `osascript`. The
164
+ first use triggers the macOS Automation permission prompt ("allow control of iTerm2") — allow
165
+ it once.
166
+
167
+ Safety first: if no recognizable dialog can be parsed (missing markers, numbering, or cursor),
168
+ RiNG only shows a toast and **never sends a key** — without the dialog, keystrokes would land in
169
+ the chat input box as text. If the dialog happens to vanish in the instant the digit is sent and
170
+ the digit lands in the input box, RiNG sends a Backspace to clean it up and warns you.
171
+
172
+ **Limits**: reading the screen requires a tmux pane coordinate, or (on macOS) an iTerm2 session
173
+ with a detectable tty; for other sessions, press `Enter` to jump over and reply there.
174
+
150
175
  ### Notifications
151
176
 
152
177
  Default behavior: with hooks installed, the moment a session changes to 🔴 waiting, the hook beeps
@@ -2,7 +2,7 @@
2
2
  # import 的 module(見 [tool.uv.build-backend] module-name)與 CLI 指令仍是 `ring`。
3
3
  [project]
4
4
  name = "ring-cli"
5
- version = "0.10.0"
5
+ version = "0.11.1"
6
6
  description = "RiNG — Realtime Instance Notification Grid for active agent CLI sessions."
7
7
  readme = "README.en.md"
8
8
  requires-python = ">=3.13"
@@ -161,6 +161,9 @@ msgstr "terminal tab not found (it may have been closed; if it still appears aft
161
161
  msgid "沒有 focuser 接得住(裝 hook,或一個專案只開一個 session 才測得到 tty)"
162
162
  msgstr "no focuser handled it (install hooks, or keep one session per project so tty is detectable)"
163
163
 
164
+ msgid "背景 agent,沒有終端可跳;用 `claude --resume {session_id}` 接回"
165
+ msgstr "background agent, no terminal to jump to; reconnect with `claude --resume {session_id}`"
166
+
164
167
  # ── install-hooks ──
165
168
  msgid "⚠️ {path} 不是合法 JSON,先處理它再來。"
166
169
  msgstr "⚠️ {path} is not valid JSON; fix it first."
@@ -653,3 +656,42 @@ msgstr "total wait"
653
656
 
654
657
  msgid "⚠️ 其中 {n} 段還在 🔴 等你(計到現在為止)。"
655
658
  msgstr "⚠️ {n} of these are still 🔴 waiting for you (counted up to now)."
659
+
660
+ msgid "回覆權限"
661
+ msgstr "reply perm"
662
+
663
+ msgid "回覆 {project} 的權限請求"
664
+ msgstr "Reply to the permission request from {project}"
665
+
666
+ msgid "Enter 或數字鍵送出、Esc 取消"
667
+ msgstr "Enter or a digit key sends, Esc cancels"
668
+
669
+ msgid "{project}:沒有 tmux 座標,且非 macOS 上的 iTerm2 session,無法就地回覆"
670
+ msgstr "{project}: no tmux coordinates, and not a macOS iTerm2 session either — cannot reply in place"
671
+
672
+ msgid "{project}:讀不到 {backend} 畫面"
673
+ msgstr "{project}: cannot read the {backend} screen"
674
+
675
+ msgid "{project}:畫面上沒有可辨識的權限對話框,未送出任何按鍵"
676
+ msgstr "{project}: no recognizable permission dialog on screen; no key was sent"
677
+
678
+ msgid "→ {project}:已回覆權限({option})"
679
+ msgstr "→ {project}: permission answered ({option})"
680
+
681
+ msgid "{project}:權限對話框已不在,未送出任何按鍵"
682
+ msgstr "{project}: the permission dialog is gone; no key was sent"
683
+
684
+ msgid "{project}:對話框內容已變化,未送出;請再按一次 p"
685
+ msgstr "{project}: the dialog changed; nothing sent — press p again"
686
+
687
+ msgid "{project}:tmux send-keys 失敗,沒能回覆"
688
+ msgstr "{project}: tmux send-keys failed; could not reply"
689
+
690
+ msgid "{project}:已送出但對話框還在,請跳過去確認"
691
+ msgstr "{project}: key sent but the dialog is still there — jump over to check"
692
+
693
+ msgid "{project}:對話框已不在,數字落進輸入框,已補 Backspace 清掉"
694
+ msgstr "{project}: the dialog was gone and the digit landed in the input box — sent Backspace to clean it up"
695
+
696
+ msgid "{project}:已送出但拿不到畫面驗證,請跳過去確認"
697
+ msgstr "{project}: key sent but the screen could not be re-read to verify — jump over to check"
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PROJECT VERSION\n"
10
10
  "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11
- "POT-Creation-Date: 2026-07-10 15:32+0800\n"
11
+ "POT-Creation-Date: 2026-07-12 09:22+0800\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -52,7 +52,7 @@ msgstr[1] ""
52
52
  msgid "🎤 RiNG — {sess} · {proc}"
53
53
  msgstr ""
54
54
 
55
- #: src/ring/cli.py:163 src/ring/cli.py:216 src/ring/tui.py:213
55
+ #: src/ring/cli.py:163 src/ring/cli.py:216 src/ring/tui.py:279
56
56
  msgid "圖例"
57
57
  msgstr ""
58
58
 
@@ -63,32 +63,32 @@ msgstr ""
63
63
  #: src/ring/cli.py:184 src/ring/cli.py:338 src/ring/commands/doctor.py:31
64
64
  #: src/ring/commands/doctor.py:68 src/ring/commands/doctor.py:70
65
65
  #: src/ring/commands/doctor.py:72 src/ring/commands/doctor.py:134
66
- #: src/ring/tui.py:168
66
+ #: src/ring/tui.py:234
67
67
  msgid "狀態"
68
68
  msgstr ""
69
69
 
70
- #: src/ring/cli.py:186 src/ring/cli.py:235 src/ring/tui.py:170
70
+ #: src/ring/cli.py:186 src/ring/cli.py:235 src/ring/tui.py:236
71
71
  msgid "工具"
72
72
  msgstr ""
73
73
 
74
74
  #: src/ring/cli.py:187 src/ring/cli.py:235 src/ring/commands/stats.py:60
75
- #: src/ring/tui.py:171
75
+ #: src/ring/tui.py:237
76
76
  msgid "專案"
77
77
  msgstr ""
78
78
 
79
- #: src/ring/cli.py:188 src/ring/cli.py:235 src/ring/tui.py:171
79
+ #: src/ring/cli.py:188 src/ring/cli.py:235 src/ring/tui.py:237
80
80
  msgid "進度"
81
81
  msgstr ""
82
82
 
83
- #: src/ring/cli.py:189 src/ring/cli.py:235 src/ring/tui.py:171
83
+ #: src/ring/cli.py:189 src/ring/cli.py:235 src/ring/tui.py:237
84
84
  msgid "閒置"
85
85
  msgstr ""
86
86
 
87
- #: src/ring/cli.py:190 src/ring/cli.py:235 src/ring/tui.py:171
87
+ #: src/ring/cli.py:190 src/ring/cli.py:235 src/ring/tui.py:237
88
88
  msgid "去哪"
89
89
  msgstr ""
90
90
 
91
- #: src/ring/cli.py:192 src/ring/cli.py:235 src/ring/tui.py:171
91
+ #: src/ring/cli.py:192 src/ring/cli.py:235 src/ring/tui.py:237
92
92
  msgid "動作"
93
93
  msgstr ""
94
94
 
@@ -305,41 +305,41 @@ msgstr ""
305
305
  msgid "重開 Codex session、並在它詢問時「信任」這個 hook,🔴 等你狀態才會精準起來(Codex 不會執行未信任的 hook)。"
306
306
  msgstr ""
307
307
 
308
- #: src/ring/hook.py:406
308
+ #: src/ring/hook.py:438
309
309
  #, python-brace-format
310
310
  msgid "⚠️ 偵測到其他工具也掛在 {events}:{cmds}"
311
311
  msgstr ""
312
312
 
313
- #: src/ring/hook.py:407
313
+ #: src/ring/hook.py:439
314
314
  msgid "它們會跟 RiNG 的通知重複觸發;要完全改用 RiNG,建議移除它們。"
315
315
  msgstr ""
316
316
 
317
- #: src/ring/hook.py:455 src/ring/hook.py:531
317
+ #: src/ring/hook.py:487 src/ring/hook.py:563
318
318
  #, python-brace-format
319
319
  msgid "⚠️ {path} 不是合法 JSON,先處理它再來。"
320
320
  msgstr ""
321
321
 
322
- #: src/ring/hook.py:493
322
+ #: src/ring/hook.py:525
323
323
  #, python-brace-format
324
324
  msgid "✅ RiNG hooks 已經裝過了,沒有變更。({path})"
325
325
  msgstr ""
326
326
 
327
- #: src/ring/hook.py:506
327
+ #: src/ring/hook.py:538
328
328
  #, python-brace-format
329
329
  msgid "✅ 已註冊 RiNG hooks({events})到 {path}"
330
330
  msgstr ""
331
331
 
332
- #: src/ring/hook.py:525
332
+ #: src/ring/hook.py:557
333
333
  #, python-brace-format
334
334
  msgid "ℹ️ {path} 不存在,沒有可移除的 hook。"
335
335
  msgstr ""
336
336
 
337
- #: src/ring/hook.py:552
337
+ #: src/ring/hook.py:584
338
338
  #, python-brace-format
339
339
  msgid "ℹ️ 沒有找到 RiNG hook 條目,無需移除。({path})"
340
340
  msgstr ""
341
341
 
342
- #: src/ring/hook.py:556
342
+ #: src/ring/hook.py:588
343
343
  #, python-brace-format
344
344
  msgid "✅ 已移除 RiNG hooks({events})從 {path}"
345
345
  msgstr ""
@@ -349,103 +349,172 @@ msgstr ""
349
349
  msgid "⚠️ ring plugin '{name}' 載入失敗:{error}"
350
350
  msgstr ""
351
351
 
352
- #: src/ring/tui.py:88
352
+ #: src/ring/tui.py:51
353
+ #, python-brace-format
354
+ msgid "背景 agent,沒有終端可跳;用 `claude --resume {session_id}` 接回"
355
+ msgstr ""
356
+
357
+ #: src/ring/tui.py:96
353
358
  #, python-brace-format
354
359
  msgid "為 {project} 命名(Enter 存、Esc 取消、清空移除)"
355
360
  msgstr ""
356
361
 
357
- #: src/ring/tui.py:89
362
+ #: src/ring/tui.py:97
358
363
  msgid "這個 session 在做什麼…"
359
364
  msgstr ""
360
365
 
361
- #: src/ring/tui.py:106
366
+ #: src/ring/tui.py:141
367
+ #, python-brace-format
368
+ msgid "回覆 {project} 的權限請求"
369
+ msgstr ""
370
+
371
+ #: src/ring/tui.py:146
372
+ msgid "Enter 或數字鍵送出、Esc 取消"
373
+ msgstr ""
374
+
375
+ #: src/ring/tui.py:169
362
376
  msgid "離場"
363
377
  msgstr ""
364
378
 
365
- #: src/ring/tui.py:107
379
+ #: src/ring/tui.py:170
366
380
  msgid "刷新"
367
381
  msgstr ""
368
382
 
369
- #: src/ring/tui.py:108
383
+ #: src/ring/tui.py:171
370
384
  msgid "含已離場"
371
385
  msgstr ""
372
386
 
373
- #: src/ring/tui.py:109
387
+ #: src/ring/tui.py:172
374
388
  msgid "命名"
375
389
  msgstr ""
376
390
 
377
- #: src/ring/tui.py:110
391
+ #: src/ring/tui.py:173
378
392
  msgid "隱藏"
379
393
  msgstr ""
380
394
 
381
- #: src/ring/tui.py:111
395
+ #: src/ring/tui.py:174
382
396
  msgid "最久等待"
383
397
  msgstr ""
384
398
 
385
- #: src/ring/tui.py:112 src/ring/tui.py:113
399
+ #: src/ring/tui.py:175
400
+ msgid "回覆權限"
401
+ msgstr ""
402
+
403
+ #: src/ring/tui.py:176 src/ring/tui.py:177
386
404
  msgid "跳過去"
387
405
  msgstr ""
388
406
 
389
- #: src/ring/tui.py:189
407
+ #: src/ring/tui.py:255
390
408
  msgid "💡 同專案開了多個 session,裝 hook 跳轉才精準:ring install-hooks"
391
409
  msgstr ""
392
410
 
393
- #: src/ring/tui.py:191
411
+ #: src/ring/tui.py:257
394
412
  msgid "↑/↓ 選一列,Enter 或 Space 跳到那個 session 的終端"
395
413
  msgstr ""
396
414
 
397
- #: src/ring/tui.py:227
415
+ #: src/ring/tui.py:293
398
416
  #, python-brace-format
399
417
  msgid "🔔 {names} 在等你回話"
400
418
  msgstr ""
401
419
 
402
- #: src/ring/tui.py:268
420
+ #: src/ring/tui.py:334
403
421
  #, python-brace-format
404
422
  msgid "→ 已跳到 {project}(來自通知)"
405
423
  msgstr ""
406
424
 
407
- #: src/ring/tui.py:273
425
+ #: src/ring/tui.py:339
408
426
  msgid "那個 session 已不在場"
409
427
  msgstr ""
410
428
 
411
- #: src/ring/tui.py:332
429
+ #: src/ring/tui.py:400
412
430
  msgid " ⚠ hook 可能失效:來源檔有更新但沒有 heartbeat"
413
431
  msgstr ""
414
432
 
415
- #: src/ring/tui.py:361 src/ring/tui.py:385 src/ring/tui.py:411
433
+ #: src/ring/tui.py:431 src/ring/tui.py:455 src/ring/tui.py:494
434
+ #: src/ring/tui.py:562
416
435
  msgid "(沒有選到 session)"
417
436
  msgstr ""
418
437
 
419
- #: src/ring/tui.py:392
438
+ #: src/ring/tui.py:462 src/ring/tui.py:470 src/ring/tui.py:500
420
439
  #, python-brace-format
421
- msgid "{project}{where}"
440
+ msgid "{project}{msg}"
422
441
  msgstr ""
423
442
 
424
- #: src/ring/tui.py:394
443
+ #: src/ring/tui.py:468
425
444
  #, python-brace-format
426
- msgid "{project}{msg}"
445
+ msgid "{project}{where}"
427
446
  msgstr ""
428
447
 
429
- #: src/ring/tui.py:402
448
+ #: src/ring/tui.py:478
430
449
  msgid "(沒有正在等待的 session)"
431
450
  msgstr ""
432
451
 
433
- #: src/ring/tui.py:419
452
+ #: src/ring/tui.py:504
453
+ #, python-brace-format
454
+ msgid "{project}:沒有 tmux 座標,且非 macOS 上的 iTerm2 session,無法就地回覆"
455
+ msgstr ""
456
+
457
+ #: src/ring/tui.py:511
458
+ #, python-brace-format
459
+ msgid "{project}:讀不到 {backend} 畫面"
460
+ msgstr ""
461
+
462
+ #: src/ring/tui.py:515
463
+ #, python-brace-format
464
+ msgid "{project}:畫面上沒有可辨識的權限對話框,未送出任何按鍵"
465
+ msgstr ""
466
+
467
+ #: src/ring/tui.py:544
468
+ #, python-brace-format
469
+ msgid "→ {project}:已回覆權限({option})"
470
+ msgstr ""
471
+
472
+ #: src/ring/tui.py:548
473
+ #, python-brace-format
474
+ msgid "{project}:權限對話框已不在,未送出任何按鍵"
475
+ msgstr ""
476
+
477
+ #: src/ring/tui.py:549
478
+ #, python-brace-format
479
+ msgid "{project}:對話框內容已變化,未送出;請再按一次 p"
480
+ msgstr ""
481
+
482
+ #: src/ring/tui.py:550
483
+ #, python-brace-format
484
+ msgid "{project}:tmux send-keys 失敗,沒能回覆"
485
+ msgstr ""
486
+
487
+ #: src/ring/tui.py:551
488
+ #, python-brace-format
489
+ msgid "{project}:已送出但對話框還在,請跳過去確認"
490
+ msgstr ""
491
+
492
+ #: src/ring/tui.py:553
493
+ #, python-brace-format
494
+ msgid "{project}:對話框已不在,數字落進輸入框,已補 Backspace 清掉"
495
+ msgstr ""
496
+
497
+ #: src/ring/tui.py:555
498
+ #, python-brace-format
499
+ msgid "{project}:已送出但拿不到畫面驗證,請跳過去確認"
500
+ msgstr ""
501
+
502
+ #: src/ring/tui.py:570
434
503
  #, python-brace-format
435
504
  msgid "再按一次 d 隱藏 {project}(有新活動會自動重新出現)"
436
505
  msgstr ""
437
506
 
438
- #: src/ring/tui.py:424
507
+ #: src/ring/tui.py:575
439
508
  #, python-brace-format
440
509
  msgid "{project} 是仍在執行的 process,無法隱藏;請跳過去結束它"
441
510
  msgstr ""
442
511
 
443
- #: src/ring/tui.py:432
512
+ #: src/ring/tui.py:583
444
513
  #, python-brace-format
445
514
  msgid "已隱藏 {project},並清掉 RiNG 狀態;有新活動會自動重新出現"
446
515
  msgstr ""
447
516
 
448
- #: src/ring/tui.py:434
517
+ #: src/ring/tui.py:585
449
518
  #, python-brace-format
450
519
  msgid "已隱藏 {project}(沒有 RiNG registry 可清;有新活動會自動重新出現)"
451
520
  msgstr ""