arp-tui 0.0.2 → 0.0.3

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.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { parseArgs as nodeParseArgs } from "util";
5
5
  import { render } from "ink";
6
6
 
7
7
  // src/app.tsx
8
- import { Box as Box7, Text as Text9, useApp, useInput, useStdin } from "ink";
8
+ import { Box as Box8, Text as Text10, useApp, useInput, useStdin } from "ink";
9
9
  import { useEffect, useSyncExternalStore } from "react";
10
10
 
11
11
  // src/state/store.ts
@@ -968,6 +968,73 @@ var RelayRest = class {
968
968
  }
969
969
  };
970
970
 
971
+ // src/state/activityFold.ts
972
+ function eventTs(e) {
973
+ return typeof e.ts === "number" && Number.isFinite(e.ts) ? e.ts : 0;
974
+ }
975
+ function supersedes(nextTs, nextOrder, prevTs, prevOrder) {
976
+ if (nextTs !== prevTs) return nextTs > prevTs;
977
+ return nextOrder >= prevOrder;
978
+ }
979
+ function foldActivityEvents(events) {
980
+ const turns = /* @__PURE__ */ new Map();
981
+ events.forEach((e, idx) => {
982
+ if (!e.turnId || !e.toolCallId) return;
983
+ let turn = turns.get(e.turnId);
984
+ if (!turn) {
985
+ turn = { order: [], calls: /* @__PURE__ */ new Map() };
986
+ turns.set(e.turnId, turn);
987
+ }
988
+ const ts = eventTs(e);
989
+ const existing = turn.calls.get(e.toolCallId);
990
+ if (!existing) {
991
+ turn.order.push(e.toolCallId);
992
+ turn.calls.set(e.toolCallId, {
993
+ toolCallId: e.toolCallId,
994
+ turnId: e.turnId,
995
+ agentId: e.agentId,
996
+ kind: e.kind,
997
+ title: e.title,
998
+ status: e.status,
999
+ locations: e.locations,
1000
+ ts,
1001
+ _winTs: ts,
1002
+ _winOrder: idx
1003
+ });
1004
+ return;
1005
+ }
1006
+ if (supersedes(ts, idx, existing._winTs, existing._winOrder)) {
1007
+ if (e.kind !== void 0) existing.kind = e.kind;
1008
+ if (e.title !== void 0) existing.title = e.title;
1009
+ if (e.status !== void 0) existing.status = e.status;
1010
+ if (e.locations !== void 0) existing.locations = e.locations;
1011
+ if (e.agentId) existing.agentId = e.agentId;
1012
+ existing.ts = ts;
1013
+ existing._winTs = ts;
1014
+ existing._winOrder = idx;
1015
+ } else {
1016
+ if (existing.kind === void 0 && e.kind !== void 0) existing.kind = e.kind;
1017
+ if (existing.title === void 0 && e.title !== void 0) existing.title = e.title;
1018
+ if (existing.status === void 0 && e.status !== void 0) existing.status = e.status;
1019
+ if (existing.locations === void 0 && e.locations !== void 0) existing.locations = e.locations;
1020
+ }
1021
+ });
1022
+ const out = /* @__PURE__ */ new Map();
1023
+ for (const [turnId, turn] of turns) {
1024
+ out.set(
1025
+ turnId,
1026
+ turn.order.map((tcId) => {
1027
+ const c = turn.calls.get(tcId);
1028
+ const { _winTs, _winOrder, ...pub } = c;
1029
+ void _winTs;
1030
+ void _winOrder;
1031
+ return pub;
1032
+ })
1033
+ );
1034
+ }
1035
+ return out;
1036
+ }
1037
+
971
1038
  // src/state/priority.ts
