csrd-utils 0.3.17__tar.gz → 0.3.18__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 (87) hide show
  1. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/PKG-INFO +9 -9
  2. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/README.md +8 -8
  3. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/pyproject.toml +1 -1
  4. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/__main__.py +45 -10
  5. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/.gitignore +0 -0
  6. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/__init__.py +0 -0
  7. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/audit.py +0 -0
  8. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/augmentor.py +0 -0
  9. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/cluster.py +0 -0
  10. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/doctor.py +0 -0
  11. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/conftest.fragment.py +0 -0
  12. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/docker-compose.fragment.yaml +0 -0
  13. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/manifest.yaml +0 -0
  14. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/requirements.fragment +0 -0
  15. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/settings.fragment.py +0 -0
  16. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/src/app/cache.py +0 -0
  17. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/caching/tests/test_cache.py +0 -0
  18. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/logging/conftest.fragment.py +0 -0
  19. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/logging/manifest.yaml +0 -0
  20. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/logging/requirements.fragment +0 -0
  21. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/logging/settings.fragment.py +0 -0
  22. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/logging/src/app/middleware/logging.py +0 -0
  23. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/logging/tests/test_logging_middleware.py +0 -0
  24. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/conftest.fragment.py +0 -0
  25. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/docker-compose.fragment.yaml +0 -0
  26. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/manifest.yaml +0 -0
  27. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/requirements.fragment +0 -0
  28. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/settings.fragment.py +0 -0
  29. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/src/app/middleware/metrics.py +0 -0
  30. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/metrics/tests/test_metrics_middleware.py +0 -0
  31. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/tracing/conftest.fragment.py +0 -0
  32. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/tracing/manifest.yaml +0 -0
  33. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/tracing/requirements.fragment +0 -0
  34. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/tracing/settings.fragment.py +0 -0
  35. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/tracing/src/app/middleware/tracing.py +0 -0
  36. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/tracing/tests/test_tracing_middleware.py +0 -0
  37. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/conftest.fragment.py +0 -0
  38. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/docker-compose.fragment.yaml +0 -0
  39. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/manifest.yaml +0 -0
  40. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/requirements.fragment +0 -0
  41. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/settings.fragment.py +0 -0
  42. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/src/app/workers/__init__.py +0 -0
  43. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/src/app/workers/celery_app.py +0 -0
  44. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/src/app/workers/tasks.py +0 -0
  45. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/features/workers/tests/test_workers.py +0 -0
  46. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/fragments.py +0 -0
  47. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/generator.py +0 -0
  48. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/resources.py +0 -0
  49. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/README.md +0 -0
  50. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/cookiecutter.json +0 -0
  51. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/hooks/post_gen_project.py +0 -0
  52. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/.dockerignore +0 -0
  53. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/.env.example +0 -0
  54. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/.gitignore +0 -0
  55. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/Dockerfile +0 -0
  56. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/README.md +0 -0
  57. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/docker-compose.yml +0 -0
  58. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/pyproject.toml +0 -0
  59. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/requirements.txt +0 -0
  60. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/__init__.py +0 -0
  61. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/cache.py +0 -0
  62. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/delegates/__init__.py +0 -0
  63. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/delegates/upstreams.py +0 -0
  64. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/__init__.py +0 -0
  65. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/delegates.py +0 -0
  66. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/item_repository.py +0 -0
  67. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/dependencies/worker_broker.py +0 -0
  68. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/middleware/__init__.py +0 -0
  69. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/middleware/logging.py +0 -0
  70. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/py.typed +0 -0
  71. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/repositories/__init__.py +0 -0
  72. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/repositories/item_repository.py +0 -0
  73. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/settings.py +0 -0
  74. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/__init__.py +0 -0
  75. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/unversioned/__init__.py +0 -0
  76. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/unversioned/health_view.py +0 -0
  77. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/views/unversioned/items_view.py +0 -0
  78. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/workers/__init__.py +0 -0
  79. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/src/app/workers/tasks.py +0 -0
  80. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/__init__.py +0 -0
  81. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/acceptance/test_logging_middleware.py +0 -0
  82. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/conftest.py +0 -0
  83. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/test_items.py +0 -0
  84. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_cache.py +0 -0
  85. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_database_settings.py +0 -0
  86. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_delegates.py +0 -0
  87. {csrd_utils-0.3.17 → csrd_utils-0.3.18}/src/csrd_utils/templates/cookiecutter-service/{{cookiecutter.service_name}}/tests/unit/test_worker_broker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csrd-utils
3
- Version: 0.3.17
3
+ Version: 0.3.18
4
4
  Summary: CLI utilities for csrd service generation and feature augmentation
5
5
  Project-URL: Repository, https://github.com/csrd-api/fastapi-common
6
6
  Project-URL: Documentation, https://github.com/csrd-api/fastapi-common/tree/main/packages/utils
@@ -70,19 +70,19 @@ csrd new workspace --name local-dev --output . --generate none
70
70
  csrd new service --name inventory --output ./local-dev --database postgres --workers
71
71
 
