pkgq 0.1.0__py3-none-any.whl

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.
pkgq/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ """
2
+ pkgq - Package Query
3
+
4
+ Find API information for Python packages.
5
+ """
6
+
7
+ __version__ = "0.1.0"
8
+
9
+ from pkgq.find import FindResult, find
10
+
11
+ __all__ = ["find", "FindResult"]
pkgq/cli.py ADDED
@@ -0,0 +1,155 @@
1
+ """
2
+ pkgq CLI - Command line interface for package query.
3
+ """
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from rich.console import Console
11
+ from rich.markdown import Markdown
12
+
13
+ from pkgq import find
14
+ from pkgq.find import get_cache_dir
15
+
16
+
17
+ def main():
18
+ """Main CLI entry point."""
19
+ parser = argparse.ArgumentParser(
20
+ prog="pkgq",
21
+ description="Package Query - Find API information for Python packages",
22
+ )
23
+ subparsers = parser.add_subparsers(dest="command", help="Commands")
24
+
25
+ # find command
26
+ find_parser = subparsers.add_parser("find", help="Find package documentation")
27
+ find_parser.add_argument("package", help="Package name")
28
+ find_parser.add_argument(
29
+ "--version", "-v", help="Desired version (default: latest)"
30
+ )
31
+ find_parser.add_argument(
32
+ "--from-version", "-f", help="Current cached version (for update check)"
33
+ )
34
+ find_parser.add_argument(
35
+ "--cache-dir", "-c", type=Path, help="Cache directory"
36
+ )
37
+ find_parser.add_argument(
38
+ "--save", "-s", action="store_true", help="Save to cache"
39
+ )
40
+ find_parser.add_argument(
41
+ "--json", "-j", action="store_true", help="Output as JSON"
42
+ )
43
+ find_parser.add_argument(
44
+ "--verbose", "-V", action="store_true", help="Verbose output"
45
+ )
46
+
47
+ # cache command
48
+ cache_parser = subparsers.add_parser("cache", help="Manage cache")
49
+ cache_parser.add_argument(
50
+ "--clear", action="store_true", help="Clear cache"
51
+ )
52
+ cache_parser.add_argument(
53
+ "--list", action="store_true", help="List cached packages"
54
+ )
55
+ cache_parser.add_argument(
56
+ "--dir", action="store_true", help="Show cache directory"
57
+ )
58
+
59
+ args = parser.parse_args()
60
+
61
+ if args.command == "find":
62
+ cmd_find(args)
63
+ elif args.command == "cache":
64
+ cmd_cache(args)
65
+ else:
66
+ parser.print_help()
67
+ sys.exit(1)
68
+
69
+
70
+ def cmd_find(args):
71
+ """Handle find command."""
72
+ console = Console()
73
+
74
+ try:
75
+ result = find(
76
+ package=args.package,
77
+ version=args.version,
78
+ from_version=args.from_version,
79
+ cache_dir=args.cache_dir,
80
+ verbose=args.verbose,
81
+ )
82
+
83
+ if args.save:
84
+ cache_path = result.save_to_cache(args.cache_dir)
85
+ console.print(f"[green]Saved to:[/green] {cache_path}")
86
+
87
+ if args.json:
88
+ print(json.dumps(result.to_dict(), indent=2))
89
+ else:
90
+ # Print version info
91
+ status = "[green]cached[/green]" if result.cached else "[blue]fetched[/blue]"
92
+ console.print(f"[bold]{result.package}[/bold] {result.version} ({status})")
93
+ console.print(f"[dim]Source: {result.source}[/dim]")
94
+ console.print()
95
+
96
+ # Print content as markdown
97
+ md = Markdown(result.content)
98
+ console.print(md)
99
+
100
+ except Exception as e:
101
+ console.print(f"[red]Error:[/red] {e}")
102
+ sys.exit(1)
103
+
104
+
105
+ def cmd_cache(args):
106
+ """Handle cache command."""
107
+ console = Console()
108
+ cache_dir = get_cache_dir()
109
+
110
+ if args.dir:
111
+ console.print(str(cache_dir))
112
+ return
113
+
114
+ if args.clear:
115
+ import shutil
116
+ if cache_dir.exists():
117
+ shutil.rmtree(cache_dir)
118
+ console.print(f"[green]Cleared cache:[/green] {cache_dir}")
119
+ else:
120
+ console.print("[yellow]Cache is empty[/yellow]")
121
+ return
122
+
123
+ if args.list:
124
+ if not cache_dir.exists():
125
+ console.print("[yellow]Cache is empty[/yellow]")
126
+ return
127
+
128
+ packages = sorted(cache_dir.iterdir())
129
+ if not packages:
130
+ console.print("[yellow]Cache is empty[/yellow]")
131
+ return
132
+
133
+ console.print(f"[bold]Cached packages ({len(packages)}):[/bold]")
134
+ for pkg_dir in packages:
135
+ metadata_file = pkg_dir / "metadata.json"
136
+ if metadata_file.exists():
137
+ metadata = json.loads(metadata_file.read_text())
138
+ version = metadata.get("version", "?")
139
+ source = metadata.get("source", "?")
140
+ console.print(f" {pkg_dir.name} {version} ({source})")
141
+ else:
142
+ console.print(f" {pkg_dir.name} (no metadata)")
143
+ return
144
+
145
+ # Default: show cache info
146
+ console.print(f"Cache directory: {cache_dir}")
147
+ if cache_dir.exists():
148
+ packages = list(cache_dir.iterdir())
149
+ console.print(f"Cached packages: {len(packages)}")
150
+ else:
151
+ console.print("Cache is empty")
152
+
153
+
154
+ if __name__ == "__main__":
155
+ main()
pkgq/find.py ADDED
@@ -0,0 +1,352 @@
1
+ """
2
+ Package Query - Find package documentation.
3
+
4
+ This module provides the find() function to query Python package information
5
+ from various sources (GitHub, PyPI, etc.).
6
+ """
7
+
8
+ import json
9
+ import os
10
+ from dataclasses import dataclass
11
+ from pathlib import Path
12
+
13
+ import httpx
14
+
15
+
16
+ @dataclass
17
+ class FindResult:
18
+ """Result of a package find operation."""
19
+
20
+ package: str
21
+ version: str
22
+ source: str
23
+ content: str
24
+ cached: bool = False
25
+
26
+ def to_dict(self) -> dict:
27
+ """Convert to dictionary."""
28
+ return {
29
+ "package": self.package,
30
+ "version": self.version,
31
+ "source": self.source,
32
+ "content": self.content,
33
+ "cached": self.cached,
34
+ }
35
+
36
+ def save_to_cache(self, cache_dir: Path | None = None) -> Path:
37
+ """Save result to cache directory."""
38
+ if cache_dir is None:
39
+ cache_dir = get_cache_dir()
40
+
41
+ package_dir = cache_dir / self.package
42
+ package_dir.mkdir(parents=True, exist_ok=True)
43
+
44
+ # Save PACKAGE.md
45
+ package_file = package_dir / "PACKAGE.md"
46
+ package_file.write_text(self.content)
47
+
48
+ # Save metadata
49
+ metadata = {
50
+ "package": self.package,
51
+ "version": self.version,
52
+ "source": self.source,
53
+ "cached": True,
54
+ }
55
+ metadata_file = package_dir / "metadata.json"
56
+ metadata_file.write_text(json.dumps(metadata, indent=2))
57
+
58
+ return package_dir
59
+
60
+
61
+ def get_cache_dir() -> Path:
62
+ """Get the cache directory for package information."""
63
+ # Check environment variable first
64
+ cache_env = os.environ.get("PKGQ_CACHE")
65
+ if cache_env:
66
+ return Path(cache_env)
67
+
68
+ # Default to ~/.cache/pkgq/packages
69
+ cache_dir = Path.home() / ".cache" / "pkgq" / "packages"
70
+ cache_dir.mkdir(parents=True, exist_ok=True)
71
+ return cache_dir
72
+
73
+
74
+ def check_cached(package: str, cache_dir: Path | None = None) -> FindResult | None:
75
+ """Check if package is cached locally.
76
+
77
+ Args:
78
+ package: Package name
79
+ cache_dir: Cache directory (default: ~/.cache/pkgq/packages)
80
+
81
+ Returns:
82
+ FindResult if cached, None if not
83
+ """
84
+ if cache_dir is None:
85
+ cache_dir = get_cache_dir()
86
+
87
+ package_dir = cache_dir / package
88
+ package_file = package_dir / "PACKAGE.md"
89
+ metadata_file = package_dir / "metadata.json"
90
+
91
+ if not package_file.exists():
92
+ return None
93
+
94
+ if not metadata_file.exists():
95
+ return None
96
+
97
+ try:
98
+ metadata = json.loads(metadata_file.read_text())
99
+ content = package_file.read_text()
100
+
101
+ return FindResult(
102
+ package=metadata["package"],
103
+ version=metadata["version"],
104
+ source=metadata["source"],
105
+ content=content,
106
+ cached=True,
107
+ )
108
+ except (json.JSONDecodeError, KeyError):
109
+ return None
110
+
111
+
112
+ def get_pypi_info(package: str) -> dict:
113
+ """Get package info from PyPI.
114
+
115
+ Args:
116
+ package: Package name
117
+
118
+ Returns:
119
+ Package metadata from PyPI
120
+ """
121
+ url = f"https://pypi.org/pypi/{package}/json"
122
+
123
+ with httpx.Client() as client:
124
+ response = client.get(url)
125
+ response.raise_for_status()
126
+ return response.json()
127
+
128
+
129
+ def extract_github_url(pypi_info: dict) -> str | None:
130
+ """Extract GitHub URL from PyPI info.
131
+
132
+ Args:
133
+ pypi_info: PyPI package info
134
+
135
+ Returns:
136
+ GitHub URL or None
137
+ """
138
+ info = pypi_info.get("info", {})
139
+ project_urls = info.get("project_urls") or {}
140
+
141
+ # Check project_urls for GitHub
142
+ for _key, url in project_urls.items():
143
+ if "github.com" in url.lower():
144
+ return url
145
+
146
+ # Check home_page
147
+ home_page = info.get("home_page", "")
148
+ if "github.com" in home_page.lower():
149
+ return home_page
150
+
151
+ return None
152
+
153
+
154
+ def parse_github_url(url: str) -> tuple[str, str]:
155
+ """Parse GitHub URL to owner and repo.
156
+
157
+ Args:
158
+ url: GitHub URL
159
+
160
+ Returns:
161
+ Tuple of (owner, repo)
162
+ """
163
+ # Handle various GitHub URL formats
164
+ # https://github.com/owner/repo
165
+ # https://github.com/owner/repo.git
166
+ # https://github.com/owner/repo/
167
+ # https://github.com/owner/repo#readme
168
+
169
+ # Remove URL fragment (e.g., #readme)
170
+ if "#" in url:
171
+ url = url.split("#")[0]
172
+
173
+ url = url.rstrip("/")
174
+ if url.endswith(".git"):
175
+ url = url[:-4]
176
+
177
+ parts = url.split("/")
178
+ if len(parts) >= 5 and "github.com" in parts[2]:
179
+ return parts[3], parts[4]
180
+
181
+ raise ValueError(f"Invalid GitHub URL: {url}")
182
+
183
+
184
+ def fetch_package_md_from_github(
185
+ owner: str, repo: str, branch: str = "main"
186
+ ) -> str | None:
187
+ """Fetch PACKAGE.md from GitHub repository.
188
+
189
+ Args:
190
+ owner: Repository owner
191
+ repo: Repository name
192
+ branch: Branch name (default: main)
193
+
194
+ Returns:
195
+ PACKAGE.md content or None
196
+ """
197
+ url = f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}/PACKAGE.md"
198
+
199
+ with httpx.Client() as client:
200
+ response = client.get(url)
201
+ if response.status_code == 200:
202
+ return response.text
203
+ return None
204
+
205
+
206
+ def get_default_branch(owner: str, repo: str) -> str:
207
+ """Get default branch from GitHub API.
208
+
209
+ Args:
210
+ owner: Repository owner
211
+ repo: Repository name
212
+
213
+ Returns:
214
+ Default branch name
215
+ """
216
+ url = f"https://api.github.com/repos/{owner}/{repo}"
217
+
218
+ with httpx.Client() as client:
219
+ response = client.get(url)
220
+ if response.status_code == 200:
221
+ data = response.json()
222
+ return data.get("default_branch", "main")
223
+ return "main"
224
+
225
+
226
+ def find(
227
+ package: str,
228
+ version: str | None = None,
229
+ from_version: str | None = None,
230
+ cache_dir: Path | None = None,
231
+ verbose: bool = False,
232
+ ) -> FindResult:
233
+ """Find package documentation.
234
+
235
+ Queries multiple sources in order:
236
+ 1. Local cache (if from_version is provided)
237
+ 2. GitHub repository (PACKAGE.md)
238
+ 3. Generate from PyPI docs
239
+
240
+ Args:
241
+ package: Package name
242
+ version: Desired version (default: latest)
243
+ from_version: Current cached version (for update check)
244
+ cache_dir: Cache directory (default: ~/.cache/pkgq/packages)
245
+ verbose: Print source information during lookup
246
+
247
+ Returns:
248
+ FindResult with package information
249
+
250
+ Raises:
251
+ ValueError: If package not found
252
+ """
253
+ if cache_dir is None:
254
+ cache_dir = get_cache_dir()
255
+
256
+ # Step 1: Check local cache
257
+ cached = check_cached(package, cache_dir)
258
+ if cached and from_version:
259
+ # Check if we need to update
260
+ if cached.version == from_version:
261
+ # Same version, return cached
262
+ return cached
263
+ # Different version, need to fetch
264
+ elif cached and not from_version:
265
+ # No version specified, use cached
266
+ return cached
267
+
268
+ # Step 2: Get PyPI info
269
+ pypi_info = get_pypi_info(package)
270
+ info = pypi_info.get("info", {})
271
+ latest_version = info.get("version", "unknown")
272
+
273
+ if version is None:
274
+ version = latest_version
275
+
276
+ # Step 3: Try GitHub
277
+ github_url = extract_github_url(pypi_info)
278
+ github_error = None
279
+ if github_url:
280
+ try:
281
+ owner, repo = parse_github_url(github_url)
282
+ default_branch = get_default_branch(owner, repo)
283
+
284
+ # Try common branches
285
+ branches_tried = []
286
+ for branch in [default_branch, "main", "master"]:
287
+ if branch in branches_tried:
288
+ continue
289
+ branches_tried.append(branch)
290
+ content = fetch_package_md_from_github(owner, repo, branch)
291
+ if content:
292
+ if verbose:
293
+ print(f"Found PACKAGE.md on GitHub ({owner}/{repo}, branch: {branch})")
294
+ return FindResult(
295
+ package=package,
296
+ version=version,
297
+ source=f"github:{owner}/{repo}",
298
+ content=content,
299
+ cached=False,
300
+ )
301
+
302
+ # GitHub URL found but no PACKAGE.md in any branch
303
+ github_error = f"GitHub repo found ({owner}/{repo}) but no PACKAGE.md found in branches: {', '.join(branches_tried)}"
304
+ except ValueError as e:
305
+ github_error = f"Invalid GitHub URL: {e}"
306
+
307
+ # Step 4: Generate basic info from PyPI
308
+ if verbose and github_error:
309
+ print(f"Warning: {github_error}")
310
+ print("Falling back to PyPI-generated documentation")
311
+
312
+ summary = info.get("summary", "No summary available")
313
+ author = info.get("author", "Unknown")
314
+ home_page = info.get("home_page", "")
315
+ project_urls = info.get("project_urls") or {}
316
+
317
+ content = f"""# {package}
318
+
319
+ > {summary}
320
+
321
+ ## Overview
322
+
323
+ Package: **{package}**
324
+ Version: **{version}**
325
+ Author: **{author}**
326
+
327
+ ## Installation
328
+
329
+ ```
330
+ pip install {package}
331
+ ```
332
+
333
+ ## References
334
+
335
+ """
336
+
337
+ if home_page:
338
+ content += f"- Homepage: {home_page}\n"
339
+
340
+ for key, url in project_urls.items():
341
+ content += f"- {key}: {url}\n"
342
+
343
+ if github_error:
344
+ content += f"\n---\n\n_Note: {github_error}_\n"
345
+
346
+ return FindResult(
347
+ package=package,
348
+ version=version,
349
+ source="pypi",
350
+ content=content,
351
+ cached=False,
352
+ )
pkgq/mcp.py ADDED
@@ -0,0 +1,62 @@
1
+ """
2
+ pkgq MCP Server - Model Context Protocol server for package query.
3
+
4
+ Provides a simple tool to find package documentation.
5
+ """
6
+
7
+ from typing import Annotated
8
+
9
+ from fastmcp import FastMCP
10
+
11
+ from pkgq import find
12
+
13
+ # Create MCP server
14
+ mcp = FastMCP(
15
+ name="pkgq",
16
+ version="0.1.0",
17
+ )
18
+
19
+
20
+ @mcp.tool()
21
+ def find_package(
22
+ package: Annotated[str, "Package name to find"],
23
+ version: Annotated[str | None, "Desired version (default: latest)"] = None,
24
+ from_version: Annotated[str | None, "Current cached version (for update check)"] = None,
25
+ ) -> str:
26
+ """Find package documentation.
27
+
28
+ Queries multiple sources in order:
29
+ 1. Local cache (if from_version is provided)
30
+ 2. GitHub repository (PACKAGE.md)
31
+ 3. Generate from PyPI docs
32
+
33
+ Args:
34
+ package: Package name (e.g., "yoker", "httpx")
35
+ version: Desired version (default: latest)
36
+ from_version: Current cached version (for update check)
37
+
38
+ Returns:
39
+ Package documentation in PACKAGE.md format
40
+ """
41
+ result = find(
42
+ package=package,
43
+ version=version,
44
+ from_version=from_version,
45
+ verbose=True, # Include source information
46
+ )
47
+
48
+ # Return formatted result
49
+ status = "cached" if result.cached else "fetched"
50
+ header = f"# {result.package} (v{result.version}) [{status}]\n\n"
51
+ header += f"Source: {result.source}\n\n---\n\n"
52
+
53
+ return header + result.content
54
+
55
+
56
+ def run():
57
+ """Run the MCP server."""
58
+ mcp.run()
59
+
60
+
61
+ if __name__ == "__main__":
62
+ run()
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: pkgq
3
+ Version: 0.1.0
4
+ Summary: Package Query - Find API information for Python packages
5
+ Project-URL: Homepage, https://github.com/christophevg/pkgq
6
+ Project-URL: Documentation, https://github.com/christophevg/pkgq#readme
7
+ Project-URL: Repository, https://github.com/christophevg/pkgq
8
+ Project-URL: Issues, https://github.com/christophevg/pkgq/issues
9
+ Author-email: Christophe VG <contact@christophe.vg>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: agent,api,documentation,mcp,package,query
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: httpx>=0.27.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Requires-Dist: rich>=13.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: build>=1.0.0; extra == 'dev'
27
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
32
+ Requires-Dist: twine>=6.0.0; extra == 'dev'
33
+ Provides-Extra: mcp
34
+ Requires-Dist: fastmcp>=3.0.0; extra == 'mcp'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # pkgq
38
+
39
+ **PacKaGe Query** - Find API information for Python packages.
40
+
41
+ A fast, agent-friendly tool for discovering Python package documentation, capabilities, and migration guides.
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ # Install with uv
47
+ uv add pkgq
48
+
49
+ # Or with pip
50
+ pip install pkgq
51
+
52
+ # For MCP server support
53
+ uv add "pkgq[mcp]"
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ### Python Module
59
+
60
+ ```python
61
+ from pkgq import find
62
+
63
+ # Find package documentation
64
+ result = find("yoker")
65
+ print(result.content)
66
+
67
+ # Find specific version
68
+ result = find("yoker", version="2.1.0")
69
+
70
+ # Check for updates
71
+ result = find("yoker", from_version="1.5.0")
72
+ if result.version != "1.5.0":
73
+ print(f"Update available: {result.version}")
74
+
75
+ # Save to cache
76
+ result.save_to_cache()
77
+ ```
78
+
79
+ ### Command Line
80
+
81
+ ```bash
82
+ # Find package documentation
83
+ pkgq find yoker
84
+
85
+ # Find specific version
86
+ pkgq find yoker --version 2.1.0
87
+
88
+ # Check for updates
89
+ pkgq find yoker --from-version 1.5.0
90
+
91
+ # Save to cache
92
+ pkgq find yoker --save
93
+
94
+ # Output as JSON
95
+ pkgq find yoker --json
96
+
97
+ # Manage cache
98
+ pkgq cache --list
99
+ pkgq cache --clear
100
+ pkgq cache --dir
101
+ ```
102
+
103
+ ### MCP Server
104
+
105
+ ```bash
106
+ # Run MCP server
107
+ pkgq-mcp-server
108
+
109
+ # Or with uvx
110
+ uvx --from pkgq pkgq-mcp-server
111
+ ```
112
+
113
+ The MCP server provides a `find_package` tool for use with Claude Code and other MCP-compatible agents.
114
+
115
+ ## Cache
116
+
117
+ Package documentation is cached locally:
118
+
119
+ - Default: `~/.cache/pkgq/packages/`
120
+ - Custom: Set `PKGQ_CACHE` environment variable
121
+
122
+ Cache structure:
123
+ ```
124
+ ~/.cache/pkgq/packages/
125
+ ├── yoker/
126
+ │ ├── PACKAGE.md # Package documentation
127
+ │ └── metadata.json # Version and source info
128
+ └── roomz/
129
+ ├── PACKAGE.md
130
+ └── metadata.json
131
+ ```
132
+
133
+ ## Development
134
+
135
+ ```bash
136
+ # Clone repository
137
+ git clone https://github.com/christophevg/pkgq.git
138
+ cd pkgq
139
+
140
+ # Install dependencies
141
+ uv sync
142
+
143
+ # Run tests
144
+ uv run pytest
145
+
146
+ # Run linter
147
+ uv run ruff check src/
148
+
149
+ # Run MCP server
150
+ uv run pkgq-mcp-server
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT License - See [LICENSE](LICENSE) for details.
@@ -0,0 +1,9 @@
1
+ pkgq/__init__.py,sha256=FJDbnF5gs_AsA7LJCsE_h__9mm2g-kVFF9bAs0iTMZ0,169
2
+ pkgq/cli.py,sha256=_Y_VlbV9lXsKH_zylnmFJM7WGGRIQeuodttP8FRe0ro,4564
3
+ pkgq/find.py,sha256=IFdJdx2p5cfVcQLMVhe30XbN7jvQnFnjf71b5JEzmA4,9275
4
+ pkgq/mcp.py,sha256=p52Yjfzjly4ARClnHW6hBlNki7k4W5JnEF8zU5oO9Yw,1504
5
+ pkgq-0.1.0.dist-info/METADATA,sha256=HdOAYUMY3kWKG2y3FKWt-EaDLysva4dVQ5pHrtIRhxY,3412
6
+ pkgq-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
7
+ pkgq-0.1.0.dist-info/entry_points.txt,sha256=Cist7pDtF1CXo6fgRc0DgHmESMzXD6POYLGlVT8BqZY,70
8
+ pkgq-0.1.0.dist-info/licenses/LICENSE,sha256=fbkavbRGILRFIQKDzdgC-IO9QoSUQ7eNvQcqA6L1cBU,1069
9
+ pkgq-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ pkgq = pkgq.cli:main
3
+ pkgq-mcp-server = pkgq.mcp:run
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Christophe VG
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.