diff --git a/Architecture.md b/Architecture.md new file mode 100644 index 0000000..8038dc9 --- /dev/null +++ b/Architecture.md @@ -0,0 +1,211 @@ +# Architecture + +Technical overview of Roster's architecture. + +## Technology Stack + +### Core Technologies + +- **GTK 4** - UI toolkit +- **libadwaita** - GNOME design patterns and widgets +- **Python 3** - Application logic +- **libsoup3** - HTTP client (from GNOME Platform) +- **libsecret** - Credential storage via GNOME Keyring +- **GJS** - JavaScript runtime for scripts + +### Build System + +- **Meson** - Build configuration +- **GResources** - Bundle UI files and assets + +## Application Structure + +### Main Components + +**RosterApplication** (`main.py`) +- Singleton application class inheriting from `Adw.Application` +- Manages application lifecycle +- Handles global actions (quit, about, preferences) +- Creates and presents main window + +**RosterWindow** (`window.py`) +- Main application window inheriting from `Adw.ApplicationWindow` +- GTK template class with UI from `window.ui` +- Manages tabs, requests, and responses +- Coordinates HTTP operations + +### UI Architecture + +**Template-based UI:** +- UI defined in XML files (GTK Builder format) +- Loaded via GResources at runtime +- `@Gtk.Template` decorator binds Python class to UI +- `Gtk.Template.Child()` accesses widgets from template + +**Resource Management:** +- UI files defined in `src/roster.gresource.xml` +- Compiled into binary bundle during build +- Base path: `/cz/bugsy/roster` + +## Data Flow + +### HTTP Request Flow + +``` +User Input → Request Configuration → Variable Substitution → +Preprocessing Script → HTTP Request (libsoup3) → Response → +Postprocessing Script → Display Response → Save to History +``` + +### Variable Substitution + +1. User enters `{{variable_name}}` in request +2. Current environment selected from dropdown +3. Variable value retrieved (from JSON or Keyring) +4. Placeholder replaced with actual value +5. Request sent with substituted values + +### Script Execution + +**Preprocessing:** +1. Load script from request +2. Create JavaScript context (GJS) +3. Inject `request`, `roster`, `console` objects +4. Execute script synchronously +5. Apply modifications to request object + +**Postprocessing:** +1. Load script from request +2. Create JavaScript context (GJS) +3. Inject `response`, `roster`, `console` objects +4. Execute script synchronously +5. Variables updated via `roster.setVariable()` + +## Data Storage + +### File Locations + +**Native:** +``` +~/.local/share/cz.bugsy.roster/ +├── requests.json # Projects, environments, regular variables +└── session.json # History, window state +``` + +**Flatpak:** +``` +~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/ +├── requests.json +└── session.json +``` + +### Data Format + +**requests.json:** +```json +{ + "projects": [ + { + "id": "uuid", + "name": "Project Name", + "icon": "icon-name", + "environments": [ + { + "id": "uuid", + "name": "Production", + "variables": { + "base_url": "https://api.example.com", + "api_key": "" // Empty if sensitive + } + } + ], + "requests": [ + { + "id": "uuid", + "name": "Get Users", + "method": "GET", + "url": "{{base_url}}/users", + "headers": {}, + "body": "", + "preprocessing_script": "", + "postprocessing_script": "" + } + ] + } + ] +} +``` + +### Sensitive Variables + +Stored in GNOME Keyring with schema: +- **Schema:** `cz.bugsy.roster.EnvironmentVariable` +- **Attributes:** `project_id`, `environment_id`, `variable_name` +- **Secret:** Variable value (encrypted) + +## Key Design Patterns + +### Singleton Application + +Single instance ensured by `Adw.Application`. Attempting to launch a second instance activates the existing window. + +### Template Classes + +UI components use GTK template pattern: +```python +@Gtk.Template(resource_path='/cz/bugsy/roster/window.ui') +class RosterWindow(Adw.ApplicationWindow): + __gtype_name__ = 'RosterWindow' + + url_entry = Gtk.Template.Child() + method_dropdown = Gtk.Template.Child() +``` + +### Actions + +Application and window actions follow GNOME conventions: +```python +action = Gio.SimpleAction.new("quit", None) +action.connect("activate", self.on_quit) +self.add_action(action) +self.set_accels_for_action("app.quit", ["Q"]) +``` + +## HTTP Client + +Uses libsoup3 (from GNOME Platform): +- Asynchronous HTTP requests +- Automatic redirect handling +- Cookie management +- SSL/TLS support +- HTTP/2 support + +## Internationalization + +Uses gettext for translations: +- Domain: "roster" +- Template files (`.in`) processed by Meson +- `i18n.merge_file()` generates localized files +- Translations in `po/` directory + +## Security Model + +### Sandboxing (Flatpak) + +Permissions required: +- `--share=network` - HTTP requests +- `--talk-name=org.freedesktop.secrets` - GNOME Keyring access +- `--filesystem=xdg-data/cz.bugsy.roster` - Data directory + +### Script Sandboxing + +Scripts run in isolated GJS context: +- No file system access +- No network access (except main request) +- No process execution +- Only whitelisted APIs available + +## Next Steps + +- [[Development]] - Developer setup and workflow +- [[Contributing]] - Contribution guidelines diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 0000000..3028c3d --- /dev/null +++ b/Contributing.md @@ -0,0 +1,56 @@ +# Contributing + +Contributions to Roster are welcome! Here's how you can help. + +## Reporting Issues + +Report bugs or request features at: https://git.bugsy.cz/beval/roster/issues + +Include: +- Description of the issue or feature request +- Steps to reproduce (for bugs) +- Expected vs actual behavior +- Roster version and installation method (native/Flatpak) + +## Code Contributions + +### Setup Development Environment + +See [[Development]] for complete setup instructions. + +### Contribution Process + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature-name`) +3. Make your changes +4. Test your changes thoroughly +5. Commit with clear messages +6. Push to your fork +7. Open a pull request + +### Code Guidelines + +- Follow existing code style and patterns +- Use Python type hints where appropriate +- Keep functions focused and well-named +- Add comments for complex logic +- Test your changes with both native and Flatpak builds + +### UI/UX Guidelines + +- Follow GNOME Human Interface Guidelines +- Use libadwaita widgets and patterns +- Maintain consistency with existing UI +- Test with both light and dark themes + +## Documentation + +Help improve documentation by: +- Fixing typos or unclear explanations +- Adding examples +- Updating outdated information +- Translating to other languages + +## Questions + +For questions about contributing, open an issue on the bug tracker. diff --git a/Development.md b/Development.md new file mode 100644 index 0000000..3ecffa9 --- /dev/null +++ b/Development.md @@ -0,0 +1,167 @@ +# Development + +Developer guide for working on Roster. + +## Development Environment + +### Prerequisites + +Install build dependencies (see [[Installation]]): +- Meson, Ninja +- GTK 4, libadwaita development files +- Python 3, PyGObject +- GJS for script testing + +### Clone Repository + +```bash +git clone https://git.bugsy.cz/beval/roster.git +cd roster +``` + +## Building + +### Native Build + +```bash +meson setup builddir +meson compile -C builddir +``` + +### Run Without Installing + +```bash +meson devenv -C builddir +python3 src/main.py +``` + +### Install Locally + +```bash +meson install -C builddir --destdir /tmp/roster-install +``` + +### Flatpak Build + +Recommended for testing sandboxed environment: + +```bash +flatpak-builder --user --install --force-clean build-dir cz.bugsy.roster.json +flatpak run cz.bugsy.roster +``` + +## Project Structure + +``` +roster/ +├── data/ # Desktop files, icons, schemas +├── po/ # Translations +├── src/ # Python source code +│ ├── main.py # Application entry point +│ ├── window.py # Main window class +│ ├── window.ui # UI definition +│ └── ... +└── meson.build # Build configuration +``` + +See [[Architecture]] for detailed technical overview. + +## Development Workflow + +### Making Changes + +1. Create feature branch +2. Edit source files in `src/` +3. Rebuild: `meson compile -C builddir` +4. Test changes +5. Commit with descriptive message + +### UI Changes + +UI files are in `src/*.ui` (GTK Builder XML format). + +After editing `.ui` files: +1. Rebuild to update GResources +2. Test with `meson devenv -C builddir` + +### Adding Python Modules + +When adding new `.py` files: +1. Add to `roster_sources` in `src/meson.build` +2. Import in appropriate module + +### Schema Changes + +After modifying `data/cz.bugsy.roster.gschema.xml`: +1. Validate: `meson test -C builddir` +2. Compile: `glib-compile-schemas data/` + +## Testing + +### Run Tests + +```bash +meson test -C builddir +``` + +### Manual Testing + +Test both installation methods: +- Native build +- Flatpak build + +Test features: +- HTTP requests (GET, POST, PUT, DELETE) +- Variables and environments +- Sensitive variables (GNOME Keyring) +- Scripts (preprocessing/postprocessing) +- Request history +- Export functionality + +## Debugging + +### Python Debugging + +Use Python debugger: +```python +import pdb; pdb.set_trace() +``` + +### GTK Inspector + +Enable GTK Inspector: +```bash +gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true +# Then press Ctrl+Shift+D in running app +``` + +### Flatpak Debugging + +```bash +flatpak run --command=sh cz.bugsy.roster +# Then run python3 /app/share/roster/roster/main.py +``` + +### Logs + +Check logs for errors: +```bash +# Native +journalctl -f | grep roster + +# Flatpak +flatpak run cz.bugsy.roster 2>&1 | tee roster.log +``` + +## Code Style + +- Follow PEP 8 for Python code +- Use 4 spaces for indentation +- Use type hints where practical +- Keep functions focused and well-named +- Document complex logic with comments + +## Next Steps + +- [[Architecture]] - Technical architecture overview +- [[Contributing]] - Contribution guidelines diff --git a/Export.md b/Export.md new file mode 100644 index 0000000..1b85b02 --- /dev/null +++ b/Export.md @@ -0,0 +1,156 @@ +# Export + +Roster can export requests to other formats for use with command-line tools or other HTTP clients. + +## Supported Formats + +### cURL + +Export requests as cURL commands for use in terminal or scripts. + +**Example output:** +```bash +curl -X POST 'https://api.example.com/users' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer token123' \ + -d '{"name":"John","email":"john@example.com"}' +``` + +### Other Formats + +Additional export formats (HTTPie, wget, etc.) may be added in future releases. + +## How to Export + +### Export Current Request + +1. Configure your request in the request editor +2. Click the **Export** button in the toolbar +3. Select export format (e.g., "cURL") +4. Exported command is copied to clipboard + +### Export from History + +1. Open a request from [[History]] +2. Click the **Export** button +3. Select format +4. Command copied to clipboard + +### Export Saved Requests + +1. Open a saved request from project +2. Click the **Export** button +3. Select format +4. Command copied to clipboard + +## Variable Substitution + +When exporting requests that contain variables: + +**Variables are substituted with current environment values:** +- `{{base_url}}` replaced with actual URL +- `{{api_key}}` replaced with actual key value +- All `{{variable}}` placeholders resolved + +The exported command contains the final values, not the placeholder syntax. + +### Sensitive Variables + +[[Sensitive-Variables]] are exported with their actual decrypted values. Be careful when sharing exported commands containing sensitive data. + +**Security note:** Exported cURL commands may contain: +- API keys in headers +- Passwords in request body +- Tokens in authorization headers + +Review exported commands before sharing. + +## Using Exported Commands + +### cURL + +Paste the exported cURL command in your terminal: + +```bash +curl -X GET 'https://api.example.com/users' \ + -H 'Authorization: Bearer token123' +``` + +### Scripts + +Use exported commands in shell scripts: + +```bash +#!/bin/bash +# exported_request.sh + +curl -X POST 'https://api.example.com/users' \ + -H 'Content-Type: application/json' \ + -d '{"name":"John"}' +``` + +### Documentation + +Include exported commands in API documentation or tutorials. + +## Export Features + +### Headers + +All request headers are included in export: +- Custom headers +- Content-Type +- Authorization +- User-Agent +- etc. + +### Request Body + +Request body is included with appropriate flags: +- `-d` for POST data +- Properly escaped JSON +- Multiline bodies formatted correctly + +### Method + +HTTP method included with `-X` flag: +- `-X GET` +- `-X POST` +- `-X PUT` +- `-X DELETE` + +## Limitations + +- Only cURL format currently supported +- No batch export of multiple requests +- Exported to clipboard only (no file export) +- Scripts (preprocessing/postprocessing) are not exported + +## Tips + +**Test exported commands:** +Always test exported cURL commands in a safe environment before using in production. + +**Redact sensitive data:** +Remove or replace sensitive values before sharing exported commands: +```bash +# Original export +curl -H 'Authorization: Bearer abc123xyz' + +# Redacted for sharing +curl -H 'Authorization: Bearer YOUR_TOKEN_HERE' +``` + +**Save to file:** +Redirect clipboard content to file: +```bash +# Paste from clipboard and save +pbpaste > request.sh # macOS +xclip -o > request.sh # Linux with xclip +``` + +## Next Steps + +- [[Getting-Started]] - Learn to create requests +- [[Variables]] - Use variables in requests +- [[History]] - Review past requests diff --git a/History.md b/History.md new file mode 100644 index 0000000..151b7cd --- /dev/null +++ b/History.md @@ -0,0 +1,124 @@ +# History + +Roster automatically saves every HTTP request you send to history, allowing you to review and replay past requests. + +## What is History? + +History captures complete request and response data for every request sent: +- Request method, URL, headers, body +- Response status, headers, body, timing +- Timestamp of when request was sent +- Environment used (if applicable) + +History persists across sessions and survives application restarts. + +## Viewing History + +### Access History Panel + +History appears in the bottom panel of the main window. + +### History Entries + +Each entry shows: +- Request method and URL +- Response status code +- Timestamp (relative or absolute) +- Response time + +Entries are sorted by timestamp (most recent first). + +### Open from History + +Click any history entry to open it in a new tab with: +- Complete request details +- Full response +- All headers + +This creates a new editable request tab - you can modify and resend. + +## Replaying Requests + +To replay a request from history: + +1. Click the history entry +2. Request opens in new tab with original configuration +3. Click **"Send"** to execute again + +The replayed request: +- Uses current environment variables (not original values) +- Can be modified before sending +- Creates a new history entry when sent + +## Using History + +### Compare Responses + +Open multiple history entries in tabs to compare responses across time or different environments. + +### Debug Issues + +Review past requests to: +- See what was actually sent +- Check response timing trends +- Verify header values +- Examine error responses + +### Create New Requests + +Use history entries as templates: +1. Open history entry +2. Modify URL, headers, or body +3. Save as new request + +## History Storage + +**Native:** +``` +~/.local/share/cz.bugsy.roster/session.json +``` + +**Flatpak:** +``` +~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/session.json +``` + +History is stored in JSON format with full request/response data. + +## Clearing History + +Currently, history can be cleared by deleting the `session.json` file: + +```bash +# Native +rm ~/.local/share/cz.bugsy.roster/session.json + +# Flatpak +rm ~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/session.json +``` + +Then restart Roster. + +## Privacy Note + +History contains complete request and response data, including: +- URLs and query parameters +- Request/response headers +- Request/response bodies + +If requests contain sensitive data: +- Use [[Sensitive-Variables]] for credentials +- Be aware history file contains plaintext data +- Clear history periodically if needed + +## Limitations + +- History is stored locally only (no cloud sync) +- No built-in UI to clear history (must delete file manually) +- No search/filter functionality (planned for future releases) +- No export functionality for history entries + +## Next Steps + +- [[Getting-Started]] - Learn to send requests +- [[Export]] - Export requests to other tools