972
1039
  function channelPriority(cid, p) {
973
1040
  const level = p.attention[cid]?.highestLevel;
@@ -1235,6 +1302,10 @@ var IDLE_CHECK_MS = 3e4;
1235
1302
  var TICK_MS = 1e4;
1236
1303
  var ACTIVITY_AUTOCLEAR_MS = 6e4;
1237
1304
  var RENDER_THROTTLE_MS = 250;
1305
+ var MAX_ACTIVITY_TURNS = 8;
1306
+ var MAX_TOOL_CALLS_PER_TURN = 50;
1307
+ var MAX_RAW_EVENTS_PER_TURN = 200;
1308
+ var ACTIVITY_SETTLE_MS = 4e3;
1238
1309
  function createStore(opts) {
1239
1310
  const instance2 = opts.instance;
1240
1311
  const relayUrl = instance2.relayUrl;
@@ -1272,7 +1343,11 @@ function createStore(opts) {
1272
1343
  unreadCapNotice: null,
1273
1344
  attention: {},
1274
1345
  notifications: [],
1275
- notifSelected: 0
1346
+ notifSelected: 0,
1347
+ activityByTurn: {},
1348
+ plansByTurn: {},
1349
+ activityPinned: false,
1350
+ activityIdleSince: null
1276
1351
  };
1277
1352
  let lastNotifyAt = 0;
1278
1353
  let notifyTimer = null;
@@ -1591,6 +1666,42 @@ function createStore(opts) {
1591
1666
  scheduleActivitySweep();
1592
1667
  }
1593
1668
  }
1669
+ let rawActivityByTurn = /* @__PURE__ */ new Map();
1670
+ let activitySettleTimer = null;
1671
+ function activityIsLive() {
1672
+ for (const rows of Object.values(state.activityByTurn))
1673
+ for (const r of rows) if (r.status === "pending" || r.status === "in_progress") return true;
1674
+ for (const entries of Object.values(state.plansByTurn))
1675
+ for (const e of entries) if (e.status !== "completed") return true;
1676
+ return false;
1677
+ }
1678
+ function evictOldestTurns(rec) {
1679
+ const keys = Object.keys(rec);
1680
+ if (keys.length <= MAX_ACTIVITY_TURNS) return rec;
1681
+ const drop = keys.slice(0, keys.length - MAX_ACTIVITY_TURNS);
1682
+ const next = { ...rec };
1683
+ for (const k of drop) delete next[k];
1684
+ return next;
1685
+ }
1686
+ function reconcileActivitySettle() {
1687
+ if (activityIsLive()) {
1688
+ if (activitySettleTimer) {
1689
+ clearTimeout(activitySettleTimer);
1690
+ activitySettleTimer = null;
1691
+ }
1692
+ if (state.activityIdleSince !== null) setThrottled({ activityIdleSince: null });
1693
+ return;
1694
+ }
1695
+ if (state.activityIdleSince === null) setThrottled({ activityIdleSince: Date.now() });
1696
+ if (activitySettleTimer) return;
1697
+ activitySettleTimer = setTimeout(() => {
1698
+ activitySettleTimer = null;
1699
+ setThrottled({});
1700
+ }, ACTIVITY_SETTLE_MS);
1701
+ }
1702
+ function togglePin() {
1703
+ set({ activityPinned: !state.activityPinned });
1704
+ }
1594
1705
  let countdownTimer = null;
1595
1706
  function syncCountdown(s) {
1596
1707
  if (s === "reconnecting" && !countdownTimer) {
@@ -1692,6 +1803,42 @@ function createStore(opts) {
1692
1803
  pushDivider("channel archived");
1693
1804
  return;
1694
1805
  }
1806
+ case "activity_event": {
1807
+ if (frame.channelId !== state.activeChannelId) return;
1808
+ if (!frame.turnId || !frame.toolCallId) return;
1809
+ const ev = {
1810
+ turnId: frame.turnId,
1811
+ toolCallId: frame.toolCallId,
1812
+ agentId: frame.agentId,
1813
+ kind: frame.kind,
1814
+ title: frame.title,
1815
+ status: frame.status,
1816
+ locations: frame.locations,
1817
+ ts: frame.ts
1818
+ };
1819
+ const list = [...rawActivityByTurn.get(frame.turnId) ?? [], ev];
1820
+ if (list.length > MAX_RAW_EVENTS_PER_TURN) list.splice(0, list.length - MAX_RAW_EVENTS_PER_TURN);
1821
+ rawActivityByTurn.set(frame.turnId, list);
1822
+ while (rawActivityByTurn.size > MAX_ACTIVITY_TURNS) {
1823
+ const oldest = rawActivityByTurn.keys().next().value;
1824
+ rawActivityByTurn.delete(oldest);
1825
+ }
1826
+ const foldedMap = foldActivityEvents(Array.from(rawActivityByTurn.values()).flat());
1827
+ let activityByTurn = {};
1828
+ for (const [tid, rows] of foldedMap) activityByTurn[tid] = rows.slice(0, MAX_TOOL_CALLS_PER_TURN);
1829
+ activityByTurn = evictOldestTurns(activityByTurn);
1830
+ setThrottled({ activityByTurn });
1831
+ reconcileActivitySettle();
1832
+ return;
1833
+ }
1834
+ case "plan_update": {
1835
+ if (frame.channelId !== state.activeChannelId) return;
1836
+ if (!frame.turnId) return;
1837
+ const plansByTurn = evictOldestTurns({ ...state.plansByTurn, [frame.turnId]: frame.entries ?? [] });
1838
+ setThrottled({ plansByTurn });
1839
+ reconcileActivitySettle();
1840
+ return;
1841
+ }
1695
1842
  default:
1696
1843
  return;
1697
1844
  }
@@ -1853,8 +2000,16 @@ function createStore(opts) {
1853
2000
  mode: "normal",
1854
2001
  switcherFilter: "",
1855
2002
  lastSeq: config.lastSeq?.[channelId] ?? null,
1856
- error: null
2003
+ error: null,
2004
+ activityByTurn: {},
2005
+ plansByTurn: {},
2006
+ activityIdleSince: null
1857
2007
  });
2008
+ rawActivityByTurn = /* @__PURE__ */ new Map();
2009
+ if (activitySettleTimer) {
2010
+ clearTimeout(activitySettleTimer);
2011
+ activitySettleTimer = null;
2012
+ }
1858
2013
  clearUnread(channelId);
1859
2014
  ws.subscribe(channelId);
1860
2015
  config = { ...config, lastChannelId: channelId };
@@ -1890,6 +2045,10 @@ function createStore(opts) {
1890
2045
  if (idleTimer) clearInterval(idleTimer);
1891
2046
  if (tickTimer) clearInterval(tickTimer);
1892
2047
  if (activitySweep) clearTimeout(activitySweep);
2048
+ if (activitySettleTimer) {
2049
+ clearTimeout(activitySettleTimer);
2050
+ activitySettleTimer = null;
2051
+ }
1893
2052
  if (countdownTimer) clearInterval(countdownTimer);
1894
2053
  if (attentionTimer) {
1895
2054
  clearInterval(attentionTimer);
@@ -1931,6 +2090,7 @@ function createStore(opts) {
1931
2090
  const target = nextActiveChannel(s.channels, s.activeChannelId, { attention: s.attention, unread: s.unread });
1932
2091
  if (target) openChannel(target.id);
1933
2092
  },
2093
+ toggleActivityPin: () => togglePin(),
1934
2094
  quit
1935
2095
  };
1936
2096
  }
@@ -1968,9 +2128,95 @@ function ActivityLine({ activities }) {
1968
2128
  ] });
