diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..be929bf
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,25 @@
+name: CI
+
+on:
+ pull_request:
+ branches: [master]
+ push:
+ branches: [master]
+
+permissions:
+ contents: read
+
+jobs:
+ checks:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
+
+ - name: Setup Python
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
+ with:
+ python-version: "3.12"
+
+ - run: python -m compileall -q get_tabs_tool.py
+ - run: python -m unittest discover -s tests
diff --git a/README.md b/README.md
index d948692..eee595e 100644
--- a/README.md
+++ b/README.md
@@ -1,125 +1,60 @@
-
-

-
+# Get Tabs Tool
-# Get Tabs Tool - README.md
+A small macOS command-line utility that returns the titles and URLs of open Safari tabs as JSON. It
+uses AppleScript through a short Python wrapper and can also be called from local automation tools.
-A command-line tool for macOS that retrieves the titles and URLs of all open tabs in Safari. It can be used as a standalone script or integrated as a local tool into AI assistants like the Gemini CLI.
+This is a best-effort hobby project built for a specific macOS workflow. It may need adjustment as
+Safari, macOS permissions, or third-party assistant integrations change.
+## Requirements
-## How It Works
-This tool relies on **AppleScript** to communicate directly with the Safari application on your Mac. A Python script executes a small AppleScript file (`get_tabs.applescript`) which asks Safari for its open tabs and returns the information.
+- macOS with Safari
+- Python 3.12 or newer
+- [uv](https://docs.astral.sh/uv/)
-Because AppleScript is a macOS-specific technology, this tool will **only run on macOS**.
+## Usage
+```bash
+git clone https://github.com/GoWithitRoger/get-tabs-tool.git
+cd get-tabs-tool
+uv run get_tabs_tool.py
+```
-## Requirements
+Example output:
+
+```json
+[
+ {
+ "title": "Example",
+ "url": "https://example.com/"
+ }
+]
+```
+
+The first run may prompt your terminal application for permission to control Safari. If needed,
+review the setting under **System Settings → Privacy & Security → Automation**.
+
+## Gemini CLI helper scripts
-- **macOS** with Safari installed.
-- **Python** >= 3.12
-- [**uv**](https://github.com/astral-sh/uv) (for easy execution with managed dependencies).
-
-
-## Standalone Usage (Command Line)
-You can use this tool directly in your terminal to get a quick JSON list of your open tabs.
-
-1. Navigate to the project directory:
-
- cd /path/to/get-tabs-tool
-
-2. Run the tool using `uv`:
-
- uv run get_tabs_tool.py
-
-The script will print a JSON array of your open Safari tabs to the terminal.
-
-#### Example Output:
-
- [
- {
- "title": "Google",
- "url": "https://www.google.com/"
- },
- {
- "title": "Gemini CLI Documentation",
- "url": "https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/index.md"
- }
- ]
-
-## Gemini CLI Integration
-To use this as a local tool within the Gemini CLI, you need to configure the CLI to discover and call the script.
-
-### Step 1: Create Helper Scripts
-The Gemini CLI needs two small shell scripts to understand how to find and run your tool. Create the following two files inside your `get-tabs-tool` project directory.
-
-**File 1: `discover_tools.sh`** (This script tells Gemini what the tool is called and what it does.)
-
- #!/bin/bash
- cat <<'EOF'
- [
- {
- "name": "get_tabs",
- "description": "Gets the title and URL of all open tabs in Safari.",
- "parameters": {
- "type": "OBJECT",
- "properties": {}
- }
- }
- ]
- EOF
-
-**File 2: `call_tool.sh`** (This script tells Gemini how to execute the tool when it's needed.)
-
- #!/bin/bash
- TOOL_NAME=$1
- SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
-
- if [ "$TOOL_NAME" == "get_tabs" ]; then
- (cd "$SCRIPT_DIR" && uv run get_tabs_tool.py)
- else
- echo "Error: Unknown tool '$TOOL_NAME'" >&2
- exit 1
- fi
-
-### Step 2: Make Scripts Executable
-In your terminal, navigate to the `get-tabs-tool` directory and run the following command to make the helper scripts runnable:
-
- chmod +x discover_tools.sh call_tool.sh
-
-### Step 3: Configure Gemini CLI `settings.json`
-Finally, edit your Gemini CLI `settings.json` file to tell it about your new scripts. You will need to add the `toolDiscoveryCommand` and `toolCallCommand` keys, pointing to the absolute paths of the scripts you just created.
-
- {
- "theme": "Default",
- "selectedAuthType": "oauth-personal",
- "contextFileName": "GEMINI.md",
- "preferredEditor": "vscode",
- "toolDiscoveryCommand": "/Users/your_username/Projects/get-tabs-tool/discover_tools.sh",
- "toolCallCommand": "/Users/your_username/Projects/get-tabs-tool/call_tool.sh",
- "mcpServers": {
- "...": "..."
- }
- }
-
-**Important:** Replace `/Users/your_username/` with the actual path to your home directory.
-
-After saving `settings.json`, restart the Gemini CLI. It will now have the `get_tabs` tool available.
-
-
-## Important: macOS Permissions
-The first time you run this tool (either standalone or via Gemini), macOS will likely ask for permission for your terminal application (e.g., `Terminal.app`, `iTerm.app`) to control Safari. **You must approve this request for the tool to work.**
-
-If you miss the pop-up or deny it, you can grant permission manually:
-
-1. Open **System Settings**.
-2. Go to **Privacy & Security > Automation**.
-3. Find your terminal application in the list.
-4. Ensure the checkbox for **Safari** is enabled.
-
-
-## Contributing
-Contributions are welcome! Please feel free to submit a pull request or open an issue.
+The repository includes `discover_tools.sh` and `call_tool.sh` for the older Gemini CLI local-tool
+interface. Point Gemini's `toolDiscoveryCommand` and `toolCallCommand` settings at those files and
+make them executable:
+```bash
+chmod +x discover_tools.sh call_tool.sh
+```
+
+That integration is kept as a convenience and may change with Gemini CLI releases. The standalone
+Python command does not depend on Gemini.
+
+## Development
+
+The parser tests do not open Safari and can run on any platform:
+
+```bash
+python -m unittest discover -s tests
+```
## License
-This project is licensed under the MIT License.
\ No newline at end of file
+
+MIT. See [LICENSE](LICENSE).
diff --git a/pyproject.toml b/pyproject.toml
index 0c9d31c..ad66fc9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,7 @@
[project]
name = "get-tabs-tool"
version = "0.1.0"
-description = "Add your description here"
+description = "Read titles and URLs from open Safari tabs on macOS"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
diff --git a/tests/test_get_tabs_tool.py b/tests/test_get_tabs_tool.py
new file mode 100644
index 0000000..2df6d7a
--- /dev/null
+++ b/tests/test_get_tabs_tool.py
@@ -0,0 +1,24 @@
+import unittest
+
+from get_tabs_tool import parse_tab_line
+
+
+class ParseTabLineTests(unittest.TestCase):
+ def test_parses_title_and_url(self):
+ self.assertEqual(
+ parse_tab_line("Example|||https://example.com/"),
+ {"title": "Example", "url": "https://example.com/"},
+ )
+
+ def test_preserves_delimiter_inside_url(self):
+ self.assertEqual(
+ parse_tab_line("Example|||https://example.com/a|||b"),
+ {"title": "Example", "url": "https://example.com/a|||b"},
+ )
+
+ def test_ignores_unrecognized_lines(self):
+ self.assertIsNone(parse_tab_line("not a tab record"))
+
+
+if __name__ == "__main__":
+ unittest.main()