@omg-dev/app 0.6.14 → 0.6.15

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.
@@ -0,0 +1,284 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { z as n } from "./embedded-Ck10Okym.js";
3
+ const t = `# Changelog
4
+
5
+ Recent product updates and deployment notes.
6
+
7
+ ## August 27, 2026 - Session sharing, pinned chats sync, and env-token Claude accounts (v0.6.15)
8
+
9
+ - **A Claude login held in \`CLAUDE_CODE_OAUTH_TOKEN\` now counts as a connected
10
+ account.** A box authenticated only through that variable showed the default
11
+ Claude account as disconnected, and the Coding Agents page asked for a login
12
+ that was not needed. Sessions launched from such a box worked the whole time,
13
+ so the page disagreed with the runtime. The account row now reads "From
14
+ CLAUDE_CODE_OAUTH_TOKEN", and the re-login button is hidden there, because the
15
+ variable outranks anything a browser sign-in stores. An isolated account no
16
+ longer inherits the variable, so accounts cannot all run on one login.
17
+ - **Hosted sessions show who they are shared with.** The session list carries an
18
+ assignee avatar, and a user filter menu narrows the list to one person.
19
+ - **Pinned chats now follow your account instead of one browser.** Pins are held
20
+ by the server, so a session pinned on one device appears pinned on the others.
21
+ - **The thread rail shows project favicons.** Each project in the rail carries
22
+ its own icon, and the activity marks beside it are simpler to read.
23
+ - **Voice failures now explain what to fix.** Batch dictation no longer goes
24
+ silent when a provider rejects a key, runs out of API credit, rate limits a
25
+ request, or cannot be reached. The server returns a stable safe error code,
26
+ and the composer shows an actionable message without exposing the provider's
27
+ response body. The mic also reports its starting and transcribing states to
28
+ assistive technology.
29
+ - **Long-press uses the native iPhone selection controls again.** A user can
30
+ select and adjust any part of a message, while the separate copy button
31
+ remains available for copying the whole message in one tap.
32
+ - **Swipe between chats is now optional per device.** The new switch under
33
+ Settings > More > This device disables only the horizontal chat-switching
34
+ gesture. Vertical scrolling, native text selection, and other gestures keep
35
+ working normally.
36
+ - **Opening the keyboard no longer scrolls the newest message away.** A
37
+ transcript pinned to the latest turn stays pinned when the soft keyboard
38
+ opens or closes.
39
+ - **Headings in an answer are no longer smaller than the text they introduce.**
40
+ A rule written for the user bubble was applying to every assistant reply, so
41
+ H1, H2 and H3 all rendered at 14px against 17px body text. The rule is now
42
+ scoped to the user bubble.
43
+ - **Computer Use refuses a debugging port that another process already holds.**
44
+ Before, a box that already had a browser on port 9222 reported a successful
45
+ start while Chrome had in fact exited. The desktop stayed empty and every
46
+ Computer Use call went to the other browser. The start now fails and says so.
47
+ - The onboarding survey is cut to two questions, and its analytics are posted to
48
+ the embedding host rather than sent from the sandboxed frame, where every
49
+ event was being dropped.
50
+ - **Deployment note:** pi resolves its proxy base from \`OMG_AI_URL\` when
51
+ \`ANTHROPIC_BASE_URL\` is unset. There is no behavior change while infra still
52
+ injects \`ANTHROPIC_BASE_URL\`, which keeps priority. This release must be
53
+ rebaked into the agent template before the infra side stops injecting the
54
+ vendor-named variable.
55
+
56
+ ## August 25, 2026 - OpenCode Go models appear without a Claude account (v0.6.14)
57
+
58
+ - **An OpenCode Go key alone now unlocks OpenCode's paid models.** If OpenCode
59
+ was the only agent signed in on a box, the picker showed the free Zen tier
60
+ and nothing else — even with a Go key connected and every \`opencode-go/*\`
61
+ model already discovered. The box was being treated as anonymous because the
62
+ "is someone signed in here" check counted only Claude and Codex. Anyone
63
+ paying for OpenCode Go and using nothing else was being billed for models the
64
+ picker hid from them.
65
+ - The check that stops a *Claude* account from unlocking OpenCode's paid
66
+ providers is unchanged. A box whose OpenCode was never signed into still gets
67
+ the free tier, because offering models that fail at launch is worse than
68
+ offering fewer.
69
+
70
+ ## August 25, 2026 - Pin a bot to a specific Claude account (v0.6.13)
71
+
72
+ - **The bot editor now lets you choose which Claude account a bot runs on.**
73
+ Open Edit bot, then Advanced. The agent row lists Claude - Auto and every
74
+ connected account, the same picker sessions and routines already had. Before,
75
+ a bot always fell back to the automatic account pick.
76
+ - Claude - Auto keeps the old behavior. It picks the connected account with the
77
+ most headroom at launch.
78
+ - Changing the account is a launch setting, so the bot reads "Update available"
79
+ after you save. The new account applies when you press Apply changes.
80
+ - A pinned account that is removed or signed out falls back to Claude - Auto.
81
+ The bot still starts.
82
+ - A bot created by another bot inherits that bot's account, the same way it
83
+ already inherits the repo and the owner.
84
+
85
+ ## August 25, 2026 - Tagging a bot with @ now reaches the bot (v0.6.12)
86
+
87
+ - **An \`@\` tag in a session chat delivers the message to that bot.** Before,
88
+ the tag was only text and routed nowhere. The tag carries the bot identity,
89
+ so renaming a bot or having two bots with the same name cannot send the
90
+ message to the wrong one.
91
+ - The tagged bot joins the conversation from the point it was tagged. It does
92
+ not read the earlier history of that session.
93
+ - A tag for a bot that is unknown, disabled, or restarting is reported instead
94
+ of being dropped without a word.
95
+ - **Note:** the tagged bot answers in its own chat. Its reply does not appear
96
+ in the session that tagged it.
97
+
98
+ ## August 25, 2026 - Tag a bot with @ in the composer (v0.6.11)
99
+
100
+ - **Typing \`@\` in the message box opens a bot picker.** Search your bots by
101
+ name, then press Enter or Tab to insert the tag. The picker is available in
102
+ every composer, including chat and the new-session box.
103
+ - The picker skips bots that are disabled, because a disabled bot cannot
104
+ accept a message. It does not open on an email address such as
105
+ \`name@example.com\`.
106
+ - The tag is text in the message. It does not notify or route to the bot yet.
107
+
108
+ ## August 25, 2026 - Mobile chat stays focused and Grok thoughts stay private (v0.6.10)
109
+
110
+ - **Grok reasoning no longer appears as an assistant answer while it streams.**
111
+ The live protocol now keeps thinking and answer text as separate typed data.
112
+ The fix does not inspect Grok text or depend on provider-specific markers.
113
+ - **Mobile chat keeps the hardware keyboard ready after send.** The composer
114
+ retains focus without reopening the software keyboard.
115
+ - **Live transcript motion is faster and the keyboard gap is gone.** New chat
116
+ activity reaches the bottom sooner, and the composer no longer leaves an
117
+ empty inset after the mobile keyboard closes.
118
+
119
+ ## August 25, 2026 - Switch bar says Schedules (v0.6.9)
120
+
121
+ - **The Chat / Bots / Schedules toggle now says Schedules.** The page heading
122
+ already used that word. The third segment was still labeled Scheduled.
123
+
124
+ ## August 25, 2026 - Chat streams more smoothly (v0.6.8)
125
+
126
+ - **Assistant markdown now uses Streamdown 2.6.** Word-by-word streaming
127
+ animation stays on one timeline, so sibling sections no longer fade in on
128
+ top of each other. The renderer also picks up the 2.6 accessibility and
129
+ download fixes. Long code and tables stay full height, so the transcript
130
+ layout model still matches what you see.
131
+ ## August 24, 2026 - Bot roster status is quieter (v0.6.7)
132
+
133
+ - **Unread is one small dot on its conversation row.** Unread rows no longer
134
+ use a blue outline or stronger text. Idle bots no longer show a status chip.
135
+ Working bots use one spinner and keep their latest message preview visible.
136
+
137
+ ## August 24, 2026 - Bot unread state stays quiet (v0.6.6)
138
+
139
+ - **Unread is now one clear dot.** The highlighted row and stronger text keep
140
+ unread conversations easy to scan without a label that crowds the bot name.
141
+ Working, Idle, and Disabled remain explicit and separate from unread state.
142
+
143
+ ## August 24, 2026 - Bot status and recent conversations stand out (v0.6.5)
144
+
145
+ - **Bot state is explicit.** Each roster row now labels the bot as Working,
146
+ Idle, or Disabled. Unread conversations have a larger badge, stronger text,
147
+ and a highlighted row. Activity and unread state stay separate, so a bot can
148
+ show both Working and Unread at the same time.
149
+ - **The newest bot conversation is first.** The desktop rail and mobile Bots
150
+ page now use the same recency order. Bots with no conversation stay at the
151
+ end.
152
+ - **Schedule names have more room on mobile.** The name now has its own line
153
+ instead of sharing a cramped row with the enable switch.
154
+
155
+ ## August 24, 2026 - Chat updates glide instead of jumping (v0.6.4)
156
+
157
+ - **New messages, tool calls, and the working indicator now move the chat
158
+ smoothly.** A time-based spring follows the live bottom of the transcript.
159
+ Streamed text and tool-status updates no longer cancel that motion and snap
160
+ the view. Changing sessions also no longer paints a provisional transcript
161
+ height that makes the layout flicker before it settles.
162
+ - **Computer control now follows the input device.** There is one Take control
163
+ toggle. A mouse points directly, while touch acts like a trackpad. A tap no
164
+ longer blocks the next drag, and agent browser input no longer shows a
165
+ desktop-wide lock that did not protect a shared resource.
166
+
167
+ ## August 24, 2026 - Hosted onboarding answers reach analytics (v0.6.3)
168
+
169
+ - **The hosted onboarding survey now sends answers through the host.** The
170
+ embedded package previously expected an analytics account at package-build
171
+ time. Release builds do not own one, so the survey event code compiled to a
172
+ no-op. The host now supplies the analytics handler that already identifies
173
+ the signed-in user. Role, friction, daily-tool, AI-tool, completion, and skip
174
+ results can reach the hosted product's existing analytics account.
175
+
176
+ ## August 24, 2026 - The Computer on a phone, and Schedules as a real list (v0.6.2)
177
+
178
+ - **The Computer survives a restart.** Its lifecycle used to live only in the
179
+ server's memory, so a deploy or a crash left the desktop running with nobody
180
+ holding it: the screen stayed up while the tab went dead, and the next start
181
+ failed because the ports were still taken. A restarted server now reattaches
182
+ to a healthy desktop instead of orphaning it, so a deploy is invisible to
183
+ whoever is watching and to an agent mid-task.
184
+ - **Touch works properly.** Dragging moves the pointer by offset, the way a
185
+ trackpad does, instead of teleporting it to wherever your finger landed --
186
+ which on a touchscreen put the target under your own hand. A tap clicks where
187
+ the cursor is. There is a keyboard button, because a canvas cannot take focus
188
+ on iOS and there was previously no way to raise the soft keyboard at all.
189
+ - **Opening the Computer starts it.** The Start button is gone: opening the
190
+ page was already the decision, and the progress indicator covers the wait.
191
+ - **Schedules is a list you can work.** The enable switch moves to the right
192
+ edge where a thumb already is, the agent icon becomes a quick switch, each
193
+ schedule fits on one line, and the findings banner is gone -- findings have
194
+ their own surface, and a banner about them was the loudest thing on a page
195
+ meant to be a list of schedules.
196
+ ## August 24, 2026 - Fix the release bundle (v0.6.1)
197
+
198
+ - **The v0.6.0 release bundle failed to build.** The Computer pulls in noVNC,
199
+ which ships top-level await, and the embedded-library build targeted a browser
200
+ set that predates it. The app build had already been raised; this config was
201
+ missed, so the app was fine and only the release bundle broke.
202
+
203
+ ## August 24, 2026 - The Computer: a desktop you and your agents share (v0.6.0)
204
+
205
+ - **This box now has a screen you can watch and take over.** The Computer is a
206
+ real desktop -- a window manager, a panel, a file manager, a terminal, and a
207
+ browser -- streamed into the app and controllable from it. Open it from the
208
+ Pages menu, press Take control, and you have the pointer and keyboard. On a
209
+ phone or tablet the usual gestures work: tap to click, two-finger tap for a
210
+ right click, drag to move, two-finger drag to scroll, pinch to zoom.
211
+ - **Agents drive the browser on that same screen.** A new Computer Use MCP gives
212
+ them navigate, click, type, press, read and screenshot. Because they work in a
213
+ visible window on the desktop you are watching, you see what they do as they
214
+ do it, rather than reading about it afterwards.
215
+ - **Chrome runs headful, not headless.** Headless Chrome announces itself in the
216
+ user agent and is trivially fingerprinted. This is an ordinary browser that
217
+ happens to have no monitor, with a persistent profile, so a site you sign into
218
+ stays signed in and an agent can pick up where you left off.
219
+ - **It costs nothing until you ask for it.** No part of the desktop is installed
220
+ by setup, and nothing starts until you press the button. The screen reaches
221
+ the browser over the existing websocket -- no extra proxy process and no new
222
+ runtime dependency.
223
+ - **The Computer Use MCP is off by default and separate from the omg MCP.** It
224
+ drives a screen that only exists where the desktop is installed, so it is its
225
+ own catalog with its own switch, next to the omg.dev MCP on the Coding agents
226
+ page rather than buried in Settings.
227
+
228
+ ## August 24, 2026 - Scrolling does what you tell it (v0.5.1)
229
+
230
+ - **The transcript no longer scrolls itself.** Following the newest message was
231
+ decided by measuring the distance to the bottom on every scroll event. That
232
+ works only while the total height is stable, and it stopped being stable when
233
+ the transcript started keeping only the visible rows in the page: a row that
234
+ comes into view replaces its estimated height with its real one, the total
235
+ moves, and the view could re-pin itself with no new message and no input from
236
+ you. Following is now a stored state that only a real gesture can change.
237
+ Scroll away and it stays away. Scroll back to the bottom, or press New
238
+ activity, and it follows again. A re-measure cannot change it. Nor can a
239
+ prepend, or the page correcting its own position. Keyboard scrolling counts
240
+ as a gesture now, which it did not before.
241
+ - **Tool calls send less over the wire.** The arguments of a tool call are no
242
+ longer streamed with the transcript. The name and the count are, which is all
243
+ a collapsed pill shows, and the arguments load when you open one. Measured on
244
+ real sessions this cuts a transcript load by 13 to 31 percent. The trade is
245
+ that opening a pill now waits for one small request.
246
+ - **Connection diagnostics are recorded again.** The browser posted five kinds
247
+ of websocket event to a route that had been deleted as unused, so every one
248
+ returned 404 and the client half of the connection record was lost. The route
249
+ is back. Only the browser knows the close code and the retry count, so the
250
+ server could not stand in for it.
251
+
252
+ ## August 24, 2026 - A transcript that stays fast, and can be searched (v0.5.0)
253
+
254
+ - **Tool-heavy sessions are readable again.** The transcript asked the server for
255
+ 80 raw messages, but the screen shows collapsed rows, and one run of tool calls
256
+ collapses into a single pill. A session that was mostly tool work therefore
257
+ arrived as three rows on an otherwise empty screen, and it could not page back,
258
+ because the page did not overflow and the backfill only ran when it did.
259
+ Paging is now measured in rows, so a page always carries enough to read. The
260
+ row rule has one definition that the server and the browser share.
261
+ - **A find bar for the transcript.** Virtualization keeps only the rows near the
262
+ viewport in the page, so the browser find command can only see those. Search
263
+ now runs on the server, over the whole session, and jumps to the row that
264
+ matched. It reports how many matches exist, walks forward and backward, and
265
+ keeps loading older pages while it hunts for a match that is not loaded yet.
266
+ It does not take over Control+F, because that would be a hostile default.
267
+ - **Sending a message during a reply no longer doubles the reply.** The chat
268
+ library appends a new copy of a message when the incoming update does not
269
+ match the end of the list. Sending mid-reply moved the reply away from the
270
+ end, so a second copy appeared, and the two drew on top of each other. The
271
+ live turn is now kept at the end, and an older copy of it is dropped.
272
+ - **Images no longer reload when you scroll back to them.** Off-screen rows are
273
+ removed from the page, so returning to an image used to download it again and
274
+ show the loading pulse again. Images and video now load in the element itself,
275
+ so the browser cache serves them. Video also seeks properly now, instead of
276
+ downloading the whole file first. The hosted surface keeps the previous path,
277
+ because it authenticates with a header.
278
+ `;
279
+ function s() {
280
+ return /* @__PURE__ */ e("div", { className: "mx-auto max-w-xl space-y-5 pb-10", children: /* @__PURE__ */ e("article", { className: "markdown rounded-2xl border border-border bg-card/40 px-4 py-4", children: /* @__PURE__ */ e(n, { children: t }) }) });
281
+ }
282
+ export {
283
+ s as default
284
+ };
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as s, Fragment as te } from "react/jsx-runtime";
2
2
  import { memo as ne, useState as m, useRef as T, useCallback as v, useEffect as C, useMemo as q, Suspense as U } from "react";