1969
2129
  }
1970
2130
 
1971
- // src/ui/ChannelSwitcher.tsx
2131
+ // src/ui/ActivitySurface.tsx
1972
2132
  import { Box, Text as Text2 } from "ink";
1973
2133
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2134
+ function statusGlyph(status) {
2135
+ switch (status) {
2136
+ case "completed":
2137
+ return "\u2713";
2138
+ case "failed":
2139
+ return "\u2717";
2140
+ case "in_progress":
2141
+ return "\u22EF";
2142
+ case "pending":
2143
+ return "\u25CB";
2144
+ default:
2145
+ return "\xB7";
2146
+ }
2147
+ }
2148
+ function kindGlyph(kind) {
2149
+ switch (kind) {
2150
+ case "read":
2151
+ return "r";
2152
+ case "edit":
2153
+ return "e";
2154
+ case "write":
2155
+ return "w";
2156
+ case "run":
2157
+ return "\u25B6";
2158
+ case "search":
2159
+ return "s";
2160
+ case "fetch":
2161
+ return "f";
2162
+ case "task":
2163
+ return "t";
2164
+ default:
2165
+ return "\xB7";
2166
+ }
2167
+ }
2168
+ function planGlyph(status) {
2169
+ switch (status) {
2170
+ case "completed":
2171
+ return "[x]";
2172
+ case "in_progress":
2173
+ return "[~]";
2174
+ default:
2175
+ return "[ ]";
2176
+ }
2177
+ }
2178
+ function fallbackTitle(call) {
2179
+ if (call.title) return call.title;
2180
+ if (call.kind) return call.kind.charAt(0).toUpperCase() + call.kind.slice(1);
2181
+ return "Tool call";
2182
+ }
2183
+ function ActivitySurface(props) {
2184
+ const { toolCalls, plan, visible, pinned } = props;
2185
+ if (!visible) return null;
2186
+ if (toolCalls.length === 0 && plan.length === 0) {
2187
+ return /* @__PURE__ */ jsx2(Box, { paddingLeft: 1, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "no activity yet" }) });
2188
+ }
2189
+ return /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", paddingLeft: 1, children: [
2190
+ toolCalls.length > 0 && /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", children: [
2191
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "tool calls \xB7 only you can see this" }),
2192
+ toolCalls.map((call) => /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", children: [
2193
+ /* @__PURE__ */ jsxs2(Text2, { children: [
2194
+ statusGlyph(call.status),
2195
+ " ",
2196
+ kindGlyph(call.kind),
2197
+ " ",
2198
+ sanitizeLabel(fallbackTitle(call), 48)
2199
+ ] }),
2200
+ pinned && call.locations && call.locations.length > 0 && /* @__PURE__ */ jsx2(Box, { flexDirection: "column", paddingLeft: 2, children: call.locations.map((loc, i) => /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2201
+ sanitizeLabel(loc.path, 60),
2202
+ loc.line != null ? `:${loc.line}` : ""
2203
+ ] }, i)) })
2204
+ ] }, call.toolCallId))
2205
+ ] }),
2206
+ plan.length > 0 && /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", children: [
2207
+ /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "plan \xB7 shared with the channel" }),
2208
+ plan.map((entry, i) => /* @__PURE__ */ jsxs2(Text2, { dimColor: entry.status === "completed", children: [
2209
+ planGlyph(entry.status),
2210
+ " ",
2211
+ sanitizeForTty(entry.content)
2212
+ ] }, i))
2213
+ ] })
2214
+ ] });
2215
+ }
2216
+
2217
+ // src/ui/ChannelSwitcher.tsx
2218
+ import { Box as Box2, Text as Text3 } from "ink";
2219
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1974
2220
  function channelLabel(ch) {
1975
2221
  return `${channelSigil(ch.kind)}${sanitizeLabel(ch.name)}`;
1976
2222
  }
