path-link 0.2.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.
@@ -0,0 +1,643 @@
1
+ Metadata-Version: 2.4
2
+ Name: path-link
3
+ Version: 0.2.0
4
+ Summary: Type-safe path and URL configuration for Python projects with validation, static models, and IDE autocompletion. Currently supports local paths, URL support coming in v0.3.0.
5
+ Author-email: Lasse Tammilehto <lasse@jaahdytyspalvelu.fi>
6
+ License: MIT
7
+ Project-URL: Homepage, http://jaahdytyspalvelu.fi
8
+ Project-URL: Documentation, https://github.com/jaahdytyspalvelu/path-link#readme
9
+ Project-URL: Issue Tracker, https://github.com/jaahdytyspalvelu/path-link/issues
10
+ Project-URL: AI Guidelines, https://github.com/jaahdytyspalvelu/path-link/blob/main/assistant_context.md
11
+ Project-URL: Developer Guide, https://github.com/jaahdytyspalvelu/path-link/blob/main/CLAUDE.md
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: Utilities
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: pydantic>=2.11.0
25
+ Requires-Dist: python-dotenv>=1.0.1
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest>=8.4.2; extra == "test"
28
+ Requires-Dist: pytest-cov>=7.0.0; extra == "test"
29
+ Provides-Extra: dev
30
+ Requires-Dist: mypy>=1.18.2; extra == "dev"
31
+ Requires-Dist: ruff>=0.8.0; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # path-link
35
+
36
+ Type-safe path and URL configuration for Python projects with validation, static models, and IDE autocompletion.
37
+
38
+ **Current:** Local path management ✅
39
+ **Coming in v0.3.0:** URL support (API endpoints, external resources)
40
+
41
+ ## 🚀 Features
42
+
43
+ - **Dynamic Path Management**: Load paths from `pyproject.toml` or custom `.paths` files
44
+ - **Type-Safe Static Models**: Generate static dataclasses for IDE autocomplete and type checking
45
+ - **Extensible Validation**: Protocol-based validator system with built-in and custom validators
46
+ - **Cross-Platform**: Works on Linux, Windows, and macOS
47
+ - **Zero Runtime Dependencies**: Only requires `pydantic` and `python-dotenv`
48
+ - **Developer Friendly**: Full type hints, comprehensive testing, and clear error messages
49
+
50
+ ## 📦 Installation
51
+
52
+ ### Using pip
53
+ ```bash
54
+ pip install path-link
55
+ ```
56
+
57
+ ### Using uv (recommended)
58
+ ```bash
59
+ uv add path-link
60
+ ```
61
+
62
+ ### From source
63
+ ```bash
64
+ git clone https://github.com/jaahdytyspalvelu/path-link.git
65
+ cd path-link
66
+ uv sync
67
+ ```
68
+
69
+ ## 🎯 Quick Start
70
+
71
+ ### Basic Usage
72
+
73
+ ```python
74
+ from project_paths import ProjectPaths
75
+
76
+ # Load paths from pyproject.toml
77
+ paths = ProjectPaths.from_pyproject()
78
+
79
+ # Access paths
80
+ print(paths.base_dir) # Project root directory
81
+ print(paths.config) # config directory path
82
+ print(paths.icons) # icons directory path
83
+
84
+ # Dictionary-style access
85
+ config_path = paths["config"]
86
+
87
+ # Get all paths as dictionary
88
+ all_paths = paths.to_dict()
89
+ ```
90
+
91
+ ### Configuration in pyproject.toml
92
+
93
+ ```toml
94
+ [tool.project_paths.paths]
95
+ config = "config"
96
+ icons = "icons"
97
+ data = "data"
98
+ cache = ".cache"
99
+ logs = "logs"
100
+
101
+ [tool.project_paths.files]
102
+ settings = "config/settings.json"
103
+ database = "data/app.db"
104
+ ```
105
+
106
+ ### Using Custom Configuration Files
107
+
108
+ ```python
109
+ # Load from custom .paths file
110
+ paths = ProjectPaths.from_config(".paths")
111
+
112
+ # Load from specific location
113
+ paths = ProjectPaths.from_config("configs/my.paths")
114
+ ```
115
+
116
+ ### Environment Variable Expansion
117
+
118
+ Path configurations support environment variable expansion and home directory expansion (`~`). This is useful for creating portable configurations that adapt to different environments.
119
+
120
+ ```python
121
+ # .paths file
122
+ # data_dir = ${DATA_ROOT}/files
123
+ # cache_dir = ~/my_app/cache
124
+ # config = ${APP_CONFIG:-/etc/myapp}
125
+
126
+ # Environment variables are expanded automatically
127
+ import os
128
+ os.environ["DATA_ROOT"] = "/custom/data"
129
+
130
+ paths = ProjectPaths.from_config(".paths")
131
+ print(paths.data_dir) # /custom/data/files
132
+ print(paths.cache_dir) # /home/username/my_app/cache
133
+ ```
134
+
135
+ **Supported patterns:**
136
+ - `${VAR}` - Expands to environment variable value (empty string if undefined)
137
+ - `$VAR` - Alternative syntax for environment variables
138
+ - `~` - Expands to user's home directory
139
+ - `~/path` - Expands to path under user's home directory
140
+
141
+ **Example `.paths` file:**
142
+ ```bash
143
+ # Production paths
144
+ data_dir = ${DATA_ROOT}/app_data
145
+ logs_dir = ${LOG_DIR:-/var/log/myapp}
146
+ cache_dir = /tmp/${USER}_cache
147
+
148
+ # User-specific paths
149
+ config_dir = ~/.config/myapp
150
+ ```
151
+
152
+ **Example `pyproject.toml`:**
153
+ ```toml
154
+ [tool.project_paths.paths]
155
+ data_dir = "${DATA_ROOT}/files"
156
+ config_dir = "~/.config/myapp"
157
+ ```
158
+
159
+ ## 🖥️ Command Line Interface
160
+
161
+ ptool-serena includes a `ptool` CLI for quick operations without writing Python code.
162
+
163
+ ### Available Commands
164
+
165
+ ```bash
166
+ # Print all configured paths as JSON
167
+ ptool print
168
+
169
+ # Validate project structure
170
+ ptool validate
171
+
172
+ # Generate static dataclass model
173
+ ptool gen-static
174
+
175
+ # Show help
176
+ ptool --help
177
+ ```
178
+
179
+ ### Command Reference
180
+
181
+ #### `ptool print` - Display Paths
182
+
183
+ Prints all configured paths as formatted JSON.
184
+
185
+ ```bash
186
+ # Print from pyproject.toml (default)
187
+ ptool print
188
+
189
+ # Print from custom .paths file
190
+ ptool print --source config --config my.paths
191
+
192
+ # Output example:
193
+ # {
194
+ # "base_dir": "/home/user/project",
195
+ # "config_dir": "/home/user/project/config",
196
+ # "data_dir": "/home/user/project/data",
197
+ # ...
198
+ # }
199
+ ```
200
+
201
+ **Options:**
202
+ - `--source {pyproject,config}` - Configuration source (default: pyproject)
203
+ - `--config PATH` - Path to .paths file (default: .paths)
204
+
205
+ #### `ptool validate` - Validate Paths
206
+
207
+ Validates that your project structure matches the configuration.
208
+
209
+ ```bash
210
+ # Basic validation (check paths can be loaded)
211
+ ptool validate
212
+
213
+ # Strict validation (check paths exist, no symlinks)
214
+ ptool validate --strict
215
+
216
+ # Raise exception on validation failure
217
+ ptool validate --strict --raise
218
+
219
+ # Validate from custom config
220
+ ptool validate --source config --config production.paths
221
+ ```
222
+
223
+ **Options:**
224
+ - `--source {pyproject,config}` - Configuration source (default: pyproject)
225
+ - `--config PATH` - Path to .paths file (default: .paths)
226
+ - `--strict` - Enable strict validation (paths must exist, correct types)
227
+ - `--raise` - Raise exception on validation failure (for CI/scripts)
228
+
229
+ **Exit codes:**
230
+ - `0` - Validation passed
231
+ - `1` - Validation failed or error occurred
232
+
233
+ #### `ptool gen-static` - Generate Static Model
234
+
235
+ Generates a static dataclass for IDE autocomplete and type checking.
236
+
237
+ ```bash
238
+ # Generate at default location (src/project_paths/project_paths_static.py)
239
+ ptool gen-static
240
+
241
+ # Generate at custom location
242
+ ptool gen-static --out custom/path/static_paths.py
243
+ ```
244
+
245
+ **Options:**
246
+ - `--out PATH` - Output path for static model
247
+
248
+ **When to use:** After modifying `[tool.project_paths]` in `pyproject.toml` to keep static model in sync.
249
+
250
+ ### CLI Usage Examples
251
+
252
+ **Quick project validation:**
253
+ ```bash
254
+ cd your-project/
255
+ ptool validate --strict
256
+ # ✅ All paths valid (strict mode)
257
+ ```
258
+
259
+ **View all configured paths:**
260
+ ```bash
261
+ ptool print
262
+ # Outputs JSON with all resolved paths
263
+ ```
264
+
265
+ **Generate static model for IDE support:**
266
+ ```bash
267
+ ptool gen-static
268
+ # ✅ Static model generated successfully
269
+ ```
270
+
271
+ **CI/CD integration:**
272
+ ```bash
273
+ # In your CI script
274
+ ptool validate --strict --raise || exit 1
275
+ ```
276
+
277
+ **Multiple environments:**
278
+ ```bash
279
+ # Development
280
+ ptool validate --source config --config .paths.dev
281
+
282
+ # Production
283
+ ptool validate --source config --config .paths.prod
284
+ ```
285
+
286
+ ### With Validation
287
+
288
+ You can validate your project's structure by using one of the built-in validators.
289
+
290
+ ```python
291
+ from project_paths import ProjectPaths, validate_or_raise, PathValidationError
292
+ from project_paths.builtin_validators import StrictPathValidator
293
+
294
+ # 1. Load your paths
295
+ paths = ProjectPaths.from_pyproject()
296
+
297
+ # 2. Configure a validator
298
+ # This example ensures a 'config' directory and a 'database' file exist.
299
+ validator = StrictPathValidator(
300
+ required=["config", "database"],
301
+ must_be_dir=["config"],
302
+ must_be_file=["database"]
303
+ )
304
+
305
+ # 3. Validate and raise an exception on failure
306
+ try:
307
+ validate_or_raise(paths, validator)
308
+ print("✅ Project structure is valid.")
309
+ except PathValidationError as e:
310
+ print(f"❌ Invalid project structure:\n{e}")
311
+
312
+ # Or, to handle results manually without raising an exception:
313
+ result = validator.validate(paths)
314
+ if not result.ok():
315
+ for error in result.errors():
316
+ print(f"Error: {error.message} (Code: {error.code})")
317
+ ```
318
+
319
+ ### Security: Sandbox Validation
320
+
321
+ The `SandboxPathValidator` prevents path traversal attacks by ensuring all paths stay within your project's base directory. This is crucial for applications that handle user input or load paths from external sources.
322
+
323
+ ```python
324
+ from project_paths import ProjectPaths
325
+ from project_paths.builtin_validators import SandboxPathValidator
326
+
327
+ paths = ProjectPaths.from_pyproject()
328
+
329
+ # Create sandbox validator with security settings
330
+ validator = SandboxPathValidator(
331
+ base_dir_key="base_dir", # Key representing the base directory
332
+ allow_absolute=False, # Block absolute paths (recommended)
333
+ strict_mode=True, # Block '..' patterns (recommended)
334
+ check_paths=[] # Empty = check all paths
335
+ )
336
+
337
+ result = validator.validate(paths)
338
+ if not result.ok():
339
+ for error in result.errors():
340
+ print(f"🔒 Security issue: {error.message}")
341
+ print(f" Field: {error.field}, Code: {error.code}")
342
+ ```
343
+
344
+ **Security Features:**
345
+
346
+ - **Path Traversal Protection**: Detects and blocks `..` patterns in strict mode
347
+ - **Absolute Path Control**: Can block or allow absolute paths
348
+ - **Sandbox Verification**: Ensures resolved paths stay within base directory
349
+ - **Symlink Resolution**: Properly resolves symlinks before validation
350
+
351
+ **Error Codes:**
352
+
353
+ - `PATH_TRAVERSAL_ATTEMPT`: Path contains `..` pattern (strict mode)
354
+ - `ABSOLUTE_PATH_BLOCKED`: Absolute path not allowed
355
+ - `PATH_ESCAPES_SANDBOX`: Path resolves outside base directory
356
+ - `SANDBOX_BASE_MISSING`: Base directory key not found
357
+ - `SANDBOX_BASE_UNRESOLVABLE`: Cannot resolve base directory
358
+ - `PATH_UNRESOLVABLE`: Cannot resolve path (warning)
359
+
360
+ **Example Use Cases:**
361
+
362
+ ```python
363
+ # 1. Maximum security - block everything suspicious
364
+ strict_sandbox = SandboxPathValidator(
365
+ allow_absolute=False,
366
+ strict_mode=True
367
+ )
368
+
369
+ # 2. Allow absolute paths within sandbox
370
+ permissive_sandbox = SandboxPathValidator(
371
+ allow_absolute=True,
372
+ strict_mode=False
373
+ )
374
+
375
+ # 3. Check specific paths only
376
+ targeted_sandbox = SandboxPathValidator(
377
+ check_paths=["user_uploads", "temp_files"],
378
+ strict_mode=True
379
+ )
380
+ ```
381
+
382
+ ## 🛠️ Advanced Features
383
+
384
+ ### Static Model Generation
385
+
386
+ Generate a static dataclass for better IDE support:
387
+
388
+ ```python
389
+ from project_paths import write_dataclass_file
390
+
391
+ # Generate src/project_paths/project_paths_static.py
392
+ write_dataclass_file()
393
+ ```
394
+
395
+ This creates a fully typed dataclass that can be imported:
396
+
397
+ ```python
398
+ from project_paths.project_paths_static import ProjectPathsStatic
399
+
400
+ paths = ProjectPathsStatic()
401
+ # Now you get full IDE autocomplete!
402
+ ```
403
+
404
+ ### Custom Validators
405
+
406
+ Create your own validators by creating a class with a `validate` method that returns a `ValidationResult`.
407
+
408
+ ```python
409
+ from dataclasses import dataclass
410
+ from project_paths import Finding, Severity, ValidationResult, ProjectPaths
411
+
412
+ @dataclass
413
+ class MyCustomValidator:
414
+ """A custom validator to check for a specific file."""
415
+ required_file: str
416
+
417
+ def validate(self, paths: ProjectPaths) -> ValidationResult:
418
+ result = ValidationResult()
419
+ # Assume 'config_dir' is a defined path in your ProjectPaths
420
+ config_path = paths.to_dict().get("config_dir")
421
+
422
+ if not config_path or not (config_path / self.required_file).exists():
423
+ result.add(Finding(
424
+ severity=Severity.ERROR,
425
+ code="CUSTOM_FILE_MISSING",
426
+ field="config_dir",
427
+ message=f"Required file '{self.required_file}' not found in config directory."
428
+ ))
429
+ return result
430
+
431
+ # Use the custom validator
432
+ paths = ProjectPaths.from_pyproject()
433
+ custom_validator = MyCustomValidator(required_file="user_settings.json")
434
+ validation_result = custom_validator.validate(paths)
435
+
436
+ if not validation_result.ok():
437
+ print("Custom validation failed!")
438
+ ```
439
+
440
+ ### Composite Validators
441
+
442
+ Combine multiple validators to run them as a single pipeline.
443
+
444
+ ```python
445
+ # Assuming MyCustomValidator is defined as in the previous example
446
+ from project_paths.builtin_validators import CompositeValidator, StrictPathValidator
447
+
448
+ # 1. Load paths
449
+ paths = ProjectPaths.from_pyproject()
450
+
451
+ # 2. Configure validators
452
+ strict_check = StrictPathValidator(required=["config_dir"])
453
+ custom_check = MyCustomValidator(required_file="user_settings.json")
454
+
455
+ # 3. Combine them
456
+ composite_validator = CompositeValidator(parts=[strict_check, custom_check])
457
+
458
+ # 4. Run all checks at once
459
+ final_result = composite_validator.validate(paths)
460
+
461
+ if not final_result.ok():
462
+ print("Composite validation failed!")
463
+ for error in final_result.errors():
464
+ print(f"- {error.message}")
465
+ ```
466
+
467
+ ### Programmatic Documentation Access
468
+
469
+ The package includes bundled documentation that can be accessed programmatically, even in offline or airgapped environments. This is especially useful for AI assistants helping users with the package.
470
+
471
+ ```python
472
+ from project_paths import get_ai_guidelines, get_developer_guide, get_metadata
473
+ import json
474
+
475
+ # Get AI assistant guidelines (comprehensive usage patterns and best practices)
476
+ ai_docs = get_ai_guidelines()
477
+ print(f"AI Guidelines: {len(ai_docs)} characters")
478
+
479
+ # Get developer guide (architecture, development setup, contribution guidelines)
480
+ dev_docs = get_developer_guide()
481
+ print(f"Developer Guide: {len(dev_docs)} characters")
482
+
483
+ # Get machine-readable metadata (version, APIs, validators, CLI commands)
484
+ metadata_json = get_metadata()
485
+ metadata = json.loads(metadata_json)
486
+ print(f"Version: {metadata['version']}")
487
+ print(f"Public APIs: {metadata['public_api']}")
488
+ ```
489
+
490
+ **Use Cases:**
491
+ - **AI Assistants**: Provide context to AI agents helping users with the package
492
+ - **Offline Environments**: Access documentation without internet connection
493
+ - **Enterprise/Airgapped**: Full documentation in restricted environments
494
+ - **Automation**: Build tools that need package metadata programmatically
495
+
496
+ **Available Functions:**
497
+ - `get_ai_guidelines()` → Comprehensive AI assistant usage guide
498
+ - `get_developer_guide()` → Architecture and development documentation
499
+ - `get_metadata()` → Machine-readable project metadata (JSON)
500
+
501
+ ## 📁 Project Structure
502
+
503
+ ```
504
+ project_root/
505
+ ├── pyproject.toml # Configuration file
506
+ ├── src/
507
+ │ └── project_paths/ # Main package
508
+ │ ├── model.py # Core ProjectPaths class
509
+ │ ├── factory.py # Factory functions
510
+ │ ├── validators.py # Built-in validators
511
+ │ └── ...
512
+ └── tests/ # Test suite
513
+ ```
514
+
515
+ ## 🧪 Testing
516
+
517
+ Run the test suite:
518
+
519
+ ```bash
520
+ # Run all tests
521
+ uv run pytest
522
+
523
+ # With coverage
524
+ uv run pytest --cov=src --cov-report=term-missing
525
+
526
+ # Run specific test
527
+ uv run pytest tests/test_validators.py
528
+ ```
529
+
530
+ ## 🔧 Development
531
+
532
+ ### Setup Development Environment
533
+
534
+ ```bash
535
+ # Clone the repository
536
+ git clone https://github.com/yourusername/ptool-serena.git
537
+ cd ptool-serena
538
+
539
+ # Install with uv
540
+ uv sync
541
+
542
+ # Run tests
543
+ uv run pytest
544
+
545
+ # Format code
546
+ uv run ruff format .
547
+
548
+ # Lint
549
+ uv run ruff check .
550
+
551
+ # Type check
552
+ uv run mypy src/
553
+ ```
554
+
555
+ ### Code Quality Standards
556
+
557
+ This project follows strict quality standards defined in `CLAUDE.md`:
558
+
559
+ - **Minimal Compliance**: For prototypes and quick fixes
560
+ - **Standard Compliance**: For production code (80% test coverage)
561
+ - **Strict Compliance**: For critical systems (90% test coverage)
562
+
563
+ ## 📚 API Reference
564
+
565
+ ### ProjectPaths
566
+
567
+ Main class for path management.
568
+
569
+ #### Methods
570
+
571
+ - `from_config(config_path: str | Path) -> ProjectPaths`: Load from custom config
572
+ - `to_dict() -> dict[str, Path]`: Get all paths as dictionary
573
+ - `get_paths() -> dict[str, Path]`: Get only Path fields
574
+
575
+ ### Factory Functions
576
+
577
+ - `create_project_paths(validator=None, raise_on_error=False)`: Create with validation
578
+
579
+ ### Documentation Functions
580
+
581
+ - `get_ai_guidelines() -> str`: Return AI assistant guidelines for working with this package
582
+ - `get_developer_guide() -> str`: Return developer guide for contributing to this package
583
+ - `get_metadata() -> str`: Return machine-readable project metadata (JSON)
584
+
585
+ ### Validators
586
+
587
+ #### Built-in Validators
588
+
589
+ - `StrictPathValidator`: Ensures all paths exist and match expected types (file/directory)
590
+ - `SandboxPathValidator`: Prevents path traversal attacks and enforces base directory sandbox
591
+ - `CompositeValidator`: Combines multiple validators into a single validation pipeline
592
+
593
+ #### Validator Protocol
594
+
595
+ ```python
596
+ class PathValidatorProtocol(Protocol):
597
+ def validate(self, paths: Any) -> None: ...
598
+ def add_error(self, message: str) -> None: ...
599
+ def add_warning(self, message: str) -> None: ...
600
+ def add_info(self, key: str, value: Any) -> None: ...
601
+ @property
602
+ def has_errors(self) -> bool: ...
603
+ def clear(self) -> None: ...
604
+ ```
605
+
606
+ ## 🤝 Contributing
607
+
608
+ Contributions are welcome! Please read our contributing guidelines and follow the code style defined in `CLAUDE.md`.
609
+
610
+ 1. Fork the repository
611
+ 2. Create a feature branch
612
+ 3. Make your changes
613
+ 4. Run tests and linting
614
+ 5. Submit a pull request
615
+
616
+ ## 📄 License
617
+
618
+ MIT License - see LICENSE file for details.
619
+
620
+ ## 🔗 Links
621
+
622
+ - [Documentation](https://github.com/yourusername/ptool-serena/docs)
623
+ - [Issue Tracker](https://github.com/yourusername/ptool-serena/issues)
624
+ - [Changelog](CHANGELOG.md)
625
+
626
+ ## 💡 Examples
627
+
628
+ Check out the `tests/examples/` directory for more usage examples:
629
+
630
+ - Basic configuration loading
631
+ - Custom validator implementation
632
+ - Static model generation
633
+ - Integration with existing projects
634
+
635
+ ## 🛟 Support
636
+
637
+ - Open an issue for bug reports
638
+ - Start a discussion for feature requests
639
+ - Check existing issues before creating new ones
640
+
641
+ ---
642
+
643
+ Made with ❤️ for Python developers who value type safety and clean configuration management.
@@ -0,0 +1,20 @@
1
+ path_link-0.2.0.dist-info/licenses/LICENSE,sha256=aA7G9nVFO_aZED5c8AfjAIlwvLH09zkdwmYefc070r4,1158
2
+ project_paths/__init__.py,sha256=1zVkmr-8iQGJ71HMHMJhPw9bkode5pFTtH0g4_K2IW0,5103
3
+ project_paths/builder.py,sha256=yMFNDg51MG4jHIDTKcMzzcN5YU2wLBtB5crYkq0jhWU,2675
4
+ project_paths/cli.py,sha256=0K_2nQZOE2uFMmbcNmA1VEv13oB-YV_ad36Qy9Z1dAw,6644
5
+ project_paths/get_paths.py,sha256=U_hnGKxa14-om1RLUbKpkoTgp9-hgguVLJkbGc8_h40,4270
6
+ project_paths/main.py,sha256=HxvBm4gr44u42HBfhwLOP1w4ZKGKGj9Ke_-4uQ-31QY,70
7
+ project_paths/model.py,sha256=4qrm72Fh0NRuid3i3X0G_tT_lOz06PM5vQxYyi85R9o,2812
8
+ project_paths/project_paths_static.py,sha256=0K-Vi2RIrHHJJ56N3C6CCTEYUHzzcHnGx-FTEuHUKuE,558
9
+ project_paths/validation.py,sha256=JBKu2-NmU_x5jomLFrXy0sT87SiL9w1CpvWGq0QvOhc,2674
10
+ project_paths/builtin_validators/__init__.py,sha256=2fvsBGxrpo5YHI8D5aDFtb73PuXg86gzw23Um_rQf_A,201
11
+ project_paths/builtin_validators/sandbox.py,sha256=7rki6esWVVLhOIt7xmfyCWNzUxqX81qxzBBcrZra7FY,5601
12
+ project_paths/builtin_validators/strict.py,sha256=mKLjjn5Y_HEfL_aLL8_ZlC4r_hZMS4MfMGKrR2BYJCs,4082
13
+ project_paths/docs/ai_guidelines.md,sha256=fUVd7h2ChO5YJ3zPUoQ5DLNcSEpKAHVwSSTYoIj8K1M,19802
14
+ project_paths/docs/developer_guide.md,sha256=e-s-8kMHEiApZurwc6Gvc6P1SIe1crfOf00-hZyjndU,12361
15
+ project_paths/docs/metadata.json,sha256=Pgo1Xa8dDOItJaYLP16UTztFd-1ensI3tIRc5c4-8qA,4233
16
+ path_link-0.2.0.dist-info/METADATA,sha256=uYoiksSeA6Xq4kpRyDFgBoJXMmhYdiE5hygQvLbkCF0,18065
17
+ path_link-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
+ path_link-0.2.0.dist-info/entry_points.txt,sha256=-9RmhjQTx5GtiJ2YLyUWRIaLlHQperuSrniLiq8yT2M,49
19
+ path_link-0.2.0.dist-info/top_level.txt,sha256=iW2KR0fh0Zp23tT_drLikfiZ1Imr5tJpCdZKmg42dA4,14
20
+ path_link-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ptool = project_paths.cli:main
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lasse Tammilehto and AI contributors
4
+ Organization: Jäähdytyspalvelu
5
+ URL: http://jaahdytyspalvely.fi
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ project_paths