ostruct-cli 0.8.8__tar.gz → 1.0.0__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.
Files changed (91) hide show
  1. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/PKG-INFO +292 -126
  2. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/README.md +284 -95
  3. ostruct_cli-1.0.0/pyproject.toml +196 -0
  4. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/__init__.py +3 -15
  5. ostruct_cli-1.0.0/src/ostruct/cli/attachment_processor.py +455 -0
  6. ostruct_cli-1.0.0/src/ostruct/cli/attachment_template_bridge.py +973 -0
  7. ostruct_cli-1.0.0/src/ostruct/cli/cli.py +299 -0
  8. ostruct_cli-1.0.0/src/ostruct/cli/click_options.py +987 -0
  9. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/code_interpreter.py +195 -12
  10. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/commands/__init__.py +0 -3
  11. ostruct_cli-1.0.0/src/ostruct/cli/commands/run.py +420 -0
  12. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/config.py +23 -22
  13. ostruct_cli-1.0.0/src/ostruct/cli/constants.py +89 -0
  14. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/errors.py +191 -6
  15. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/explicit_file_processor.py +0 -15
  16. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/file_info.py +118 -14
  17. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/file_list.py +82 -1
  18. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/file_search.py +68 -2
  19. ostruct_cli-1.0.0/src/ostruct/cli/help_json.py +235 -0
  20. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/mcp_integration.py +13 -16
  21. ostruct_cli-1.0.0/src/ostruct/cli/params.py +217 -0
  22. ostruct_cli-1.0.0/src/ostruct/cli/plan_assembly.py +335 -0
  23. ostruct_cli-1.0.0/src/ostruct/cli/plan_printing.py +385 -0
  24. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/progress_reporting.py +8 -56
  25. ostruct_cli-1.0.0/src/ostruct/cli/quick_ref_help.py +128 -0
  26. ostruct_cli-1.0.0/src/ostruct/cli/rich_config.py +299 -0
  27. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/runner.py +397 -190
  28. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/__init__.py +2 -0
  29. ostruct_cli-1.0.0/src/ostruct/cli/security/allowed_checker.py +96 -0
  30. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/normalization.py +13 -9
  31. ostruct_cli-1.0.0/src/ostruct/cli/security/security_manager.py +948 -0
  32. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/types.py +15 -0
  33. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_debug.py +283 -261
  34. ostruct_cli-1.0.0/src/ostruct/cli/template_debug_help.py +253 -0
  35. ostruct_cli-1.0.0/src/ostruct/cli/template_env.py +105 -0
  36. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_filters.py +415 -8
  37. ostruct_cli-1.0.0/src/ostruct/cli/template_processor.py +829 -0
  38. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_rendering.py +49 -73
  39. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_validation.py +2 -1
  40. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/token_validation.py +35 -15
  41. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/types.py +15 -19
  42. ostruct_cli-1.0.0/src/ostruct/cli/unicode_compat.py +283 -0
  43. ostruct_cli-1.0.0/src/ostruct/cli/upload_manager.py +448 -0
  44. ostruct_cli-1.0.0/src/ostruct/cli/utils.py +63 -0
  45. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/validators.py +272 -54
  46. ostruct_cli-0.8.8/pyproject.toml +0 -149
  47. ostruct_cli-0.8.8/src/ostruct/cli/cli.py +0 -145
  48. ostruct_cli-0.8.8/src/ostruct/cli/click_options.py +0 -904
  49. ostruct_cli-0.8.8/src/ostruct/cli/commands/quick_ref.py +0 -54
  50. ostruct_cli-0.8.8/src/ostruct/cli/commands/run.py +0 -193
  51. ostruct_cli-0.8.8/src/ostruct/cli/security/allowed_checker.py +0 -55
  52. ostruct_cli-0.8.8/src/ostruct/cli/security/security_manager.py +0 -407
  53. ostruct_cli-0.8.8/src/ostruct/cli/template_debug_help.py +0 -162
  54. ostruct_cli-0.8.8/src/ostruct/cli/template_env.py +0 -64
  55. ostruct_cli-0.8.8/src/ostruct/cli/template_optimizer.py +0 -478
  56. ostruct_cli-0.8.8/src/ostruct/cli/template_processor.py +0 -1208
  57. ostruct_cli-0.8.8/src/ostruct/cli/utils.py +0 -33
  58. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/LICENSE +0 -0
  59. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/__init__.py +0 -0
  60. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/base_errors.py +0 -0
  61. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/cache_manager.py +0 -0
  62. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/commands/list_models.py +0 -0
  63. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/commands/update_registry.py +0 -0
  64. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/cost_estimation.py +0 -0
  65. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/exit_codes.py +0 -0
  66. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/field_utils.py +0 -0
  67. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/file_utils.py +0 -0
  68. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/json_extract.py +0 -0
  69. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/model_creation.py +0 -0
  70. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/model_validation.py +0 -0
  71. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/path_utils.py +0 -0
  72. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/progress.py +0 -0
  73. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/registry_updates.py +0 -0
  74. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/schema_utils.py +0 -0
  75. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/schema_validation.py +0 -0
  76. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/base.py +0 -0
  77. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/case_manager.py +0 -0
  78. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/errors.py +0 -0
  79. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/safe_joiner.py +0 -0
  80. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/symlink_resolver.py +0 -0
  81. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/security/windows_paths.py +0 -0
  82. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/sentinel.py +0 -0
  83. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/serialization.py +0 -0
  84. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/services.py +0 -0
  85. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_extensions.py +0 -0
  86. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_io.py +0 -0
  87. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_schema.py +0 -0
  88. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/template_utils.py +0 -0
  89. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/token_utils.py +0 -0
  90. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/cli/unattended_operation.py +0 -0
  91. {ostruct_cli-0.8.8 → ostruct_cli-1.0.0}/src/ostruct/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ostruct-cli
