@townco/cli 0.1.33 → 0.1.35

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.
@@ -39,7 +39,6 @@ export function MergedLogsPane({ services, onClear }) {
39
39
  const [searchQuery, setSearchQuery] = useState("");
40
40
  const [serviceFilter, setServiceFilter] = useState(null);
41
41
  const [levelFilter, setLevelFilter] = useState(null);
42
- const maxLines = 25;
43
42
  // Only include services that actually have output
44
43
  const availableServices = useMemo(() => services.filter((s) => s.output.length > 0).map((s) => s.service), [services]);
45
44
  // Clear service filter if the selected service is no longer available
@@ -153,16 +152,13 @@ export function MergedLogsPane({ services, onClear }) {
153
152
  return levelFilteredLines.filter((log) => fuzzyMatch(searchQuery, log.line));
154
153
  }, [levelFilteredLines, searchQuery]);
155
154
  const isAtBottom = scrollOffset === 0;
156
- // Calculate which slice to show
155
+ // Show all lines - no truncation
157
156
  const displayLines = useMemo(() => {
158
157
  if (isAtBottom) {
159
- return searchedLines.slice(-maxLines);
158
+ return searchedLines; // Show all logs when at bottom
160
159
  }
161
- return searchedLines.slice(Math.max(0, searchedLines.length - maxLines - scrollOffset), searchedLines.length - scrollOffset);
160
+ return searchedLines.slice(0, searchedLines.length - scrollOffset);
162
161
  }, [searchedLines, scrollOffset, isAtBottom]);
163
- const _canScrollUp = searchedLines.length > maxLines &&
164
- scrollOffset < searchedLines.length - maxLines;
165
- const _canScrollDown = scrollOffset > 0;
166
162
  // Get overall status (error if any error, stopped if all stopped, etc.)
