Skip to content

Commit 9e27fff

Browse files
feat(examples): CLI interface improvements
changes: - file: common.py area: core modified: [generate_spec] - file: function_logic.py area: core modified: [FunctionLogicGenerator, generate_toon_schema] - file: behavioral_benchmark.py area: core added: [_looks_like_template_stub] modified: [main, _run_case, FunctionBehaviorResult] - file: benchmark_report.py area: core modified: [main] - file: benchmark_summary.py area: core added: [_token_estimate_bytes, _fmt_bytes, _artifact_row] modified: [main] stats: lines: "+209/-66 (net +143)" files: 14 complexity: "Large structural change (normalized)"
1 parent bff89d3 commit 9e27fff

22 files changed

Lines changed: 243 additions & 73 deletions

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# OpenRouter (https://openrouter.ai)
99
OPENROUTER_API_KEY=sk-or-v1-your-key-here
1010
OPENROUTER_MODEL=qwen/qwen-2.5-coder-32b-instruct
11+
BENCH_USE_LLM=1
1112

1213
# OpenAI (https://platform.openai.com)
1314
OPENAI_API_KEY=sk-your-key-here

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
## [1.0.39] - 2026-02-25
2+
3+
### Summary
4+
5+
feat(examples): CLI interface improvements
6+
7+
### Docs
8+
9+
- docs: update README
10+
- docs: update 03-cli-reference.md
11+
- docs: update 07-toon.md
12+
13+
### Other
14+
15+
- update .env.example
16+
- build: update Makefile
17+
- update code2logic/benchmarks/common.py
18+
- update code2logic/function_logic.py
19+
- update examples/behavioral_benchmark.py
20+
- update examples/benchmark_report.py
21+
- update examples/benchmark_summary.py
22+
- update function.toon
23+
- update project.functions-schema.json
24+
- update project.functions.toon
25+
- ... and 1 more
26+
27+
128
## [1.0.38] - 2026-02-25
229

330
### Summary

Makefile

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,16 @@ status: ## Show library status
306306
BENCH_SAMPLES := tests/samples
307307
BENCH_OUTPUT := examples/output
308308
BENCH_LIMIT := 20
309-
BENCH_FORMATS := yaml toon logicml json
309+
BENCH_FORMATS := yaml toon logicml json markdown csv gherkin
310+
311+
# Set BENCH_USE_LLM=1 to run benchmarks with a configured LLM provider
312+
# (e.g. OpenRouter) instead of offline template mode.
313+
BENCH_USE_LLM ?= 0
314+
ifeq ($(BENCH_USE_LLM),1)
315+
BENCH_NO_LLM_FLAG :=
316+
else
317+
BENCH_NO_LLM_FLAG := --no-llm
318+
endif
310319

311320
benchmark: benchmark-format benchmark-function benchmark-token benchmark-project benchmark-toon benchmark-compare ## Run all benchmarks (no LLM)
312321
@echo ""
@@ -324,19 +333,19 @@ benchmark-format: ## Benchmark format reproduction (yaml/toon/logicml/json)
324333
@echo "# Auto-generated by make benchmark" > $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
325334
@echo "set -euo pipefail" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
326335
@echo "" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
327-
@printf '%s\n' "$(PYTHON) examples/15_unified_benchmark.py --no-llm --type format --folder $(BENCH_SAMPLES)/ --formats $(BENCH_FORMATS) --limit $(BENCH_LIMIT) --verbose --output $(BENCH_OUTPUT)/benchmark_format.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
336+
@printf '%s\n' "$(PYTHON) examples/15_unified_benchmark.py $(BENCH_NO_LLM_FLAG) --type format --folder $(BENCH_SAMPLES)/ --formats $(BENCH_FORMATS) --limit $(BENCH_LIMIT) --verbose --output $(BENCH_OUTPUT)/benchmark_format.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
328337
$(PYTHON) examples/15_unified_benchmark.py \
329-
--no-llm --type format \
338+
$(BENCH_NO_LLM_FLAG) --type format \
330339
--folder $(BENCH_SAMPLES)/ \
331340
--formats $(BENCH_FORMATS) \
332341
--limit $(BENCH_LIMIT) --verbose \
333342
--output $(BENCH_OUTPUT)/benchmark_format.json
334343