72
72
  # 1) Verify service compatibility
73
- csrd doctor --service ./local-dev/inventory
73
+ csrd doctor --service ./local-dev/src/inventory
74
74
 
75
75
  # 1b) Audit for weak/insecure defaults
76
- csrd audit --service ./local-dev/inventory
76
+ csrd audit --service ./local-dev/src/inventory
77
77
 
78
78
  # 2) Inspect available bundled features
79
79
  csrd feature list
80
80
 
81
81
  # 3) Dry-run a feature
82
- csrd feature plan workers --service ./local-dev/inventory
82
+ csrd feature plan workers --service ./local-dev/src/inventory
83
83
 
84
84
  # 4) Apply feature files/merges
85
- csrd feature add workers --service ./local-dev/inventory
85
+ csrd feature add workers --service ./local-dev/src/inventory
86
86
 
87
87
  # 5) Add a second service — workspace auto-upgrades to cluster
88
88
  csrd new service --name pricing --output ./local-dev --database postgres
@@ -135,8 +135,8 @@ Then run a clean smoke flow:
135
135
  mkdir -p /tmp/csrd-smoke
136
136
  csrd new workspace --name ws --output /tmp/csrd-smoke --generate none
137
137
  csrd new service --name demo-svc --output /tmp/csrd-smoke/ws --no-interactive
