clauderipple 0.9.5 → 0.11.0

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 (163) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README.es.md +45 -0
  3. package/README.ja.md +17 -0
  4. package/README.ko.md +31 -0
  5. package/README.md +70 -0
  6. package/README.pt-BR.md +45 -0
  7. package/README.zh-CN.md +17 -0
  8. package/dist/app/assets/icon.icns +0 -0
  9. package/dist/app/assets/icon.ico +0 -0
  10. package/dist/app/assets/icon.png +0 -0
  11. package/dist/app/assets/trayDirectTemplate.png +0 -0
  12. package/dist/app/assets/trayDirectTemplate@2x.png +0 -0
  13. package/dist/app/assets/trayDownTemplate.png +0 -0
  14. package/dist/app/assets/trayDownTemplate@2x.png +0 -0
  15. package/dist/app/assets/trayTemplate.png +0 -0
  16. package/dist/app/assets/trayTemplate@2x.png +0 -0
  17. package/dist/app/assets/trayWarnTemplate.png +0 -0
  18. package/dist/app/assets/trayWarnTemplate@2x.png +0 -0
  19. package/dist/app/assets/trayWin.png +0 -0
  20. package/dist/app/assets/trayWin@2x.png +0 -0
  21. package/dist/app/assets/trayWinDirect.png +0 -0
  22. package/dist/app/assets/trayWinDirect@2x.png +0 -0
  23. package/dist/app/assets/trayWinDown.png +0 -0
  24. package/dist/app/assets/trayWinDown@2x.png +0 -0
  25. package/dist/app/assets/trayWinWarn.png +0 -0
  26. package/dist/app/assets/trayWinWarn@2x.png +0 -0
  27. package/dist/app/dist/claude-desktop.js +67 -0
  28. package/dist/app/dist/main.js +423 -110
  29. package/dist/app/dist/preload.js +21 -0
  30. package/dist/app/dist/protocol.js +121 -0
  31. package/dist/app/dist/status-model.js +87 -0
  32. package/dist/app/dist/window.js +133 -0
  33. package/dist/app/package.json +1 -1
  34. package/dist/cli/src/awake-setup.js +314 -0
  35. package/dist/cli/src/bundle.js +9 -5
  36. package/dist/cli/src/direct.js +159 -0
  37. package/dist/cli/src/doctor.js +205 -0
  38. package/dist/cli/src/hooks/agent-title.js +7 -4
  39. package/dist/cli/src/index.js +227 -31
  40. package/dist/cli/src/launchd.js +29 -20
  41. package/dist/cli/src/launcher.js +215 -0
  42. package/dist/cli/src/power.js +182 -0
  43. package/dist/cli/src/registration.js +157 -0
  44. package/dist/cli/src/remote.js +263 -0
  45. package/dist/cli/src/schtasks.js +50 -40
  46. package/dist/cli/src/settings.js +26 -1
  47. package/dist/cli/src/tray.js +5 -2
  48. package/dist/mod/hooks/i18n.ts +473 -227
  49. package/dist/mod/hooks/judge.ts +35 -17
  50. package/dist/mod/hooks/modes.ts +56 -1
  51. package/dist/mod/hooks/register.tsx +237 -32
  52. package/dist/mod/hooks/session.ts +102 -1
  53. package/dist/mod/hooks/settings.js +7 -3
  54. package/dist/mod/hooks/settings.ts +9 -4
  55. package/dist/mod/hooks/stats.ts +25 -1
  56. package/dist/mod/hooks/ui/agents.tsx +903 -79
  57. package/dist/mod/hooks/ui/alerts.tsx +20 -17
  58. package/dist/mod/hooks/ui/art.ts +33 -7
  59. package/dist/mod/hooks/ui/band.tsx +262 -81
  60. package/dist/mod/hooks/ui/flat.ts +265 -0
  61. package/dist/mod/hooks/ui/kit.tsx +70 -55
  62. package/dist/mod/hooks/ui/look.ts +129 -0
  63. package/dist/mod/hooks/ui/settings.tsx +71 -46
  64. package/dist/mod/hooks/ui/setup.tsx +15 -13
  65. package/dist/mod/hooks/ui/theme.ts +3 -0
  66. package/dist/mod/hooks/ui/tools.ts +124 -0
  67. package/dist/mod/hooks/ui/view.ts +120 -4
  68. package/dist/mod/hooks/workers.ts +33 -6
  69. package/dist/mod/tests/register.test.tsx +155 -11
  70. package/dist/mod/tests/ui.test.tsx +408 -27
  71. package/dist/mod/types/index.d.ts +66 -2
  72. package/dist/remote/package.json +28 -0
  73. package/dist/remote/src/away.js +85 -0
  74. package/dist/remote/src/bridge-client.js +336 -0
  75. package/dist/remote/src/composer-menu.js +11 -0
  76. package/dist/remote/src/config.js +102 -0
  77. package/dist/remote/src/desktop.js +1018 -0
  78. package/dist/remote/src/e2ee.js +126 -0
  79. package/dist/remote/src/e2ee.ts +126 -0
  80. package/dist/remote/src/eventlog.js +298 -0
  81. package/dist/remote/src/expo-push.js +127 -0
  82. package/dist/remote/src/folders.js +79 -0
  83. package/dist/remote/src/fsutil.js +39 -0
  84. package/dist/remote/src/handoff.js +38 -0
  85. package/dist/remote/src/host-service.js +168 -0
  86. package/dist/remote/src/images.js +215 -0
  87. package/dist/remote/src/local-control.js +138 -0
  88. package/dist/remote/src/main.js +264 -0
  89. package/dist/remote/src/permissions.js +124 -0
  90. package/dist/remote/src/power.js +76 -0
  91. package/dist/remote/src/processes.js +24 -0
  92. package/dist/remote/src/protocol.js +32 -0
  93. package/dist/remote/src/protocol.ts +284 -0
  94. package/dist/remote/src/push-content.js +32 -0
  95. package/dist/remote/src/push.js +134 -0
  96. package/dist/remote/src/receipts.js +111 -0
  97. package/dist/remote/src/relay.js +438 -0
  98. package/dist/remote/src/router.js +208 -0
  99. package/dist/remote/src/sdk-launcher.js +18 -0
  100. package/dist/remote/src/server.js +706 -0
  101. package/dist/remote/src/service.js +157 -0
  102. package/dist/remote/src/sessions.js +1800 -0
  103. package/dist/remote/src/sidebar-storage.js +211 -0
  104. package/dist/remote/src/sidebar.js +173 -0
  105. package/dist/remote/src/tool-details.js +205 -0
  106. package/dist/remote/src/tool-details.ts +153 -0
  107. package/dist/remote/src/worktree.js +99 -0
  108. package/dist/remote/web/app.ts +746 -0
  109. package/dist/remote/web/conn.ts +193 -0
  110. package/dist/remote/web/demo.ts +134 -0
  111. package/dist/remote/web/dom.ts +124 -0
  112. package/dist/remote/web/esc.ts +4 -0
  113. package/dist/remote/web/i18n.ts +374 -0
  114. package/dist/remote/web/icon.svg +1 -0
  115. package/dist/remote/web/index.html +24 -0
  116. package/dist/remote/web/manifest.webmanifest +10 -0
  117. package/dist/remote/web/mascot.ts +60 -0
  118. package/dist/remote/web/md.ts +78 -0
  119. package/dist/remote/web/notify.ts +55 -0
  120. package/dist/remote/web/pushstate.ts +27 -0
  121. package/dist/remote/web/secure.ts +109 -0
  122. package/dist/remote/web/sidebar.ts +106 -0
  123. package/dist/remote/web/style.css +311 -0
  124. package/dist/remote/web/sw.ts +48 -0
  125. package/dist/remote/web/timeline.ts +224 -0
  126. package/dist/remote/web/views.ts +323 -0
  127. package/dist/router/src/admin.js +331 -5
  128. package/dist/router/src/awake-win.js +590 -0
  129. package/dist/router/src/awake.js +432 -0
  130. package/dist/router/src/config.js +94 -0
  131. package/dist/router/src/health.js +86 -3
  132. package/dist/router/src/hold.js +107 -0
  133. package/dist/router/src/index.js +108 -6
  134. package/dist/router/src/ingress/server.js +26 -4
  135. package/dist/router/src/ingress/translate.js +6 -2
  136. package/dist/router/src/phone.js +82 -0
  137. package/dist/router/src/power.js +107 -0
  138. package/dist/router/src/providers/anthropic-usage.js +33 -1
  139. package/dist/router/src/providers/google/antigravity.js +73 -10
  140. package/dist/router/src/providers/google/index.js +191 -14
  141. package/dist/router/src/providers/google/prompt-refusal.js +29 -0
  142. package/dist/router/src/providers/google/thoughtSignatures.js +13 -0
  143. package/dist/router/src/providers/google/transport.js +1 -1
  144. package/dist/router/src/providers/google/usage.js +302 -0
  145. package/dist/router/src/providers/grok/index.js +18 -0
  146. package/dist/router/src/providers/grok/usage.js +77 -0
  147. package/dist/router/src/providers/openai/translate.js +13 -2
  148. package/dist/router/src/providers/opencode-usage.js +116 -0
  149. package/dist/router/src/providers/retry.js +4 -1
  150. package/dist/router/src/proxy.js +371 -261
  151. package/dist/router/src/remote-host.js +320 -0
  152. package/dist/router/src/remote-tunnel.js +320 -0
  153. package/dist/router/src/requestlog.js +48 -39
  154. package/dist/router/src/tether-win.js +211 -0
  155. package/dist/router/src/tether.js +712 -0
  156. package/dist/router/src/usage-history.js +227 -0
  157. package/dist/router/src/version.js +1 -1
  158. package/dist/ui/app.js +1083 -59
  159. package/dist/ui/i18n.js +670 -69
  160. package/dist/ui/index.html +33 -6
  161. package/dist/ui/style.css +177 -0
  162. package/docs/ARCHITECTURE.md +402 -14
  163. package/package.json +8 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,123 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.0 — 2026-10-20
