claude-ps 0.2.1 → 0.2.2

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 (2) hide show
  1. package/dist/index.js +117 -107
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -15,10 +15,6 @@ import { Box as Box7, Text as Text7, useApp, useInput, useStdout } from "ink";
15
15
  import { Box, Text } from "ink";
16
16
 
17
17
  // src/constants/theme.ts
18
- var USAGE_THRESHOLD = {
19
- LOW: 30,
20
- HIGH: 70
21
- };
22
18
  var COLORS = {
23
19
  /** 使用率颜色 */
24
20
  usage: {
@@ -47,11 +43,6 @@ var COLUMN_WIDTH = {
47
43
  elapsed: 9
48
44
  };
49
45
  var ESTIMATED_TOTAL_MEMORY_MB = 16 * 1024;
50
- function getUsageColor(percent) {
51
- if (percent < USAGE_THRESHOLD.LOW) return COLORS.usage.low;
52
- if (percent < USAGE_THRESHOLD.HIGH) return COLORS.usage.medium;
53
- return COLORS.usage.high;
54
- }
55
46
 
56
47
  // src/components/ui/StatusBar.tsx
57
48
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -71,7 +62,7 @@ function calculateStats(processes) {
71
62
  }
72
63
  function StatusBar({ processes }) {
73
64
  const stats = calculateStats(processes);
74
- return /* @__PURE__ */ jsxs(Box, { paddingX: 1, children: [
65
+ return /* @__PURE__ */ jsxs(Box, { height: 2, children: [
75
66
  /* @__PURE__ */ jsx(Text, { color: COLORS.label, children: "\u8FDB\u7A0B: " }),
76
67
  /* @__PURE__ */ jsx(Text, { color: COLORS.value, children: stats.count }),
77
68
  /* @__PURE__ */ jsx(Text, { color: COLORS.label, children: " | CPU: " }),
@@ -199,16 +190,6 @@ function formatElapsed(elapsed) {
199
190
  }
200
191
  return elapsed;
201
192
  }
202
- function shortenPath(inputPath, maxLen = 25) {
203
- let path = inputPath;
204
- const home = process.env.HOME || "";
205
- if (home && path.startsWith(home)) {
206
- path = `~${path.slice(home.length)}`;
207
- }
208
- if (path.length <= maxLen) return path;
209
- const half = Math.floor((maxLen - 3) / 2);
210
- return `${path.slice(0, half)}...${path.slice(-half)}`;
211
- }
212
193
 
213
194
  // src/components/ui/DetailPanel.tsx
214
195
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -216,29 +197,25 @@ function DetailPanel({ process: proc }) {
216
197
  if (!proc) {
217
198
  return /* @__PURE__ */ jsx4(EmptyPrompt, { message: "\u9009\u62E9\u4E00\u4E2A\u8FDB\u7A0B\u67E5\u770B\u8BE6\u60C5" });
218
199
  }
219
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, children: [
200
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
220
201
  /* @__PURE__ */ jsxs4(Section, { title: "\u8D44\u6E90\u4FE1\u606F", children: [
221
202
  /* @__PURE__ */ jsx4(InfoRow, { label: "CPU", value: `${proc.cpu.toFixed(1)}%` }),
222
203
  /* @__PURE__ */ jsx4(InfoRow, { label: "\u5185\u5B58", value: formatMemory(proc.memory) }),
223
204
  /* @__PURE__ */ jsx4(InfoRow, { label: "\u65F6\u957F", value: formatElapsed(proc.elapsed) })
224
205
  ] }),
225
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
206
+ /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingBottom: 1, children: [
226
207
  /* @__PURE__ */ jsx4(Text4, { children: " " }),
227
208
  /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: "Session:" }),
228
209
  /* @__PURE__ */ jsx4(Text4, { color: COLORS.label, wrap: "truncate", children: proc.sessionPath || "\u65E0\u4F1A\u8BDD\u6587\u4EF6" })
229
210
  ] }),
230
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
231
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: "\u2500 \u6700\u8FD1\u5BF9\u8BDD \u2500" }),
232
- proc.messages.length === 0 ? /* @__PURE__ */ jsx4(Text4, { color: COLORS.label, children: "\u65E0\u5BF9\u8BDD\u8BB0\u5F55" }) : proc.messages.map((msg) => /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
233
- /* @__PURE__ */ jsxs4(Text4, { color: msg.role === "user" ? COLORS.current : "blue", children: [
234
- "[",
235
- msg.role === "user" ? "User" : "Claude",
236
- "]",
237
- " "
238
- ] }),
239
- /* @__PURE__ */ jsx4(Text4, { wrap: "truncate", children: msg.content })
240
- ] }, msg.timestamp))
241
- ] })
211
+ /* @__PURE__ */ jsx4(Box4, { paddingBottom: 1, children: /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: "\u6700\u8FD1\u5BF9\u8BDD" }) }),
212
+ /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: proc.messages.length === 0 ? /* @__PURE__ */ jsx4(Text4, { color: COLORS.label, children: "\u65E0\u5BF9\u8BDD\u8BB0\u5F55" }) : proc.messages.map((msg) => /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
213
+ /* @__PURE__ */ jsxs4(Text4, { color: msg.role === "user" ? COLORS.current : "blue", children: [
214
+ msg.role === "user" ? "[User]" : "[Claude]",
215
+ " "
216
+ ] }),
217
+ /* @__PURE__ */ jsx4(Text4, { wrap: "truncate", children: msg.content })
218
+ ] }, msg.timestamp)) })
242
219
  ] });