138
- csrd doctor --service /tmp/csrd-smoke/ws/demo-svc
139
- csrd audit --service /tmp/csrd-smoke/ws/demo-svc
140
- csrd feature plan workers --service /tmp/csrd-smoke/ws/demo-svc
141
- csrd feature add workers --service /tmp/csrd-smoke/ws/demo-svc
138
+ csrd doctor --service /tmp/csrd-smoke/ws/src/demo-svc
139
+ csrd audit --service /tmp/csrd-smoke/ws/src/demo-svc
140
+ csrd feature plan workers --service /tmp/csrd-smoke/ws/src/demo-svc
141
+ csrd feature add workers --service /tmp/csrd-smoke/ws/src/demo-svc
142
142
  ```
@@ -57,19 +57,19 @@ csrd new workspace --name local-dev --output . --generate none
57
57
  csrd new service --name inventory --output ./local-dev --database postgres --workers
58
58
 
59
59
  # 1) Verify service compatibility
60
- csrd doctor --service ./local-dev/inventory
60
+ csrd doctor --service ./local-dev/src/inventory
61
61
 
62
62
  # 1b) Audit for weak/insecure defaults
63
- csrd audit --service ./local-dev/inventory
63
+ csrd audit --service ./local-dev/src/inventory
64
64
 
65
65
  # 2) Inspect available bundled features
66
66
  csrd feature list
67
67
 
68
68
  # 3) Dry-run a feature
69
- csrd feature plan workers --service ./local-dev/inventory
69
+ csrd feature plan workers --service ./local-dev/src/inventory
70
70
 
71
71
  # 4) Apply feature files/merges
72
- csrd feature add workers --service ./local-dev/inventory
72
+ csrd feature add workers --service ./local-dev/src/inventory
73
73
 
74
74
  # 5) Add a second service — workspace auto-upgrades to cluster
75
75
  csrd new service --name pricing --output ./local-dev --database postgres
@@ -122,8 +122,8 @@ Then run a clean smoke flow:
122
122
  mkdir -p /tmp/csrd-smoke
123
123
  csrd new workspace --name ws --output /tmp/csrd-smoke --generate none
124
124
  csrd new service --name demo-svc --output /tmp/csrd-smoke/ws --no-interactive
125
- csrd doctor --service /tmp/csrd-smoke/ws/demo-svc
126
- csrd audit --service /tmp/csrd-smoke/ws/demo-svc
127
- csrd feature plan workers --service /tmp/csrd-smoke/ws/demo-svc
128
- csrd feature add workers --service /tmp/csrd-smoke/ws/demo-svc
125
+ csrd doctor --service /tmp/csrd-smoke/ws/src/demo-svc
126
+ csrd audit --service /tmp/csrd-smoke/ws/src/demo-svc
127
+ csrd feature plan workers --service /tmp/csrd-smoke/ws/src/demo-svc
128
+ csrd feature add workers --service /tmp/csrd-smoke/ws/src/demo-svc
129
129
  ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "csrd-utils"
3
- version = "0.3.17"
3
+ version = "0.3.18"
4
4
  description = "CLI utilities for csrd service generation and feature augmentation"
5
5
  license = { text = "MIT" }
6
6
  requires-python = ">=3.12"
@@ -61,6 +61,10 @@ WORKSPACE_MARKER = ".csrd-workspace"
61
61
  WORKSPACE_CLUSTER_SPEC = Path(".csrd") / "cluster.yaml"
62
62
 
63
63
 
64
+ def _workspace_services_dir(workspace_root: Path) -> Path:
65
+ return workspace_root / "src"
66
+
67
+
64
68
  def _prompt_text(label: str, default: str) -> str:
65
69
  value = input(f"{label} [{default}]: ").strip()
66
70
  return value or default
@@ -486,7 +490,11 @@ def _append_service_to_workspace_cluster(
486
490
 
487
491
  def _workspace_service_roots(workspace_root: Path) -> list[Path]:
488
492
  roots: list[Path] = []
489
- for child in workspace_root.iterdir():
493
+ services_root = _workspace_services_dir(workspace_root)
494
+ if not services_root.is_dir():
495
+ return roots
496
+
497
+ for child in services_root.iterdir():
490
498
  if not child.is_dir() or child.name.startswith("."):
491
499
  continue
492
500
  if (
@@ -499,6 +507,24 @@ def _workspace_service_roots(workspace_root: Path) -> list[Path]:
499
507
  return sorted(roots)
500
508
 
501
509
 
510
+ def _resolve_feature_service_root(service_arg: Path) -> Path:
511
+ candidate = service_arg.resolve()
512
+ if not _is_workspace(candidate):
513
+ return candidate
514
+
515
+ service_roots = _workspace_service_roots(candidate)
516
+ if len(service_roots) == 1:
517
+ print(f"Detected workspace service target: {service_roots[0]}")
518
+ return service_roots[0]
519
+ if not service_roots:
520
+ raise ValueError(
521
+ "No services found under workspace src/. Pass --service with a service root path."
522
+ )
523
+ raise ValueError(
524
+ "Multiple services found under workspace src/. Pass --service with a specific service root path."
525
+ )
526
+
527
+
502
528
  def _infer_port_from_service_root(service_root: Path) -> int:
503
529
  try:
504
530
  payload = yaml.safe_load((service_root / "docker-compose.yml").read_text(encoding="utf-8"))
@@ -566,9 +592,6 @@ def _maybe_update_workspace_cluster(
566
592
  return generate_cluster(updated_spec, workspace_root, force=True, workspace_mode=True)
567
593
 
568
594
  service_roots = _workspace_service_roots(workspace_root)
569
- if len(service_roots) < 2:
570
- return None
571
-
572
595
  generated_name = generated_service.name
573
596
  services: list[ServiceSpec] = [_service_config_to_cluster_service(service_config)]
574
597
  for service_root in service_roots:
@@ -816,12 +839,13 @@ def main() -> int:
816
839
  if args.command == "new" and args.new_command == "service":
817
840
  try:
818
841
  service_config = _collect_new_service_config(args)
819
- service_config["output_dir"] = _ensure_workspace_for_output(
842
+ workspace_root = _ensure_workspace_for_output(
820
843
  service_config["output_dir"], allow_prompt=_service_is_interactive(args)
821
844
  )
845
+ service_config["output_dir"] = _workspace_services_dir(workspace_root)
822
846
  generated = generate_service(**service_config)
823
847
  generated_cluster = _maybe_update_workspace_cluster(
824
- service_config["output_dir"], service_config, generated
848
+ workspace_root, service_config, generated
825
849
  )
826
850
  if generated_cluster is not None:
827
851
  print(f"Refreshed cluster scaffold at: {generated_cluster}")
@@ -864,10 +888,15 @@ def main() -> int:
864
888
  generate_mode = workspace_config["generate"]
865
889
  if generate_mode == "service":
866
890
  service_config = _collect_new_service_config(
867
- _default_service_namespace(workspace_root)
891
+ _default_service_namespace(_workspace_services_dir(workspace_root))
868
892
  )
869
- service_config["output_dir"] = workspace_root
893
+ service_config["output_dir"] = _workspace_services_dir(workspace_root)
870
894
  generated_service = generate_service(**service_config)
895
+ generated_cluster = _maybe_update_workspace_cluster(
896
+ workspace_root, service_config, generated_service
897
+ )
898
+ if generated_cluster is not None:
899
+ print(f"Refreshed cluster scaffold at: {generated_cluster}")
871
900
  print(f"Generated service at: {generated_service}")
872
901
  elif generate_mode == "cluster":
873
902
  cluster_config = _collect_new_cluster_config(
@@ -901,8 +930,14 @@ def main() -> int:
901
930
  if args.feature_command == "list":
902
931
  return _list_features()
903
932
 
933
+ try:
934
+ resolved_service = _resolve_feature_service_root(args.service)
935
+ except ValueError as exc:
936
+ print(f"ERROR: {exc}")
937
+ return 1
938
+
904
939
  with features_path() as feature_lib:
905
- augmentor = ServiceAugmentor(args.service, feature_lib)
940
+ augmentor = ServiceAugmentor(resolved_service, feature_lib)
906
941
  if args.feature_command == "plan" and args.json:
907
942
  plan = augmentor.build_plan(args.feature)
908
943
  if plan is None:
@@ -911,7 +946,7 @@ def main() -> int:
911
946
  json.dumps(
912
947
  {
913
948
  "feature": args.feature,
914
- "service": str(args.service.resolve()),
949
+ "service": str(resolved_service),
915
950
  "modifies": plan["modifies"],
916
951
  "creates": plan["creates"],
917
952
  },
File without changes