allium-cli 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. allium_cli-0.2.0/.github/workflows/ci.yml +44 -0
  2. allium_cli-0.2.0/.github/workflows/release.yml +68 -0
  3. allium_cli-0.2.0/.gitignore +45 -0
  4. allium_cli-0.2.0/.pre-commit-config.yaml +13 -0
  5. allium_cli-0.2.0/CONTRIBUTING.md +39 -0
  6. allium_cli-0.2.0/LICENSE +21 -0
  7. allium_cli-0.2.0/PKG-INFO +306 -0
  8. allium_cli-0.2.0/README.md +277 -0
  9. allium_cli-0.2.0/cli/__init__.py +0 -0
  10. allium_cli-0.2.0/cli/auth/__init__.py +0 -0
  11. allium_cli-0.2.0/cli/auth/api_key.py +7 -0
  12. allium_cli-0.2.0/cli/auth/tempo.py +103 -0
  13. allium_cli-0.2.0/cli/auth/x402_key.py +31 -0
  14. allium_cli-0.2.0/cli/auth/x402_privy.py +27 -0
  15. allium_cli-0.2.0/cli/clients/__init__.py +4 -0
  16. allium_cli-0.2.0/cli/clients/factory.py +89 -0
  17. allium_cli-0.2.0/cli/clients/http.py +94 -0
  18. allium_cli-0.2.0/cli/clients/protocol.py +18 -0
  19. allium_cli-0.2.0/cli/clients/tempo.py +54 -0
  20. allium_cli-0.2.0/cli/clients/x402.py +185 -0
  21. allium_cli-0.2.0/cli/commands/__init__.py +16 -0
  22. allium_cli-0.2.0/cli/commands/auth.py +397 -0
  23. allium_cli-0.2.0/cli/commands/explorer.py +304 -0
  24. allium_cli-0.2.0/cli/commands/mp.py +159 -0
  25. allium_cli-0.2.0/cli/commands/realtime.py +445 -0
  26. allium_cli-0.2.0/cli/constants/__init__.py +28 -0
  27. allium_cli-0.2.0/cli/constants/api.py +4 -0
  28. allium_cli-0.2.0/cli/constants/config.py +23 -0
  29. allium_cli-0.2.0/cli/constants/ui.py +27 -0
  30. allium_cli-0.2.0/cli/main.py +108 -0
  31. allium_cli-0.2.0/cli/types/__init__.py +38 -0
  32. allium_cli-0.2.0/cli/types/config.py +33 -0
  33. allium_cli-0.2.0/cli/types/context.py +14 -0
  34. allium_cli-0.2.0/cli/types/enums.py +62 -0
  35. allium_cli-0.2.0/cli/types/labels.py +26 -0
  36. allium_cli-0.2.0/cli/types/profiles.py +45 -0
  37. allium_cli-0.2.0/cli/utils/__init__.py +0 -0
  38. allium_cli-0.2.0/cli/utils/async_cmd.py +15 -0
  39. allium_cli-0.2.0/cli/utils/body.py +40 -0
  40. allium_cli-0.2.0/cli/utils/config.py +90 -0
  41. allium_cli-0.2.0/cli/utils/console.py +6 -0
  42. allium_cli-0.2.0/cli/utils/cost_log.py +101 -0
  43. allium_cli-0.2.0/cli/utils/errors.py +63 -0
  44. allium_cli-0.2.0/cli/utils/options.py +44 -0
  45. allium_cli-0.2.0/cli/utils/output.py +103 -0
  46. allium_cli-0.2.0/cli/utils/payment.py +28 -0
  47. allium_cli-0.2.0/cli/utils/version.py +46 -0
  48. allium_cli-0.2.0/install.sh +31 -0
  49. allium_cli-0.2.0/lint.sh +6 -0
  50. allium_cli-0.2.0/lint_fix.sh +4 -0
  51. allium_cli-0.2.0/pyproject.toml +70 -0
  52. allium_cli-0.2.0/release.sh +18 -0
  53. allium_cli-0.2.0/test.sh +4 -0
  54. allium_cli-0.2.0/tests/__init__.py +0 -0
  55. allium_cli-0.2.0/tests/test_config.py +100 -0
  56. allium_cli-0.2.0/tests/test_cost_log.py +136 -0
  57. allium_cli-0.2.0/tests/test_helpers.py +109 -0
  58. allium_cli-0.2.0/tests/test_main.py +48 -0
  59. allium_cli-0.2.0/tests/test_models.py +142 -0
  60. allium_cli-0.2.0/uv.lock +2166 -0
