Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
75deaba
crisp: add `ty` as a dev dependency
kkysen Nov 16, 2025
fd6f05e
crisp: add `mypy` as a dev dependency
kkysen Nov 16, 2025
7662e07
crisp: add `types-{docker,requests,toml}` dev dependencies for `mypy`
kkysen Nov 16, 2025
8b9a3bb
crisp: fix `def _all_field_types` to include `@property`s
kkysen Nov 18, 2025
ad9c5fc
crisp: define properties with `@property` on an annotated method
kkysen Nov 16, 2025
0720e59
crisp: use kwargs for `pygit2` calls, as one of the args was wrong
kkysen Nov 16, 2025
b501a08
crisp: fix typo in `def _print_step_value` (`y` instead of `v`)
kkysen Nov 16, 2025
af28093
crisp: fix return type for `def find_unsafe`
kkysen Nov 16, 2025
c004c5a
crisp: use a `list` instead of `tuple` for `status_cmd` to fix `mypy`…
kkysen Nov 16, 2025
b3e1926
crisp: fix return type for `def Workflow.transpile`
kkysen Nov 16, 2025
0205e11
crisp: fix `def _all_field_types` to include `ClassVar[T]`s as `T`s
kkysen Nov 18, 2025
4a7f7e6
crisp: add type for `Node.KIND` (`ClassVar[str]`)
kkysen Nov 17, 2025
b834fa0
crisp: add type for `WorkContainer.container`
kkysen Nov 17, 2025
9c7bd11
crisp: add `Self` return type to `def Node.new`
kkysen Nov 17, 2025
b70e763
crisp: add type for `tree_files` with `TypeAlias` for the recursive type
kkysen Nov 17, 2025
4100e30
crisp: add return type to `def SudoSandbox._run_sudo`
kkysen Nov 17, 2025
d3b03a0
crisp: fix return type of `def run_rewrite`
kkysen Nov 17, 2025
22c0214
crisp: fix return type for `def emit_files` (`tuple[]` needs to be used)
kkysen Nov 17, 2025
ac88ca0
crisp: fix type for `glob_filter` arg of `def emit_files`
kkysen Nov 17, 2025
96e7594
crisp: replace runtime-defined `Sandbox` type with `class Sandbox(ABC)`
kkysen Nov 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crisp/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ def crisp_git_state(subdir=None) -> str:
return "unknown"
rev = p.stdout.decode("utf-8").strip()

status_cmd = ("git", "status", "--porcelain=v1", "-z")
status_cmd = ["git", "status", "--porcelain=v1", "-z"]
if subdir is not None:
status_cmd = status_cmd + (subdir,)
status_cmd.append(subdir)
p = subprocess.run(status_cmd, cwd=_CRISP_DIR, check=True, stdout=subprocess.PIPE)

parts = p.stdout.split(b"\0")
Expand Down Expand Up @@ -297,6 +297,6 @@ def _find_unsafe_impl(
return n


def find_unsafe(cfg: Config, mvir: MVIR, code: TreeNode) -> CompileCommandsOpNode:
def find_unsafe(cfg: Config, mvir: MVIR, code: TreeNode) -> FindUnsafeAnalysisNode:
commit = crisp_git_state("tools/find_unsafe")
return _find_unsafe_impl(cfg, mvir, code, commit)
15 changes: 9 additions & 6 deletions crisp/git.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
import pygit2
from typing import Optional
from typing import Optional, TypeAlias

from . import mvir as mvir_module
from .mvir import MVIR, TreeNode, FileNode
Expand All @@ -15,15 +15,15 @@ def get_repo(mvir: MVIR) -> pygit2.Repository:

try:
return pygit2.Repository(
path,
pygit2.GIT_REPOSITORY_OPEN_NO_SEARCH
path=path,
flags=pygit2.GIT_REPOSITORY_OPEN_NO_SEARCH
| pygit2.GIT_REPOSITORY_OPEN_BARE
| pygit2.GIT_REPOSITORY_OPEN_NO_DOTGIT,
)
except pygit2.GitError:
return pygit2.init_repository(
path,
pygit2.GIT_REPOSITORY_INIT_BARE
path=path,
flags=pygit2.GIT_REPOSITORY_INIT_BARE
| pygit2.GIT_REPOSITORY_INIT_NO_REINIT
| pygit2.GIT_REPOSITORY_INIT_NO_DOTGIT_DIR,
)
Expand Down Expand Up @@ -76,6 +76,9 @@ def render(mvir: MVIR, target: TreeNode) -> pygit2.Oid:
return commit


Tree: TypeAlias = dict[str, "Tree" | FileNode]


def commit_tree(
mvir: MVIR,
repo: pygit2.Repository,
Expand All @@ -86,7 +89,7 @@ def commit_tree(
# Convert the `TreeNode`'s flat path->ID mapping to a nested structure like
# the one used by git tree objects. At each level, each entry is either a
# `FileNode` or a dict representing a directory.
tree_files = {}
tree_files: Tree = {}

def get_parent_and_name(path):
head, tail = os.path.split(path)
Expand Down
20 changes: 13 additions & 7 deletions crisp/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import pathlib
import re
from typing import Iterable
import requests

from .config import Config, ModelConfig
Expand Down Expand Up @@ -41,9 +42,9 @@ def emit_file(n: FileNode, path, file_type="Rust"):
def emit_files(
mvir: MVIR,
n: TreeNode,
glob_filter: str = None,
glob_filter: Iterable[str] | str | None = None,
file_type_map: dict[str, str] = DEFAULT_FILE_TYPE_MAP,
) -> (str, dict[str, str]):
) -> tuple[str, dict[str, str]]:
"""
Generate markdown-formatted text giving the contents of files in `n`, along
with a dict mapping short path names used in the output to full paths as
Expand All @@ -53,8 +54,13 @@ def emit_files(
"""
assert isinstance(n, TreeNode)

if isinstance(glob_filter, str):
glob_filter = (glob_filter,)
glob_filters: Iterable[str] | None
if glob_filter is None:
glob_filters = None
elif isinstance(glob_filter, str):
glob_filters = (glob_filter,)
else:
glob_filters = glob_filter

if len(n.files) == 0:
common_prefix = ""
Expand All @@ -66,9 +72,9 @@ def emit_files(
parts = []
short_path_map = {}
for path, child_id in n.files.items():
if glob_filter is not None:
if glob_filters is not None:
path_obj = pathlib.Path(path)
glob_match = any(path_obj.match(g) for g in glob_filter)
glob_match = any(path_obj.match(g) for g in glob_filters)
if not glob_match:
continue

Expand Down Expand Up @@ -325,7 +331,7 @@ def run_rewrite(
file_type_map=DEFAULT_FILE_TYPE_MAP,
format_kwargs: dict = {},
think: bool = False,
) -> TreeNode:
) -> tuple[TreeNode, LlmOpNode]:
model = API_MODEL or cfg.model
if model is None:
model = get_default_model()
Expand Down
Loading