agent-discogs 0.2.0__tar.gz → 0.3.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.
- agent_discogs-0.3.0/PKG-INFO +171 -0
- agent_discogs-0.3.0/README.md +146 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/pyproject.toml +16 -5
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/pyproject.toml.orig +23 -6
- agent_discogs-0.3.0/src/agent_discogs/__init__.py +555 -0
- agent_discogs-0.3.0/src/agent_discogs/account.py +153 -0
- agent_discogs-0.3.0/src/agent_discogs/client.py +74 -0
- agent_discogs-0.3.0/src/agent_discogs/collection.py +290 -0
- agent_discogs-0.3.0/src/agent_discogs/commands/cache.py +30 -0
- agent_discogs-0.3.0/src/agent_discogs/commands/completion.py +36 -0
- agent_discogs-0.3.0/src/agent_discogs/commands/get.py +1910 -0
- agent_discogs-0.3.0/src/agent_discogs/commands/search.py +540 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/commands/skills.py +8 -2
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/commands/status.py +5 -4
- agent_discogs-0.3.0/src/agent_discogs/config.py +34 -0
- agent_discogs-0.3.0/src/agent_discogs/errors.py +418 -0
- agent_discogs-0.3.0/src/agent_discogs/formatting.py +1612 -0
- agent_discogs-0.3.0/src/agent_discogs/inventory.py +192 -0
- agent_discogs-0.3.0/src/agent_discogs/json_output.py +104 -0
- agent_discogs-0.3.0/src/agent_discogs/markup.py +262 -0
- agent_discogs-0.3.0/src/agent_discogs/pagination.py +346 -0
- agent_discogs-0.3.0/src/agent_discogs/projections.py +489 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/refs.py +2 -2
- agent_discogs-0.3.0/src/agent_discogs/sanitize.py +39 -0
- agent_discogs-0.3.0/src/agent_discogs/skills/core/SKILL.md +246 -0
- agent_discogs-0.3.0/src/agent_discogs/skills/core/references/commands.md +354 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/skills/core/references/discogs-domain.md +37 -4
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/skills/core/references/pressings-guide.md +1 -1
- agent_discogs-0.3.0/src/agent_discogs/skills/core/references/search-patterns.md +94 -0
- agent_discogs-0.3.0/src/agent_discogs/style.py +101 -0
- agent_discogs-0.3.0/src/agent_discogs/trace.py +271 -0
- agent_discogs-0.3.0/src/agent_discogs/wantlist.py +71 -0
- agent_discogs-0.2.0/PKG-INFO +0 -260
- agent_discogs-0.2.0/README.md +0 -235
- agent_discogs-0.2.0/src/agent_discogs/__init__.py +0 -180
- agent_discogs-0.2.0/src/agent_discogs/client.py +0 -38
- agent_discogs-0.2.0/src/agent_discogs/commands/cache.py +0 -16
- agent_discogs-0.2.0/src/agent_discogs/commands/get.py +0 -794
- agent_discogs-0.2.0/src/agent_discogs/commands/search.py +0 -275
- agent_discogs-0.2.0/src/agent_discogs/errors.py +0 -175
- agent_discogs-0.2.0/src/agent_discogs/formatting.py +0 -741
- agent_discogs-0.2.0/src/agent_discogs/json_output.py +0 -66
- agent_discogs-0.2.0/src/agent_discogs/pagination.py +0 -196
- agent_discogs-0.2.0/src/agent_discogs/projections.py +0 -300
- agent_discogs-0.2.0/src/agent_discogs/skills/core/SKILL.md +0 -171
- agent_discogs-0.2.0/src/agent_discogs/skills/core/references/commands.md +0 -181
- agent_discogs-0.2.0/src/agent_discogs/skills/core/references/search-patterns.md +0 -72
- agent_discogs-0.2.0/src/agent_discogs/trace.py +0 -223
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/LICENSE.txt +0 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/__main__.py +0 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/commands/__init__.py +0 -0
- {agent_discogs-0.2.0 → agent_discogs-0.3.0}/src/agent_discogs/py.typed +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-discogs
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Token-efficient Discogs CLI for AI agents
|
|
5
|
+
Keywords: ai-agent,cli,discogs,discogs-api,music-database
|
|
6
|
+
Author: Jean-Marc Fontaine
|
|
7
|
+
Author-email: Jean-Marc Fontaine <jm@jmfontaine.net>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
License-File: LICENSE.txt
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
17
|
+
Requires-Dist: click>=8.3.1
|
|
18
|
+
Requires-Dist: discogs-sdk>=0.8.1
|
|
19
|
+
Requires-Dist: pydantic>=2.12.5
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Project-URL: Homepage, https://github.com/jmfontaine/agent-discogs
|
|
22
|
+
Project-URL: Issues, https://github.com/jmfontaine/agent-discogs/issues
|
|
23
|
+
Project-URL: Repository, https://github.com/jmfontaine/agent-discogs
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# agent-discogs
|
|
27
|
+
|
|
28
|
+
A token-efficient Discogs CLI for AI agents that minimizes API calls.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
agent-discogs search "Nine Inch Nails"
|
|
32
|
+
agent-discogs get release @r352665 # ref from search output
|
|
33
|
+
agent-discogs tracks @r352665 # tracklist shortcut
|
|
34
|
+
agent-discogs price @r352665 # price guide shortcut
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pipx install agent-discogs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or with [uv](https://docs.astral.sh/uv/):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
uv tool install agent-discogs
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or with pip:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install agent-discogs
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
pipx, uv and pip need Python 3.10 or later.
|
|
56
|
+
|
|
57
|
+
### Homebrew
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
brew install jmfontaine/tap/agent-discogs
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The formula comes from the maintainer's [Homebrew](https://brew.sh/) tap. It installs the PyPI release into a virtualenv on Homebrew's own Python, whatever Python you have.
|
|
64
|
+
|
|
65
|
+
To tap once and then use the short name:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
brew tap jmfontaine/tap
|
|
69
|
+
brew install agent-discogs
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or in a Brewfile:
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
tap "jmfontaine/tap"
|
|
76
|
+
brew "agent-discogs"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
A prebuilt bottle exists only for Apple Silicon Macs on macOS 26 or later. Everywhere else (Intel Macs, earlier macOS, Linux) Homebrew builds from source, which needs Rust (for pydantic-core; Homebrew installs it as a build dependency) and takes a few minutes.
|
|
80
|
+
|
|
81
|
+
`brew upgrade` installs a new release once the tap has picked it up from PyPI.
|
|
82
|
+
|
|
83
|
+
### AI Coding Agent Skill
|
|
84
|
+
|
|
85
|
+
Install the skill so your AI coding agent can use agent-discogs automatically:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx skills add jmfontaine/agent-discogs
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The installed skill is a thin pointer; the usage guide itself ships inside the package and is served by `agent-discogs skills get core`, so agents always read instructions that match the version they run (see [skills](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md#skills)).
|
|
92
|
+
|
|
93
|
+
## Authentication
|
|
94
|
+
|
|
95
|
+
Set your personal access token from [your Discogs developer settings](https://www.discogs.com/settings/developers):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
export DISCOGS_TOKEN="your-token-here"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Credentials are required for price lookups, and Discogs' API documentation requires them for search too: unauthenticated searches currently get answers, but Discogs may refuse one with `auth_required`. Without any credentials the limit is 25 requests/minute; with a token, every command works at 60 requests/minute.
|
|
102
|
+
|
|
103
|
+
`price` needs one thing more than a token or OAuth credentials: Discogs only returns price suggestions to accounts that have filled out their [seller settings](https://www.discogs.com/settings/seller). Until you do, the endpoint answers 404 and `price` tells you so; every other command is unaffected.
|
|
104
|
+
|
|
105
|
+
The CLI sends whichever credentials discogs-sdk finds in the environment, in this order:
|
|
106
|
+
|
|
107
|
+
1. `DISCOGS_TOKEN`;
|
|
108
|
+
2. OAuth 1.0a (`DISCOGS_CONSUMER_KEY`, `DISCOGS_CONSUMER_SECRET`, `DISCOGS_ACCESS_TOKEN` and `DISCOGS_ACCESS_TOKEN_SECRET`, all four);
|
|
109
|
+
3. a consumer key and secret alone (`DISCOGS_CONSUMER_KEY` and `DISCOGS_CONSUMER_SECRET`);
|
|
110
|
+
4. otherwise none.
|
|
111
|
+
|
|
112
|
+
A consumer key and secret get 60 requests/minute but identify an app, not a user, so `price` needs a token or OAuth, and so do `--owned`, `--in-wantlist`, `get owned`, `get collection`, `get lists` and `get wantlist`, which read your own collection, lists and wantlist. `get inventory` alone works without credentials: Discogs shows anyone a seller's For Sale listings. `agent-discogs status` reports the mode in use.
|
|
113
|
+
|
|
114
|
+
> [!TIP]
|
|
115
|
+
> Use a `.env` file with [direnv](https://direnv.net/) to avoid exporting tokens manually in every shell.
|
|
116
|
+
|
|
117
|
+
## Commands
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
agent-discogs search release "The Downward Spiral" --year 1994
|
|
121
|
+
agent-discogs search artist "Nine Inch Nails" --limit 10
|
|
122
|
+
agent-discogs get artist @a3857
|
|
123
|
+
agent-discogs get versions @m3719 --country US --format Vinyl
|
|
124
|
+
agent-discogs get owned @r352665 @r847868
|
|
125
|
+
agent-discogs search release --artist "Nine Inch Nails" --year 1994 --limit 20 --owned
|
|
126
|
+
agent-discogs get collection --style Techno --format 12\" --max-requests 20
|
|
127
|
+
agent-discogs get wantlist --for-sale --max-price 20 --currency EUR --max-requests 60
|
|
128
|
+
agent-discogs get inventory <seller> --in-wantlist --condition VG+ --max-requests 60
|
|
129
|
+
agent-discogs get lists
|
|
130
|
+
agent-discogs get list 123
|
|
131
|
+
agent-discogs get release @r352665 --json
|
|
132
|
+
agent-discogs status
|
|
133
|
+
agent-discogs cache clear
|
|
134
|
+
agent-discogs skills get core
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Each command, its own flags and its text output are described in [Commands](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md). The global flags (`--cached`, `--fresh`, `--debug`, `--color`), the output modes (`--json`, `--full`) and the `--max-requests` cap have their own pages:
|
|
138
|
+
|
|
139
|
+
- `--json` and `--full`: [JSON output](https://github.com/jmfontaine/agent-discogs/blob/main/docs/json-output.md);
|
|
140
|
+
- `--cached`, `--fresh` and `--max-requests`: [Caching and request budget](https://github.com/jmfontaine/agent-discogs/blob/main/docs/caching-and-budget.md);
|
|
141
|
+
- `--debug`: [Debugging](https://github.com/jmfontaine/agent-discogs/blob/main/docs/debugging.md);
|
|
142
|
+
- `--color`: [Color](https://github.com/jmfontaine/agent-discogs/blob/main/docs/debugging.md#color); the default, `auto`, colors a terminal only, never a pipe.
|
|
143
|
+
|
|
144
|
+
For Tab completion in an interactive bash, zsh or fish shell, add `eval "$(agent-discogs completion zsh)"` (or `bash`) to the shell's startup file; see [Shell completion](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md#shell-completion) for fish.
|
|
145
|
+
|
|
146
|
+
## Ref system
|
|
147
|
+
|
|
148
|
+
Output includes typed refs that encode the entity type and Discogs ID. Copy them into subsequent commands.
|
|
149
|
+
|
|
150
|
+
| Prefix | Type | Example |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| `@r` | Release | `@r352665` |
|
|
153
|
+
| `@a` | Artist | `@a3857` |
|
|
154
|
+
| `@m` | Master | `@m3719` |
|
|
155
|
+
| `@l` | Label | `@l647` |
|
|
156
|
+
|
|
157
|
+
Raw numeric IDs also work: `agent-discogs get release 352665`.
|
|
158
|
+
|
|
159
|
+
Smart resolution: `get versions @r352665` auto-resolves the release to its master.
|
|
160
|
+
|
|
161
|
+
## Documentation
|
|
162
|
+
|
|
163
|
+
- [Commands](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md): `search` (filters, sorting, client-side scans, `--added-since`, `--owned`), `get` and its nouns (`get owned`, `get collection` and its filters, `get wantlist` and its `--for-sale` scan, `get inventory` and its grade, origin, price and `--in-wantlist` filters, `get lists` and `get list`), `tracks` / `price`, `status`, `cache`, `skills`, shell completion.
|
|
164
|
+
- [JSON output](https://github.com/jmfontaine/agent-discogs/blob/main/docs/json-output.md): projections, `--full`, the pagination envelope, `owned` rows, collection rows, wantlist rows and their `market`, inventory listings and their `wantlist` object, lists and their items, non-ASCII and control-character escaping.
|
|
165
|
+
- [Caching and request budget](https://github.com/jmfontaine/agent-discogs/blob/main/docs/caching-and-budget.md): `--cached` / `--fresh`, cache errors, rate limits, what each command costs, `--max-requests`.
|
|
166
|
+
- [Errors](https://github.com/jmfontaine/agent-discogs/blob/main/docs/errors.md): the error layout, error codes, and the 401, 429 and connection-error hints.
|
|
167
|
+
- [Debugging](https://github.com/jmfontaine/agent-discogs/blob/main/docs/debugging.md): the `--debug` panel, output encoding, how Discogs text is neutralized, and `--color`.
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
agent-discogs is licensed under the [Apache License 2.0](LICENSE.txt).
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# agent-discogs
|
|
2
|
+
|
|
3
|
+
A token-efficient Discogs CLI for AI agents that minimizes API calls.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
agent-discogs search "Nine Inch Nails"
|
|
7
|
+
agent-discogs get release @r352665 # ref from search output
|
|
8
|
+
agent-discogs tracks @r352665 # tracklist shortcut
|
|
9
|
+
agent-discogs price @r352665 # price guide shortcut
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pipx install agent-discogs
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or with [uv](https://docs.astral.sh/uv/):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv tool install agent-discogs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or with pip:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install agent-discogs
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
pipx, uv and pip need Python 3.10 or later.
|
|
31
|
+
|
|
32
|
+
### Homebrew
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
brew install jmfontaine/tap/agent-discogs
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The formula comes from the maintainer's [Homebrew](https://brew.sh/) tap. It installs the PyPI release into a virtualenv on Homebrew's own Python, whatever Python you have.
|
|
39
|
+
|
|
40
|
+
To tap once and then use the short name:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
brew tap jmfontaine/tap
|
|
44
|
+
brew install agent-discogs
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or in a Brewfile:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
tap "jmfontaine/tap"
|
|
51
|
+
brew "agent-discogs"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
A prebuilt bottle exists only for Apple Silicon Macs on macOS 26 or later. Everywhere else (Intel Macs, earlier macOS, Linux) Homebrew builds from source, which needs Rust (for pydantic-core; Homebrew installs it as a build dependency) and takes a few minutes.
|
|
55
|
+
|
|
56
|
+
`brew upgrade` installs a new release once the tap has picked it up from PyPI.
|
|
57
|
+
|
|
58
|
+
### AI Coding Agent Skill
|
|
59
|
+
|
|
60
|
+
Install the skill so your AI coding agent can use agent-discogs automatically:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx skills add jmfontaine/agent-discogs
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The installed skill is a thin pointer; the usage guide itself ships inside the package and is served by `agent-discogs skills get core`, so agents always read instructions that match the version they run (see [skills](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md#skills)).
|
|
67
|
+
|
|
68
|
+
## Authentication
|
|
69
|
+
|
|
70
|
+
Set your personal access token from [your Discogs developer settings](https://www.discogs.com/settings/developers):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
export DISCOGS_TOKEN="your-token-here"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Credentials are required for price lookups, and Discogs' API documentation requires them for search too: unauthenticated searches currently get answers, but Discogs may refuse one with `auth_required`. Without any credentials the limit is 25 requests/minute; with a token, every command works at 60 requests/minute.
|
|
77
|
+
|
|
78
|
+
`price` needs one thing more than a token or OAuth credentials: Discogs only returns price suggestions to accounts that have filled out their [seller settings](https://www.discogs.com/settings/seller). Until you do, the endpoint answers 404 and `price` tells you so; every other command is unaffected.
|
|
79
|
+
|
|
80
|
+
The CLI sends whichever credentials discogs-sdk finds in the environment, in this order:
|
|
81
|
+
|
|
82
|
+
1. `DISCOGS_TOKEN`;
|
|
83
|
+
2. OAuth 1.0a (`DISCOGS_CONSUMER_KEY`, `DISCOGS_CONSUMER_SECRET`, `DISCOGS_ACCESS_TOKEN` and `DISCOGS_ACCESS_TOKEN_SECRET`, all four);
|
|
84
|
+
3. a consumer key and secret alone (`DISCOGS_CONSUMER_KEY` and `DISCOGS_CONSUMER_SECRET`);
|
|
85
|
+
4. otherwise none.
|
|
86
|
+
|
|
87
|
+
A consumer key and secret get 60 requests/minute but identify an app, not a user, so `price` needs a token or OAuth, and so do `--owned`, `--in-wantlist`, `get owned`, `get collection`, `get lists` and `get wantlist`, which read your own collection, lists and wantlist. `get inventory` alone works without credentials: Discogs shows anyone a seller's For Sale listings. `agent-discogs status` reports the mode in use.
|
|
88
|
+
|
|
89
|
+
> [!TIP]
|
|
90
|
+
> Use a `.env` file with [direnv](https://direnv.net/) to avoid exporting tokens manually in every shell.
|
|
91
|
+
|
|
92
|
+
## Commands
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
agent-discogs search release "The Downward Spiral" --year 1994
|
|
96
|
+
agent-discogs search artist "Nine Inch Nails" --limit 10
|
|
97
|
+
agent-discogs get artist @a3857
|
|
98
|
+
agent-discogs get versions @m3719 --country US --format Vinyl
|
|
99
|
+
agent-discogs get owned @r352665 @r847868
|
|
100
|
+
agent-discogs search release --artist "Nine Inch Nails" --year 1994 --limit 20 --owned
|
|
101
|
+
agent-discogs get collection --style Techno --format 12\" --max-requests 20
|
|
102
|
+
agent-discogs get wantlist --for-sale --max-price 20 --currency EUR --max-requests 60
|
|
103
|
+
agent-discogs get inventory <seller> --in-wantlist --condition VG+ --max-requests 60
|
|
104
|
+
agent-discogs get lists
|
|
105
|
+
agent-discogs get list 123
|
|
106
|
+
agent-discogs get release @r352665 --json
|
|
107
|
+
agent-discogs status
|
|
108
|
+
agent-discogs cache clear
|
|
109
|
+
agent-discogs skills get core
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Each command, its own flags and its text output are described in [Commands](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md). The global flags (`--cached`, `--fresh`, `--debug`, `--color`), the output modes (`--json`, `--full`) and the `--max-requests` cap have their own pages:
|
|
113
|
+
|
|
114
|
+
- `--json` and `--full`: [JSON output](https://github.com/jmfontaine/agent-discogs/blob/main/docs/json-output.md);
|
|
115
|
+
- `--cached`, `--fresh` and `--max-requests`: [Caching and request budget](https://github.com/jmfontaine/agent-discogs/blob/main/docs/caching-and-budget.md);
|
|
116
|
+
- `--debug`: [Debugging](https://github.com/jmfontaine/agent-discogs/blob/main/docs/debugging.md);
|
|
117
|
+
- `--color`: [Color](https://github.com/jmfontaine/agent-discogs/blob/main/docs/debugging.md#color); the default, `auto`, colors a terminal only, never a pipe.
|
|
118
|
+
|
|
119
|
+
For Tab completion in an interactive bash, zsh or fish shell, add `eval "$(agent-discogs completion zsh)"` (or `bash`) to the shell's startup file; see [Shell completion](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md#shell-completion) for fish.
|
|
120
|
+
|
|
121
|
+
## Ref system
|
|
122
|
+
|
|
123
|
+
Output includes typed refs that encode the entity type and Discogs ID. Copy them into subsequent commands.
|
|
124
|
+
|
|
125
|
+
| Prefix | Type | Example |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `@r` | Release | `@r352665` |
|
|
128
|
+
| `@a` | Artist | `@a3857` |
|
|
129
|
+
| `@m` | Master | `@m3719` |
|
|
130
|
+
| `@l` | Label | `@l647` |
|
|
131
|
+
|
|
132
|
+
Raw numeric IDs also work: `agent-discogs get release 352665`.
|
|
133
|
+
|
|
134
|
+
Smart resolution: `get versions @r352665` auto-resolves the release to its master.
|
|
135
|
+
|
|
136
|
+
## Documentation
|
|
137
|
+
|
|
138
|
+
- [Commands](https://github.com/jmfontaine/agent-discogs/blob/main/docs/commands.md): `search` (filters, sorting, client-side scans, `--added-since`, `--owned`), `get` and its nouns (`get owned`, `get collection` and its filters, `get wantlist` and its `--for-sale` scan, `get inventory` and its grade, origin, price and `--in-wantlist` filters, `get lists` and `get list`), `tracks` / `price`, `status`, `cache`, `skills`, shell completion.
|
|
139
|
+
- [JSON output](https://github.com/jmfontaine/agent-discogs/blob/main/docs/json-output.md): projections, `--full`, the pagination envelope, `owned` rows, collection rows, wantlist rows and their `market`, inventory listings and their `wantlist` object, lists and their items, non-ASCII and control-character escaping.
|
|
140
|
+
- [Caching and request budget](https://github.com/jmfontaine/agent-discogs/blob/main/docs/caching-and-budget.md): `--cached` / `--fresh`, cache errors, rate limits, what each command costs, `--max-requests`.
|
|
141
|
+
- [Errors](https://github.com/jmfontaine/agent-discogs/blob/main/docs/errors.md): the error layout, error codes, and the 401, 429 and connection-error hints.
|
|
142
|
+
- [Debugging](https://github.com/jmfontaine/agent-discogs/blob/main/docs/debugging.md): the `--debug` panel, output encoding, how Discogs text is neutralized, and `--color`.
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
agent-discogs is licensed under the [Apache License 2.0](LICENSE.txt).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
build-backend = "uv_build"
|
|
3
|
-
requires = ["uv-build>=0.12.13,<0.
|
|
3
|
+
requires = ["uv-build>=0.12.13,<0.14"]
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agent-discogs"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Token-efficient Discogs CLI for AI agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
dependencies = [
|
|
30
30
|
"click>=8.3.1",
|
|
31
|
-
"discogs-sdk>=0.
|
|
31
|
+
"discogs-sdk>=0.8.1",
|
|
32
32
|
"pydantic>=2.12.5",
|
|
33
33
|
]
|
|
34
34
|
|
|
@@ -47,6 +47,7 @@ agent-discogs = "agent_discogs:main"
|
|
|
47
47
|
[dependency-groups]
|
|
48
48
|
dev = [
|
|
49
49
|
"deptry>=0.24",
|
|
50
|
+
"pre-commit>=4.6.2",
|
|
50
51
|
"pyproject-fmt>=2.16.1",
|
|
51
52
|
"pyright>=1.1.408",
|
|
52
53
|
"ruff>=0.15.2",
|
|
@@ -107,7 +108,6 @@ select = [
|
|
|
107
108
|
ignore = [
|
|
108
109
|
"EM101",
|
|
109
110
|
"EM102",
|
|
110
|
-
"PLC0415",
|
|
111
111
|
"PLR0911",
|
|
112
112
|
"PLR0912",
|
|
113
113
|
"PLR0913",
|
|
@@ -121,7 +121,6 @@ ignore = [
|
|
|
121
121
|
|
|
122
122
|
[tool.ruff.lint.per-file-ignores]
|
|
123
123
|
"tests/**" = [
|
|
124
|
-
"ARG001",
|
|
125
124
|
"ARG005",
|
|
126
125
|
"PLR2004",
|
|
127
126
|
"S101",
|
|
@@ -137,13 +136,25 @@ max_supported_python = "3.15"
|
|
|
137
136
|
addopts = "-m 'not live'"
|
|
138
137
|
markers = ["live: hits the real Discogs API; run with `just test-live` (needs DISCOGS_TOKEN)"]
|
|
139
138
|
|
|
139
|
+
[tool.coverage.run]
|
|
140
|
+
source = ["agent_discogs"]
|
|
141
|
+
|
|
142
|
+
[tool.coverage.report]
|
|
143
|
+
fail_under = 100
|
|
144
|
+
|
|
140
145
|
[tool.deadcode]
|
|
141
146
|
ignore-names = [
|
|
147
|
+
"_color_terminal",
|
|
148
|
+
"_fake_api",
|
|
149
|
+
"_isolate_env",
|
|
150
|
+
"_patch_clients",
|
|
142
151
|
"_patch_get",
|
|
143
152
|
"_patch_search",
|
|
144
153
|
"_reset_singleton",
|
|
154
|
+
"_real_client",
|
|
145
155
|
"_scoped_client",
|
|
146
156
|
"format_help",
|
|
147
157
|
"get_skill",
|
|
158
|
+
"pytest_plugins",
|
|
148
159
|
"skill_path",
|
|
149
160
|
]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
build-backend = "uv_build"
|
|
3
|
-
requires = [ "uv-build>=0.12.13,<0.
|
|
3
|
+
requires = [ "uv-build>=0.12.13,<0.14" ]
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agent-discogs"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Token-efficient Discogs CLI for AI agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [ "ai-agent", "cli", "discogs", "discogs-api", "music-database" ]
|
|
@@ -21,7 +21,11 @@ classifiers = [
|
|
|
21
21
|
"Programming Language :: Python :: 3.14",
|
|
22
22
|
"Programming Language :: Python :: 3.15",
|
|
23
23
|
]
|
|
24
|
-
dependencies = [
|
|
24
|
+
dependencies = [
|
|
25
|
+
"click>=8.3.1",
|
|
26
|
+
"discogs-sdk>=0.8.1",
|
|
27
|
+
"pydantic>=2.12.5",
|
|
28
|
+
]
|
|
25
29
|
urls.Homepage = "https://github.com/jmfontaine/agent-discogs"
|
|
26
30
|
urls.Issues = "https://github.com/jmfontaine/agent-discogs/issues"
|
|
27
31
|
urls.Repository = "https://github.com/jmfontaine/agent-discogs"
|
|
@@ -30,6 +34,7 @@ scripts.agent-discogs = "agent_discogs:main"
|
|
|
30
34
|
[dependency-groups]
|
|
31
35
|
dev = [
|
|
32
36
|
"deptry>=0.24",
|
|
37
|
+
"pre-commit>=4.6.2",
|
|
33
38
|
"pyproject-fmt>=2.16.1",
|
|
34
39
|
"pyright>=1.1.408",
|
|
35
40
|
"ruff>=0.15.2",
|
|
@@ -90,7 +95,6 @@ lint.select = [
|
|
|
90
95
|
lint.ignore = [
|
|
91
96
|
"EM101", # raw-string-in-exception - the test doubles that raise use one-off literals; naming them first adds a line and no clarity
|
|
92
97
|
"EM102", # f-string-in-exception - refs.py and get.py interpolate the offending ref or noun, which is what makes the message actionable
|
|
93
|
-
"PLC0415", # import-outside-top-level - errors.py and __init__.py import discogs_sdk lazily so --help and --version never pay to load it
|
|
94
98
|
"PLR0911", # too-many-return-statements - format_error() returns one tailored message per SDK exception type
|
|
95
99
|
"PLR0912", # too-many-branches - verbose release output walks a long list of independently optional Discogs fields
|
|
96
100
|
"PLR0913", # too-many-arguments - click hands every command option to the callback as its own keyword argument
|
|
@@ -102,12 +106,11 @@ lint.ignore = [
|
|
|
102
106
|
"TRY003", # raise-vanilla-args - these messages are read by agents, so they belong at the raise site rather than in an exception subclass
|
|
103
107
|
]
|
|
104
108
|
lint.per-file-ignores."tests/**" = [
|
|
105
|
-
"ARG001", # unused-function-argument - the fake _send() in test_pagination.py must accept params= because fetch_page passes it by keyword, then ignores it
|
|
106
109
|
"ARG005", # unused-lambda-argument - the SimpleNamespace lambdas standing in for SDK methods take the real signature and use only part of it
|
|
107
110
|
"PLR2004", # magic-value-comparison - assertions compare against literal Discogs IDs and counts, which read better inline than as named constants
|
|
108
111
|
"S101", # assert - pytest expresses every assertion this way
|
|
109
112
|
"S108", # hardcoded-temp-file - test_formatting.py only formats /tmp/test-cache into the status output; nothing is created or written there
|
|
110
|
-
"SLF001", # private-member-access -
|
|
113
|
+
"SLF001", # private-member-access - conftest.py's real_sdk resets the module-level client._client singleton, and tests read private state such as trace._trace
|
|
111
114
|
]
|
|
112
115
|
|
|
113
116
|
[tool.pyproject-fmt]
|
|
@@ -120,13 +123,27 @@ ini_options.markers = [
|
|
|
120
123
|
"live: hits the real Discogs API; run with `just test-live` (needs DISCOGS_TOKEN)",
|
|
121
124
|
]
|
|
122
125
|
|
|
126
|
+
# Line coverage only. Branch coverage would fail fail_under today on partial
|
|
127
|
+
# branches in cache.py (#18), formatting.py and projections.py.
|
|
128
|
+
[tool.coverage]
|
|
129
|
+
# Only the package: this also keeps out the test modules pytester writes under
|
|
130
|
+
# the basetemp, which its in-process runs would otherwise add to the report.
|
|
131
|
+
run.source = [ "agent_discogs" ]
|
|
132
|
+
report.fail_under = 100
|
|
133
|
+
|
|
123
134
|
[tool.deadcode]
|
|
124
135
|
ignore-names = [
|
|
136
|
+
"_color_terminal",
|
|
137
|
+
"_fake_api",
|
|
138
|
+
"_isolate_env",
|
|
139
|
+
"_patch_clients",
|
|
125
140
|
"_patch_get",
|
|
126
141
|
"_patch_search",
|
|
127
142
|
"_reset_singleton",
|
|
143
|
+
"_real_client",
|
|
128
144
|
"_scoped_client",
|
|
129
145
|
"format_help",
|
|
130
146
|
"get_skill", # click subcommands are registered by decorator, invisible to deadcode
|
|
147
|
+
"pytest_plugins", # pytest reads it from conftest.py, invisible to deadcode
|
|
131
148
|
"skill_path",
|
|
132
149
|
]
|