janito 0.6.0__py3-none-any.whl → 0.7.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.
- janito/__main__.py +37 -30
- janito/agents/__init__.py +8 -2
- janito/agents/agent.py +10 -3
- janito/agents/claudeai.py +13 -23
- janito/agents/openai.py +5 -1
- janito/change/analysis/analyze.py +8 -7
- janito/change/analysis/prompts.py +4 -12
- janito/change/analysis/view/terminal.py +21 -11
- janito/change/applier/text.py +7 -5
- janito/change/core.py +22 -29
- janito/change/parser.py +0 -2
- janito/change/prompts.py +16 -21
- janito/change/validator.py +27 -9
- janito/change/viewer/content.py +1 -1
- janito/change/viewer/panels.py +93 -115
- janito/change/viewer/styling.py +15 -4
- janito/cli/commands.py +63 -20
- janito/common.py +44 -18
- janito/config.py +44 -44
- janito/prompt.py +36 -0
- janito/qa.py +5 -14
- janito/search_replace/README.md +63 -17
- janito/search_replace/__init__.py +2 -1
- janito/search_replace/core.py +15 -14
- janito/search_replace/logger.py +35 -0
- janito/search_replace/searcher.py +160 -48
- janito/search_replace/strategy_result.py +10 -0
- janito/shell/__init__.py +15 -16
- janito/shell/commands.py +38 -97
- janito/shell/processor.py +7 -27
- janito/shell/prompt.py +48 -0
- janito/shell/registry.py +60 -0
- janito/workspace/__init__.py +4 -5
- janito/workspace/analysis.py +2 -2
- janito/workspace/show.py +141 -0
- janito/workspace/stats.py +43 -0
- janito/workspace/types.py +98 -0
- janito/workspace/workset.py +108 -0
- janito/workspace/workspace.py +114 -0
- janito-0.7.0.dist-info/METADATA +167 -0
- {janito-0.6.0.dist-info → janito-0.7.0.dist-info}/RECORD +44 -43
- janito/change/viewer/pager.py +0 -56
- janito/cli/handlers/ask.py +0 -22
- janito/cli/handlers/demo.py +0 -22
- janito/cli/handlers/request.py +0 -24
- janito/cli/handlers/scan.py +0 -9
- janito/prompts.py +0 -2
- janito/shell/handlers.py +0 -122
- janito/workspace/manager.py +0 -48
- janito/workspace/scan.py +0 -232
- janito-0.6.0.dist-info/METADATA +0 -185
- {janito-0.6.0.dist-info → janito-0.7.0.dist-info}/WHEEL +0 -0
- {janito-0.6.0.dist-info → janito-0.7.0.dist-info}/entry_points.txt +0 -0
- {janito-0.6.0.dist-info → janito-0.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: janito
|
3
|
+
Version: 0.7.0
|
4
|
+
Summary: A CLI tool for software development tasks powered by AI
|
5
|
+
Project-URL: Homepage, https://github.com/joaompinto/janito
|
6
|
+
Project-URL: Repository, https://github.com/joaompinto/janito.git
|
7
|
+
Author-email: João Pinto <lamego.pinto@gmail.com>
|
8
|
+
License: MIT
|
9
|
+
License-File: LICENSE
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
11
|
+
Classifier: Environment :: Console
|
12
|
+
Classifier: Intended Audience :: Developers
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
17
|
+
Classifier: Topic :: Software Development
|
18
|
+
Requires-Python: >=3.8
|
19
|
+
Requires-Dist: anthropic
|
20
|
+
Requires-Dist: pathspec
|
21
|
+
Requires-Dist: rich
|
22
|
+
Requires-Dist: tomli
|
23
|
+
Requires-Dist: typer
|
24
|
+
Description-Content-Type: text/markdown
|
25
|
+
|
26
|
+
# Janito
|
27
|
+
|
28
|
+
[](https://badge.fury.io/py/janito)
|
29
|
+
[](https://opensource.org/licenses/MIT)
|
30
|
+
|
31
|
+
AI-powered CLI tool for code modifications and analysis. Janito helps you modify, analyze, and understand your codebase using natural language commands.
|
32
|
+
|
33
|
+
## Table of Contents
|
34
|
+
|
35
|
+
- [Features](#features)
|
36
|
+
- [Installation](#installation)
|
37
|
+
- [Usage](#usage)
|
38
|
+
- [Basic Commands](#basic-commands)
|
39
|
+
- [Examples](#examples)
|
40
|
+
- [Configuration](#configuration)
|
41
|
+
- [Development](#development)
|
42
|
+
- [License](#license)
|
43
|
+
|
44
|
+
## Features
|
45
|
+
|
46
|
+
- 🤖 AI-powered code analysis and modifications
|
47
|
+
- 🔄 Incremental code changes with search/replace operations
|
48
|
+
- 🎯 Precise text modifications with context matching
|
49
|
+
- 💬 Natural language interface for code operations
|
50
|
+
- 🔍 Interactive code exploration
|
51
|
+
- 📝 Automatic documentation generation
|
52
|
+
- ⚡ Fast and efficient codebase navigation
|
53
|
+
- 💾 Smart Claude AI prompt caching for faster responses
|
54
|
+
|
55
|
+
## Installation
|
56
|
+
|
57
|
+
### Prerequisites
|
58
|
+
|
59
|
+
- Python 3.8 or higher
|
60
|
+
- Anthropic API key (with smart caching to reduce API costs)
|
61
|
+
|
62
|
+
### Install via pip
|
63
|
+
|
64
|
+
```bash
|
65
|
+
pip install janito
|
66
|
+
```
|
67
|
+
|
68
|
+
### Set up API key
|
69
|
+
|
70
|
+
```bash
|
71
|
+
export ANTHROPIC_API_KEY=your_api_key_here
|
72
|
+
```
|
73
|
+
|
74
|
+
## Usage
|
75
|
+
|
76
|
+
### Basic Commands
|
77
|
+
|
78
|
+
Janito supports incremental code changes through precise text operations:
|
79
|
+
- Search and replace with context matching
|
80
|
+
- Delete specific code blocks
|
81
|
+
- File operations (create, replace, rename, move, remove)
|
82
|
+
|
83
|
+
```bash
|
84
|
+
# Start interactive shell
|
85
|
+
janito
|
86
|
+
|
87
|
+
# Modify code with natural language
|
88
|
+
janito "add docstrings to this file"
|
89
|
+
|
90
|
+
# Ask questions about the codebase
|
91
|
+
janito --ask "explain the main function in this file"
|
92
|
+
|
93
|
+
# Preview files that would be analyzed
|
94
|
+
janito --scan
|
95
|
+
```
|
96
|
+
|
97
|
+
### Examples
|
98
|
+
|
99
|
+
1. Add documentation to a file:
|
100
|
+
```bash
|
101
|
+
janito "add docstrings to all functions in src/main.py"
|
102
|
+
```
|
103
|
+
|
104
|
+
2. Analyze code structure:
|
105
|
+
```bash
|
106
|
+
janito --ask "what are the main classes in this project?"
|
107
|
+
```
|
108
|
+
|
109
|
+
3. Refactor code:
|
110
|
+
```bash
|
111
|
+
janito "convert this function to use async/await"
|
112
|
+
```
|
113
|
+
|
114
|
+
4. Generate tests:
|
115
|
+
```bash
|
116
|
+
janito "create unit tests for the User class"
|
117
|
+
```
|
118
|
+
|
119
|
+
## Configuration
|
120
|
+
|
121
|
+
### Environment Variables
|
122
|
+
|
123
|
+
- `ANTHROPIC_API_KEY`: Anthropic API key for Claude AI
|
124
|
+
- `JANITO_TEST_CMD`: Default test command to run after changes
|
125
|
+
|
126
|
+
### Command Line Options
|
127
|
+
|
128
|
+
- `-w, --workspace_dir`: Set working directory
|
129
|
+
- `-i, --include`: Additional paths to include
|
130
|
+
- `--debug`: Show debug information
|
131
|
+
- `--verbose`: Show verbose output
|
132
|
+
- `--auto-apply`: Apply changes without confirmation
|
133
|
+
|
134
|
+
## Development
|
135
|
+
|
136
|
+
### Setting up Development Environment
|
137
|
+
|
138
|
+
```bash
|
139
|
+
# Clone the repository
|
140
|
+
git clone https://github.com/joaompinto/janito.git
|
141
|
+
cd janito
|
142
|
+
|
143
|
+
# Create and activate virtual environment
|
144
|
+
python -m venv venv
|
145
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
146
|
+
|
147
|
+
# Install development dependencies
|
148
|
+
pip install -e ".[dev]"
|
149
|
+
```
|
150
|
+
|
151
|
+
### Running Tests
|
152
|
+
|
153
|
+
```bash
|
154
|
+
pytest
|
155
|
+
```
|
156
|
+
|
157
|
+
### Contributing
|
158
|
+
|
159
|
+
1. Fork the repository
|
160
|
+
2. Create a feature branch
|
161
|
+
3. Commit your changes
|
162
|
+
4. Push to the branch
|
163
|
+
5. Create a Pull Request
|
164
|
+
|
165
|
+
## License
|
166
|
+
|
167
|
+
MIT License - see [LICENSE](LICENSE)
|
@@ -1,46 +1,45 @@
|
|
1
1
|
janito/__init__.py,sha256=Svp3i5NGeapDV4xB-CDu9TjqEzvsnjQwSzdmDT9DDqc,47
|
2
|
-
janito/__main__.py,sha256=
|
3
|
-
janito/common.py,sha256=
|
4
|
-
janito/config.py,sha256=
|
5
|
-
janito/
|
6
|
-
janito/qa.py,sha256=
|
2
|
+
janito/__main__.py,sha256=l20_V0iIX_8yjJeP-THirJATybgCbmikzu5colMb1P0,5544
|
3
|
+
janito/common.py,sha256=VaFTF5VM6dClNGFVC1A9b-EbpqcqrQpybl6eidl8T9c,3381
|
4
|
+
janito/config.py,sha256=f0chVHjfds62W-wUDPLlshxh8W1VviqHw2kbm-_qLSA,3126
|
5
|
+
janito/prompt.py,sha256=Rd6I0C4y0uSgWCggoLJiSiET9vT3nlgtwfSKo06jMDc,1011
|
6
|
+
janito/qa.py,sha256=8MBQnKgUGErgJ3XWE2cd9WvSAHyke-AL5jO8iPhfhng,1794
|
7
7
|
janito/review.py,sha256=5Oc6BfxMGNmKbIeDP5_EiAKUDeQwVOD0YL7iqfgJLRE,471
|
8
8
|
janito/version.py,sha256=ylfPwGtdY8dEOFJ-DB9gKUQLggqRCvoLxhpnwjzCM94,739
|
9
|
-
janito/agents/__init__.py,sha256=
|
10
|
-
janito/agents/agent.py,sha256=
|
11
|
-
janito/agents/claudeai.py,sha256=
|
12
|
-
janito/agents/openai.py,sha256=
|
9
|
+
janito/agents/__init__.py,sha256=o4CL_6UkTx62W9VyOshecAgnPrlBeiDqH3l82RKN2gA,755
|
10
|
+
janito/agents/agent.py,sha256=81Bx9I6U0U-KDFMKkV0Q-ZlzCxbuJBUHGKUHqG45S_E,927
|
11
|
+
janito/agents/claudeai.py,sha256=WWCFWJ4T6v6dPZubpGgsQTzgd9lB4ViNm29FC66wl_U,1608
|
12
|
+
janito/agents/openai.py,sha256=VdskCojBIbRvKTjiVqwn1f3rfGHynUFDaIvnlwRYs1c,2282
|
13
13
|
janito/agents/test.py,sha256=xoN1q9DUSYpUbnvTP1qZsEfxYrZfocJlt9DkIuMDvvY,1552
|
14
14
|
janito/change/__init__.py,sha256=vGn9qudqiusp4LsR2zzr3mbb4dhXvcGBY2NNzl1JC5M,955
|
15
15
|
janito/change/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
janito/change/core.py,sha256=
|
16
|
+
janito/change/core.py,sha256=fTAFv3FwYgPxwhuMOSigglYX0l30KY6X17L_VxBviB4,3871
|
17
17
|
janito/change/history.py,sha256=rbprE1lnOl5We85c-VsDnHAiGphW0t2fA7zu4N9uulw,1405
|
18
18
|
janito/change/operations.py,sha256=5HeUvFa503Foemngu-ShomPn9W82XH-gLlTfXxAZoEw,165
|
19
|
-
janito/change/parser.py,sha256=
|
19
|
+
janito/change/parser.py,sha256=EYQgy1L8yWNPTgdVNWeiXFbAtzPJNBwU15-dE4ThG68,11169
|
20
20
|
janito/change/play.py,sha256=ZzYp-eaIBn578EiPB9uVR-G-mxXiK_hD_GI15htb0DU,1835
|
21
21
|
janito/change/preview.py,sha256=xfwo0q7jAx-U92U3iEwDDlsZnzndj7fshq8OLgjv3Vw,2720
|
22
|
-
janito/change/prompts.py,sha256=
|
22
|
+
janito/change/prompts.py,sha256=00HcNIEZwLCEY1SvT5unaIiAkCoiSCG-DYk94YmWcPQ,4345
|
23
23
|
janito/change/test.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
janito/change/validator.py,sha256=
|
24
|
+
janito/change/validator.py,sha256=sd8QXruxQPdG-rVCM6NIXsVmK50ytzrtsx2J3is06Ww,10943
|
25
25
|
janito/change/analysis/__init__.py,sha256=yg9LhcC1nCvleGt4cnQMuJYCARXBZNvmXaT23S3szJo,593
|
26
26
|
janito/change/analysis/__main__.py,sha256=M6JmJnZfOKB0OB29EpzzfbNZu7cusKT92KQhmnaWd5c,196
|
27
|
-
janito/change/analysis/analyze.py,sha256=
|
27
|
+
janito/change/analysis/analyze.py,sha256=CRpfRn_3KQHNdTZ1wQtsSafzmJzPblNggEf-ZkiTEzw,1760
|
28
28
|
janito/change/analysis/formatting.py,sha256=VqDL6fBzvVm5pdDN4fX9nQQP1wZwhlxDKyaMlDj9ju4,2602
|
29
29
|
janito/change/analysis/options.py,sha256=JNyXCFjOxS1Qm1oqqn8JSXrF4KQ9MotclfKMLD7dZFc,2957
|
30
|
-
janito/change/analysis/prompts.py,sha256=
|
30
|
+
janito/change/analysis/prompts.py,sha256=UmuJzrdxpEpL3EcgrsJO4OwKWDWMlFucd162Oje-7F4,2962
|
31
31
|
janito/change/analysis/view/__init__.py,sha256=oQd_ClbL7sWmb8jbie74qRrn09CIUTxLH18b02PJFLk,204
|
32
|
-
janito/change/analysis/view/terminal.py,sha256=
|
32
|
+
janito/change/analysis/view/terminal.py,sha256=IxsIZG7IJQwfJ1dtZDCga7E7Qq3u5EI5lPszbvi82u4,6598
|
33
33
|
janito/change/applier/__init__.py,sha256=KdViLadNAWcSUbJcsfAt66cDJpaqYGIHdzSDKZjzsEw,183
|
34
34
|
janito/change/applier/file.py,sha256=NQnoywcVXAxLU0xipsByajs2SCRtsSqFPO8tlJl1J2w,2420
|
35
35
|
janito/change/applier/main.py,sha256=Ua-0tmOHYImSlYzmRPppz9stg50bGM1AFFUdQEFMxhY,6644
|
36
|
-
janito/change/applier/text.py,sha256=
|
36
|
+
janito/change/applier/text.py,sha256=cORCCLZdph31tJ2Jr5bueRTawrBr-m2csaGYmJexD2I,11031
|
37
37
|
janito/change/applier/workspace_dir.py,sha256=whiuIIYyDHh2m-K_ZRMZGvMMQ1nh6lzXaWGhnFK1B1o,2443
|
38
38
|
janito/change/viewer/__init__.py,sha256=tj-rIVbuAm80B7-no-YgdxbtkDlwRK_0hqUfIDtDOAc,250
|
39
|
-
janito/change/viewer/content.py,sha256=
|
39
|
+
janito/change/viewer/content.py,sha256=iHRjhbpTJMi9v0W91XLogDfbVQEwLg04hlfYJOochzo,2036
|
40
40
|
janito/change/viewer/diff.py,sha256=OzaocnrnH4RCdzZPjT05pEmFJLcd_EgpKhRiAXJrvpc,1815
|
41
|
-
janito/change/viewer/
|
42
|
-
janito/change/viewer/
|
43
|
-
janito/change/viewer/styling.py,sha256=vpOT0noD4Br-veZ8SuNihg_4RB55TZen-h3L7lX4IhM,3715
|
41
|
+
janito/change/viewer/panels.py,sha256=9i-b_vhpDK8cnh1qJ78xtg7cHxvOIMpvotdgK5oHNtU,21612
|
42
|
+
janito/change/viewer/styling.py,sha256=6i3xdnj4s5YkSH58oMgfgwZ3nD8T1tI-4Zy7HvcuoMg,4204
|
44
43
|
janito/change/viewer/themes.py,sha256=HISrK7-qR0m4dGZqFmC5loW2E1RSwAicP0mnpZvbSv0,1470
|
45
44
|
janito/clear_statement_parser/clear_statement_format.txt,sha256=_5iQylnCqgBaMVFVgx33QvEColV16oOwl1W4scu_-zc,13497
|
46
45
|
janito/clear_statement_parser/examples.txt,sha256=NnxDraTpCPZCjJjL2HvCMtA1NxBY7C0l3b5v61Y-5iY,8547
|
@@ -48,34 +47,33 @@ janito/clear_statement_parser/models.py,sha256=b7-lLHfQLI4q5dtaF4BVCwE9DI2xWwVQA
|
|
48
47
|
janito/clear_statement_parser/parser.py,sha256=KO7Bj0pEl7iPH3FQ3knTGSLMGqKS_pXe3_eqfEHBtXw,20847
|
49
48
|
janito/cli/__init__.py,sha256=3gyMSaEAH2N4mXfZTLsHXKxXDxdhlYUeAPYQuhnOVBE,77
|
50
49
|
janito/cli/base.py,sha256=WKFSxX5FKk5Se5QUZ0X3_fAQVIWG6OEGKAXKebWiRaM,1188
|
51
|
-
janito/cli/commands.py,sha256=
|
50
|
+
janito/cli/commands.py,sha256=SlS39cSKEbM1oRup96ys9SlR59JxidJp6rnR-JeRk80,2823
|
52
51
|
janito/cli/functions.py,sha256=7DSFQaxKJ7JvkA8-wPuifogGk9NvqTUqC24nU2UUbVM,4143
|
53
52
|
janito/cli/history.py,sha256=UIP_6UiGnJXmBke5hYqKXQVsOPrtKeyfBXW8vDxIoHQ,2114
|
54
53
|
janito/cli/registry.py,sha256=R1sI45YonxjMSLhAle7Dt18X_devrMsLt0ljb-rNza4,690
|
55
|
-
janito/cli/handlers/ask.py,sha256=jmD-XoP1-ldKlfNNu1WCja9NM7zJgPB3eOaglKOa7dE,829
|
56
|
-
janito/cli/handlers/demo.py,sha256=TCjN2nVUTivUDvlRxJDhx-rZnfQDR0H_6Yuteq-zkQ0,725
|
57
|
-
janito/cli/handlers/request.py,sha256=ytmmTSFzHoDPmOm-fWUEa6lkZRwL7e1VjcfJntoyvW8,1083
|
58
|
-
janito/cli/handlers/scan.py,sha256=zg4AVsFTYkNtUrLA5uCi1Gr6gxDD8PbnFP0eozPtRVw,296
|
59
54
|
janito/demo/__init__.py,sha256=vIGC6fs44yzuSK3-RgYnnanBtZwnW52ivdVbA8Yc8Lk,108
|
60
55
|
janito/demo/data.py,sha256=t208Kixcc3J6xbn43P2OSpqkpcRrrFoEXZ44oOQMcCE,415
|
61
56
|
janito/demo/mock_data.py,sha256=mBg-qF8GcRx7M40IGXGytQJOWihEUm51CJqcez1BKIk,695
|
62
57
|
janito/demo/operations.py,sha256=6QXFsrMVJqX30Y19nBD8fxTj5I6MJN4duQ2qwVG_lHY,1392
|
63
58
|
janito/demo/runner.py,sha256=Xv6v8QVlIkEnlSaNU-Jt6Yjl_NbNg_g8DMZnp8kiFGQ,2385
|
64
59
|
janito/demo/scenarios.py,sha256=xKW6cAL3tSHWP76fvbKHf2HyruhamAzHY1VaTVCkM8o,1060
|
65
|
-
janito/search_replace/README.md,sha256=
|
66
|
-
janito/search_replace/__init__.py,sha256=
|
60
|
+
janito/search_replace/README.md,sha256=ctN4ubykUdUMaqHtM9TGM31pCrdyCKiwfHn03b0cwBw,4614
|
61
|
+
janito/search_replace/__init__.py,sha256=7Er1wQRTqJ9fE7qFgzwnnhGHiEPWHel3KslOSWWDW5Q,319
|
67
62
|
janito/search_replace/__main__.py,sha256=i0Wz387fqgiHq46QXCXpU9wnwdJYinjyY6HyoJJr_xw,520
|
68
|
-
janito/search_replace/core.py,sha256=
|
63
|
+
janito/search_replace/core.py,sha256=wxx-f0SCMmNfxymfobUlhQizcFyS1rD6RnMx0YekEQs,5904
|
64
|
+
janito/search_replace/logger.py,sha256=eJR1FA-KiGfZTo416NmGCdlpp3Cgaq7jj-CDFsAGqSU,1052
|
69
65
|
janito/search_replace/parser.py,sha256=wFr5Dc7Im6oh4AcVUkpwKIc0Gf5oNBCYKT2lhexmyQg,2123
|
70
66
|
janito/search_replace/play.py,sha256=vmEqbna8CAEYk4B6Og0eETCRAYRmrBSnFTdiXopsH3M,1820
|
71
67
|
janito/search_replace/replacer.py,sha256=7MKO9PpbAMUqmnxDk1mqkZ_yWE13QwjDfvjT0uU4ypA,1556
|
72
|
-
janito/search_replace/searcher.py,sha256=
|
73
|
-
janito/
|
68
|
+
janito/search_replace/searcher.py,sha256=F23WQ14myJ4pCIpDgS0wCFM4poimrlXBz7_XF3lmTZg,17228
|
69
|
+
janito/search_replace/strategy_result.py,sha256=-XaT7blkoADV7VjFJZWTm2VztADojHmYn1dAvUBIVyw,293
|
70
|
+
janito/shell/__init__.py,sha256=TFZi_TSEefpGXQwYcavsgJ0mX8d--wzNk-7qLgqmnOI,1158
|
74
71
|
janito/shell/bus.py,sha256=xRl2-zlJsa0KPL2aSVtVJy9xH6GLw_7tEplvMIY5eCk,1041
|
75
|
-
janito/shell/commands.py,sha256=
|
76
|
-
janito/shell/handlers.py,sha256=aiS1ASNyhZNEuzUCkhqeH1_eIpBX6R3yKjYiBmG8jQI,3978
|
72
|
+
janito/shell/commands.py,sha256=pjiJhf7jZB0TORDEewyFEKjjKiSus2VRLZdvs3BiQpg,4997
|
77
73
|
janito/shell/history.py,sha256=EMSbdW9ccHQ__WA-WM5VHjnu_ihTk-4sCpQXmi7e8iI,706
|
78
|
-
janito/shell/processor.py,sha256=
|
74
|
+
janito/shell/processor.py,sha256=GvINV9eR2JLG9lZ0ZbVIfGz6E6575iMhtst4oN5qwKw,1102
|
75
|
+
janito/shell/prompt.py,sha256=zyHXbuugu8kyVtqbg3SvIWwpCQpv1qHtEBE2jbhNY8I,1744
|
76
|
+
janito/shell/registry.py,sha256=5nDeTQ8rl5ZAEaR6RefZOuf9k5wB0T20QIJV1hTciI4,2339
|
79
77
|
janito/tui/__init__.py,sha256=5u1TfGO99LmCtC8ilpXahkXWVJSWtBACqU_O8VtJewI,773
|
80
78
|
janito/tui/base.py,sha256=qU_8i0aQ3sWIkgnKQDUGr3bhypDzSdqYCkNGFfRbIos,692
|
81
79
|
janito/tui/flows/__init__.py,sha256=uI8MtTdIe2BWqbqcfJNnBdhxZcwc207wVjIWusGuDq4,161
|
@@ -84,12 +82,15 @@ janito/tui/flows/content.py,sha256=mAi4R0ncpC_PzjETqqH9kvy2n1xRKWLhNX5xqPgQjoM,4
|
|
84
82
|
janito/tui/flows/selection.py,sha256=PcrcY8hTl3ljZOmLYA_I3r3CVRdqKfqFlRxZSgS9rDo,4031
|
85
83
|
janito/tui/screens/__init__.py,sha256=YZ8NVoXMs7c_aT1NuIBiZrkLfXCzaQ85yMKZ_Uh6wlE,69
|
86
84
|
janito/tui/screens/app.py,sha256=XEiADppmDOYkjR1p7sH6N7Zqqm7RWvXSd5_udlAdvbA,92
|
87
|
-
janito/workspace/__init__.py,sha256=
|
88
|
-
janito/workspace/analysis.py,sha256=
|
89
|
-
janito/workspace/
|
90
|
-
janito/workspace/
|
91
|
-
janito
|
92
|
-
janito
|
93
|
-
janito
|
94
|
-
janito-0.
|
95
|
-
janito-0.
|
85
|
+
janito/workspace/__init__.py,sha256=BV-O8czw125wprurtIOm-DNA01ZpSojNTYGBWZx14Cw,111
|
86
|
+
janito/workspace/analysis.py,sha256=pJ6fe7P8Ex1WXlZfhjr_73ZJpPfkjxt9BMoH6aSMLh8,4084
|
87
|
+
janito/workspace/show.py,sha256=nyHBM4xTYQL61axXemq0b4O6sHtS00EQQSoeT2PdCnc,4932
|
88
|
+
janito/workspace/stats.py,sha256=KcLouvJ3xqDIf1qTZaZeAaojeuixkBNcooob2twqFPg,1325
|
89
|
+
janito/workspace/types.py,sha256=qPZj8DCC38ygFB9am2j4sXsw-cmtMMG60aAOjoVPxr0,3450
|
90
|
+
janito/workspace/workset.py,sha256=my9HBWdGz09zHGR1BmwYiPxr-rNHH-pDEs_YVNVHd64,3903
|
91
|
+
janito/workspace/workspace.py,sha256=dDx78YQjTCHoiTu7gP4n2TdFnNbmFBOC-n07ka7YKEQ,4509
|
92
|
+
janito-0.7.0.dist-info/METADATA,sha256=7KpfpqDHPRgcU2dgvHoqX6JzQyhl_1Fnih_6zpmL6gE,3990
|
93
|
+
janito-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
94
|
+
janito-0.7.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
|
95
|
+
janito-0.7.0.dist-info/licenses/LICENSE,sha256=xLIUXRPjtsgQml2zD1Pn4LpgiyZ49raw6jZDlO_gZdo,1062
|
96
|
+
janito-0.7.0.dist-info/RECORD,,
|
janito/change/viewer/pager.py
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
from rich.console import Console
|
2
|
-
import shutil
|
3
|
-
from typing import Optional
|
4
|
-
|
5
|
-
def wait_for_enter(console: Console):
|
6
|
-
"""Wait for ENTER key press to continue with progress indicator"""
|
7
|
-
console.print("\n[yellow]More content to show[/yellow]")
|
8
|
-
console.print("[dim]Press ENTER to continue...[/dim]", end="")
|
9
|
-
try:
|
10
|
-
input()
|
11
|
-
console.print() # Just add a newline
|
12
|
-
except KeyboardInterrupt:
|
13
|
-
console.print() # Just add a newline
|
14
|
-
raise KeyboardInterrupt
|
15
|
-
|
16
|
-
# Track current file being displayed
|
17
|
-
_current_file = None
|
18
|
-
|
19
|
-
def set_current_file(filename: str) -> None:
|
20
|
-
"""Set the current file being displayed"""
|
21
|
-
global _current_file
|
22
|
-
_current_file = filename
|
23
|
-
|
24
|
-
def get_current_file() -> Optional[str]:
|
25
|
-
"""Get the current file being displayed"""
|
26
|
-
return _current_file
|
27
|
-
|
28
|
-
def check_pager(console: Console, height: int, content_height: Optional[int] = None) -> int:
|
29
|
-
"""Check if we need to pause and wait for user input
|
30
|
-
|
31
|
-
Args:
|
32
|
-
console: Rich console instance
|
33
|
-
height: Current accumulated height
|
34
|
-
content_height: Optional height of content to be displayed next
|
35
|
-
|
36
|
-
Returns:
|
37
|
-
New accumulated height
|
38
|
-
"""
|
39
|
-
# Get current file being displayed
|
40
|
-
current_file = get_current_file()
|
41
|
-
if not current_file:
|
42
|
-
return height
|
43
|
-
|
44
|
-
term_height = shutil.get_terminal_size().lines
|
45
|
-
margin = 5 # Add margin to prevent too early paging
|
46
|
-
available_height = term_height - margin
|
47
|
-
|
48
|
-
# Calculate total height including upcoming content
|
49
|
-
total_height = height + (content_height or 0)
|
50
|
-
|
51
|
-
# Only page if we're at a file boundary or content won't fit
|
52
|
-
if total_height > available_height:
|
53
|
-
wait_for_enter(console)
|
54
|
-
return 0
|
55
|
-
|
56
|
-
return height
|
janito/cli/handlers/ask.py
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from typing import Optional
|
3
|
-
from rich.console import Console
|
4
|
-
from janito.config import config
|
5
|
-
from janito.qa import ask_question, display_answer
|
6
|
-
from janito.workspace.scan import collect_files_content
|
7
|
-
from ..base import BaseCLIHandler
|
8
|
-
|
9
|
-
class AskHandler(BaseCLIHandler):
|
10
|
-
def handle(self, question: str):
|
11
|
-
"""Process a question about the codebase"""
|
12
|
-
paths_to_scan = [config.workspace_dir] if not config.include else config.include
|
13
|
-
files_content = collect_files_content(paths_to_scan)
|
14
|
-
|
15
|
-
if config.tui:
|
16
|
-
answer = ask_question(question, files_content)
|
17
|
-
from janito.tui import TuiApp
|
18
|
-
app = TuiApp(content=answer)
|
19
|
-
app.run()
|
20
|
-
else:
|
21
|
-
answer = ask_question(question, files_content)
|
22
|
-
display_answer(answer)
|
janito/cli/handlers/demo.py
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
from rich.console import Console
|
2
|
-
from janito.demo import DemoRunner
|
3
|
-
from janito.demo.data import get_demo_scenarios
|
4
|
-
from ..base import BaseCLIHandler
|
5
|
-
|
6
|
-
class DemoHandler(BaseCLIHandler):
|
7
|
-
def handle(self):
|
8
|
-
"""Run demo scenarios"""
|
9
|
-
runner = DemoRunner()
|
10
|
-
|
11
|
-
# Add predefined scenarios
|
12
|
-
for scenario in get_demo_scenarios():
|
13
|
-
runner.add_scenario(scenario)
|
14
|
-
|
15
|
-
# Preview and run scenarios
|
16
|
-
self.console.print("\n[bold cyan]Demo Scenarios Preview:[/bold cyan]")
|
17
|
-
runner.preview_changes()
|
18
|
-
|
19
|
-
self.console.print("\n[bold cyan]Running Demo Scenarios:[/bold cyan]")
|
20
|
-
runner.run_all()
|
21
|
-
|
22
|
-
self.console.print("\n[green]Demo completed successfully![/green]")
|
janito/cli/handlers/request.py
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from rich.console import Console
|
3
|
-
from janito.config import config
|
4
|
-
from janito.workspace import is_dir_empty
|
5
|
-
from janito.change.core import process_change_request
|
6
|
-
from ..base import BaseCLIHandler
|
7
|
-
|
8
|
-
class RequestHandler(BaseCLIHandler):
|
9
|
-
def handle(self, request: str, preview_only: bool = False):
|
10
|
-
"""Process a modification request"""
|
11
|
-
is_empty = is_dir_empty(config.workspace_dir)
|
12
|
-
if is_empty and not config.include:
|
13
|
-
self.console.print("\n[bold blue]Empty directory - will create new files as needed[/bold blue]")
|
14
|
-
|
15
|
-
success, history_file = process_change_request(request, preview_only)
|
16
|
-
|
17
|
-
if success and history_file and config.verbose:
|
18
|
-
try:
|
19
|
-
rel_path = history_file.relative_to(config.workspace_dir)
|
20
|
-
self.console.print(f"\nChanges saved to: ./{rel_path}")
|
21
|
-
except ValueError:
|
22
|
-
self.console.print(f"\nChanges saved to: {history_file}")
|
23
|
-
elif not success:
|
24
|
-
self.console.print("[red]Failed to process change request[/red]")
|
janito/cli/handlers/scan.py
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from typing import List
|
3
|
-
from janito.workspace import preview_scan
|
4
|
-
from ..base import BaseCLIHandler
|
5
|
-
|
6
|
-
class ScanHandler(BaseCLIHandler):
|
7
|
-
def handle(self, paths_to_scan: List[Path]):
|
8
|
-
"""Preview files that would be analyzed"""
|
9
|
-
preview_scan(paths_to_scan)
|
janito/prompts.py
DELETED
janito/shell/handlers.py
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
"""Command handlers for Janito shell."""
|
2
|
-
from pathlib import Path
|
3
|
-
from rich.console import Console
|
4
|
-
from rich.table import Table
|
5
|
-
from prompt_toolkit import PromptSession
|
6
|
-
from prompt_toolkit.completion import PathCompleter
|
7
|
-
from prompt_toolkit.shortcuts import clear as ptk_clear
|
8
|
-
from janito.config import config
|
9
|
-
from janito.scan import collect_files_content
|
10
|
-
from janito.scan.analysis import analyze_workspace_content
|
11
|
-
from .registry import CommandRegistry, get_path_completer
|
12
|
-
|
13
|
-
def handle_request(args: str) -> None:
|
14
|
-
"""Handle a change request."""
|
15
|
-
if not args:
|
16
|
-
Console().print("[red]Error: Change request required[/red]")
|
17
|
-
return
|
18
|
-
from janito.cli.commands import handle_request as cli_handle_request
|
19
|
-
cli_handle_request(args)
|
20
|
-
|
21
|
-
def handle_exit(_: str) -> None:
|
22
|
-
"""Handle exit command."""
|
23
|
-
raise EOFError()
|
24
|
-
|
25
|
-
def handle_clear(_: str) -> None:
|
26
|
-
"""Handle clear command to clear terminal screen."""
|
27
|
-
ptk_clear()
|
28
|
-
|
29
|
-
def handle_ask(args: str) -> None:
|
30
|
-
"""Handle ask command."""
|
31
|
-
if not args:
|
32
|
-
Console().print("[red]Error: Question required[/red]")
|
33
|
-
return
|
34
|
-
from janito.cli.commands import handle_ask as cli_handle_ask
|
35
|
-
cli_handle_ask(args)
|
36
|
-
|
37
|
-
def handle_help(args: str) -> None:
|
38
|
-
"""Handle help command."""
|
39
|
-
console = Console()
|
40
|
-
registry = CommandRegistry()
|
41
|
-
|
42
|
-
command = args.strip() if args else None
|
43
|
-
if command and (cmd := registry.get_command(command)):
|
44
|
-
console.print(f"\n[bold]{command}[/bold]: {cmd.description}")
|
45
|
-
if cmd.usage:
|
46
|
-
console.print(f"Usage: {cmd.usage}")
|
47
|
-
return
|
48
|
-
|
49
|
-
table = Table(title="Available Commands")
|
50
|
-
table.add_column("Command", style="cyan")
|
51
|
-
table.add_column("Description")
|
52
|
-
|
53
|
-
for name, cmd in sorted(registry.get_commands().items()):
|
54
|
-
table.add_row(name, cmd.description)
|
55
|
-
|
56
|
-
console.print(table)
|
57
|
-
|
58
|
-
def handle_include(args: str) -> None:
|
59
|
-
"""Handle include command with path completion."""
|
60
|
-
console = Console()
|
61
|
-
session = PromptSession()
|
62
|
-
completer = PathCompleter()
|
63
|
-
|
64
|
-
# If no args provided, prompt with completion
|
65
|
-
if not args:
|
66
|
-
try:
|
67
|
-
args = session.prompt("Enter paths (space separated): ", completer=completer)
|
68
|
-
except (KeyboardInterrupt, EOFError):
|
69
|
-
return
|
70
|
-
|
71
|
-
paths = [p.strip() for p in args.split() if p.strip()]
|
72
|
-
if not paths:
|
73
|
-
console.print("[red]Error: At least one path required[/red]")
|
74
|
-
return
|
75
|
-
|
76
|
-
resolved_paths = []
|
77
|
-
for path_str in paths:
|
78
|
-
path = Path(path_str)
|
79
|
-
if not path.is_absolute():
|
80
|
-
path = config.workdir / path
|
81
|
-
resolved_paths.append(path.resolve())
|
82
|
-
|
83
|
-
config.set_include(resolved_paths)
|
84
|
-
content = collect_files_content(resolved_paths)
|
85
|
-
analyze_workspace_content(content)
|
86
|
-
|
87
|
-
console.print(f"[green]Updated include paths:[/green]")
|
88
|
-
for path in resolved_paths:
|
89
|
-
console.print(f" {path}")
|
90
|
-
|
91
|
-
def handle_rinclude(args: str) -> None:
|
92
|
-
"""Handle rinclude command with recursive path scanning."""
|
93
|
-
console = Console()
|
94
|
-
session = PromptSession()
|
95
|
-
completer = get_path_completer(only_directories=True)
|
96
|
-
|
97
|
-
if not args:
|
98
|
-
try:
|
99
|
-
args = session.prompt("Enter directory paths (space separated): ", completer=completer)
|
100
|
-
except (KeyboardInterrupt, EOFError):
|
101
|
-
return
|
102
|
-
|
103
|
-
paths = [p.strip() for p in args.split() if p.strip()]
|
104
|
-
if not paths:
|
105
|
-
console.print("[red]Error: At least one path required[/red]")
|
106
|
-
return
|
107
|
-
|
108
|
-
resolved_paths = []
|
109
|
-
for path_str in paths:
|
110
|
-
path = Path(path_str)
|
111
|
-
if not path.is_absolute():
|
112
|
-
path = config.workdir / path
|
113
|
-
resolved_paths.append(path.resolve())
|
114
|
-
|
115
|
-
config.set_recursive(resolved_paths)
|
116
|
-
config.set_include(resolved_paths)
|
117
|
-
content = collect_files_content(resolved_paths)
|
118
|
-
analyze_workspace_content(content)
|
119
|
-
|
120
|
-
console.print(f"[green]Updated recursive include paths:[/green]")
|
121
|
-
for path in resolved_paths:
|
122
|
-
console.print(f" {path}")
|
janito/workspace/manager.py
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
from pathlib import Path
|
2
|
-
from typing import Dict, List, Optional, Set
|
3
|
-
from collections import defaultdict
|
4
|
-
|
5
|
-
class WorkspaceManager:
|
6
|
-
"""Manages workspace state and operations using singleton pattern."""
|
7
|
-
_instance = None
|
8
|
-
|
9
|
-
def __init__(self):
|
10
|
-
if WorkspaceManager._instance is not None:
|
11
|
-
raise RuntimeError("Use WorkspaceManager.get_instance() instead")
|
12
|
-
self.content: str = ""
|
13
|
-
self.scan_completed: bool = False
|
14
|
-
self._analyzed: bool = False
|
15
|
-
|
16
|
-
@classmethod
|
17
|
-
def get_instance(cls) -> "WorkspaceManager":
|
18
|
-
"""Get singleton instance of WorkspaceManager."""
|
19
|
-
if cls._instance is None:
|
20
|
-
cls._instance = cls()
|
21
|
-
return cls._instance
|
22
|
-
|
23
|
-
def collect_content(self, paths: List[Path]) -> None:
|
24
|
-
"""Collect and store content from specified paths."""
|
25
|
-
from .scan import _scan_paths
|
26
|
-
content_parts, _, _, _ = _scan_paths(paths)
|
27
|
-
self.content = "\n".join(content_parts)
|
28
|
-
self.scan_completed = True
|
29
|
-
self._analyzed = False
|
30
|
-
|
31
|
-
def analyze(self) -> None:
|
32
|
-
"""Analyze workspace content and update statistics."""
|
33
|
-
from .analysis import analyze_workspace_content
|
34
|
-
if not self.scan_completed:
|
35
|
-
return
|
36
|
-
if not self._analyzed and self.content:
|
37
|
-
analyze_workspace_content(self.content)
|
38
|
-
self._analyzed = True
|
39
|
-
|
40
|
-
def get_content(self) -> str:
|
41
|
-
"""Get collected workspace content."""
|
42
|
-
return self.content
|
43
|
-
|
44
|
-
def clear(self) -> None:
|
45
|
-
"""Clear workspace content and stats."""
|
46
|
-
self.content = ""
|
47
|
-
self.scan_completed = False
|
48
|
-
self._analyzed = False
|