{"id":35835352,"url":"https://github.com/Asthestarsfalll/piri","last_synced_at":"2026-01-14T06:00:41.779Z","repository":{"id":331262076,"uuid":"1125215891","full_name":"Asthestarsfalll/piri","owner":"Asthestarsfalll","description":"🚀 Piri is a high-performance Niri extension tool built with Rust. It leverages efficient Niri IPC interaction and a unified event distribution mechanism to provide a robust, state-driven plugin system.","archived":false,"fork":false,"pushed_at":"2026-01-03T11:02:27.000Z","size":30422,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-05T04:01:15.175Z","etag":null,"topics":["desktop","extension","multiscreen","niri","niri-ipc","plugin","productivity","quality-of-life","scratchpad","scriptable"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Asthestarsfalll.png","metadata":{"files":{"readme":"README.en.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-30T10:38:06.000Z","updated_at":"2026-01-04T12:00:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Asthestarsfalll/piri","commit_stats":null,"previous_names":["asthestarsfalll/piri"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Asthestarsfalll/piri","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asthestarsfalll%2Fpiri","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asthestarsfalll%2Fpiri/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asthestarsfalll%2Fpiri/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asthestarsfalll%2Fpiri/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Asthestarsfalll","download_url":"https://codeload.github.com/Asthestarsfalll/piri/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Asthestarsfalll%2Fpiri/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["desktop","extension","multiscreen","niri","niri-ipc","plugin","productivity","quality-of-life","scratchpad","scriptable"],"created_at":"2026-01-08T00:00:35.336Z","updated_at":"2026-01-14T06:00:41.761Z","avatar_url":"https://github.com/Asthestarsfalll.png","language":"Rust","funding_links":[],"categories":["Tools"],"sub_categories":["Toolkits"],"readme":"# Piri\n\n**English** | [中文](README.md)\n\n---\n\nPiri is a high-performance [Niri](https://github.com/YaLTeR/niri) extension tool built with Rust. It leverages efficient Niri IPC interaction and a unified event distribution mechanism to provide a robust, state-driven plugin system.\n\n## Core Plugins\n\n- 📦 **Scratchpads**: Intelligent hide/show windows. Supports auto-capturing existing windows or launching on-demand, following you seamlessly across workspaces and monitors (see [Scratchpads Docs](docs/en/plugins/scratchpads.md))\n- 🔌 **Empty**: Automation for empty workspaces. Automatically triggers preset commands when switching to an empty workspace to get you into the flow faster (see [Empty Docs](docs/en/plugins/empty.md))\n- 🎯 **Window Rule**: Powerful rule engine. Automatically places windows based on regex matching and provides focus-triggered command execution with a built-in de-duplication mechanism (see [Window Rule Docs](docs/en/plugins/window_rule.md))\n- 🔄 **Autofill**: Layout auto-alignment. Automatically aligns remaining windows when a window is closed or layout changes, keeping your interface clean (see [Autofill Docs](docs/en/plugins/autofill.md))\n- 🔒 **Singleton**: Single-instance assurance. Ensures specific applications remain globally unique, supporting quick focus or automatic process launching (see [Singleton Docs](docs/en/plugins/singleton.md))\n- 📋 **Window Order**: Intelligent reordering. Automatically reorders tiled windows based on configured weights, preserving relative positions for identical weights to minimize movement (see [Window Order Docs](docs/en/plugins/window_order.md))\n\n\n## Quick Start\n\n### Installation\n\n#### Using Install Script (Recommended)\n\nThe easiest way is to use the provided install script:\n\n```bash\n# Run the install script\n./install.sh\n```\n\nThe install script will automatically:\n- Build the release version\n- Install to `~/.local/bin/piri` (regular user) or `/usr/local/bin/piri` (root)\n- Copy configuration file to `~/.config/niri/piri.toml`\n\nIf `~/.local/bin` is not in your PATH, the script will prompt you to add it.\n\n#### Using Cargo\n\n```bash\n# Install to user directory (recommended, no root required)\ncargo install --path .\n\n# Or install to system directory (requires root)\nsudo cargo install --path . --root /usr/local\n```\n\nAfter installation, if installed to user directory, make sure `~/.cargo/bin` is in your `PATH`:\n\n```bash\nexport PATH=\"$PATH:$HOME/.cargo/bin\"\n```\n\nYou can add this command to your shell configuration file (e.g., `~/.bashrc` or `~/.zshrc`).\n\n### Configuration\n\nCopy the example configuration file to the config directory:\n\n```bash\nmkdir -p ~/.config/niri\ncp config.example.toml ~/.config/niri/piri.toml\n```\n\nThen edit `~/.config/niri/piri.toml` to configure your features.\n\n## Usage\n\n### Starting the Daemon\n\n#### Manual Start\n\n```bash\n# Start daemon (runs in foreground)\npiri daemon\n```\n\n```bash\n# More debug logs\npiri --debug daemon\n```\n\n#### Auto-start (Recommended)\n\nAdd the following configuration to your niri config file to automatically start piri daemon when niri starts:\n\nEdit `~/.config/niri/config.kdl`, add to the `spawn-at-startup` section:\n\n```kdl\nspawn-at-startup \"bash\" \"-c\" \"/path/to/piri daemon \u003e /dev/null 2\u003e\u00261 \u0026\"\n```\n\n### Shell Completion\n\nGenerate shell completion scripts:\n\n```bash\n# Bash\npiri completion bash \u003e ~/.bash_completion.d/piri\n\n# Zsh\npiri completion zsh \u003e ~/.zsh_completion.d/_piri\n\n# Fish\npiri completion fish \u003e ~/.config/fish/completions/piri.fish\n```\n\n## Plugins\n\n### Scratchpads\n\n![Scratchpads](./assets/scratchpads.mp4)\n\nQuickly show and hide windows of frequently used applications. Supports cross-workspace and cross-monitor, so you can quickly access your scratchpad windows regardless of which workspace or monitor you're on. Features **dynamic window addition**, **automatic retention of manual size and margin adjustments**, and **automatic moving to a specific workspace when hidden**.\n\n**Configuration Example**:\n```toml\n[piri.plugins]\nscratchpads = true\n\n[piri.scratchpad]\ndefault_size = \"40% 60%\"\ndefault_margin = 50\nmove_to_workspace = \"tmp\" # Automatically move to workspace tmp when hidden\n\n[scratchpads.term]\ndirection = \"fromRight\"\ncommand = \"GTK_IM_MODULE=wayland ghostty --class=float.dropterm\"\napp_id = \"float.dropterm\"\nsize = \"40% 60%\"\nmargin = 50\n```\n\n**Quick Usage**:\n```bash\n# Toggle scratchpad show/hide\npiri scratchpads {name} toggle\n\n# Dynamically add current window as scratchpad\npiri scratchpads {name} add {direction}\n```\n\n\u003e **Tip**: Dynamically added windows only use default size and margin during initial registration. After that, you can manually resize or move the window, and the plugin will automatically maintain these adjustments.\n\nFor detailed documentation, please refer to [Scratchpads documentation](docs/en/plugins/scratchpads.md).\n\n### Empty\n\nAutomatically execute commands when switching to empty workspaces, useful for automating workflows.\n\n\u003e **Reference**: This functionality is similar to [Hyprland's `on-created-empty` workspace rule](https://wiki.hypr.land/Configuring/Workspace-Rules/#rules).\n\n**Configuration Example**:\n```toml\n[piri.plugins]\nempty = true\n\n# Execute command when switching to workspace 1 if it's empty\n[empty.1]\ncommand = \"alacritty\"\n\n# Use workspace name\n[empty.main]\ncommand = \"firefox\"\n```\n\n**Workspace Identifiers**: Supports matching by workspace name (e.g., `\"main\"`) or index (e.g., `\"1\"`).\n\nFor detailed documentation, please refer to [Plugin System documentation](docs/en/plugins/empty.md).\n\n### Window Rule\n\nAutomatically move windows to specified workspaces based on their `app_id` or `title` using regular expression matching. This is very useful for automating window management, such as automatically assigning specific applications to specific workspaces.\n\n\u003e **Reference**: This functionality is similar to [Hyprland's window rules](https://wiki.hypr.land/Configuring/Window-Rules/).\n\n**Configuration Example**:\n```toml\n[piri.plugins]\nwindow_rule = true\n\n# Match by app_id\n[[window_rule]]\napp_id = \"ghostty\"\nopen_on_workspace = \"1\"\n\n# Match by title\n[[window_rule]]\ntitle = \".*Chrome.*\"\nopen_on_workspace = \"browser\"\n\n# Specify both app_id and title (either match works)\n[[window_rule]]\napp_id = \"code\"\ntitle = \".*VS Code.*\"\nopen_on_workspace = \"dev\"\n\n# app_id as a list (any one matches)\n[[window_rule]]\napp_id = [\"code\", \"code-oss\", \"codium\"]\nopen_on_workspace = \"dev\"\n\n# title as a list (any one matches)\n[[window_rule]]\ntitle = [\".*Chrome.*\", \".*Chromium.*\", \".*Google Chrome.*\"]\nopen_on_workspace = \"browser\"\n```\n\n**Features**:\n- Regular expression pattern matching support\n- Match by `app_id` or `title`, or both combined (OR logic)\n- Support for lists of patterns: `app_id` and `title` can be lists, any one match triggers the rule\n- Support workspace name or index matching\n- Pure event-driven, real-time response to window creation\n\nFor detailed documentation, please refer to the [Window Rule documentation](docs/en/plugins/window_rule.md).\n\n### Autofill\n\n![Autofill](./assets/autofill.mp4)\n\nAutomatically aligns the last column of windows to the rightmost position when windows are closed or layout changes, maintaining a clean and organized window layout.\n\n**Configuration Example**:\n```toml\n[piri.plugins]\nautofill = true\n```\n\n**Features**:\n- Zero configuration required\n- Pure event-driven, real-time response\n- Workspace-aware, only affects the current workspace\n- Automatically maintains clean window layouts\n\nFor detailed documentation, please refer to the [Autofill documentation](docs/en/plugins/autofill.md).\n\n### Singleton\n\nManages singleton windows - windows that should only have one instance. When you toggle a singleton, if the window already exists, it will focus it; otherwise, it will launch the application. This is useful for applications like browsers, terminals, or other tools where you typically only want one instance running.\n\n**Configuration Example**:\n```toml\n[piri.plugins]\nsingleton = true\n\n[singleton.browser]\ncommand = \"google-chrome-stable\"\n\n[singleton.term]\ncommand = \"GTK_IM_MODULE=wayland ghostty --class=singleton.term\"\napp_id = \"singleton.term\"\n```\n\n**Quick Usage**:\n```bash\n# Toggle singleton (focus if exists, launch if not)\npiri singleton {name} toggle\n```\n\n**Features**:\n- Smart window detection, automatically detects existing windows\n- Automatic App ID extraction, no manual specification needed\n- Window registry for fast lookup of existing windows\n- Automatically focuses existing windows, prevents duplicate instances\n\nFor detailed documentation, please refer to the [Singleton documentation](docs/en/plugins/singleton.md).\n\n### Window Order\n\n![Window Order - Manual Trigger](./assets/window_order.mp4)\n\n![Window Order - Event-Driven Automatic Trigger](./assets/window_order_envent.mp4)\n\nAutomatically reorder windows in workspace based on configured priority weights. Larger weight values position windows further to the left.\n\n**Configuration Example**:\n```toml\n[piri.plugins]\nwindow_order = true\n\n[piri.window_order]\nenable_event_listener = true  # Enable event listening for automatic reordering\ndefault_weight = 0            # Default weight for unconfigured windows\n# workspaces = [\"1\", \"2\", \"dev\"]  # Optional: only apply to specific workspaces (empty = all)\n\n[window_order]\ngoogle-chrome = 100\ncode = 80\nghostty = 70\n```\n\n**Quick Usage**:\n```bash\n# Manually trigger window reordering (works in any workspace)\npiri window_order toggle\n```\n\n**Features**:\n- Intelligent sorting algorithm that minimizes window moves\n- Supports manual trigger and event-driven automatic trigger\n- Supports workspace filtering (only for automatic trigger)\n- Preserves relative order for windows with same weight\n- Supports partial matching of `app_id`\n\nFor detailed documentation, please refer to the [Window Order documentation](docs/en/plugins/window_order.md).\n\n## Documentation\n\n- [Architecture](docs/en/architecture.md) - Project architecture and how it works\n- [Plugin System](docs/en/plugins/plugins.md) - Detailed plugin system documentation\n- [Development Guide](docs/en/development.md) - Development, extension, and contribution guide\n\n## License\n\nMIT License\n\n## References\n\nThis project is inspired by [Pyprland](https://github.com/hyprland-community/pyprland). Pyprland is an excellent project that provides extension capabilities for the Hyprland compositor, offering a plethora of plugins to enhance user experience.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAsthestarsfalll%2Fpiri","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAsthestarsfalll%2Fpiri","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAsthestarsfalll%2Fpiri/lists"}