243
220
  }
244
221
 
@@ -246,52 +223,58 @@ function DetailPanel({ process: proc }) {
246
223
  import { Box as Box6, Text as Text6 } from "ink";
247
224
 
248
225
  // src/components/ui/ProcessItem.tsx
249
- import { Box as Box5, Text as Text5 } from "ink";
250
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
226
+ import { Text as Text5 } from "ink";
227
+ import { jsx as jsx5 } from "react/jsx-runtime";
251
228
  var PADDING_X = 1;
229
+ var BG_CODES = {
230
+ reset: "\x1B[49m",
231
+ blue: "\x1B[48;5;24m",
232
+ // 深蓝背景
233
+ gray: "\x1B[48;5;240m"
234
+ // 深灰背景
235
+ };
236
+ function withBgColor(text, bgColor) {
237
+ return `${BG_CODES[bgColor]}${text}${BG_CODES.reset}`;
238
+ }
252
239
  function ProcessItem({ process: process2, isSelected }) {
253
240
  let cwdColor = void 0;
254
241
  if (process2.isOrphan) cwdColor = "red";
255
242
  else if (process2.isCurrent) cwdColor = "green";
256
- const pidText = String(process2.pid).padStart(COLUMN_WIDTH.pid - 1);
257
- const cpuText = `${process2.cpu.toFixed(1)}%`.padStart(COLUMN_WIDTH.cpu - 1);
258
- const memText = `${process2.memory.toFixed(1)}%`.padStart(COLUMN_WIDTH.memory - 1);
259
- const elapsedText = formatElapsed(process2.elapsed).padEnd(COLUMN_WIDTH.elapsed);
260
- const cwdText = shortenPath(process2.cwd, 30) + (process2.isCurrent ? " \u25CF" : "");
261
- return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsxs5(
243
+ const pidText = String(process2.pid).padEnd(COLUMN_WIDTH.pid);
244
+ const cpuText = `${process2.cpu.toFixed(1)}%`.padEnd(COLUMN_WIDTH.cpu);
245
+ const memText = `${process2.memory.toFixed(1)}%`.padEnd(COLUMN_WIDTH.memory);
246
+ const elapsedText = formatElapsed(process2.elapsed).padEnd(
247
+ COLUMN_WIDTH.elapsed
248
+ );
249
+ const cwdText = process2.cwd;
250
+ const rowText = pidText + cpuText + memText + elapsedText + cwdText + " ".repeat(PADDING_X);
251
+ const displayText = isSelected ? withBgColor(rowText, "blue") : rowText;
252
+ return /* @__PURE__ */ jsx5(
262
253
  Text5,
263
254
  {
264
- inverse: isSelected,
265
255
  color: isSelected ? void 0 : cwdColor,
266
256
  dimColor: !isSelected && cwdColor === void 0,
267
- children: [
268
- " ".repeat(PADDING_X),
269
- pidText,
270
- /* @__PURE__ */ jsx5(Text5, { color: getUsageColor(process2.cpu), inverse: isSelected, children: cpuText }),
271
- /* @__PURE__ */ jsx5(Text5, { color: getUsageColor(process2.memory), inverse: isSelected, children: memText }),
272
- /* @__PURE__ */ jsx5(Text5, { inverse: isSelected, color: isSelected ? void 0 : "gray", children: elapsedText }),
273
- /* @__PURE__ */ jsx5(Text5, { color: cwdColor, inverse: isSelected, children: cwdText }),
274
- " ".repeat(PADDING_X)
275
- ]
257
+ children: displayText
276
258
  }
277
- ) });
259
+ );
278
260
  }
279
261
 
280
262
  // src/components/ProcessList.tsx
