arp-tui 0.0.2 → 0.0.4
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 +370 -104
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
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
|
|
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,50 @@ function createStore(opts) {
|
|
|
1591
1666
|
scheduleActivitySweep();
|
|
1592
1667
|
}
|
|
1593
1668
|
}
|
|
1669
|
+
let rawActivityByTurn = /* @__PURE__ */ new Map();
|
|
1670
|
+
let activitySettleTimer = null;
|
|
1671
|
+
function activityIsLive() {
|
|
1672
|
+
const aKeys = Object.keys(state.activityByTurn);
|
|
1673
|
+
const lastA = aKeys[aKeys.length - 1];
|
|
1674
|
+
const rows = lastA !== void 0 ? state.activityByTurn[lastA] : void 0;
|
|
1675
|
+
if (rows) {
|
|
1676
|
+
for (const r of rows) if (r.status === "pending" || r.status === "in_progress") return true;
|
|
1677
|
+
}
|
|
1678
|
+
const pKeys = Object.keys(state.plansByTurn);
|
|
1679
|
+
const lastP = pKeys[pKeys.length - 1];
|
|
1680
|
+
const entries = lastP !== void 0 ? state.plansByTurn[lastP] : void 0;
|
|
1681
|
+
if (entries) {
|
|
1682
|
+
for (const e of entries) if (e.status !== "completed") return true;
|
|
1683
|
+
}
|
|
1684
|
+
return false;
|
|
1685
|
+
}
|
|
1686
|
+
function evictOldestTurns(rec) {
|
|
1687
|
+
const keys = Object.keys(rec);
|
|
1688
|
+
if (keys.length <= MAX_ACTIVITY_TURNS) return rec;
|
|
1689
|
+
const drop = keys.slice(0, keys.length - MAX_ACTIVITY_TURNS);
|
|
1690
|
+
const next = { ...rec };
|
|
1691
|
+
for (const k of drop) delete next[k];
|
|
1692
|
+
return next;
|
|
1693
|
+
}
|
|
1694
|
+
function reconcileActivitySettle() {
|
|
1695
|
+
if (activityIsLive()) {
|
|
1696
|
+
if (activitySettleTimer) {
|
|
1697
|
+
clearTimeout(activitySettleTimer);
|
|
1698
|
+
activitySettleTimer = null;
|
|
1699
|
+
}
|
|
1700
|
+
if (state.activityIdleSince !== null) setThrottled({ activityIdleSince: null });
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
if (state.activityIdleSince === null) setThrottled({ activityIdleSince: Date.now() });
|
|
1704
|
+
if (activitySettleTimer) return;
|
|
1705
|
+
activitySettleTimer = setTimeout(() => {
|
|
1706
|
+
activitySettleTimer = null;
|
|
1707
|
+
setThrottled({});
|
|
1708
|
+
}, ACTIVITY_SETTLE_MS);
|
|
1709
|
+
}
|
|
1710
|
+
function togglePin() {
|
|
1711
|
+
set({ activityPinned: !state.activityPinned });
|
|
1712
|
+
}
|
|
1594
1713
|
let countdownTimer = null;
|
|
1595
1714
|
function syncCountdown(s) {
|
|
1596
1715
|
if (s === "reconnecting" && !countdownTimer) {
|
|
@@ -1692,6 +1811,42 @@ function createStore(opts) {
|
|
|
1692
1811
|
pushDivider("channel archived");
|
|
1693
1812
|
return;
|
|
1694
1813
|
}
|
|
1814
|
+
case "activity_event": {
|
|
1815
|
+
if (frame.channelId !== state.activeChannelId) return;
|
|
1816
|
+
if (!frame.turnId || !frame.toolCallId) return;
|
|
1817
|
+
const ev = {
|
|
1818
|
+
turnId: frame.turnId,
|
|
1819
|
+
toolCallId: frame.toolCallId,
|
|
1820
|
+
agentId: frame.agentId,
|
|
1821
|
+
kind: frame.kind,
|
|
1822
|
+
title: frame.title,
|
|
1823
|
+
status: frame.status,
|
|
1824
|
+
locations: frame.locations,
|
|
1825
|
+
ts: frame.ts
|
|
1826
|
+
};
|
|
1827
|
+
const list = [...rawActivityByTurn.get(frame.turnId) ?? [], ev];
|
|
1828
|
+
if (list.length > MAX_RAW_EVENTS_PER_TURN) list.splice(0, list.length - MAX_RAW_EVENTS_PER_TURN);
|
|
1829
|
+
rawActivityByTurn.set(frame.turnId, list);
|
|
1830
|
+
while (rawActivityByTurn.size > MAX_ACTIVITY_TURNS) {
|
|
1831
|
+
const oldest = rawActivityByTurn.keys().next().value;
|
|
1832
|
+
rawActivityByTurn.delete(oldest);
|
|
1833
|
+
}
|
|
1834
|
+
const foldedMap = foldActivityEvents(Array.from(rawActivityByTurn.values()).flat());
|
|
1835
|
+
let activityByTurn = {};
|
|
1836
|
+
for (const [tid, rows] of foldedMap) activityByTurn[tid] = rows.slice(0, MAX_TOOL_CALLS_PER_TURN);
|
|
1837
|
+
activityByTurn = evictOldestTurns(activityByTurn);
|
|
1838
|
+
setThrottled({ activityByTurn });
|
|
1839
|
+
reconcileActivitySettle();
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
case "plan_update": {
|
|
1843
|
+
if (frame.channelId !== state.activeChannelId) return;
|
|
1844
|
+
if (!frame.turnId) return;
|
|
1845
|
+
const plansByTurn = evictOldestTurns({ ...state.plansByTurn, [frame.turnId]: frame.entries ?? [] });
|
|
1846
|
+
setThrottled({ plansByTurn });
|
|
1847
|
+
reconcileActivitySettle();
|
|
1848
|
+
return;
|
|
1849
|
+
}
|
|
1695
1850
|
default:
|
|
1696
1851
|
return;
|
|
1697
1852
|
}
|
|
@@ -1853,8 +2008,16 @@ function createStore(opts) {
|
|
|
1853
2008
|
mode: "normal",
|
|
1854
2009
|
switcherFilter: "",
|
|
1855
2010
|
lastSeq: config.lastSeq?.[channelId] ?? null,
|
|
1856
|
-
error: null
|
|
2011
|
+
error: null,
|
|
2012
|
+
activityByTurn: {},
|
|
2013
|
+
plansByTurn: {},
|
|
2014
|
+
activityIdleSince: null
|
|
1857
2015
|
});
|
|
2016
|
+
rawActivityByTurn = /* @__PURE__ */ new Map();
|
|
2017
|
+
if (activitySettleTimer) {
|
|
2018
|
+
clearTimeout(activitySettleTimer);
|
|
2019
|
+
activitySettleTimer = null;
|
|
2020
|
+
}
|
|
1858
2021
|
clearUnread(channelId);
|
|
1859
2022
|
ws.subscribe(channelId);
|
|
1860
2023
|
config = { ...config, lastChannelId: channelId };
|
|
@@ -1890,6 +2053,10 @@ function createStore(opts) {
|
|
|
1890
2053
|
if (idleTimer) clearInterval(idleTimer);
|
|
1891
2054
|
if (tickTimer) clearInterval(tickTimer);
|
|
1892
2055
|
if (activitySweep) clearTimeout(activitySweep);
|
|
2056
|
+
if (activitySettleTimer) {
|
|
2057
|
+
clearTimeout(activitySettleTimer);
|
|
2058
|
+
activitySettleTimer = null;
|
|
2059
|
+
}
|
|
1893
2060
|
if (countdownTimer) clearInterval(countdownTimer);
|
|
1894
2061
|
if (attentionTimer) {
|
|
1895
2062
|
clearInterval(attentionTimer);
|
|
@@ -1931,6 +2098,7 @@ function createStore(opts) {
|
|
|
1931
2098
|
const target = nextActiveChannel(s.channels, s.activeChannelId, { attention: s.attention, unread: s.unread });
|
|
1932
2099
|
if (target) openChannel(target.id);
|
|
1933
2100
|
},
|
|
2101
|
+
toggleActivityPin: () => togglePin(),
|
|
1934
2102
|
quit
|
|
1935
2103
|
};
|
|
1936
2104
|
}
|
|
@@ -1968,9 +2136,95 @@ function ActivityLine({ activities }) {
|
|
|
1968
2136
|
] });
|
|
1969
2137
|
}
|
|
1970
2138
|
|
|
1971
|
-
// src/ui/
|
|
2139
|
+
// src/ui/ActivitySurface.tsx
|
|
1972
2140
|
import { Box, Text as Text2 } from "ink";
|
|
1973
2141
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2142
|
+
function statusGlyph(status) {
|
|
2143
|
+
switch (status) {
|
|
2144
|
+
case "completed":
|
|
2145
|
+
return "\u2713";
|
|
2146
|
+
case "failed":
|
|
2147
|
+
return "\u2717";
|
|
2148
|
+
case "in_progress":
|
|
2149
|
+
return "\u22EF";
|
|
2150
|
+
case "pending":
|
|
2151
|
+
return "\u25CB";
|
|
2152
|
+
default:
|
|
2153
|
+
return "\xB7";
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
function kindGlyph(kind) {
|
|
2157
|
+
switch (kind) {
|
|
2158
|
+
case "read":
|
|
2159
|
+
return "r";
|
|
2160
|
+
case "edit":
|
|
2161
|
+
return "e";
|
|
2162
|
+
case "write":
|
|
2163
|
+
return "w";
|
|
2164
|
+
case "run":
|
|
2165
|
+
return "\u25B6";
|
|
2166
|
+
case "search":
|
|
2167
|
+
return "s";
|
|
2168
|
+
case "fetch":
|
|
2169
|
+
return "f";
|
|
2170
|
+
case "task":
|
|
2171
|
+
return "t";
|
|
2172
|
+
default:
|
|
2173
|
+
return "\xB7";
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
function planGlyph(status) {
|
|
2177
|
+
switch (status) {
|
|
2178
|
+
case "completed":
|
|
2179
|
+
return "[x]";
|
|
2180
|
+
case "in_progress":
|
|
2181
|
+
return "[~]";
|
|
2182
|
+
default:
|
|
2183
|
+
return "[ ]";
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
function fallbackTitle(call) {
|
|
2187
|
+
if (call.title) return call.title;
|
|
2188
|
+
if (call.kind) return call.kind.charAt(0).toUpperCase() + call.kind.slice(1);
|
|
2189
|
+
return "Tool call";
|
|
2190
|
+
}
|
|
2191
|
+
function ActivitySurface(props) {
|
|
2192
|
+
const { toolCalls, plan, visible, pinned } = props;
|
|
2193
|
+
if (!visible) return null;
|
|
2194
|
+
if (toolCalls.length === 0 && plan.length === 0) {
|
|
2195
|
+
return /* @__PURE__ */ jsx2(Box, { paddingLeft: 1, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "no activity yet" }) });
|
|
2196
|
+
}
|
|
2197
|
+
return /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", paddingLeft: 1, children: [
|
|
2198
|
+
toolCalls.length > 0 && /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", children: [
|
|
2199
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "tool calls \xB7 only you can see this" }),
|
|
2200
|
+
toolCalls.map((call) => /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", children: [
|
|
2201
|
+
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
2202
|
+
statusGlyph(call.status),
|
|
2203
|
+
" ",
|
|
2204
|
+
kindGlyph(call.kind),
|
|
2205
|
+
" ",
|
|
2206
|
+
sanitizeLabel(fallbackTitle(call), 48)
|
|
2207
|
+
] }),
|
|
2208
|
+
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: [
|
|
2209
|
+
sanitizeLabel(loc.path, 60),
|
|
2210
|
+
loc.line != null ? `:${loc.line}` : ""
|
|
2211
|
+
] }, i)) })
|
|
2212
|
+
] }, call.toolCallId))
|
|
2213
|
+
] }),
|
|
2214
|
+
plan.length > 0 && /* @__PURE__ */ jsxs2(Box, { flexDirection: "column", children: [
|
|
2215
|
+
/* @__PURE__ */ jsx2(Text2, { color: "yellow", children: "plan \xB7 shared with the channel" }),
|
|
2216
|
+
plan.map((entry, i) => /* @__PURE__ */ jsxs2(Text2, { dimColor: entry.status === "completed", children: [
|
|
2217
|
+
planGlyph(entry.status),
|
|
2218
|
+
" ",
|
|
2219
|
+
sanitizeForTty(entry.content)
|
|
2220
|
+
] }, i))
|
|
2221
|
+
] })
|
|
2222
|
+
] });
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
// src/ui/ChannelSwitcher.tsx
|
|
2226
|
+
import { Box as Box2, Text as Text3 } from "ink";
|
|
2227
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1974
2228
|
function channelLabel(ch) {
|
|
1975
2229
|
return `${channelSigil(ch.kind)}${sanitizeLabel(ch.name)}`;
|
|
1976
2230
|
}
|
|
@@ -1985,7 +2239,7 @@ function ChannelBadge({
|
|
|
1985
2239
|
if (att) {
|
|
1986
2240
|
const color = att.highestLevel === "critical" ? "red" : att.highestLevel === "action_required" ? "yellow" : "cyan";
|
|
1987
2241
|
const sigil = att.highestLevel === "critical" ? "!" : att.highestLevel === "action_required" ? "\u25B2" : "\u2022";
|
|
1988
|
-
return /* @__PURE__ */
|
|
2242
|
+
return /* @__PURE__ */ jsxs3(Text3, { color, children: [
|
|
1989
2243
|
" ",
|
|
1990
2244
|
"[",
|
|
1991
2245
|
sigil,
|
|
@@ -1995,7 +2249,7 @@ function ChannelBadge({
|
|
|
1995
2249
|
}
|
|
1996
2250
|
const count = unread[channelId] ?? 0;
|
|
1997
2251
|
if (count > 0) {
|
|
1998
|
-
return /* @__PURE__ */
|
|
2252
|
+
return /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
1999
2253
|
" (",
|
|
2000
2254
|
count,
|
|
2001
2255
|
")"
|
|
@@ -2014,11 +2268,11 @@ function ChannelSwitcher({
|
|
|
2014
2268
|
const sorted = sortChannelsByPriority(filtered, { attention, unread });
|
|
2015
2269
|
const visible = sorted.slice(0, 9);
|
|
2016
2270
|
const hidden = sorted.length - visible.length;
|
|
2017
|
-
return /* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2271
|
+
return /* @__PURE__ */ jsxs3(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
2272
|
+
/* @__PURE__ */ jsxs3(Text3, { bold: true, children: [
|
|
2019
2273
|
"channels",
|
|
2020
2274
|
" ",
|
|
2021
|
-
/* @__PURE__ */
|
|
2275
|
+
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
2022
2276
|
"(",
|
|
2023
2277
|
sorted.length,
|
|
2024
2278
|
"/",
|
|
@@ -2026,23 +2280,23 @@ function ChannelSwitcher({
|
|
|
2026
2280
|
")"
|
|
2027
2281
|
] })
|
|
2028
2282
|
] }),
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
/* @__PURE__ */
|
|
2031
|
-
/* @__PURE__ */
|
|
2032
|
-
/* @__PURE__ */
|
|
2283
|
+
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2284
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "filter: " }),
|
|
2285
|
+
/* @__PURE__ */ jsx3(Text3, { children: sanitizeLabel(filter, 40) }),
|
|
2286
|
+
/* @__PURE__ */ jsx3(Text3, { inverse: true, children: " " })
|
|
2033
2287
|
] }),
|
|
2034
|
-
visible.map((ch, i) => /* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2288
|
+
visible.map((ch, i) => /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2289
|
+
/* @__PURE__ */ jsxs3(Text3, { color: "cyan", children: [
|
|
2036
2290
|
i + 1,
|
|
2037
2291
|
" "
|
|
2038
2292
|
] }),
|
|
2039
|
-
/* @__PURE__ */
|
|
2040
|
-
/* @__PURE__ */
|
|
2293
|
+
/* @__PURE__ */ jsx3(Text3, { bold: ch.id === activeChannelId, children: channelLabel(ch) }),
|
|
2294
|
+
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
2041
2295
|
" \xB7 ",
|
|
2042
2296
|
ch.members.length,
|
|
2043
2297
|
" members"
|
|
2044
2298
|
] }),
|
|
2045
|
-
/* @__PURE__ */
|
|
2299
|
+
/* @__PURE__ */ jsx3(
|
|
2046
2300
|
ChannelBadge,
|
|
2047
2301
|
{
|
|
2048
2302
|
channelId: ch.id,
|
|
@@ -2052,36 +2306,36 @@ function ChannelSwitcher({
|
|
|
2052
2306
|
}
|
|
2053
2307
|
)
|
|
2054
2308
|
] }, ch.id)),
|
|
2055
|
-
hidden > 0 ? /* @__PURE__ */
|
|
2309
|
+
hidden > 0 ? /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
2056
2310
|
"\u2026",
|
|
2057
2311
|
hidden,
|
|
2058
2312
|
" more \u2014 keep typing to narrow"
|
|
2059
2313
|
] }) : null,
|
|
2060
|
-
sorted.length === 0 ? /* @__PURE__ */
|
|
2314
|
+
sorted.length === 0 ? /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
2061
2315
|
'no channels match "',
|
|
2062
2316
|
sanitizeLabel(filter, 20),
|
|
2063
2317
|
'"'
|
|
2064
2318
|
] }) : null,
|
|
2065
|
-
/* @__PURE__ */
|
|
2319
|
+
/* @__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
2320
|
] });
|
|
2067
2321
|
}
|
|
2068
2322
|
|
|
2069
2323
|
// src/ui/Composer.tsx
|
|
2070
|
-
import { Box as
|
|
2071
|
-
import { jsx as
|
|
2324
|
+
import { Box as Box3, Text as Text4 } from "ink";
|
|
2325
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2072
2326
|
function Composer({ draft, focused }) {
|
|
2073
2327
|
const width = Math.max((process.stdout.columns ?? 80) - 8, 20);
|
|
2074
2328
|
const visible = draft.length > width ? "\u2026" + draft.slice(-(width - 1)) : draft;
|
|
2075
|
-
return /* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */
|
|
2077
|
-
draft.length === 0 && !focused ? /* @__PURE__ */
|
|
2078
|
-
focused ? /* @__PURE__ */
|
|
2329
|
+
return /* @__PURE__ */ jsx4(Box3, { borderStyle: "round", borderColor: focused ? "cyan" : "gray", paddingX: 1, width: "100%", children: /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate", children: [
|
|
2330
|
+
/* @__PURE__ */ jsx4(Text4, { color: focused ? "cyan" : "gray", children: "> " }),
|
|
2331
|
+
draft.length === 0 && !focused ? /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "i to compose" }) : /* @__PURE__ */ jsx4(Text4, { children: visible }),
|
|
2332
|
+
focused ? /* @__PURE__ */ jsx4(Text4, { inverse: true, children: " " }) : null
|
|
2079
2333
|
] }) });
|
|
2080
2334
|
}
|
|
2081
2335
|
|
|
2082
2336
|
// src/ui/Header.tsx
|
|
2083
|
-
import { Box as
|
|
2084
|
-
import { jsx as
|
|
2337
|
+
import { Box as Box4, Text as Text5 } from "ink";
|
|
2338
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2085
2339
|
var STATUS_DOT = {
|
|
2086
2340
|
online: { glyph: "\u25CF", color: "green" },
|
|
2087
2341
|
away: { glyph: "\u25D0", color: "yellow" },
|
|
@@ -2098,32 +2352,32 @@ function Header({
|
|
|
2098
2352
|
members,
|
|
2099
2353
|
presence
|
|
2100
2354
|
}) {
|
|
2101
|
-
return /* @__PURE__ */
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2104
|
-
/* @__PURE__ */
|
|
2105
|
-
/* @__PURE__ */
|
|
2106
|
-
/* @__PURE__ */
|
|
2355
|
+
return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", children: [
|
|
2356
|
+
/* @__PURE__ */ jsxs5(Box4, { justifyContent: "space-between", children: [
|
|
2357
|
+
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2358
|
+
/* @__PURE__ */ jsx5(Text5, { color: "cyan", bold: true, children: "arp-tui" }),
|
|
2359
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: " \u25B8 " }),
|
|
2360
|
+
/* @__PURE__ */ jsxs5(Text5, { bold: true, children: [
|
|
2107
2361
|
channelSigil(channelKind),
|
|
2108
2362
|
sanitizeLabel(channelName)
|
|
2109
2363
|
] })
|
|
2110
2364
|
] }),
|
|
2111
|
-
/* @__PURE__ */
|
|
2365
|
+
/* @__PURE__ */ jsx5(Text5, { children: members.map((m) => {
|
|
2112
2366
|
const dot = STATUS_DOT[effectiveStatus(m, presence)];
|
|
2113
|
-
return /* @__PURE__ */
|
|
2114
|
-
/* @__PURE__ */
|
|
2367
|
+
return /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
2368
|
+
/* @__PURE__ */ jsxs5(Text5, { color: dot.color, children: [
|
|
2115
2369
|
dot.glyph,
|
|
2116
2370
|
" "
|
|
2117
2371
|
] }),
|
|
2118
|
-
/* @__PURE__ */
|
|
2372
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: effectiveStatus(m, presence) === "offline", children: [
|
|
2119
2373
|
m.type === "bot" ? "\u2699" : "",
|
|
2120
2374
|
sanitizeLabel(m.name, 20)
|
|
2121
2375
|
] }),
|
|
2122
|
-
/* @__PURE__ */
|
|
2376
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " })
|
|
2123
2377
|
] }, m.id);
|
|
2124
2378
|
}) })
|
|
2125
2379
|
] }),
|
|
2126
|
-
/* @__PURE__ */
|
|
2380
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "\u2500".repeat(Math.min(process.stdout.columns ?? 80, 100)) })
|
|
2127
2381
|
] });
|
|
2128
2382
|
}
|
|
2129
2383
|
|
|
@@ -2131,8 +2385,8 @@ function Header({
|
|
|
2131
2385
|
import { Static } from "ink";
|
|
2132
2386
|
|
|
2133
2387
|
// src/ui/MessageRow.tsx
|
|
2134
|
-
import { Box as
|
|
2135
|
-
import { jsx as
|
|
2388
|
+
import { Box as Box5, Text as Text6 } from "ink";
|
|
2389
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2136
2390
|
function hhmm(rfc3339) {
|
|
2137
2391
|
const d = new Date(rfc3339);
|
|
2138
2392
|
return isNaN(d.getTime()) ? "--:--" : `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
@@ -2145,7 +2399,7 @@ function TokenChip({ message }) {
|
|
|
2145
2399
|
if (message.messageType !== "agent" || !message.tokensUsed) return null;
|
|
2146
2400
|
const parts = [`${formatTokens(message.tokensUsed)} tok`];
|
|
2147
2401
|
if (message.model) parts.push(sanitizeLabel(message.model, 16));
|
|
2148
|
-
return /* @__PURE__ */
|
|
2402
|
+
return /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
2149
2403
|
message.verified ? "\u2713 " : "",
|
|
2150
2404
|
parts.join(" \xB7 ")
|
|
2151
2405
|
] });
|
|
@@ -2155,41 +2409,41 @@ function MessageRow({ message }) {
|
|
|
2155
2409
|
const isSystem = message.messageType === "system";
|
|
2156
2410
|
const name = sanitizeLabel(message.agentName, 20);
|
|
2157
2411
|
if (isSystem) {
|
|
2158
|
-
return /* @__PURE__ */
|
|
2412
|
+
return /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsxs6(Text6, { dimColor: true, italic: true, children: [
|
|
2159
2413
|
" ",
|
|
2160
2414
|
"\u2500\u2500 ",
|
|
2161
2415
|
sanitizeForTty(message.content),
|
|
2162
2416
|
" \u2500\u2500"
|
|
2163
2417
|
] }) });
|
|
2164
2418
|
}
|
|
2165
|
-
return /* @__PURE__ */
|
|
2166
|
-
/* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2419
|
+
return /* @__PURE__ */ jsxs6(Box5, { justifyContent: "space-between", gap: 2, children: [
|
|
2420
|
+
/* @__PURE__ */ jsx6(Box5, { flexShrink: 1, children: /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
2421
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
2168
2422
|
hhmm(message.createdAt),
|
|
2169
2423
|
" "
|
|
2170
2424
|
] }),
|
|
2171
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ jsxs6(Text6, { color: isBot ? "magenta" : "cyan", bold: !isBot, children: [
|
|
2172
2426
|
isBot ? "\u2699" : "",
|
|
2173
2427
|
name.padEnd(12)
|
|
2174
2428
|
] }),
|
|
2175
|
-
/* @__PURE__ */
|
|
2429
|
+
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
2176
2430
|
" ",
|
|
2177
2431
|
sanitizeForTty(message.content)
|
|
2178
2432
|
] })
|
|
2179
2433
|
] }) }),
|
|
2180
|
-
/* @__PURE__ */
|
|
2434
|
+
/* @__PURE__ */ jsx6(Box5, { flexShrink: 0, children: /* @__PURE__ */ jsx6(TokenChip, { message }) })
|
|
2181
2435
|
] });
|
|
2182
2436
|
}
|
|
2183
2437
|
|
|
2184
2438
|
// src/ui/MessageList.tsx
|
|
2185
|
-
import { jsx as
|
|
2439
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2186
2440
|
function MessageList({ messages }) {
|
|
2187
|
-
return /* @__PURE__ */
|
|
2441
|
+
return /* @__PURE__ */ jsx7(Static, { items: messages, children: (m) => /* @__PURE__ */ jsx7(MessageRow, { message: m }, m.id) });
|
|
2188
2442
|
}
|
|
2189
2443
|
|
|
2190
2444
|
// src/ui/NotificationsPanel.tsx
|
|
2191
|
-
import { Box as
|
|
2192
|
-
import { jsx as
|
|
2445
|
+
import { Box as Box6, Text as Text7 } from "ink";
|
|
2446
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2193
2447
|
function relativeAge(createdAt) {
|
|
2194
2448
|
const ms = Date.now() - new Date(createdAt).getTime();
|
|
2195
2449
|
if (!Number.isFinite(ms) || ms < 0) return "\u2014";
|
|
@@ -2207,11 +2461,11 @@ function NotificationsPanel({
|
|
|
2207
2461
|
notifSelected
|
|
2208
2462
|
}) {
|
|
2209
2463
|
const unreadCount = notifications.filter((n) => !n.readAt).length;
|
|
2210
|
-
return /* @__PURE__ */
|
|
2211
|
-
/* @__PURE__ */
|
|
2464
|
+
return /* @__PURE__ */ jsxs7(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
2465
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, children: [
|
|
2212
2466
|
"alerts",
|
|
2213
2467
|
" ",
|
|
2214
|
-
/* @__PURE__ */
|
|
2468
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2215
2469
|
"(",
|
|
2216
2470
|
unreadCount,
|
|
2217
2471
|
" unread \xB7 ",
|
|
@@ -2219,32 +2473,32 @@ function NotificationsPanel({
|
|
|
2219
2473
|
" total)"
|
|
2220
2474
|
] })
|
|
2221
2475
|
] }),
|
|
2222
|
-
notifications.length === 0 ? /* @__PURE__ */
|
|
2476
|
+
notifications.length === 0 ? /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "no notifications" }) : notifications.map((n, i) => {
|
|
2223
2477
|
const isSelected = i === notifSelected;
|
|
2224
2478
|
const isUnread = n.readAt === null;
|
|
2225
2479
|
const type = sanitizeLabel(n.type, 20);
|
|
2226
2480
|
const ref = shortRef(sanitizeForTty(n.entityRef));
|
|
2227
2481
|
const age = relativeAge(n.createdAt);
|
|
2228
|
-
return /* @__PURE__ */
|
|
2229
|
-
isUnread ? /* @__PURE__ */
|
|
2230
|
-
/* @__PURE__ */
|
|
2231
|
-
/* @__PURE__ */
|
|
2482
|
+
return /* @__PURE__ */ jsxs7(Text7, { inverse: isSelected, children: [
|
|
2483
|
+
isUnread ? /* @__PURE__ */ jsx8(Text7, { color: "yellow", children: "\u2022 " }) : /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " " }),
|
|
2484
|
+
/* @__PURE__ */ jsx8(Text7, { bold: isSelected, children: type }),
|
|
2485
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2232
2486
|
" ",
|
|
2233
2487
|
ref
|
|
2234
2488
|
] }),
|
|
2235
|
-
/* @__PURE__ */
|
|
2489
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
2236
2490
|
" ",
|
|
2237
2491
|
age
|
|
2238
2492
|
] })
|
|
2239
2493
|
] }, n.id);
|
|
2240
2494
|
}),
|
|
2241
|
-
/* @__PURE__ */
|
|
2495
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "J/K move \xB7 d dismiss \xB7 a mark all read \xB7 Esc close" })
|
|
2242
2496
|
] });
|
|
2243
2497
|
}
|
|
2244
2498
|
|
|
2245
2499
|
// src/ui/StatusBar.tsx
|
|
2246
|
-
import { Text as
|
|
2247
|
-
import { Fragment, jsx as
|
|
2500
|
+
import { Text as Text8 } from "ink";
|
|
2501
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2248
2502
|
var MODE_LABEL = {
|
|
2249
2503
|
normal: "NORMAL",
|
|
2250
2504
|
insert: "INSERT",
|
|
@@ -2301,41 +2555,41 @@ function StatusBar({
|
|
|
2301
2555
|
color: stale ? "yellow" : "green"
|
|
2302
2556
|
};
|
|
2303
2557
|
}
|
|
2304
|
-
return /* @__PURE__ */
|
|
2305
|
-
/* @__PURE__ */
|
|
2558
|
+
return /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2559
|
+
/* @__PURE__ */ jsxs8(Text8, { bold: true, color: mode === "insert" ? "cyan" : mode === "token" ? "yellow" : "white", children: [
|
|
2306
2560
|
" ",
|
|
2307
2561
|
MODE_LABEL[mode],
|
|
2308
2562
|
" "
|
|
2309
2563
|
] }),
|
|
2310
|
-
/* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2312
|
-
/* @__PURE__ */
|
|
2313
|
-
/* @__PURE__ */
|
|
2314
|
-
/* @__PURE__ */
|
|
2564
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "\u2502 " }),
|
|
2565
|
+
/* @__PURE__ */ jsx9(Text8, { color: connColor, children: connectionLabel(connection, reconnectAt, reconnectAttempt) }),
|
|
2566
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " \u2502 " }),
|
|
2567
|
+
/* @__PURE__ */ jsx9(Text8, { color: tokenSeg.color, children: tokenSeg.text }),
|
|
2568
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
2315
2569
|
" \u2502 seq ",
|
|
2316
2570
|
lastSeq ?? "\u2014"
|
|
2317
2571
|
] }),
|
|
2318
|
-
notifCount > 0 ? /* @__PURE__ */
|
|
2572
|
+
notifCount > 0 ? /* @__PURE__ */ jsxs8(Text8, { color: "yellow", children: [
|
|
2319
2573
|
" \u2502 alerts:",
|
|
2320
2574
|
notifCount
|
|
2321
2575
|
] }) : null,
|
|
2322
2576
|
error ? (
|
|
2323
2577
|
// BL-222: an error replaces the full hint line but must never strand
|
|
2324
2578
|
// the user — keep the exit hint visible alongside it
|
|
2325
|
-
/* @__PURE__ */
|
|
2326
|
-
/* @__PURE__ */
|
|
2579
|
+
/* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
2580
|
+
/* @__PURE__ */ jsxs8(Text8, { color: "red", children: [
|
|
2327
2581
|
" \u2502 ",
|
|
2328
2582
|
sanitizeForTty(error)
|
|
2329
2583
|
] }),
|
|
2330
|
-
/* @__PURE__ */
|
|
2584
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " \u2502 q quit" })
|
|
2331
2585
|
] })
|
|
2332
|
-
) : /* @__PURE__ */
|
|
2586
|
+
) : /* @__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
2587
|
] });
|
|
2334
2588
|
}
|
|
2335
2589
|
|
|
2336
2590
|
// src/ui/TokenPrompt.tsx
|
|
2337
|
-
import { Box as
|
|
2338
|
-
import { jsx as
|
|
2591
|
+
import { Box as Box7, Text as Text9 } from "ink";
|
|
2592
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2339
2593
|
function TokenPrompt({
|
|
2340
2594
|
value,
|
|
2341
2595
|
reason,
|
|
@@ -2343,26 +2597,27 @@ function TokenPrompt({
|
|
|
2343
2597
|
jwtTemplate
|
|
2344
2598
|
}) {
|
|
2345
2599
|
const masked = value.length === 0 ? "" : value.length <= 16 ? value : `${value.slice(0, 12)}\u2026 (${value.length} chars)`;
|
|
2346
|
-
return /* @__PURE__ */
|
|
2347
|
-
/* @__PURE__ */
|
|
2348
|
-
reason ? /* @__PURE__ */
|
|
2349
|
-
/* @__PURE__ */
|
|
2600
|
+
return /* @__PURE__ */ jsxs9(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
2601
|
+
/* @__PURE__ */ jsx10(Text9, { bold: true, color: "yellow", children: "token needed" }),
|
|
2602
|
+
reason ? /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: sanitizeForTty(reason) }) : null,
|
|
2603
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2350
2604
|
"mint one: open ",
|
|
2351
2605
|
webUrl,
|
|
2352
2606
|
" logged in, browser console:"
|
|
2353
2607
|
] }),
|
|
2354
|
-
/* @__PURE__ */
|
|
2355
|
-
/* @__PURE__ */
|
|
2356
|
-
/* @__PURE__ */
|
|
2357
|
-
/* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2608
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: ` await window.Clerk.session.getToken({template:'${jwtTemplate}'})` }),
|
|
2609
|
+
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2610
|
+
/* @__PURE__ */ jsx10(Text9, { color: "yellow", children: "> " }),
|
|
2611
|
+
/* @__PURE__ */ jsx10(Text9, { children: masked }),
|
|
2612
|
+
/* @__PURE__ */ jsx10(Text9, { inverse: true, children: " " })
|
|
2359
2613
|
] }),
|
|
2360
|
-
/* @__PURE__ */
|
|
2614
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "paste, then Enter \xB7 Ctrl+C quits" })
|
|
2361
2615
|
] });
|
|
2362
2616
|
}
|
|
2363
2617
|
|
|
2364
2618
|
// src/app.tsx
|
|
2365
|
-
import { jsx as
|
|
2619
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2620
|
+
var ACTIVITY_SETTLE_MS2 = 4e3;
|
|
2366
2621
|
function cleanInput(input) {
|
|
2367
2622
|
return input.replace(/\r\n|[\r\n]/g, " ").replace(/[\x00-\x1f\x7f]/g, "");
|
|
2368
2623
|
}
|
|
@@ -2434,12 +2689,22 @@ function App({ store: store2 }) {
|
|
|
2434
2689
|
else if (input === "i" || key.return) store2.setMode("insert");
|
|
2435
2690
|
else if (input === "r") store2.reconnectNow();
|
|
2436
2691
|
else if (input === "n") store2.jumpNextActive();
|
|
2692
|
+
else if (input === "v") store2.toggleActivityPin();
|
|
2437
2693
|
},
|
|
2438
2694
|
{ isActive: interactive }
|
|
2439
2695
|
);
|
|
2440
2696
|
const activeChannel = state.channels.find((c) => c.id === state.activeChannelId);
|
|
2441
|
-
|
|
2442
|
-
|
|
2697
|
+
const lastKey = (r) => {
|
|
2698
|
+
const ks = Object.keys(r);
|
|
2699
|
+
return ks[ks.length - 1];
|
|
2700
|
+
};
|
|
2701
|
+
const activityRows = state.activityByTurn[lastKey(state.activityByTurn) ?? ""] ?? [];
|
|
2702
|
+
const activityPlan = state.plansByTurn[lastKey(state.plansByTurn) ?? ""] ?? [];
|
|
2703
|
+
const activityLive = activityRows.some((r) => r.status === "pending" || r.status === "in_progress") || activityPlan.some((e) => e.status !== "completed");
|
|
2704
|
+
const activityWithinSettle = state.activityIdleSince !== null && Date.now() - state.activityIdleSince < ACTIVITY_SETTLE_MS2;
|
|
2705
|
+
const activityVisible = state.activityPinned || activityLive || activityWithinSettle;
|
|
2706
|
+
return /* @__PURE__ */ jsxs10(Box8, { flexDirection: "column", children: [
|
|
2707
|
+
/* @__PURE__ */ jsx11(
|
|
2443
2708
|
Header,
|
|
2444
2709
|
{
|
|
2445
2710
|
channelName: activeChannel?.name ?? "(connecting\u2026)",
|
|
@@ -2448,8 +2713,9 @@ function App({ store: store2 }) {
|
|
|
2448
2713
|
presence: state.presence
|
|
2449
2714
|
}
|
|
2450
2715
|
),
|
|
2451
|
-
/* @__PURE__ */
|
|
2452
|
-
|
|
2716
|
+
/* @__PURE__ */ jsx11(MessageList, { messages: state.messages }),
|
|
2717
|
+
/* @__PURE__ */ jsx11(ActivitySurface, { toolCalls: activityRows, plan: activityPlan, visible: activityVisible, pinned: state.activityPinned }),
|
|
2718
|
+
state.mode === "switcher" ? /* @__PURE__ */ jsx11(
|
|
2453
2719
|
ChannelSwitcher,
|
|
2454
2720
|
{
|
|
2455
2721
|
channels: state.channels,
|
|
@@ -2459,14 +2725,14 @@ function App({ store: store2 }) {
|
|
|
2459
2725
|
unread: state.unread
|
|
2460
2726
|
}
|
|
2461
2727
|
) : null,
|
|
2462
|
-
state.mode === "notifications" ? /* @__PURE__ */
|
|
2728
|
+
state.mode === "notifications" ? /* @__PURE__ */ jsx11(
|
|
2463
2729
|
NotificationsPanel,
|
|
2464
2730
|
{
|
|
2465
2731
|
notifications: state.notifications,
|
|
2466
2732
|
notifSelected: state.notifSelected
|
|
2467
2733
|
}
|
|
2468
2734
|
) : null,
|
|
2469
|
-
state.mode === "token" ? /* @__PURE__ */
|
|
2735
|
+
state.mode === "token" ? /* @__PURE__ */ jsx11(
|
|
2470
2736
|
TokenPrompt,
|
|
2471
2737
|
{
|
|
2472
2738
|
value: state.tokenPrompt,
|
|
@@ -2475,9 +2741,9 @@ function App({ store: store2 }) {
|
|
|
2475
2741
|
jwtTemplate: store2.instance.clerkJwtTemplate
|
|
2476
2742
|
}
|
|
2477
2743
|
) : null,
|
|
2478
|
-
/* @__PURE__ */
|
|
2479
|
-
/* @__PURE__ */
|
|
2480
|
-
/* @__PURE__ */
|
|
2744
|
+
/* @__PURE__ */ jsx11(ActivityLine, { activities: state.activities }),
|
|
2745
|
+
/* @__PURE__ */ jsx11(Composer, { draft: state.draft, focused: state.mode === "insert" }),
|
|
2746
|
+
/* @__PURE__ */ jsx11(
|
|
2481
2747
|
StatusBar,
|
|
2482
2748
|
{
|
|
2483
2749
|
mode: state.mode,
|
|
@@ -2493,7 +2759,7 @@ function App({ store: store2 }) {
|
|
|
2493
2759
|
error: state.error
|
|
2494
2760
|
}
|
|
2495
2761
|
),
|
|
2496
|
-
!interactive ? /* @__PURE__ */
|
|
2762
|
+
!interactive ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "(non-interactive terminal: keys disabled \u2014 tail is read-only here)" }) : null
|
|
2497
2763
|
] });
|
|
2498
2764
|
}
|
|
2499
2765
|
|
|
@@ -2577,7 +2843,7 @@ unknown profile command "${args2.sub}".`);
|
|
|
2577
2843
|
}
|
|
2578
2844
|
|
|
2579
2845
|
// src/index.tsx
|
|
2580
|
-
import { jsx as
|
|
2846
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2581
2847
|
function helpText(profileName2, base2, effective) {
|
|
2582
2848
|
const relayOverridden = effective.relayUrl !== base2.relayUrl;
|
|
2583
2849
|
const overrideNote = relayOverridden ? `
|
|
@@ -2772,4 +3038,4 @@ if (credentials?.tokenType === "dev-jwt" && credentials.token && !credentials.cl
|
|
|
2772
3038
|
);
|
|
2773
3039
|
}
|
|
2774
3040
|
var store = createStore({ instance, credentials });
|
|
2775
|
-
render(/* @__PURE__ */
|
|
3041
|
+
render(/* @__PURE__ */ jsx12(App, { store }));
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arp-tui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "arp-tui",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.4",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"ink": "^5.2.0",
|
package/package.json
CHANGED