3
- Version: 0.8.8
3
+ Version: 1.0.0
4
4
  Summary: CLI for OpenAI Structured Output with Multi-Tool Integration
5
5
  Author: Yaniv Golan
6
6
  Author-email: yaniv@golan.name
@@ -10,55 +10,32 @@ Classifier: Programming Language :: Python :: 3.10
10
10
  Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
- Provides-Extra: dev
14
13
  Provides-Extra: docs
15
14
  Provides-Extra: examples
16
- Requires-Dist: anyio[trio] (==3.7.1) ; extra == "dev"
17
15
  Requires-Dist: asyncio-throttle (>=1.0.2,<2.0) ; extra == "examples"
18
- Requires-Dist: black (==24.8.0) ; extra == "dev"
19
- Requires-Dist: build (>=1.2.2.post1,<2.0) ; extra == "dev"
16
+ Requires-Dist: bleach (>=6.0.0,<7.0)
20
17
  Requires-Dist: cachetools (>=5.3.2,<6.0)
21
18
  Requires-Dist: chardet (>=5.0.0,<6.0)
22
19
  Requires-Dist: click (>=8.1.7,<9.0)
23
- Requires-Dist: flake8 (>=6.0,<7.0) ; extra == "dev"
24
- Requires-Dist: flake8-pyproject (>=1.2.3,<2.0) ; extra == "dev"
25
- Requires-Dist: hypothesis (>=6.0.0,<7.0) ; extra == "dev"
26
20
  Requires-Dist: ijson (>=3.2.3,<4.0)
27
21
  Requires-Dist: jinja2 (>=3.1.2,<4.0)
28
22
  Requires-Dist: jsonschema (>=4.23.0,<5.0)
29
- Requires-Dist: mypy (>=1.0,<2.0) ; extra == "dev"
30
- Requires-Dist: myst-parser (>=2.0.0,<3.0) ; extra == "docs"
23
+ Requires-Dist: myst-parser (>=4.0.1,<5.0) ; extra == "docs"
31
24
  Requires-Dist: openai (==1.81.0)
32
25
  Requires-Dist: openai-model-registry (>=0.7.0,<1.0)
33
- Requires-Dist: pre-commit (>=4.1.0,<5.0) ; extra == "dev"
34
- Requires-Dist: psutil (>=7.0.0,<8.0) ; extra == "dev"
35
26
  Requires-Dist: pydantic (>=2.6.3,<3.0)
36
- Requires-Dist: pyfakefs (>=5.7.4,<6.0) ; extra == "dev"
37
27
  Requires-Dist: pygments (>=2.15.0,<3.0)
38
- Requires-Dist: pytest (>=8.3.4,<9.0) ; extra == "dev"
39
- Requires-Dist: pytest-asyncio (>=0.25.2,<1.0) ; extra == "dev"
40
- Requires-Dist: pytest-mock (>=3.14.0,<4.0) ; extra == "dev"
41
- Requires-Dist: pytest-rerunfailures (>=12.0,<13.0) ; extra == "dev"
42
28
  Requires-Dist: python-dotenv (>=1.0.1,<2.0)
43
- Requires-Dist: python-dotenv (>=1.0.1,<2.0) ; extra == "dev"
44
29
  Requires-Dist: pyyaml (>=6.0.2,<7.0)
45
- Requires-Dist: sphinx (>=7.0,<8.0) ; extra == "dev"
46
- Requires-Dist: sphinx (>=7.0,<8.0) ; extra == "docs"
47
- Requires-Dist: sphinx-design (>=0.5.0,<1.0) ; extra == "docs"
48
- Requires-Dist: sphinx-rtd-theme (>=1.0,<2.0) ; extra == "docs"
30
+ Requires-Dist: rich (>=13.0.0,<14.0.0)
31
+ Requires-Dist: rich-click (>=1.8.9,<2.0.0)
32
+ Requires-Dist: sphinx (>=7.0.0,<8.0) ; extra == "docs"
33
+ Requires-Dist: sphinx-design (>=0.4.1,<1.0) ; extra == "docs"
34
+ Requires-Dist: sphinx-rtd-theme (>=2.0,<3.0) ; extra == "docs"
49
35
  Requires-Dist: tenacity (>=8.2.3,<9.0) ; extra == "examples"
