summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2026-02-16 13:07:23 +0800
committerlittleblack111 <littleblack11111@gmail.com>2026-02-16 13:07:23 +0800
commit9043b3642b1f6f34bfc32eeb77ccc9553a4a6858 (patch)
tree4aae92e261ccb3d9b0ca6c68305ff7d6ae3c36e4
parent686d7f542d4db6b6ec0d9402d530ea71e9daee63 (diff)
bump: AGENTS
-rw-r--r--AGENTS.md334
1 files changed, 291 insertions, 43 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 2279d40..7b0097f 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,63 +1,311 @@
# AGENTS.md
-# THE ACTUAOL QT CODE IS QUICKSHELL
-- The components that we might need/not have here, in regards or related to integrations with system etc. will need to be fetched from https://quickshell.org/docs/master, sitemap: https://quickshell.org/sitemap-0.xml
-# MAKE SURE TO CHECK FETCH THE DOCS IF QUICKSHELL OR QUICKSHELL.* IS IMPORTED
+This document provides guidelines for agentic coding agents working in this Quickshell/QML codebase.
+
+## Project Overview
+
+This is a Quickshell-based desktop shell configuration written in QML. Quickshell is a Qt-based shell renderer for Wayland/X11.
+
+## Quickshell Documentation
+
+When working with Quickshell-specific APIs (`Quickshell.*` imports), fetch documentation from:
+- Main docs: https://quickshell.org/docs/master
+- Sitemap: https://quickshell.org/sitemap-0.xml
## How to Run and Test
-- To run or test the shell, use:
- ```
- timeout 1 qs
- ```
-- To test components triggered by IPC(if the component have anything to do with component IpcHandler), use
-```
-qs msg <target> <func> <args...>
-```
-for example:
-```
-qs msg reload true
+### Basic Run
+```bash
+timeout 1 qs
```
-or for standalone components:
-```
-qs msg launcher standalone Clip
-```
-where reload is the target and true is the argument, the argument is seperated by space
-most IPCHandlers are located in shell.qml, check that
+The `qs` command may not return on success, so always use a timeout.
-Obviously this is IPC, meaning qs should be running already, so consider something like this:
-```
+### IPC Testing (for components with IpcHandler)
+First, check `shell.qml` for available IpcHandler targets.
+
+```bash
+# Start qs in background, then send IPC message
+timeout 3 qs & sleep 1; qs msg <target> <func> <args...>
+
+# Examples:
timeout 3 qs & sleep 1; qs msg reload true
+timeout 3 qs & sleep 1; qs msg launcher toggle
+timeout 3 qs & sleep 1; qs msg launcher standalone Clip
```
-sleep 1 is to ensure qs is fully initialized and ready to receive messages.
- (The `qs` command may not return if it succeeded, so always use a timeout.)
-- There are no automated tests or linting tools set up.
+The `sleep 1` ensures qs is fully initialized before receiving messages.
+
+### Testing Single Components
+For standalone component testing via IPC:
+```bash
+timeout 3 qs & sleep 1; qs msg launcher standalone <ComponentName>
+```
+Where `<ComponentName>` matches a file in `popups/launcher/components/` (e.g., `Clip`, `Emoji`, `Calc`).
+
+### No Automated Tests or Linting
+There are no automated tests or linting tools configured for this project.
## Code Style Guidelines
-- **Imports:**
- - Do NOT add version numbers to QML import statements (e.g., use `import QtQuick`, not `import QtQuick 2.15`).
- - Place all imports at the top of each QML file.
- - For JavaScript utilities, use: `import "../utils/filename.js" as Name`.
+### Imports
+
+1. **No version numbers** in QML import statements:
+ ```qml
+ // Correct
+ import QtQuick
+ import Quickshell
+
+ // Incorrect
+ import QtQuick 2.15
+ import Quickshell 1.0
+ ```
+
+2. **Order**: Place all imports at the top of each QML file.
+
+3. **Local imports**: Use directory imports or qmldir-based imports:
+ ```qml
+ import "bar"
+ import "popups/launcher/components"
+ import qs.components // via qmldir
+ import qs.config // via qmldir
+ ```
+
+4. **JavaScript utilities**: Use the `as` keyword:
+ ```qml
+ import "../utils/filename.js" as Name
+ ```
+
+### Formatting
+
+1. **Indentation**: Use 4 spaces (no tabs).
+
+2. **Properties and signals**: Place at the top of QML objects, before any other content:
+ ```qml
+ IRect {
+ id: root
+ property bool standalone: false
+ property var state: SelectionState
+ property string name
+
+ signal close
+
+ // Then behaviors, children, etc.
+ }
+ ```
+
+3. **Property declarations**: Always specify types:
+ ```qml
+ property int count: 0
+ property string name: ""
+ property bool active: false
+ property var items: []
+ property color bgColor: Colors.background1
+ property MprisPlayer trackedPlayer: null
+ ```
+
+### Naming Conventions
+
+1. **QML types and components**: UpperCamelCase
+ ```qml
+ Bar {}
+ Launcher {}
+ IText {}
+ SelectionState {}
+ ```
+
+2. **Properties, functions, and variables**: lowerCamelCase
+ ```qml
+ property int selectedIndex: 0
+ property string predictiveCompletion: ""
+
+ function updateTrack() { ... }
+ function setActivePlayer(player: MprisPlayer) { ... }
+ ```
+
+3. **IDs**: lowerCamelCase
+ ```qml
+ id: root
+ id: leftInnerRow
+ id: scaleAnim
+ ```
+
+4. **Private/internal properties**: Prefix with underscore or double underscore:
+ ```qml
+ property bool __reverse: false
+ property var _input: state.input
+ ```
+
+### Pragma Directives
+
+1. **Singletons**: Use `pragma Singleton` for service/config files:
+ ```qml
+ pragma Singleton
+ import Quickshell
+
+ Singleton {
+ readonly property color background1: WallustColors.color8
+ }
+ ```
+
+2. **ComponentBehavior**: Use for type-safe component bindings:
+ ```qml
+ pragma ComponentBehavior: Bound
+ ```
+
+### QML Object Patterns
+
+1. **Base components**: Custom base components are prefixed with `I`:
+ - `IText` - Custom text with animations
+ - `IRect` - Rectangle with color/opacity behaviors
+ - `IWindow` - Window wrapper
+ - `IPopup` - Popup window base
+ - `ISpringAnimation` - Spring animation wrapper
+
+2. **Singleton services**: Located in `services/`, provide global state:
+ ```qml
+ // services/Mpris.qml
+ pragma Singleton
+ Singleton {
+ property MprisPlayer activePlayer: ...
+ signal trackChanged(reverse: bool)
+ }
+ ```
+
+3. **Config singletons**: Located in `config/`, provide theme/configuration:
+ ```qml
+ // config/Colors.qml
+ pragma Singleton
+ Singleton {
+ readonly property color background1: ...
+ readonly property color foreground1: ...
+ }
+ ```
+
+4. **Launcher components**: Extend `IComponent` pattern (see `popups/launcher/components/IComponent.qml`):
+ - Must have `standalone`, `state`, `prefix`, `valid`, `priority` properties
+ - Implement `process()` function returning `{ valid, priority, answer, preview, predictiveCompletion }`
+ - Implement navigation functions: `up()`, `down()`, `prev()`, `next()`, `exec()`
+
+### Animations
+
+1. **Behavior on property**: For smooth transitions:
+ ```qml
+ Behavior on color {
+ ColorAnimation {
+ duration: General.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+ ```
+
+2. **Spring animations**: Use `ISpringAnimation`:
+ ```qml
+ Behavior on x {
+ ISpringAnimation {}
+ }
+ ```
+
+3. **Animation durations**: Reference `General.animationDuration` or `Style.anim.durations.*`.
+
+### Error Handling
+
+1. **JavaScript utilities**: Use exceptions for errors:
+ ```javascript
+ function riskyOperation() {
+ if (!condition) {
+ throw new Error("Operation failed");
+ }
+ }
+ ```
+
+2. **QML**: Use console.log for debugging, null checks for safety:
+ ```qml
+ property var activePlayer: Mpris.players.values[0] ?? null
+
+ function exec() {
+ if (this.canTogglePlaying)
+ this.activePlayer.togglePlaying();
+ }
+ ```
+
+### Comments
+
+1. Use comments for TODOs and known issues:
+ ```qml
+ // TODO: use visible instead of opacity for perf
+ // FIXME: currently relying on compositor animation
+ ```
+
+2. Document complex logic with inline comments.
+
+3. Use JSDoc-style comments in JavaScript files:
+ ```javascript
+ /**
+ * Formats a string according to the args that are passed in
+ * @param { string } str
+ * @returns { string }
+ */
+ function format(str, ...args) { ... }
+ ```
+
+## Project Structure
+
+```
+.
+├── shell.qml # Main entry point, IpcHandler definitions
+├── bar/ # Status bar components
+│ ├── Bar.qml # Main bar layout
+│ └── *.qml # Bar modules (Workspace, Mpris, TimeDate, etc.)
+├── components/ # Reusable base components
+│ ├── IText.qml
+│ ├── IRect.qml
+│ ├── IWindow.qml
+│ └── ...
+├── config/ # Configuration singletons
+│ ├── Colors.qml # Color palette
+│ ├── Style.qml # Typography and animation styles
+│ ├── Bar.qml # Bar configuration
+│ └── General.qml # General settings
+├── popups/ # Popup windows
+│ ├── IPopup.qml
+│ └── launcher/ # Launcher popup
+│ ├── Launcher.qml
+│ └── components/ # Launcher widget components
+├── services/ # Service singletons
+│ ├── Mpris.qml # Media player service
+│ ├── Network.qml # Network service
+│ └── ...
+└── utils/ # JavaScript utilities
+ ├── string_utils.js
+ ├── fzf.js
+ └── ...
+```
+
+## Common Tasks
+
+### Adding a new launcher component
-- **Formatting:**
- - Use 4 spaces for indentation.
- - Place properties and signals at the top of QML objects.
+1. Create `popups/launcher/components/NewComponent.qml`
+2. Extend `IComponent` and implement required properties/functions
+3. Add to `Launcher.widgets` list in `popups/launcher/ILauncher.qml`
-- **Naming:**
- - Use UpperCamelCase for QML types and components.
- - Use lowerCamelCase for properties, functions, and variables.
+### Adding a new bar module
-- **Types:**
- - Always specify types for QML properties (e.g., `property int`, `property string`).
+1. Create `bar/NewModule.qml`
+2. Import and add to `Bar.qml` in the appropriate RowLayout
+3. Use `IText`, `IRect`, `Icon` components for consistent styling
-- **Error Handling:**
- - Use exceptions in JavaScript utilities for errors.
- - Use comments for TODOs and known issues.
+### Adding IPC commands
-- **General:**
- - Keep code modular; use components and utility scripts.
- - Add comments for complex logic or workarounds.
+1. Add `IpcHandler` to `shell.qml`:
+ ```qml
+ IpcHandler {
+ target: "newTarget"
+ function doSomething(arg: string): void {
+ // implementation
+ }
+ }
+ ```
+2. Test with: `qs msg newTarget doSomething "argument"`