opencode-top 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/bin/octop.js +2 -9
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +22432 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/cli.mjs +22570 -0
  7. package/dist/core/agents.d.ts +11 -0
  8. package/dist/core/agents.d.ts.map +1 -0
  9. package/dist/core/agents.js +58 -0
  10. package/dist/core/agents.js.map +1 -0
  11. package/dist/core/session.d.ts +19 -0
  12. package/dist/core/session.d.ts.map +1 -0
  13. package/dist/core/session.js +261 -0
  14. package/dist/core/session.js.map +1 -0
  15. package/dist/core/types.d.ts +140 -0
  16. package/dist/core/types.d.ts.map +1 -0
  17. package/dist/core/types.js +29 -0
  18. package/dist/core/types.js.map +1 -0
  19. package/dist/data/pricing.d.ts +4 -0
  20. package/dist/data/pricing.d.ts.map +1 -0
  21. package/dist/data/pricing.js +76 -0
  22. package/dist/data/pricing.js.map +1 -0
  23. package/dist/data/sqlite.d.ts +5 -0
  24. package/dist/data/sqlite.d.ts.map +1 -0
  25. package/dist/data/sqlite.js +222 -0
  26. package/dist/data/sqlite.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/{src/index.ts → dist/index.js} +1 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/ui/App.d.ts +6 -0
  32. package/dist/ui/App.d.ts.map +1 -0
  33. package/dist/ui/App.js +101 -0
  34. package/dist/ui/App.js.map +1 -0
  35. package/dist/ui/components/AgentChainGraph.d.ts +9 -0
  36. package/dist/ui/components/AgentChainGraph.d.ts.map +1 -0
  37. package/dist/ui/components/AgentChainGraph.js +41 -0
  38. package/dist/ui/components/AgentChainGraph.js.map +1 -0
  39. package/dist/ui/components/AgentTree.d.ts +13 -0
  40. package/dist/ui/components/AgentTree.d.ts.map +1 -0
  41. package/dist/ui/components/AgentTree.js +50 -0
  42. package/dist/ui/components/AgentTree.js.map +1 -0
  43. package/dist/ui/components/DetailsPanel.d.ts +9 -0
  44. package/dist/ui/components/DetailsPanel.d.ts.map +1 -0
  45. package/dist/ui/components/DetailsPanel.js +82 -0
  46. package/dist/ui/components/DetailsPanel.js.map +1 -0
  47. package/dist/ui/components/MessagesPanel.d.ts +12 -0
  48. package/dist/ui/components/MessagesPanel.d.ts.map +1 -0
  49. package/dist/ui/components/MessagesPanel.js +107 -0
  50. package/dist/ui/components/MessagesPanel.js.map +1 -0
  51. package/dist/ui/components/SparkLine.d.ts +10 -0
  52. package/dist/ui/components/SparkLine.d.ts.map +1 -0
  53. package/dist/ui/components/SparkLine.js +12 -0
  54. package/dist/ui/components/SparkLine.js.map +1 -0
  55. package/dist/ui/components/StatusBar.d.ts +9 -0
  56. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  57. package/dist/ui/components/StatusBar.js +9 -0
  58. package/dist/ui/components/StatusBar.js.map +1 -0
  59. package/dist/ui/components/TabBar.d.ts +10 -0
  60. package/dist/ui/components/TabBar.d.ts.map +1 -0
  61. package/dist/ui/components/TabBar.js +17 -0
  62. package/dist/ui/components/TabBar.js.map +1 -0
  63. package/dist/ui/screens/OverviewScreen.d.ts +12 -0
  64. package/dist/ui/screens/OverviewScreen.d.ts.map +1 -0
  65. package/dist/ui/screens/OverviewScreen.js +94 -0
  66. package/dist/ui/screens/OverviewScreen.js.map +1 -0
  67. package/dist/ui/screens/SessionsScreen.d.ts +12 -0
  68. package/dist/ui/screens/SessionsScreen.d.ts.map +1 -0
  69. package/dist/ui/screens/SessionsScreen.js +98 -0
  70. package/dist/ui/screens/SessionsScreen.js.map +1 -0
  71. package/dist/ui/screens/TimelineScreen.d.ts +11 -0
  72. package/dist/ui/screens/TimelineScreen.d.ts.map +1 -0
  73. package/dist/ui/screens/TimelineScreen.js +128 -0
  74. package/dist/ui/screens/TimelineScreen.js.map +1 -0
  75. package/dist/ui/screens/ToolsScreen.d.ts +12 -0
  76. package/dist/ui/screens/ToolsScreen.d.ts.map +1 -0
  77. package/dist/ui/screens/ToolsScreen.js +113 -0
  78. package/dist/ui/screens/ToolsScreen.js.map +1 -0
  79. package/dist/ui/theme.d.ts +21 -0
  80. package/dist/ui/theme.d.ts.map +1 -0
  81. package/dist/ui/theme.js +21 -0
  82. package/dist/ui/theme.js.map +1 -0
  83. package/package.json +2 -1
  84. package/bin/octop.mjs +0 -13
  85. package/src/cli.ts +0 -60
  86. package/src/core/agents.ts +0 -78
  87. package/src/core/session.ts +0 -315
  88. package/src/core/types.ts +0 -156
  89. package/src/data/pricing.ts +0 -82
  90. package/src/data/sqlite.ts +0 -347
  91. package/src/ui/App.tsx +0 -154
  92. package/src/ui/components/AgentChainGraph.tsx +0 -95
  93. package/src/ui/components/AgentTree.tsx +0 -101
  94. package/src/ui/components/DetailsPanel.tsx +0 -211
  95. package/src/ui/components/MessagesPanel.tsx +0 -323
  96. package/src/ui/components/SparkLine.tsx +0 -18
  97. package/src/ui/components/StatusBar.tsx +0 -24
  98. package/src/ui/components/TabBar.tsx +0 -42
  99. package/src/ui/screens/OverviewScreen.tsx +0 -327
  100. package/src/ui/screens/SessionsScreen.tsx +0 -168
  101. package/src/ui/screens/TimelineScreen.tsx +0 -222
  102. package/src/ui/screens/ToolsScreen.tsx +0 -260
  103. package/src/ui/theme.ts +0 -21