281
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
263
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
282
264
  function TableHeader() {
283
- return /* @__PURE__ */ jsxs6(Box6, { paddingX: 1, children: [
284
- /* @__PURE__ */ jsx6(Box6, { width: COLUMN_WIDTH.pid, children: /* @__PURE__ */ jsx6(Text6, { bold: true, color: COLORS.title, children: "PID" }) }),
285
- /* @__PURE__ */ jsx6(Box6, { width: COLUMN_WIDTH.cpu, children: /* @__PURE__ */ jsx6(Text6, { bold: true, color: COLORS.title, children: "CPU" }) }),
286
- /* @__PURE__ */ jsx6(Box6, { width: COLUMN_WIDTH.memory, children: /* @__PURE__ */ jsx6(Text6, { bold: true, color: COLORS.title, children: "MEM" }) }),
287
- /* @__PURE__ */ jsx6(Box6, { width: COLUMN_WIDTH.elapsed, children: /* @__PURE__ */ jsx6(Text6, { bold: true, color: COLORS.title, children: "\u65F6\u957F" }) }),
288
- /* @__PURE__ */ jsx6(Text6, { bold: true, color: COLORS.title, children: "\u5DE5\u4F5C\u76EE\u5F55" })
265
+ return /* @__PURE__ */ jsxs5(Text6, { bold: true, color: COLORS.title, children: [
266
+ "PID".padEnd(COLUMN_WIDTH.pid),
267
+ "CPU".padEnd(COLUMN_WIDTH.cpu),
268
+ "MEM".padEnd(COLUMN_WIDTH.memory),
269
+ "\u65F6\u957F".padEnd(COLUMN_WIDTH.elapsed),
270
+ "\u5DE5\u4F5C\u76EE\u5F55"
289
271
  ] });
290
272
  }
291
273
  function ProcessList({
292
274
  processes,
293
275
  selectedIndex,
294
- loading
276
+ loading,
277
+ leftWidth
295
278
  }) {
296
279
  if (loading) {
297
280
  return /* @__PURE__ */ jsx6(LoadingState, { message: "\u52A0\u8F7D\u4E2D..." });
@@ -299,9 +282,9 @@ function ProcessList({
299
282
  if (processes.length === 0) {
300
283
  return /* @__PURE__ */ jsx6(EmptyPrompt, { message: "\u65E0\u8FD0\u884C\u4E2D\u7684 Claude \u8FDB\u7A0B" });
301
284
  }
302
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
285
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
303
286
  /* @__PURE__ */ jsx6(TableHeader, {}),
304
- /* @__PURE__ */ jsx6(Separator, { char: "\u2500", length: 60 }),
287
+ /* @__PURE__ */ jsx6(Separator, { char: "\u2500", length: leftWidth - 12 }),
305
288
  processes.map((proc, index) => /* @__PURE__ */ jsx6(
306
289
  ProcessItem,
307
290
  {
@@ -526,7 +509,7 @@ function useProcesses(interval2) {
526
509
  }
527
510
 
528
511
  // src/App.tsx
529
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
512
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
530
513
  function App({ interval: interval2 }) {
531
514
  const { exit } = useApp();
532
515
  const { stdout } = useStdout();
@@ -564,57 +547,74 @@ function App({ interval: interval2 }) {
564
547
  });
565
548
  const leftWidth = Math.floor(termWidth * 0.45);
566
549
  const rightWidth = termWidth - leftWidth - 1;
567
- const contentHeight = termHeight - 10;
550
+ const contentHeight = termHeight - 4;
568
551
  if (error) {
569
- return /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", width: termWidth, height: termHeight, children: /* @__PURE__ */ jsxs7(Text7, { color: COLORS.orphan, children: [
552
+ return /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", width: termWidth, height: termHeight, children: /* @__PURE__ */ jsxs6(Text7, { color: COLORS.orphan, children: [
570
553
  "\u9519\u8BEF: ",
571
554
  error
572
555
  ] }) });
573
556
  }
574
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", width: termWidth, height: termHeight, children: [
575
- /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 2, children: [
576
- /* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: `
577
- _ _ _ _
578
- | | | | | | |
579
- __| | ___ ___| | | __| |
580
- / _\` |/ _ / __| | |/ _\` |
581
- | (_| | (_) \\__ \\_ (_| |
582
- \\__,_|\\___/|___/ |_|\\__,_|
583
- ` }),
584
- /* @__PURE__ */ jsx7(Text7, { color: "gray", children: "Claude Code \u8FDB\u7A0B\u7BA1\u7406\u5668" })
585
- ] }),
586
- /* @__PURE__ */ jsx7(StatusBar, { processes }),
587
- /* @__PURE__ */ jsxs7(Box7, { height: contentHeight, children: [
588
- /* @__PURE__ */ jsx7(Box7, { width: leftWidth, flexDirection: "column", height: contentHeight, children: /* @__PURE__ */ jsx7(
589
- ProcessList,
590
- {
591
- processes,
592
- selectedIndex,
593
- loading
594
- }
595
- ) }),
596
- /* @__PURE__ */ jsx7(Box7, { width: 1, flexDirection: "column", height: contentHeight, children: /* @__PURE__ */ jsx7(Text7, { color: COLORS.label, children: "\u2502\n".repeat(contentHeight).trim() }) }),
597
- /* @__PURE__ */ jsx7(Box7, { width: rightWidth, flexDirection: "column", height: contentHeight, children: /* @__PURE__ */ jsx7(DetailPanel, { process: selectedProcess }) })
598
- ] }),
599
- /* @__PURE__ */ jsx7(
600
- Box7,
601
- {
602
- borderStyle: "single",
603
- borderTop: true,
604
- borderBottom: false,
605
- borderLeft: false,
606
- borderRight: false,
607
- children: /* @__PURE__ */ jsx7(
608
- HelpBar,
557
+ return /* @__PURE__ */ jsxs6(
558
+ Box7,
559
+ {
560
+ flexDirection: "column",
561
+ width: termWidth,
562
+ height: termHeight,
563
+ paddingX: 4,
564
+ children: [
565
+ /* @__PURE__ */ jsxs6(Box7, { height: contentHeight, children: [
566
+ /* @__PURE__ */ jsxs6(Box7, { width: leftWidth, flexDirection: "column", height: contentHeight, children: [
567
+ /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", children: /* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: `
568
+ \u250F\u2501\u2578\u257B \u250F\u2501\u2513\u257B \u257B\u257A\u2533\u2513\u250F\u2501\u2578 \u250F\u2501\u2513\u250F\u2501\u2513
569
+ \u2503 \u2503 \u2523\u2501\u252B\u2503 \u2503 \u2503\u2503\u2523\u2578 \u257A\u2501\u2578\u2523\u2501\u251B\u2517\u2501\u2513
570
+ \u2517\u2501\u2578\u2517\u2501\u2578\u2579 \u2579\u2517\u2501\u251B\u257A\u253B\u251B\u2517\u2501\u2578 \u2579 \u2517\u2501\u251B
571
+ ` }) }),
572
+ /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", height: 2, children: /* @__PURE__ */ jsx7(Text7, { color: "gray", children: "Claude Code \u8FDB\u7A0B\u7BA1\u7406\u5668" }) }),
573
+ /* @__PURE__ */ jsx7(StatusBar, { processes }),
574
+ /* @__PURE__ */ jsx7(
575
+ ProcessList,
576
+ {
577
+ leftWidth,
578
+ processes,
579
+ selectedIndex,
580
+ loading
581
+ }
582
+ )
583
+ ] }),
584
+ /* @__PURE__ */ jsx7(Box7, { width: 1, flexDirection: "column", height: contentHeight, children: /* @__PURE__ */ jsx7(Text7, { color: COLORS.label, children: "\u2502\n".repeat(contentHeight).trim() }) }),
585
+ /* @__PURE__ */ jsx7(
586
+ Box7,
587
+ {
588
+ width: rightWidth,
589
+ flexDirection: "column",
590
+ height: contentHeight,
591
+ paddingX: 4,
592
+ paddingY: 2,
593
+ children: /* @__PURE__ */ jsx7(DetailPanel, { process: selectedProcess })
594
+ }
595
+ )
596
+ ] }),
597
+ /* @__PURE__ */ jsx7(
598
+ Box7,
609
599
  {
610
- processCount: processes.length,
611
- interval: interval2,
612
- sortField
600
+ borderStyle: "single",
601
+ borderTop: true,
602
+ borderBottom: false,
603
+ borderLeft: false,
604
+ borderRight: false,
605
+ children: /* @__PURE__ */ jsx7(
606
+ HelpBar,
607
+ {
608
+ processCount: processes.length,
609
+ interval: interval2,
610
+ sortField
611
+ }
612
+ )
613
613
  }
614
614
  )
615
- }
616
- )
617
- ] });
615
+ ]
616
+ }
617
+ );
618
618
  }
619
619
 
620
620
  // src/index.tsx
@@ -640,6 +640,11 @@ var cli = meow(
640
640
  {
641
641
  importMeta: import.meta,
642
642
  flags: {
643
+ help: {
644
+ type: "boolean",
645
+ shortFlag: "h",
646
+ default: false
647
+ },
643
648
  list: {
644
649
  type: "boolean",
645
650
  shortFlag: "l",
@@ -654,6 +659,11 @@ var cli = meow(
654
659
  type: "number",
655
660
  shortFlag: "i",
656
661
  default: 2
662
+ },
663
+ version: {
664
+ type: "boolean",
665
+ shortFlag: "v",
666
+ default: false
657
667
  }
658
668
  }
659
669
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-ps",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "TUI application for viewing and managing Claude Code processes",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",