onepaste 1.3.0__tar.gz → 1.3.1__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.
- {onepaste-1.3.0 → onepaste-1.3.1}/PKG-INFO +36 -32
- {onepaste-1.3.0 → onepaste-1.3.1}/PUBLISHING.md +4 -4
- {onepaste-1.3.0 → onepaste-1.3.1}/README.md +35 -31
- onepaste-1.3.1/onepaste/__init__.py +10 -0
- onepaste-1.3.1/onepaste/__main__.py +6 -0
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/cli.py +20 -20
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/collector.py +2 -2
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/config.py +3 -3
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/formatter.py +3 -3
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/selector.py +1 -1
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/splitter.py +4 -4
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/uninstall.py +3 -3
- {onepaste-1.3.0 → onepaste-1.3.1}/pyproject.toml +3 -3
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/conftest.py +2 -2
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_cli.py +5 -5
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_collector.py +4 -4
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_config.py +3 -3
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_formatter.py +3 -3
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_output.py +2 -2
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_splitter.py +4 -4
- {onepaste-1.3.0 → onepaste-1.3.1}/tests/test_tokens.py +2 -2
- onepaste-1.3.0/codecollector/__init__.py +0 -10
- onepaste-1.3.0/codecollector/__main__.py +0 -6
- {onepaste-1.3.0 → onepaste-1.3.1}/.github/workflows/publish.yml +0 -0
- {onepaste-1.3.0 → onepaste-1.3.1}/.gitignore +0 -0
- {onepaste-1.3.0 → onepaste-1.3.1}/LICENSE +0 -0
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/gitignore.py +0 -0
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/output.py +0 -0
- {onepaste-1.3.0/codecollector → onepaste-1.3.1/onepaste}/tokens.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: onepaste
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: Collect project code files into a single output for AI assistants
|
|
5
5
|
Project-URL: Homepage, https://github.com/emVisible/codecollector
|
|
6
6
|
Project-URL: Repository, https://github.com/emVisible/codecollector.git
|
|
@@ -35,7 +35,11 @@ Provides-Extra: tokens
|
|
|
35
35
|
Requires-Dist: tiktoken>=0.5; extra == 'tokens'
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
|
-
#
|
|
38
|
+
# OnePaste
|
|
39
|
+
|
|
40
|
+
[](https://pypi.org/project/onepaste/)
|
|
41
|
+
[](https://pypi.org/project/onepaste/)
|
|
42
|
+
[](LICENSE)
|
|
39
43
|
|
|
40
44
|
Collect project code into LLM-ready Markdown. Select a directory, press Enter, copy and paste.
|
|
41
45
|
|
|
@@ -57,8 +61,8 @@ Without the `tokens` extra, token counts use a fast characters/4 estimate.
|
|
|
57
61
|
### From source (for development)
|
|
58
62
|
|
|
59
63
|
```bash
|
|
60
|
-
git clone https://github.com/emVisible/
|
|
61
|
-
cd
|
|
64
|
+
git clone https://github.com/emVisible/onepaste.git
|
|
65
|
+
cd onepaste
|
|
62
66
|
pipx install -e .
|
|
63
67
|
```
|
|
64
68
|
|
|
@@ -66,13 +70,13 @@ pipx install -e .
|
|
|
66
70
|
|
|
67
71
|
```bash
|
|
68
72
|
# Uninstall package
|
|
69
|
-
|
|
73
|
+
onepaste --uninstall
|
|
70
74
|
|
|
71
|
-
# Uninstall and remove ~/.config/
|
|
72
|
-
|
|
75
|
+
# Uninstall and remove ~/.config/onepaste
|
|
76
|
+
onepaste --uninstall --purge-config
|
|
73
77
|
|
|
74
78
|
# Reinstall editable from local source
|
|
75
|
-
cd /path/to/
|
|
79
|
+
cd /path/to/OnePaste
|
|
76
80
|
pipx install -e .
|
|
77
81
|
```
|
|
78
82
|
|
|
@@ -80,16 +84,16 @@ pipx install -e .
|
|
|
80
84
|
|
|
81
85
|
```bash
|
|
82
86
|
# Interactive: navigate to folder → select "Collect this directory" → Enter
|
|
83
|
-
|
|
87
|
+
onepaste
|
|
84
88
|
|
|
85
89
|
# Collect current directory (.gitignore filtering on automatically inside git repos)
|
|
86
|
-
|
|
90
|
+
onepaste .
|
|
87
91
|
|
|
88
92
|
# Pipe straight into another tool — no file written
|
|
89
|
-
|
|
93
|
+
onepaste . --stdout | llm "Explain what this project does"
|
|
90
94
|
|
|
91
95
|
# Only TypeScript sources, skip tests
|
|
92
|
-
|
|
96
|
+
onepaste . --include "src/**/*.ts" --exclude-pattern "*.test.ts"
|
|
93
97
|
```
|
|
94
98
|
|
|
95
99
|
Output is a single Markdown file (`code_collection.md`) ready to copy-paste into any LLM.
|
|
@@ -98,40 +102,40 @@ Output is a single Markdown file (`code_collection.md`) ready to copy-paste into
|
|
|
98
102
|
|
|
99
103
|
```bash
|
|
100
104
|
# Interactive mode
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
onepaste
|
|
106
|
+
onepaste -i # force .gitignore filter (deprecated: auto inside git)
|
|
103
107
|
|
|
104
108
|
# Collect a specific directory
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
onepaste /path/to/project
|
|
110
|
+
onepaste . --no-gitignore # include gitignored files too
|
|
107
111
|
|
|
108
112
|
# Non-recursive (current directory only)
|
|
109
|
-
|
|
113
|
+
onepaste . -n
|
|
110
114
|
|
|
111
115
|
# Custom output
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
onepaste . -o my_project.md
|
|
117
|
+
onepaste . -d ./collected
|
|
114
118
|
|
|
115
119
|
# Glob filtering (repeatable)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
onepaste . --include "src/**"
|
|
121
|
+
onepaste . --include "*.py" --include "*.md"
|
|
122
|
+
onepaste . --exclude-pattern "*.min.js" --exclude-pattern "tests/*"
|
|
119
123
|
|
|
120
124
|
# Split large output (default: 2MB per part)
|
|
121
|
-
|
|
125
|
+
onepaste . --max-output-size 5
|
|
122
126
|
|
|
123
127
|
# Preview without writing
|
|
124
|
-
|
|
128
|
+
onepaste . --dry-run
|
|
125
129
|
|
|
126
130
|
# Extra exclusions
|
|
127
|
-
|
|
131
|
+
onepaste . --exclude vendor --exclude tmp
|
|
128
132
|
```
|
|
129
133
|
|
|
130
134
|
## Options
|
|
131
135
|
|
|
132
136
|
| Option | Description |
|
|
133
137
|
| ---------------------------- | ---------------------------------------------------------------------------------- |
|
|
134
|
-
| `path` | Directory to
|
|
138
|
+
| `path` | Directory to onepaste (default: interactive picker) |
|
|
135
139
|
| `-i` | Force-enable `.gitignore` filtering (deprecated alias; see below) |
|
|
136
140
|
| `--no-gitignore` | Disable `.gitignore` filtering |
|
|
137
141
|
| `-n, --non-recursive` | Only current directory, skip subdirectories |
|
|
@@ -139,15 +143,15 @@ collect . --exclude vendor --exclude tmp
|
|
|
139
143
|
| `-d, --output-dir` | Output directory (default: current working directory) |
|
|
140
144
|
| `--max-output-size MB` | Max output size per file; auto-split when exceeded (default: 2) |
|
|
141
145
|
| `--exclude DIR` | Extra directory to exclude (repeatable) |
|
|
142
|
-
| `--include GLOB` | Only
|
|
146
|
+
| `--include GLOB` | Only onepaste files matching glob (repeatable; overrides extension whitelist) |
|
|
143
147
|
| `--exclude-pattern GLOB` | Skip files matching glob (repeatable) |
|
|
144
148
|
| `--stdout` | Write collection to stdout; progress goes to stderr; no file written |
|
|
145
149
|
| `--dry-run` | Preview collection without writing output |
|
|
146
150
|
| `--force` | Overwrite existing output instead of auto-incrementing |
|
|
147
151
|
| `--config` | Path to config file (merged with global config) |
|
|
148
|
-
| `--init-config` | Generate default config at `~/.config/
|
|
149
|
-
| `--uninstall` | Uninstall
|
|
150
|
-
| `--purge-config` | Also remove `~/.config/
|
|
152
|
+
| `--init-config` | Generate default config at `~/.config/onepaste/config.json` |
|
|
153
|
+
| `--uninstall` | Uninstall onepaste via pipx and/or pip |
|
|
154
|
+
| `--purge-config` | Also remove `~/.config/onepaste` (with `--uninstall`) |
|
|
151
155
|
| `-v, --version` | Show version |
|
|
152
156
|
| `-h, --help` | Show help |
|
|
153
157
|
|
|
@@ -206,10 +210,10 @@ own output into the piped stream.
|
|
|
206
210
|
## Configuration
|
|
207
211
|
|
|
208
212
|
```bash
|
|
209
|
-
|
|
213
|
+
onepaste --init-config
|
|
210
214
|
```
|
|
211
215
|
|
|
212
|
-
Edit `~/.config/
|
|
216
|
+
Edit `~/.config/onepaste/config.json`:
|
|
213
217
|
|
|
214
218
|
```json
|
|
215
219
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Publishing to PyPI
|
|
2
2
|
|
|
3
|
-
Package name: **onepaste** (import name stays `
|
|
3
|
+
Package name: **onepaste** (import name stays `onepaste`, command stays `onepaste`).
|
|
4
4
|
|
|
5
5
|
## One-time setup (manual first release)
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ Package name: **onepaste** (import name stays `codecollector`, command stays `co
|
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
pipx install onepaste
|
|
22
|
-
|
|
22
|
+
onepaste --version # OnePaste v1.3.0
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Subsequent releases (GitHub Actions, zero tokens)
|
|
@@ -27,7 +27,7 @@ Package name: **onepaste** (import name stays `codecollector`, command stays `co
|
|
|
27
27
|
Uses PyPI Trusted Publishing (OIDC) — no secrets stored in GitHub.
|
|
28
28
|
|
|
29
29
|
1. On PyPI: your project → *Settings* → *Publishing* → add a **Trusted Publisher**:
|
|
30
|
-
- Owner: `emVisible` Repo: `
|
|
30
|
+
- Owner: `emVisible` Repo: `OnePaste`
|
|
31
31
|
- Workflow filename: `publish.yml`
|
|
32
32
|
- Environment name: `pypi`
|
|
33
33
|
2. Release: create a GitHub *Release* (or run the workflow manually via `workflow_dispatch`).
|
|
@@ -37,5 +37,5 @@ The workflow runs tests, builds, twine-checks, then publishes.
|
|
|
37
37
|
## Bump a version
|
|
38
38
|
|
|
39
39
|
1. `pyproject.toml` → `version`
|
|
40
|
-
2. `
|
|
40
|
+
2. `onepaste/__init__.py` → `__version__` (a test enforces both match)
|
|
41
41
|
3. Commit + GitHub Release with tag `vX.Y.Z`
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OnePaste
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/onepaste/)
|
|
4
|
+
[](https://pypi.org/project/onepaste/)
|
|
5
|
+
[](LICENSE)
|
|
2
6
|
|
|
3
7
|
Collect project code into LLM-ready Markdown. Select a directory, press Enter, copy and paste.
|
|
4
8
|
|
|
@@ -20,8 +24,8 @@ Without the `tokens` extra, token counts use a fast characters/4 estimate.
|
|
|
20
24
|
### From source (for development)
|
|
21
25
|
|
|
22
26
|
```bash
|
|
23
|
-
git clone https://github.com/emVisible/
|
|
24
|
-
cd
|
|
27
|
+
git clone https://github.com/emVisible/onepaste.git
|
|
28
|
+
cd onepaste
|
|
25
29
|
pipx install -e .
|
|
26
30
|
```
|
|
27
31
|
|
|
@@ -29,13 +33,13 @@ pipx install -e .
|
|
|
29
33
|
|
|
30
34
|
```bash
|
|
31
35
|
# Uninstall package
|
|
32
|
-
|
|
36
|
+
onepaste --uninstall
|
|
33
37
|
|
|
34
|
-
# Uninstall and remove ~/.config/
|
|
35
|
-
|
|
38
|
+
# Uninstall and remove ~/.config/onepaste
|
|
39
|
+
onepaste --uninstall --purge-config
|
|
36
40
|
|
|
37
41
|
# Reinstall editable from local source
|
|
38
|
-
cd /path/to/
|
|
42
|
+
cd /path/to/OnePaste
|
|
39
43
|
pipx install -e .
|
|
40
44
|
```
|
|
41
45
|
|
|
@@ -43,16 +47,16 @@ pipx install -e .
|
|
|
43
47
|
|
|
44
48
|
```bash
|
|
45
49
|
# Interactive: navigate to folder → select "Collect this directory" → Enter
|
|
46
|
-
|
|
50
|
+
onepaste
|
|
47
51
|
|
|
48
52
|
# Collect current directory (.gitignore filtering on automatically inside git repos)
|
|
49
|
-
|
|
53
|
+
onepaste .
|
|
50
54
|
|
|
51
55
|
# Pipe straight into another tool — no file written
|
|
52
|
-
|
|
56
|
+
onepaste . --stdout | llm "Explain what this project does"
|
|
53
57
|
|
|
54
58
|
# Only TypeScript sources, skip tests
|
|
55
|
-
|
|
59
|
+
onepaste . --include "src/**/*.ts" --exclude-pattern "*.test.ts"
|
|
56
60
|
```
|
|
57
61
|
|
|
58
62
|
Output is a single Markdown file (`code_collection.md`) ready to copy-paste into any LLM.
|
|
@@ -61,40 +65,40 @@ Output is a single Markdown file (`code_collection.md`) ready to copy-paste into
|
|
|
61
65
|
|
|
62
66
|
```bash
|
|
63
67
|
# Interactive mode
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
onepaste
|
|
69
|
+
onepaste -i # force .gitignore filter (deprecated: auto inside git)
|
|
66
70
|
|
|
67
71
|
# Collect a specific directory
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
onepaste /path/to/project
|
|
73
|
+
onepaste . --no-gitignore # include gitignored files too
|
|
70
74
|
|
|
71
75
|
# Non-recursive (current directory only)
|
|
72
|
-
|
|
76
|
+
onepaste . -n
|
|
73
77
|
|
|
74
78
|
# Custom output
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
onepaste . -o my_project.md
|
|
80
|
+
onepaste . -d ./collected
|
|
77
81
|
|
|
78
82
|
# Glob filtering (repeatable)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
onepaste . --include "src/**"
|
|
84
|
+
onepaste . --include "*.py" --include "*.md"
|
|
85
|
+
onepaste . --exclude-pattern "*.min.js" --exclude-pattern "tests/*"
|
|
82
86
|
|
|
83
87
|
# Split large output (default: 2MB per part)
|
|
84
|
-
|
|
88
|
+
onepaste . --max-output-size 5
|
|
85
89
|
|
|
86
90
|
# Preview without writing
|
|
87
|
-
|
|
91
|
+
onepaste . --dry-run
|
|
88
92
|
|
|
89
93
|
# Extra exclusions
|
|
90
|
-
|
|
94
|
+
onepaste . --exclude vendor --exclude tmp
|
|
91
95
|
```
|
|
92
96
|
|
|
93
97
|
## Options
|
|
94
98
|
|
|
95
99
|
| Option | Description |
|
|
96
100
|
| ---------------------------- | ---------------------------------------------------------------------------------- |
|
|
97
|
-
| `path` | Directory to
|
|
101
|
+
| `path` | Directory to onepaste (default: interactive picker) |
|
|
98
102
|
| `-i` | Force-enable `.gitignore` filtering (deprecated alias; see below) |
|
|
99
103
|
| `--no-gitignore` | Disable `.gitignore` filtering |
|
|
100
104
|
| `-n, --non-recursive` | Only current directory, skip subdirectories |
|
|
@@ -102,15 +106,15 @@ collect . --exclude vendor --exclude tmp
|
|
|
102
106
|
| `-d, --output-dir` | Output directory (default: current working directory) |
|
|
103
107
|
| `--max-output-size MB` | Max output size per file; auto-split when exceeded (default: 2) |
|
|
104
108
|
| `--exclude DIR` | Extra directory to exclude (repeatable) |
|
|
105
|
-
| `--include GLOB` | Only
|
|
109
|
+
| `--include GLOB` | Only onepaste files matching glob (repeatable; overrides extension whitelist) |
|
|
106
110
|
| `--exclude-pattern GLOB` | Skip files matching glob (repeatable) |
|
|
107
111
|
| `--stdout` | Write collection to stdout; progress goes to stderr; no file written |
|
|
108
112
|
| `--dry-run` | Preview collection without writing output |
|
|
109
113
|
| `--force` | Overwrite existing output instead of auto-incrementing |
|
|
110
114
|
| `--config` | Path to config file (merged with global config) |
|
|
111
|
-
| `--init-config` | Generate default config at `~/.config/
|
|
112
|
-
| `--uninstall` | Uninstall
|
|
113
|
-
| `--purge-config` | Also remove `~/.config/
|
|
115
|
+
| `--init-config` | Generate default config at `~/.config/onepaste/config.json` |
|
|
116
|
+
| `--uninstall` | Uninstall onepaste via pipx and/or pip |
|
|
117
|
+
| `--purge-config` | Also remove `~/.config/onepaste` (with `--uninstall`) |
|
|
114
118
|
| `-v, --version` | Show version |
|
|
115
119
|
| `-h, --help` | Show help |
|
|
116
120
|
|
|
@@ -169,10 +173,10 @@ own output into the piped stream.
|
|
|
169
173
|
## Configuration
|
|
170
174
|
|
|
171
175
|
```bash
|
|
172
|
-
|
|
176
|
+
onepaste --init-config
|
|
173
177
|
```
|
|
174
178
|
|
|
175
|
-
Edit `~/.config/
|
|
179
|
+
Edit `~/.config/onepaste/config.json`:
|
|
176
180
|
|
|
177
181
|
```json
|
|
178
182
|
{
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""OnePaste - Collect project code files for AI assistants."""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.3.1"
|
|
4
|
+
__author__ = "thawn"
|
|
5
|
+
__license__ = "MIT"
|
|
6
|
+
|
|
7
|
+
from onepaste.collector import FileCollector
|
|
8
|
+
from onepaste.config import CollectorConfig
|
|
9
|
+
|
|
10
|
+
__all__ = ["FileCollector", "CollectorConfig", "__version__"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Command-line interface for
|
|
1
|
+
"""Command-line interface for OnePaste."""
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
@@ -9,15 +9,15 @@ from rich.panel import Panel
|
|
|
9
9
|
from rich.table import Table
|
|
10
10
|
from rich.theme import Theme
|
|
11
11
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from
|
|
17
|
-
from
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
12
|
+
from onepaste import __version__
|
|
13
|
+
from onepaste.collector import FileCollector
|
|
14
|
+
from onepaste.config import CONFIG_FILE, CollectorConfig, ensure_config_dir
|
|
15
|
+
from onepaste.formatter import OutputFormatter
|
|
16
|
+
from onepaste.output import output_files_exist, write_manifest
|
|
17
|
+
from onepaste.selector import InteractiveSelector
|
|
18
|
+
from onepaste.splitter import write_collection_output
|
|
19
|
+
from onepaste.tokens import count_tokens, method_label
|
|
20
|
+
from onepaste.uninstall import uninstall_package
|
|
21
21
|
|
|
22
22
|
custom_theme = Theme({
|
|
23
23
|
"info": "cyan",
|
|
@@ -35,8 +35,8 @@ console = Console(theme=custom_theme)
|
|
|
35
35
|
err_console = Console(file=sys.stderr, theme=custom_theme)
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class
|
|
39
|
-
"""Main application class for
|
|
38
|
+
class OnePasteApp:
|
|
39
|
+
"""Main application class for OnePaste."""
|
|
40
40
|
|
|
41
41
|
def __init__(self):
|
|
42
42
|
self.config: Optional[CollectorConfig] = None
|
|
@@ -377,7 +377,7 @@ class CodeCollectorApp:
|
|
|
377
377
|
console.print()
|
|
378
378
|
console.print(
|
|
379
379
|
Panel(
|
|
380
|
-
"[title]
|
|
380
|
+
"[title]OnePaste[/title]\n"
|
|
381
381
|
"[subtitle]Select a directory → Enter → ready for LLM[/subtitle]\n"
|
|
382
382
|
f"[dim]v{__version__}[/dim]",
|
|
383
383
|
border_style="cyan",
|
|
@@ -391,7 +391,7 @@ def main() -> None:
|
|
|
391
391
|
import argparse
|
|
392
392
|
|
|
393
393
|
parser = argparse.ArgumentParser(
|
|
394
|
-
description="
|
|
394
|
+
description="OnePaste - Collect project code for AI assistants",
|
|
395
395
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
396
396
|
epilog=f"""
|
|
397
397
|
Examples:
|
|
@@ -410,8 +410,8 @@ Examples:
|
|
|
410
410
|
collect . --include "src/**" Only include files matching glob (repeatable)
|
|
411
411
|
collect . --exclude-pattern "*_test.go" Skip files matching glob (repeatable)
|
|
412
412
|
collect --init-config Initialize default configuration
|
|
413
|
-
collect --uninstall Uninstall
|
|
414
|
-
collect --uninstall --purge-config Uninstall and remove ~/.config/
|
|
413
|
+
collect --uninstall Uninstall onepaste (pipx/pip)
|
|
414
|
+
collect --uninstall --purge-config Uninstall and remove ~/.config/onepaste
|
|
415
415
|
|
|
416
416
|
Version: {__version__}
|
|
417
417
|
""",
|
|
@@ -478,14 +478,14 @@ Version: {__version__}
|
|
|
478
478
|
parser.add_argument(
|
|
479
479
|
"--uninstall",
|
|
480
480
|
action="store_true",
|
|
481
|
-
help="Uninstall
|
|
481
|
+
help="Uninstall onepaste (via pipx and/or pip)",
|
|
482
482
|
)
|
|
483
483
|
parser.add_argument(
|
|
484
484
|
"--purge-config",
|
|
485
485
|
action="store_true",
|
|
486
|
-
help="Also remove ~/.config/
|
|
486
|
+
help="Also remove ~/.config/onepaste (use with --uninstall)",
|
|
487
487
|
)
|
|
488
|
-
parser.add_argument("-v", "--version", action="version", version=f"
|
|
488
|
+
parser.add_argument("-v", "--version", action="version", version=f"OnePaste v{__version__}")
|
|
489
489
|
|
|
490
490
|
args = parser.parse_args()
|
|
491
491
|
|
|
@@ -535,7 +535,7 @@ Version: {__version__}
|
|
|
535
535
|
return
|
|
536
536
|
|
|
537
537
|
try:
|
|
538
|
-
app =
|
|
538
|
+
app = OnePasteApp()
|
|
539
539
|
|
|
540
540
|
if not args.path and not args.config:
|
|
541
541
|
respect = True if args.i else (False if args.no_gitignore else None)
|
|
@@ -6,8 +6,8 @@ import re
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Iterable, List, Optional, Set, Tuple
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
9
|
+
from onepaste.config import CollectorConfig
|
|
10
|
+
from onepaste.gitignore import GitignoreMatcher, list_git_visible_files
|
|
11
11
|
|
|
12
12
|
# Own outputs should never be re-collected (prevents runaway growth).
|
|
13
13
|
_OUTPUT_ARTIFACT_RE = re.compile(
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""Configuration management for
|
|
1
|
+
"""Configuration management for OnePaste."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
from dataclasses import dataclass, field, fields
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Any, Dict, List, Optional, Set
|
|
7
7
|
|
|
8
|
-
from
|
|
8
|
+
from onepaste.gitignore import is_inside_git_work_tree
|
|
9
9
|
|
|
10
|
-
CONFIG_DIR = Path.home() / ".config" / "
|
|
10
|
+
CONFIG_DIR = Path.home() / ".config" / "onepaste"
|
|
11
11
|
CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
12
12
|
|
|
13
13
|
|
|
@@ -5,8 +5,8 @@ from datetime import datetime
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import List, Tuple
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from onepaste.config import CollectorConfig
|
|
9
|
+
from onepaste.tokens import count_tokens, method_label
|
|
10
10
|
|
|
11
11
|
_FENCE_RUN_RE = re.compile(r"`{3,}")
|
|
12
12
|
_TOP_TOKEN_FILES = 10
|
|
@@ -76,7 +76,7 @@ class OutputFormatter:
|
|
|
76
76
|
file_tokens.append((fp, 0))
|
|
77
77
|
|
|
78
78
|
summary = [
|
|
79
|
-
"#
|
|
79
|
+
"# OnePaste - Collection Summary",
|
|
80
80
|
"",
|
|
81
81
|
f"**Generated:** {now} ",
|
|
82
82
|
f"**Root:** `{config.root_path.absolute()}` ",
|
|
@@ -48,7 +48,7 @@ class InteractiveSelector:
|
|
|
48
48
|
|
|
49
49
|
console.print()
|
|
50
50
|
console.print(Panel.fit(
|
|
51
|
-
"[bold cyan]
|
|
51
|
+
"[bold cyan]OnePaste[/bold cyan] [dim]- Select directory, press Enter to collect[/dim]",
|
|
52
52
|
border_style="cyan",
|
|
53
53
|
))
|
|
54
54
|
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import List, Tuple
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
6
|
+
from onepaste.config import CollectorConfig
|
|
7
|
+
from onepaste.output import resolve_unique_filename
|
|
8
8
|
|
|
9
9
|
HEADER_SIZE_BUFFER = 512
|
|
10
10
|
ESTIMATED_PART_HEADER = (
|
|
11
|
-
"#
|
|
11
|
+
"# OnePaste - Part 999 of 999\n\n"
|
|
12
12
|
f"- **Root:** `{'x' * 60}`\n"
|
|
13
13
|
"- **Files in this part:** 999\n"
|
|
14
14
|
+ "\n".join(f" - `{'x' * 60}`" for _ in range(10))
|
|
@@ -33,7 +33,7 @@ def format_part_header(
|
|
|
33
33
|
) -> str:
|
|
34
34
|
"""Format the header for a split output file."""
|
|
35
35
|
lines = [
|
|
36
|
-
f"#
|
|
36
|
+
f"# OnePaste - Part {part} of {total}",
|
|
37
37
|
"",
|
|
38
38
|
]
|
|
39
39
|
|
|
@@ -6,9 +6,9 @@ import sys
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import List, Optional, Tuple
|
|
8
8
|
|
|
9
|
-
from
|
|
9
|
+
from onepaste.config import CONFIG_DIR
|
|
10
10
|
|
|
11
|
-
PACKAGE_NAME = "
|
|
11
|
+
PACKAGE_NAME = "onepaste"
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def _run(cmd: List[str]) -> Tuple[int, str]:
|
|
@@ -60,7 +60,7 @@ def remove_config_dir() -> Optional[Path]:
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
def uninstall_package(purge_config: bool = False) -> Tuple[bool, List[str]]:
|
|
63
|
-
"""Uninstall
|
|
63
|
+
"""Uninstall onepaste via pipx and/or pip.
|
|
64
64
|
|
|
65
65
|
Returns (success, messages).
|
|
66
66
|
"""
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "onepaste"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.1"
|
|
8
8
|
description = "Collect project code files into a single output for AI assistants"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -39,7 +39,7 @@ Repository = "https://github.com/emVisible/codecollector.git"
|
|
|
39
39
|
Issues = "https://github.com/emVisible/codecollector/issues"
|
|
40
40
|
|
|
41
41
|
[project.scripts]
|
|
42
|
-
|
|
42
|
+
onepaste = "onepaste.cli:main"
|
|
43
43
|
|
|
44
44
|
[project.optional-dependencies]
|
|
45
45
|
tokens = ["tiktoken>=0.5"]
|
|
@@ -53,7 +53,7 @@ dev = [
|
|
|
53
53
|
]
|
|
54
54
|
|
|
55
55
|
[tool.hatch.build.targets.wheel]
|
|
56
|
-
packages = ["
|
|
56
|
+
packages = ["onepaste"]
|
|
57
57
|
|
|
58
58
|
[tool.hatch.build.targets.sdist]
|
|
59
59
|
exclude = ["/website"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Shared fixtures for
|
|
1
|
+
"""Shared fixtures for OnePaste tests."""
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
@@ -45,7 +45,7 @@ def project_dir(tmp_path: Path) -> Path:
|
|
|
45
45
|
@pytest.fixture
|
|
46
46
|
def isolated_config(monkeypatch, tmp_path: Path):
|
|
47
47
|
"""Point the global config at a missing temp path for determinism."""
|
|
48
|
-
import
|
|
48
|
+
import onepaste.config as config_module
|
|
49
49
|
|
|
50
50
|
fake_global = tmp_path / "global_config.json"
|
|
51
51
|
monkeypatch.setattr(config_module, "CONFIG_FILE", fake_global)
|
|
@@ -11,9 +11,9 @@ import pytest
|
|
|
11
11
|
|
|
12
12
|
def run_cli(args, cwd, home):
|
|
13
13
|
env = dict(os.environ)
|
|
14
|
-
env["HOME"] = str(home) # isolate ~/.config/
|
|
14
|
+
env["HOME"] = str(home) # isolate ~/.config/onepaste
|
|
15
15
|
return subprocess.run(
|
|
16
|
-
[sys.executable, "-m", "
|
|
16
|
+
[sys.executable, "-m", "onepaste", *args],
|
|
17
17
|
cwd=str(cwd),
|
|
18
18
|
env=env,
|
|
19
19
|
capture_output=True,
|
|
@@ -38,10 +38,10 @@ class TestMeta:
|
|
|
38
38
|
def test_version_flag(self, tmp_path):
|
|
39
39
|
r = run_cli(["-v"], cwd=tmp_path, home=tmp_path)
|
|
40
40
|
assert r.returncode == 0
|
|
41
|
-
assert "
|
|
41
|
+
assert "OnePaste v" in (r.stdout + r.stderr)
|
|
42
42
|
|
|
43
43
|
def test_version_matches_package(self, tmp_path):
|
|
44
|
-
from
|
|
44
|
+
from onepaste import __version__
|
|
45
45
|
|
|
46
46
|
pyproject = (
|
|
47
47
|
Path(__file__).resolve().parent.parent / "pyproject.toml"
|
|
@@ -94,7 +94,7 @@ class TestStdoutMode:
|
|
|
94
94
|
|
|
95
95
|
r = run_cli([str(project_dir), "--stdout"], cwd=tmp_path, home=tmp_path)
|
|
96
96
|
assert r.returncode == 0
|
|
97
|
-
assert "#
|
|
97
|
+
assert "# OnePaste - Collection Summary" in r.stdout
|
|
98
98
|
assert "### `main.py`" in r.stdout
|
|
99
99
|
assert "print('hi')" in r.stdout
|
|
100
100
|
assert not out_file.exists()
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""Tests for
|
|
1
|
+
"""Tests for onepaste.collector."""
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
import onepaste.collector as collector_module
|
|
9
|
+
from onepaste.collector import FileCollector
|
|
10
|
+
from onepaste.config import CollectorConfig
|
|
11
11
|
|
|
12
12
|
DEFAULT_EXPECTED = {
|
|
13
13
|
".gitignore",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"""Tests for
|
|
1
|
+
"""Tests for onepaste.config."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
from
|
|
7
|
+
import onepaste.config as config_module
|
|
8
|
+
from onepaste.config import CollectorConfig
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
@pytest.fixture
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"""Tests for
|
|
1
|
+
"""Tests for onepaste.formatter."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from onepaste.config import CollectorConfig
|
|
6
|
+
from onepaste.formatter import OutputFormatter
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class TestFenceMarker:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""Tests for
|
|
1
|
+
"""Tests for onepaste.splitter."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from
|
|
3
|
+
from onepaste.config import CollectorConfig
|
|
4
|
+
from onepaste.splitter import (
|
|
5
5
|
ESTIMATED_PART_HEADER,
|
|
6
6
|
HEADER_SIZE_BUFFER,
|
|
7
7
|
byte_size,
|
|
@@ -99,7 +99,7 @@ class TestWriteCollectionOutput:
|
|
|
99
99
|
"code_collection.part2.md",
|
|
100
100
|
]
|
|
101
101
|
text1 = paths[0].read_text(encoding="utf-8")
|
|
102
|
-
assert text1.startswith("#
|
|
102
|
+
assert text1.startswith("# OnePaste - Part 1 of 2")
|
|
103
103
|
assert "SUMMARY" in text1
|
|
104
104
|
assert "chunk-two" not in text1
|
|
105
105
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"""CodeCollector - Collect project code files for AI assistants."""
|
|
2
|
-
|
|
3
|
-
__version__ = "1.3.0"
|
|
4
|
-
__author__ = "thawn"
|
|
5
|
-
__license__ = "MIT"
|
|
6
|
-
|
|
7
|
-
from codecollector.collector import FileCollector
|
|
8
|
-
from codecollector.config import CollectorConfig
|
|
9
|
-
|
|
10
|
-
__all__ = ["FileCollector", "CollectorConfig", "__version__"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|