335344
benchmark-function: ## Benchmark function-level reproduction
336345
@echo "$(BLUE)━━━ Function Benchmark ━━━$(NC)"
337-
@printf '%s\n' "$(PYTHON) examples/15_unified_benchmark.py --no-llm --type function --file $(BENCH_SAMPLES)/sample_functions.py --limit 10 --verbose --output $(BENCH_OUTPUT)/benchmark_function.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
346+
@printf '%s\n' "$(PYTHON) examples/15_unified_benchmark.py $(BENCH_NO_LLM_FLAG) --type function --file $(BENCH_SAMPLES)/sample_functions.py --limit 10 --verbose --output $(BENCH_OUTPUT)/benchmark_function.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
338347
$(PYTHON) examples/15_unified_benchmark.py \
339-
--no-llm --type function \
348+
$(BENCH_NO_LLM_FLAG) --type function \
340349
--file $(BENCH_SAMPLES)/sample_functions.py \
341350
--limit 10 --verbose \
342351
--output $(BENCH_OUTPUT)/benchmark_function.json
@@ -347,19 +356,19 @@ benchmark-function: ## Benchmark function-level reproduction
347356

348357
benchmark-token: ## Benchmark token efficiency across formats
349358
@echo "$(BLUE)━━━ Token Efficiency Benchmark ━━━$(NC)"
350-
@printf '%s\n' "$(PYTHON) examples/11_token_benchmark.py --no-llm --folder $(BENCH_SAMPLES)/ --formats $(BENCH_FORMATS) --limit $(BENCH_LIMIT) --verbose --output $(BENCH_OUTPUT)/benchmark_token.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
359+
@printf '%s\n' "$(PYTHON) examples/11_token_benchmark.py $(BENCH_NO_LLM_FLAG) --folder $(BENCH_SAMPLES)/ --formats $(BENCH_FORMATS) --limit $(BENCH_LIMIT) --verbose --output $(BENCH_OUTPUT)/benchmark_token.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
351360
$(PYTHON) examples/11_token_benchmark.py \
352-
--no-llm \
361+
$(BENCH_NO_LLM_FLAG) \
353362
--folder $(BENCH_SAMPLES)/ \
354363
--formats $(BENCH_FORMATS) \
355364
--limit $(BENCH_LIMIT) --verbose \
356365
--output $(BENCH_OUTPUT)/benchmark_token.json
357366

358367
benchmark-project: ## Benchmark project-level reproduction
359368
@echo "$(BLUE)━━━ Project Benchmark ━━━$(NC)"
360-
@printf '%s\n' "$(PYTHON) examples/15_unified_benchmark.py --no-llm --type project --folder $(BENCH_SAMPLES)/ --formats $(BENCH_FORMATS) --limit $(BENCH_LIMIT) --verbose --output $(BENCH_OUTPUT)/benchmark_project.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
369+
@printf '%s\n' "$(PYTHON) examples/15_unified_benchmark.py $(BENCH_NO_LLM_FLAG) --type project --folder $(BENCH_SAMPLES)/ --formats $(BENCH_FORMATS) --limit $(BENCH_LIMIT) --verbose --output $(BENCH_OUTPUT)/benchmark_project.json" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
361370
$(PYTHON) examples/15_unified_benchmark.py \
362-
--no-llm --type project \
371+
$(BENCH_NO_LLM_FLAG) --type project \
363372
--folder $(BENCH_SAMPLES)/ \
364373
--formats $(BENCH_FORMATS) \
365374
--limit $(BENCH_LIMIT) --verbose \
@@ -368,14 +377,15 @@ benchmark-project: ## Benchmark project-level reproduction
368377
benchmark-toon: ## Generate TOON + function-logic for self-analysis
369378
@echo "$(BLUE)━━━ TOON Self-Analysis ━━━$(NC)"
370379
@mkdir -p $(BENCH_OUTPUT)
380+
@rm -f $(BENCH_OUTPUT)/function.toon $(BENCH_OUTPUT)/function-schema.json 2>/dev/null || true
371381
@printf '%s\n' "$(PYTHON) -m code2logic ./ -f toon --compact --name project -o ./" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
372382
$(PYTHON) -m code2logic ./ -f toon --compact --name project -o ./
373-
@printf '%s\n' "$(PYTHON) -m code2logic ./ -f toon --compact --no-repeat-module --function-logic function.toon --with-schema --name project -o ./" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
374-
$(PYTHON) -m code2logic ./ -f toon --compact --no-repeat-module --function-logic function.toon --with-schema --name project -o ./
383+
@printf '%s\n' "$(PYTHON) -m code2logic ./ -f toon --compact --no-repeat-module --function-logic --with-schema --name project -o ./" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
384+
$(PYTHON) -m code2logic ./ -f toon --compact --no-repeat-module --function-logic --with-schema --name project -o ./
375385
@cp -f project.toon $(BENCH_OUTPUT)/project.toon 2>/dev/null || true
376386
@cp -f project.toon-schema.json $(BENCH_OUTPUT)/project.toon-schema.json 2>/dev/null || true
377-
@cp -f function.toon $(BENCH_OUTPUT)/function.toon 2>/dev/null || true
378-
@cp -f function-schema.json $(BENCH_OUTPUT)/function-schema.json 2>/dev/null || true
387+
@cp -f project.functions.toon $(BENCH_OUTPUT)/project.functions.toon 2>/dev/null || true
388+
@cp -f project.functions-schema.json $(BENCH_OUTPUT)/project.functions-schema.json 2>/dev/null || true
379389
@printf '%s\n' "$(PYTHON) -m code2logic ./ -f yaml --compact --name project -o $(BENCH_OUTPUT)/" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
380390
$(PYTHON) -m code2logic ./ -f yaml --compact --name project -o $(BENCH_OUTPUT)/
381391
@printf '%s\n' "$(PYTHON) -m code2logic ./ -f json --name project -o $(BENCH_OUTPUT)/" >> $(BENCH_OUTPUT)/BENCHMARK_COMMANDS.sh
@@ -390,7 +400,7 @@ benchmark-toon: ## Generate TOON + function-logic for self-analysis
390400
@echo "$(BLUE)Format size comparison (self-analysis):$(NC)"
391401
@printf " %-25s %10s %10s\n" "Format" "Size" "~Tokens"
392402
@printf " %-25s %10s %10s\n" "-------------------------" "----------" "----------"
393-
@for f in $(BENCH_OUTPUT)/project.toon $(BENCH_OUTPUT)/function.toon $(BENCH_OUTPUT)/project.yaml $(BENCH_OUTPUT)/project.json $(BENCH_OUTPUT)/project.md $(BENCH_OUTPUT)/project.txt $(BENCH_OUTPUT)/project.csv; do \
403+
@for f in $(BENCH_OUTPUT)/project.toon $(BENCH_OUTPUT)/project.functions.toon $(BENCH_OUTPUT)/project.yaml $(BENCH_OUTPUT)/project.json $(BENCH_OUTPUT)/project.md $(BENCH_OUTPUT)/project.txt $(BENCH_OUTPUT)/project.csv; do \
394404
if [ -f "$$f" ]; then \
395405
sz=$$(wc -c < "$$f"); \
396406
tok=$$((sz / 4)); \
@@ -399,7 +409,7 @@ benchmark-toon: ## Generate TOON + function-logic for self-analysis
399409
done
400410
@echo ""
401411
@echo "$(GREEN)TOON files:$(NC)"
402-
@ls -lh $(BENCH_OUTPUT)/project.toon $(BENCH_OUTPUT)/function.toon $(BENCH_OUTPUT)/project.toon-schema.json $(BENCH_OUTPUT)/function-schema.json 2>/dev/null
412+
@ls -lh $(BENCH_OUTPUT)/project.toon $(BENCH_OUTPUT)/project.functions.toon $(BENCH_OUTPUT)/project.toon-schema.json $(BENCH_OUTPUT)/project.functions-schema.json 2>/dev/null
403413