4
+
5
+ ### Added
6
+
7
+ - **Close the laptop, Claude keeps working.** For sessions driven from a phone, the laptop now
8
+ stays awake with the lid shut while a model call runs and for 10 minutes after (or until a time
9
+ you set), and lets go under a 20% battery floor or, on macOS, a thermal warning, putting a closed
10
+ laptop to sleep when it does. macOS needs one setup: macOS's own password dialog installs a
11
+ sudoers rule for exactly the commands used, and Insomnia is cleaned up. Windows needs no
12
+ administrator rights: a router child holds `SetThreadExecutionState` and sets the lid action
13
+ only while held, restoring yours afterwards. Off until turned on in the dashboard's Laptop view.
14
+ - **Wi-Fi without internet fails over to the phone hotspot, and comes back.** The router probes the
15
+ internet through the Wi-Fi interface (a dead uplink or a captive portal still reads "connected"
16
+ to the OS), joins the hotspot you name after 3 of 5 failed rounds, and tries the way back to a
17
+ known Wi-Fi 5, 10, 20, 30, 40, 50 and 60 minutes after landing, then every 10 minutes. iPhone and
18
+ Android hotspots both work: an Android hotspot's subnet is learned from the router's own join.
19
+ When calls never stop, the switch holds new model calls for a moment instead of waiting forever;
20
+ nothing is refused.
21
+ - **The app's window is the dashboard, and it opens with the router down.** It draws its own copy
22
+ of the dashboard, so a broken router no longer takes the only screen with it; the Status view
23
+ offers repair and a switch to Claude's own connection. `clauderipple doctor`, `repair` and
24
+ `direct on|off` do the same from a terminal. Opening the app from its icon shows the window.
25
+ - **The app and its tray wear 리플이,** and the Dock shows that icon instead of Electron's.
26
+
27
+ ### Changed
28
+
29
+ - **Gemini 3.8 Flash's high effort uses the medium tier.** `-high` thinks without a budget, and
30
+ on a normal day the requests past medium's 4,000 tokens took 64% of all request time.
31
+ - **Every model goes to the Antigravity host that offers it** (Gemini 3.1 Pro is on prod only),
32
+ and the limits row reads the quota of the host the requests spend.
33
+ - **Korean reads as everyday Korean** across the dashboard, the mod and the menu-bar app, and the
34
+ power screens name no device brand: laptop and phone, with iPhone and Android steps side by side.
35
+ - **An agent's conversation shows whole,** with no "earlier" to press, and a back button floats at
36
+ the top once you scroll down. Narrow agent cards give the elapsed time no row of its own and cut
37
+ titles at two lines; the band and log drop a hosted model's vendor path.
38
+
39
+ ### Fixed
40
+
41
+ - **A Mac offline no longer restarts the router in a loop.** The health self-exit, meant for a
42
+ wedged process, fired 27 times in 18 minutes on a commute and kept the hotspot failover from ever
43
+ counting its failures; it now asks a fresh process first and stays up when the machine is offline.
44
+ - **Google's "no capacity" no longer rests the account.** A 503 `MODEL_CAPACITY_EXHAUSTED` is retried
45
+ twice, slowly, then handed to the route fallback or answered 529 overloaded; other turns are not
46
+ refused with "all accounts resting".
47
+ - **Ripple Remote keeps sending when the `claude` CLI's login lapses.** The phone host borrowed the
48
+ CLI's keychain login, which only the CLI refreshes; it now falls back to the login the Claude app
49
+ is using.
50
+ - **Gemini's quota is read from the host the requests spend it on,** a window past its reset reads
51
+ 0% instead of vanishing, and Gemini's Claude-and-GPT windows show only when such a model runs
52
+ through it.
53
+
54
+ ## 0.10.0 — 2026-10-20
55
+
56
+ ### Added
57
+
58
+ - **Code tab sessions on an SSH host route through Ripple.** Claude Code on a remote host went
59
+ straight to Anthropic and could not find the GPT workers, because Claude Desktop opens that
60
+ connection itself and never reads `RemoteForward` (#67). `clauderipple remote add <host>` copies
61
+ the CA and the generated agent files over plain `sh`, points the host's `settings.json` at a
62
+ router-held reverse tunnel on `127.0.0.1:18791`, re-syncs the agents whenever they change, and
63
+ `remote hosts` / `remote remove` manage them. It needs key-based `ssh` with no password prompt;
64
+ the mod is not on the remote host yet.
65
+ - **The logs page shows token usage for any period, and every provider.** The chips covered only
66
+ the last hour. A period control (1 hour, today, 7 days, 30 days, this month, all time, custom
67
+ dates) now reads an hourly history that survives restarts, a per-model table shows where the
68
+ tokens went, and the provider menu lists every configured provider instead of only the ones in
69
+ the last 200 requests, filtering the chips, the table and the recent requests together. A figure
70
+ too wide for a narrow pane or a 1,024px window steps its type down instead of being cut.
71
+ - **The band's limits row shows every provider.** Claude, ChatGPT, Antigravity (Gemini), OpenCode
72
+ Go and a Grok subscription each draw a group in their provider's colour, from one
73
+ `/api/limits` read; before, only Claude and ChatGPT did. At about 100 columns four providers
74
+ took roughly 207 cells as gauges against 96, so the row picks the roomiest of three densities
75
+ and gives up later groups only when none fits. Each provider can be kept off the status bar.
76
+ - **The Agents pane gives each agent a card.** The pane showed "no agents running · 2 done" over
77
+ an empty panel. Each card now holds the state, title, the model that answered and the effort it
78
+ was sent at, the API's real token counts with cache share, the tool count, and the elapsed time,
79
+ and keeps its size steady while the agent runs. Opening a card shows its conversation in the
80
+ pane, with a run of tool calls collapsed into one summary line ("3 files read, 1 command run"),
81
+ as the Claude app draws it.
82
+ - **The dashboard's Phone view pairs Ripple Remote and manages the connection.** Pairing used to
83
+ mean running `npm run remote -- pair` in a source checkout. The view now shows the host's state,
84
+ a pairing QR on request, the mode, the phones seen and a key rotation, answered on a
85
+ loopback-only `/local` API with a secret from a `0600` file. The published CLI and dashboard now
86
+ install the phone host, which runs under Windows and Linux user supervisors as well as launchd.
87
+ - **Ripple Remote tells you which session finished and what it did.** Notifications carried one
88
+ fixed line for every session; the host now sends the title and the last answer, approval request
89
+ or failure reason inside an encrypted blob, leaving Expo, APNs and FCM with only the fallback
90
+ text. Mac sessions push when a turn ends while the Mac is away, Claude app sessions send and
91
+ receive photos, a subagent shows its model and opens its own chat, and thinking no longer
92
+ splits a run (one real session went from 1,442 rows to 549).
93
+ - **The desktop has two skins, deep and flat.** A `skin` setting picks them on the quick settings
94
+ panel and the dashboard's Look card; deep stays the default. Flat follows the app's own surface
95
+ and quiet text colour, keeps one accent, and the band's labels, counts and controls carry the
96
+ right colour.
97
+
98
+ ### Fixed
99
+
100
+ - **Google and Antigravity prompt refusals are retried instead of failing the turn.** A refusal is
101
+ now returned unwritten and retried once along a configured fallback route with the original
102
+ request, and an Antigravity 429 is called a real limit only when fresh account and project quota
103
+ evidence says so.
104
+ - **Parallel tool results with images stay together on the OpenAI-compatible wire.** Three image
105
+ Reads used to interleave `tool|user|tool|user`, and DeepSeek refused them
106
+ ("insufficient tool messages following tool_calls", #64). Images now wait until the run of tool
107
+ results ends.
108
+ - **A slow reasoning model passes the connection check.** Hive answers a streamed request in 0.3
109
+ seconds but a whole one in 3–23, past the 8-second probe, so a working key read as "could not
110
+ connect"; the check now streams and drops the body once the status is in.
111
+ - **A provider named in Hangul is named after its domain.** "하이브" slugged to nothing and showed
112
+ as "provider"; it now falls back to the URL's domain ("thehive").
113
+ - **A failed restart no longer ends the Windows supervisor loop.** One `Start-Process` error, such
114
+ as a locked log file, stopped the script and left the router and host unsupervised until logon.
115
+ - **A dark-mode select's options are readable.** Native options and optgroups now get opaque,
116
+ theme-aware backgrounds.
117
+ - **Slash commands stay available when settings fail to load.** A throw while loading settings
118
+ took `/ripple`, `/ripple-log` and `/ripple-bar` with it (#62); the settings step now has its own
119
+ catch, so the commands register either way.
120
+
3
121
  ## 0.9.5 — 2026-10-14
4
122
 
5
123
  ### Fixed
package/README.es.md CHANGED
@@ -321,6 +321,13 @@ los modelos que asignas van a tu proveedor, y todo lo demás va a Anthropic byte
321
321
  imágenes de referencia y fondos transparentes. A los subagentes se les explica cómo
322
322
  hacerlo, así que un worker de GPT o DeepSeek puede crear una imagen y verla sin una
323
323
  herramienta de imágenes.
324
+ - **Cierra el portátil y Claude sigue trabajando.** En macOS y Windows el portátil se
325
+ mantiene despierto con la tapa cerrada mientras Claude trabaja (y 10 minutos después),
326
+ así que una tarea que lanzaste desde el teléfono llega al final. Si el Wi-Fi se queda sin
327
+ internet, pasa al punto de acceso de tu teléfono (iPhone o Android) y más tarde vuelve a
328
+ un Wi-Fi conocido. Viene desactivado hasta que lo actives en la vista Portátil del panel;
329
+ consulta [Tapa cerrada y el punto de acceso del
330
+ teléfono](#tapa-cerrada-y-el-punto-de-acceso-del-teléfono).
324
331
  - **Workers ligeros, si los quieres.** Un solo interruptor da a los subagentes generados
325
332
  solo las herramientas que usa un worker, en lugar de todos los servidores MCP y plugins
326
333
  de la sesión: la primera solicitud de un worker bajó de 33k a 9k tokens.
@@ -546,6 +553,44 @@ compatible con Anthropic que hayas configurado está disponible de la misma form
546
553
  <img src="docs/media/add-provider.png" width="880" alt="Añadir proveedor: suscripción de ChatGPT, ajustes predefinidos, proveedores compatibles con OpenAI">
547
554
  </p>
548
555
 
556
+ ## Tapa cerrada y el punto de acceso del teléfono
557
+
558
+ Para las sesiones que llevas desde el teléfono (Remote Control, Ripple Remote): el portátil
559
+ sigue trabajando dentro de una mochila. Abre la vista **Portátil** del panel.
560
+
561
+ **Seguir despierto con la tapa cerrada.** Hay tres modos: *No*; *Mientras trabaja* —
562
+ despierto mientras corre una llamada al modelo y durante 10 minutos después de la última;
563
+ *Siempre* — hasta que lo apagues o llegue una hora que fijes. Deja de mantenerse despierto
564
+ por sí solo cuando la batería baja del 20 % o (en macOS) el Mac avisa de un problema térmico,
565
+ y entonces pone en reposo un portátil con la tapa cerrada. Mientras está despierto, no lo
566
+ lleves mucho tiempo en una mochila cerrada.
567
+
568
+ - macOS: pulsa **Configurar** una vez. El propio cuadro de contraseña de macOS instala una
569
+ regla de sudoers para exactamente los comandos que se usan (`pmset disablesleep`,
570
+ `pmset sleepnow`, conectarse al punto de acceso que indicas); ClaudeRipple nunca ve la
571
+ contraseña. `clauderipple awake setup --remove` la quita. Si Insomnia está instalado, la
572
+ configuración lo elimina (hace el mismo trabajo).
573
+ - Windows: no hacen falta permisos de administrador. Un proceso hijo del router mantiene
574
+ `SetThreadExecutionState`, y la acción de la tapa se pone en «no hacer nada» solo mientras
575
+ lo mantiene; tus propios ajustes de energía vuelven después, también si el router muere.
576
+
577
+ **Wi-Fi sin internet → punto de acceso del teléfono.** Comprueba internet a través de la
578
+ interfaz Wi-Fi (un router con el enlace caído o un portal cautivo sigue pareciendo
579
+ «conectado» al sistema) y se une al punto de acceso que indicas cuando fallan 3 de 5
580
+ intentos. En el punto de acceso prueba la vuelta a los 5, 10, 20, 30, 40, 50 y 60 minutos de
581
+ llegar, y luego cada 10 minutos: sale del punto de acceso para que el sistema se una al mejor
582
+ Wi-Fi conocido que haya en el alcance, y se queda solo si ese Wi-Fi tiene internet. Una
583
+ llamada al modelo que empieza durante el cambio espera un momento en lugar de fallar.
584
+
585
+ - Conéctate una vez a mano al punto de acceso del teléfono desde el portátil, para que el
586
+ sistema guarde su contraseña.
587
+ - iPhone: mantén activado Ajustes › Punto de acceso personal ›
588
+ «Permitir a otros conectarse». En un Mac, la misma cuenta de Apple y el Bluetooth
589
+ activado ayudan a encontrar el teléfono.
590
+ - Android: un punto de acceso inactivo se apaga solo al cabo de un rato; vuelve a encenderlo
591
+ si no aparece.
592
+ - Linux: aún no es compatible.
593
+
549
594
  ## Proveedores
550
595
 
551
596
  | Proveedor | Tipo | Autenticación | Lista de modelos | Notas |
package/README.ja.md CHANGED
@@ -173,6 +173,7 @@ Claude Codeのシステムプロンプトとツールの説明はClaude向けに
173
173
  - **サブエージェントの名前タグ**。バックグラウンドタスクパネルに、汎用の「Agent」ではなく`Terra·high · Review`のように表示されます。
174
174
  - **プロンプトの上のrippleモッド**。帯1本に推論強度、コンテキスト、キャッシュタイマー、直前のリクエストに実際に応答したモデルとキャッシュヒット率を表示します。小さな判定モデル(Haiku 5.5またはJev)がプロンプトごとに直近の会話と合わせて読み、lowからmaxまで推論強度を決めます。任せた作業は`ripple:auto`に渡り、判定モデルが難しさに応じてワーカーを選びます。軽い作業はDeepSeekやGLM、難しい作業はGPTやOpusへ。キャッシュが冷えたとき、コンテキストが重くなったとき、プランの上限が80%を超えたときにカードで知らせ、圧縮か、同じフォルダの新しいセッションへの引き継ぎを提案します。`Log`(または`/ripple-log`)でリクエストログをサイドペインに開きます。「クライアント」画面のスイッチ1つ、または`clauderipple mod on`で有効にできます。
175
175
  - **ChatGPTのサブスクリプションで画像を生成**。`clauderipple image "<prompt>"`で、参照画像や透明背景にも対応します。サブエージェントにもやり方が伝えられているので、GPTやDeepSeekのワーカーでも、画像ツールなしで画像を作って確認できます。
176
+ - **ノートPCのふたを閉じても、Claudeは作業を続けます**。macOSとWindowsでは、Claudeが作業している間(終わってから10分間も)ふたを閉じたままでもノートPCがスリープしないので、スマホから頼んだ作業が最後まで進みます。Wi-Fiがインターネットにつながらなくなると、スマホのインターネット共有(iPhoneまたはAndroid)に切り替え、あとで登録済みのWi-Fiに戻ります。ダッシュボードの「ノートPC の管理」画面でオンにするまでは無効です。[ふたを閉じたときとスマートフォンのインターネット共有](#ふたを閉じたときとスマートフォンのインターネット共有)を参照してください。
176
177
  - **必要なら軽量なワーカーを**。スイッチ1つで、生成されるサブエージェントに、セッションのすべてのMCPサーバーとプラグインではなく、ワーカーが使うツールだけを渡します。あるワーカーの最初のリクエストは33kトークンから9kトークンに減りました。
177
178
  - **ターミナルを使いたくない人のために**。ワンクリックの接続テストとモデル検出付きのプロバイダープリセット、ドロップダウンによるモデルマッピング、自動保存、韓国語と英語のUI。独自のランタイムを同梱し、初回起動時に自らセットアップするメニューバーアプリ。署名・公証済みです。
178
179
 
@@ -315,6 +316,22 @@ ClaudeのモデルはCodexのモデル一覧にそれぞれの名前で表示さ
315
316
  <img src="docs/media/add-provider.png" width="880" alt="プロバイダーの追加:ChatGPTサブスクリプション、プリセット、OpenAI互換プロバイダー">
316
317
  </p>
317
318
 
319
+ ## ふたを閉じたときとスマートフォンのインターネット共有
320
+
321
+ スマホから進めるセッション(Remote Control、Ripple Remote)のための機能です。ノートPCをかばんに入れたままでも作業が続きます。ダッシュボードの**ノートPC の管理**画面でオンにします。
322
+
323
+ **ふたを閉じてもスリープしない。** モードは3つです。*オフ*、*作業中のみ*(モデルの呼び出しが動いている間と、最後の呼び出しから10分間)、*常にオン*(オフにするか、決めた時刻になるまで)。バッテリーが20%を下回るか、(macOSでは)Macが熱の警告を出すと、自動でスリープ防止をやめ、ふたが閉じていればノートPCをスリープさせます。スリープしない間は、密閉したかばんに長く入れたままにしないでください。
324
+
325
+ - macOS:**設定する**を一度押します。macOS自身のパスワード画面が、使うコマンド(`pmset disablesleep`、`pmset sleepnow`、指定したインターネット共有への接続)だけを許可するsudoersルールをインストールし、ClaudeRippleがパスワードを見ることはありません。`clauderipple awake setup --remove`で削除できます。Insomniaが入っている場合は同じ役割なので、設定時に片付けます。
326
+ - Windows:管理者権限は不要です。ルーターの子プロセスが`SetThreadExecutionState`を保持し、保持している間だけふたの動作を「何もしない」にします。元の電源設定は、ルーターが落ちた場合も含めて後で戻ります。
327
+
328
+ **インターネットにつながらないWi-Fi → スマホのインターネット共有。** Wi-Fiインターフェース経由で実際にインターネットを確かめ(上流が切れたルーターや、ログインページが出るWi-Fiも、OSには「接続済み」に見えるためです)、5回中3回失敗すると指定したインターネット共有に接続します。共有に接続してから5、10、20、30、40、50、60分後に戻り先を試し、その後は10分ごとに試します。共有からいったん離れてOSに範囲内で一番良い登録済みWi-Fiへ接続させ、そのWi-Fiでインターネットが使えるときだけとどまります。切り替えの瞬間に始まったモデルの呼び出しは、失敗せずに少し待ちます。
329
+
330
+ - ノートPCから一度、手動でスマホのインターネット共有に接続しておいてください。OSがパスワードを覚えます。
331
+ - iPhone:設定 › インターネット共有 ›「ほかの人の接続を許可」をオンにしておいてください。Macの場合は、同じAppleアカウントとBluetoothがオンだと見つけやすくなります。
332
+ - Android:誰も接続していないと、共有はしばらくして自動で切れます。見つからないときは、もう一度オンにしてください。
333
+ - Linux:まだ対応していません。
334
+
318
335
  ## プロバイダー
319
336
 
320
337
  | プロバイダー | 種類 | 認証 | モデル一覧 | 備考 |
package/README.ko.md CHANGED
@@ -257,6 +257,10 @@ ClaudeRipple은 Claude Code 프로세스만 신뢰하는 작은 HTTPS 프록시
257
257
  클라이언트 화면의 스위치 하나, 또는 `clauderipple mod on`.
258
258
  - **ChatGPT 구독으로 이미지 생성.** `clauderipple image "<프롬프트>"`. 참고 이미지와 투명 배경도 됩니다. 서브에이전트에도
259
259
  방법이 적혀 있어, GPT나 DeepSeek 워커가 이미지 도구 없이 이미지를 만들고 직접 확인합니다.
260
+ - **노트북을 덮어도 Claude는 계속 일합니다.** macOS와 Windows에서 Claude가 일하는 동안(끝난 뒤 10분까지)
261
+ 덮개를 닫아도 노트북이 잠들지 않아, 휴대폰으로 맡긴 일이 끝까지 갑니다. 와이파이에서 인터넷이 끊기면 휴대폰
262
+ 핫스팟(아이폰·안드로이드)으로 옮겼다가 나중에 아는 와이파이로 돌아옵니다. 대시보드의 노트북 관리 화면에서
263
+ 켜기 전까지는 꺼져 있습니다. [노트북 덮개와 휴대폰 핫스팟](#노트북-덮개와-휴대폰-핫스팟)을 보세요.
260
264
  - **원하면 가벼운 워커.** 스위치 하나로, 생성된 서브에이전트에 세션의 MCP·플러그인 도구 전부 대신 워커가 쓰는 도구만
261
265
  줍니다. 워커 첫 요청이 3.3만에서 0.9만 토큰으로 줄었습니다.
262
266
  - **터미널이 싫은 사람을 위해.** 원클릭 연결 확인과 모델 자동 검색이 붙은 프로바이더 프리셋, 드롭다운 모델 매핑, 자동 저장,
@@ -443,6 +447,33 @@ Anthropic API 키로 갑니다. 구독 로그인 재사용은 Anthropic 약관
443
447
  <img src="docs/media/add-provider.png" width="880" alt="프로바이더 추가: ChatGPT 구독, 프리셋, OpenAI 호환 프로바이더">
444
448
  </p>
445
449
 
450
+ ## 노트북 덮개와 휴대폰 핫스팟
451
+
452
+ 휴대폰으로 돌리는 세션(Remote Control, Ripple Remote)을 위한 기능입니다. 노트북을 가방에 넣어도 일이 이어집니다.
453
+ 대시보드의 **노트북 관리** 화면에서 켭니다.
454
+
455
+ **덮개를 닫아도 잠들지 않게.** 모드는 셋입니다. *끔*, *일할 때만*(모델 요청이 도는 동안과 마지막 요청 뒤 10분),
456
+ *계속 켜 두기*(끄거나 정한 시각까지). 배터리가 20% 아래로 내려가거나 (macOS에서) 맥이 과열 경고를 내면 스스로
457
+ 멈추고, 덮개가 닫혀 있으면 노트북을 재웁니다. 깨어 있는 동안 막힌 가방에 오래 넣어 두지는 마세요.
458
+
459
+ - macOS: **설정하기**를 한 번 누릅니다. macOS 자체 암호 창이 쓰는 명령(`pmset disablesleep`, `pmset sleepnow`,
460
+ 정해 둔 핫스팟 접속)만 허용하는 sudoers 규칙을 설치하며, ClaudeRipple은 암호를 보지 않습니다.
461
+ `clauderipple awake setup --remove`로 지웁니다. Insomnia가 깔려 있으면 같은 일을 하므로 설정할 때 정리합니다.
462
+ - Windows: 관리자 권한이 필요 없습니다. 라우터의 자식 프로세스가 `SetThreadExecutionState`를 잡고, 그동안만
463
+ 덮개 동작을 "아무것도 안 함"으로 둡니다. 원래 전원 설정은 라우터가 죽어도 되돌아옵니다.
464
+
465
+ **인터넷 안 되는 와이파이 → 휴대폰 핫스팟.** 와이파이 인터페이스로 실제 인터넷을 확인합니다(업링크가 죽은 공유기나
466
+ 로그인 페이지가 뜨는 와이파이도 OS에는 "연결됨"으로 보이기 때문입니다). 5번 중 3번 실패하면 정해 둔 핫스팟에
467
+ 붙습니다. 핫스팟에 붙은 뒤 5·10·20·30·40·50·60분에, 그다음엔 10분마다 돌아가기를 시도합니다. 핫스팟에서 잠깐
468
+ 나와 OS가 범위 안의 아는 와이파이에 붙게 하고, 그 와이파이에서 인터넷이 될 때만 머뭅니다. 전환하는 순간
469
+ 시작된 모델 요청은 실패하지 않고 잠깐 기다립니다.
470
+
471
+ - 노트북에서 휴대폰 핫스팟에 한 번 직접 접속해 두세요. 그래야 OS가 암호를 기억합니다.
472
+ - 아이폰: 설정 › 개인용 핫스팟 › '다른 사람의 연결 허용'을 켜 두세요. 맥이라면 같은 Apple 계정과 블루투스가
473
+ 있으면 더 잘 찾습니다.
474
+ - 안드로이드: 아무도 안 붙어 있으면 핫스팟이 잠시 뒤 스스로 꺼집니다. 못 찾으면 다시 켜 주세요.
475
+ - Linux: 아직 지원하지 않습니다.
476
+
446
477
  ## 프로바이더
447
478
 
448
479
  | 프로바이더 | 종류 | 인증 | 모델 목록 | 비고 |
package/README.md CHANGED
@@ -310,6 +310,11 @@ you map go to your provider, everything else goes to Anthropic byte for byte.
310
310
  - **Images from your ChatGPT subscription.** `clauderipple image "<prompt>"`, with
311
311
  reference images and transparent backgrounds. Subagents are told how, so a GPT or
312
312
  DeepSeek worker can make an image and look at it without an image tool.
313
+ - **Close the laptop, Claude keeps working.** On macOS and Windows the laptop stays awake
314
+ with the lid shut while Claude works (and 10 minutes after), so a task you started from
315
+ your phone finishes. If the Wi-Fi loses its internet, it moves to your phone's hotspot
316
+ (iPhone or Android) and back to a known Wi-Fi later. Off until you turn it on in the
317
+ dashboard's Laptop view; see [Lid closed and the phone hotspot](#lid-closed-and-the-phone-hotspot).
313
318
  - **Lean workers, if you want them.** One switch gives generated subagents only the
314
319
  tools a worker uses instead of every MCP server and plugin of the session: one
315
320
  worker's first request fell from 33k to 9k tokens.
@@ -495,6 +500,71 @@ same ChatGPT provider as the search backend in `config.json`:
495
500
  This is opt-in. With no `webSearch` setting, Claude Code's existing search path
496
501
  is unchanged.
497
502
 
503
+ ### Remote (SSH) sessions
504
+
505
+ Claude Desktop's Code tab can run a session on a remote Linux host over SSH.
506
+ Claude Code then runs **on that host**, where ClaudeRipple is not, so routed
507
+ models are unknown there (`Agent type 'gpt-6-1-sol' not found`). Connect the
508
+ host once from the machine ClaudeRipple runs on:
509
+
510
+ ```bash
511
+ clauderipple remote add my-server # an ssh alias or user@host; --port N (default 18791)
512
+ clauderipple remote hosts # tunnel state per host (also in `remote status`)
513
+ clauderipple remote remove my-server # undo it
514
+ ```
515
+
516
+ `remote add` needs key-based `ssh my-server` to work without a password prompt.
517
+ It copies the router's CA certificate (the public certificate only) to
518
+ `~/.clauderipple-remote/` on the host, points the host's
519
+ `~/.claude/settings.json` at the tunnel (`HTTPS_PROXY=http://127.0.0.1:18791`,
520
+ `NODE_EXTRA_CA_CERTS`; the original is kept as
521
+ `settings.json.clauderipple-backup`; a different proxy already there is refused
522
+ without `--force`), and copies the generated agent files. The router then keeps
523
+ a reverse SSH tunnel open from the host's `127.0.0.1:18791` to itself, restarts
524
+ it when it drops, and copies the agent files again whenever they change. The
525
+ host needs only `sh` — no Node and no ClaudeRipple.
526
+
527
+ While the tunnel is down, Claude Code on the host gets *connection refused*
528
+ rather than going to Anthropic around the router. The remote session only exists
529
+ while this machine's Claude Desktop is connected to it anyway. The tunnel
530
+ listens on the host's loopback only, but on a shared host every user there can
531
+ reach that port, and through it your router. The status mod and image
532
+ generation are not available on remote hosts yet.
533
+
534
+ ## Lid closed and the phone hotspot
535
+
536
+ For sessions you drive from your phone (Remote Control, Ripple Remote): the laptop
537
+ keeps working in a bag. Open the dashboard's **Laptop** view.
538
+
539
+ **Stay awake with the lid closed.** Three modes: *Off*; *While working* — awake while a
540
+ model call runs and for 10 minutes after the last one; *Always* — until you turn it off
541
+ or a time you set. It lets go by itself when the battery drops below 20% or (on macOS) the
542
+ Mac reports a thermal warning, and puts a closed laptop to sleep when it does. Don't carry
543
+ it in a closed bag for long while it is awake.
544
+
545
+ - macOS: press **Set up** once. macOS's own password dialog installs a sudoers rule for
546
+ exactly the commands used (`pmset disablesleep`, `pmset sleepnow`, joining the hotspot
547
+ you name); ClaudeRipple never sees the password. `clauderipple awake setup --remove`
548
+ takes it out. If Insomnia is installed, setup removes it (it does the same job).
549
+ - Windows: no administrator rights. A child of the router holds
550
+ `SetThreadExecutionState`, and the lid action is set to "do nothing" only while it is
551
+ held; your own power settings come back afterwards, also if the router dies.
552
+
553
+ **Wi-Fi without internet → phone hotspot.** It probes the internet through the Wi-Fi
554
+ interface (a router with a dead uplink or a captive portal still looks "connected" to
555
+ the OS) and joins the hotspot you name after 3 of 5 rounds fail. On the hotspot it tries
556
+ the way back 5, 10, 20, 30, 40, 50 and 60 minutes after landing, then every 10 minutes:
557
+ it leaves the hotspot so the OS joins the best known Wi-Fi in range, and stays there only
558
+ if that Wi-Fi has internet. A model call that starts during the switch waits a moment
559
+ instead of failing.
560
+
561
+ - Join the phone's hotspot from the laptop once by hand, so the OS keeps its password.
562
+ - iPhone: keep Settings › Personal Hotspot › "Allow Others to Join" on. On a Mac, the
563
+ same Apple Account and Bluetooth on help it find the phone.
564
+ - Android: an idle hotspot turns itself off after a while; turn it on again if it is
565
+ not found.
566
+ - Linux: not supported yet.
567
+
498
568
  ### Codex app and Codex CLI
499
569
 
500
570
  ```bash
package/README.pt-BR.md CHANGED
@@ -316,6 +316,13 @@ que você mapeia vão para o seu provedor, e todo o resto vai para a Anthropic b
316
316
  de referência e fundos transparentes. Os subagentes recebem instruções de como fazer,
317
317
  então um worker GPT ou DeepSeek consegue criar uma imagem e olhar para ela sem uma
318
318
  ferramenta de imagem.
319
+ - **Feche o notebook e o Claude continua trabalhando.** No macOS e no Windows o notebook
320
+ fica acordado com a tampa fechada enquanto o Claude trabalha (e por 10 minutos depois),
321
+ então uma tarefa que você começou pelo celular chega ao fim. Se o Wi-Fi ficar sem
322
+ internet, ele passa para o Acesso Pessoal do celular (iPhone ou Android) e mais tarde
323
+ volta para um Wi-Fi conhecido. Vem desligado até você ativá-lo na tela **Notebook** do
324
+ painel; veja [Tampa fechada e o Acesso Pessoal do
325
+ celular](#tampa-fechada-e-o-acesso-pessoal-do-celular).
319
326
  - **Workers enxutos, se você quiser.** Um único botão faz com que os subagentes gerados
320
327
  recebam só as ferramentas que um worker usa, em vez de todos os servidores MCP e plugins
321
328
  da sessão: a primeira requisição de um worker caiu de 33k para 9k tokens.
@@ -533,6 +540,44 @@ que você tenha configurado fica disponível da mesma forma.
533
540
  <img src="docs/media/add-provider.png" width="880" alt="Adicionar provedor: assinatura do ChatGPT, presets, provedores compatíveis com OpenAI">
534
541
  </p>
535
542
 
543
+ ## Tampa fechada e o Acesso Pessoal do celular
544
+
545
+ Para as sessões que você conduz pelo celular (Remote Control, Ripple Remote): o notebook
546
+ continua trabalhando dentro de uma mochila. Abra a tela **Notebook** do painel.
547
+
548
+ **Continuar acordado com a tampa fechada.** São três modos: *Não*; *Enquanto trabalha* —
549
+ acordado enquanto uma chamada ao modelo roda e por 10 minutos depois da última; *Sempre* —
550
+ até você desligar ou chegar um horário que você definir. Ele se solta sozinho quando a
551
+ bateria cai abaixo de 20% ou (no macOS) o Mac avisa de um problema térmico, e põe um
552
+ notebook de tampa fechada em repouso. Enquanto estiver acordado, não o carregue por muito
553
+ tempo numa mochila fechada.
554
+
555
+ - macOS: clique em **Configurar** uma vez. A própria janela de senha do macOS instala uma
556
+ regra de sudoers para exatamente os comandos usados (`pmset disablesleep`,
557
+ `pmset sleepnow`, entrar no Acesso Pessoal que você indicar); o ClaudeRipple nunca vê a
558
+ senha. `clauderipple awake setup --remove` a remove. Se o Insomnia estiver instalado, a
559
+ configuração o remove (ele faz o mesmo trabalho).
560
+ - Windows: não precisa de permissões de administrador. Um processo filho do roteador mantém
561
+ `SetThreadExecutionState`, e a ação da tampa fica em "não fazer nada" só enquanto ele a
562
+ mantém; suas próprias configurações de energia voltam depois, também se o roteador
563
+ morrer.
564
+
565
+ **Wi-Fi sem internet → Acesso Pessoal do celular.** Ele testa a internet pela interface
566
+ Wi-Fi (um roteador com o link caído ou um portal cativo ainda parece "conectado" para o
567
+ sistema) e entra no Acesso Pessoal que você indicar quando 3 de 5 tentativas falham. No
568
+ Acesso Pessoal ele tenta a volta 5, 10, 20, 30, 40, 50 e 60 minutos depois de chegar, e
569
+ depois a cada 10 minutos: sai do Acesso Pessoal para o sistema entrar no melhor Wi-Fi
570
+ conhecido ao alcance, e só fica se esse Wi-Fi tiver internet. Uma chamada ao modelo que
571
+ começa durante a troca espera um momento em vez de falhar.
572
+
573
+ - Conecte-se uma vez à mão ao Acesso Pessoal do celular a partir do notebook, para o sistema
574
+ guardar a senha.
575
+ - iPhone: mantenha ativado Ajustes › Acesso Pessoal › «Permitir Outros». Num Mac, a mesma
576
+ Conta Apple e o Bluetooth ligado ajudam a encontrar o celular.
577
+ - Android: um Acesso Pessoal ocioso se desliga sozinho depois de um tempo; ligue-o de novo
578
+ se ele não aparecer.
579
+ - Linux: ainda não é compatível.
580
+
536
581
  ## Provedores
537
582
 
538
583
  | Provedor | Tipo | Autenticação | Lista de modelos | Observações |
package/README.zh-CN.md CHANGED
@@ -174,6 +174,7 @@ Claude Code 的系统提示词和工具描述是为 Claude 编写的,所以其
174
174
  - **子代理名称标签。** 后台任务面板显示 `Terra·high · Review`,而不是笼统的“Agent”。
175
175
  - **输入框上方的 ripple 模组。** 一条横栏显示推理强度、上下文、缓存计时,以及上一个请求实际由哪个模型作答和缓存命中率。一个小型判定模型(Haiku 5.5 或 Jev)会结合最近的对话阅读每条提示词,在 low 到 max 之间设定推理强度。委派的工作交给 `ripple:auto`,由判定模型按难度挑选 worker:轻活交给 DeepSeek 或 GLM,难活交给 GPT 或 Opus。缓存变冷、上下文变重或套餐额度超过 80% 时会弹出卡片提醒,并提供压缩或交接到同一文件夹的新会话。`Log`(或 `/ripple-log`)会在侧边窗格中打开请求日志。在“客户端”页面上打开一个开关即可启用,或运行 `clauderipple mod on`。
176
176
  - **用 ChatGPT 订阅生成图片。** `clauderipple image "<prompt>"`,支持参考图和透明背景。子代理会被告知用法,因此 GPT 或 DeepSeek worker 无需图像工具也能生成图片并查看结果。
177
+ - **合上笔记本,Claude 照样干活。** 在 macOS 和 Windows 上,Claude 工作期间(以及结束后 10 分钟内)笔记本合盖也不睡眠,所以你从手机发起的任务能做完。Wi-Fi 断了网,它会转到手机热点(iPhone 或 Android),之后再回到已知的 Wi-Fi。该功能默认关闭,需要在控制面板的“笔记本管理”中打开;见[合盖与手机热点](#合盖与手机热点)。
177
178
  - **按需精简 worker。** 打开一个开关,生成的子代理就只获得 worker 会用到的工具,而不是会话中的所有 MCP 服务器和插件:某个 worker 的首个请求因此从 33k token 降到了 9k token。
178
179
  - **为不想碰终端的人而设计。** 供应商预设支持一键连接测试和模型发现,下拉式模型映射,自动保存,韩语和英语界面。菜单栏应用自带运行时,首次启动时自动完成设置。经过签名和公证。
179
180
 
@@ -316,6 +317,22 @@ Claude 模型会以各自的名称出现在 Codex 的模型列表中(ClaudeRip
316
317
  <img src="docs/media/add-provider.png" width="880" alt="添加供应商:ChatGPT 订阅、预设、OpenAI 兼容供应商">
317
318
  </p>
318
319
 
320
+ ## 合盖与手机热点
321
+
322
+ 这是给用手机远程推进的会话(Remote Control、Ripple Remote)准备的功能:笔记本放进背包也照样工作。在控制面板的 **笔记本管理** 页面打开。
323
+
324
+ **合盖时保持唤醒。** 共三档:*关闭*、*仅在工作时*(模型请求进行中,以及最后一次请求结束后 10 分钟)、*始终开启*(直到你关闭或到达设定的时间)。电量降到 20% 以下,或(在 macOS 上)Mac 报告过热警告时,它会自动停止保持唤醒;如果此时已合盖,就让笔记本睡眠。保持唤醒期间,不要长时间把它放在封闭的背包里。
325
+
326
+ - macOS:点一次 **设置**。macOS 自己的密码窗口会安装一条 sudoers 规则,只允许用到的命令(`pmset disablesleep`、`pmset sleepnow`,以及连接你指定的热点);ClaudeRipple 看不到密码。用 `clauderipple awake setup --remove` 可以删除。如果装了 Insomnia,设置时会把它清理掉(它与本功能作用相同)。
327
+ - Windows:不需要管理员权限。路由服务的子进程持有 `SetThreadExecutionState`,只在持有期间把合盖动作设为“不采取任何操作”;你自己的电源设置随后会恢复,即使路由服务崩溃也一样。
328
+
329
+ **Wi-Fi 无法上网 → 手机热点。** 它通过 Wi-Fi 网卡实际检查能否上网(上行链路坏掉的路由器,或弹出登录页的 Wi-Fi,在系统看来仍是“已连接”),5 次检查中失败 3 次就加入你指定的热点。加入热点后,在 5、10、20、30、40、50、60 分钟时尝试切回,之后每 10 分钟一次:先离开热点,让系统连上范围内最好的已知 Wi-Fi,只有那个 Wi-Fi 能上网才留下。切换瞬间开始的模型请求不会失败,而是稍等一下。
330
+
331
+ - 先在笔记本上手动连接一次手机热点,系统才会记住密码。
332
+ - iPhone:保持开启 设置 › 个人热点 ›“允许其他人加入”。在 Mac 上,登录同一个 Apple 账户并开启蓝牙会更容易找到手机。
333
+ - Android:热点闲置一段时间会自动关闭;找不到时请重新打开。
334
+ - Linux:暂不支持。
335
+
319
336
  ## 供应商
320
337
 
321
338
  | 供应商 | 类型 | 认证 | 模型列表 | 备注 |
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ // Quitting and reopening Claude Desktop, which is how it picks up a changed connection. The caller
3
+ // asks the user first: quitting ends whatever is open in the app.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.reopenClaude = reopenClaude;
6
+ const node_child_process_1 = require("node:child_process");
7
+ const MAC_BUNDLE_ID = "com.anthropic.claudefordesktop";
8
+ const QUIT_WAIT_MS = 20_000;
9
+ function run(file, args, timeoutMs = 30_000) {
10
+ return new Promise((resolve) => {
11
+ (0, node_child_process_1.execFile)(file, args, { timeout: timeoutMs, windowsHide: true }, (err, stdout) => resolve({ ok: !err, stdout: String(stdout) }));
12
+ });
13
+ }
14
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
15
+ /** True once Claude Desktop is running again. */
16
+ async function reopenClaude() {
17
+ if (process.platform === "darwin")
18
+ return reopenMac();
19
+ if (process.platform === "win32")
20
+ return reopenWindows();
21
+ return false;
22
+ }
23
+ async function macRunning() {
24
+ // `is running` asks without launching the app.
25
+ const r = await run("osascript", ["-e", `application id "${MAC_BUNDLE_ID}" is running`], 10_000);
26
+ return r.ok && r.stdout.trim() === "true";
27
+ }
28
+ async function reopenMac() {
29
+ if (await macRunning()) {
30
+ await run("osascript", ["-e", `tell application id "${MAC_BUNDLE_ID}" to quit`]);
31
+ const deadline = Date.now() + QUIT_WAIT_MS;
32
+ while (Date.now() < deadline && (await macRunning()))
33
+ await sleep(500);
34
+ // Opening it while the old one is still on its way out would only bring that one forward.
35
+ if (await macRunning())
36
+ return false;
37
+ }
38
+ const opened = await run("open", ["-b", MAC_BUNDLE_ID]);
39
+ return opened.ok || (await run("open", ["-a", "Claude"])).ok;
40
+ }
41
+ /**
42
+ * Claude Desktop is the claude.exe that owns a window; Claude Code's own claude.exe (terminal
43
+ * sessions, the copy Desktop caches) has none and must not be touched. Closing the window asks it
44
+ * to quit; whatever of that same executable is left after a few seconds is ended, then it is
45
+ * started again from the same path.
46
+ */
47
+ const WINDOWS_SCRIPT = String.raw `
48
+ $ErrorActionPreference = 'SilentlyContinue'
49
+ $main = Get-Process -Name claude | Where-Object { $_.MainWindowHandle -ne 0 -and $_.Path } | Select-Object -First 1
50
+ if ($main) {
51
+ $exe = $main.Path
52
+ Get-Process -Name claude | Where-Object { $_.Path -eq $exe } | ForEach-Object { [void]$_.CloseMainWindow() }
53
+ $deadline = (Get-Date).AddSeconds(8)
54
+ while ((Get-Process -Name claude | Where-Object { $_.Path -eq $exe }) -and (Get-Date) -lt $deadline) { Start-Sleep -Milliseconds 500 }
55
+ Get-Process -Name claude | Where-Object { $_.Path -eq $exe } | Stop-Process -Force
56
+ Start-Sleep -Milliseconds 500
57
+ } else {
58
+ $exe = Join-Path $env:LOCALAPPDATA 'AnthropicClaude\claude.exe'
59
+ if (-not (Test-Path $exe)) { exit 1 }
60
+ }
61
+ Start-Process -FilePath $exe
62
+ if (-not $?) { exit 1 }
63
+ `;
64
+ async function reopenWindows() {
65
+ const r = await run("powershell.exe", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", WINDOWS_SCRIPT], 40_000);
66
+ return r.ok;
67
+ }