promptmint 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.
- promptmint/__init__.py +3 -0
- promptmint/cli.py +73 -0
- promptmint/models.py +17 -0
- promptmint/renderer.py +59 -0
- promptmint/scanner.py +206 -0
- promptmint/tokens.py +9 -0
- promptmint-0.1.0.dist-info/METADATA +127 -0
- promptmint-0.1.0.dist-info/RECORD +12 -0
- promptmint-0.1.0.dist-info/WHEEL +5 -0
- promptmint-0.1.0.dist-info/entry_points.txt +2 -0
- promptmint-0.1.0.dist-info/licenses/LICENSE +21 -0
- promptmint-0.1.0.dist-info/top_level.txt +1 -0
promptmint/__init__.py
ADDED
promptmint/cli.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from .renderer import MODE_REQUESTS, render_context_pack
|
|
10
|
+
from .scanner import scan_project
|
|
11
|
+
from .tokens import estimate_tokens
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
15
|
+
parser = argparse.ArgumentParser(
|
|
16
|
+
prog="promptmint",
|
|
17
|
+
description="Turn any codebase into an AI-ready Markdown prompt pack.",
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument("path", nargs="?", default=".", help="Project directory to scan")
|
|
20
|
+
parser.add_argument("-g", "--goal", default=None, help="Task goal to include in the prompt")
|
|
21
|
+
parser.add_argument("-m", "--mode", choices=sorted(MODE_REQUESTS), default="debug", help="Prompt mode")
|
|
22
|
+
parser.add_argument("-e", "--error", dest="error_file", help="Path to an error log to include")
|
|
23
|
+
parser.add_argument("-i", "--include", action="append", default=[], help="Glob to include; can be repeated")
|
|
24
|
+
parser.add_argument("-x", "--exclude", action="append", default=[], help="Glob to exclude; can be repeated")
|
|
25
|
+
parser.add_argument("-o", "--output", default="promptmint-output.md", help="Output Markdown file")
|
|
26
|
+
parser.add_argument("-c", "--copy", action="store_true", help="Copy output to clipboard if a clipboard tool is available")
|
|
27
|
+
parser.add_argument("-s", "--max-file-bytes", type=int, default=50_000, help="Skip files larger than this size")
|
|
28
|
+
return parser
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def main(argv: list[str] | None = None) -> int:
|
|
32
|
+
args = build_parser().parse_args(argv)
|
|
33
|
+
root = Path(args.path).resolve()
|
|
34
|
+
error_log = None
|
|
35
|
+
if args.error_file:
|
|
36
|
+
error_log = Path(args.error_file).read_text(encoding="utf-8", errors="replace")
|
|
37
|
+
|
|
38
|
+
scan = scan_project(
|
|
39
|
+
root,
|
|
40
|
+
include=args.include,
|
|
41
|
+
exclude=args.exclude,
|
|
42
|
+
max_file_bytes=args.max_file_bytes,
|
|
43
|
+
)
|
|
44
|
+
output = render_context_pack(scan, goal=args.goal, mode=args.mode, error_log=error_log)
|
|
45
|
+
output_path = Path(args.output).resolve()
|
|
46
|
+
output_path.write_text(output, encoding="utf-8")
|
|
47
|
+
|
|
48
|
+
if args.copy:
|
|
49
|
+
_copy_to_clipboard(output)
|
|
50
|
+
|
|
51
|
+
print(f"Created: {output_path}")
|
|
52
|
+
print(f"Tokens estimate: {estimate_tokens(output):,}")
|
|
53
|
+
print(f"Files included: {len(scan.files)}")
|
|
54
|
+
return 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _copy_to_clipboard(text: str) -> None:
|
|
58
|
+
commands = [
|
|
59
|
+
(["pbcopy"], None),
|
|
60
|
+
(["xclip", "-selection", "clipboard"], None),
|
|
61
|
+
(["xsel", "--clipboard", "--input"], None),
|
|
62
|
+
(["wl-copy"], None),
|
|
63
|
+
]
|
|
64
|
+
for command, _ in commands:
|
|
65
|
+
if shutil.which(command[0]):
|
|
66
|
+
subprocess.run(command, input=text, text=True, check=False)
|
|
67
|
+
print("Copied to clipboard")
|
|
68
|
+
return
|
|
69
|
+
print("Clipboard tool not found; install pbcopy, xclip, xsel, or wl-copy.", file=sys.stderr)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
raise SystemExit(main())
|
promptmint/models.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass(frozen=True)
|
|
5
|
+
class ProjectFile:
|
|
6
|
+
relative_path: str
|
|
7
|
+
language: str
|
|
8
|
+
content: str
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class ScanResult:
|
|
13
|
+
root: str
|
|
14
|
+
tree: str
|
|
15
|
+
files: list[ProjectFile] = field(default_factory=list)
|
|
16
|
+
dependency_files: list[ProjectFile] = field(default_factory=list)
|
|
17
|
+
git_diff: str = ""
|
promptmint/renderer.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .models import ProjectFile, ScanResult
|
|
4
|
+
|
|
5
|
+
MODE_REQUESTS = {
|
|
6
|
+
"debug": "Please find the root cause, explain it briefly, and suggest the smallest safe fix.",
|
|
7
|
+
"review": "Please review this code for bugs, security issues, performance, and maintainability.",
|
|
8
|
+
"explain": "Please explain how this project works, focusing on the included files.",
|
|
9
|
+
"refactor": "Please suggest a safe refactor plan and identify the smallest first change.",
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def render_context_pack(
|
|
14
|
+
scan: ScanResult,
|
|
15
|
+
goal: str | None = None,
|
|
16
|
+
mode: str = "debug",
|
|
17
|
+
error_log: str | None = None,
|
|
18
|
+
) -> str:
|
|
19
|
+
mode = mode if mode in MODE_REQUESTS else "debug"
|
|
20
|
+
sections = ["# Project Context Pack", ""]
|
|
21
|
+
sections.extend(["## Goal", goal or "Analyze this project context and help with the task.", ""])
|
|
22
|
+
sections.extend([f"## {mode.title()} Request", MODE_REQUESTS[mode], ""])
|
|
23
|
+
sections.extend(["## Project Root", f"`{scan.root}`", ""])
|
|
24
|
+
sections.extend(["## Project Tree", "```text", scan.tree or "(empty)", "```", ""])
|
|
25
|
+
|
|
26
|
+
if scan.dependency_files:
|
|
27
|
+
sections.append("## Dependency / Manifest Files")
|
|
28
|
+
sections.append("")
|
|
29
|
+
for file in scan.dependency_files:
|
|
30
|
+
sections.extend(_render_file(file))
|
|
31
|
+
|
|
32
|
+
if scan.git_diff:
|
|
33
|
+
sections.extend(["## Git Diff", "```diff", scan.git_diff, "```", ""])
|
|
34
|
+
|
|
35
|
+
relevant_files = [
|
|
36
|
+
file for file in scan.files
|
|
37
|
+
if all(file.relative_path != dep.relative_path for dep in scan.dependency_files)
|
|
38
|
+
]
|
|
39
|
+
if relevant_files:
|
|
40
|
+
sections.append("## Relevant Files")
|
|
41
|
+
sections.append("")
|
|
42
|
+
for file in relevant_files:
|
|
43
|
+
sections.extend(_render_file(file))
|
|
44
|
+
|
|
45
|
+
if error_log:
|
|
46
|
+
sections.extend(["## Error Log", "```text", error_log.strip(), "```", ""])
|
|
47
|
+
|
|
48
|
+
sections.extend(["## Final Instruction", MODE_REQUESTS[mode], ""])
|
|
49
|
+
return "\n".join(sections).rstrip() + "\n"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _render_file(file: ProjectFile) -> list[str]:
|
|
53
|
+
return [
|
|
54
|
+
f"### `{file.relative_path}`",
|
|
55
|
+
f"```{file.language}",
|
|
56
|
+
file.content.rstrip(),
|
|
57
|
+
"```",
|
|
58
|
+
"",
|
|
59
|
+
]
|
promptmint/scanner.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import fnmatch
|
|
4
|
+
import subprocess
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from .models import ProjectFile, ScanResult
|
|
8
|
+
|
|
9
|
+
DEFAULT_EXCLUDED_DIRS = {
|
|
10
|
+
".git",
|
|
11
|
+
".hg",
|
|
12
|
+
".svn",
|
|
13
|
+
".idea",
|
|
14
|
+
".vscode",
|
|
15
|
+
"__pycache__",
|
|
16
|
+
".pytest_cache",
|
|
17
|
+
".mypy_cache",
|
|
18
|
+
".ruff_cache",
|
|
19
|
+
"node_modules",
|
|
20
|
+
"vendor",
|
|
21
|
+
"dist",
|
|
22
|
+
"build",
|
|
23
|
+
"target",
|
|
24
|
+
".next",
|
|
25
|
+
".nuxt",
|
|
26
|
+
".venv",
|
|
27
|
+
"venv",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
DEFAULT_EXCLUDED_FILES = {
|
|
31
|
+
".env",
|
|
32
|
+
".env.local",
|
|
33
|
+
".env.production",
|
|
34
|
+
".DS_Store",
|
|
35
|
+
"promptmint-output.md",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
DEPENDENCY_FILES = {
|
|
39
|
+
"package.json",
|
|
40
|
+
"pnpm-lock.yaml",
|
|
41
|
+
"yarn.lock",
|
|
42
|
+
"package-lock.json",
|
|
43
|
+
"requirements.txt",
|
|
44
|
+
"pyproject.toml",
|
|
45
|
+
"poetry.lock",
|
|
46
|
+
"Pipfile",
|
|
47
|
+
"composer.json",
|
|
48
|
+
"composer.lock",
|
|
49
|
+
"go.mod",
|
|
50
|
+
"go.sum",
|
|
51
|
+
"Cargo.toml",
|
|
52
|
+
"Cargo.lock",
|
|
53
|
+
"pubspec.yaml",
|
|
54
|
+
"pubspec.lock",
|
|
55
|
+
"Dockerfile",
|
|
56
|
+
"docker-compose.yml",
|
|
57
|
+
"docker-compose.yaml",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
LANGUAGE_BY_SUFFIX = {
|
|
61
|
+
".py": "python",
|
|
62
|
+
".js": "javascript",
|
|
63
|
+
".jsx": "jsx",
|
|
64
|
+
".ts": "typescript",
|
|
65
|
+
".tsx": "tsx",
|
|
66
|
+
".go": "go",
|
|
67
|
+
".php": "php",
|
|
68
|
+
".dart": "dart",
|
|
69
|
+
".rs": "rust",
|
|
70
|
+
".java": "java",
|
|
71
|
+
".c": "c",
|
|
72
|
+
".h": "c",
|
|
73
|
+
".cpp": "cpp",
|
|
74
|
+
".hpp": "cpp",
|
|
75
|
+
".cs": "csharp",
|
|
76
|
+
".rb": "ruby",
|
|
77
|
+
".sh": "bash",
|
|
78
|
+
".bash": "bash",
|
|
79
|
+
".zsh": "zsh",
|
|
80
|
+
".md": "markdown",
|
|
81
|
+
".json": "json",
|
|
82
|
+
".yaml": "yaml",
|
|
83
|
+
".yml": "yaml",
|
|
84
|
+
".toml": "toml",
|
|
85
|
+
".xml": "xml",
|
|
86
|
+
".html": "html",
|
|
87
|
+
".css": "css",
|
|
88
|
+
".scss": "scss",
|
|
89
|
+
".sql": "sql",
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
TEXT_SUFFIXES = set(LANGUAGE_BY_SUFFIX) | {
|
|
93
|
+
".txt",
|
|
94
|
+
".ini",
|
|
95
|
+
".cfg",
|
|
96
|
+
".conf",
|
|
97
|
+
".gitignore",
|
|
98
|
+
".dockerignore",
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def scan_project(
|
|
103
|
+
root: str | Path,
|
|
104
|
+
include: list[str] | None = None,
|
|
105
|
+
exclude: list[str] | None = None,
|
|
106
|
+
max_file_bytes: int = 50_000,
|
|
107
|
+
) -> ScanResult:
|
|
108
|
+
root_path = Path(root).resolve()
|
|
109
|
+
exclude_patterns = exclude or []
|
|
110
|
+
include_patterns = include or []
|
|
111
|
+
|
|
112
|
+
files: list[ProjectFile] = []
|
|
113
|
+
dependency_files: list[ProjectFile] = []
|
|
114
|
+
tree_paths: list[str] = []
|
|
115
|
+
|
|
116
|
+
for path in sorted(root_path.rglob("*")):
|
|
117
|
+
rel = path.relative_to(root_path).as_posix()
|
|
118
|
+
if _is_excluded(path, rel, root_path, exclude_patterns):
|
|
119
|
+
continue
|
|
120
|
+
if path.is_dir():
|
|
121
|
+
tree_paths.append(rel + "/")
|
|
122
|
+
continue
|
|
123
|
+
if include_patterns and not _matches_any(rel, include_patterns):
|
|
124
|
+
continue
|
|
125
|
+
if not _is_text_file(path):
|
|
126
|
+
continue
|
|
127
|
+
if path.stat().st_size > max_file_bytes:
|
|
128
|
+
continue
|
|
129
|
+
|
|
130
|
+
project_file = ProjectFile(
|
|
131
|
+
relative_path=rel,
|
|
132
|
+
language=_language_for(path),
|
|
133
|
+
content=path.read_text(encoding="utf-8", errors="replace"),
|
|
134
|
+
)
|
|
135
|
+
files.append(project_file)
|
|
136
|
+
if path.name in DEPENDENCY_FILES:
|
|
137
|
+
dependency_files.append(project_file)
|
|
138
|
+
tree_paths.append(rel)
|
|
139
|
+
|
|
140
|
+
return ScanResult(
|
|
141
|
+
root=str(root_path),
|
|
142
|
+
tree=_render_tree(tree_paths),
|
|
143
|
+
files=files,
|
|
144
|
+
dependency_files=dependency_files,
|
|
145
|
+
git_diff=_git_diff(root_path),
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _is_excluded(path: Path, rel: str, root: Path, extra_patterns: list[str]) -> bool:
|
|
150
|
+
parts = set(path.relative_to(root).parts)
|
|
151
|
+
if parts & DEFAULT_EXCLUDED_DIRS:
|
|
152
|
+
return True
|
|
153
|
+
if path.name in DEFAULT_EXCLUDED_FILES:
|
|
154
|
+
return True
|
|
155
|
+
return _matches_any(rel, extra_patterns)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _matches_any(rel: str, patterns: list[str]) -> bool:
|
|
159
|
+
path = Path(rel)
|
|
160
|
+
for pattern in patterns:
|
|
161
|
+
pattern = pattern.strip()
|
|
162
|
+
if not pattern:
|
|
163
|
+
continue
|
|
164
|
+
if fnmatch.fnmatch(rel, pattern) or path.match(pattern):
|
|
165
|
+
return True
|
|
166
|
+
if "**/" in pattern and fnmatch.fnmatch(rel, pattern.replace("**/", "")):
|
|
167
|
+
return True
|
|
168
|
+
return False
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _is_text_file(path: Path) -> bool:
|
|
172
|
+
if path.name in DEPENDENCY_FILES or path.name in {"README", "LICENSE", "Makefile"}:
|
|
173
|
+
return True
|
|
174
|
+
if path.suffix in TEXT_SUFFIXES:
|
|
175
|
+
return True
|
|
176
|
+
try:
|
|
177
|
+
chunk = path.read_bytes()[:1024]
|
|
178
|
+
except OSError:
|
|
179
|
+
return False
|
|
180
|
+
return b"\0" not in chunk and path.suffix == ""
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _language_for(path: Path) -> str:
|
|
184
|
+
if path.name == "Dockerfile":
|
|
185
|
+
return "dockerfile"
|
|
186
|
+
return LANGUAGE_BY_SUFFIX.get(path.suffix, "text")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _render_tree(paths: list[str]) -> str:
|
|
190
|
+
return "\n".join(paths)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _git_diff(root: Path) -> str:
|
|
194
|
+
try:
|
|
195
|
+
result = subprocess.run(
|
|
196
|
+
["git", "diff", "--no-ext-diff"],
|
|
197
|
+
cwd=str(root),
|
|
198
|
+
text=True,
|
|
199
|
+
stdout=subprocess.PIPE,
|
|
200
|
+
stderr=subprocess.DEVNULL,
|
|
201
|
+
timeout=10,
|
|
202
|
+
check=False,
|
|
203
|
+
)
|
|
204
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
205
|
+
return ""
|
|
206
|
+
return result.stdout.strip()
|
promptmint/tokens.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
def estimate_tokens(text: str) -> int:
|
|
2
|
+
"""Return a simple dependency-free token estimate.
|
|
3
|
+
|
|
4
|
+
Most English/code prompts average around 3-5 chars per token. We use 4 and
|
|
5
|
+
round up so the estimate is useful without requiring tiktoken.
|
|
6
|
+
"""
|
|
7
|
+
if not text:
|
|
8
|
+
return 0
|
|
9
|
+
return (len(text) + 3) // 4
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: promptmint
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn any codebase into an AI-ready prompt context pack.
|
|
5
|
+
Author: Asim Awdah
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: ai,prompt,developer-tools,cli,codebase,context
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Topic :: Software Development
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# PromptMint
|
|
21
|
+
|
|
22
|
+
Turn any codebase into an AI-ready prompt.
|
|
23
|
+
|
|
24
|
+
PromptMint scans your project, collects useful source files, dependency manifests, git diff, and optional error logs, then generates a clean Markdown context pack you can paste into ChatGPT, Claude, Gemini, or any coding agent.
|
|
25
|
+
|
|
26
|
+
## Why?
|
|
27
|
+
|
|
28
|
+
Copying files into AI chats is slow and messy. PromptMint gives you one command that creates a structured, safe context file for debugging, code review, refactoring, and project explanation.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install promptmint
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Install locally for development
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/YOUR_USERNAME/promptmint.git
|
|
40
|
+
cd promptmint
|
|
41
|
+
python3 -m pip install -e .
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
promptmint -g "Fix this bug" -m debug
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
promptmint --goal "Review this PR" --mode review --output review-context.md
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
promptmint --goal "Explain this project" --mode explain
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
promptmint -e error.log -m debug -c
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI Shortcuts
|
|
63
|
+
|
|
64
|
+
- `-g`, `--goal`: task goal
|
|
65
|
+
- `-m`, `--mode`: prompt mode
|
|
66
|
+
- `-e`, `--error`: error log file
|
|
67
|
+
- `-i`, `--include`: include glob, repeatable
|
|
68
|
+
- `-x`, `--exclude`: exclude glob, repeatable
|
|
69
|
+
- `-o`, `--output`: output Markdown file
|
|
70
|
+
- `-c`, `--copy`: copy output to clipboard
|
|
71
|
+
- `-s`, `--max-file-bytes`: skip files larger than this size
|
|
72
|
+
|
|
73
|
+
## Modes
|
|
74
|
+
|
|
75
|
+
- `debug`: root cause + smallest safe fix
|
|
76
|
+
- `review`: bugs, security, performance, maintainability
|
|
77
|
+
- `explain`: explain how the project works
|
|
78
|
+
- `refactor`: safe refactor plan
|
|
79
|
+
|
|
80
|
+
## What it includes
|
|
81
|
+
|
|
82
|
+
- Project tree
|
|
83
|
+
- Dependency/manifest files like `package.json`, `pyproject.toml`, `composer.json`, `go.mod`, `pubspec.yaml`
|
|
84
|
+
- Git diff, if available
|
|
85
|
+
- Text source files
|
|
86
|
+
- Optional error log
|
|
87
|
+
- Final instruction tailored to the selected mode
|
|
88
|
+
|
|
89
|
+
## What it ignores by default
|
|
90
|
+
|
|
91
|
+
- `.git`, `node_modules`, `vendor`, `dist`, `build`, virtual environments, caches
|
|
92
|
+
- `.env` files
|
|
93
|
+
- Binary files
|
|
94
|
+
- Large files over 50KB by default
|
|
95
|
+
|
|
96
|
+
## Examples
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
promptmint . --include "src/**/*.py" --goal "Find the bug"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
promptmint . --exclude "tests/fixtures/**" --max-file-bytes 20000
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Development
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
python3 -m unittest discover -s tests -v
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Roadmap
|
|
113
|
+
|
|
114
|
+
- [x] Markdown context pack generator
|
|
115
|
+
- [x] Project tree + file scanner
|
|
116
|
+
- [x] Dependency manifest detection
|
|
117
|
+
- [x] Git diff inclusion
|
|
118
|
+
- [x] Debug/review/explain/refactor modes
|
|
119
|
+
- [ ] Better `.gitignore` support
|
|
120
|
+
- [ ] Token budget smart trimming
|
|
121
|
+
- [ ] Interactive file picker
|
|
122
|
+
- [ ] JSON output
|
|
123
|
+
- [ ] MCP server integration
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
promptmint/__init__.py,sha256=KOUPYVNGNu1kRsZGnOzGS7_zl-6Zy0d6zSXeBJ4OlXk,82
|
|
2
|
+
promptmint/cli.py,sha256=kxvv7DQoBnLDZgzTft9xFZ-1gbxxQNSFoqBm1X3A7g8,2837
|
|
3
|
+
promptmint/models.py,sha256=z8N5Jna4OxRrZerh6FGKvevK8M-VyHXLiBz-ApKGbeU,368
|
|
4
|
+
promptmint/renderer.py,sha256=006E_ddfLgD9x0ebGf4nAJT-mUHRbFA2k8YQQOaF-ms,2125
|
|
5
|
+
promptmint/scanner.py,sha256=fxfwmiH29G9RiTpFYH6k2GCkqVNLCF64H1HgKIjdUhw,4831
|
|
6
|
+
promptmint/tokens.py,sha256=6Jwa7_AOP66qSSTQMxOrUTO4Qwn8cmhsGDGhRRbON2c,315
|
|
7
|
+
promptmint-0.1.0.dist-info/licenses/LICENSE,sha256=WeKhaawhmMJlph1tsbWuzf3Fo3wj3Gdfrdd40n1uraI,1067
|
|
8
|
+
promptmint-0.1.0.dist-info/METADATA,sha256=FZK2Yx2OsfDK8NH9ybz4CgGTNfrnSjG6gnfsMwN0baY,3143
|
|
9
|
+
promptmint-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
10
|
+
promptmint-0.1.0.dist-info/entry_points.txt,sha256=O_X23VJ199FimxyB3CR53hl8EQE8PnCgTNVePTHPufk,51
|
|
11
|
+
promptmint-0.1.0.dist-info/top_level.txt,sha256=swbI5q-U0IiTX-0OW4wPZlUms5Cj9H9Gz1_PUDBEOkY,11
|
|
12
|
+
promptmint-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Asim Awdah
|
|
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 @@
|
|
|
1
|
+
promptmint
|