arclith-cli 0.11.0__tar.gz → 0.12.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 (29) hide show
  1. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/PKG-INFO +2 -2
  2. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/README.md +10 -8
  3. arclith_cli-0.12.0/arclith_cli/__init__.py +1 -0
  4. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/capabilities.py +2 -2
  5. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/core_scaffold.py +24 -24
  6. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/init_project.py +2 -2
  7. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/main.py +10 -10
  8. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/project_paths.py +2 -2
  9. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/pyproject.toml +2 -2
  10. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/e2e_manual.sh +1 -1
  11. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/test_core_scaffold.py +22 -15
  12. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/test_e2e_scaffold.py +8 -6
  13. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/uv.lock +2 -2
  14. arclith_cli-0.11.0/arclith_cli/__init__.py +0 -1
  15. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/.gitignore +0 -0
  16. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/LICENSE +0 -0
  17. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/Makefile +0 -0
  18. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/adapter_templates.py +0 -0
  19. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/add_adapter.py +0 -0
  20. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/entity_scanner.py +0 -0
  21. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/export_config.py +0 -0
  22. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/rename.py +0 -0
  23. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/scaffold.py +0 -0
  24. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/arclith_cli/updater.py +0 -0
  25. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/__init__.py +0 -0
  26. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/test_add_adapter.py +0 -0
  27. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/test_capabilities.py +0 -0
  28. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/test_project_paths.py +0 -0
  29. {arclith_cli-0.11.0 → arclith_cli-0.12.0}/tests/test_rename.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arclith-cli
3
- Version: 0.11.0
3
+ Version: 0.12.0
4
4
  Summary: CLI scaffolding tool for arclith — hexagonal architecture framework
5
5
  Author-email: Killian KOPP <killiankopp@gmail.com>
6
6
  License: Apache License
@@ -186,7 +186,7 @@ License: Apache License
186
186
  License-File: LICENSE
187
187
  Keywords: arclith,cli,ddd,hexagonal-architecture,scaffold
188
188
  Requires-Python: >=3.13
189
- Requires-Dist: arclith>=0.14.0
189
+ Requires-Dist: arclith>=0.15.0
190
190
  Requires-Dist: httpx>=0.27.0
191
191
  Requires-Dist: rich>=13.0.0
192
192
  Requires-Dist: typer>=0.15.0
@@ -96,25 +96,27 @@ Comme `add-entity`, cette commande ne câble pas FastAPI, FastMCP, LangGraph, un
96
96
 
97
97
  ---
98
98
 
99
- ### `add-planner` — Ajouter un planner applicatif
99
+ ### `add-intent-interpreter` — Ajouter un interpréteur d'intention
100
100
 
101
- Crée uniquement le fichier minimal d'un planner dans `src/<package>/application/planners/`.
101
+ Crée uniquement le fichier minimal d'un interpréteur d'intention dans
102
+ `src/<package>/application/intent_interpreters/`.
102
103
 
103
104
  ```bash
104
105
  cd my-recipe-service
105
- arclith-cli add-planner IngredientIntent
106
- arclith-cli add-planner command-router
106
+ arclith-cli add-intent-interpreter IngredientIntent
107
+ arclith-cli add-intent-interpreter command-router
107
108
  ```
108
109
 
109
110
  Fichier généré :
110
111
 
111
112
  ```text
112
- src/<package>/application/planners/ingredient_intent.py
113
+ src/<package>/application/intent_interpreters/ingredient_intent.py
113
114
  ```
114
115
 
115
- Le planner est le composant applicatif qui transforme une demande naturelle en commande ou DTO
116
- structuré. Il ne remplace pas LangGraph : LangGraph orchestre les nœuds, tandis que le planner porte
117
- la traduction d'intention. Le fichier généré reste volontairement vide de logique métier.
116
+ L'interpréteur d'intention est le composant applicatif qui transforme une demande naturelle en
117
+ commande ou DTO structuré. Il ne remplace pas LangGraph : LangGraph orchestre les nœuds, tandis que
118
+ l'interpréteur porte la traduction d'intention. Le fichier généré reste volontairement vide de
119
+ logique métier.
118
120
 