404414
benchmark-compare: ## Show summary comparison of all benchmark results
405415
@echo ""

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ pip install code2logic[nlp] # Enhanced intents
4949
## 📖 Quick Start
5050
```bash
5151
code2logic ./ -f yaml --compact --function-logic --with-schema -o project.yaml
52-
code2logic ./ -f toon --function-logic function.toon --with-schema --name project -o ./
53-
# Optional: include function intent/purpose column in function.toon
54-
code2logic ./ -f toon --function-logic function.toon --does --name project -o ./
52+
code2logic ./ -f toon --function-logic --with-schema --name project -o ./
53+
# Optional: include function intent/purpose column in project.functions.toon
54+
code2logic ./ -f toon --function-logic --does --name project -o ./
5555
```
5656

5757
### Command Line

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.38
1+
1.0.39

code2logic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
>>> print(output)
1919
"""
2020

21-
__version__ = "1.0.38"
21+
__version__ = "1.0.39"
2222
__author__ = "Softreck"
2323
__email__ = "info@softreck.dev"
2424
__license__ = "MIT"

code2logic/benchmarks/common.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from datetime import datetime
55
from pathlib import Path
66

7-
from ..generators import JSONGenerator, YAMLGenerator
7+
from ..generators import CSVGenerator, JSONGenerator, YAMLGenerator
88
from ..gherkin import GherkinGenerator
99
from ..logicml import LogicMLGenerator
1010
from ..markdown_format import MarkdownHybridGenerator
@@ -32,6 +32,9 @@ def generate_spec(project: ProjectInfo, fmt: str) -> str:
3232
if fmt == "gherkin":
3333
gen = GherkinGenerator()
3434
return gen.generate(project)
35+
if fmt == "csv":
36+
gen = CSVGenerator()
37+
return gen.generate(project, detail="full")
3538
if fmt == "yaml":
3639
gen = YAMLGenerator()
3740
return gen.generate(project, detail="full")

code2logic/function_logic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def generate_toon_schema(self) -> str:
160160
"$schema": "https://json-schema.org/draft/2020-12/schema",
161161
"title": "Code2Logic Function-Logic TOON Schema",
162162
"description": (
163-
"Schema for function.toon — compact function/method index. "
163+
"Schema for function-logic TOON output (e.g. project.functions.toon) — compact function/method index. "
164164
"Conventions: name containing '.' = method (Class.method), "
165165
"~prefix = async, 'cc:N' suffix = cyclomatic complexity (only when >1)."
166166
),

docs/03-cli-reference.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ code2logic /path/to/project -f hybrid -o analysis.hybrid.yaml
120120
# Standard TOON (token-efficient)
121121
code2logic /path/to/project -f toon -o analysis.toon
122122

123-
# Function-logic TOON (outputs function.toon + optional schema)
124-
code2logic /path/to/project -f toon --compact --function-logic function.toon --name project -o ./
123+
# Function-logic TOON (outputs project.functions.toon + optional schema)
124+
code2logic /path/to/project -f toon --compact --function-logic --name project -o ./
125125

126126
# Same as above, but also compress repeated module paths and generate JSON Schema
127-
code2logic /path/to/project -f toon --compact --no-repeat-module --function-logic function.toon --with-schema --name project -o ./
127+
code2logic /path/to/project -f toon --compact --no-repeat-module --function-logic --with-schema --name project -o ./
128128

129129
# Ultra-compact TOON (71% smaller, single-letter keys)
130130
code2logic /path/to/project -f toon --ultra-compact -o analysis-ultra.toon
@@ -141,8 +141,8 @@ code2logic /path/to/project -f toon --function-logic --name project -o ./ --no-r
141141
# Generate function-logic TOON with intent descriptions (does column)
142142
code2logic /path/to/project -f toon --function-logic --does --name project -o ./
143143

144-
# Generate function-logic TOON + schema (function.toon + function-schema.json)
145-
code2logic /path/to/project -f toon --function-logic function.toon --with-schema --name project -o ./
144+
# Generate function-logic TOON + schema (project.functions.toon + project.functions-schema.json)
145+
code2logic /path/to/project -f toon --function-logic --with-schema --name project -o ./
146146
```
147147

148148
Token-oriented object notation - most efficient format for LLM consumption.
@@ -163,7 +163,7 @@ Generated artifacts (written to `examples/output/`):
163163
- Exact commands used to generate each artifact
164164
- `benchmark_format.json`, `benchmark_project.json`, `benchmark_token.json`, `benchmark_function.json`
165165
- Raw benchmark results
166-
- `project.toon`, `function.toon` (+ `*-schema.json`)
166+
- `project.toon`, `project.functions.toon` (+ `*-schema.json`)
167167
- Self-analysis outputs used for size/token comparisons
168168

169169
Run all example scripts step-by-step:

docs/07-toon.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,20 @@ code2logic /path/to/project -f toon --no-repeat-module -o analysis.toon
129129
code2logic /path/to/project -f toon --function-logic --name project -o ./ --no-repeat-details
130130

131131
# Generate function-logic TOON
132-
# Output file: function.toon
133-
code2logic /path/to/project -f toon --function-logic function.toon --name project -o ./
132+
# Output file: project.functions.toon
133+
code2logic /path/to/project -f toon --function-logic --name project -o ./
134134

135135
# Generate function-logic TOON + schema
136136
# Output files:
137-
# - function.toon
138-
# - function-schema.json
139-
code2logic /path/to/project -f toon --function-logic function.toon --with-schema --name project -o ./
137+
# - project.functions.toon
138+
# - project.functions-schema.json
139+
code2logic /path/to/project -f toon --function-logic --with-schema --name project -o ./
140140

141141
# Generate function-logic TOON + schema + compress repeated module paths
142142
# Output files:
143-
# - function.toon
144-
# - function-schema.json
145-
code2logic /path/to/project -f toon --compact --no-repeat-module --function-logic function.toon --with-schema --name project -o ./
143+
# - project.functions.toon
144+
# - project.functions-schema.json
145+
code2logic /path/to/project -f toon --compact --no-repeat-module --function-logic --with-schema --name project -o ./
146146
```
147147

148148
### Reducing Path Repetition (Filesystem Tree Hint)
@@ -250,8 +250,8 @@ Use `--does` when you need the LLM to understand **what each function does**, no
250250
When `--with-schema` is used with `--function-logic` and TOON format, a JSON schema is written alongside:
251251

252252
```bash
253-
code2logic /path/to/project -f toon --function-logic function.toon --with-schema --name project -o ./
254-
# Produces: function.toon + function-schema.json
253+
code2logic /path/to/project -f toon --function-logic --with-schema --name project -o ./
254+
# Produces: project.functions.toon + project.functions-schema.json
255255
```
256256

257257
If using `--stdout`, the function-logic schema is printed under the `=== FUNCTION_LOGIC_SCHEMA ===` section marker.

0 commit comments

Comments
 (0)