50
36
  Requires-Dist: tiktoken (==0.9.0)
51
37
  Requires-Dist: tomli (>=2.0.1,<3.0) ; (python_version < "3.11") and (extra == "docs")
52
- Requires-Dist: tomli (>=2.0.1,<3.0) ; extra == "dev"
53
38
  Requires-Dist: tomli (>=2.0.1,<3.0) ; python_version < "3.11"
54
- Requires-Dist: twine (>=6.0.1,<7.0) ; extra == "dev"
55
- Requires-Dist: types-cachetools (>=5.5.0.20240820) ; extra == "dev"
56
- Requires-Dist: types-chardet (>=5.0.4.6) ; extra == "dev"
57
- Requires-Dist: types-click (>=7.1.8,<8.0) ; extra == "dev"
58
- Requires-Dist: types-jsonschema (>=4.23.0.20241208) ; extra == "dev"
59
- Requires-Dist: types-pygments (>=2.19.0.20250107) ; extra == "dev"
60
- Requires-Dist: types-pyyaml (>=6.0.12.20241230) ; extra == "dev"
61
- Requires-Dist: types-requests (>=2.32.0.20241016) ; extra == "dev"
62
39
  Requires-Dist: typing-extensions (>=4.9.0,<5.0)
63
40
  Requires-Dist: werkzeug (>=3.1.3,<4.0)
64
41
  Description-Content-Type: text/markdown
@@ -95,7 +72,7 @@ ostruct processes unstructured data (text files, code, CSVs, etc.), input variab
95
72
 
96
73
  <div align="center">
97
74
 
98
- ![How ostruct works](src/assets/ostrict-hl-diagram.png)
75
+ ![How ostruct works](src/assets/ostruct-hl-diagram.png)
99
76
 
100
77
  </div>
101
78
 
@@ -116,11 +93,11 @@ ostruct can be used for various scenarios, including:
116
93
  ### Automated Code Review with Multi-Tool Analysis
117
94
 
118
95
  ```bash
119
- # Traditional pattern matching
120
- ostruct run prompts/task.j2 schemas/code_review.json -p source "examples/security/*.py"
96
+ # Template-only analysis (fast, cost-effective)
97
+ ostruct run prompts/task.j2 schemas/code_review.json --collect source @file-list.txt
121
98
 
122
99
  # Enhanced with Code Interpreter for deeper analysis
123
- ostruct run prompts/task.j2 schemas/code_review.json -fc examples/security/ -fs documentation/
100
+ ostruct run prompts/task.j2 schemas/code_review.json --file ci:code examples/security/ --file fs:docs documentation/
124
101
  ```
125
102
 
126
103
  Analyze code for security vulnerabilities, style issues, and performance problems. The enhanced version uses Code Interpreter for execution analysis and File Search for documentation context.
@@ -130,15 +107,15 @@ Analyze code for security vulnerabilities, style issues, and performance problem
130
107
  ```bash
131
108
  # Budget-friendly static analysis (recommended for most projects)
132
109
  ostruct run prompts/static_analysis.j2 schemas/scan_result.json \
133
- -d code examples -R --sys-file prompts/system.txt
110
+ --dir code examples --pattern "*.py" --sys-file prompts/system.txt
134
111
 
135
112
  # Professional security analysis with Code Interpreter (best balance)
136
113
  ostruct run prompts/code_interpreter.j2 schemas/scan_result.json \
137
- -dc examples --sys-file prompts/system.txt
114
+ --dir ci:code examples --sys-file prompts/system.txt
138
115
 
139
116
  # Comprehensive hybrid analysis for critical applications
140
117
  ostruct run prompts/hybrid_analysis.j2 schemas/scan_result.json \
141
- -d code examples -R -dc examples --sys-file prompts/system.txt
118
+ --dir code examples --dir ci:analysis examples --sys-file prompts/system.txt
142
119
  ```
143
120
 
144
121
  **Three optimized approaches** for automated security vulnerability scanning:
@@ -154,8 +131,8 @@ Each approach finds the same core vulnerabilities but with different levels of d
154
131
  ```bash
155
132
  # Upload data for analysis and visualization
156
133
  ostruct run analysis.j2 schemas/analysis_result.json \
157
- -fc sales_data.csv -fc customer_data.json \
158
- -fs reports/ -ft config.yaml
134
+ --file ci:sales sales_data.csv --file ci:customers customer_data.json \
135
+ --dir fs:reports reports/ --file config config.yaml
159
136
  ```
160
137
 
161
138
  Perform sophisticated data analysis using Python execution, generate visualizations, and create comprehensive reports with document context.