119
121
  ---
120
122
 
@@ -0,0 +1 @@
1
+ __version__ = "0.12.0"
@@ -314,7 +314,7 @@ port: {port}
314
314
  LLM_CAPABILITY = CapabilitySpec(
315
315
  name="llm",
316
316
  layer="outbound",
317
- description="Configuration LLM pour planners et agents via une factory Arclith.",
317
+ description="Configuration LLM pour interpréteurs d'intention et agents via une factory Arclith.",
318
318
  activation_config_key=None,
319
319
  adapters=(
320
320
  AdapterSpec(
@@ -401,7 +401,7 @@ OPENAI_API_KEY={api_key}
401
401
  name="anthropic",
402
402
  capability="llm",
403
403
  layer="outbound",
404
- description="Modèle Anthropic pour planners et agents.",
404
+ description="Modèle Anthropic pour interpréteurs d'intention et agents.",
405
405
  config_path="config/adapters/outbound/lm.yaml",
406
406
  config_template="""\
407
407
  provider: anthropic
@@ -38,9 +38,9 @@ class {class_name}UseCase({class_name}Port):
38
38
  raise NotImplementedError("Implement {class_name}UseCase.execute")
39
39
  """
40
40
 
41
- _PLANNER_TEMPLATE = """class {class_name}Planner:
42
- async def plan(self, prompt: str) -> None:
43
- raise NotImplementedError("Implement {class_name}Planner.plan")
41
+ _INTENT_INTERPRETER_TEMPLATE = """class {class_name}Interpreter:
42
+ async def interpret(self, prompt: str) -> None:
43
+ raise NotImplementedError("Implement {class_name}Interpreter.interpret")
44
44
  """
45
45
 
46
46
 
@@ -61,17 +61,17 @@ class UseCaseNames:
61
61
 
62
62
 
63
63
  @dataclass(frozen=True)
64
- class PlannerNames:
64
+ class IntentInterpreterNames:
65
65
  pascal: str
66
66
  snake: str
67
67
 
68
68
  @classmethod
69
- def from_input(cls, raw: str) -> PlannerNames:
69
+ def from_input(cls, raw: str) -> IntentInterpreterNames:
70
70
  names = EntityNames.from_input(raw)
71
- pascal = _strip_pascal_planner_suffix(names.pascal)
72
- snake = _strip_snake_planner_suffix(names.snake)
71
+ pascal = _strip_pascal_intent_interpreter_suffix(names.pascal)
72
+ snake = _strip_snake_intent_interpreter_suffix(names.snake)
73
73
  if not pascal or not snake:
74
- console.print(f"[red]✗[/red] Nom de planner invalide : [bold]{raw}[/bold].")
74
+ console.print(f"[red]✗[/red] Nom d'interpréteur d'intention invalide : [bold]{raw}[/bold].")
75
75
  raise typer.Exit(1)
76
76
  return cls(pascal=pascal, snake=snake)
77
77
 
@@ -130,24 +130,24 @@ def add_usecase_cmd(*, project_dir: Path | None = None, usecase_name: str) -> Pa
130
130
  return usecase_file
131
131
 
132
132
 
133
- def add_planner_cmd(*, project_dir: Path | None = None, planner_name: str) -> Path:
133
+ def add_intent_interpreter_cmd(*, project_dir: Path | None = None, intent_name: str) -> Path:
134
134
  project_dir = project_dir or Path.cwd()
135
- planner_name = planner_name.strip()
136
- _assert_project_root(project_dir, command="add-planner")
137
- _assert_valid_name(planner_name, label="planner")
135
+ intent_name = intent_name.strip()
136
+ _assert_project_root(project_dir, command="add-intent-interpreter")
137
+ _assert_valid_name(intent_name, label="interpréteur d'intention")
138
138
 
139
139
  paths = detect_project_paths(project_dir)
140
- names = PlannerNames.from_input(planner_name)
141
- planner_file = paths.application_planners / f"{names.snake}.py"
142
- _assert_missing(planner_file, project_dir)
140
+ names = IntentInterpreterNames.from_input(intent_name)
141
+ intent_file = paths.application_intent_interpreters / f"{names.snake}.py"
142
+ _assert_missing(intent_file, project_dir)
143
143
 
144
- _ensure_package_dirs(paths, "application", "planners")
145
- planner_file.write_text(_PLANNER_TEMPLATE.format(class_name=names.pascal), encoding="utf-8")
144
+ _ensure_package_dirs(paths, "application", "intent_interpreters")
145
+ intent_file.write_text(_INTENT_INTERPRETER_TEMPLATE.format(class_name=names.pascal), encoding="utf-8")
146
146
  console.print(
147
- f"[green]✓[/green] Planner {names.pascal}Planner créé : "
148
- f"[bold]{planner_file.relative_to(project_dir)}[/bold]"
147
+ f"[green]✓[/green] Interpréteur d'intention {names.pascal}Interpreter créé : "
148
+ f"[bold]{intent_file.relative_to(project_dir)}[/bold]"
149
149
  )
150
- return planner_file
150
+ return intent_file
151
151
 
152
152
 
153
153
  def _assert_project_root(project_dir: Path, *, command: str) -> None:
@@ -232,8 +232,8 @@ def _strip_snake_suffix(value: str) -> str:
232
232
  value = stripped
233
233
 
234
234
 
235
- def _strip_pascal_planner_suffix(value: str) -> str:
236
- suffixes = ("Planner",)
235
+ def _strip_pascal_intent_interpreter_suffix(value: str) -> str:
236
+ suffixes = ("Interpreter",)
237
237
  while True:
238
238
  stripped = value
239
239
  for suffix in suffixes:
@@ -245,8 +245,8 @@ def _strip_pascal_planner_suffix(value: str) -> str:
245
245
  value = stripped
246
246
 
247
247
 
248
- def _strip_snake_planner_suffix(value: str) -> str:
249
- suffixes = ("_planner",)
248
+ def _strip_snake_intent_interpreter_suffix(value: str) -> str:
249
+ suffixes = ("_interpreter",)
250
250
  while True:
251
251
  stripped = value
252
252
  for suffix in suffixes:
@@ -72,7 +72,7 @@ def _framework_version() -> str:
72
72
  try:
73
73
  return version("arclith")
74
74
  except PackageNotFoundError:
75
- return "0.14.0"
75
+ return "0.15.0"
76
76
 
77
77
 
78
78
  def _create_package_layout(package_root: Path) -> None:
@@ -85,7 +85,7 @@ def _create_package_layout(package_root: Path) -> None:
85
85
  package_root / "domain" / "ports" / "outbound",
86
86
  package_root / "application",
87
87
  package_root / "application" / "use_cases",
88
- package_root / "application" / "planners",
88
+ package_root / "application" / "intent_interpreters",
89
89
  package_root / "adapters",
90
90
  package_root / "adapters" / "inbound",
91
91
  package_root / "adapters" / "outbound",
@@ -15,7 +15,7 @@ from rich.tree import Tree
15
15
  from . import __version__
16
16
  from .add_adapter import add_adapter_cmd
17
17
  from .capabilities import CAPABILITY_CATALOG, capability_catalog_as_dict
18
- from .core_scaffold import add_entity_cmd, add_planner_cmd, add_usecase_cmd
18
+ from .core_scaffold import add_entity_cmd, add_intent_interpreter_cmd, add_usecase_cmd
19
19
  from .export_config import export_config_cmd
20
20
  from .init_project import init_project_cmd
21
21
  from .rename import EntityNames, apply_rename
@@ -221,17 +221,17 @@ def add_usecase(
221
221
  add_usecase_cmd(usecase_name=usecase or _prompt_usecase())
222
222
 
223
223
 
224
- @app.command(name="add-planner")
225
- def add_planner(
226
- planner: Annotated[
224
+ @app.command(name="add-intent-interpreter")
225
+ def add_intent_interpreter(
226
+ intent: Annotated[
227
227
  str | None,
228
228
  typer.Argument(
229
- help="Nom du planner applicatif. Exemple : IngredientIntent, todo_planner, command-router",
229
+ help="Nom de l'interpréteur d'intention. Exemple : IngredientIntent, todo-intent, command-router",
230
230
  ),
231
231
  ] = None,
232
232
  ) -> None:
233
- """Créer uniquement le fichier minimal d'un planner dans application/planners."""
234
- add_planner_cmd(planner_name=planner or _prompt_planner())
233
+ """Créer uniquement le fichier minimal d'un interpréteur d'intention."""
234
+ add_intent_interpreter_cmd(intent_name=intent or _prompt_intent_interpreter())
235
235
 
236
236
 
237
237
  @app.command(name="capabilities")
@@ -327,10 +327,10 @@ def _prompt_usecase() -> str:
327
327
  return value
328
328
 
329
329
 
330
- def _prompt_planner() -> str:
331
- console.print("\n[bold]Planner[/bold] [dim](ex : IngredientIntent, todo_planner)[/dim]")
330
+ def _prompt_intent_interpreter() -> str:
331
+ console.print("\n[bold]Interpréteur d'intention[/bold] [dim](ex : IngredientIntent, todo_intent)[/dim]")
332
332
  while True:
333
- value = Prompt.ask(" [bold green]Nom du planner[/bold green]").strip()
333
+ value = Prompt.ask(" [bold green]Nom de l'interpréteur[/bold green]").strip()
334
334
  if not value:
335
335
  console.print(" [red]Le nom ne peut pas être vide.[/red]")
336
336
  elif not _ENTITY_RE.match(value):
@@ -21,8 +21,8 @@ class ProjectPaths:
21
21
  return self.package_root / "domain" / "ports" / "inbound"
22
22
 
23
23
  @property
24
- def application_planners(self) -> Path:
25
- return self.package_root / "application" / "planners"
24
+ def application_intent_interpreters(self) -> Path:
25
+ return self.package_root / "application" / "intent_interpreters"
26
26
 
27
27
  @property
28
28
  def adapters_outbound(self) -> Path:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "arclith-cli"
7
- version = "0.11.0"
7
+ version = "0.12.0"
8
8
  description = "CLI scaffolding tool for arclith — hexagonal architecture framework"
9
9
  license = { file = "LICENSE" }
10
10
  requires-python = ">=3.13"
@@ -16,7 +16,7 @@ dependencies = [
16
16
  "typer>=0.15.0",
17
17
  "rich>=13.0.0",
18
18
  "httpx>=0.27.0",
19
- "arclith>=0.14.0",
19
+ "arclith>=0.15.0",
20
20
  ]
21
21
 
22
22
  [tool.uv.sources]
@@ -39,7 +39,7 @@ if grep -q '\[tool\.uv\.sources\]' pyproject.toml; then
39
39
  fi
40
40
 
41
41
  ARCLITH_VERSION=$(grep 'arclith\[' pyproject.toml | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
42
- MIN_ARCLITH_VERSION="0.13.0"
42
+ MIN_ARCLITH_VERSION="0.15.0"
43
43
  if version_lt "$ARCLITH_VERSION" "$MIN_ARCLITH_VERSION"; then
44
44
  echo -e "${RED}✗ FAIL: arclith version < $MIN_ARCLITH_VERSION (found: $ARCLITH_VERSION)${NC}"
45
45
  exit 1
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  import pytest
4
4
  import typer
5
5
 
6
- from arclith_cli.core_scaffold import add_entity_cmd, add_planner_cmd, add_usecase_cmd
6
+ from arclith_cli.core_scaffold import add_entity_cmd, add_intent_interpreter_cmd, add_usecase_cmd
7
7
  from arclith_cli.init_project import init_project_cmd
8
8
 
9
9
 
@@ -47,7 +47,7 @@ def test_init_project_creates_minimal_src_layout_without_entity(tmp_path: Path)
47
47
  "observability:\n"
48
48
  " enabled: []\n"
49
49
  )
50
- assert "arclith[fastapi,mcp]>=0.14.0" in (generated / "pyproject.toml").read_text(encoding="utf-8")
50
+ assert "arclith[fastapi,mcp]>=0.15.0" in (generated / "pyproject.toml").read_text(encoding="utf-8")
51
51
  assert (package_root / "domain" / "models" / "__init__.py").exists()
52
52
  assert (package_root / "domain" / "ports" / "inbound" / "__init__.py").exists()
53
53
  assert (package_root / "domain" / "ports" / "outbound" / "__init__.py").exists()
@@ -97,19 +97,23 @@ def test_add_usecase_creates_minimal_usecase_in_src_package(tmp_path: Path) -> N
97
97
  assert not (project_dir / "src" / "demo_service" / "adapters").exists()
98
98
 
99
99
 
100
- def test_add_planner_creates_minimal_planner_in_src_package(tmp_path: Path) -> None:
100
+ def test_add_intent_interpreter_creates_minimal_interpreter_in_src_package(tmp_path: Path) -> None:
101
101
  project_dir = _src_project(tmp_path)
102
102
 
103
- generated = add_planner_cmd(project_dir=project_dir, planner_name="IngredientIntent")
103
+ generated = add_intent_interpreter_cmd(project_dir=project_dir, intent_name="IngredientIntent")
104
104
 
105
- assert generated == project_dir / "src" / "demo_service" / "application" / "planners" / "ingredient_intent.py"
105
+ assert generated == (
106
+ project_dir / "src" / "demo_service" / "application" / "intent_interpreters" / "ingredient_intent.py"
107
+ )
106
108
  assert generated.read_text(encoding="utf-8") == (
107
- "class IngredientIntentPlanner:\n"
108
- " async def plan(self, prompt: str) -> None:\n"
109
- ' raise NotImplementedError("Implement IngredientIntentPlanner.plan")\n'
109
+ "class IngredientIntentInterpreter:\n"
110
+ " async def interpret(self, prompt: str) -> None:\n"
111
+ ' raise NotImplementedError("Implement IngredientIntentInterpreter.interpret")\n'
110
112
  )
111
113
  assert (project_dir / "src" / "demo_service" / "application" / "__init__.py").exists()
112
- assert (project_dir / "src" / "demo_service" / "application" / "planners" / "__init__.py").exists()
114
+ assert (
115
+ project_dir / "src" / "demo_service" / "application" / "intent_interpreters" / "__init__.py"
116
+ ).exists()
113
117
  assert not (project_dir / "src" / "demo_service" / "adapters").exists()
114
118
 
115
119
 
@@ -129,14 +133,17 @@ def test_add_usecase_strips_repeated_usecase_suffix(tmp_path: Path) -> None:
129
133
  assert "UseCaseUseCase" not in generated.read_text(encoding="utf-8")
130
134
 
131
135
 
132
- def test_add_planner_strips_repeated_planner_suffix(tmp_path: Path) -> None:
136
+ def test_add_intent_interpreter_strips_repeated_interpreter_suffix(tmp_path: Path) -> None:
133
137
  project_dir = _src_project(tmp_path)
134
138
 
135
- generated = add_planner_cmd(project_dir=project_dir, planner_name="ingredient-intent-planner-planner")
139
+ generated = add_intent_interpreter_cmd(
140
+ project_dir=project_dir,
141
+ intent_name="ingredient-intent-interpreter-interpreter",
142
+ )
136
143
 
137
144
  assert generated.name == "ingredient_intent.py"
138
- assert "class IngredientIntentPlanner:" in generated.read_text(encoding="utf-8")
139
- assert "PlannerPlanner" not in generated.read_text(encoding="utf-8")
145
+ assert "class IngredientIntentInterpreter:" in generated.read_text(encoding="utf-8")
146
+ assert "InterpreterInterpreter" not in generated.read_text(encoding="utf-8")
140
147
 
141
148
 
142
149
  def test_add_entity_supports_legacy_root_layout(tmp_path: Path) -> None:
@@ -201,8 +208,8 @@ def test_add_usecase_refuses_to_overwrite_existing_inbound_port(tmp_path: Path)
201
208
  assert not (project_dir / "src" / "demo_service" / "application" / "use_cases" / "recipe.py").exists()
202
209
 
203
210
 
204
- def test_add_planner_rejects_invalid_name(tmp_path: Path) -> None:
211
+ def test_add_intent_interpreter_rejects_invalid_name(tmp_path: Path) -> None:
205
212
  project_dir = _src_project(tmp_path)
206
213
 
207
214
  with pytest.raises(typer.Exit):
208
- add_planner_cmd(project_dir=project_dir, planner_name="123-planner")
215
+ add_intent_interpreter_cmd(project_dir=project_dir, intent_name="123-intent")
@@ -225,7 +225,7 @@ def test_scaffold_and_run(temp_workspace: Path):
225
225
  result = subprocess.run(
226
226
  [
227
227
  "arclith-cli",
228
- "add-planner",
228
+ "add-intent-interpreter",
229
229
  "ShoppingIntent",
230
230
  ],
231
231
  cwd=project_dir,
@@ -233,9 +233,11 @@ def test_scaffold_and_run(temp_workspace: Path):
233
233
  text=True,
234
234
  timeout=30,
235
235
  )
236
- assert result.returncode == 0, f"add-planner failed:\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
236
+ assert result.returncode == 0, (
237
+ f"add-intent-interpreter failed:\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
238
+ )
237
239
  assert (
238
- project_dir / "src" / "test_plan_service" / "application" / "planners" / "shopping_intent.py"
240
+ project_dir / "src" / "test_plan_service" / "application" / "intent_interpreters" / "shopping_intent.py"
239
241
  ).exists()
240
242
 
241
243
  printed_names = ", ".join(
@@ -243,7 +245,7 @@ def test_scaffold_and_run(temp_workspace: Path):
243
245
  "ShoppingItem.__name__",
244
246
  "PlanShoppingListPort.__name__",
245
247
  "PlanShoppingListUseCase.__name__",
246
- "ShoppingIntentPlanner.__name__",
248
+ "ShoppingIntentInterpreter.__name__",
247
249
  ]
248
250
  )
249
251
  import_script = "\n".join(
@@ -251,7 +253,7 @@ def test_scaffold_and_run(temp_workspace: Path):
251
253
  "from test_plan_service.domain.models.shopping_item import ShoppingItem",
252
254
  "from test_plan_service.domain.ports.inbound.plan_shopping_list import PlanShoppingListPort",
253
255
  "from test_plan_service.application.use_cases.plan_shopping_list import PlanShoppingListUseCase",
254
- "from test_plan_service.application.planners.shopping_intent import ShoppingIntentPlanner",
256
+ "from test_plan_service.application.intent_interpreters.shopping_intent import ShoppingIntentInterpreter",
255
257
  f"print({printed_names})",
256
258
  ]
257
259
  )
@@ -269,7 +271,7 @@ def test_scaffold_and_run(temp_workspace: Path):
269
271
  timeout=30,
270
272
  )
271
273
  assert result.returncode == 0, f"Core scaffold import failed:\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
272
- assert "ShoppingItem PlanShoppingListPort PlanShoppingListUseCase ShoppingIntentPlanner" in result.stdout
274
+ assert "ShoppingItem PlanShoppingListPort PlanShoppingListUseCase ShoppingIntentInterpreter" in result.stdout
273
275
 
274
276
  # Step 7 — validate non-interactive adapter generation through the CLI entry point
275
277
  result = subprocess.run(
@@ -46,7 +46,7 @@ wheels = [
46
46
 
47
47
  [[package]]
48
48
  name = "arclith"
49
- version = "0.14.0"
49
+ version = "0.15.0"
50
50
  source = { editable = "../" }
51
51
  dependencies = [
52
52
  { name = "fastapi" },
@@ -132,7 +132,7 @@ docs = [
132
132
 
133
133
  [[package]]
134
134
  name = "arclith-cli"
135
- version = "0.11.0"
135
+ version = "0.12.0"
136
136
  source = { editable = "." }
137
137
  dependencies = [
138
138
  { name = "arclith" },
@@ -1 +0,0 @@
1
- __version__ = "0.11.0"
File without changes
File without changes
File without changes