indent 0.1__tar.gz → 0.1.2__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.
Potentially problematic release.
This version of indent might be problematic. Click here for more details.
- indent-0.1.2/.gitignore +176 -0
- indent-0.1.2/PKG-INFO +35 -0
- indent-0.1.2/exponent/__init__.py +1 -0
- indent-0.1.2/exponent/cli.py +112 -0
- indent-0.1.2/exponent/commands/cloud_commands.py +85 -0
- indent-0.1.2/exponent/commands/common.py +434 -0
- indent-0.1.2/exponent/commands/config_commands.py +581 -0
- indent-0.1.2/exponent/commands/github_app_commands.py +211 -0
- indent-0.1.2/exponent/commands/listen_commands.py +96 -0
- indent-0.1.2/exponent/commands/run_commands.py +208 -0
- indent-0.1.2/exponent/commands/settings.py +56 -0
- indent-0.1.2/exponent/commands/shell_commands.py +2840 -0
- indent-0.1.2/exponent/commands/theme.py +246 -0
- indent-0.1.2/exponent/commands/types.py +111 -0
- indent-0.1.2/exponent/commands/upgrade.py +29 -0
- indent-0.1.2/exponent/commands/utils.py +236 -0
- indent-0.1.2/exponent/core/config.py +180 -0
- indent-0.1.2/exponent/core/graphql/__init__.py +0 -0
- indent-0.1.2/exponent/core/graphql/client.py +59 -0
- indent-0.1.2/exponent/core/graphql/cloud_config_queries.py +77 -0
- indent-0.1.2/exponent/core/graphql/get_chats_query.py +47 -0
- indent-0.1.2/exponent/core/graphql/github_config_queries.py +56 -0
- indent-0.1.2/exponent/core/graphql/mutations.py +75 -0
- indent-0.1.2/exponent/core/graphql/queries.py +110 -0
- indent-0.1.2/exponent/core/graphql/subscriptions.py +452 -0
- indent-0.1.2/exponent/core/remote_execution/checkpoints.py +212 -0
- indent-0.1.2/exponent/core/remote_execution/cli_rpc_types.py +217 -0
- indent-0.1.2/exponent/core/remote_execution/client.py +545 -0
- indent-0.1.2/exponent/core/remote_execution/code_execution.py +58 -0
- indent-0.1.2/exponent/core/remote_execution/error_info.py +45 -0
- indent-0.1.2/exponent/core/remote_execution/exceptions.py +10 -0
- indent-0.1.2/exponent/core/remote_execution/file_write.py +410 -0
- indent-0.1.2/exponent/core/remote_execution/files.py +443 -0
- indent-0.1.2/exponent/core/remote_execution/git.py +268 -0
- indent-0.1.2/exponent/core/remote_execution/languages/python_execution.py +239 -0
- indent-0.1.2/exponent/core/remote_execution/languages/shell_streaming.py +221 -0
- indent-0.1.2/exponent/core/remote_execution/languages/types.py +20 -0
- indent-0.1.2/exponent/core/remote_execution/session.py +128 -0
- indent-0.1.2/exponent/core/remote_execution/system_context.py +54 -0
- indent-0.1.2/exponent/core/remote_execution/tool_execution.py +284 -0
- indent-0.1.2/exponent/core/remote_execution/truncation.py +284 -0
- indent-0.1.2/exponent/core/remote_execution/types.py +670 -0
- indent-0.1.2/exponent/core/remote_execution/utils.py +600 -0
- indent-0.1.2/exponent/core/types/__init__.py +0 -0
- indent-0.1.2/exponent/core/types/command_data.py +206 -0
- indent-0.1.2/exponent/core/types/event_types.py +89 -0
- indent-0.1.2/exponent/core/types/generated/__init__.py +0 -0
- indent-0.1.2/exponent/core/types/generated/strategy_info.py +225 -0
- indent-0.1.2/exponent/migration-docs/login.md +112 -0
- indent-0.1.2/exponent/py.typed +4 -0
- indent-0.1.2/exponent/utils/__init__.py +0 -0
- indent-0.1.2/exponent/utils/colors.py +92 -0
- indent-0.1.2/exponent/utils/version.py +289 -0
- indent-0.1.2/pyproject.toml +165 -0
- indent-0.1/PKG-INFO +0 -12
- indent-0.1/indent/indent.py +0 -22
- indent-0.1/indent/test.py +0 -13
- indent-0.1/setup.cfg +0 -2
- indent-0.1/setup.py +0 -14
indent-0.1.2/.gitignore
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Vercel Folder
|
|
2
|
+
.vercel
|
|
3
|
+
|
|
4
|
+
# Byte-compiled / optimized / DLL files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
.env
|
|
9
|
+
.env.production
|
|
10
|
+
.env.*_db
|
|
11
|
+
.gcp-sa-credentials.json
|
|
12
|
+
.indent-gh-app.pem
|
|
13
|
+
workflow_input.json
|
|
14
|
+
.anthropic.log.json
|
|
15
|
+
CLAUDE.local.md
|
|
16
|
+
|
|
17
|
+
# C extensions
|
|
18
|
+
*.so
|
|
19
|
+
|
|
20
|
+
# Distribution / packaging
|
|
21
|
+
.Python
|
|
22
|
+
build/
|
|
23
|
+
develop-eggs/
|
|
24
|
+
dist/
|
|
25
|
+
downloads/
|
|
26
|
+
eggs/
|
|
27
|
+
.eggs/
|
|
28
|
+
lib/
|
|
29
|
+
lib64/
|
|
30
|
+
parts/
|
|
31
|
+
sdist/
|
|
32
|
+
var/
|
|
33
|
+
wheels/
|
|
34
|
+
pip-wheel-metadata/
|
|
35
|
+
share/python-wheels/
|
|
36
|
+
*.egg-info/
|
|
37
|
+
.installed.cfg
|
|
38
|
+
*.egg
|
|
39
|
+
MANIFEST
|
|
40
|
+
|
|
41
|
+
# PyInstaller
|
|
42
|
+
# Usually these files are written by a python script from a template
|
|
43
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
44
|
+
*.manifest
|
|
45
|
+
*.spec
|
|
46
|
+
|
|
47
|
+
# Installer logs
|
|
48
|
+
pip-log.txt
|
|
49
|
+
pip-delete-this-directory.txt
|
|
50
|
+
|
|
51
|
+
# Unit test / coverage reports
|
|
52
|
+
htmlcov/
|
|
53
|
+
.tox/
|
|
54
|
+
.nox/
|
|
55
|
+
.coverage
|
|
56
|
+
.coverage.*
|
|
57
|
+
.cache
|
|
58
|
+
nosetests.xml
|
|
59
|
+
coverage.xml
|
|
60
|
+
*.cover
|
|
61
|
+
*.py,cover
|
|
62
|
+
.hypothesis/
|
|
63
|
+
.pytest_cache/
|
|
64
|
+
log.txt
|
|
65
|
+
|
|
66
|
+
# Translations
|
|
67
|
+
*.mo
|
|
68
|
+
*.pot
|
|
69
|
+
|
|
70
|
+
# Django stuff:
|
|
71
|
+
*.log
|
|
72
|
+
local_settings.py
|
|
73
|
+
db.sqlite3
|
|
74
|
+
db.sqlite3-journal
|
|
75
|
+
|
|
76
|
+
# Flask stuff:
|
|
77
|
+
instance/
|
|
78
|
+
.webassets-cache
|
|
79
|
+
|
|
80
|
+
# Scrapy stuff:
|
|
81
|
+
.scrapy
|
|
82
|
+
|
|
83
|
+
# Sphinx documentation
|
|
84
|
+
docs/_build/
|
|
85
|
+
|
|
86
|
+
# PyBuilder
|
|
87
|
+
target/
|
|
88
|
+
|
|
89
|
+
# Jupyter Notebook
|
|
90
|
+
.ipynb_checkpoints
|
|
91
|
+
|
|
92
|
+
# IPython
|
|
93
|
+
profile_default/
|
|
94
|
+
ipython_config.py
|
|
95
|
+
|
|
96
|
+
# pyenv
|
|
97
|
+
.python-version
|
|
98
|
+
|
|
99
|
+
# pipenv
|
|
100
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
101
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
102
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
103
|
+
# install all needed dependencies.
|
|
104
|
+
#Pipfile.lock
|
|
105
|
+
|
|
106
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
107
|
+
__pypackages__/
|
|
108
|
+
|
|
109
|
+
# Celery stuff
|
|
110
|
+
celerybeat-schedule
|
|
111
|
+
celerybeat.pid
|
|
112
|
+
|
|
113
|
+
# SageMath parsed files
|
|
114
|
+
*.sage.py
|
|
115
|
+
|
|
116
|
+
# Environments
|
|
117
|
+
|
|
118
|
+
.venv
|
|
119
|
+
env/
|
|
120
|
+
venv/
|
|
121
|
+
ENV/
|
|
122
|
+
env.bak/
|
|
123
|
+
venv.bak/
|
|
124
|
+
|
|
125
|
+
# Spyder project settings
|
|
126
|
+
.spyderproject
|
|
127
|
+
.spyproject
|
|
128
|
+
|
|
129
|
+
# Rope project settings
|
|
130
|
+
.ropeproject
|
|
131
|
+
|
|
132
|
+
# mkdocs documentation
|
|
133
|
+
/site
|
|
134
|
+
|
|
135
|
+
# mypy
|
|
136
|
+
.mypy_cache/
|
|
137
|
+
.dmypy.json
|
|
138
|
+
dmypy.json
|
|
139
|
+
|
|
140
|
+
# ruff
|
|
141
|
+
.ruff_cache
|
|
142
|
+
|
|
143
|
+
# Pyre type checker
|
|
144
|
+
.pyre/
|
|
145
|
+
|
|
146
|
+
.idea
|
|
147
|
+
.vscode/
|
|
148
|
+
.DS_Store
|
|
149
|
+
|
|
150
|
+
# Sentry
|
|
151
|
+
.sentryclirc
|
|
152
|
+
|
|
153
|
+
# Aider
|
|
154
|
+
.aider*
|
|
155
|
+
|
|
156
|
+
# Debug logs
|
|
157
|
+
debug/
|
|
158
|
+
|
|
159
|
+
# Benchmarks
|
|
160
|
+
.benchy.*
|
|
161
|
+
node_modules
|
|
162
|
+
finetune
|
|
163
|
+
|
|
164
|
+
# Codegen
|
|
165
|
+
benchmark_specs.csv
|
|
166
|
+
generated_benchmarks/
|
|
167
|
+
|
|
168
|
+
# pnpm
|
|
169
|
+
.pnpm-store/
|
|
170
|
+
|
|
171
|
+
# GitHub App private keys
|
|
172
|
+
*.private-key.pem
|
|
173
|
+
private-key.pem
|
|
174
|
+
|
|
175
|
+
# Claude Code
|
|
176
|
+
.claude
|
indent-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: indent
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Indent is an AI Pair Programmer
|
|
5
|
+
Author-email: Sashank Thupukari <sashank@exponent.run>
|
|
6
|
+
Requires-Python: <3.13,>=3.10
|
|
7
|
+
Requires-Dist: anyio<5,>=4.6.0
|
|
8
|
+
Requires-Dist: async-timeout<5,>=4.0.3; python_version < '3.11'
|
|
9
|
+
Requires-Dist: beautifulsoup4[chardet]<5,>=4.13.4
|
|
10
|
+
Requires-Dist: certifi<2025,>=2024.8.30
|
|
11
|
+
Requires-Dist: click<9,>=8.1.7
|
|
12
|
+
Requires-Dist: colour<0.2,>=0.1.5
|
|
13
|
+
Requires-Dist: diff-match-patch<20230431,>=20230430
|
|
14
|
+
Requires-Dist: eval-type-backport<0.3,>=0.2.0
|
|
15
|
+
Requires-Dist: git-python>=1.0.3
|
|
16
|
+
Requires-Dist: gitignore-parser<0.2,>=0.1.11
|
|
17
|
+
Requires-Dist: gql[httpx,websockets]<4,>=3.5.0
|
|
18
|
+
Requires-Dist: httpx<0.28,>=0.27.0
|
|
19
|
+
Requires-Dist: ipykernel<7,>=6.29.4
|
|
20
|
+
Requires-Dist: jupyter-client<9,>=8.6.1
|
|
21
|
+
Requires-Dist: msgspec>=0.19.0
|
|
22
|
+
Requires-Dist: packaging~=24.1
|
|
23
|
+
Requires-Dist: pip<26,>=25.0.1
|
|
24
|
+
Requires-Dist: prompt-toolkit<4,>=3.0.36
|
|
25
|
+
Requires-Dist: pydantic-settings<3,>=2.2.1
|
|
26
|
+
Requires-Dist: pydantic[email]<3,>=2.6.4
|
|
27
|
+
Requires-Dist: pygit2<2,>=1.15.0
|
|
28
|
+
Requires-Dist: python-ripgrep==0.0.8
|
|
29
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
30
|
+
Requires-Dist: questionary<3,>=2.0.1
|
|
31
|
+
Requires-Dist: rapidfuzz<4,>=3.9.0
|
|
32
|
+
Requires-Dist: rich<14,>=13.7.1
|
|
33
|
+
Requires-Dist: sentry-sdk<3,>=2.1.1
|
|
34
|
+
Requires-Dist: toml<0.11,>=0.10.2
|
|
35
|
+
Requires-Dist: websockets~=11.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.2" # Keep in sync with pyproject.toml
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from click import Context, HelpFormatter
|
|
3
|
+
|
|
4
|
+
from exponent.commands.cloud_commands import cloud_cli
|
|
5
|
+
from exponent.commands.common import set_log_level
|
|
6
|
+
from exponent.commands.config_commands import config_cli
|
|
7
|
+
from exponent.commands.github_app_commands import github_app_cli
|
|
8
|
+
from exponent.commands.listen_commands import listen_cli
|
|
9
|
+
from exponent.commands.run_commands import run_cli
|
|
10
|
+
from exponent.commands.shell_commands import shell_cli
|
|
11
|
+
from exponent.commands.types import ExponentGroup, exponent_cli_group
|
|
12
|
+
from exponent.commands.upgrade import upgrade_cli
|
|
13
|
+
from exponent.utils.version import (
|
|
14
|
+
get_installed_version,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@exponent_cli_group()
|
|
19
|
+
@click.version_option(get_installed_version(), prog_name="Indent CLI")
|
|
20
|
+
@click.pass_context
|
|
21
|
+
def cli(ctx: Context) -> None:
|
|
22
|
+
"""
|
|
23
|
+
Indent: Your AI pair programmer.
|
|
24
|
+
|
|
25
|
+
Run indent run to start
|
|
26
|
+
"""
|
|
27
|
+
set_log_level()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
sources: list[ExponentGroup] = [
|
|
31
|
+
config_cli, # Configuration commands
|
|
32
|
+
run_cli, # Run AI chat commands
|
|
33
|
+
shell_cli, # Shell interaction commands
|
|
34
|
+
upgrade_cli, # Upgrade-related commands
|
|
35
|
+
cloud_cli, # Cloud commands
|
|
36
|
+
listen_cli, # Listen to chat events
|
|
37
|
+
github_app_cli, # Setup github app installation
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
for source in sources:
|
|
41
|
+
for command in source.commands.values():
|
|
42
|
+
cli.add_command(command)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def format_commands(
|
|
46
|
+
ctx: Context, formatter: HelpFormatter, include_hidden: bool = False
|
|
47
|
+
) -> None:
|
|
48
|
+
commands = []
|
|
49
|
+
hidden_commands = []
|
|
50
|
+
for cmd_name in cli.list_commands(ctx):
|
|
51
|
+
cmd = cli.get_command(ctx, cmd_name)
|
|
52
|
+
if cmd is None:
|
|
53
|
+
continue
|
|
54
|
+
if cmd.hidden:
|
|
55
|
+
hidden_commands.append((cmd_name, cmd))
|
|
56
|
+
else:
|
|
57
|
+
commands.append((cmd_name, cmd))
|
|
58
|
+
|
|
59
|
+
if commands:
|
|
60
|
+
max_cmd_length = (
|
|
61
|
+
max(len(cmd_name) for cmd_name, _ in commands) if commands else 0
|
|
62
|
+
)
|
|
63
|
+
limit = (
|
|
64
|
+
(formatter.width or 80) - 6 - max_cmd_length
|
|
65
|
+
) # Default width to 80 if None
|
|
66
|
+
rows = []
|
|
67
|
+
for cmd_name, cmd in commands:
|
|
68
|
+
help_text = cmd.get_short_help_str(limit)
|
|
69
|
+
rows.append((cmd_name, help_text))
|
|
70
|
+
|
|
71
|
+
with formatter.section("Commands"):
|
|
72
|
+
formatter.write_dl(rows)
|
|
73
|
+
|
|
74
|
+
if include_hidden and hidden_commands:
|
|
75
|
+
max_cmd_length = (
|
|
76
|
+
max(len(cmd_name) for cmd_name, _ in hidden_commands)
|
|
77
|
+
if hidden_commands
|
|
78
|
+
else 0
|
|
79
|
+
)
|
|
80
|
+
limit = (
|
|
81
|
+
(formatter.width or 80) - 6 - max_cmd_length
|
|
82
|
+
) # Default width to 80 if None
|
|
83
|
+
hidden_rows = []
|
|
84
|
+
for cmd_name, cmd in hidden_commands:
|
|
85
|
+
help_text = cmd.get_short_help_str(limit)
|
|
86
|
+
hidden_rows.append((cmd_name, help_text))
|
|
87
|
+
|
|
88
|
+
with formatter.section("Hidden Commands"):
|
|
89
|
+
formatter.write_dl(hidden_rows)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@cli.command(hidden=True)
|
|
93
|
+
@click.pass_context
|
|
94
|
+
def hidden(ctx: Context) -> None:
|
|
95
|
+
"""Show all commands, including hidden ones."""
|
|
96
|
+
formatter = ctx.make_formatter()
|
|
97
|
+
with formatter.section("Usage"):
|
|
98
|
+
if ctx.parent and ctx.parent.command:
|
|
99
|
+
formatter.write_usage(
|
|
100
|
+
ctx.parent.command.name or "exponent", "COMMAND [ARGS]..."
|
|
101
|
+
)
|
|
102
|
+
formatter.write_paragraph()
|
|
103
|
+
with formatter.indentation():
|
|
104
|
+
if cli.help:
|
|
105
|
+
formatter.write_text(cli.help)
|
|
106
|
+
formatter.write_paragraph()
|
|
107
|
+
format_commands(ctx, formatter, include_hidden=True)
|
|
108
|
+
click.echo(formatter.getvalue().rstrip("\n"))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
cli()
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from exponent.commands.common import (
|
|
7
|
+
check_inside_git_repo,
|
|
8
|
+
check_running_from_home_directory,
|
|
9
|
+
check_ssl,
|
|
10
|
+
create_cloud_chat,
|
|
11
|
+
redirect_to_login,
|
|
12
|
+
start_chat_turn,
|
|
13
|
+
)
|
|
14
|
+
from exponent.commands.settings import use_settings
|
|
15
|
+
from exponent.commands.types import exponent_cli_group
|
|
16
|
+
from exponent.commands.utils import (
|
|
17
|
+
launch_exponent_browser,
|
|
18
|
+
print_exponent_message,
|
|
19
|
+
)
|
|
20
|
+
from exponent.core.config import Settings
|
|
21
|
+
from exponent.utils.version import check_exponent_version_and_upgrade
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@exponent_cli_group(hidden=True)
|
|
25
|
+
def cloud_cli() -> None:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@cloud_cli.command(hidden=True)
|
|
30
|
+
@click.option(
|
|
31
|
+
"--cloud-config-id",
|
|
32
|
+
help="ID of an existing cloud config to reconnect",
|
|
33
|
+
required=True,
|
|
34
|
+
)
|
|
35
|
+
@click.option(
|
|
36
|
+
"--prompt",
|
|
37
|
+
help="Prompt to kick off the cloud session.",
|
|
38
|
+
required=True,
|
|
39
|
+
)
|
|
40
|
+
@click.option(
|
|
41
|
+
"--background",
|
|
42
|
+
"-b",
|
|
43
|
+
help="Start the cloud session without launching the Exponent UI",
|
|
44
|
+
is_flag=True,
|
|
45
|
+
default=False,
|
|
46
|
+
)
|
|
47
|
+
@use_settings
|
|
48
|
+
def cloud(
|
|
49
|
+
settings: Settings,
|
|
50
|
+
cloud_config_id: str,
|
|
51
|
+
prompt: str,
|
|
52
|
+
background: bool,
|
|
53
|
+
) -> None:
|
|
54
|
+
check_exponent_version_and_upgrade(settings)
|
|
55
|
+
|
|
56
|
+
if not settings.api_key:
|
|
57
|
+
redirect_to_login(settings)
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
loop = asyncio.get_event_loop()
|
|
61
|
+
|
|
62
|
+
check_running_from_home_directory()
|
|
63
|
+
loop.run_until_complete(check_inside_git_repo(settings))
|
|
64
|
+
check_ssl()
|
|
65
|
+
|
|
66
|
+
api_key = settings.api_key
|
|
67
|
+
base_url = settings.base_url
|
|
68
|
+
base_api_url = settings.get_base_api_url()
|
|
69
|
+
base_ws_url = settings.get_base_ws_url()
|
|
70
|
+
|
|
71
|
+
chat_uuid = loop.run_until_complete(
|
|
72
|
+
create_cloud_chat(api_key, base_api_url, base_ws_url, cloud_config_id)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if chat_uuid is None:
|
|
76
|
+
sys.exit(1)
|
|
77
|
+
|
|
78
|
+
loop.run_until_complete(
|
|
79
|
+
start_chat_turn(api_key, base_api_url, base_ws_url, chat_uuid, prompt)
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
print_exponent_message(base_url, chat_uuid)
|
|
83
|
+
|
|
84
|
+
if not background:
|
|
85
|
+
launch_exponent_browser(settings.environment, base_url, chat_uuid)
|