# applydir
[](https://github.com/eyecantell/applydir/actions/runs/18212548824)
[](https://badge.fury.io/py/applydir)
[](https://www.python.org/downloads/)
[](https://pepy.tech/project/applydir)
[](https://opensource.org/licenses/MIT)
## Overview
`applydir` is a Python command-line tool that automates the application of LLM-generated code changes to a codebase. It processes changes specified in a JSON format, supporting actions like line replacements, file creation, and deletion. Changes are applied directly to the codebase—use Git or other version control tools (e.g., via planned `vibedir` integration) for tracking and reverting. Designed to integrate with `prepdir` (for logging and configuration) and eventually `vibedir` (for LLM communication, Git integration, and linting), `applydir` validates and applies changes with robust error handling, fuzzy matching for reliability, and resolvable file paths.
## Features
- **Supported Actions**:
- `replace_lines`: Replace blocks of lines in existing files (unified approach for modifications, additions, deletions).
- `create_file`: Create new files with specified content.
- `delete_file`: Delete files (configurable via `--no-allow-file-deletion`).
- **Reliability**: Uses fuzzy matching (Levenshtein or sequence matcher, configurable) to locate lines in existing files, with options for whitespace handling and case sensitivity.
- **JSON Input**: Processes a simple JSON structure with `file_entries`, each containing `file`, `action`, and `changes` (with `original_lines` and `changed_lines` for replacements).
- **Resolvable Paths**: Accepts relative or absolute file paths, resolved relative to `--base-dir` (default: current directory).
- **Validation**: Validates JSON structure, file paths, and non-ASCII characters (configurable via `config.yaml` or `--non-ascii-action`).
- **Configuration**: Loads defaults from `.applydir/config.yaml` or bundled `src/applydir/config.yaml` using `prepdir`'s `load_config`. Overrides via CLI or programmatic `config_override`.
- **Error Handling**: Returns structured `ApplydirError` objects with type, severity, message, and details; logged via `prepdir`'s logging system.
- **CLI Utility**: Run `applydir <input_file>` with options to customize behavior.
- **Direct Application**: Changes are applied directly to files for simplicity; track/revert via Git in workflows like `vibedir`.
- **Modular Design**: Separates JSON parsing (`ApplydirChanges`), change validation (`ApplydirFileChange`), matching (`ApplydirMatcher`), and application (`ApplydirApplicator`).
## JSON Format
Changes are provided in a JSON object with a `file_entries` array:
```json
{
"file_entries": [
{
"file": "<relative_or_absolute_file_path>",
"action": "<replace_lines|create_file|delete_file>",
"changes": [
{
"original_lines": ["<lines to match in existing file (empty for create_file)>"],
"changed_lines": ["<new lines to insert (full content for create_file)>"]
}
]
}
]
}
```
### Prompting to use applydir
To facilitate integration with, the `applydir_format_description` function provides a detailed prompt for LLMs to generate JSON changes compatible with `applydir`. The function includes:
- **Structure and Requirements**: Describes the JSON format, including `file_entries`, supported actions (`replace_lines`, `create_file`, `delete_file`), and validation rules (e.g., non-empty `original_lines` for `replace_lines`, resolvable file paths).
- **File Output**: Instructs the LLM to return the JSON in a file (default: `applydir_changes.json`), separate from explanatory text, aligning with LLM API practices.
- **Example JSON**: Includes a sample with multiple `replace_lines` changes, a `create_file` action, and a `delete_file` action.
- **Customization**: Accepts a `filename` parameter to specify the output file name.
This function ensures LLMs generate valid JSON for `applydir`, supporting LLM communication. See the [example JSON](#json-format) for reference.
### Example Cases
- **Modification (replace_lines)**: Replace a block in `src/main.py`:
```json
{
"file_entries": [
{
"file": "src/main.py",
"action": "replace_lines",
"changes": [
{"original_lines": ["print('Hello')"], "changed_lines": ["print('Hello World')"]}
]
}
]
}
```
- **Addition**: Match a block and replace with additional lines.
- **Deletion**: Match a block and replace with fewer lines, or use `delete_file` for entire files.
- **Creation (create_file)**: Create `src/new.py` with content:
```json
{
"file_entries": [
{
"file": "src/new.py",
"action": "create_file",
"changes": [
{"original_lines": [], "changed_lines": ["def new_func():", " pass"]}
]
}
]
}
```
- **Deletion (delete_file)**: Delete `src/old.py`:
```json
{
"file_entries": [
{
"file": "src/old.py",
"action": "delete_file",
"changes": []
}
]
}
```
## Installation
```bash
pip install applydir
```
## Usage
### CLI
Run the `applydir` utility to apply changes from a JSON file:
```bash
applydir changes.json [--base-dir <path>] [--no-allow-file-deletion] [--non-ascii-action {error,warning,ignore}] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
```
- `changes.json`: Path to the JSON file containing changes.
- `--base-dir`: Base directory for file paths (default: `.`).
- `--no-allow-file-deletion`: Disable file deletions (overrides config).
- `--non-ascii-action`: Handle non-ASCII characters (`error`, `warning`, or `ignore`; overrides config).
- `--log-level`: Set logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`).
### Example
```bash
applydir changes.json --base-dir /path/to/project --no-allow-file-deletion --non-ascii-action=error --log-level=DEBUG
```
### Programmatic
```python
from applydir import ApplydirApplicator, ApplydirChanges, ApplydirMatcher
from applydir.applydir_error import ApplydirError, ErrorSeverity
import logging
from prepdir import configure_logging
logger = logging.getLogger("applydir")
configure_logging(logger, level="INFO")
changes_json = {
"file_entries": [
{
"file": "src/main.py",
"action": "replace_lines",
"changes": [{"original_lines": ["print('Hello')"], "changed_lines": ["print('Hello World')"]}]
}
]
}
changes = ApplydirChanges(file_entries=changes_json["file_entries"])
matcher = ApplydirMatcher(similarity_threshold=0.95)
applicator = ApplydirApplicator(
base_dir="/path/to/project",
changes=changes,
matcher=matcher,
logger=logger,
config_override={"allow_file_deletion": False, "validation": {"non_ascii": {"default": "error"}}}
)
errors = applicator.apply_changes()
has_errors = False
for error in errors:
log_level = (
logging.INFO if error.severity == ErrorSeverity.INFO
else logging.WARNING if error.severity == ErrorSeverity.WARNING
else logging.ERROR
)
logger.log(log_level, f"{error.message}: {error.details}")
if error.severity in [ErrorSeverity.ERROR, ErrorSeverity.WARNING]:
has_errors = True
if not has_errors:
logger.info("Changes applied successfully")
```
## Configuration
`applydir` loads defaults from `.applydir/config.yaml` or bundled `src/applydir/config.yaml` using `prepdir`'s `load_config`. CLI options or programmatic `config_override` can override settings.
Example `config.yaml`:
```yaml
validation:
non_ascii:
default: warning
rules:
- extensions: [".py", ".js"]
action: error
- extensions: [".md", ".markdown"]
action: ignore
- extensions: [".json", ".yaml"]
action: warning
allow_file_deletion: true
matching:
whitespace:
default: collapse
similarity:
default: 0.95
similarity_metric:
default: levenshtein
use_fuzzy:
default: true
```
- `validation.non_ascii`: Controls non-ASCII handling (default, rules by extension).
- `allow_file_deletion`: Enables/disables deletions (default: true).
- `matching`: Settings for `ApplydirMatcher` (whitespace, similarity threshold/metric, fuzzy matching).
Logging level is set via CLI `--log-level` or programmatically.
## Error Format
Errors and warnings are returned as a list of `ApplydirError` objects and logged:
```json
[
{
"change": null,
"error_type": "json_structure",
"severity": "error",
"message": "Invalid JSON structure",
"details": {}
},
{
"change": null,
"error_type": "file_not_found",
"severity": "error",
"message": "File does not exist for deletion",
"details": {"file": "/path/to/missing.py"}
},
{
"change": null,
"error_type": "file_changes_successful",
"severity": "info",
"message": "All changes to file applied successfully",
"details": {"file": "/path/to/main.py", "actions": ["replace_lines"], "change_count": 1}
}
]
```
## Error Types
- `json_structure`: Invalid JSON (e.g., missing `file_entries`).
- `invalid_change`: Invalid change format or validation failure.
- `file_not_found`: File missing for modification/deletion.
- `file_already_exists`: File exists for creation.
- `no_match`: No matching lines found.
- `multiple_matches`: Multiple matches for lines.
- `permission_denied`: Deletion disabled.
- `file_system`: File operation failure.
- `file_changes_successful`: Successful application (info level).
## Class Structure
1. **ApplydirError**:
- Represents errors/warnings.
- Attributes: `change: Optional[Any]`, `error_type: ErrorType`, `severity: ErrorSeverity`, `message: str`, `details: Dict`.
2. **ApplydirChanges**:
- Parses/validates JSON `file_entries`.
- Methods: `validate_changes(base_dir: str, config: Dict) -> List[ApplydirError]`.
3. **ApplydirFileChange**:
- Represents a single change.
- Methods: `from_file_entry(file_path: Path, action: str, change_dict: Optional[Dict]) -> ApplydirFileChange`, `validate_change(config: Dict) -> List[ApplydirError]`.
4. **ApplydirMatcher**:
- Matches lines with fuzzy options.
- Methods: `match(file_content: List[str], change: ApplydirFileChange) -> Tuple[Optional[Dict], List[ApplydirError]]`.
5. **ApplydirApplicator**:
- Applies changes.
- Methods: `apply_changes() -> List[ApplydirError]`, supports create/replace/delete.
## Workflow
1. **Input**: Run `applydir <input_file>` with JSON changes.
2. **Parsing**: Load JSON, check `file_entries`, create `ApplydirChanges`.
3. **Validation**: Validate structure, paths, non-ASCII via `validate_changes`.
4. **Application**: Use `ApplydirApplicator` to match lines (`ApplydirMatcher`) and apply changes directly.
5. **Output**: Log errors/successes, return exit code (0 success, 1 failure).
## Planned Features
- **vibedir Integration**: LLM prompting, Git commits/rollbacks, linting.
- **Extended Actions**: More action types if needed.
- **Additional Validation**: Syntax/linting checks.
## Dependencies
- **prepdir**: For `load_config` (configuration) and `configure_logging` (logging).
- **Pydantic**: For model validation (e.g., `ApplydirError`, `ApplydirChanges`).
- **dynaconf**: For configuration merging.
- **difflib** (standard library): For sequence matcher in fuzzy matching.
## Python Best Practices
- PEP 8 compliant naming and structure.
- Type hints and Pydantic for safety.
- Modular classes for testability.
- Logging via `prepdir`.
## Edge Cases
- Invalid JSON/missing `file_entries`: Logged and exit 1.
- Non-existent files for replace/delete: `file_not_found` error.
- Existing files for create: `file_already_exists` error.
- Non-ASCII: Handled per config/CLI.
- Multiple/no matches: `multiple_matches` or `no_match` errors.
## Testing
- Tests in `tests/test_main.py` cover CLI execution, validation, errors, and options.
- Run: `pdm run pytest tests/test_main.py`
## Next Steps
- Implement `vibedir` for full workflow.
Raw data
{
"_id": null,
"home_page": null,
"name": "applydir",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "applydir, prepdir, automated code changes, code modification, developer tools, large language models, llm, cli, code automation, ai-driven development, fuzzy matching",
"author": null,
"author_email": "eyecantell <paul@pneuma.solutions>",
"download_url": "https://files.pythonhosted.org/packages/83/6f/f48d2a07f95500c8cdc520b8d354ac9105580e832c3979960a5726a15e99/applydir-0.4.0.tar.gz",
"platform": null,
"description": "# applydir\n\n[](https://github.com/eyecantell/applydir/actions/runs/18212548824)\n[](https://badge.fury.io/py/applydir)\n[](https://www.python.org/downloads/)\n[](https://pepy.tech/project/applydir)\n[](https://opensource.org/licenses/MIT)\n\n## Overview\n`applydir` is a Python command-line tool that automates the application of LLM-generated code changes to a codebase. It processes changes specified in a JSON format, supporting actions like line replacements, file creation, and deletion. Changes are applied directly to the codebase\u2014use Git or other version control tools (e.g., via planned `vibedir` integration) for tracking and reverting. Designed to integrate with `prepdir` (for logging and configuration) and eventually `vibedir` (for LLM communication, Git integration, and linting), `applydir` validates and applies changes with robust error handling, fuzzy matching for reliability, and resolvable file paths.\n\n## Features\n- **Supported Actions**: \n - `replace_lines`: Replace blocks of lines in existing files (unified approach for modifications, additions, deletions).\n - `create_file`: Create new files with specified content.\n - `delete_file`: Delete files (configurable via `--no-allow-file-deletion`).\n- **Reliability**: Uses fuzzy matching (Levenshtein or sequence matcher, configurable) to locate lines in existing files, with options for whitespace handling and case sensitivity.\n- **JSON Input**: Processes a simple JSON structure with `file_entries`, each containing `file`, `action`, and `changes` (with `original_lines` and `changed_lines` for replacements).\n- **Resolvable Paths**: Accepts relative or absolute file paths, resolved relative to `--base-dir` (default: current directory).\n- **Validation**: Validates JSON structure, file paths, and non-ASCII characters (configurable via `config.yaml` or `--non-ascii-action`).\n- **Configuration**: Loads defaults from `.applydir/config.yaml` or bundled `src/applydir/config.yaml` using `prepdir`'s `load_config`. Overrides via CLI or programmatic `config_override`.\n- **Error Handling**: Returns structured `ApplydirError` objects with type, severity, message, and details; logged via `prepdir`'s logging system.\n- **CLI Utility**: Run `applydir <input_file>` with options to customize behavior.\n- **Direct Application**: Changes are applied directly to files for simplicity; track/revert via Git in workflows like `vibedir`.\n- **Modular Design**: Separates JSON parsing (`ApplydirChanges`), change validation (`ApplydirFileChange`), matching (`ApplydirMatcher`), and application (`ApplydirApplicator`).\n\n## JSON Format\nChanges are provided in a JSON object with a `file_entries` array:\n\n```json\n{\n \"file_entries\": [\n {\n \"file\": \"<relative_or_absolute_file_path>\",\n \"action\": \"<replace_lines|create_file|delete_file>\",\n \"changes\": [\n {\n \"original_lines\": [\"<lines to match in existing file (empty for create_file)>\"],\n \"changed_lines\": [\"<new lines to insert (full content for create_file)>\"]\n }\n ]\n }\n ]\n}\n```\n\n### Prompting to use applydir\nTo facilitate integration with, the `applydir_format_description` function provides a detailed prompt for LLMs to generate JSON changes compatible with `applydir`. The function includes:\n\n- **Structure and Requirements**: Describes the JSON format, including `file_entries`, supported actions (`replace_lines`, `create_file`, `delete_file`), and validation rules (e.g., non-empty `original_lines` for `replace_lines`, resolvable file paths).\n- **File Output**: Instructs the LLM to return the JSON in a file (default: `applydir_changes.json`), separate from explanatory text, aligning with LLM API practices.\n- **Example JSON**: Includes a sample with multiple `replace_lines` changes, a `create_file` action, and a `delete_file` action.\n- **Customization**: Accepts a `filename` parameter to specify the output file name.\n\nThis function ensures LLMs generate valid JSON for `applydir`, supporting LLM communication. See the [example JSON](#json-format) for reference.\n\n### Example Cases\n- **Modification (replace_lines)**: Replace a block in `src/main.py`:\n ```json\n {\n \"file_entries\": [\n {\n \"file\": \"src/main.py\",\n \"action\": \"replace_lines\",\n \"changes\": [\n {\"original_lines\": [\"print('Hello')\"], \"changed_lines\": [\"print('Hello World')\"]}\n ]\n }\n ]\n }\n ```\n- **Addition**: Match a block and replace with additional lines.\n- **Deletion**: Match a block and replace with fewer lines, or use `delete_file` for entire files.\n- **Creation (create_file)**: Create `src/new.py` with content:\n ```json\n {\n \"file_entries\": [\n {\n \"file\": \"src/new.py\",\n \"action\": \"create_file\",\n \"changes\": [\n {\"original_lines\": [], \"changed_lines\": [\"def new_func():\", \" pass\"]}\n ]\n }\n ]\n }\n ```\n- **Deletion (delete_file)**: Delete `src/old.py`:\n ```json\n {\n \"file_entries\": [\n {\n \"file\": \"src/old.py\",\n \"action\": \"delete_file\",\n \"changes\": []\n }\n ]\n }\n ```\n\n## Installation\n```bash\npip install applydir\n```\n\n## Usage\n### CLI\nRun the `applydir` utility to apply changes from a JSON file:\n```bash\napplydir changes.json [--base-dir <path>] [--no-allow-file-deletion] [--non-ascii-action {error,warning,ignore}] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]\n```\n- `changes.json`: Path to the JSON file containing changes.\n- `--base-dir`: Base directory for file paths (default: `.`).\n- `--no-allow-file-deletion`: Disable file deletions (overrides config).\n- `--non-ascii-action`: Handle non-ASCII characters (`error`, `warning`, or `ignore`; overrides config).\n- `--log-level`: Set logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`).\n\n### Example\n```bash\napplydir changes.json --base-dir /path/to/project --no-allow-file-deletion --non-ascii-action=error --log-level=DEBUG\n```\n\n### Programmatic\n```python\nfrom applydir import ApplydirApplicator, ApplydirChanges, ApplydirMatcher\nfrom applydir.applydir_error import ApplydirError, ErrorSeverity\nimport logging\nfrom prepdir import configure_logging\n\nlogger = logging.getLogger(\"applydir\")\nconfigure_logging(logger, level=\"INFO\")\n\nchanges_json = {\n \"file_entries\": [\n {\n \"file\": \"src/main.py\",\n \"action\": \"replace_lines\",\n \"changes\": [{\"original_lines\": [\"print('Hello')\"], \"changed_lines\": [\"print('Hello World')\"]}]\n }\n ]\n}\nchanges = ApplydirChanges(file_entries=changes_json[\"file_entries\"])\nmatcher = ApplydirMatcher(similarity_threshold=0.95)\napplicator = ApplydirApplicator(\n base_dir=\"/path/to/project\",\n changes=changes,\n matcher=matcher,\n logger=logger,\n config_override={\"allow_file_deletion\": False, \"validation\": {\"non_ascii\": {\"default\": \"error\"}}}\n)\nerrors = applicator.apply_changes()\nhas_errors = False\nfor error in errors:\n log_level = (\n logging.INFO if error.severity == ErrorSeverity.INFO\n else logging.WARNING if error.severity == ErrorSeverity.WARNING\n else logging.ERROR\n )\n logger.log(log_level, f\"{error.message}: {error.details}\")\n if error.severity in [ErrorSeverity.ERROR, ErrorSeverity.WARNING]:\n has_errors = True\nif not has_errors:\n logger.info(\"Changes applied successfully\")\n```\n\n## Configuration\n`applydir` loads defaults from `.applydir/config.yaml` or bundled `src/applydir/config.yaml` using `prepdir`'s `load_config`. CLI options or programmatic `config_override` can override settings.\n\nExample `config.yaml`:\n```yaml\nvalidation:\n non_ascii:\n default: warning\n rules:\n - extensions: [\".py\", \".js\"]\n action: error\n - extensions: [\".md\", \".markdown\"]\n action: ignore\n - extensions: [\".json\", \".yaml\"]\n action: warning\nallow_file_deletion: true\nmatching:\n whitespace:\n default: collapse\n similarity:\n default: 0.95\n similarity_metric:\n default: levenshtein\n use_fuzzy:\n default: true\n```\n\n- `validation.non_ascii`: Controls non-ASCII handling (default, rules by extension).\n- `allow_file_deletion`: Enables/disables deletions (default: true).\n- `matching`: Settings for `ApplydirMatcher` (whitespace, similarity threshold/metric, fuzzy matching).\n\nLogging level is set via CLI `--log-level` or programmatically.\n\n## Error Format\nErrors and warnings are returned as a list of `ApplydirError` objects and logged:\n\n```json\n[\n {\n \"change\": null,\n \"error_type\": \"json_structure\",\n \"severity\": \"error\",\n \"message\": \"Invalid JSON structure\",\n \"details\": {}\n },\n {\n \"change\": null,\n \"error_type\": \"file_not_found\",\n \"severity\": \"error\",\n \"message\": \"File does not exist for deletion\",\n \"details\": {\"file\": \"/path/to/missing.py\"}\n },\n {\n \"change\": null,\n \"error_type\": \"file_changes_successful\",\n \"severity\": \"info\",\n \"message\": \"All changes to file applied successfully\",\n \"details\": {\"file\": \"/path/to/main.py\", \"actions\": [\"replace_lines\"], \"change_count\": 1}\n }\n]\n```\n\n## Error Types\n- `json_structure`: Invalid JSON (e.g., missing `file_entries`).\n- `invalid_change`: Invalid change format or validation failure.\n- `file_not_found`: File missing for modification/deletion.\n- `file_already_exists`: File exists for creation.\n- `no_match`: No matching lines found.\n- `multiple_matches`: Multiple matches for lines.\n- `permission_denied`: Deletion disabled.\n- `file_system`: File operation failure.\n- `file_changes_successful`: Successful application (info level).\n\n## Class Structure\n1. **ApplydirError**:\n - Represents errors/warnings.\n - Attributes: `change: Optional[Any]`, `error_type: ErrorType`, `severity: ErrorSeverity`, `message: str`, `details: Dict`.\n\n2. **ApplydirChanges**:\n - Parses/validates JSON `file_entries`.\n - Methods: `validate_changes(base_dir: str, config: Dict) -> List[ApplydirError]`.\n\n3. **ApplydirFileChange**:\n - Represents a single change.\n - Methods: `from_file_entry(file_path: Path, action: str, change_dict: Optional[Dict]) -> ApplydirFileChange`, `validate_change(config: Dict) -> List[ApplydirError]`.\n\n4. **ApplydirMatcher**:\n - Matches lines with fuzzy options.\n - Methods: `match(file_content: List[str], change: ApplydirFileChange) -> Tuple[Optional[Dict], List[ApplydirError]]`.\n\n5. **ApplydirApplicator**:\n - Applies changes.\n - Methods: `apply_changes() -> List[ApplydirError]`, supports create/replace/delete.\n\n## Workflow\n1. **Input**: Run `applydir <input_file>` with JSON changes.\n2. **Parsing**: Load JSON, check `file_entries`, create `ApplydirChanges`.\n3. **Validation**: Validate structure, paths, non-ASCII via `validate_changes`.\n4. **Application**: Use `ApplydirApplicator` to match lines (`ApplydirMatcher`) and apply changes directly.\n5. **Output**: Log errors/successes, return exit code (0 success, 1 failure).\n\n## Planned Features\n- **vibedir Integration**: LLM prompting, Git commits/rollbacks, linting.\n- **Extended Actions**: More action types if needed.\n- **Additional Validation**: Syntax/linting checks.\n\n## Dependencies\n- **prepdir**: For `load_config` (configuration) and `configure_logging` (logging).\n- **Pydantic**: For model validation (e.g., `ApplydirError`, `ApplydirChanges`).\n- **dynaconf**: For configuration merging.\n- **difflib** (standard library): For sequence matcher in fuzzy matching.\n\n## Python Best Practices\n- PEP 8 compliant naming and structure.\n- Type hints and Pydantic for safety.\n- Modular classes for testability.\n- Logging via `prepdir`.\n\n## Edge Cases\n- Invalid JSON/missing `file_entries`: Logged and exit 1.\n- Non-existent files for replace/delete: `file_not_found` error.\n- Existing files for create: `file_already_exists` error.\n- Non-ASCII: Handled per config/CLI.\n- Multiple/no matches: `multiple_matches` or `no_match` errors.\n\n## Testing\n- Tests in `tests/test_main.py` cover CLI execution, validation, errors, and options.\n- Run: `pdm run pytest tests/test_main.py`\n\n## Next Steps\n- Implement `vibedir` for full workflow.",
"bugtrack_url": null,
"license": "MIT",
"summary": "Utility to apply changes to files based on AI-generated recommendations.",
"version": "0.4.0",
"project_urls": {
"Documentation": "https://github.com/eyecantell/applydir#readme",
"Issues": "https://github.com/eyecantell/applydir/issues",
"Repository": "https://github.com/eyecantell/applydir"
},
"split_keywords": [
"applydir",
" prepdir",
" automated code changes",
" code modification",
" developer tools",
" large language models",
" llm",
" cli",
" code automation",
" ai-driven development",
" fuzzy matching"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d811bbea47fdfe875a0946fdc86f6c0203b7d7bae3cca2c61e657552e1d38fca",
"md5": "4e160cb6f0f497f2939c0ad2be163598",
"sha256": "abf94e1146b7fcceccc1e19bc582f2b00bd50baf68f8a19781264b9bb50439cf"
},
"downloads": -1,
"filename": "applydir-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4e160cb6f0f497f2939c0ad2be163598",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 22154,
"upload_time": "2025-10-06T04:49:43",
"upload_time_iso_8601": "2025-10-06T04:49:43.953892Z",
"url": "https://files.pythonhosted.org/packages/d8/11/bbea47fdfe875a0946fdc86f6c0203b7d7bae3cca2c61e657552e1d38fca/applydir-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "836ff48d2a07f95500c8cdc520b8d354ac9105580e832c3979960a5726a15e99",
"md5": "e56e51cbc50e0a12f607703c2edc57ca",
"sha256": "6499ae52e481b33b6bcc45770a27938af6e8d6cafbc3fd7be0bc17f2005f853a"
},
"downloads": -1,
"filename": "applydir-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "e56e51cbc50e0a12f607703c2edc57ca",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 35911,
"upload_time": "2025-10-06T04:49:44",
"upload_time_iso_8601": "2025-10-06T04:49:44.840336Z",
"url": "https://files.pythonhosted.org/packages/83/6f/f48d2a07f95500c8cdc520b8d354ac9105580e832c3979960a5726a15e99/applydir-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-06 04:49:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "eyecantell",
"github_project": "applydir#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "applydir"
}