@@ -1985,7 +2231,7 @@ function ChannelBadge({
1985
2231
  if (att) {
1986
2232
  const color = att.highestLevel === "critical" ? "red" : att.highestLevel === "action_required" ? "yellow" : "cyan";
1987
2233
  const sigil = att.highestLevel === "critical" ? "!" : att.highestLevel === "action_required" ? "\u25B2" : "\u2022";
1988
- return /* @__PURE__ */ jsxs2(Text2, { color, children: [
2234
+ return /* @__PURE__ */ jsxs3(Text3, { color, children: [
1989
2235
  " ",
1990
2236
  "[",
1991
2237
  sigil,
@@ -1995,7 +2241,7 @@ function ChannelBadge({
1995
2241
  }
1996
2242
  const count = unread[channelId] ?? 0;
1997
2243
  if (count > 0) {
1998
- return /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2244
+ return /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
1999
2245
  " (",
2000
2246
  count,
2001
2247
  ")"
@@ -2014,11 +2260,11 @@ function ChannelSwitcher({
2014
2260
  const sorted = sortChannelsByPriority(filtered, { attention, unread });
2015
2261
  const visible = sorted.slice(0, 9);
2016
2262
  const hidden = sorted.length - visible.length;
2017
- return /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
2018
- /* @__PURE__ */ jsxs2(Text2, { bold: true, children: [
2263
+ return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
2264
+ /* @__PURE__ */ jsxs3(Text3, { bold: true, children: [
2019
2265
  "channels",
2020
2266
  " ",
2021
- /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2267
+ /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
2022
2268
  "(",
2023
2269
  sorted.length,
2024
2270
  "/",
@@ -2026,23 +2272,23 @@ function ChannelSwitcher({
2026
2272
  ")"
2027
2273
  ] })
2028
2274
  ] }),
2029
- /* @__PURE__ */ jsxs2(Text2, { children: [
2030
- /* @__PURE__ */ jsx2(Text2, { color: "cyan", children: "filter: " }),
2031
- /* @__PURE__ */ jsx2(Text2, { children: sanitizeLabel(filter, 40) }),
2032
- /* @__PURE__ */ jsx2(Text2, { inverse: true, children: " " })
2275
+ /* @__PURE__ */ jsxs3(Text3, { children: [
2276
+ /* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "filter: " }),
2277
+ /* @__PURE__ */ jsx3(Text3, { children: sanitizeLabel(filter, 40) }),
2278
+ /* @__PURE__ */ jsx3(Text3, { inverse: true, children: " " })
2033
2279
  ] }),
2034
- visible.map((ch, i) => /* @__PURE__ */ jsxs2(Text2, { children: [
2035
- /* @__PURE__ */ jsxs2(Text2, { color: "cyan", children: [
2280
+ visible.map((ch, i) => /* @__PURE__ */ jsxs3(Text3, { children: [
2281
+ /* @__PURE__ */ jsxs3(Text3, { color: "cyan", children: [
2036
2282
  i + 1,
2037
2283
  " "
2038
2284
  ] }),
2039
- /* @__PURE__ */ jsx2(Text2, { bold: ch.id === activeChannelId, children: channelLabel(ch) }),
2040
- /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2285
+ /* @__PURE__ */ jsx3(Text3, { bold: ch.id === activeChannelId, children: channelLabel(ch) }),
2286
+ /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
2041
2287
  " \xB7 ",
2042
2288
  ch.members.length,
2043
2289
  " members"
2044
2290
  ] }),
2045
- /* @__PURE__ */ jsx2(
2291
+ /* @__PURE__ */ jsx3(
2046
2292
  ChannelBadge,
2047
2293
  {
2048
2294
  channelId: ch.id,
@@ -2052,36 +2298,36 @@ function ChannelSwitcher({
2052
2298
  }
2053
2299
  )
2054
2300
  ] }, ch.id)),
2055
- hidden > 0 ? /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2301
+ hidden > 0 ? /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
2056
2302
  "\u2026",
2057
2303
  hidden,
2058
2304
  " more \u2014 keep typing to narrow"
2059
2305
  ] }) : null,
2060
- sorted.length === 0 ? /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2306
+ sorted.length === 0 ? /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
2061
2307
  'no channels match "',
2062
2308
  sanitizeLabel(filter, 20),
2063
2309
  '"'
2064
2310
  ] }) : null,
2065
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: filter.length === 0 ? "type to filter \xB7 1\u20139 quick-select \xB7 n jump \xB7 Esc cancel" : "keep typing to narrow \xB7 Enter opens top match \xB7 Esc cancel" })
2311
+ /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: filter.length === 0 ? "type to filter \xB7 1\u20139 quick-select \xB7 n jump \xB7 Esc cancel" : "keep typing to narrow \xB7 Enter opens top match \xB7 Esc cancel" })
2066
2312
  ] });
2067
2313
  }
2068
2314
 
2069
2315
  // src/ui/Composer.tsx
2070
- import { Box as Box2, Text as Text3 } from "ink";
2071
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2316
+ import { Box as Box3, Text as Text4 } from "ink";
2317
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2072
2318
  function Composer({ draft, focused }) {
2073
2319
  const width = Math.max((process.stdout.columns ?? 80) - 8, 20);
2074
2320
  const visible = draft.length > width ? "\u2026" + draft.slice(-(width - 1)) : draft;
2075
- return /* @__PURE__ */ jsx3(Box2, { borderStyle: "round", borderColor: focused ? "cyan" : "gray", paddingX: 1, width: "100%", children: /* @__PURE__ */ jsxs3(Text3, { wrap: "truncate", children: [
2076
- /* @__PURE__ */ jsx3(Text3, { color: focused ? "cyan" : "gray", children: "> " }),
2077
- draft.length === 0 && !focused ? /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "i to compose" }) : /* @__PURE__ */ jsx3(Text3, { children: visible }),
2078
- focused ? /* @__PURE__ */ jsx3(Text3, { inverse: true, children: " " }) : null
2321
+ return /* @__PURE__ */ jsx4(Box3, { borderStyle: "round", borderColor: focused ? "cyan" : "gray", paddingX: 1, width: "100%", children: /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate", children: [
2322
+ /* @__PURE__ */ jsx4(Text4, { color: focused ? "cyan" : "gray", children: "> " }),
2323
+ draft.length === 0 && !focused ? /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "i to compose" }) : /* @__PURE__ */ jsx4(Text4, { children: visible }),
2324
+ focused ? /* @__PURE__ */ jsx4(Text4, { inverse: true, children: " " }) : null
2079
2325
  ] }) });
2080
2326
  }
2081
2327
 
2082
2328
  // src/ui/Header.tsx
2083
- import { Box as Box3, Text as Text4 } from "ink";
2084
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2329
+ import { Box as Box4, Text as Text5 } from "ink";
2330
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2085
2331
  var STATUS_DOT = {
2086
2332
  online: { glyph: "\u25CF", color: "green" },
2087
2333
  away: { glyph: "\u25D0", color: "yellow" },
@@ -2098,32 +2344,32 @@ function Header({
2098
2344
  members,
2099
2345
  presence
2100
2346
  }) {
2101
- return /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", children: [
2102
- /* @__PURE__ */ jsxs4(Box3, { justifyContent: "space-between", children: [
2103
- /* @__PURE__ */ jsxs4(Text4, { children: [
2104
- /* @__PURE__ */ jsx4(Text4, { color: "cyan", bold: true, children: "arp-tui" }),
2105
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: " \u25B8 " }),
2106
- /* @__PURE__ */ jsxs4(Text4, { bold: true, children: [
2347
+ return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", children: [
2348
+ /* @__PURE__ */ jsxs5(Box4, { justifyContent: "space-between", children: [
2349
+ /* @__PURE__ */ jsxs5(Text5, { children: [
2350
+ /* @__PURE__ */ jsx5(Text5, { color: "cyan", bold: true, children: "arp-tui" }),
2351
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " \u25B8 " }),
2352
+ /* @__PURE__ */ jsxs5(Text5, { bold: true, children: [
2107
2353
  channelSigil(channelKind),
2108
2354
  sanitizeLabel(channelName)
2109
2355
  ] })
2110
2356
  ] }),
2111
- /* @__PURE__ */ jsx4(Text4, { children: members.map((m) => {
2357
+ /* @__PURE__ */ jsx5(Text5, { children: members.map((m) => {
2112
2358
  const dot = STATUS_DOT[effectiveStatus(m, presence)];
2113
- return /* @__PURE__ */ jsxs4(Text4, { children: [
2114
- /* @__PURE__ */ jsxs4(Text4, { color: dot.color, children: [
2359
+ return /* @__PURE__ */ jsxs5(Text5, { children: [
2360
+ /* @__PURE__ */ jsxs5(Text5, { color: dot.color, children: [
2115
2361
  dot.glyph,
2116
2362
  " "
2117
2363
  ] }),
2118
- /* @__PURE__ */ jsxs4(Text4, { dimColor: effectiveStatus(m, presence) === "offline", children: [
2364
+ /* @__PURE__ */ jsxs5(Text5, { dimColor: effectiveStatus(m, presence) === "offline", children: [
2119
2365
  m.type === "bot" ? "\u2699" : "",
2120
2366
  sanitizeLabel(m.name, 20)
2121
2367
  ] }),
2122
- /* @__PURE__ */ jsx4(Text4, { children: " " })
2368
+ /* @__PURE__ */ jsx5(Text5, { children: " " })
2123
2369
  ] }, m.id);
2124
2370
  }) })
2125
2371
  ] }),
2126
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\u2500".repeat(Math.min(process.stdout.columns ?? 80, 100)) })
2372
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "\u2500".repeat(Math.min(process.stdout.columns ?? 80, 100)) })
2127
2373
  ] });
2128
2374
  }
2129
2375
 
@@ -2131,8 +2377,8 @@ function Header({
2131
2377
  import { Static } from "ink";
2132
2378
 
2133
2379
  // src/ui/MessageRow.tsx
2134
- import { Box as Box4, Text as Text5 } from "ink";
2135
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2380
+ import { Box as Box5, Text as Text6 } from "ink";
2381
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2136
2382
  function hhmm(rfc3339) {
2137
2383
  const d = new Date(rfc3339);
2138
2384
  return isNaN(d.getTime()) ? "--:--" : `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
@@ -2145,7 +2391,7 @@ function TokenChip({ message }) {
2145
2391
  if (message.messageType !== "agent" || !message.tokensUsed) return null;
2146
2392
  const parts = [`${formatTokens(message.tokensUsed)} tok`];
2147
2393
  if (message.model) parts.push(sanitizeLabel(message.model, 16));
2148
- return /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
2394
+ return /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2149
2395
  message.verified ? "\u2713 " : "",
2150
2396
  parts.join(" \xB7 ")
2151
2397
  ] });
@@ -2155,41 +2401,41 @@ function MessageRow({ message }) {
2155
2401
  const isSystem = message.messageType === "system";
2156
2402
  const name = sanitizeLabel(message.agentName, 20);
2157
2403
  if (isSystem) {
2158
- return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsxs5(Text5, { dimColor: true, italic: true, children: [
2404
+ return /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsxs6(Text6, { dimColor: true, italic: true, children: [
2159
2405
  " ",
2160
2406
  "\u2500\u2500 ",
2161
2407
  sanitizeForTty(message.content),
2162
2408
  " \u2500\u2500"
2163
2409
  ] }) });
2164
2410
  }
2165
- return /* @__PURE__ */ jsxs5(Box4, { justifyContent: "space-between", gap: 2, children: [
2166
- /* @__PURE__ */ jsx5(Box4, { flexShrink: 1, children: /* @__PURE__ */ jsxs5(Text5, { children: [
2167
- /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
2411
+ return /* @__PURE__ */ jsxs6(Box5, { justifyContent: "space-between", gap: 2, children: [
2412
+ /* @__PURE__ */ jsx6(Box5, { flexShrink: 1, children: /* @__PURE__ */ jsxs6(Text6, { children: [
2413
+ /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2168
2414
  hhmm(message.createdAt),
2169
2415
  " "
2170
2416
  ] }),
2171
- /* @__PURE__ */ jsxs5(Text5, { color: isBot ? "magenta" : "cyan", bold: !isBot, children: [
2417
+ /* @__PURE__ */ jsxs6(Text6, { color: isBot ? "magenta" : "cyan", bold: !isBot, children: [
2172
2418
  isBot ? "\u2699" : "",
2173
2419
  name.padEnd(12)
2174
2420
  ] }),
2175
- /* @__PURE__ */ jsxs5(Text5, { children: [
2421
+ /* @__PURE__ */ jsxs6(Text6, { children: [
2176
2422
  " ",
2177
2423
  sanitizeForTty(message.content)
2178
2424
  ] })
2179
2425
  ] }) }),
2180
- /* @__PURE__ */ jsx5(Box4, { flexShrink: 0, children: /* @__PURE__ */ jsx5(TokenChip, { message }) })
2426
+ /* @__PURE__ */ jsx6(Box5, { flexShrink: 0, children: /* @__PURE__ */ jsx6(TokenChip, { message }) })
2181
2427
  ] });
2182
2428
  }
2183
2429
 
2184
2430
  // src/ui/MessageList.tsx
2185
- import { jsx as jsx6 } from "react/jsx-runtime";
2431
+ import { jsx as jsx7 } from "react/jsx-runtime";
2186
2432
  function MessageList({ messages }) {
2187
- return /* @__PURE__ */ jsx6(Static, { items: messages, children: (m) => /* @__PURE__ */ jsx6(MessageRow, { message: m }, m.id) });
2433
+ return /* @__PURE__ */ jsx7(Static, { items: messages, children: (m) => /* @__PURE__ */ jsx7(MessageRow, { message: m }, m.id) });
2188
2434
  }
2189
2435
 
2190
2436
  // src/ui/NotificationsPanel.tsx
2191
- import { Box as Box5, Text as Text6 } from "ink";
2192
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2437
+ import { Box as Box6, Text as Text7 } from "ink";
2438
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2193
2439
  function relativeAge(createdAt) {
2194
2440
  const ms = Date.now() - new Date(createdAt).getTime();
2195
2441
  if (!Number.isFinite(ms) || ms < 0) return "\u2014";
@@ -2207,11 +2453,11 @@ function NotificationsPanel({
2207
2453
  notifSelected
2208
2454
  }) {
2209
2455
  const unreadCount = notifications.filter((n) => !n.readAt).length;
2210
- return /* @__PURE__ */ jsxs6(Box5, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
2211
- /* @__PURE__ */ jsxs6(Text6, { bold: true, children: [
2456
+ return /* @__PURE__ */ jsxs7(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
2457
+ /* @__PURE__ */ jsxs7(Text7, { bold: true, children: [
2212
2458
  "alerts",
2213
2459
  " ",
2214
- /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2460
+ /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
2215
2461
  "(",
2216
2462
  unreadCount,
2217
2463
  " unread \xB7 ",
@@ -2219,32 +2465,32 @@ function NotificationsPanel({
2219
2465
  " total)"
2220
2466
  ] })
2221
2467
  ] }),
2222
- notifications.length === 0 ? /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "no notifications" }) : notifications.map((n, i) => {
2468
+ notifications.length === 0 ? /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "no notifications" }) : notifications.map((n, i) => {
2223
2469
  const isSelected = i === notifSelected;
2224
2470
  const isUnread = n.readAt === null;
2225
2471
  const type = sanitizeLabel(n.type, 20);
2226
2472
  const ref = shortRef(sanitizeForTty(n.entityRef));
2227
2473
  const age = relativeAge(n.createdAt);
2228
- return /* @__PURE__ */ jsxs6(Text6, { inverse: isSelected, children: [
2229
- isUnread ? /* @__PURE__ */ jsx7(Text6, { color: "yellow", children: "\u2022 " }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " " }),
2230
- /* @__PURE__ */ jsx7(Text6, { bold: isSelected, children: type }),
2231
- /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2474
+ return /* @__PURE__ */ jsxs7(Text7, { inverse: isSelected, children: [
2475
+ isUnread ? /* @__PURE__ */ jsx8(Text7, { color: "yellow", children: "\u2022 " }) : /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " " }),
2476
+ /* @__PURE__ */ jsx8(Text7, { bold: isSelected, children: type }),
2477
+ /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
2232
2478
  " ",
2233
2479
  ref
2234
2480
  ] }),
2235
- /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2481
+ /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
2236
2482
  " ",
2237
2483
  age
2238
2484
  ] })
2239
2485
  ] }, n.id);
2240
2486
  }),
2241
- /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "J/K move \xB7 d dismiss \xB7 a mark all read \xB7 Esc close" })
2487
+ /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "J/K move \xB7 d dismiss \xB7 a mark all read \xB7 Esc close" })
2242
2488
  ] });
2243
2489
  }
2244
2490
 
2245
2491
  // src/ui/StatusBar.tsx
2246
- import { Text as Text7 } from "ink";
2247
- import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2492
+ import { Text as Text8 } from "ink";
2493
+ import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2248
2494
  var MODE_LABEL = {
2249
2495
  normal: "NORMAL",
2250
2496
  insert: "INSERT",
@@ -2301,41 +2547,41 @@ function StatusBar({
2301
2547
  color: stale ? "yellow" : "green"
2302
2548
  };
2303
2549
  }
2304
- return /* @__PURE__ */ jsxs7(Text7, { children: [
2305
- /* @__PURE__ */ jsxs7(Text7, { bold: true, color: mode === "insert" ? "cyan" : mode === "token" ? "yellow" : "white", children: [
2550
+ return /* @__PURE__ */ jsxs8(Text8, { children: [
2551
+ /* @__PURE__ */ jsxs8(Text8, { bold: true, color: mode === "insert" ? "cyan" : mode === "token" ? "yellow" : "white", children: [
2306
2552
  " ",
2307
2553
  MODE_LABEL[mode],
2308
2554
  " "
2309
2555
  ] }),
2310
- /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "\u2502 " }),
2311
- /* @__PURE__ */ jsx8(Text7, { color: connColor, children: connectionLabel(connection, reconnectAt, reconnectAttempt) }),
2312
- /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " \u2502 " }),
2313
- /* @__PURE__ */ jsx8(Text7, { color: tokenSeg.color, children: tokenSeg.text }),
2314
- /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
2556
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "\u2502 " }),
2557
+ /* @__PURE__ */ jsx9(Text8, { color: connColor, children: connectionLabel(connection, reconnectAt, reconnectAttempt) }),
2558
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " \u2502 " }),
2559
+ /* @__PURE__ */ jsx9(Text8, { color: tokenSeg.color, children: tokenSeg.text }),
2560
+ /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
2315
2561
  " \u2502 seq ",
2316
2562
  lastSeq ?? "\u2014"
2317
2563
  ] }),
2318
- notifCount > 0 ? /* @__PURE__ */ jsxs7(Text7, { color: "yellow", children: [
2564
+ notifCount > 0 ? /* @__PURE__ */ jsxs8(Text8, { color: "yellow", children: [
2319
2565
  " \u2502 alerts:",
2320
2566
  notifCount
2321
2567
  ] }) : null,
2322
2568
  error ? (
2323
2569
  // BL-222: an error replaces the full hint line but must never strand
2324
2570
  // the user — keep the exit hint visible alongside it
2325
- /* @__PURE__ */ jsxs7(Fragment, { children: [
2326
- /* @__PURE__ */ jsxs7(Text7, { color: "red", children: [
2571
+ /* @__PURE__ */ jsxs8(Fragment, { children: [
2572
+ /* @__PURE__ */ jsxs8(Text8, { color: "red", children: [
2327
2573
  " \u2502 ",
2328
2574
  sanitizeForTty(error)
2329
2575
  ] }),
2330
- /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " \u2502 q quit" })
2576
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " \u2502 q quit" })
2331
2577
  ] })
2332
- ) : /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " \u2502 c channels \xB7 a alerts \xB7 n next \xB7 i compose \xB7 r reconnect \xB7 Esc normal \xB7 q quit" })
2578
+ ) : /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " \u2502 c channels \xB7 a alerts \xB7 n next \xB7 v watch \xB7 i compose \xB7 r reconnect \xB7 Esc normal \xB7 q quit" })
2333
2579
  ] });
2334
2580
  }
2335
2581
 
2336
2582
  // src/ui/TokenPrompt.tsx
2337
- import { Box as Box6, Text as Text8 } from "ink";
2338
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2583
+ import { Box as Box7, Text as Text9 } from "ink";
2584
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2339
2585
  function TokenPrompt({
2340
2586
  value,
2341
2587
  reason,
@@ -2343,26 +2589,27 @@ function TokenPrompt({
2343
2589
  jwtTemplate
2344
2590
  }) {
2345
2591
  const masked = value.length === 0 ? "" : value.length <= 16 ? value : `${value.slice(0, 12)}\u2026 (${value.length} chars)`;
2346
- return /* @__PURE__ */ jsxs8(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
2347
- /* @__PURE__ */ jsx9(Text8, { bold: true, color: "yellow", children: "token needed" }),
2348
- reason ? /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: sanitizeForTty(reason) }) : null,
2349
- /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
2592
+ return /* @__PURE__ */ jsxs9(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
2593
+ /* @__PURE__ */ jsx10(Text9, { bold: true, color: "yellow", children: "token needed" }),
2594
+ reason ? /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: sanitizeForTty(reason) }) : null,
2595
+ /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
2350
2596
  "mint one: open ",
2351
2597
  webUrl,
2352
2598
  " logged in, browser console:"
2353
2599
  ] }),
2354
- /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: ` await window.Clerk.session.getToken({template:'${jwtTemplate}'})` }),
2355
- /* @__PURE__ */ jsxs8(Text8, { children: [
2356
- /* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "> " }),
2357
- /* @__PURE__ */ jsx9(Text8, { children: masked }),
2358
- /* @__PURE__ */ jsx9(Text8, { inverse: true, children: " " })
2600
+ /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: ` await window.Clerk.session.getToken({template:'${jwtTemplate}'})` }),
2601
+ /* @__PURE__ */ jsxs9(Text9, { children: [
2602
+ /* @__PURE__ */ jsx10(Text9, { color: "yellow", children: "> " }),
2603
+ /* @__PURE__ */ jsx10(Text9, { children: masked }),
2604
+ /* @__PURE__ */ jsx10(Text9, { inverse: true, children: " " })
2359
2605
  ] }),
2360
- /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "paste, then Enter \xB7 Ctrl+C quits" })
2606
+ /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "paste, then Enter \xB7 Ctrl+C quits" })
2361
2607
  ] });
2362
2608
  }
2363
2609
 
2364
2610
  // src/app.tsx
2365
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2611
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2612
+ var ACTIVITY_SETTLE_MS2 = 4e3;
2366
2613
  function cleanInput(input) {
2367
2614
  return input.replace(/\r\n|[\r\n]/g, " ").replace(/[\x00-\x1f\x7f]/g, "");
2368
2615
  }
@@ -2434,12 +2681,22 @@ function App({ store: store2 }) {
2434
2681
  else if (input === "i" || key.return) store2.setMode("insert");
2435
2682
  else if (input === "r") store2.reconnectNow();
2436
2683
  else if (input === "n") store2.jumpNextActive();
2684
+ else if (input === "v") store2.toggleActivityPin();
2437
2685
  },
2438
2686
  { isActive: interactive }
2439
2687
  );
2440
2688
  const activeChannel = state.channels.find((c) => c.id === state.activeChannelId);
2441
- return /* @__PURE__ */ jsxs9(Box7, { flexDirection: "column", children: [
2442
- /* @__PURE__ */ jsx10(
2689
+ const lastKey = (r) => {
2690
+ const ks = Object.keys(r);
2691
+ return ks[ks.length - 1];
2692
+ };
2693
+ const activityRows = state.activityByTurn[lastKey(state.activityByTurn) ?? ""] ?? [];
2694
+ const activityPlan = state.plansByTurn[lastKey(state.plansByTurn) ?? ""] ?? [];
2695
+ const activityLive = activityRows.some((r) => r.status === "pending" || r.status === "in_progress") || activityPlan.some((e) => e.status !== "completed");
2696
+ const activityWithinSettle = state.activityIdleSince !== null && Date.now() - state.activityIdleSince < ACTIVITY_SETTLE_MS2;
2697
+ const activityVisible = state.activityPinned || activityLive || activityWithinSettle;
2698
+ return /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", children: [
2699
+ /* @__PURE__ */ jsx11(
2443
2700
  Header,
2444
2701
  {
2445
2702
  channelName: activeChannel?.name ?? "(connecting\u2026)",
@@ -2448,8 +2705,9 @@ function App({ store: store2 }) {
2448
2705
  presence: state.presence
2449
2706
  }
2450
2707
  ),
2451
- /* @__PURE__ */ jsx10(MessageList, { messages: state.messages }),
2452
- state.mode === "switcher" ? /* @__PURE__ */ jsx10(
2708
+ /* @__PURE__ */ jsx11(MessageList, { messages: state.messages }),
2709
+ /* @__PURE__ */ jsx11(ActivitySurface, { toolCalls: activityRows, plan: activityPlan, visible: activityVisible, pinned: state.activityPinned }),
2710
+ state.mode === "switcher" ? /* @__PURE__ */ jsx11(
2453
2711
  ChannelSwitcher,
2454
2712
  {
2455
2713
  channels: state.channels,
@@ -2459,14 +2717,14 @@ function App({ store: store2 }) {
2459
2717
  unread: state.unread
2460
2718
  }
2461
2719
  ) : null,
2462
- state.mode === "notifications" ? /* @__PURE__ */ jsx10(
2720
+ state.mode === "notifications" ? /* @__PURE__ */ jsx11(
2463
2721
  NotificationsPanel,
2464
2722
  {
2465
2723
  notifications: state.notifications,
2466
2724
  notifSelected: state.notifSelected
2467
2725
  }
2468
2726
  ) : null,
2469
- state.mode === "token" ? /* @__PURE__ */ jsx10(
2727
+ state.mode === "token" ? /* @__PURE__ */ jsx11(
2470
2728
  TokenPrompt,
2471
2729
  {
2472
2730
  value: state.tokenPrompt,
@@ -2475,9 +2733,9 @@ function App({ store: store2 }) {
2475
2733
  jwtTemplate: store2.instance.clerkJwtTemplate
2476
2734
  }
2477
2735
  ) : null,
2478
- /* @__PURE__ */ jsx10(ActivityLine, { activities: state.activities }),
2479
- /* @__PURE__ */ jsx10(Composer, { draft: state.draft, focused: state.mode === "insert" }),
2480
- /* @__PURE__ */ jsx10(
2736
+ /* @__PURE__ */ jsx11(ActivityLine, { activities: state.activities }),
2737
+ /* @__PURE__ */ jsx11(Composer, { draft: state.draft, focused: state.mode === "insert" }),
2738
+ /* @__PURE__ */ jsx11(
2481
2739
  StatusBar,
2482
2740
  {
2483
2741
  mode: state.mode,
@@ -2493,7 +2751,7 @@ function App({ store: store2 }) {
2493
2751
  error: state.error
2494
2752
  }
2495
2753
  ),
2496
- !interactive ? /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "(non-interactive terminal: keys disabled \u2014 tail is read-only here)" }) : null
2754
+ !interactive ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "(non-interactive terminal: keys disabled \u2014 tail is read-only here)" }) : null
2497
2755
  ] });
2498
2756
  }
2499
2757
 
@@ -2577,7 +2835,7 @@ unknown profile command "${args2.sub}".`);
2577
2835
  }
2578
2836
 
2579
2837
  // src/index.tsx
2580
- import { jsx as jsx11 } from "react/jsx-runtime";
2838
+ import { jsx as jsx12 } from "react/jsx-runtime";
2581
2839
  function helpText(profileName2, base2, effective) {
2582
2840
  const relayOverridden = effective.relayUrl !== base2.relayUrl;
2583
2841
  const overrideNote = relayOverridden ? `
@@ -2772,4 +3030,4 @@ if (credentials?.tokenType === "dev-jwt" && credentials.token && !credentials.cl
2772
3030
  );
2773
3031
  }
2774
3032
  var store = createStore({ instance, credentials });
2775
- render(/* @__PURE__ */ jsx11(App, { store }));
3033
+ render(/* @__PURE__ */ jsx12(App, { store }));
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "arp-tui",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "arp-tui",
9
- "version": "0.0.2",
9
+ "version": "0.0.3",
10
10
  "license": "SEE LICENSE IN LICENSE.md",
11
11
  "dependencies": {
12
12
  "ink": "^5.2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arp-tui",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Human-facing terminal client for Agent Relay Protocol. Tail channels and post messages from your terminal.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "SnowyRoad",