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 @@
1
+ {"version":3,"file":"SessionsScreen.js","sourceRoot":"","sources":["../../../src/ui/screens/SessionsScreen.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import type { Workflow } from "../../core/types";
3
+ interface TimelineScreenProps {
4
+ workflows: Workflow[];
5
+ isActive: boolean;
6
+ contentHeight: number;
7
+ }
8
+ declare function TimelineScreenInner({ workflows, isActive, contentHeight }: TimelineScreenProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare const TimelineScreen: React.MemoExoticComponent<typeof TimelineScreenInner>;
10
+ export {};
11
+ //# sourceMappingURL=TimelineScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimelineScreen.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/TimelineScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,KAAK,EAAE,QAAQ,EAA4B,MAAM,kBAAkB,CAAC;AAE3E,UAAU,mBAAmB;IAC3B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA8ID,iBAAS,mBAAmB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,mBAAmB,2CA8DvF;AAED,eAAO,MAAM,cAAc,uDAA4B,CAAC"}
@@ -0,0 +1,128 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } 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
+ function formatTime(ts) {
7
+ if (!ts)
8
+ return "??:??";
9
+ return new Date(ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
10
+ }
11
+ function buildTimeline(workflows) {
12
+ const lines = [];
13
+ const allSessions = workflows.flatMap((w) => [
14
+ w.mainSession,
15
+ ...w.subAgentSessions,
16
+ ]);
17
+ // Sort by timeCreated
18
+ allSessions.sort((a, b) => (a.timeCreated ?? 0) - (b.timeCreated ?? 0));
19
+ for (const session of allSessions) {
20
+ const agentName = session.interactions[0]?.agent ?? null;
21
+ lines.push({
22
+ kind: "session-header",
23
+ sessionId: session.id,
24
+ title: session.title ?? session.id.slice(0, 12),
25
+ agent: agentName,
26
+ time: session.timeCreated,
27
+ });
28
+ for (const interaction of session.interactions) {
29
+ if (interaction.role !== "assistant")
30
+ continue;
31
+ lines.push({
32
+ kind: "interaction-header",
33
+ interactionId: interaction.id,
34
+ modelId: interaction.modelId,
35
+ time: interaction.time.created,
36
+ agent: interaction.agent,
37
+ });
38
+ for (const part of interaction.parts) {
39
+ if (part.type === "tool") {
40
+ lines.push({
41
+ kind: "tool-call",
42
+ part: part,
43
+ interactionId: interaction.id,
44
+ });
45
+ }
46
+ else if (part.type === "text" && part.text.trim().length > 0) {
47
+ lines.push({
48
+ kind: "text-snippet",
49
+ text: part.text.slice(0, 120).replace(/\n/g, " "),
50
+ interactionId: interaction.id,
51
+ });
52
+ }
53
+ else if (part.type === "reasoning" && part.text.trim().length > 0) {
54
+ lines.push({
55
+ kind: "reasoning-snippet",
56
+ text: part.text.slice(0, 100).replace(/\n/g, " "),
57
+ interactionId: interaction.id,
58
+ });
59
+ }
60
+ }
61
+ }
62
+ lines.push({ kind: "spacer" });
63
+ }
64
+ return lines;
65
+ }
66
+ function renderLine(line, idx) {
67
+ switch (line.kind) {
68
+ case "session-header":
69
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: colors.accent, bold: true, children: ["\u25B6 ", truncate(line.title, 40)] }), line.agent && _jsxs(Text, { color: colors.cyan, children: [" [", line.agent, "]"] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: formatTime(line.time) })] }, idx));
70
+ case "interaction-header":
71
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: " " }), _jsx(Text, { color: colors.purple, children: "\u25C6 " }), _jsx(Text, { color: colors.info, children: truncate(line.modelId, 30) }), line.agent && _jsxs(Text, { color: colors.cyan, children: [" [", line.agent, "]"] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: formatTime(line.time) })] }, idx));
72
+ case "tool-call": {
73
+ const p = line.part;
74
+ const statusIcon = p.status === "completed" ? "✓" : p.status === "error" ? "✗" : "◌";
75
+ const statusColor = p.status === "completed" ? colors.success : p.status === "error" ? colors.error : colors.warning;
76
+ const durationMs = p.timeEnd > 0 && p.timeStart > 0 ? p.timeEnd - p.timeStart : 0;
77
+ const durationStr = durationMs > 0 ? ` ${(durationMs / 1000).toFixed(1)}s` : "";
78
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: " " }), _jsxs(Text, { color: statusColor, children: [statusIcon, " "] }), _jsx(Text, { color: colors.text, children: truncate(p.toolName, 20) }), p.title && _jsxs(Text, { color: colors.textDim, children: [" ", truncate(p.title, 25)] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: durationStr })] }, idx));
79
+ }
80
+ case "text-snippet":
81
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: " \u2502 " }), _jsx(Text, { color: colors.text, children: truncate(line.text, 80) })] }, idx));
82
+ case "reasoning-snippet":
83
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, children: " \u26A1 " }), _jsx(Text, { color: colors.accentDim, children: truncate(line.text, 80) })] }, idx));
84
+ case "spacer":
85
+ return _jsx(Box, {}, idx);
86
+ }
87
+ }
88
+ function TimelineScreenInner({ workflows, isActive, contentHeight }) {
89
+ const [scrollOffset, setScrollOffset] = useState(0);
90
+ const allLines = useMemo(() => buildTimeline(workflows), [workflows]);
91
+ const visibleHeight = contentHeight - 4; // header row + status bar + borders
92
+ const clampOffset = useCallback((offset) => Math.max(0, Math.min(offset, Math.max(0, allLines.length - visibleHeight))), [allLines.length, visibleHeight]);
93
+ useInput((input, key) => {
94
+ if (key.upArrow || input === "k") {
95
+ setScrollOffset((o) => clampOffset(o - 1));
96
+ return;
97
+ }
98
+ if (key.downArrow || input === "j") {
99
+ setScrollOffset((o) => clampOffset(o + 1));
100
+ return;
101
+ }
102
+ if (input === "g") {
103
+ setScrollOffset(0);
104
+ return;
105
+ }
106
+ if (input === "G") {
107
+ setScrollOffset(clampOffset(allLines.length));
108
+ return;
109
+ }
110
+ if (key.pageUp) {
111
+ setScrollOffset((o) => clampOffset(o - visibleHeight));
112
+ return;
113
+ }
114
+ if (key.pageDown) {
115
+ setScrollOffset((o) => clampOffset(o + visibleHeight));
116
+ return;
117
+ }
118
+ }, { isActive });
119
+ const visibleLines = allLines.slice(scrollOffset, scrollOffset + visibleHeight);
120
+ return (_jsxs(Box, { flexDirection: "column", height: contentHeight, children: [_jsxs(Box, { paddingX: 1, flexDirection: "row", children: [_jsx(Text, { color: colors.accent, bold: true, children: "Timeline" }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.textDim, children: [scrollOffset + 1, "-", Math.min(scrollOffset + visibleHeight, allLines.length), "/", allLines.length] })] }), _jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: visibleLines.map((line, i) => renderLine(line, scrollOffset + i)) }), _jsx(StatusBar, { hints: "j/k:scroll g/G:top/bottom PgUp/PgDn:page 1:sessions 3:tools 4:overview q:quit" })] }));
121
+ }
122
+ export const TimelineScreen = memo(TimelineScreenInner);
123
+ function truncate(s, max) {
124
+ if (s.length <= max)
125
+ return s;
126
+ return s.slice(0, max - 1) + "…";
127
+ }
128
+ //# sourceMappingURL=TimelineScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimelineScreen.js","sourceRoot":"","sources":["../../../src/ui/screens/TimelineScreen.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 ToolsScreenProps {
4
+ workflows: Workflow[];
5
+ isActive: boolean;
6
+ contentHeight: number;
7
+ terminalWidth: number;
8
+ }
9
+ declare function ToolsScreenInner({ workflows, isActive, contentHeight, terminalWidth }: ToolsScreenProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const ToolsScreen: React.MemoExoticComponent<typeof ToolsScreenInner>;
11
+ export {};
12
+ //# sourceMappingURL=ToolsScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolsScreen.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/ToolsScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAIvD,OAAO,KAAK,EAAE,QAAQ,EAAa,MAAM,kBAAkB,CAAC;AAG5D,UAAU,gBAAgB;IACxB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAgED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,gBAAgB,2CAgLhG;AAED,eAAO,MAAM,WAAW,oDAAyB,CAAC"}
@@ -0,0 +1,113 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState, useMemo, memo } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { colors } from "../theme";
5
+ import { StatusBar } from "../components/StatusBar";
6
+ import { getToolUsage } from "../../core/session";
7
+ function aggregateToolUsage(workflows) {
8
+ const merged = new Map();
9
+ for (const workflow of workflows) {
10
+ const allSessions = [workflow.mainSession, ...workflow.subAgentSessions];
11
+ for (const session of allSessions) {
12
+ for (const tool of getToolUsage(session)) {
13
+ const existing = merged.get(tool.name) ?? {
14
+ calls: 0,
15
+ successes: 0,
16
+ failures: 0,
17
+ totalDurationMs: 0,
18
+ recentErrors: [],
19
+ };
20
+ existing.calls += tool.calls;
21
+ existing.successes += tool.successes;
22
+ existing.failures += tool.failures;
23
+ existing.totalDurationMs += tool.totalDurationMs;
24
+ for (const err of tool.recentErrors) {
25
+ if (existing.recentErrors.length < 3)
26
+ existing.recentErrors.push(err);
27
+ }
28
+ merged.set(tool.name, existing);
29
+ }
30
+ }
31
+ }
32
+ return Array.from(merged.entries()).map(([name, s]) => ({
33
+ name,
34
+ calls: s.calls,
35
+ successes: s.successes,
36
+ failures: s.failures,
37
+ totalDurationMs: s.totalDurationMs,
38
+ avgDurationMs: s.calls > 0 ? s.totalDurationMs / s.calls : 0,
39
+ recentErrors: s.recentErrors,
40
+ }));
41
+ }
42
+ function SuccessBar({ successes, calls, width = 12 }) {
43
+ const pct = calls > 0 ? successes / calls : 0;
44
+ const filled = Math.round(pct * width);
45
+ const empty = width - filled;
46
+ const color = pct >= 0.9 ? colors.success : pct >= 0.7 ? colors.warning : colors.error;
47
+ 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), "%"] })] }));
48
+ }
49
+ function formatDuration(ms) {
50
+ if (ms === 0)
51
+ return "—";
52
+ if (ms < 1000)
53
+ return `${ms.toFixed(0)}ms`;
54
+ return `${(ms / 1000).toFixed(1)}s`;
55
+ }
56
+ function ToolsScreenInner({ workflows, isActive, contentHeight, terminalWidth }) {
57
+ const [selectedIndex, setSelectedIndex] = useState(0);
58
+ const [sortKey, setSortKey] = useState("calls");
59
+ const allTools = useMemo(() => aggregateToolUsage(workflows), [workflows]);
60
+ const sortedTools = useMemo(() => {
61
+ const copy = [...allTools];
62
+ switch (sortKey) {
63
+ case "calls":
64
+ return copy.sort((a, b) => b.calls - a.calls);
65
+ case "failures":
66
+ return copy.sort((a, b) => b.failures - a.failures);
67
+ case "avgTime":
68
+ return copy.sort((a, b) => b.avgDurationMs - a.avgDurationMs);
69
+ }
70
+ }, [allTools, sortKey]);
71
+ const listHeight = contentHeight - 4; // header + status bar + padding
72
+ const clampedIndex = Math.min(selectedIndex, Math.max(0, sortedTools.length - 1));
73
+ const selectedTool = sortedTools[clampedIndex] ?? null;
74
+ // Pagination
75
+ const startIndex = clampedIndex >= listHeight ? clampedIndex - listHeight + 1 : 0;
76
+ const visibleTools = sortedTools.slice(startIndex, startIndex + listHeight);
77
+ useInput((input, key) => {
78
+ if (key.upArrow || input === "k") {
79
+ setSelectedIndex((i) => Math.max(0, i - 1));
80
+ return;
81
+ }
82
+ if (key.downArrow || input === "j") {
83
+ setSelectedIndex((i) => Math.min(sortedTools.length - 1, i + 1));
84
+ return;
85
+ }
86
+ if (key.tab) {
87
+ setSortKey((k) => {
88
+ if (k === "calls")
89
+ return "failures";
90
+ if (k === "failures")
91
+ return "avgTime";
92
+ return "calls";
93
+ });
94
+ return;
95
+ }
96
+ }, { isActive });
97
+ const sortLabels = {
98
+ calls: "Calls",
99
+ failures: "Failures",
100
+ avgTime: "Avg Time",
101
+ };
102
+ 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: "Tools" }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.textDim, children: ["sort:", " ", ["calls", "failures", "avgTime"].map((k) => (_jsxs(Text, { color: sortKey === k ? colors.accent : colors.textDim, children: ["[", k === sortKey ? sortLabels[k] : k, "]", " "] }, k))), "Tab:cycle"] })] }), _jsxs(Box, { flexDirection: "row", flexGrow: 1, children: [_jsxs(Box, { width: 36, flexDirection: "column", borderStyle: "single", borderColor: colors.border, children: [_jsxs(Box, { paddingX: 1, flexDirection: "row", children: [_jsx(Text, { color: colors.textDim, bold: true, children: "Tool" }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.textDim, children: "calls " }), _jsx(Text, { color: colors.textDim, children: "err" })] }), visibleTools.map((tool, i) => {
103
+ const isSelected = tool.name === selectedTool?.name;
104
+ return (_jsxs(Box, { flexDirection: "row", paddingX: 1, children: [_jsxs(Text, { color: isSelected ? colors.accent : colors.textDim, bold: isSelected, children: [isSelected ? "▶ " : " ", truncate(tool.name, 20)] }), _jsx(Box, { flexGrow: 1 }), _jsx(Text, { color: colors.info, children: tool.calls }), _jsx(Text, { color: colors.textDim, children: " " }), _jsx(Text, { color: tool.failures > 0 ? colors.error : colors.textDim, children: tool.failures })] }, tool.name));
105
+ }), allTools.length === 0 && (_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: colors.textDim, children: "No tool data yet" }) }))] }), _jsx(Box, { flexGrow: 1, flexDirection: "column", borderStyle: "single", borderColor: colors.border, paddingX: 1, children: selectedTool ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: colors.cyan, bold: true, children: selectedTool.name }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 14, children: _jsx(Text, { color: colors.textDim, children: "Total calls" }) }), _jsx(Text, { color: colors.text, children: selectedTool.calls })] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 14, children: _jsx(Text, { color: colors.textDim, children: "Successes" }) }), _jsx(Text, { color: colors.success, children: selectedTool.successes })] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 14, children: _jsx(Text, { color: colors.textDim, children: "Failures" }) }), _jsx(Text, { color: selectedTool.failures > 0 ? colors.error : colors.textDim, children: selectedTool.failures })] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 14, children: _jsx(Text, { color: colors.textDim, children: "Avg time" }) }), _jsx(Text, { color: colors.info, children: formatDuration(selectedTool.avgDurationMs) })] })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: colors.textDim, children: "Success rate " }), _jsx(SuccessBar, { successes: selectedTool.successes, calls: selectedTool.calls })] }), selectedTool.recentErrors.length > 0 && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.warning, bold: true, children: "Recent Errors" }) }), selectedTool.recentErrors.map((err, i) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: colors.error, children: "\u2022 " }), _jsx(Text, { color: colors.text, children: truncate(err, 60) })] }, i)))] }))] })) : (_jsx(Text, { color: colors.textDim, children: "No tools found. Run some OpenCode sessions first." })) })] }), _jsx(StatusBar, { hints: "j/k:nav Tab:cycle-sort 1:sessions 3:overview q:quit", info: `${allTools.length} tools` })] }));
106
+ }
107
+ export const ToolsScreen = memo(ToolsScreenInner);
108
+ function truncate(s, max) {
109
+ if (s.length <= max)
110
+ return s;
111
+ return s.slice(0, max - 1) + "…";
112
+ }
113
+ //# sourceMappingURL=ToolsScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolsScreen.js","sourceRoot":"","sources":["../../../src/ui/screens/ToolsScreen.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export declare const colors: {
2
+ readonly bg: "#1a1a2e";
3
+ readonly bgSecondary: "#16213e";
4
+ readonly border: "#0f3460";
5
+ readonly accent: "#e94560";
6
+ readonly accentDim: "#533483";
7
+ readonly text: "#eaeaea";
8
+ readonly textDim: "#888";
9
+ readonly success: "#4ade80";
10
+ readonly warning: "#fbbf24";
11
+ readonly error: "#f87171";
12
+ readonly info: "#60a5fa";
13
+ readonly purple: "#a855f7";
14
+ readonly cyan: "#22d3ee";
15
+ };
16
+ export declare const tokens: {
17
+ readonly radius: 1;
18
+ readonly paddingX: 1;
19
+ readonly paddingY: 0;
20
+ };
21
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;CAcT,CAAC;AAEX,eAAO,MAAM,MAAM;;;;CAIT,CAAC"}
@@ -0,0 +1,21 @@
1
+ export const colors = {
2
+ bg: "#1a1a2e",
3
+ bgSecondary: "#16213e",
4
+ border: "#0f3460",
5
+ accent: "#e94560",
6
+ accentDim: "#533483",
7
+ text: "#eaeaea",
8
+ textDim: "#888",
9
+ success: "#4ade80",
10
+ warning: "#fbbf24",
11
+ error: "#f87171",
12
+ info: "#60a5fa",
13
+ purple: "#a855f7",
14
+ cyan: "#22d3ee",
15
+ };
16
+ export const tokens = {
17
+ radius: 1,
18
+ paddingX: 1,
19
+ paddingY: 0,
20
+ };
21
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,EAAE,EAAE,SAAS;IACb,WAAW,EAAE,SAAS;IACtB,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,SAAS;IACjB,SAAS,EAAE,SAAS;IACpB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;CACP,CAAC;AAEX,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;CACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-top",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "Monitor OpenCode AI coding sessions - Token usage, costs, and agent analytics",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "scripts": {
10
10
  "build": "node build.mjs",