@@ -165,11 +142,11 @@ Perform sophisticated data analysis using Python execution, generate visualizati
165
142
  ```bash
166
143
  # Traditional file comparison
167
144
  ostruct run prompts/task.j2 schemas/validation_result.json \
168
- -f dev examples/basic/dev.yaml -f prod examples/basic/prod.yaml
145
+ --file dev examples/basic/dev.yaml --file prod examples/basic/prod.yaml
169
146
 
170
147
  # Enhanced with environment context
171
148
  ostruct run prompts/task.j2 schemas/validation_result.json \
172
- -ft dev.yaml -ft prod.yaml -fs infrastructure_docs/
149
+ --file dev dev.yaml --file prod prod.yaml --dir fs:docs infrastructure_docs/
173
150
  ```
174
151
 
175
152
  Validate configuration files across environments with documentation context for better analysis and recommendations.
@@ -179,11 +156,40 @@ Oh, and also, among endless other use cases:
179
156
  ### Etymology Analysis
180
157
 
181
158
  ```bash
182
- ostruct run prompts/task.j2 schemas/etymology.json -ft examples/scientific.txt
159
+ ostruct run prompts/task.j2 schemas/etymology.json --file text examples/scientific.txt
183
160
  ```
184
161
 
185
162
  Break down words into their components, showing their origins, meanings, and hierarchical relationships. Useful for linguistics, educational tools, and understanding terminology in specialized fields.
186
163
 
164
+ ### Optional File References
165
+
166
+ ```bash
167
+ # Attach files with aliases
168
+ ostruct run template.j2 schema.json \
169
+ --dir source-code src/ \
170
+ --file config config.yaml
171
+ ```
172
+
173
+ **Two ways to access files in templates:**
174
+
175
+ ```jinja2
176
+ {# Option 1: Automatic XML appendix (optional) #}
177
+ Analyze {{ file_ref("source-code") }} and {{ file_ref("config") }}.
178
+
179
+ {# Option 2: Manual formatting (full control) #}
180
+ ## Source Code
181
+ {% for file in source-code %}
182
+ ### {{ file.name }}
183
+ ```{{ file.name.split('.')[-1] }}
184
+ {{ file.content }}
185
+ ```
186
+
187
+ {% endfor %}
188
+
189
+ ```
190
+
191
+ The optional `file_ref()` function provides clean references with automatic XML appendix generation. Alternatively, access files directly for custom formatting and placement control. Perfect for code reviews, documentation analysis, and multi-file processing workflows.
192
+
187
193
  ## Features
188
194
 
189
195
  ### Core Capabilities
@@ -201,7 +207,7 @@ Break down words into their components, showing their origins, meanings, and hie
201
207
  - **File Search**: Vector-based document search and retrieval from uploaded files
202
208
  - **Web Search**: Real-time information retrieval and current data access via OpenAI's web search tool
203
209
  - **MCP Servers**: Connect to Model Context Protocol servers for extended functionality
204
- - **Explicit File Routing**: Route different files to specific tools for optimized processing
210
+ - **Explicit Tool Targeting**: Route files to specific tools (prompt, code-interpreter, file-search) with precise control
205
211
 
206
212
  ### Advanced Features
207
213
 
@@ -209,6 +215,7 @@ Break down words into their components, showing their origins, meanings, and hie
209
215
  - **Unattended Operation**: Designed for CI/CD and automation scenarios
210
216
  - **Progress Reporting**: Real-time progress updates with clear, user-friendly messaging
211
217
  - **Model Registry**: Dynamic model management with support for latest OpenAI models
218
+ - **Optional File References**: Clean `file_ref()` function for automatic XML appendix, or direct file access for custom formatting
212
219
 
213
220
  ## Requirements
214
221
 
@@ -216,23 +223,93 @@ Break down words into their components, showing their origins, meanings, and hie
216
223
 
217
224
  ## Installation
218
225
 
219
- ### Quick Install (macOS)
226
+ We provide multiple installation methods to suit different user needs. Choose the one that's right for you.
220
227
 
221
- For macOS users, we provide a one-line installer that handles everything automatically:
228
+ <details>
229
+ <summary><strong>Recommended: pipx</strong></summary>
230
+
231
+ `pipx` is the recommended installation method. It installs `ostruct` in an isolated environment, preventing conflicts with other Python packages.
232
+
233
+ **macOS (with Homebrew):**
234
+ ```bash
235
+ brew install pipx
236
+ pipx install ostruct-cli # new users
237
+ pipx upgrade ostruct-cli # existing users
238
+ ```
239
+
240
+ **Linux (Ubuntu/Debian):**
222
241
 
223
242
  ```bash
224
- curl -sSL https://github.com/yaniv-golan/ostruct/releases/latest/download/install-macos.sh | bash
243
+ sudo apt install pipx
244
+ pipx install ostruct-cli # new users
245
+ pipx upgrade ostruct-cli # existing users
225
246
  ```
226
247
 