167
163
  const overallStatus = useMemo(() => {
168
164
  if (services.some((s) => s.status === "error"))
@@ -20,7 +20,6 @@ export function ProcessPane({ title, output, port, status, onClear, }) {
20
20
  const [scrollOffset, setScrollOffset] = useState(0); // 0 = at bottom, positive = scrolled up
21
21
  const [searchMode, setSearchMode] = useState(false);
22
22
  const [searchQuery, setSearchQuery] = useState("");
23
- const maxLines = 25;
24
23
  // Handle keyboard input for scrolling, clearing, and search
25
24
  useInput((input, key) => {
26
25
  // '/' to enter search mode
@@ -45,7 +44,7 @@ export function ProcessPane({ title, output, port, status, onClear, }) {
45
44
  }
46
45
  // Up arrow to scroll up
47
46
  if (key.upArrow) {
48
- setScrollOffset((prev) => Math.min(prev + 1, Math.max(0, output.length - maxLines)));
47
+ setScrollOffset((prev) => Math.min(prev + 1, output.length - 1));
49
48
  return;
50
49
  }
51
50
  // Down arrow to scroll down
@@ -69,16 +68,14 @@ export function ProcessPane({ title, output, port, status, onClear, }) {
69
68
  return output;
70
69
  return output.filter((line) => fuzzyMatch(searchQuery, line));
71
70
  }, [output, searchQuery]);
72
- // Calculate which slice of output to show
71
+ // Show all lines - no truncation
73
72
  const displayOutput = useMemo(() => {
74
- const source = searchedOutput;
75
73
  if (isAtBottom) {
76
- return source.slice(-maxLines); // Show last 25 when at bottom
74
+ return searchedOutput; // Show all logs when at bottom
77
75
  }
78
- return source.slice(Math.max(0, source.length - maxLines - scrollOffset), source.length - scrollOffset);
76
+ return searchedOutput.slice(0, searchedOutput.length - scrollOffset);
79
77
  }, [searchedOutput, scrollOffset, isAtBottom]);
80
- const canScrollUp = searchedOutput.length > maxLines &&
81
- scrollOffset < searchedOutput.length - maxLines;
78
+ const canScrollUp = scrollOffset < searchedOutput.length - 1;
82
79
  const canScrollDown = scrollOffset > 0;
83
80
  const statusColor = status === "running"
84
81
  ? "green"
@@ -87,5 +84,5 @@ export function ProcessPane({ title, output, port, status, onClear, }) {
87
84
  : status === "starting"
88
85
  ? "yellow"
89
86
  : "gray";
90
- return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsxs(Box, { borderStyle: "single", paddingX: 1, marginBottom: 1, flexShrink: 0, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: title }), port && _jsxs(Text, { color: "gray", children: [" - http://localhost:", port] }), _jsx(Text, { children: " " }), _jsx(Text, { color: statusColor, children: "\u25CF" }), _jsxs(Text, { children: [" ", status] }), searchQuery && _jsxs(Text, { color: "cyan", children: [" [SEARCH: ", searchQuery, "]"] }), !isAtBottom && _jsx(Text, { color: "yellow", children: " [SCROLLED]" })] }), _jsx(Text, { color: "gray", children: "(/)search | \u2191\u2193 | (c)lear | ESC" })] }), searchMode && (_jsxs(Box, { borderStyle: "single", borderBottom: true, borderColor: "cyan", paddingX: 1, marginBottom: 1, flexShrink: 0, children: [_jsx(Text, { color: "cyan", children: "Search: " }), _jsx(TextInput, { value: searchQuery, onChange: setSearchQuery, placeholder: "Type to search..." }), _jsx(Text, { dimColor: true, children: " (ESC to exit)" })] })), _jsx(Box, { flexDirection: "column", flexGrow: 1, minHeight: 0, paddingX: 1, children: displayOutput.length === 0 ? (_jsx(Text, { color: "gray", children: "Waiting for output..." })) : (displayOutput.map((line, idx) => (_jsx(Text, { children: line }, `${idx}-${line.slice(0, 20)}`)))) }), _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexShrink: 0, justifyContent: "space-between", children: [_jsxs(Text, { color: "gray", children: ["Showing ", displayOutput.length, " of ", searchedOutput.length, " lines", searchQuery && ` (${searchedOutput.length} matches)`, scrollOffset > 0 && ` (${scrollOffset} from bottom)`] }), searchedOutput.length > maxLines && (_jsxs(Text, { color: "gray", children: [canScrollUp && "↑ ", canScrollDown && "↓"] }))] })] }));
87
+ return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsxs(Box, { borderStyle: "single", paddingX: 1, marginBottom: 1, flexShrink: 0, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: title }), port && _jsxs(Text, { color: "gray", children: [" - http://localhost:", port] }), _jsx(Text, { children: " " }), _jsx(Text, { color: statusColor, children: "\u25CF" }), _jsxs(Text, { children: [" ", status] }), searchQuery && _jsxs(Text, { color: "cyan", children: [" [SEARCH: ", searchQuery, "]"] }), !isAtBottom && _jsx(Text, { color: "yellow", children: " [SCROLLED]" })] }), _jsx(Text, { color: "gray", children: "(/)search | \u2191\u2193 | (c)lear | ESC" })] }), searchMode && (_jsxs(Box, { borderStyle: "single", borderBottom: true, borderColor: "cyan", paddingX: 1, marginBottom: 1, flexShrink: 0, children: [_jsx(Text, { color: "cyan", children: "Search: " }), _jsx(TextInput, { value: searchQuery, onChange: setSearchQuery, placeholder: "Type to search..." }), _jsx(Text, { dimColor: true, children: " (ESC to exit)" })] })), _jsx(Box, { flexDirection: "column", flexGrow: 1, minHeight: 0, paddingX: 1, children: displayOutput.length === 0 ? (_jsx(Text, { color: "gray", children: "Waiting for output..." })) : (displayOutput.map((line, idx) => (_jsx(Text, { children: line }, `${idx}-${line.slice(0, 20)}`)))) }), _jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, flexShrink: 0, justifyContent: "space-between", children: [_jsxs(Text, { color: "gray", children: ["Showing ", displayOutput.length, " of ", searchedOutput.length, " lines", searchQuery && ` (${searchedOutput.length} matches)`, scrollOffset > 0 && ` (${scrollOffset} from bottom)`] }), (canScrollUp || canScrollDown) && (_jsxs(Text, { color: "gray", children: [canScrollUp && "↑ ", canScrollDown && "↓"] }))] })] }));
91
88
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@townco/cli",
3
- "version": "0.1.33",
3
+ "version": "0.1.35",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "town": "./dist/index.js"
@@ -15,17 +15,17 @@
15
15
  "build": "tsc"
16
16
  },
17
17
  "devDependencies": {
18
- "@townco/tsconfig": "0.1.25",
18
+ "@townco/tsconfig": "0.1.27",
19
19
  "@types/bun": "^1.3.1",
20
20
  "@types/react": "^19.2.2"
21
21
  },
22
22
  "dependencies": {
23
23
  "@optique/core": "^0.6.2",
24
24
  "@optique/run": "^0.6.2",
25
- "@townco/agent": "0.1.33",
26
- "@townco/core": "0.0.6",
27
- "@townco/secret": "0.1.28",
28
- "@townco/ui": "0.1.28",
25
+ "@townco/agent": "0.1.35",
26
+ "@townco/core": "0.0.8",
27
+ "@townco/secret": "0.1.30",
28
+ "@townco/ui": "0.1.30",
29
29
  "@types/inquirer": "^9.0.9",
30
30
  "ink": "^6.4.0",
31
31
  "ink-text-input": "^6.0.0",