diff --git a/bun.lock b/bun.lock index da5f1bd..0088dc9 100644 --- a/bun.lock +++ b/bun.lock @@ -6,6 +6,7 @@ "dependencies": { "@kksh/api": "0.1.5", "i18next": "^23.15.1", + "pretty-bytes": "^6.1.1", }, "devDependencies": { "@types/bun": "latest", @@ -442,6 +443,8 @@ "prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="], + "pretty-bytes": ["pretty-bytes@6.1.1", "", {}, "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ=="], + "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], "queue-lit": ["queue-lit@1.5.2", "", {}, "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw=="], diff --git a/package.json b/package.json index 1d4a97a..6678204 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ }, "dependencies": { "@kksh/api": "0.1.5", - "i18next": "^23.15.1" + "i18next": "^23.15.1", + "pretty-bytes": "^6.1.1" }, "devDependencies": { "@types/bun": "latest" diff --git a/src/index.ts b/src/index.ts index efb05fd..5da1b1b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +import prettyBytes from "pretty-bytes"; import { Action, expose, @@ -8,6 +9,7 @@ import { toast, ui, clipboard, + Markdown, } from "@kksh/api/ui/template"; class ExtensionTemplate extends TemplateUiCommand { @@ -15,6 +17,61 @@ class ExtensionTemplate extends TemplateUiCommand { async onFormSubmit(value: Record): Promise { toast.success(`Form submitted: ${JSON.stringify(value)}`); } + + onHighlightedListItemChanged(value: string): Promise { + super.onHighlightedListItemChanged(value); + console.log("Highlighted list item changed:", value); + if (!this.highlightedListItemValue) { + return toast.warning("No process selected"); + } + const { pid, name } = JSON.parse(this.highlightedListItemValue); + const process = this.processes.find((p) => p.pid === pid); + if (!process) { + return toast.warning("Process not found"); + } + ui.render( + new List.List({ + inherits: ["items"], + detail: new List.ItemDetail({ + children: [ + new List.ItemDetailMetadata([ + new List.ItemDetailMetadataLabel({ + title: "Name", + text: name, + }), + new List.ItemDetailMetadataLabel({ + title: "PID", + text: pid.toString(), + }), + new List.ItemDetailMetadataLabel({ + title: "CPU Usage", + text: `${(process.cpu_usage ?? 0).toFixed(2)}%`, + }), + new List.ItemDetailMetadataLabel({ + title: "Memory Usage", + text: prettyBytes(process.memory ?? 0), + }), + new List.ItemDetailMetadataLabel({ + title: "Parent", + text: process.parent?.toString() ?? "Unknown", + }), + new List.ItemDetailMetadataLabel({ + title: "Group", + text: process.group_id?.toString() ?? "Unknown", + }), + ]), + new Markdown(` +- **exe:** ${process.exe} +- **Virtual Memory:** ${prettyBytes(process.virtual_memory ?? 0)} +`), + ], + width: 50, + }), + }) + ); + return Promise.resolve(); + } + async load() { ui.render(new List.List({ items: [] })); sysInfo @@ -22,11 +79,12 @@ class ExtensionTemplate extends TemplateUiCommand { .then(() => sysInfo.processes()) .then((processes) => { this.processes = processes; - processes.sort((a, b) => (b.cpu_usage ?? 0) - (a.cpu_usage ?? 0)); - console.log(processes); + this.processes.sort((a, b) => (b.cpu_usage ?? 0) - (a.cpu_usage ?? 0)); + console.log(this.processes); + ui.setSearchBarPlaceholder("Search by process name or pid"); ui.render( new List.List({ - items: processes.map((p) => { + items: this.processes.map((p) => { // const exe = p.exe ?? "Unknown Executable"; // const trimmedExe = exe.length > 50 ? "..." + exe.slice(-47) : exe; return new List.Item({