3
3
  import { createPortal as re } from "react-dom";
4
4
  import { cn as y } from "cnfast";
5
- import { f as oe, a3 as W, a4 as se, X as I, a5 as ie, a6 as ae, L as H, a7 as le, y as de, C as ce, a8 as L } from "./embedded-oaPwSSek.js";
5
+ import { f as oe, a3 as W, a4 as se, X as I, a5 as ie, a6 as ae, L as H, a7 as le, y as de, C as ce, a8 as L } from "./embedded-Ck10Okym.js";
6
6
  import { c as me } from "./create-CBk9uwJH.js";
7
7
  /**
8
8
  * @license lucide-react v0.577.0 - ISC
@@ -1,7 +1,7 @@
1
1
  import { jsxs as r, jsx as k, Fragment as vA } from "react/jsx-runtime";
2
2
  import { useState as L, useRef as R, useEffect as p, useCallback as q } from "react";
3
- import { f as UA, o as iQ, X as CA, a9 as wQ, y as sQ, aa as tQ, ab as eQ, a3 as aQ, ac as MQ, R as hQ, C as NQ } from "./embedded-oaPwSSek.js";
4
- import { K as ZA } from "./keyboard-M0kWYsLv.js";
3
+ import { f as UA, o as iQ, X as CA, a9 as wQ, y as sQ, aa as tQ, ab as eQ, a3 as aQ, ac as MQ, R as hQ, C as NQ } from "./embedded-Ck10Okym.js";
4
+ import { K as ZA } from "./keyboard-B8vaZRTC.js";
5
5
  /**
6
6
  * @license lucide-react v0.577.0 - ISC
7
7
  *
@@ -1,7 +1,7 @@
1
1
  import { jsx as ao } from "react/jsx-runtime";
2
2
  import { useRef as Dt, useCallback as Lt, useSyncExternalStore as ut, useEffect as so } from "react";
3
3
  import { g as io } from "./_commonjsHelpers-C6fGbg64.js";
4
- import { ad as uo } from "./embedded-oaPwSSek.js";
4
+ import { ad as uo } from "./embedded-Ck10Okym.js";
5
5
  var Ar = "vercel.ai.error", co = Symbol.for(Ar), Ut, Ft, se = class Nr extends (Ft = Error, Ut = co, Ft) {
6
6
  /**
7
7
  * Creates an AI SDK Error.
@@ -1,16 +1,16 @@
1
- import { jsxs as t, jsx as e, Fragment as B } from "react/jsx-runtime";
2
- import { R, B as d, L as $, n as A, o as S, M as H, p as j, q as I, s as h, T as E, u as D, v as W, w as P, x as X, y as J, X as Q, K as V } from "./embedded-oaPwSSek.js";
3
- import { cn as M } from "cnfast";
4
- import { useState as T } from "react";
5
- function O(s) {
1
+ import { jsxs as t, jsx as e, Fragment as O } from "react/jsx-runtime";
2
+ import { R, B as d, L as $, n as A, o as S, M as G, p as j, q as E, s as h, T as P, u as D, v as W, w as T, x as X, y as J, X as Q, K as V } from "./embedded-Ck10Okym.js";
3
+ import { cn as U } from "cnfast";
4
+ import { useState as I } from "react";
5
+ function B(s) {
6
6
  return /CLI$|runtime$/i.test(s);
7
7
  }
8
8
  function Y(s) {
9
- return s.some((a) => O(a.label) && !a.ok);
9
+ return s.some((a) => B(a.label) && !a.ok);
10
10
  }
11
11
  function Z(s) {
12
12
  const a = s.filter((r) => !r.ok);
13
- return a.length ? a.some((r) => O(r.label)) ? "Install" : "Connect" : null;
13
+ return a.length ? a.some((r) => B(r.label)) ? "Install" : "Connect" : null;
14
14
  }
15
15
  function ee(s) {
16
16
  const a = s.filter((r) => !r.ok);
@@ -62,7 +62,7 @@ function L({
62
62
  /* @__PURE__ */ e(
63
63
  X,
64
64
  {
65
- className: M(
65
+ className: U(
66
66
  "size-4 shrink-0 text-muted-foreground/60 transition-transform duration-150",
67
67
  u && "rotate-180"
68
68
  )
@@ -86,7 +86,7 @@ function te({
86
86
  /* @__PURE__ */ e("span", { className: "block truncate text-xs font-medium", children: s.label }),
87
87
  s.needsReconnect ? /* @__PURE__ */ e("span", { className: "block truncate text-[11px] text-destructive", children: "Sign-in expired" }) : s.detail || s.fromEnv ? /* @__PURE__ */ e("span", { className: "block truncate text-[11px] text-muted-foreground", children: s.detail ?? "From the environment" }) : null
88
88
  ] }),
89
- s.connected ? /* @__PURE__ */ t(B, { children: [
89
+ s.connected ? /* @__PURE__ */ t(O, { children: [
90
90
  /* @__PURE__ */ e("span", { className: "text-[11px] text-success", children: "Connected" }),
91
91
  s.fromEnv ? null : /* @__PURE__ */ e(
92
92
  "button",
@@ -96,7 +96,7 @@ function te({
96
96
  title: `Disconnect ${s.label}`,
97
97
  "aria-label": `Disconnect ${s.label}`,
98
98
  className: "flex size-7 items-center justify-center rounded-full text-muted-foreground transition hover:bg-destructive/10 hover:text-destructive",
99
- children: /* @__PURE__ */ e(E, { className: "size-3.5" })
99
+ children: /* @__PURE__ */ e(P, { className: "size-3.5" })
100
100
  }
101
101
  )
102
102
  ] }) : /* @__PURE__ */ t(d, { size: "sm", variant: "outline", onClick: () => a(s), children: [
@@ -115,19 +115,19 @@ function re({
115
115
  onRemoveClaudeAccount: u,
116
116
  onConnectProvider: x,
117
117
  onDisconnectProvider: b,
118
- onSetupCheck: U,
118
+ onSetupCheck: _,
119
119
  onRefresh: K,
120
120
  computerMcpEnabled: g,
121
- onComputerMcpChange: q
121
+ onComputerMcpChange: M
122
122
  }) {
123
- const [p, y] = T(!1), [v, C] = T(null), z = (n) => C((l) => l === n ? null : n);
123
+ const [p, y] = I(!1), [v, C] = I(null), z = (n) => C((i) => i === n ? null : n);
124
124
  async function F() {
125
125
  if (!p) {
126
126
  y(!0);
127
127
  try {
128
- await K(), P.success("Coding agents refreshed");
128
+ await K(), T.success("Coding agents refreshed");
129
129
  } catch (n) {
130
- P.error(n instanceof Error ? n.message : "Could not refresh coding agents");
130
+ T.error(n instanceof Error ? n.message : "Could not refresh coding agents");
131
131
  } finally {
132
132
  y(!1);
133
133
  }
@@ -144,7 +144,7 @@ function re({
144
144
  disabled: p,
145
145
  className: "flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50",
146
146
  children: [
147
- /* @__PURE__ */ e(R, { className: M("size-3.5", p && "animate-spin") }),
147
+ /* @__PURE__ */ e(R, { className: U("size-3.5", p && "animate-spin") }),
148
148
  "Refresh"
149
149
  ]
150
150
  }
@@ -162,14 +162,14 @@ function re({
162
162
  onToggle: () => z(`setup:${n.key}`),
163
163
  children: [
164
164
  /* @__PURE__ */ e(ne, { checks: n.checks }),
165
- n.instructions.map((l) => /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: l }, l)),
165
+ n.instructions.map((i) => /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: i }, i)),
166
166
  /* @__PURE__ */ t(
167
167
  d,
168
168
  {
169
169
  size: "sm",
170
170
  variant: "outline",
171
171
  disabled: !n.canAutoSetup || n.running,
172
- onClick: () => U(n.key),
172
+ onClick: () => _(n.key),
173
173
  title: n.canAutoSetup ? n.actionLabel : "Install a supported coding agent first",
174
174
  children: [
175
175
  n.running ? /* @__PURE__ */ e($, { className: "size-4 animate-spin" }) : /* @__PURE__ */ e(A, { className: "size-4" }),
@@ -183,7 +183,7 @@ function re({
183
183
  )),
184
184
  /* @__PURE__ */ t("div", { className: "flex items-center justify-between gap-4 px-4 py-3", children: [
185
185
  /* @__PURE__ */ t("div", { className: "flex min-w-0 items-center gap-3", children: [
186
- /* @__PURE__ */ e(H, { className: "size-4 shrink-0 text-muted-foreground" }),
186
+ /* @__PURE__ */ e(G, { className: "size-4 shrink-0 text-muted-foreground" }),
187
187
  /* @__PURE__ */ t("span", { className: "min-w-0", children: [
188
188
  /* @__PURE__ */ e("span", { className: "block truncate text-sm font-medium", children: "Computer Use MCP" }),
189
189
  /* @__PURE__ */ e("span", { className: "block text-xs text-muted-foreground", children: g ? "Agents can drive this box's desktop and browser." : "Off. Agents cannot see or drive the desktop." })
@@ -193,21 +193,21 @@ function re({
193
193
  j,
194
194
  {
195
195
  checked: g,
196
- onCheckedChange: q,
196
+ onCheckedChange: M,
197
197
  "aria-label": g ? "Disable the Computer Use MCP" : "Enable the Computer Use MCP"
198
198
  }
199
199
  )
200
200
  ] })
201
201
  ] }) : null,
202
202
  /* @__PURE__ */ e("div", { className: "overflow-hidden rounded-2xl border border-border bg-card/40 divide-y divide-border", children: a.map((n) => {
203
- const l = n.status, c = n.key === "aisdk" ? l.accounts ?? [] : [], k = l.providers ?? [], _ = c.some((i) => i.connected), G = c.length > 0 || k.length > 0, w = Y(l.checks);
203
+ const i = n.status, c = n.key === "aisdk" ? i.accounts ?? [] : [], k = i.providers ?? [], q = c.some((l) => l.connected), H = c.length > 0 || k.length > 0, w = Y(i.checks);
204
204
  return /* @__PURE__ */ t(
205
205
  L,
206
206
  {
207
- icon: /* @__PURE__ */ e("img", { src: I(n.key), alt: W(n.key), className: "size-5" }),
207
+ icon: /* @__PURE__ */ e("img", { src: E(n.key), alt: W(n.key), className: "size-5" }),
208
208
  title: n.label,
209
- note: Z(l.checks),
210
- ok: l.configured,
209
+ note: Z(i.checks),
210
+ ok: i.configured,
211
211
  showDot: !1,
212
212
  open: v === `agent:${n.key}`,
213
213
  onToggle: () => z(`agent:${n.key}`),
@@ -215,39 +215,40 @@ function re({
215
215
  j,
216
216
  {
217
217
  checked: n.visible,
218
- onCheckedChange: (i) => {
219
- if (i && !l.configured) {
218
+ onCheckedChange: (l) => {
219
+ if (l && !i.configured) {
220
220
  C(`agent:${n.key}`);
221
221
  return;
222
222
  }
223
- r(n.key, i);
223
+ r(n.key, l);
224
224
  },
225
225
  "aria-label": `${n.label} visible in composer`
226
226
  }
227
227
  ),
228
228
  children: [
229
- c.length ? /* @__PURE__ */ e("div", { className: "space-y-1.5", children: c.map((i) => /* @__PURE__ */ t(
229
+ c.length ? /* @__PURE__ */ e("div", { className: "space-y-1.5", children: c.map((l) => /* @__PURE__ */ t(
230
230
  "div",
231
231
  {
232
232
  className: "flex items-center gap-2 rounded-xl border border-border/70 bg-background/55 px-2.5 py-2",
233
233
  children: [
234
234
  /* @__PURE__ */ t("span", { className: "relative flex size-7 shrink-0 items-center justify-center rounded-full bg-muted", children: [
235
- /* @__PURE__ */ e("img", { src: I("aisdk"), alt: "", className: "size-4.5" }),
236
- /* @__PURE__ */ e("span", { className: "absolute -bottom-0.5 -right-0.5 flex size-3.5 items-center justify-center rounded-full bg-foreground text-[8px] font-bold text-background ring-1 ring-background", children: i.number })
235
+ /* @__PURE__ */ e("img", { src: E("aisdk"), alt: "", className: "size-4.5" }),
236
+ /* @__PURE__ */ e("span", { className: "absolute -bottom-0.5 -right-0.5 flex size-3.5 items-center justify-center rounded-full bg-foreground text-[8px] font-bold text-background ring-1 ring-background", children: l.number })
237
237
  ] }),
238
238
  /* @__PURE__ */ t("span", { className: "min-w-0 flex-1", children: [
239
- /* @__PURE__ */ e("span", { className: "block truncate text-xs font-medium", children: i.label }),
240
- i.needsReconnect ? /* @__PURE__ */ e("span", { className: "block truncate text-[11px] text-destructive", children: "Sign-in expired" }) : null
239
+ /* @__PURE__ */ e("span", { className: "block truncate text-xs font-medium", children: l.label }),
240
+ l.needsReconnect ? /* @__PURE__ */ e("span", { className: "block truncate text-[11px] text-destructive", children: "Sign-in expired" }) : null,
241
+ l.fromEnv ? /* @__PURE__ */ e("span", { className: "block truncate text-[11px] text-muted-foreground", children: "From CLAUDE_CODE_OAUTH_TOKEN" }) : null
241
242
  ] }),
242
- i.connected ? /* @__PURE__ */ t(B, { children: [
243
+ l.connected ? /* @__PURE__ */ t(O, { children: [
243
244
  /* @__PURE__ */ e("span", { className: "text-[11px] text-success", children: "Connected" }),
244
- /* @__PURE__ */ e(
245
+ l.fromEnv ? null : /* @__PURE__ */ e(
245
246
  "button",
246
247
  {
247
248
  type: "button",
248
- onClick: () => o(n.key, i.id),
249
- title: `Sign in to ${i.label} again`,
250
- "aria-label": `Sign in to ${i.label} again`,
249
+ onClick: () => o(n.key, l.id),
250
+ title: `Sign in to ${l.label} again`,
251
+ "aria-label": `Sign in to ${l.label} again`,
251
252
  className: "flex size-7 items-center justify-center rounded-full text-muted-foreground transition hover:bg-muted hover:text-foreground",
252
253
  children: /* @__PURE__ */ e(R, { className: "size-3.5" })
253
254
  }
@@ -257,32 +258,32 @@ function re({
257
258
  {
258
259
  size: "sm",
259
260
  variant: "outline",
260
- onClick: () => o(n.key, i.id),
261
+ onClick: () => o(n.key, l.id),
261
262
  children: [
262
263
  /* @__PURE__ */ e(h, { className: "size-3.5" }),
263
- i.needsReconnect ? "Reconnect" : "Connect"
264
+ l.needsReconnect ? "Reconnect" : "Connect"
264
265
  ]
265
266
  }
266
267
  ),
267
- i.removable ? /* @__PURE__ */ e(
268
+ l.removable ? /* @__PURE__ */ e(
268
269
  "button",
269
270
  {
270
271
  type: "button",
271
- onClick: () => u(i),
272
- title: `Remove ${i.label}`,
273
- "aria-label": `Remove ${i.label}`,
272
+ onClick: () => u(l),
273
+ title: `Remove ${l.label}`,
274
+ "aria-label": `Remove ${l.label}`,
274
275
  className: "flex size-7 items-center justify-center rounded-full text-muted-foreground transition hover:bg-destructive/10 hover:text-destructive",
275
- children: /* @__PURE__ */ e(E, { className: "size-3.5" })
276
+ children: /* @__PURE__ */ e(P, { className: "size-3.5" })
276
277
  }
277
278
  ) : null
278
279
  ]
279
280
  },
280
- i.id
281
+ l.id
281
282
  )) }) : null,
282
- k.length ? /* @__PURE__ */ e("div", { className: "space-y-1.5", children: k.map((i) => /* @__PURE__ */ e(
283
+ k.length ? /* @__PURE__ */ e("div", { className: "space-y-1.5", children: k.map((l) => /* @__PURE__ */ e(
283
284
  te,
284
285
  {
285
- provider: i,
286
+ provider: l,
286
287
  onConnect: (N) => {
287
288
  if (n.key === "jcode" && w) {
288
289
  m(n.key);
@@ -292,29 +293,29 @@ function re({
292
293
  },
293
294
  onDisconnect: (N) => b(n.key, N)
294
295
  },
295
- i.id
296
+ l.id
296
297
  )) }) : null,
297
298
  /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center gap-2", children: [
298
- l.canAutoSetup && w ? /* @__PURE__ */ t(
299
+ i.canAutoSetup && w ? /* @__PURE__ */ t(
299
300
  d,
300
301
  {
301
302
  size: "sm",
302
303
  variant: "outline",
303
- disabled: l.setupRunning,
304
+ disabled: i.setupRunning,
304
305
  onClick: () => m(n.key),
305
306
  title: "Run setup for this agent",
306
307
  children: [
307
- l.setupRunning ? /* @__PURE__ */ e($, { className: "size-4 animate-spin" }) : /* @__PURE__ */ e(A, { className: "size-4" }),
308
- l.setupRunning ? "Running…" : "Install"
308
+ i.setupRunning ? /* @__PURE__ */ e($, { className: "size-4 animate-spin" }) : /* @__PURE__ */ e(A, { className: "size-4" }),
309
+ i.setupRunning ? "Running…" : "Install"
309
310
  ]
310
311
  }
311
312
  ) : null,
312
- c.length && _ ? /* @__PURE__ */ t(
313
+ c.length && q ? /* @__PURE__ */ t(
313
314
  d,
314
315
  {
315
316
  size: "sm",
316
317
  variant: "outline",
317
- disabled: l.setupRunning,
318
+ disabled: i.setupRunning,
318
319
  onClick: () => f(),
319
320
  title: "Add another Claude account",
320
321
  children: [
@@ -323,14 +324,14 @@ function re({
323
324
  ]
324
325
  }
325
326
  ) : null,
326
- l.canLoginInTerminal && !G ? /* @__PURE__ */ t(
327
+ i.canLoginInTerminal && !H ? /* @__PURE__ */ t(
327
328
  d,
328
329
  {
329
330
  size: "sm",
330
331
  variant: "outline",
331
- disabled: l.setupRunning,
332
+ disabled: i.setupRunning,
332
333
  onClick: () => o(n.key),
333
- title: n.key === "aisdk" && c.length ? "Add another Claude account" : D.has(n.key) ? `Sign in to ${n.label} in your browser` : `Open terminal and run ${l.loginCommand}`,
334
+ title: n.key === "aisdk" && c.length ? "Add another Claude account" : D.has(n.key) ? `Sign in to ${n.label} in your browser` : `Open terminal and run ${i.loginCommand}`,
334
335
  children: [
335
336
  D.has(n.key) ? /* @__PURE__ */ e(h, { className: "size-4" }) : /* @__PURE__ */ e(S, { className: "size-4" }),
336
337
  "Login"
@@ -1,7 +1,7 @@
1
1
  import { jsxs as pe, jsx as J, Fragment as zt } from "react/jsx-runtime";
2
2
  import { useState as Ve, useRef as Qe, useCallback as ve, useEffect as Le } from "react";
3
- import { f as Fn, a3 as Ai, ab as Mn, B as Ge, R as Tn, X as Qn, L as Xi, ae as Ln } from "./embedded-oaPwSSek.js";
4
- import { K as Rn } from "./keyboard-M0kWYsLv.js";
3
+ import { f as Fn, a3 as Ai, ab as Mn, B as Ge, R as Tn, X as Qn, L as Xi, ae as Ln } from "./embedded-Ck10Okym.js";
4
+ import { K as Rn } from "./keyboard-B8vaZRTC.js";
5
5
  /**
6
6
  * @license lucide-react v0.577.0 - ISC
7
7
  *