@@ -0,0 +1,44 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: ci-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: astral-sh/setup-uv@v5
18
+ - run: uv sync --frozen
19
+ - run: uv run ruff check .
20
+ - run: uv run ruff format --check .
21
+
22
+ test:
23
+ runs-on: ubuntu-latest
24
+ strategy:
25
+ matrix:
26
+ python-version: ["3.12", "3.13"]
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: astral-sh/setup-uv@v5
30
+ with:
31
+ python-version: ${{ matrix.python-version }}
32
+ - run: uv sync --frozen
33
+ - run: uv run pytest
34
+
35
+ build:
36
+ runs-on: ubuntu-latest
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ - uses: astral-sh/setup-uv@v5
40
+ - run: uv build
41
+ - uses: actions/upload-artifact@v4
42
+ with:
43
+ name: dist
44
+ path: dist/
@@ -0,0 +1,68 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "cli.prod.v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: astral-sh/setup-uv@v5
18
+
19
+ - name: Verify tag matches pyproject.toml version
20
+ run: |
21
+ TAG_VERSION="${GITHUB_REF_NAME#cli.prod.v}"
22
+ PKG_VERSION="$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")"
23
+ if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
24
+ echo "::error::Tag version ($TAG_VERSION) does not match pyproject.toml ($PKG_VERSION)"
25
+ exit 1
26
+ fi
27
+
28
+ - run: uv build
29
+
30
+ - uses: actions/upload-artifact@v4
31
+ with:
32
+ name: dist
33
+ path: dist/
34
+
35
+ publish:
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ environment: pypi
39
+ steps:
40
+ - uses: actions/download-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ - uses: pypa/gh-action-pypi-publish@release/v1
46
+
47
+ github-release:
48
+ needs: publish
49
+ runs-on: ubuntu-latest
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+ with:
53
+ fetch-depth: 0
54
+
55
+ - name: Generate release notes
56
+ id: notes
57
+ run: |
58
+ PREV_TAG=$(git tag --sort=-creatordate | grep '^cli\.prod\.v' | sed -n '2p')
59
+ if [ -n "$PREV_TAG" ]; then
60
+ echo "range=$PREV_TAG...$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT"
61
+ else
62
+ echo "range=" >> "$GITHUB_OUTPUT"
63
+ fi
64
+
65
+ - uses: softprops/action-gh-release@v2
66
+ with:
67
+ generate_release_notes: true
68
+ files: ""
@@ -0,0 +1,45 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ build/
11
+ dist/
12
+ *.egg-info/
13
+ *.egg
14
+ MANIFEST
15
+
16
+ # Virtual environments
17
+ .venv/
18
+ env/
19
+ venv/
20
+
21
+ # Unit test / coverage
22
+ .pytest_cache/
23
+ .coverage
24
+ .coverage.*
25
+ htmlcov/
26
+ coverage.xml
27
+
28
+ # Type checkers
29
+ .mypy_cache/
30
+ .pytype/
31
+ .pyre/
32
+
33
+ # Ruff
34
+ .ruff_cache/
35
+
36
+ # Environments
37
+ .env
38
+ .envrc
39
+
40
+ # PyPI
41
+ .pypirc
42
+
43
+ # OS
44
+ .DS_Store
45
+ Thumbs.db
@@ -0,0 +1,13 @@
1
+ repos:
2
+ - repo: https://github.com/commitizen-tools/commitizen
3
+ rev: v4.4.1
4
+ hooks:
5
+ - id: commitizen
6
+ stages: [commit-msg]
7
+
8
+ - repo: https://github.com/astral-sh/ruff-pre-commit
9
+ rev: v0.11.2
10
+ hooks:
11
+ - id: ruff
12
+ args: [--fix]
13
+ - id: ruff-format
@@ -0,0 +1,39 @@
1
+ # Contributing
2
+
3
+ ## Development setup
4
+
5
+ ```bash
6
+ git clone https://github.com/Allium-Science/allium-cli.git
7
+ cd allium-cli
8
+ uv sync
9
+ ```
10
+
11
+ Run the CLI locally:
12
+
13
+ ```bash
14
+ uv run allium --help
15
+ ```
16
+
17
+ ### Tests
18
+
19
+ ```bash
20
+ uv run pytest
21
+ ```
22
+
23
+ ### Linting
24
+
25
+ ```bash
26
+ uv run ruff check .
27
+ uv run ruff format --check .
28
+ ```
29
+
30
+ ## Release process
31
+
32
+ Releases are automated via GitHub Actions, triggered by git tags.
33
+
34
+ 1. Bump `version` in `pyproject.toml` (e.g., `0.1.0` -> `0.2.0`)
35
+ 2. Commit and push to `main`
36
+ 3. Tag the release: `git tag cli.prod.v0.2.0 && git push origin cli.prod.v0.2.0`
37
+ 4. The tag triggers the publish workflow which builds and uploads to PyPI
38
+
39
+ The workflow validates that the tag version matches `pyproject.toml` before publishing.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Allium
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,306 @@
1
+ Metadata-Version: 2.4
2
+ Name: allium-cli
3
+ Version: 0.2.0
4
+ Summary: CLI for Allium blockchain data APIs
5
+ Project-URL: Documentation, https://docs.allium.so
6
+ Project-URL: Homepage, https://allium.so
7
+ Project-URL: Repository, https://github.com/Allium-Science/allium-cli
8
+ Author-email: Allium <support@allium.so>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Environment :: Console
12
+ Classifier: Framework :: Pydantic :: 2
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Database :: Front-Ends
17
+ Requires-Python: >=3.12
18
+ Requires-Dist: click>=8.1
19
+ Requires-Dist: eth-account~=0.13
20
+ Requires-Dist: httpx~=0.27
21
+ Requires-Dist: privy-client~=0.5
22
+ Requires-Dist: pydantic>=2.0
23
+ Requires-Dist: pympp[tempo]==0.3
24
+ Requires-Dist: questionary>=2.0
25
+ Requires-Dist: rich-click>=1.9.7
26
+ Requires-Dist: rich>=13.0
27
+ Requires-Dist: tomli-w>=1.0
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Allium CLI
31
+
32
+ Command-line interface for querying blockchain data across 80+ chains via the [Allium](https://allium.so) platform. Supports realtime token prices, wallet balances, transaction history, and SQL queries against Allium's data warehouse.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ curl -sSL https://raw.githubusercontent.com/Allium-Science/allium-cli/main/install.sh | sh
38
+ ```
39
+
40
+ Or install directly with your preferred package manager:
41
+
42
+ ```bash
43
+ uv tool install allium-cli # recommended
44
+ pipx install allium-cli
45
+ pip install allium-cli
46
+ ```
47
+
48
+ This installs the `allium` command. Run `allium auth setup` to configure authentication.
49
+
50
+ ## Authentication
51
+
52
+ The CLI supports four authentication methods. Run the interactive wizard, or pass arguments directly for scripted/CI setups:
53
+
54
+ ```bash
55
+ # Interactive wizard (arrow-key selection)
56
+ allium auth setup
57
+
58
+ # Non-interactive one-liners
59
+ allium auth setup --method api_key --api-key sk-...
60
+ allium auth setup --method x402_key --private-key 0x... --network eip155:8453
61
+ allium auth setup --method x402_privy \
62
+ --privy-app-id ... --privy-app-secret ... \
63
+ --privy-wallet-id ... --network eip155:8453
64
+ allium auth setup --method tempo --private-key 0x... --chain-id 42431
65
+ ```
66
+
67
+ | Method | Description |
68
+ |---|---|
69
+ | **API Key** | Standard key from [app.allium.so/settings/api-keys](https://app.allium.so/settings/api-keys) |
70
+ | **x402 Private Key** | Pay-per-call with USDC on Base -- no API key needed |
71
+ | **x402 Privy** | x402 via Privy server wallets -- no private key handling |
72
+ | **Tempo MPP** | Tempo micropayment protocol |
73
+
74
+ Optional flags: `--name <profile-name>` (defaults to the method name), `--no-active` (skip setting as active profile).
75
+
76
+ Credentials are stored in `~/.config/allium/credentials.toml` (file permissions restricted to owner).
77
+
78
+ ### Profile management
79
+
80
+ ```bash
81
+ allium auth list # Show all profiles
82
+ allium auth use <name> # Switch active profile
83
+ allium auth remove <name> # Delete a profile
84
+ ```
85
+
86
+ ## Global Options
87
+
88
+ ```
89
+ --profile TEXT Override the active auth profile for this command
90
+ --format [json|table|csv] Output format (default: json)
91
+ -v, --verbose Show progress details (run IDs, spinners, status)
92
+ --help Show help and exit
93
+ ```
94
+
95
+ ## Commands
96
+
97
+ ### `allium realtime` -- Realtime Blockchain Data
98
+
99
+ Query realtime blockchain data with 3-5s freshness across 20+ chains.
100
+
101
+ #### Prices
102
+
103
+ Token prices derived from on-chain DEX trades with VWAP calculation and outlier detection.
104
+
105
+ ```bash
106
+ # Latest minute-level price and OHLC values
107
+ allium realtime prices latest \
108
+ --chain solana --token-address So11111111111111111111111111111111111111112
109
+
110
+ # Price at a specific timestamp
111
+ allium realtime prices at-timestamp \
112
+ --chain ethereum --token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
113
+ --timestamp 2026-01-15T12:00:00Z --time-granularity 1h
114
+
115
+ # Historical price series
116
+ allium realtime prices history \
117
+ --chain ethereum --token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
118
+ --start-timestamp 2026-01-01T00:00:00Z --end-timestamp 2026-01-07T00:00:00Z \
119
+ --time-granularity 1d
120
+
121
+ # 24h/1h price stats (high, low, volume, trade count, percent change)
122
+ allium realtime prices stats \
123
+ --chain solana --token-address So11111111111111111111111111111111111111112
124
+ ```
125
+
126
+ **Options:** `--chain`, `--token-address` (repeatable, paired in order), `--body` (JSON override), `--timestamp`, `--start-timestamp`, `--end-timestamp`, `--time-granularity [15s|1m|5m|1h|1d]`
127
+
128
+ #### Tokens
129
+
130
+ ```bash
131
+ # List top tokens by volume
132
+ allium realtime tokens list --chain ethereum --sort volume --limit 10
133
+
134
+ # Fuzzy search by name or symbol
135
+ allium realtime tokens search -q "USDC"
136
+
137
+ # Exact lookup by chain + contract address
138
+ allium realtime tokens chain-address \
139
+ --chain ethereum --token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
140
+ ```
141
+
142
+ **Options:** `--chain`, `--token-address` (repeatable), `--sort [volume|trade_count|fully_diluted_valuation|address|name]`, `--order [asc|desc]`, `--limit`, `-q/--query`
143
+
144
+ #### Balances
145
+
146
+ ```bash
147
+ # Current token balances for a wallet
148
+ allium realtime balances latest \
149
+ --chain ethereum --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
150
+
151
+ # Historical balance snapshots
152
+ allium realtime balances history \
153
+ --chain ethereum --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
154
+ --start-timestamp 2026-01-01T00:00:00Z --limit 100
155
+ ```
156
+
157
+ **Options:** `--chain`, `--address` (repeatable, paired), `--start-timestamp`, `--end-timestamp`, `--limit`, `--body`
158
+
159
+ #### Transactions
160
+
161
+ ```bash
162
+ # Wallet transaction activity with decoded activities and labels
163
+ allium realtime transactions \
164
+ --chain ethereum --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
165
+ --activity-type dex_trade --lookback-days 7 --limit 50
166
+ ```
167
+
168
+ **Options:** `--chain`, `--address` (repeatable), `--activity-type`, `--lookback-days`, `--limit`, `--body`
169
+
170
+ #### PnL
171
+
172
+ ```bash
173
+ # Wallet profit and loss
174
+ allium realtime pnl \
175
+ --chain ethereum --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
176
+
177
+ # With historical breakdown
178
+ allium realtime pnl \
179
+ --chain ethereum --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \
180
+ --with-historical-breakdown
181
+ ```
182
+
183
+ **Options:** `--chain`, `--address` (repeatable), `--with-historical-breakdown`, `--body`
184
+
185
+ ---
186
+
187
+ ### `allium explorer` -- SQL Query Execution
188
+
189
+ Run SQL queries on Allium's data warehouse. By default, the CLI polls silently and prints results. Use `-v` for progress details.
190
+
191
+ ```bash
192
+ # Execute ad-hoc SQL (requires x402 or Tempo auth)
193
+ allium explorer run-sql "SELECT chain, COUNT(*) FROM crosschain.dex.trades GROUP BY chain LIMIT 10"
194
+
195
+ # Execute SQL from a file
196
+ allium explorer run-sql query.sql --limit 1000
197
+
198
+ # Run a saved query by ID with parameters
199
+ allium explorer run abc123 --param start_date=2026-01-01 --param chain=ethereum
200
+
201
+ # Just get the run ID without waiting
202
+ allium explorer run-sql "SELECT 1" --no-wait
203
+
204
+ # Check status of a query run
205
+ allium explorer status <run_id>
206
+
207
+ # Fetch results of a completed run
208
+ allium explorer results <run_id>
209
+
210
+ # Pipe CSV output directly
211
+ allium --format csv explorer run-sql "SELECT 1" > output.csv
212
+ ```
213
+
214
+ | Command | Description |
215
+ |---|---|
216
+ | `run-sql <SQL_OR_FILE>` | Execute ad-hoc SQL (x402/Tempo auth required) |
217
+ | `run <QUERY_ID>` | Execute a saved Explorer query by ID |
218
+ | `status <RUN_ID>` | Check query run status (created, running, success, failed, canceled) |
219
+ | `results <RUN_ID>` | Download results of a completed run |
220
+
221
+ **Options:** `--limit`, `--no-wait`, `--param key=value` (repeatable), `--compute-profile`
222
+
223
+ ---
224
+
225
+ ### `allium mp` -- Machine Payment Tracking
226
+
227
+ Track costs for x402 and Tempo micropayment API calls. Payments are logged automatically to `~/.config/allium/cost_log.csv`.
228
+
229
+ ```bash
230
+ # Total spend summary grouped by method and network
231
+ allium mp cost
232
+
233
+ # Full itemized payment history
234
+ allium mp cost list
235
+
236
+ # Export as CSV
237
+ allium --format csv mp cost list
238
+
239
+ # Clear the cost log
240
+ allium mp cost clear
241
+ ```
242
+
243
+ | Command | Description |
244
+ |---|---|
245
+ | `mp cost` | Total spend summary (grouped by method/network with call counts) |
246
+ | `mp cost list` | Full itemized history with per-row details |
247
+ | `mp cost clear` | Delete the cost log (with confirmation prompt) |
248
+
249
+ ---
250
+
251
+ ### `allium auth` -- Authentication Management
252
+
253
+ ```bash
254
+ # Interactive setup wizard (arrow-key selection)
255
+ allium auth setup
256
+
257
+ # Non-interactive setup (for scripts/CI)
258
+ allium auth setup --method api_key --api-key sk-...
259
+ allium auth setup --method tempo --private-key 0x... --chain-id 42431
260
+
261
+ # List all configured profiles
262
+ allium auth list
263
+
264
+ # Switch active profile
265
+ allium auth use <name>
266
+
267
+ # Delete a profile
268
+ allium auth remove <name>
269
+ ```
270
+
271
+ ## JSON Body Override
272
+
273
+ All realtime commands support a `--body` flag that accepts either inline JSON or a path to a `.json` file. When provided, it overrides all other options:
274
+
275
+ ```bash
276
+ # Inline JSON
277
+ allium realtime prices latest --body '[{"chain":"solana","token_address":"So111..."}]'
278
+
279
+ # From file
280
+ allium realtime prices latest --body tokens.json
281
+ ```
282
+
283
+ ## Shell Completions
284
+
285
+ Tab-completion is available for all commands, subcommands, and options. Add one of the following to your shell config:
286
+
287
+ ```bash
288
+ # Bash — add to ~/.bashrc
289
+ eval "$(_ALLIUM_COMPLETE=bash_source allium)"
290
+
291
+ # Zsh — add to ~/.zshrc
292
+ eval "$(_ALLIUM_COMPLETE=zsh_source allium)"
293
+
294
+ # Fish — add to ~/.config/fish/config.fish
295
+ _ALLIUM_COMPLETE=fish_source allium | source
296
+ ```
297
+
298
+ Reload your shell to activate completions.
299
+
300
+ ## Documentation
301
+
302
+ Full API documentation: [docs.allium.so](https://docs.allium.so)
303
+
304
+ ## Contributing
305
+
306
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and release instructions.