@@ -0,0 +1,82 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { memo, useMemo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { colors } from "../theme";
5
+ import { getSessionTokens, getSessionCostSingle, getSessionDuration, getOutputRate, getToolUsage, } from "../../core/session";
6
+ import { getPricing } from "../../data/pricing";
7
+ import { AgentChainGraph } from "./AgentChainGraph";
8
+ function StatRow({ label, value, color = colors.text, }) {
9
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 12, children: _jsx(Text, { color: colors.textDim, children: label }) }), _jsx(Text, { color: color, children: value })] }));
10
+ }
11
+ function formatDuration(ms) {
12
+ if (ms === 0)
13
+ return "—";
14
+ const mins = Math.floor(ms / 60000);
15
+ const secs = Math.floor((ms % 60000) / 1000);
16
+ if (mins === 0)
17
+ return `${secs}s`;
18
+ return `${mins}m ${secs}s`;
19
+ }
20
+ function ProgressBar({ value, max, width = 16, color = colors.accent, }) {
21
+ const pct = max > 0 ? Math.min(value / max, 1) : 0;
22
+ const filled = Math.round(pct * width);
23
+ const empty = width - filled;
24
+ return (_jsxs(Text, { children: [_jsx(Text, { color: color, children: "█".repeat(filled) }), _jsx(Text, { color: colors.border, children: "░".repeat(empty) }), _jsxs(Text, { color: colors.textDim, children: [" ", Math.round(pct * 100), "%"] })] }));
25
+ }
26
+ function formatTokens(n) {
27
+ if (n >= 1_000_000)
28
+ return `${(n / 1_000_000).toFixed(1)}M`;
29
+ if (n >= 1_000)
30
+ return `${(n / 1_000).toFixed(1)}K`;
31
+ return n.toString();
32
+ }
33
+ function DetailsPanelInner({ workflow }) {
34
+ const data = useMemo(() => {
35
+ if (!workflow)
36
+ return null;
37
+ const session = workflow.mainSession;
38
+ const tokens = getSessionTokens(session);
39
+ const modelId = session.interactions[0]?.modelId ?? "";
40
+ const pricing = getPricing(modelId);
41
+ const cost = getSessionCostSingle(session, pricing);
42
+ const duration = getSessionDuration(session);
43
+ const outputRate = getOutputRate(session);
44
+ const contextUsage = tokens.input + tokens.cacheRead + tokens.cacheWrite;
45
+ const contextPct = pricing.contextWindow > 0 ? contextUsage / pricing.contextWindow : 0;
46
+ const modelBreakdown = new Map();
47
+ for (const i of session.interactions) {
48
+ const existing = modelBreakdown.get(i.modelId) ?? { count: 0, tokens: 0 };
49
+ existing.count++;
50
+ existing.tokens += i.tokens.total;
51
+ modelBreakdown.set(i.modelId, existing);
52
+ }
53
+ const toolUsage = getToolUsage(session);
54
+ const topTools = toolUsage
55
+ .sort((a, b) => b.calls - a.calls)
56
+ .slice(0, 3);
57
+ return {
58
+ title: session.title ?? "Untitled",
59
+ project: session.projectName ?? "—",
60
+ tokens: tokens.total,
61
+ cost,
62
+ duration,
63
+ outputRate,
64
+ calls: session.interactions.length,
65
+ contextUsage,
66
+ contextWindow: pricing.contextWindow,
67
+ contextPct,
68
+ modelBreakdown,
69
+ topTools,
70
+ agentTree: workflow.agentTree,
71
+ hasSubAgents: workflow.subAgentSessions.length > 0,
72
+ };
73
+ }, [workflow]);
74
+ if (!data) {
75
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, children: _jsx(Text, { color: colors.textDim, children: "Select a session" }) }));
76
+ }
77
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: colors.accent, bold: true, children: "Details" }) }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.cyan, bold: true, children: data.title }), _jsx(Text, { color: colors.textDim, children: data.project }), _jsx(StatRow, { label: "Tokens", value: formatTokens(data.tokens) }), _jsx(StatRow, { label: "Cost", value: `$${data.cost.toFixed(4)}`, color: colors.success }), _jsx(StatRow, { label: "Duration", value: formatDuration(data.duration) }), _jsx(StatRow, { label: "Rate", value: `${data.outputRate.toFixed(0)} tok/s` }), _jsx(StatRow, { label: "Calls", value: data.calls.toString() }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.textDim, children: "Context" }) }), _jsx(ProgressBar, { value: data.contextUsage, max: data.contextWindow, color: data.contextPct > 0.8 ? colors.warning : colors.accent })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.purple, bold: true, children: "Models" }) }), Array.from(data.modelBreakdown.entries())
78
+ .slice(0, 3)
79
+ .map(([model, stats]) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.text, children: model.slice(0, 25) }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: stats.count }), _jsx(Box, { width: 1 }), _jsx(Text, { color: colors.info, children: formatTokens(stats.tokens) })] }, model))), data.topTools.length > 0 && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.purple, bold: true, children: "Top Tools" }) }), data.topTools.map((tool) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.text, children: tool.name.slice(0, 20) }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: tool.failures > 0 ? colors.warning : colors.success, children: [tool.successes, "/", tool.calls] })] }, tool.name)))] })), data.hasSubAgents && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.purple, bold: true, children: "Agent Chain" }) }), _jsx(AgentChainGraph, { agentTree: data.agentTree })] }))] }));
80
+ }
81
+ export const DetailsPanel = memo(DetailsPanelInner);
82
+ //# sourceMappingURL=DetailsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DetailsPanel.js","sourceRoot":"","sources":["../../../src/ui/components/DetailsPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { Session } from "../../core/types";
3
+ interface MessagesPanelProps {
4
+ session: Session | null;
5
+ scrollOffset: number;
6
+ onScrollOffsetChange: (offset: number) => void;
7
+ maxHeight: number;
8
+ }
9
+ declare function MessagesPanelInner({ session, scrollOffset, maxHeight, }: MessagesPanelProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const MessagesPanel: React.MemoExoticComponent<typeof MessagesPanelInner>;
11
+ export {};
12
+ //# sourceMappingURL=MessagesPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagesPanel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessagesPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAG7C,OAAO,KAAK,EAAE,OAAO,EAA4B,MAAM,kBAAkB,CAAC;AAE1E,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;CACnB;AAiID,iBAAS,kBAAkB,CAAC,EAC1B,OAAO,EACP,YAAY,EACZ,SAAS,GACV,EAAE,kBAAkB,2CAqCpB;AAED,eAAO,MAAM,aAAa,sDAA2B,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, memo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { colors } from "../theme";
5
+ function buildLines(session) {
6
+ const lines = [];
7
+ for (const interaction of session.interactions) {
8
+ if (interaction.role !== "assistant")
9
+ continue;
10
+ lines.push({ kind: "interaction-header", interaction });
11
+ for (const part of interaction.parts) {
12
+ if (part.type === "tool") {
13
+ lines.push({ kind: "tool-call", part: part });
14
+ }
15
+ else if (part.type === "text" && part.text.trim()) {
16
+ // Split long text into display lines of ~wrap length
17
+ const wrapped = wrapText(part.text.trim(), 200);
18
+ for (const line of wrapped) {
19
+ lines.push({ kind: "text", text: line });
20
+ }
21
+ }
22
+ else if (part.type === "reasoning" && part.text.trim()) {
23
+ const wrapped = wrapText(part.text.trim(), 200);
24
+ for (const line of wrapped) {
25
+ lines.push({ kind: "reasoning", text: line });
26
+ }
27
+ }
28
+ }
29
+ lines.push({ kind: "spacer" });
30
+ }
31
+ return lines;
32
+ }
33
+ function wrapText(text, maxLen) {
34
+ const rawLines = text.split("\n");
35
+ const out = [];
36
+ for (const raw of rawLines) {
37
+ if (raw.length <= maxLen) {
38
+ out.push(raw);
39
+ }
40
+ else {
41
+ for (let i = 0; i < raw.length; i += maxLen) {
42
+ out.push(raw.slice(i, i + maxLen));
43
+ }
44
+ }
45
+ }
46
+ return out;
47
+ }
48
+ function formatTime(ts) {
49
+ if (!ts)
50
+ return "";
51
+ return new Date(ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
52
+ }
53
+ function formatDuration(ms) {
54
+ if (ms <= 0)
55
+ return "";
56
+ if (ms < 1000)
57
+ return `${ms}ms`;
58
+ return `${(ms / 1000).toFixed(1)}s`;
59
+ }
60
+ function renderLine(line, idx) {
61
+ switch (line.kind) {
62
+ case "interaction-header": {
63
+ const { interaction: i } = line;
64
+ const dur = i.time.completed && i.time.created
65
+ ? i.time.completed - i.time.created
66
+ : 0;
67
+ return (_jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsx(Text, { color: colors.purple, bold: true, children: "\u25C6 " }), _jsx(Text, { color: colors.info, children: truncate(i.modelId, 28) }), i.agent && _jsxs(Text, { color: colors.cyan, children: [" [", i.agent, "]"] }), _jsx(Box, { flexGrow: 1 }), dur > 0 && _jsxs(Text, { color: colors.textDim, children: [formatDuration(dur), " "] }), _jsx(Text, { color: colors.textDim, children: formatTime(i.time.created) })] }, idx));
68
+ }
69
+ case "tool-call": {
70
+ const p = line.part;
71
+ const statusIcon = p.status === "completed" ? "✓" : p.status === "error" ? "✗" : "◌";
72
+ const statusColor = p.status === "completed" ? colors.success : p.status === "error" ? colors.error : colors.warning;
73
+ const dur = p.timeEnd > 0 && p.timeStart > 0 ? p.timeEnd - p.timeStart : 0;
74
+ const exitStr = p.exitCode !== null && p.exitCode !== 0 ? ` exit:${p.exitCode}` : "";
75
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: statusColor, children: [statusIcon, " "] }), _jsx(Text, { color: colors.text, bold: true, children: truncate(p.toolName, 20) }), p.title && _jsxs(Text, { color: colors.textDim, children: [" ", truncate(p.title, 30)] }), _jsx(Box, { flexGrow: 1 }), exitStr && _jsxs(Text, { color: colors.error, children: [exitStr, " "] }), dur > 0 && _jsx(Text, { color: colors.textDim, children: formatDuration(dur) })] }), (p.status === "error" || (p.output && p.output.length < 200 && p.output.trim())) && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: p.status === "error" ? colors.error : colors.textDim, children: truncate(p.output.trim(), 120) }) }))] }, idx));
76
+ }
77
+ case "text":
78
+ return (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: colors.text, children: line.text }) }, idx));
79
+ case "reasoning":
80
+ return (_jsx(Box, { paddingLeft: 2, children: _jsxs(Text, { color: colors.accentDim, children: ["\u26A1 ", line.text] }) }, idx));
81
+ case "spacer":
82
+ return _jsx(Box, {}, idx);
83
+ }
84
+ }
85
+ function MessagesPanelInner({ session, scrollOffset, maxHeight, }) {
86
+ const allLines = useMemo(() => {
87
+ if (!session)
88
+ return [];
89
+ return buildLines(session);
90
+ }, [session]);
91
+ if (!session) {
92
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: colors.textDim, children: "Select a session" }) }));
93
+ }
94
+ if (allLines.length === 0) {
95
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: colors.textDim, children: "No messages" }) }));
96
+ }
97
+ const clampedOffset = Math.max(0, Math.min(scrollOffset, Math.max(0, allLines.length - maxHeight)));
98
+ const visibleLines = allLines.slice(clampedOffset, clampedOffset + maxHeight);
99
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, overflow: "hidden", children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: colors.textDim, children: [clampedOffset + 1, "\u2013", Math.min(clampedOffset + maxHeight, allLines.length), "/", allLines.length] }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.textDim, children: [session.interactions.length, " turns"] })] }), visibleLines.map((line, i) => renderLine(line, clampedOffset + i))] }));
100
+ }
101
+ export const MessagesPanel = memo(MessagesPanelInner);
102
+ function truncate(s, max) {
103
+ if (s.length <= max)
104
+ return s;
105
+ return s.slice(0, max - 1) + "…";
106
+ }
107
+ //# sourceMappingURL=MessagesPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagesPanel.js","sourceRoot":"","sources":["../../../src/ui/components/MessagesPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ interface SparkLineProps {
3
+ values: number[];
4
+ color?: string;
5
+ width?: number;
6
+ }
7
+ declare function SparkLineInner({ values, color, width }: SparkLineProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare const SparkLine: React.MemoExoticComponent<typeof SparkLineInner>;
9
+ export {};
10
+ //# sourceMappingURL=SparkLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SparkLine.d.ts","sourceRoot":"","sources":["../../../src/ui/components/SparkLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAKpC,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iBAAS,cAAc,CAAC,EAAE,MAAM,EAAE,KAAmB,EAAE,KAAK,EAAE,EAAE,cAAc,2CAI7E;AAED,eAAO,MAAM,SAAS,kDAAuB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { Text } from "ink";
4
+ import { colors } from "../theme";
5
+ import { buildSparkSeries } from "../../core/session";
6
+ function SparkLineInner({ values, color = colors.info, width }) {
7
+ const data = width && values.length > width ? values.slice(-width) : values;
8
+ const spark = buildSparkSeries(data);
9
+ return _jsx(Text, { color: color, children: spark });
10
+ }
11
+ export const SparkLine = memo(SparkLineInner);
12
+ //# sourceMappingURL=SparkLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SparkLine.js","sourceRoot":"","sources":["../../../src/ui/components/SparkLine.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQtD,SAAS,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,EAAkB;IAC5E,MAAM,IAAI,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5E,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,KAAK,GAAQ,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface StatusBarProps {
3
+ hints: string;
4
+ info?: string;
5
+ }
6
+ declare function StatusBarInner({ hints, info }: StatusBarProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare const StatusBar: React.MemoExoticComponent<typeof StatusBarInner>;
8
+ export {};
9
+ //# sourceMappingURL=StatusBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAIpC,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,iBAAS,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,cAAc,2CAYtD;AAED,eAAO,MAAM,SAAS,kDAAuB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { colors } from "../theme";
5
+ function StatusBarInner({ hints, info }) {
6
+ return (_jsxs(Box, { paddingX: 1, borderStyle: "single", borderColor: colors.border, flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: hints }), info && (_jsxs(_Fragment, { children: [_jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.info, children: info })] }))] }));
7
+ }
8
+ export const StatusBar = memo(StatusBarInner);
9
+ //# sourceMappingURL=StatusBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC,SAAS,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAkB;IACrD,OAAO,CACL,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAC,KAAK,aACpF,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,OAAO,YAAG,KAAK,GAAQ,EAC1C,IAAI,IAAI,CACP,8BACE,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,GAAI,EACpB,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,YAAG,IAAI,GAAQ,IACtC,CACJ,IACG,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { ScreenId } from "../../core/types";
3
+ interface TabBarProps {
4
+ activeScreen: ScreenId;
5
+ lastRefresh: Date;
6
+ }
7
+ declare function TabBarInner({ activeScreen, lastRefresh }: TabBarProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare const TabBar: React.MemoExoticComponent<typeof TabBarInner>;
9
+ export {};
10
+ //# sourceMappingURL=TabBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabBar.d.ts","sourceRoot":"","sources":["../../../src/ui/components/TabBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAGpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,UAAU,WAAW;IACnB,YAAY,EAAE,QAAQ,CAAC;IACvB,WAAW,EAAE,IAAI,CAAC;CACnB;AAQD,iBAAS,WAAW,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,WAAW,2CAuB9D;AAED,eAAO,MAAM,MAAM,+CAAoB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { colors } from "../theme";
5
+ const TABS = [
6
+ { id: "sessions", label: "Sessions", key: "1" },
7
+ { id: "tools", label: "Tools", key: "2" },
8
+ { id: "overview", label: "Overview", key: "3" },
9
+ ];
10
+ function TabBarInner({ activeScreen, lastRefresh }) {
11
+ return (_jsxs(Box, { paddingX: 1, borderStyle: "single", borderColor: colors.border, flexDirection: "row", children: [_jsxs(Text, { color: colors.accent, bold: true, children: ["OCMonitor", " "] }), TABS.map((tab) => {
12
+ const isActive = tab.id === activeScreen;
13
+ return (_jsx(Box, { marginRight: 1, children: _jsxs(Text, { color: isActive ? colors.accent : colors.textDim, bold: isActive, children: ["[", tab.key, "]", isActive ? _jsxs(Text, { color: colors.text, children: [" ", tab.label] }) : ` ${tab.label}`] }) }, tab.id));
14
+ }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: lastRefresh.toLocaleTimeString() })] }));
15
+ }
16
+ export const TabBar = memo(TabBarInner);
17
+ //# sourceMappingURL=TabBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabBar.js","sourceRoot":"","sources":["../../../src/ui/components/TabBar.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAQlC,MAAM,IAAI,GAAmD;IAC3D,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE;IAC/C,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE;IACzC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE;CAChD,CAAC;AAEF,SAAS,WAAW,CAAC,EAAE,YAAY,EAAE,WAAW,EAAe;IAC7D,OAAO,CACL,MAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAC,KAAK,aACpF,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,gCACpB,GAAG,IACR,EACN,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBAChB,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,KAAK,YAAY,CAAC;gBACzC,OAAO,CACL,KAAC,GAAG,IAAc,WAAW,EAAE,CAAC,YAC9B,MAAC,IAAI,IACH,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAChD,IAAI,EAAE,QAAQ,kBAEZ,GAAG,CAAC,GAAG,OAAG,QAAQ,CAAC,CAAC,CAAC,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,kBAAI,GAAG,CAAC,KAAK,IAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,IACjF,IANC,GAAG,CAAC,EAAE,CAOV,CACP,CAAC;YACJ,CAAC,CAAC,EACF,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,GAAI,EACpB,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,OAAO,YAAG,WAAW,CAAC,kBAAkB,EAAE,GAAQ,IAClE,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { Workflow } from "../../core/types";
3
+ interface OverviewScreenProps {
4
+ workflows: Workflow[];
5
+ isActive: boolean;
6
+ contentHeight: number;
7
+ terminalWidth: number;
8
+ }
9
+ declare function OverviewScreenInner({ workflows, isActive, contentHeight, terminalWidth }: OverviewScreenProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const OverviewScreen: React.MemoExoticComponent<typeof OverviewScreenInner>;
11
+ export {};
12
+ //# sourceMappingURL=OverviewScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverviewScreen.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/OverviewScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAK7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,UAAU,mBAAmB;IAC3B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AA8FD,iBAAS,mBAAmB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,mBAAmB,2CAmNtG;AAED,eAAO,MAAM,cAAc,uDAA4B,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, memo } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { colors } from "../theme";
5
+ import { StatusBar } from "../components/StatusBar";
6
+ import { SparkLine } from "../components/SparkLine";
7
+ import { computeOverviewStats, buildSparkSeries } from "../../core/session";
8
+ import { getAllPricing } from "../../data/pricing";
9
+ function formatTokens(n) {
10
+ if (n >= 1_000_000)
11
+ return `${(n / 1_000_000).toFixed(1)}M`;
12
+ if (n >= 1_000)
13
+ return `${(n / 1_000).toFixed(1)}K`;
14
+ return n.toString();
15
+ }
16
+ function StatRow({ label, value, color = colors.text }) {
17
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 18, children: _jsx(Text, { color: colors.textDim, children: label }) }), _jsx(Text, { color: color, children: value })] }));
18
+ }
19
+ function SectionHeader({ title }) {
20
+ return (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.purple, bold: true, children: title }) }));
21
+ }
22
+ /** Horizontal bar: filled █ proportional to value/max, with label and count */
23
+ function HBar({ label, value, max, total, width = 16, barColor = colors.info, labelWidth = 10, showPct = false, }) {
24
+ const pct = max > 0 ? value / max : 0;
25
+ const filled = Math.max(0, Math.round(pct * width));
26
+ const empty = width - filled;
27
+ const pctStr = showPct && total && total > 0 ? ` ${Math.round((value / total) * 100)}%` : "";
28
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: labelWidth, children: _jsx(Text, { color: colors.text, children: truncate(label, labelWidth - 1) }) }), _jsx(Text, { color: barColor, children: "█".repeat(filled) }), _jsx(Text, { color: colors.border, children: "░".repeat(empty) }), _jsxs(Text, { color: colors.textDim, children: [" ", value, pctStr] })] }));
29
+ }
30
+ /** Error rate bar: shows ok + error segments */
31
+ function ErrorBar({ label, calls, errors, width = 16, labelWidth = 8, }) {
32
+ const okCount = calls - errors;
33
+ const okFilled = calls > 0 ? Math.round((okCount / calls) * width) : width;
34
+ const errFilled = width - okFilled;
35
+ const errPct = calls > 0 ? Math.round((errors / calls) * 100) : 0;
36
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: labelWidth, children: _jsx(Text, { color: colors.text, children: truncate(label, labelWidth - 1) }) }), _jsx(Text, { color: colors.success, children: "█".repeat(okFilled) }), _jsx(Text, { color: errors > 0 ? colors.error : colors.border, children: "█".repeat(errFilled) }), _jsxs(Text, { color: colors.textDim, children: [" ", calls, " calls"] }), errors > 0 && _jsxs(Text, { color: colors.error, children: [" ", errors, " err (", errPct, "%)"] })] }));
37
+ }
38
+ function OverviewScreenInner({ workflows, isActive, contentHeight, terminalWidth }) {
39
+ const pricing = useMemo(() => getAllPricing(), []);
40
+ const stats = useMemo(() => computeOverviewStats(workflows, pricing), [workflows, pricing]);
41
+ const topModels = useMemo(() => Array.from(stats.modelBreakdown.entries())
42
+ .sort((a, b) => b[1].calls - a[1].calls)
43
+ .slice(0, 4), [stats]);
44
+ const topProjects = useMemo(() => Array.from(stats.projectBreakdown.entries())
45
+ .sort((a, b) => b[1].sessions - a[1].sessions)
46
+ .slice(0, 4), [stats]);
47
+ const agentToolErrorList = useMemo(() => Array.from(stats.agentToolErrors.entries())
48
+ .sort((a, b) => b[1].calls - a[1].calls), [stats]);
49
+ const topTools = useMemo(() => Array.from(stats.toolCallCounts.entries())
50
+ .sort((a, b) => b[1].calls - a[1].calls)
51
+ .slice(0, 8), [stats]);
52
+ const maxToolCalls = topTools[0]?.[1].calls ?? 1;
53
+ // Weekly sparklines
54
+ const weeklyTokenValues = stats.weeklyTokens.map((d) => d.tokens);
55
+ const weeklySessionValues = stats.weeklySessions.map((d) => d.sessions);
56
+ const maxWeeklyTokens = Math.max(...weeklyTokenValues, 1);
57
+ const maxWeeklySessions = Math.max(...weeklySessionValues, 1);
58
+ // Hourly heatmap — group into 4-hour buckets for compactness: 0-3,4-7,8-11,12-15,16-19,20-23
59
+ const hourlyBuckets = Array.from({ length: 6 }, (_, i) => stats.hourlyActivity.slice(i * 4, i * 4 + 4).reduce((a, b) => a + b, 0));
60
+ const hourSpark = buildSparkSeries(stats.hourlyActivity);
61
+ // Column widths based on terminal
62
+ const leftW = Math.max(32, Math.floor(terminalWidth * 0.38));
63
+ const midW = Math.max(26, Math.floor(terminalWidth * 0.30));
64
+ // right gets remaining
65
+ return (_jsxs(Box, { flexDirection: "column", width: terminalWidth, height: contentHeight, children: [_jsxs(Box, { paddingX: 1, flexDirection: "row", children: [_jsx(Text, { color: colors.accent, bold: true, children: "Overview" }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.textDim, children: [workflows.length, " workflows ", stats.totalTokens.total > 0 ? formatTokens(stats.totalTokens.total) + " tokens" : ""] })] }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, paddingX: 1, children: [_jsxs(Box, { flexDirection: "column", width: leftW, children: [_jsx(SectionHeader, { title: "Totals" }), _jsx(StatRow, { label: "Total tokens", value: formatTokens(stats.totalTokens.total) }), _jsx(StatRow, { label: " input", value: formatTokens(stats.totalTokens.input), color: colors.info }), _jsx(StatRow, { label: " output", value: formatTokens(stats.totalTokens.output), color: colors.cyan }), _jsx(StatRow, { label: " cache r/w", value: `${formatTokens(stats.totalTokens.cacheRead)} / ${formatTokens(stats.totalTokens.cacheWrite)}`, color: colors.textDim }), _jsx(StatRow, { label: "Total cost", value: `$${stats.totalCost.toFixed(4)}`, color: colors.success }), _jsx(SectionHeader, { title: "Token trend (7d)" }), _jsx(Box, { flexDirection: "row", children: _jsx(SparkLine, { values: weeklyTokenValues, color: colors.cyan }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: stats.weeklyTokens[0]?.date.slice(3) ?? "" }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.textDim, children: ["peak ", formatTokens(maxWeeklyTokens)] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: stats.weeklyTokens[6]?.date.slice(3) ?? "" })] }), _jsx(SectionHeader, { title: "Sessions (7d)" }), _jsx(Box, { flexDirection: "row", children: _jsx(SparkLine, { values: weeklySessionValues, color: colors.accent }) }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: stats.weeklySessions[0]?.date.slice(3) ?? "" }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.textDim, children: ["peak ", maxWeeklySessions, "/day"] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: stats.weeklySessions[6]?.date.slice(3) ?? "" })] }), _jsx(SectionHeader, { title: "Hourly activity" }), _jsx(Text, { color: colors.warning, children: hourSpark }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: "00" }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: "06" }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: "12" }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: "18" }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: "23" })] })] }), _jsxs(Box, { flexDirection: "column", width: midW, paddingLeft: 2, children: [_jsx(SectionHeader, { title: "Tool errors by agent" }), agentToolErrorList.length === 0
66
+ ? _jsx(Text, { color: colors.textDim, children: "No tool data" })
67
+ : agentToolErrorList.map(([agent, data]) => (_jsx(ErrorBar, { label: agent, calls: data.calls, errors: data.errors, width: 14, labelWidth: 9 }, agent))), _jsx(SectionHeader, { title: "Top tools (calls / errors)" }), topTools.length === 0
68
+ ? _jsx(Text, { color: colors.textDim, children: "No tool data" })
69
+ : topTools.map(([name, data]) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 10, children: _jsx(Text, { color: colors.text, children: truncate(name, 9) }) }), _jsx(Text, { color: data.errors > 0 ? colors.warning : colors.info, children: "█".repeat(Math.max(1, Math.round((data.calls / maxToolCalls) * 12))) }), _jsx(Text, { color: colors.border, children: "░".repeat(Math.max(0, 12 - Math.max(1, Math.round((data.calls / maxToolCalls) * 12)))) }), _jsxs(Text, { color: colors.textDim, children: [" ", data.calls] }), data.errors > 0 && _jsxs(Text, { color: colors.error, children: [" \u2717", data.errors] })] }, name)))] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingLeft: 2, children: [_jsx(SectionHeader, { title: "Projects" }), topProjects.length === 0
70
+ ? _jsx(Text, { color: colors.textDim, children: "No project data" })
71
+ : topProjects.map(([project, data]) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 22, children: _jsx(Text, { color: colors.text, children: truncate(project, 20) }) }), _jsxs(Text, { color: colors.info, children: [data.sessions, " sess"] }), _jsxs(Text, { color: colors.success, children: [" $", data.cost.toFixed(3)] })] }, project))), _jsx(SectionHeader, { title: "Tool avg duration (top 5)" }), (() => {
72
+ const durList = Array.from(stats.toolCallCounts.entries())
73
+ .filter(([, d]) => d.calls > 0 && d.totalDurationMs > 0)
74
+ .map(([name, d]) => ({ name, avg: d.totalDurationMs / d.calls }))
75
+ .sort((a, b) => b.avg - a.avg)
76
+ .slice(0, 5);
77
+ const maxAvg = durList[0]?.avg ?? 1;
78
+ const barW = 10;
79
+ return durList.map(({ name, avg }) => {
80
+ const filled = Math.max(1, Math.round((avg / maxAvg) * barW));
81
+ const durStr = avg < 1000 ? `${avg.toFixed(0)}ms` : `${(avg / 1000).toFixed(1)}s`;
82
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 12, children: _jsx(Text, { color: colors.text, children: truncate(name, 10) }) }), _jsx(Text, { color: colors.warning, children: "█".repeat(filled) }), _jsx(Text, { color: colors.border, children: "░".repeat(barW - filled) }), _jsxs(Text, { color: colors.textDim, children: [" ", durStr] })] }, name));
83
+ });
84
+ })(), _jsx(SectionHeader, { title: "Models" }), topModels.length === 0
85
+ ? _jsx(Text, { color: colors.textDim, children: "No model data" })
86
+ : topModels.map(([model, data]) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 22, children: _jsx(Text, { color: colors.text, children: truncate(model, 20) }) }), _jsx(Text, { color: colors.info, children: data.calls }), _jsxs(Text, { color: colors.textDim, children: [" ", formatTokens(data.tokens)] })] }, model)))] })] }), _jsx(StatusBar, { hints: "1:sessions 2:tools r:refresh q:quit" })] }));
87
+ }
88
+ export const OverviewScreen = memo(OverviewScreenInner);
89
+ function truncate(s, max) {
90
+ if (s.length <= max)
91
+ return s;
92
+ return s.slice(0, max - 1) + "…";
93
+ }
94
+ //# sourceMappingURL=OverviewScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverviewScreen.js","sourceRoot":"","sources":["../../../src/ui/screens/OverviewScreen.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { Workflow } from "../../core/types";
3
+ interface SessionsScreenProps {
4
+ workflows: Workflow[];
5
+ isActive: boolean;
6
+ contentHeight: number;
7
+ terminalWidth: number;
8
+ }
9
+ declare function SessionsScreenInner({ workflows, isActive, contentHeight, terminalWidth, }: SessionsScreenProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const SessionsScreen: React.MemoExoticComponent<typeof SessionsScreenInner>;
11
+ export {};
12
+ //# sourceMappingURL=SessionsScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionsScreen.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/SessionsScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAOpE,OAAO,KAAK,EAAE,QAAQ,EAAgC,MAAM,kBAAkB,CAAC;AAE/E,UAAU,mBAAmB;IAC3B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAyBD,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,QAAQ,EACR,aAAa,EACb,aAAa,GACd,EAAE,mBAAmB,2CAgJrB;AAED,eAAO,MAAM,cAAc,uDAA4B,CAAC"}
@@ -0,0 +1,98 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useMemo, useCallback, memo } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { colors } from "../theme";
5
+ import { StatusBar } from "../components/StatusBar";
6
+ import { AgentTree } from "../components/AgentTree";
7
+ import { DetailsPanel } from "../components/DetailsPanel";
8
+ import { MessagesPanel } from "../components/MessagesPanel";
9
+ function flattenWorkflow(workflow, workflowIndex) {
10
+ const nodes = [];
11
+ function walk(node) {
12
+ nodes.push({
13
+ id: node.session.id,
14
+ session: node.session,
15
+ workflowIndex,
16
+ depth: node.depth,
17
+ hasChildren: node.children.length > 0,
18
+ agentNode: node,
19
+ });
20
+ for (const child of node.children) {
21
+ walk(child);
22
+ }
23
+ }
24
+ walk(workflow.agentTree);
25
+ return nodes;
26
+ }
27
+ function SessionsScreenInner({ workflows, isActive, contentHeight, terminalWidth, }) {
28
+ const [selectedIndex, setSelectedIndex] = useState(0);
29
+ const [rightMode, setRightMode] = useState("stats");
30
+ const [msgScrollOffset, setMsgScrollOffset] = useState(0);
31
+ // Flat list of all nodes (root workflows + sub-agents in tree order)
32
+ const flatNodes = useMemo(() => {
33
+ return workflows.flatMap((w, i) => flattenWorkflow(w, i));
34
+ }, [workflows]);
35
+ const clampedIndex = Math.min(selectedIndex, Math.max(0, flatNodes.length - 1));
36
+ const selectedNode = flatNodes[clampedIndex] ?? null;
37
+ // For DetailsPanel we need the full Workflow — use the root workflow of the selected node
38
+ const selectedWorkflow = useMemo(() => {
39
+ if (!selectedNode)
40
+ return null;
41
+ const w = workflows[selectedNode.workflowIndex];
42
+ if (!w)
43
+ return null;
44
+ // If we selected a sub-agent, wrap it as a single-session workflow for DetailsPanel
45
+ if (selectedNode.session.id !== w.mainSession.id) {
46
+ return {
47
+ id: selectedNode.session.id,
48
+ mainSession: selectedNode.session,
49
+ subAgentSessions: selectedNode.agentNode.children.map((c) => c.session),
50
+ agentTree: selectedNode.agentNode,
51
+ };
52
+ }
53
+ return w;
54
+ }, [selectedNode, workflows]);
55
+ const leftWidth = Math.floor(terminalWidth * 0.35);
56
+ const rightWidth = terminalWidth - leftWidth - 2; // 2 for borders
57
+ // Message scroll: reset when selection changes
58
+ const handleSelect = useCallback((index) => {
59
+ setSelectedIndex(index);
60
+ setMsgScrollOffset(0);
61
+ }, []);
62
+ useInput((input, key) => {
63
+ if (key.upArrow || input === "k") {
64
+ handleSelect(Math.max(0, clampedIndex - 1));
65
+ return;
66
+ }
67
+ if (key.downArrow || input === "j") {
68
+ handleSelect(Math.min(flatNodes.length - 1, clampedIndex + 1));
69
+ return;
70
+ }
71
+ if (key.tab) {
72
+ setRightMode((m) => (m === "stats" ? "messages" : "stats"));
73
+ setMsgScrollOffset(0);
74
+ return;
75
+ }
76
+ // Message scroll (only when in messages mode)
77
+ if (rightMode === "messages") {
78
+ if (input === "u" || key.pageUp) {
79
+ setMsgScrollOffset((o) => Math.max(0, o - 10));
80
+ return;
81
+ }
82
+ if (input === "d" || key.pageDown) {
83
+ setMsgScrollOffset((o) => o + 10);
84
+ return;
85
+ }
86
+ }
87
+ }, { isActive });
88
+ const panelHeight = contentHeight - 2; // leave room for status bar
89
+ return (_jsxs(Box, { flexDirection: "column", width: terminalWidth, height: contentHeight, children: [_jsxs(Box, { flexDirection: "row", flexGrow: 1, children: [_jsx(Box, { width: leftWidth, borderStyle: "single", borderColor: colors.border, flexDirection: "column", overflow: "hidden", children: _jsx(AgentTree, { workflows: workflows, selectedId: selectedNode?.id ?? null, flatNodes: flatNodes, onSelect: (id) => {
90
+ const idx = flatNodes.findIndex((n) => n.id === id);
91
+ if (idx >= 0)
92
+ handleSelect(idx);
93
+ }, maxHeight: panelHeight }) }), _jsxs(Box, { flexGrow: 1, width: rightWidth, borderStyle: "single", borderColor: colors.border, flexDirection: "column", overflow: "hidden", children: [_jsxs(Box, { paddingX: 1, flexDirection: "row", children: [_jsx(Text, { color: rightMode === "stats" ? colors.accent : colors.textDim, bold: rightMode === "stats", children: "[Stats]" }), _jsx(Text, { color: colors.textDim, children: " " }), _jsx(Text, { color: rightMode === "messages" ? colors.accent : colors.textDim, bold: rightMode === "messages", children: "[Messages]" }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: "Tab:switch" })] }), rightMode === "stats" ? (_jsx(DetailsPanel, { workflow: selectedWorkflow })) : (_jsx(MessagesPanel, { session: selectedNode?.session ?? null, scrollOffset: msgScrollOffset, onScrollOffsetChange: setMsgScrollOffset, maxHeight: panelHeight - 2 }))] })] }), _jsx(StatusBar, { hints: rightMode === "messages"
94
+ ? "j/k:nav Tab:stats u/d:scroll 2:tools 3:overview r:refresh q:quit"
95
+ : "j/k:nav Tab:messages 2:tools 3:overview r:refresh q:quit" })] }));
96
+ }
97
+ export const SessionsScreen = memo(SessionsScreenInner);
98
+ //# sourceMappingURL=SessionsScreen.js.map