11
+ "prepublishOnly": "node build.mjs",
11
12
  "dev": "tsc --watch",
12
13
  "start": "node --import tsx src/cli.ts",
13
14
  "lint": "biome check src",
package/bin/octop.mjs DELETED
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from "module";
3
- import { fileURLToPath } from "url";
4
- import { dirname, join } from "path";
5
-
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
- const pkgRoot = join(__dirname, "..");
8
-
9
- // Use tsx to run the TypeScript source
10
- const { register } = await import("tsx/esm/api");
11
- register();
12
-
13
- await import(join(pkgRoot, "src", "cli.ts"));
package/src/cli.ts DELETED
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env node
2
- import React from "react";
3
- import { render } from "ink";
4
- import { program } from "commander";
5
- import { App } from "./ui/App";
6
- import { loadSessions, getDbPath } from "./data/sqlite";
7
- import { groupSessionsToWorkflows } from "./core/agents";
8
- import { getWorkflowCostSingle, getSessionDuration } from "./core/session";
9
- import { getPricing } from "./data/pricing";
10
-
11
- const pkg = { version: "3.0.0", name: "ocmonitor" };
12
-
13
- program
14
- .name(pkg.name)
15
- .version(pkg.version)
16
- .description("Monitor OpenCode AI coding sessions");
17
-
18
- program
19
- .command("live")
20
- .description("Start live monitoring dashboard")
21
- .option("-i, --interval <ms>", "Refresh interval in milliseconds", "2000")
22
- .action((options) => {
23
- const refreshInterval = Number.parseInt(options.interval, 10);
24
- render(React.createElement(App, { refreshInterval }));
25
- });
26
-
27
- program
28
- .command("sessions")
29
- .description("List all sessions")
30
- .option("-l, --limit <n>", "Limit number of sessions", "50")
31
- .action((options) => {
32
- const limit = Number.parseInt(options.limit, 10);
33
- try {
34
- const sessions = loadSessions(getDbPath());
35
- const workflows = groupSessionsToWorkflows(sessions);
36
-
37
- const shown = workflows.slice(0, limit);
38
- console.log(`\nOCMonitor — ${shown.length}/${workflows.length} workflows\n`);
39
- console.log(`${"Title".padEnd(40)} ${"Project".padEnd(20)} ${"Cost".padEnd(10)} Dur`);
40
- console.log("─".repeat(80));
41
-
42
- for (const workflow of shown) {
43
- const { mainSession } = workflow;
44
- const pricing = getPricing(mainSession.interactions[0]?.modelId ?? "");
45
- const cost = getWorkflowCostSingle(workflow, pricing);
46
- const dur = getSessionDuration(mainSession);
47
- const title = (mainSession.title ?? "Untitled").slice(0, 38).padEnd(40);
48
- const project = (mainSession.projectName ?? "—").slice(0, 18).padEnd(20);
49
- const costStr = `$${cost.toFixed(3)}`.padEnd(10);
50
- const durStr = dur > 0 ? `${Math.floor(dur / 60000)}m${Math.floor((dur % 60000) / 1000)}s` : "—";
51
- console.log(`${title} ${project} ${costStr} ${durStr}`);
52
- }
53
- console.log();
54
- } catch (e) {
55
- console.error("Error:", e instanceof Error ? e.message : e);
56
- process.exit(1);
57
- }
58
- });
59
-
60
- program.parse();
@@ -1,78 +0,0 @@
1
- import type { Session, Workflow, AgentNode } from "./types";
2
-
3
- export class AgentRegistry {
4
- private mainAgents = new Set(["plan", "build"]);
5
- private subAgents = new Set(["explore"]);
6
-
7
- isMainAgent(agent: string | null): boolean {
8
- if (!agent) return true;
9
- return this.mainAgents.has(agent);
10
- }
11
-
12
- isSubAgent(agent: string | null): boolean {
13
- if (!agent) return false;
14
- return this.subAgents.has(agent);
15
- }
16
-
17
- addMainAgent(agent: string): void {
18
- this.mainAgents.add(agent);
19
- }
20
-
21
- addSubAgent(agent: string): void {
22
- this.subAgents.add(agent);
23
- }
24
- }
25
-
26
- function buildAgentNode(
27
- session: Session,
28
- sessionMap: Map<string, Session>,
29
- depth: number
30
- ): AgentNode {
31
- // Find all direct children of this session
32
- const children: AgentNode[] = [];
33
- for (const [, s] of sessionMap) {
34
- if (s.parentId === session.id) {
35
- children.push(buildAgentNode(s, sessionMap, depth + 1));
36
- }
37
- }
38
- // Sort children by timeCreated
39
- children.sort(
40
- (a, b) => (a.session.timeCreated ?? 0) - (b.session.timeCreated ?? 0)
41
- );
42
- return { session, children, depth };
43
- }
44
-
45
- function collectAllDescendants(node: AgentNode): Session[] {
46
- const result: Session[] = [];
47
- for (const child of node.children) {
48
- result.push(child.session);
49
- result.push(...collectAllDescendants(child));
50
- }
51
- return result;
52
- }
53
-
54
- export function groupSessionsToWorkflows(
55
- sessions: Session[],
56
- _registry?: AgentRegistry
57
- ): Workflow[] {
58
- const sessionMap = new Map<string, Session>(sessions.map((s) => [s.id, s]));
59
-
60
- // Find root sessions (no parentId)
61
- const roots = sessions.filter((s) => s.parentId === null);
62
-
63
- const workflows: Workflow[] = [];
64
-
65
- for (const root of roots) {
66
- const agentTree = buildAgentNode(root, sessionMap, 0);
67
- const subAgentSessions = collectAllDescendants(agentTree);
68
-
69
- workflows.push({
70
- id: root.id,
71
- mainSession: root,
72
- subAgentSessions,
73
- agentTree,
74
- });
75
- }
76
-
77
- return workflows;
78
- }