227
- This script will:
248
+ **Other systems:**
249
+
250
+ ```bash
251
+ python3 -m pip install --user pipx
252
+ python3 -m pipx ensurepath
253
+ # Restart your terminal
254
+ pipx install ostruct-cli
255
+ ```
256
+
257
+ </details>
258
+
259
+ <details>
260
+ <summary><strong>macOS: Homebrew</strong></summary>
261
+
262
+ If you're on macOS and use Homebrew, you can install `ostruct` with a single command:
263
+
264
+ ```bash
265
+ brew install yaniv-golan/ostruct/ostruct-cli
266
+ ```
267
+
268
+ </details>
269
+
270
+ <details>
271
+ <summary><strong>Standalone Binaries (No Python Required)</strong></summary>
272
+
273
+ We provide pre-compiled .zip archives for macOS, Windows, and Linux that do not require Python to be installed.
274
+
275
+ 1. Go to the [**Latest Release**](https://github.com/yaniv-golan/ostruct/releases/latest) page.
276
+ 2. Download the `.zip` file for your operating system (e.g., `ostruct-macos-latest.zip`, `ostruct-windows-latest.zip`, `ostruct-ubuntu-latest.zip`).
277
+ 3. Extract the `.zip` file. This will create a folder (e.g., `ostruct-macos-amd64`).
278
+ 4. On macOS/Linux, make the executable inside the extracted folder runnable:
279
+
280
+ ```bash
281
+ chmod +x /path/to/ostruct-macos-amd64/ostruct
282
+ ```
283
+
284
+ 5. Run the executable from within the extracted folder, as it depends on bundled libraries in the same directory.
285
+
286
+ </details>
287
+
288
+ <details>
289
+ <summary><strong>Docker</strong></summary>
290
+
291
+ If you prefer to use Docker, you can run `ostruct` from our official container image available on the GitHub Container Registry.
292
+
293
+ ```bash
294
+ docker run -it --rm \
295
+ -v "$(pwd)":/app \
296
+ -w /app \
297
+ ghcr.io/yaniv-golan/ostruct:latest \
298
+ run template.j2 schema.json --file config input.txt
299
+ ```
300
+
301
+ This command mounts the current directory into the container and runs `ostruct`.
302
+
303
+ </details>
228
304
 
229
- - Install Python 3.10+ if needed (via Homebrew or python.org)
230
- - Install Homebrew if needed
231
- - Install ostruct-cli via pip
232
- - Configure your shell PATH automatically
233
- - Verify the installation works
305
+ ### Uninstallation
234
306
 
235
- After installation, restart your terminal and test with `ostruct --version`.
307
+ To uninstall `ostruct`, use the method corresponding to how you installed it:
308
+
309
+ - **pipx**: `pipx uninstall ostruct-cli`
310
+ - **Homebrew**: `brew uninstall ostruct-cli`
311
+ - **Binaries**: Simply delete the binary file.
312
+ - **Docker**: No uninstallation is needed for the image itself, but you can remove it with `docker rmi ghcr.io/yaniv-golan/ostruct:latest`.
236
313
 
237
314
  ### Manual Installation
238
315
 
@@ -254,12 +331,25 @@ If you plan to contribute to the project, see the [Development Setup](#developme
254
331
 
255
332
  ostruct-cli respects the following environment variables:
256
333
 
334
+ **API Configuration:**
335
+
257
336
  - `OPENAI_API_KEY`: Your OpenAI API key (required unless provided via command line)
258
337
  - `OPENAI_API_BASE`: Custom API base URL (optional)
259
338
  - `OPENAI_API_VERSION`: API version to use (optional)
260
339
  - `OPENAI_API_TYPE`: API type (e.g., "azure") (optional)
340
+
341
+ **System Configuration:**
342
+
261
343
  - `OSTRUCT_DISABLE_REGISTRY_UPDATE_CHECKS`: Set to "1", "true", or "yes" to disable automatic registry update checks
262
- - `MCP_<NAME>_URL`: Custom MCP server URLs (e.g., `MCP_STRIPE_URL=https://mcp.stripe.com`)
344
+ - `OSTRUCT_MCP_URL_<name>`: Custom MCP server URLs (e.g., `OSTRUCT_MCP_URL_stripe=https://mcp.stripe.com`)
345
+
346
+ **Template Processing Limits (Template-only files via `--file alias path`):**
347
+
348
+ - `OSTRUCT_TEMPLATE_FILE_LIMIT`: Maximum individual file size for template access (default: 65536 bytes / 64KB)
349
+ - `OSTRUCT_TEMPLATE_TOTAL_LIMIT`: Maximum total file size for all template files (default: 1048576 bytes / 1MB)
350
+ - `OSTRUCT_TEMPLATE_PREVIEW_LIMIT`: Maximum characters shown in template debugging previews (default: 4096)
351
+
352
+ > **Note**: Template limits only apply to files accessed via `--file alias path` (template-only routing). Files routed to Code Interpreter (`--file ci:`) or File Search (`--file fs:`) are not subject to these limits.
263
353
 
264
354
  **💡 Tip**: ostruct automatically loads `.env` files from the current directory. Environment variables take precedence over `.env` file values.
265
355
 
@@ -304,78 +394,101 @@ Shell completion will help you with:
304
394
 
305
395
  ## Enhanced CLI with Multi-Tool Integration
306
396
 
307
- ### Migration Notice
397
+ ### Breaking Changes in v0.9.0
398
+
399
+ **⚠️ Important:** ostruct v0.9.0 introduces breaking changes to the file attachment system. The legacy file routing syntax has been completely replaced with a new explicit target/alias attachment system.
308
400
 
309
- ostruct now includes powerful multi-tool integration while maintaining **full backward compatibility**. All existing commands continue to work exactly as before, but you can now take advantage of:
401
+ **New capabilities in v0.9.0:**
310
402
 
311
- - **Code Interpreter** for data analysis and visualization
312
- - **File Search** for document retrieval
313
- - **Web Search** for real-time information access
314
- - **MCP Servers** for extended functionality
315
- - **Explicit File Routing** for optimized processing
403
+ - **Explicit Tool Targeting**: Direct control over which tools receive files
404
+ - **Enhanced Security**: Three-tier security modes with path validation
405
+ - **Improved Multi-Tool Integration**: Better file sharing between tools
406
+ - **JSON Help Output**: Programmatic access to command help
407
+ - **Migration Guide**: Automated migration scripts for bulk updates
316
408
 
317
409
  <details>
318
- <summary><strong>New File Routing Options</strong> (Click to expand)</summary>
410
+ <summary><strong>New Attachment System (v0.9.0)</strong> (Click to expand)</summary>
319
411
 
320
- #### Basic File Routing (Explicit Tool Assignment)
412
+ #### Basic File Attachments
321
413
 
322
414
  ```bash
323
- # Template access only (config files, small data)
324
- ostruct run template.j2 schema.json -ft config.yaml
415
+ # Template access only (default - no tool upload)
416
+ ostruct run template.j2 schema.json --file config config.yaml
325
417
 
326
418
  # Code Interpreter (data analysis, code execution)
327
- ostruct run analysis.j2 schema.json -fc data.csv
419
+ ostruct run analysis.j2 schema.json --file ci:data data.csv
328
420
 
329
421
  # File Search (document retrieval)
330
- ostruct run search.j2 schema.json -fs documentation.pdf
331
-
332
- # Web Search (real-time information)
333
- ostruct run research.j2 schema.json --enable-tool web-search -V topic="latest AI developments"
422
+ ostruct run search.j2 schema.json --file fs:docs documentation.pdf
334
423
 
335
- # Multiple tools with one file
336
- ostruct run template.j2 schema.json --file-for code-interpreter shared.json --file-for file-search shared.json
424
+ # Multi-tool attachment (share between tools)
425
+ ostruct run workflow.j2 schema.json --file ci,fs:shared data.json
337
426
  ```
338
427
 
339
- #### Directory Routing
428
+ #### Directory Attachments
340
429
 
341
- ostruct provides two directory routing patterns to match different use cases:
430
+ ```bash
431
+ # Template-only directory access
432
+ ostruct run template.j2 schema.json --dir config ./config
342
433
 
343
- **Auto-Naming Pattern** (for known directory structures):
434
+ # Upload directory to Code Interpreter
435
+ ostruct run analysis.j2 schema.json --dir ci:datasets ./data
344
436
 
345
- ```bash
346
- # Variables are auto-generated from directory contents
347
- ostruct run template.j2 schema.json -dt ./config -dc ./datasets -ds ./docs
348
- # Creates variables like: config_yaml, datasets_csv, docs_pdf (based on actual files)
437
+ # Upload directory to File Search
438
+ ostruct run search.j2 schema.json --dir fs:knowledge ./docs
439
+
440
+ # Directory with file pattern filtering
441
+ ostruct run template.j2 schema.json --dir source ./src --pattern "*.py"
349
442
  ```
350
443
 
351
- **Alias Pattern** (for generic, reusable templates):
444
+ #### File Collections
352
445
 
353
446
  ```bash
354
- # Create stable variable names regardless of directory contents
355
- ostruct run template.j2 schema.json --dta app_config ./config --dca data ./datasets --dsa knowledge ./docs
356
- # Creates stable variables: app_config, data, knowledge (always these names)
447
+ # Process multiple files from list
448
+ ostruct run batch.j2 schema.json --collect files @file-list.txt
449
+
450
+ # Upload collection to Code Interpreter
451
+ ostruct run analyze.j2 schema.json --collect ci:data @datasets.txt
357
452
  ```
358
453
 
359
- **When to Use Each Pattern:**
454
+ #### Tool Targeting
360
455
 
361
- - Use **auto-naming** (`-dt`, `-dc`, `-ds`) when your template knows the specific directory structure
362
- - Use **alias syntax** (`--dta`, `--dca`, `--dsa`) when your template is generic and needs stable variable names
456
+ The new system uses explicit targets for precise control:
363
457
 
364
- **Template Example:**
458
+ - **`prompt`** (default): Template access only, no upload
459
+ - **`code-interpreter`** or **`ci`**: Upload for Python execution and analysis
460
+ - **`file-search`** or **`fs`**: Upload to vector store for document search
461
+ - **Multi-target**: `ci,fs:alias` shares file between multiple tools
365
462
 
366
- ```jinja
367
- {# Works with alias pattern - variables are predictable #}
368
- {% for file in app_config %}
369
- Configuration: {{ file.name }} = {{ file.content }}
370
- {% endfor %}
463
+ #### Development Best Practice: Always Use --dry-run
371
464
 
372
- {# Analysis data from stable variable name #}
373
- {% for file in data %}
374
- Processing: {{ file.path }}
375
- {% endfor %}
465
+ **Validate templates before execution** to catch errors early and save API costs:
466
+
467
+ ```bash
468
+ # 1. Validate everything first (catches binary file issues, template errors)
469
+ ostruct run analysis.j2 schema.json --file ci:data report.xlsx --dry-run
470
+
471
+ # 2. If validation passes, run for real
472
+ ostruct run analysis.j2 schema.json --file ci:data report.xlsx
376
473
  ```
377
474
 
378
- This design pattern makes templates reusable across different projects while maintaining full backward compatibility.
475
+ The `--dry-run` flag performs comprehensive validation including template rendering, catching issues like:
476
+
477
+ - Binary file content access errors
478
+ - Template syntax problems
479
+ - Missing template variables
480
+ - File accessibility issues
481
+
482
+ #### Security Modes
483
+
484
+ ```bash
485
+ # Strict security with explicit allowlists
486
+ ostruct run template.j2 schema.json \
487
+ --path-security strict \
488
+ --allow /safe/directory \
489
+ --allow-file /specific/file.txt \
490
+ --file data input.txt
491
+ ```
379
492
 
380
493
  #### MCP Server Integration
381
494
 
@@ -397,7 +510,7 @@ models:
397
510
  tools:
398
511
  code_interpreter:
399
512
  auto_download: true
400
- output_directory: "./output"
513
+ output_directory: "./downloads"
401
514
  download_strategy: "two_pass_sentinel" # Enable reliable file downloads
402
515
 
403
516
  mcp:
@@ -413,6 +526,44 @@ Load custom configuration:
413
526
  ostruct --config my-config.yaml run template.j2 schema.json
414
527
  ```
415
528
 
529
+ ### Model Validation
530
+
531
+ ostruct automatically validates model names against the OpenAI model registry. Only models that support structured output are available for selection, ensuring compatibility with JSON schema outputs.
532
+
533
+ ```bash
534
+ # See all available models with details
535
+ ostruct list-models
536
+
537
+ # Models are validated at command time
538
+ ostruct run template.j2 schema.json --model invalid-model
539
+ # Error: Invalid model 'invalid-model'. Available models: gpt-4o, gpt-4o-mini, o1 (and 12 more).
540
+ # Run 'ostruct list-models' to see all 15 available models.
541
+
542
+ # Shell completion works with model names
543
+ ostruct run template.j2 schema.json --model <TAB>
544
+ # Shows: gpt-4o gpt-4o-mini o1 o1-mini o3-mini ...
545
+ ```
546
+
547
+ **Model Registry Updates:**
548
+
549
+ The model list is automatically updated when you run `ostruct update-registry`. If you encounter model validation errors, try updating your registry first:
550
+
551
+ ```bash
552
+ # Update model registry
553
+ ostruct update-registry
554
+
555
+ # Check available models
556
+ ostruct list-models
557
+ ```
558
+
559
+ **Migration from Free-form Model Names:**
560
+
561
+ If you have existing scripts with hardcoded model names, they will continue to work as long as the model names are valid. Common issues and solutions:
562
+
563
+ - **Typos**: `gpt4o` → `gpt-4o`
564
+ - **Old names**: `gpt-4-turbo` → `gpt-4o`
565
+ - **Custom names**: Use `ostruct list-models` to see what's available
566
+
416
567
  ### Code Interpreter File Downloads
417
568
 
418
569
  **Important**: If you're using Code Interpreter with structured output (JSON schemas), you may need to enable the two-pass download strategy to ensure files are downloaded reliably.
@@ -421,10 +572,14 @@ ostruct --config my-config.yaml run template.j2 schema.json
421
572
 
422
573
  ```bash
423
574
  # Enable reliable file downloads for this run
424
- ostruct run template.j2 schema.json -fc data.csv --enable-feature ci-download-hack
575
+ ostruct run template.j2 schema.json --file ci:data data.csv --enable-feature ci-download-hack
425
576
 
426
577
  # Force single-pass mode (override config)
427
- ostruct run template.j2 schema.json -fc data.csv --disable-feature ci-download-hack
578
+ ostruct run template.j2 schema.json --file ci:data data.csv --disable-feature ci-download-hack
579
+
580
+ # Handle duplicate output file names
581
+ ostruct run template.j2 schema.json --file ci:data data.csv --ci-duplicate-outputs rename
582
+ ostruct run template.j2 schema.json --file ci:data data.csv --ci-duplicate-outputs skip
428
583
  ```
429
584
 
430
585
  #### Option 2: Configuration File (Recommended for persistent settings)
@@ -436,6 +591,8 @@ tools:
436
591
  download_strategy: "two_pass_sentinel" # Enables reliable file downloads
437
592
  auto_download: true
438
593
  output_directory: "./downloads"
594
+ duplicate_outputs: "rename" # Handle duplicate file names: overwrite|rename|skip
595
+ output_validation: "basic" # Validate downloaded files: basic|strict|off
439
596
  ```
440
597
 
441
598
  **Why this is needed**: OpenAI's structured output mode can prevent file download annotations from being generated. The two-pass strategy works around this by making two API calls: one to generate files (without structured output), then another to ensure schema compliance. For detailed technical information, see [docs/known-issues/2025-06-responses-ci-file-output.md](docs/known-issues/2025-06-responses-ci-file-output.md).
@@ -446,6 +603,8 @@ tools:
446
603
 
447
604
  🚀 **New to ostruct?** Follow our [step-by-step quickstart guide](https://ostruct.readthedocs.io/en/latest/user-guide/quickstart.html) featuring Juno the beagle for a hands-on introduction.
448
605
 
606
+ 📝 **Template Scripting:** Learn ostruct's templating capabilities with the [template scripting guide](https://ostruct.readthedocs.io/en/latest/user-guide/ostruct_template_scripting_guide.html) - no prior Jinja2 knowledge required!
607
+
449
608
  📖 **Full Documentation:** <https://ostruct.readthedocs.io/>
450
609
 
451
610
  ### Quick Start
@@ -555,47 +714,54 @@ Provide comprehensive analysis and actionable insights.
555
714
  }
556
715
  ```
557
716
 
558
- 3. For more complex scenarios, use explicit file routing with flexible syntax options:
717
+ 3. Use the new attachment system for precise tool targeting:
559
718
 
560
719
  ```bash
561
- # Auto-naming (fastest for one-off analysis)
720
+ # Basic multi-tool analysis
562
721
  ostruct run analysis_template.j2 analysis_schema.json \
563
- -fc sales_data.csv \
564
- -fc customer_data.json \
565
- -fs market_reports.pdf \
566
- -ft config.yaml
722
+ --file ci:sales sales_data.csv \
723
+ --file ci:customers customer_data.json \
724
+ --file fs:reports market_reports.pdf \
725
+ --file config config.yaml
567
726
 
568
- # Mixed syntax with custom variable names
727
+ # Multi-tool attachment with shared data
569
728
  ostruct run analysis_template.j2 analysis_schema.json \
570
- -fc sales_data.csv \
571
- -fc customers customer_data.json \
572
- --fsa reports market_reports.pdf \
573
- --fta app_config config.yaml
729
+ --file ci,fs:shared_data data.json \
730
+ --file prompt:config settings.yaml
574
731
 
575
- # Alias syntax for reusable templates (best tab completion)
732
+ # Directory-based analysis
576
733
  ostruct run reusable_analysis.j2 analysis_schema.json \
577
- --fca sales_data sales_data.csv \
578
- --fca customer_data customer_data.json \
579
- --fsa market_reports market_reports.pdf \
580
- --fta config config.yaml
734
+ --dir ci:sales_data ./sales \
735
+ --dir fs:documentation ./docs \
736
+ --file config ./config.yaml
581
737
 
582
- # Code review with stable variable names
738
+ # Code review with multiple tool integration
583
739
  ostruct run code_review.j2 review_schema.json \
584
- --fca source_code source_code/ \
585
- --fsa documentation docs/ \
586
- --fta eslint_config .eslintrc.json
740
+ --dir ci:source ./src \
741
+ --dir fs:docs ./documentation \
742
+ --file config .eslintrc.json
587
743
  ```
588
744
 
589
- ### Example 3: Legacy Compatibility
745
+ ### Example 3: Migration from v0.8.x
590
746
 
591
- All existing commands continue to work unchanged:
747
+ Legacy commands need to be updated to the new syntax:
592
748
 
593
749
  ```bash
594
- # Traditional usage (fully supported)
595
- ostruct run extract_from_file.j2 schema.json -f text input.txt -d configs
596
- ostruct run template.j2 schema.json -p "*.py" source -V env=prod
750
+ # Legacy (v0.8.x) - NO LONGER SUPPORTED
751
+ # ostruct run extract_from_file.j2 schema.json --file text input.txt -d configs
752
+
753
+ # New (v0.9.0) - Updated syntax
754
+ ostruct run extract_from_file.j2 schema.json --file text input.txt --dir configs ./configs
755
+
756
+ # Legacy pattern matching - NO LONGER SUPPORTED
757
+ # ostruct run template.j2 schema.json --dir "*.py" source --pattern "*.py" -V env=prod
758
+
759
+ # New pattern matching with directory attachment
760
+ ostruct run template.j2 schema.json --dir source ./source --pattern "*.py" -V env=prod
597
761
  ```
598
762
 
763
+ **Migration Help:** See `MIGRATION_GUIDE.md` for automated migration scripts and detailed examples.
764
+
599
765
  <details>
600
766
  <summary><strong>System Prompt Handling</strong> (Click to expand)</summary>
601
767