{"id":28029171,"url":"https://github.com/rasjonell/dashbrew","last_synced_at":"2025-05-11T08:02:00.727Z","repository":{"id":289123545,"uuid":"970198485","full_name":"rasjonell/dashbrew","owner":"rasjonell","description":"TUI dashboard builder that lets you visualize data from scripts and APIs right in your console","archived":false,"fork":false,"pushed_at":"2025-05-03T04:31:40.000Z","size":2712,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-03T05:26:14.468Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://rasjonell.github.io/dashbrew/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rasjonell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-21T16:28:40.000Z","updated_at":"2025-05-03T04:31:44.000Z","dependencies_parsed_at":"2025-04-21T17:49:08.680Z","dependency_job_id":null,"html_url":"https://github.com/rasjonell/dashbrew","commit_stats":null,"previous_names":["rasjonell/dashbrew"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasjonell%2Fdashbrew","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasjonell%2Fdashbrew/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasjonell%2Fdashbrew/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasjonell%2Fdashbrew/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rasjonell","download_url":"https://codeload.github.com/rasjonell/dashbrew/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253534795,"owners_count":21923544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-11T08:01:07.661Z","updated_at":"2025-05-11T08:02:00.671Z","avatar_url":"https://github.com/rasjonell.png","language":"Go","funding_links":[],"categories":["Table of Contents","\u003ca name=\"viewers\"\u003e\u003c/a\u003eViewers"],"sub_categories":[],"readme":"```\n       /$$                     /$$       /$$                                        \n      | $$                    | $$      | $$                                        \n  /$$$$$$$  /$$$$$$   /$$$$$$$| $$$$$$$ | $$$$$$$   /$$$$$$   /$$$$$$  /$$  /$$  /$$\n /$$__  $$ |____  $$ /$$_____/| $$__  $$| $$__  $$ /$$__  $$ /$$__  $$| $$ | $$ | $$\n| $$  | $$  /$$$$$$$|  $$$$$$ | $$  \\ $$| $$  \\ $$| $$  \\__/| $$$$$$$$| $$ | $$ | $$\n| $$  | $$ /$$__  $$ \\____  $$| $$  | $$| $$  | $$| $$      | $$_____/| $$ | $$ | $$\n|  $$$$$$$|  $$$$$$$ /$$$$$$$/| $$  | $$| $$$$$$$/| $$      |  $$$$$$$|  $$$$$/$$$$/\n \\_______/ \\_______/|_______/ |__/  |__/|_______/ |__/       \\_______/ \\_____/\\___/ \n```\n\n**Dashbrew** is a terminal dashboard builder that lets you visualize data from scripts and APIs right in your console, using a simple JSON configuration. Stay informed without leaving your terminal!\n\n![screenshot](./screen.gif)\n\n---\n\n## ✨ Features\n\n* **Configurable Layout:** Define complex dashboard layouts (rows, columns, flexible sizing)\n* **Multiple Data Sources:**\n    * `script`: Execute local shell commands/scripts and display their output.\n    * `api`: Fetch data from HTTP APIs and display the response body.\n    * `todo`: For ToDo lists, read and write a custom todo list text file.\n* **Component Types**\n    * _Text_: Scrollable, auto-wrapped text output.\n    * _List_: Display a list of items from scripts or APIs.\n    * _Todo_: Interactive todo list with add/remove and toggle done state support.\n    * _Chart_: Display simple ASCII line charts from numerical data.\n    * _Table_: Display data in a structured table with columns defined in the configuration.\n* **Terminal UI:** Built with the delightful [Bubble Tea](https://github.com/charmbracelet/bubbletea) framework.\n* **Navigation:** Easily move focus between components using arrow keys, `hjkl`, or your mouse.\n* **Auto-Refresh:** Configure components to automatically refresh their data at specified intervals.\n* **Mouse Support:** Click to focus, scroll with the wheel.\n\n---\n\n## 🚀 Installation \u0026 Usage\n\n_(Ensure you have Go installed)_\n\n1. Install:\n\n```bash\ngo install github.com/rasjonell/dashbrew/cmd/dashbrew@latest\n```\n\n2. Create your dashboard configuration file (e.g., `my_dashboard.json`). See the Configuration section below and the example [dashboard.json](./dashboard.json).\n\n3. Run:\n\n```bash\ndashbrew -c my_dashboard.json\n```\n\n## ⚙️ Configuration (`dashboard.json`)\n\nDashbrew uses a `json` file in to define the layout and components. Find an example [here](./dashboard.json)\n\n**Structure:**\n\n```jsonc\n{\n  \"style\": {\n    \"borderType\": \"rounded\",\n    \"borderColor\": \"#ffffff\",\n    \"focusedBorderColor\": \"#00ff00\"\n  },\n  \"layout\": {\n    \"type\": \"container\", // \"container\" or \"component\"\n    \"direction\": \"row\",  // \"row\" or \"column\" (for containers)\n    \"flex\": 1,           // Optional: Relative size factor (default: 1)\n    \"children\": [ ], // Array of child layout nodes (for containers)\n    \"component\": { } // Component definition (for components)\n  }\n}\n```\n\n### Style Configuration:\n\n*All of the style configuration is optional, defaults will be used when not provided.*\n\n- `borderType`: `\"rounded\"` | `\"thicc\"` | `\"double\"` | `\"hidden\"` | `\"normal\"` | `\"md\"` | `\"ascii\"` | `\"block\"`\n- `borderColor`: any valid hex color (`#ffffff`, `#696969`)\n- `focusedBorderColor`: any valid hex color (`#00ff00`, `#694200`)\n\n### Layout Nodes:\n\n- `type`: Can be \"container\" or \"component\".\n- `direction`: (Only for container) How children are arranged (\"row\" or \"column\").\n- `flex`: (Optional) An integer determining how space is distributed among siblings. A component with flex: 2 will try to be twice as large (in the container's direction) as a sibling with flex: 1. Defaults to 1.\n- `children`: (Only for container) An array of nested layout nodes.\n- `component`: (Only for component) Defines the actual widget to display.\n\n### Component Definition:\n\n**Example Structure:**\n```jsonc\n{\n  \"id\": \"unique-component-id\", // Optional: Explicit ID\n  \"type\": \"text\",              // \"text\", \"list\", \"todo\", \"chart\", or \"table\"\n  \"title\": \"My Component Title\", // Optional: Title shown in header\n  \"data\": {\n    \"source\": \"script\", // \"script\", \"api\", \"file\", or path for \"todo\" type\n    \"command\": \"date +%Y-%m-%d\", // Required if source is \"script\"\n    \"url\": \"https://api.example.com/status\", // Required if source is \"api\"\n    \"path\": \"./my_data.txt\", // Required if source is \"file\"\n    \"json_path\": \"$.data.value\", // Optional: JSONPath expression for 'api' source\n    \"caption\": \"Chart Caption\", // Optional: Caption for 'chart' type\n    \"refresh_interval\": 5 // Optional: Refresh data every 5 seconds (0 = no auto-refresh)\n  }\n}\n```\n\n- `id`: (Optional) A unique ID. If omitted, an internal ID is generated.\n- `type`: The type of widget. Currently, `text`, `list`, `todo`, and `chart` components are supported.\n- `title`: The title displayed in the component's header.\n- `data`: Defines where the component gets its content.\n    - `source`: \"script\", \"api\", or todo list file path for components with type `todo` (example bellow).\n    - `command`: (Required if `source` is `\"script\"`) The command to execute.\n    - `url`: (Required if `source` is `\"api\"`) The URL to fetch via HTTP GET.\n    - `jsonPath` (Optional, for `\"api\"` source) a [JSONPath](https://github.com/oliveagle/jsonpath#example-json-path-syntax) expression to filter or extract data from API's JSON response\n    - `caption`: (Optional, for `\"chart\"` type) A caption displayed bellow the chart\n    - `refresh_interval`: (Optional) Time in seconds between data refreshes.\n    - `refresh_mode`: (Optional, for `\"chart\"` type) Either `\"append\"` or `\"replace\"` current ascii plot data\n    - `columns`: (Optional, for `\"table\"` type) Array of `{\"label\": \"string\", \"field\": \"string\", \"flex\": 1}`\n\n\n### Text Component\n\nDisplays the output of a script or API as scrollable, wrapped text.\n\n```jsonc\n{\n  \"type\": \"component\",\n  \"component\": {\n    \"type\": \"text\",\n    \"title\": \"System Info\",\n    \"data\": {\n      \"source\": \"script\", // \"script\" or \"api\"\n      \"command\": \"uname -a\", // Required if source is \"script\"\n      \"url\": \"https://api.adviceslip.com/advice\", // Fetch a random advice\n      \"json_path\": \"$.slip.advice\", // Get only the advice string\n      \"refresh_interval\": 10 // Optional: seconds between refreshes\n    }\n  }\n}\n```\n\n### List Component\n\nDisplays a list of items, with filtering and selection.\n\n- If `source` is `\"script\"`, each line of output is an item.\n- If `source` is `\"api\"`, the API must return a JSON array of a primitive value (string, number, boolean).\n\n```jsonc\n{\n  \"type\": \"component\",\n  \"component\": {\n    \"type\": \"list\",\n    \"title\": \"Recent Logs\",\n    \"data\": {\n      \"source\": \"script\", // \"script\" or \"api\"\n      \"command\": \"cat /var/log/syslog | tail -n 10\", // For script\n      \"url\": \"https://api.example.com/items\", // For api, must return [\"item1\", \"item2\", ...]\n      \"refresh_interval\": 5 // Optional\n    }\n  }\n}\n```\n\n### Todo Component\n\nDisplays and manages a todo list stored in a local file.\nYou can add, toggle, and delete items interactively.\n\n```jsonc\n{\n  \"type\": \"component\",\n  \"component\": {\n    \"type\": \"todo\",\n    \"title\": \"My Todos\",\n    \"data\": {\n      \"source\": \"./todos.txt\"\n    }\n  }\n}\n```\n\n#### Todo File Format\n\nEach line represents a todo item:\n  - `-` means to do\n  - `+` means done\n\nExample:\n```\n + learn HTMX\n + rise \u0026 grind\n - profit\n```\n\n\n### Chart Component\n\nDisplays a simple ASCII line chart based on numerical data.\n\n```jsonc\n{\n  \"type\": \"component\",\n  \"component\": {\n    \"id\": \"cpu-chart\",\n    \"type\": \"chart\",\n    \"title\": \"CPU Usage (%)\",\n    \"data\": {\n      \"source\": \"script\",\n      \"command\": \"./get_cpu_history.sh\", // Script outputs numbers on newlines\n      \"caption\": \"Last 15 CPU readings\",\n      \"refresh_interval\": 2, // Update every 2 seconds\n      \"refresh_mode\": \"append\" // Append new results to the chart(can be \"replace\")\n    }\n  }\n}\n```\n\n### Table Component\n\nDisplays data in a structured table with columns defined in the configuration.\n\nIt accepts JSON Arrays:\n\nEither an array of objects with the given fields:\n```jsonc\n{\n  \"type\": \"component\",\n  \"component\": {\n    \"id\": \"data-table\",\n    \"type\": \"table\",\n    \"title\": \"My Data Table\",\n    \"data\": {\n      \"source\": \"api\",\n      \"url\": \"https://api.example.com/structured_data\", // API returns [{\"id\":.., \"title\":.., \"status_code\":..}, ...]\n      \"refresh_interval\": 30,\n      \"columns\": [\n        { \"label\": \"Identifier\", \"field\": \"id\", \"flex\": 1 },\n        { \"label\": \"Row Title\", \"field\": \"title\", \"flex\": 4 },\n        { \"label\": \"Status Code\", \"field\": \"status_code\" } // Uses default flex: 1\n      ],\n    }\n  }\n}\n```\n\nOr an array of primitive value arrays(e.g. `[[\"string\", 1], [true, 2.3]]`)\n\n```jsonc\n{\n  \"type\": \"component\",\n  \"component\": {\n    \"id\": \"array-data-table\",\n    \"type\": \"table\",\n    \"title\": \"Array Data Table\",\n    \"columns\": [\n      { \"label\": \"Rank\" }, // Uses default flex: 1\n      { \"label\": \"Name\", \"flex\": 3 }\n    ],\n    \"data\": {\n      \"source\": \"script\",\n      \"command\": \"./get_array_data.sh\" // Script returns [[1, \"First\"], [2, \"Second\"]]\n    }\n  }\n}\n\n```\n\n## ⌨️ Keybindings\n\n- Navigation:\n    - `shift + ↑` / `shifht + K` - Move Up\n    - `shift + ↓` / `shift + J` - Move Down\n    - `shift + ←` / `shift + H` - Move Left\n    - `shift + →` / `shift + L` - Move Right\n    - `Left Click` - Focus Component Under Cursor\n- Focused Componet Actions:\n  - Every Component:\n    - `r` - Refresh Data Source\n  - Scrolalble Components (Text, List, Table):\n    - Mouse Wheel - Scroll\n    - `h` / `↑` / `PgUp` / `b` / `u` - Scroll up.\n    - `j` / `↓` / `PgDown` / `Space` / `d` - Scroll down. \n    - `g` - Go to the top\n    - `G` - Go to the end\n  - Lists (Todo and regular)\n    - `/` - Filter the list (type, then `Enter` to apply, `Esc` to cancel)\n  - Todo List:\n    - `a` - Add a new todo item (type, then `Enter` to save, `Esc` to cancel)\n    - `Space` - Toggle done/undone for selected item\n    - `d` / `Delete` / `Backspace` - Delete selected item\n- Quit: `Ctrl+C`\n\n### 💡 Future Ideas\n\n- More advanced chart types (bar, guage) and customizations\n- More data sources\n- More sophisticated data parsing/transformation options beyond JSONPath.\n- Customizable themes/colors beyond border colors.\n- Component-specific styling options.\n- Table component.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasjonell%2Fdashbrew","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frasjonell%2Fdashbrew","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasjonell%2Fdashbrew/lists"}