@tdk-landscape/tdk-cli-core 1.3.14 → 1.3.22

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 (277) hide show
  1. package/README.md +3 -3
  2. package/Tiltfile +144 -0
  3. package/discovery/AGENTS.md +362 -0
  4. package/discovery/TILT_DISCOVERY.star +424 -0
  5. package/discovery/Tiltfile +58 -0
  6. package/discovery/config.star +258 -0
  7. package/discovery/constants.star +127 -0
  8. package/discovery/deterministic.star +211 -0
  9. package/discovery/discovery_daemon.star +191 -0
  10. package/discovery/discovery_orchestrator.star +460 -0
  11. package/discovery/filtering.star +5 -0
  12. package/discovery/identity-management-backend/service.yaml +26 -0
  13. package/discovery/identity-management-frontend/service.yaml +29 -0
  14. package/discovery/identity-sdk/service.yaml +9 -0
  15. package/discovery/incremental_discovery.star +213 -0
  16. package/discovery/indexing.star +7 -0
  17. package/discovery/json_manifest_scanner.star +51 -0
  18. package/discovery/libraries.star +46 -0
  19. package/discovery/loading.star +23 -0
  20. package/discovery/manifest/constants.star +104 -0
  21. package/discovery/manifest/loading.star +386 -0
  22. package/discovery/manifest/normalize.star +281 -0
  23. package/discovery/manifest/validation.star +108 -0
  24. package/discovery/normalization.star +11 -0
  25. package/discovery/registry.star +544 -0
  26. package/discovery/resource_snapshot.py +382 -0
  27. package/discovery/resource_snapshot.star +143 -0
  28. package/discovery/schemas.star +1 -0
  29. package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
  30. package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
  31. package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
  32. package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
  33. package/discovery/test_resource_snapshot.py +251 -0
  34. package/discovery/validation.star +78 -0
  35. package/discovery/versioning.star +1 -0
  36. package/dist/commands/config.d.ts.map +1 -1
  37. package/dist/commands/config.js +11 -0
  38. package/dist/commands/config.js.map +1 -1
  39. package/dist/commands/doctor.d.ts.map +1 -1
  40. package/dist/commands/doctor.js +1 -2
  41. package/dist/commands/doctor.js.map +1 -1
  42. package/dist/commands/project.d.ts.map +1 -1
  43. package/dist/commands/project.js +36 -41
  44. package/dist/commands/project.js.map +1 -1
  45. package/dist/commands/resource.d.ts.map +1 -1
  46. package/dist/commands/resource.js +51 -55
  47. package/dist/commands/resource.js.map +1 -1
  48. package/dist/commands/stack.d.ts.map +1 -1
  49. package/dist/commands/stack.js +22 -24
  50. package/dist/commands/stack.js.map +1 -1
  51. package/dist/commands/ui.d.ts.map +1 -1
  52. package/dist/commands/ui.js +1 -2
  53. package/dist/commands/ui.js.map +1 -1
  54. package/dist/commands/up.d.ts.map +1 -1
  55. package/dist/commands/up.js +1 -2
  56. package/dist/commands/up.js.map +1 -1
  57. package/dist/commands/upgrade.d.ts +8 -0
  58. package/dist/commands/upgrade.d.ts.map +1 -1
  59. package/dist/commands/upgrade.js +62 -21
  60. package/dist/commands/upgrade.js.map +1 -1
  61. package/dist/generator/extension-fetch.d.ts +19 -0
  62. package/dist/generator/extension-fetch.d.ts.map +1 -1
  63. package/dist/generator/extension-fetch.js +71 -5
  64. package/dist/generator/extension-fetch.js.map +1 -1
  65. package/dist/generator/template-engine.d.ts +1 -0
  66. package/dist/generator/template-engine.d.ts.map +1 -1
  67. package/dist/generator/template-engine.js +50 -6
  68. package/dist/generator/template-engine.js.map +1 -1
  69. package/dist/utils/command-helpers.d.ts.map +1 -1
  70. package/dist/utils/command-helpers.js +7 -9
  71. package/dist/utils/command-helpers.js.map +1 -1
  72. package/dist/utils/constants.d.ts +1 -0
  73. package/dist/utils/constants.d.ts.map +1 -1
  74. package/dist/utils/constants.js +1 -0
  75. package/dist/utils/constants.js.map +1 -1
  76. package/dist/utils/errors.d.ts +2 -0
  77. package/dist/utils/errors.d.ts.map +1 -1
  78. package/dist/utils/errors.js +6 -1
  79. package/dist/utils/errors.js.map +1 -1
  80. package/dist/utils/paths.js +1 -1
  81. package/dist/utils/paths.js.map +1 -1
  82. package/dist/utils/project-features.d.ts.map +1 -1
  83. package/dist/utils/project-features.js +1 -1
  84. package/dist/utils/project-features.js.map +1 -1
  85. package/dist/utils/resource-features.d.ts.map +1 -1
  86. package/dist/utils/resource-features.js +2 -2
  87. package/dist/utils/resource-features.js.map +1 -1
  88. package/dist/utils/tar.js +4 -4
  89. package/dist/utils/tar.js.map +1 -1
  90. package/dist/utils/validation.d.ts +7 -0
  91. package/dist/utils/validation.d.ts.map +1 -1
  92. package/dist/utils/validation.js +9 -0
  93. package/dist/utils/validation.js.map +1 -1
  94. package/engine/AGENTS.md +705 -0
  95. package/engine/README.md +29 -0
  96. package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
  97. package/engine/Tiltfile +80 -0
  98. package/engine/assets/docker/golden-layers.Dockerfile +221 -0
  99. package/engine/assets/scripts/cleanup-completed-migrator-images.sh +37 -0
  100. package/engine/assets/scripts/cleanup-tilt-images.sh +120 -0
  101. package/engine/assets/scripts/mac-m1-resource-monitor.sh +121 -0
  102. package/engine/config.star +3 -0
  103. package/engine/docs/AUTODISCOVERY_TEST.md +182 -0
  104. package/engine/docs/C4-ARCHITECTURE-operations.md +396 -0
  105. package/engine/docs/C4-ARCHITECTURE-overview.md +284 -0
  106. package/engine/docs/C4-ARCHITECTURE.md +17 -0
  107. package/engine/docs/GOLDEN_IMAGE_INTEGRATION.md +349 -0
  108. package/engine/docs/MANIFEST_DRIVEN_ARCHITECTURE.md +357 -0
  109. package/engine/docs/README.md +284 -0
  110. package/engine/entrypoint.star +97 -0
  111. package/engine/lifecycle/orchestrator.star +260 -0
  112. package/engine/paths.star +717 -0
  113. package/engine/schemas/manifest-schema.json +301 -0
  114. package/engine/schemas/service-schema.json +301 -0
  115. package/engine/scripts/README.md +89 -0
  116. package/engine/scripts/build-and-publish-lib.sh +205 -0
  117. package/engine/scripts/check-lib-publish.sh +85 -0
  118. package/engine/scripts/debug-container.sh +258 -0
  119. package/engine/scripts/generate-manifest.sh +197 -0
  120. package/engine/spec.master +702 -0
  121. package/engine/spec.master.example +341 -0
  122. package/engine/topologies/README.md +34 -0
  123. package/engine/topologies/platform/docker/AGENTS.md +59 -0
  124. package/engine/topologies/platform/docker/auth/auth.star +167 -0
  125. package/engine/topologies/platform/docker/build/golden_image.star +37 -0
  126. package/engine/topologies/platform/docker/build/golden_image_build.star +82 -0
  127. package/engine/topologies/platform/docker/build/golden_image_constants.star +93 -0
  128. package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +291 -0
  129. package/engine/topologies/platform/docker/compose/compose.star +636 -0
  130. package/engine/topologies/platform/docker/compose/compose_helpers.star +52 -0
  131. package/engine/topologies/platform/docker/compose/traefik_standalone.star +53 -0
  132. package/engine/topologies/platform/docker/config/bunignore.star +142 -0
  133. package/engine/topologies/platform/docker/config/dockerignore.star +150 -0
  134. package/engine/topologies/platform/docker/constants.star +170 -0
  135. package/engine/topologies/platform/docker/dockerfile/dockerfile.star +54 -0
  136. package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +73 -0
  137. package/engine/topologies/platform/docker/index.star +27 -0
  138. package/engine/topologies/platform/docker/layers/bun_helpers.star +23 -0
  139. package/engine/topologies/platform/docker/layers/infisical/index.star +40 -0
  140. package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +262 -0
  141. package/engine/topologies/platform/docker/layers/l1_base_layers.star +87 -0
  142. package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +125 -0
  143. package/engine/topologies/platform/docker/layers/l3_builder_layers.star +209 -0
  144. package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +214 -0
  145. package/engine/topologies/platform/docker/layers/prisma/constants.star +135 -0
  146. package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +96 -0
  147. package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +109 -0
  148. package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +98 -0
  149. package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +126 -0
  150. package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +161 -0
  151. package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +119 -0
  152. package/engine/topologies/platform/docker/networking/api_path_constants.star +230 -0
  153. package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +27 -0
  154. package/engine/topologies/platform/docker/networking/traefik.star +232 -0
  155. package/engine/topologies/platform/docker/networking/traefik_constants.star +146 -0
  156. package/engine/topologies/platform/docker/networking/traefik_helpers.star +160 -0
  157. package/engine/topologies/platform/docker/secrets/infisical.star +135 -0
  158. package/engine/topologies/platform/net/proxy.star +4 -0
  159. package/engine/topologies/platform/registries/local.star +4 -0
  160. package/engine/topologies/platform/security/secrets.star +239 -0
  161. package/engine/topologies/platform/state/relational.star +4 -0
  162. package/engine/topologies/tilt/common/AGENTS.md +59 -0
  163. package/engine/topologies/tilt/common/utils.star +364 -0
  164. package/engine/topologies/tilt/common/utils_debug.star +69 -0
  165. package/engine/topologies/tilt/common/utils_deterministic.star +168 -0
  166. package/engine/topologies/tilt/common/utils_docker_networks.star +46 -0
  167. package/engine/topologies/tilt/common/utils_env.star +43 -0
  168. package/engine/topologies/tilt/common/utils_output.star +97 -0
  169. package/engine/topologies/tilt/config/AGENTS.md +68 -0
  170. package/engine/topologies/tilt/config/defaults.star +3 -0
  171. package/engine/topologies/tilt/config/feature_flags.star +10 -0
  172. package/engine/topologies/tilt/config/global.star +55 -0
  173. package/engine/topologies/tilt/config/profiles.star +382 -0
  174. package/engine/topologies/tilt/generators/agents_md.star +62 -0
  175. package/engine/topologies/tilt/generators/api_gateway.star +145 -0
  176. package/engine/topologies/tilt/generators/index.star +124 -0
  177. package/engine/topologies/tilt/generators/infisical/README.md +424 -0
  178. package/engine/topologies/tilt/generators/infisical/examples.star +312 -0
  179. package/engine/topologies/tilt/generators/infisical/index.star +57 -0
  180. package/engine/topologies/tilt/generators/infisical/machine_identity.star +420 -0
  181. package/engine/topologies/tilt/generators/infisical/organization.star +534 -0
  182. package/engine/topologies/tilt/generators/infisical/path_manager.star +476 -0
  183. package/engine/topologies/tilt/generators/infisical/secrets_generator.star +420 -0
  184. package/engine/topologies/tilt/generators/nginx_conf.star +143 -0
  185. package/engine/topologies/tilt/generators/npmrc.star +111 -0
  186. package/engine/topologies/tilt/generators/tsconfig.star +23 -0
  187. package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +71 -0
  188. package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +124 -0
  189. package/engine/topologies/tilt/generators/typescript/common.star +7 -0
  190. package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +76 -0
  191. package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +110 -0
  192. package/engine/topologies/tilt/generators/typescript/include.star +23 -0
  193. package/engine/topologies/tilt/generators/typescript/playwright_config.star +40 -0
  194. package/engine/topologies/tilt/generators/typescript/prisma_config.star +49 -0
  195. package/engine/topologies/tilt/generators/validators.star +853 -0
  196. package/engine/topologies/tilt/generators/vite/backend.star +78 -0
  197. package/engine/topologies/tilt/generators/vite/frontend.star +98 -0
  198. package/engine/topologies/tilt/generators/vite/generators.star +43 -0
  199. package/engine/topologies/tilt/generators/vite/helpers.star +244 -0
  200. package/engine/topologies/tilt/generators/vite/library.star +65 -0
  201. package/engine/topologies/tilt/generators/vite/sdk.star +73 -0
  202. package/engine/topologies/tilt/generators/vite/templates.star +737 -0
  203. package/engine/topologies/tilt/generators/vite_config.star +22 -0
  204. package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
  205. package/engine/topologies/tilt/manifest/README.md +693 -0
  206. package/engine/topologies/tilt/manifest/__init__.star +218 -0
  207. package/engine/topologies/tilt/manifest/constants.star +252 -0
  208. package/engine/topologies/tilt/manifest/errors.star +266 -0
  209. package/engine/topologies/tilt/manifest/integration.star +339 -0
  210. package/engine/topologies/tilt/manifest/json_to_yaml.py +54 -0
  211. package/engine/topologies/tilt/manifest/loader.star +214 -0
  212. package/engine/topologies/tilt/manifest/mapper.star +227 -0
  213. package/engine/topologies/tilt/manifest/parser.star +400 -0
  214. package/engine/topologies/tilt/manifest/schema.star +462 -0
  215. package/engine/topologies/tilt/manifest/tests/test_integration.star +276 -0
  216. package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +397 -0
  217. package/engine/topologies/tilt/manifest/tests/test_manifest.star +316 -0
  218. package/engine/topologies/tilt/manifest/tests/test_validator.star +470 -0
  219. package/engine/topologies/tilt/manifest/validator.star +717 -0
  220. package/engine/topologies/tilt/manifest/yaml_to_json.py +18 -0
  221. package/engine/topologies/tilt/resources/AGENTS.md +71 -0
  222. package/engine/topologies/tilt/resources/conditions.star +3 -0
  223. package/engine/topologies/tilt/resources/databases.star +244 -0
  224. package/engine/topologies/tilt/resources/declaration.star +3 -0
  225. package/engine/topologies/tilt/resources/deps.star +3 -0
  226. package/engine/topologies/tilt/resources/infra-loader.star +437 -0
  227. package/engine/topologies/tilt/resources/libs.star +30 -0
  228. package/engine/topologies/tilt/resources/libs_discovery.star +102 -0
  229. package/engine/topologies/tilt/resources/libs_paths.star +79 -0
  230. package/engine/topologies/tilt/resources/libs_resource_definition.star +151 -0
  231. package/engine/topologies/tilt/resources/libs_setup.star +164 -0
  232. package/engine/topologies/tilt/resources/libs_tsconfig.star +37 -0
  233. package/engine/topologies/tilt/resources/orchestrator/apply.star +77 -0
  234. package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +431 -0
  235. package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +81 -0
  236. package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +148 -0
  237. package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +36 -0
  238. package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +44 -0
  239. package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +164 -0
  240. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
  241. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +21 -0
  242. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +134 -0
  243. package/engine/topologies/tilt/resources/orchestrator/generators/env.star +258 -0
  244. package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +169 -0
  245. package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +524 -0
  246. package/engine/topologies/tilt/resources/orchestrator/helpers.star +33 -0
  247. package/engine/topologies/tilt/resources/orchestrator.star +54 -0
  248. package/engine/topologies/tilt/resources/ordering.star +3 -0
  249. package/engine/topologies/tilt/resources/triggers.star +3 -0
  250. package/engine/topologies/tilt/resources/watchers.star +299 -0
  251. package/engine/where-things-live.star +717 -0
  252. package/ext/Tiltfile +66 -0
  253. package/ext/ide-components/README.md +219 -0
  254. package/ext/ide-components/code_executor/server.py +268 -0
  255. package/ext/ide-components/code_viewer/server.py +206 -0
  256. package/ext/ide-components/config_inspector/server.py +1050 -0
  257. package/ext/ide-components/file_browser/server.py +285 -0
  258. package/ext/ide-components/shared/config_service.py +469 -0
  259. package/ext/ide-components/shared/file_utils.py +298 -0
  260. package/ext/ide-components/shared/http_utils.py +232 -0
  261. package/ext/ide-components/shared/static/styles.css +1334 -0
  262. package/ext/ide-components/shared/syntax_highlighter.py +140 -0
  263. package/ext/ide-components/shared/template_engine.py +123 -0
  264. package/ext/ide-components/shared/templates/base.html +121 -0
  265. package/ext/ide-components/shared/test_config_service.py +326 -0
  266. package/ext/ide-components/shared/tilt_integration.py +158 -0
  267. package/ext/ui-enhancements/cron-status-server.sh +49 -0
  268. package/ext/ui-enhancements/cron-status-tracker.sh +146 -0
  269. package/ext/ui-enhancements/extension.yaml +36 -0
  270. package/ext/ui-enhancements/tiltfile.py +99 -0
  271. package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
  272. package/ext/ui-enhancements/ui/help-panel.css +279 -0
  273. package/ext/ui-enhancements/ui/icons.css +125 -0
  274. package/ext/ui-enhancements/ui/tooltips.css +114 -0
  275. package/package.json +13 -9
  276. package/specs/specs/TILT_SERVICE_DEFAULTS.star +205 -0
  277. package/specs/specs/TILT_TECH_STACK.star +159 -0
@@ -0,0 +1,266 @@
1
+ # =============================================================================
2
+ # 📋 MANIFEST MODULE - ERROR HANDLING
3
+ # =============================================================================
4
+ # Path: .tilt/topologies/tilt/manifest/errors.star
5
+ # Purpose: Standardized error types and handling for manifest system
6
+ # Status: Phase 1 of manifest system refactoring
7
+ # =============================================================================
8
+
9
+ # Error severity levels
10
+ SEVERITY = {
11
+ 'CRITICAL': 'critical', # Must fix, system won't function
12
+ 'ERROR': 'error', # Should fix, may cause issues
13
+ 'WARNING': 'warning', # Should consider, non-blocking
14
+ 'INFO': 'info', # Informational only
15
+ 'DEPRECATION': 'deprecation', # Feature will be removed
16
+ }
17
+
18
+ # Error categories
19
+ CATEGORY = {
20
+ 'SCHEMA': 'schema', # Schema violations
21
+ 'VALIDATION': 'validation', # Value validation failures
22
+ 'IO': 'io', # File I/O errors
23
+ 'PARSE': 'parse', # JSON parsing errors
24
+ 'DEPENDENCY': 'dependency', # Service dependency issues
25
+ 'CONFIG': 'config', # Configuration errors
26
+ 'RUNTIME': 'runtime', # Runtime errors
27
+ 'NETWORK': 'network', # Network/remote fetch errors
28
+ }
29
+
30
+ # Common error messages
31
+ ERROR_MESSAGES = {
32
+ 'MISSING_REQUIRED_FIELD': 'Missing required field: {field}',
33
+ 'INVALID_FIELD_TYPE': 'Field {field} has invalid type: expected {expected}, got {actual}',
34
+ 'INVALID_FIELD_VALUE': 'Field {field} has invalid value: {value}',
35
+ 'FIELD_OUT_OF_RANGE': 'Field {field} value {value} is outside valid range [{min}, {max}]',
36
+ 'INVALID_PATTERN': 'Field {field} value does not match required pattern: {pattern}',
37
+ 'INVALID_ENUM': 'Field {field} value {value} is not in allowed values: {allowed}',
38
+ 'FILE_NOT_FOUND': 'Manifest file not found: {path}',
39
+ 'FILE_EMPTY': 'Manifest file is empty: {path}',
40
+ 'INVALID_JSON': 'Invalid JSON in manifest file: {path} - {error}',
41
+ 'DEPENDENCY_NOT_FOUND': 'Dependency {dependency} not found for service {service}',
42
+ 'CIRCULAR_DEPENDENCY': 'Circular dependency detected: {path}',
43
+ 'PORT_CONFLICT': 'Port {port} is already used by service {existing_service}',
44
+ 'DUPLICATE_RESOURCE_NAME': 'Duplicate service name: {name}',
45
+ 'INVALID_APP_TYPE': 'Invalid app type {appType} for service {service}',
46
+ 'MISSING_BACKEND': 'Frontend {service} is missing backendName field',
47
+ 'MISSING_DATABASE': 'Service {service} has prisma feature but no databaseName',
48
+ }
49
+
50
+ def new_error(message, category, severity, context=None):
51
+ """
52
+ Create a standardized error struct.
53
+
54
+ Args:
55
+ message: Human-readable error message
56
+ category: Error category (from CATEGORY)
57
+ severity: Error severity (from SEVERITY)
58
+ context: Optional dict with:
59
+ - field: Field name if field-specific
60
+ - path: File path
61
+ - value: Invalid value
62
+ - expected: Expected value/type
63
+ - suggestion: Suggested fix
64
+
65
+ Returns:
66
+ Error struct
67
+ """
68
+ return struct(
69
+ message=message,
70
+ category=category,
71
+ severity=severity,
72
+ context=context or {},
73
+ timestamp=None, # Tilt doesn't have time functions, set externally if needed
74
+ )
75
+
76
+ def format_error(error):
77
+ """
78
+ Format error for display.
79
+
80
+ Args:
81
+ error: Error struct
82
+
83
+ Returns:
84
+ Formatted string
85
+ """
86
+ base = "[{severity}] {category}: {message}".format(
87
+ severity=error.severity.upper(),
88
+ category=error.category.upper(),
89
+ message=error.message,
90
+ )
91
+
92
+ if error.context:
93
+ if 'field' in error.context:
94
+ base += " (field: {field})".format(field=error.context['field'])
95
+ if 'path' in error.context:
96
+ base += " @ {path}".format(path=error.context['path'])
97
+ if 'suggestion' in error.context:
98
+ base += "\n 💡 Suggestion: {suggestion}".format(
99
+ suggestion=error.context['suggestion']
100
+ )
101
+
102
+ return base
103
+
104
+ def group_errors(errors):
105
+ """
106
+ Group errors by category and severity.
107
+
108
+ Args:
109
+ errors: List of error structs
110
+
111
+ Returns:
112
+ Dict with errors grouped by category and severity
113
+ """
114
+ grouped = {}
115
+
116
+ for error in errors:
117
+ cat = error.category
118
+ sev = error.severity
119
+
120
+ if cat not in grouped:
121
+ grouped[cat] = {}
122
+
123
+ if sev not in grouped[cat]:
124
+ grouped[cat][sev] = []
125
+
126
+ grouped[cat][sev].append(error)
127
+
128
+ return grouped
129
+
130
+ def has_critical_errors(errors):
131
+ """
132
+ Check if any critical errors exist.
133
+
134
+ Args:
135
+ errors: List of error structs
136
+
137
+ Returns:
138
+ True if any critical errors exist
139
+ """
140
+ for error in errors:
141
+ if error.severity == SEVERITY['CRITICAL']:
142
+ return True
143
+ return False
144
+
145
+ def has_errors(errors, min_severity='ERROR'):
146
+ """
147
+ Check if any errors of specified severity or higher exist.
148
+
149
+ Args:
150
+ errors: List of error structs
151
+ min_severity: Minimum severity to check (ERROR, WARNING, etc.)
152
+
153
+ Returns:
154
+ True if any matching errors exist
155
+ """
156
+ severity_order = ['INFO', 'DEPRECATION', 'WARNING', 'ERROR', 'CRITICAL']
157
+ min_idx = severity_order.index(min_severity)
158
+
159
+ for error in errors:
160
+ error_idx = severity_order.index(error.severity)
161
+ if error_idx >= min_idx:
162
+ return True
163
+
164
+ return False
165
+
166
+ def filter_errors(errors, category=None, severity=None):
167
+ """
168
+ Filter errors by category and/or severity.
169
+
170
+ Args:
171
+ errors: List of error structs
172
+ category: Optional category to filter by
173
+ severity: Optional severity to filter by
174
+
175
+ Returns:
176
+ Filtered list of errors
177
+ """
178
+ filtered = []
179
+
180
+ for error in errors:
181
+ if category and error.category != category:
182
+ continue
183
+ if severity and error.severity != severity:
184
+ continue
185
+ filtered.append(error)
186
+
187
+ return filtered
188
+
189
+ def get_error_summary(errors):
190
+ """
191
+ Get a summary of errors by category and severity.
192
+
193
+ Args:
194
+ errors: List of error structs
195
+
196
+ Returns:
197
+ Summary dict with counts
198
+ """
199
+ summary = {
200
+ 'total': len(errors),
201
+ 'by_severity': {
202
+ 'CRITICAL': 0,
203
+ 'ERROR': 0,
204
+ 'WARNING': 0,
205
+ 'INFO': 0,
206
+ 'DEPRECATION': 0,
207
+ },
208
+ 'by_category': {},
209
+ }
210
+
211
+ for error in errors:
212
+ summary['by_severity'][error.severity] += 1
213
+
214
+ cat = error.category
215
+ if cat not in summary['by_category']:
216
+ summary['by_category'][cat] = 0
217
+ summary['by_category'][cat] += 1
218
+
219
+ return summary
220
+
221
+ def create_field_error(field_name, field_value, error_type, **kwargs):
222
+ """
223
+ Convenience function to create field-specific errors.
224
+
225
+ Args:
226
+ field_name: Name of the field with error
227
+ field_value: The invalid value
228
+ error_type: Type of error (key in ERROR_MESSAGES)
229
+ **kwargs: Additional context for error message formatting
230
+
231
+ Returns:
232
+ Error struct
233
+ """
234
+ message_template = ERROR_MESSAGES.get(error_type, 'Unknown error for field {field}')
235
+
236
+ context = {
237
+ 'field': field_name,
238
+ 'value': field_value,
239
+ }
240
+ context.update(kwargs)
241
+
242
+ message = message_template.format(**context)
243
+
244
+ return new_error(
245
+ message=message,
246
+ category=CATEGORY['VALIDATION'],
247
+ severity=SEVERITY['ERROR'],
248
+ context=context,
249
+ )
250
+
251
+ # Export all error handling functions and constants
252
+ ManifestErrors = struct(
253
+ SEVERITY=SEVERITY,
254
+ CATEGORY=CATEGORY,
255
+ ERROR_MESSAGES=ERROR_MESSAGES,
256
+ new=new_error,
257
+ format=format_error,
258
+ group=group_errors,
259
+ has_critical=has_critical_errors,
260
+ has_errors=has_errors,
261
+ filter=filter_errors,
262
+ get_summary=get_error_summary,
263
+ create_field_error=create_field_error,
264
+ )
265
+
266
+ VALIDATION = {}
@@ -0,0 +1,339 @@
1
+ # =============================================================================
2
+ # 📋 MANIFEST MODULE - DISCOVERY INTEGRATION (Phase 5 Complete)
3
+ # =============================================================================
4
+ # Path: .tilt/topologies/tilt/manifest/integration.star
5
+ # Purpose: Integration layer between new manifest module and discovery system
6
+ # Status: Phase 5 COMPLETE - Fully integrated, backward compatibility removed
7
+ #
8
+ # This module provides the bridge between the new manifest system and the
9
+ # discovery infrastructure. Phase 5 complete - using new system exclusively.
10
+ # =============================================================================
11
+
12
+ load("./__init__.star", "Manifest")
13
+ load("./loader.star", "ManifestLoader")
14
+ load("./parser.star", "ManifestParser")
15
+ load("./validator.star", "ManifestValidator")
16
+
17
+ # Phase 5: Migration complete - always use new system
18
+ def load_and_validate_manifest(manifest_path, all_manifests=None):
19
+ """
20
+ Load and validate a manifest using the new manifest system.
21
+
22
+ This is the main integration point for discovery.star to use
23
+ the new manifest module. Phase 5: Always uses new system.
24
+
25
+ Args:
26
+ manifest_path: Path to manifest JSON file
27
+ all_manifests: Optional list of all manifests for cross-validation
28
+
29
+ Returns:
30
+ struct(
31
+ manifest=None, # Normalized manifest dict
32
+ error=None, # Error message or None
33
+ warnings=[], # List of warnings
34
+ validation=None, # Validation result struct
35
+ metadata={}, # Loading metadata
36
+ )
37
+ """
38
+
39
+ if load_result.error:
40
+ return struct(
41
+ manifest=None,
42
+ error=load_result.error,
43
+ warnings=load_result.warnings,
44
+ validation=None,
45
+ metadata=load_result.metadata,
46
+ )
47
+
48
+ raw_manifest = load_result.manifest
49
+ resource_path = ManifestParser.extract_resource_path(manifest_path)
50
+
51
+ # Step 2: Parse and normalize
52
+ parse_result = ManifestParser.get_normalized(raw_manifest, resource_path)
53
+
54
+ if parse_result.error:
55
+ return struct(
56
+ manifest=None,
57
+ error=parse_result.error,
58
+ warnings=parse_result.warnings + load_result.warnings,
59
+ validation=None,
60
+ metadata=load_result.metadata,
61
+ )
62
+
63
+ normalized_manifest = parse_result.manifest
64
+ all_warnings = parse_result.warnings + load_result.warnings
65
+
66
+ # Step 3: Validate
67
+ context = {'resource_path': resource_path}
68
+ if all_manifests:
69
+ context['all_manifests'] = all_manifests
70
+
71
+ validation_result = ManifestValidator.validate(normalized_manifest, context, level='all')
72
+
73
+ # Add validation warnings to list
74
+ for warning in validation_result.warnings:
75
+ all_warnings.append(Manifest.format_error(warning))
76
+
77
+ return struct(
78
+ manifest=normalized_manifest,
79
+ error=None,
80
+ warnings=all_warnings,
81
+ validation=validation_result,
82
+ metadata=load_result.metadata,
83
+ )
84
+
85
+ def load_all_manifests(services_root, filters=None, validate=False):
86
+ """
87
+ Load all manifests with optional validation.
88
+
89
+ Integration wrapper for Manifest.load_all() with additional
90
+ processing for discovery system compatibility.
91
+
92
+ Args:
93
+ services_root: Root directory to search
94
+ filters: Optional filters (appType, stack, features)
95
+ validate: Whether to validate each manifest
96
+
97
+ Returns:
98
+ struct(
99
+ manifests=[], # List of normalized manifests
100
+ errors=[], # List of errors
101
+ warnings=[], # List of warnings
102
+ stats={}, # Loading statistics
103
+ by_name={}, # Dict mapping appName to manifest
104
+ by_port={}, # Dict mapping port to manifest
105
+ )
106
+ """
107
+ # Use the new loader
108
+ load_result = ManifestLoader.load_all(services_root, filters)
109
+
110
+ manifests = []
111
+ errors = []
112
+ warnings = []
113
+ by_name = {}
114
+ by_port = {}
115
+
116
+ # Normalize each manifest
117
+ for raw_manifest in load_result.manifests:
118
+ resource_path = raw_manifest.get('_resource_path', '')
119
+
120
+ # Normalize
121
+ parse_result = ManifestParser.get_normalized(raw_manifest, resource_path)
122
+
123
+ if parse_result.error:
124
+ errors.append(parse_result.error)
125
+ continue
126
+
127
+ normalized = parse_result.manifest
128
+ manifests.append(normalized)
129
+
130
+ # Build lookup maps
131
+ app_name = normalized.get('appName')
132
+ if app_name:
133
+ by_name[app_name] = normalized
134
+
135
+ port = normalized.get('port')
136
+ if port:
137
+ by_port[port] = normalized
138
+
139
+ # Collect warnings
140
+ warnings.extend(parse_result.warnings)
141
+
142
+ # Add loading errors
143
+ for error in load_result.errors:
144
+ errors.append(ManifestErrors.format(error))
145
+
146
+ # Validate if requested
147
+ if validate:
148
+ for manifest in manifests:
149
+ context = {
150
+ 'all_manifests': manifests,
151
+ 'resource_path': manifest.get('_resource_path', ''),
152
+ }
153
+
154
+ validation = ManifestValidator.validate(manifest, context, level='cross_service')
155
+
156
+ if not validation.valid:
157
+ for error in validation.errors:
158
+ errors.append(Manifest.format_error(error))
159
+
160
+ return struct(
161
+ manifests=manifests,
162
+ errors=errors,
163
+ warnings=warnings,
164
+ stats=load_result.stats,
165
+ by_name=by_name,
166
+ by_port=by_port,
167
+ )
168
+
169
+ def convert_to_resource_format(manifest):
170
+ """
171
+ Convert normalized manifest to discovery resource format.
172
+
173
+ This ensures compatibility with the existing discovery system
174
+ by converting the new manifest format to the expected resource format.
175
+
176
+ Args:
177
+ manifest: Normalized manifest dict
178
+
179
+ Returns:
180
+ Resource dict in discovery format
181
+ """
182
+ app_name = manifest.get('appName', 'unknown')
183
+ app_type = manifest.get('appType', 'backend')
184
+ stack = manifest.get('stack', 'unknown')
185
+ port = manifest.get('port', 4000)
186
+ syncs = manifest.get('syncs', [])
187
+ dockerfile = manifest.get('dockerfile', '.autogenerated/Dockerfile.app.autogenerated')
188
+ resource_path = manifest.get('_resource_path', '')
189
+
190
+ resource = {
191
+ 'name': app_name,
192
+ 'dockerfile': app_name + '/' + dockerfile,
193
+ 'syncs': syncs,
194
+ 'port': port,
195
+ 'stack': stack,
196
+ '_manifest': manifest.get('_manifest', manifest), # Original manifest
197
+ '_resource_path': resource_path,
198
+ '_normalized': True,
199
+ }
200
+
201
+ # Add frontend-specific fields
202
+ if app_type == 'frontend':
203
+ resource['frontend'] = True
204
+ resource['backendName'] = manifest.get('backendName', app_name.replace('-frontend', '-backend'))
205
+
206
+ # Add optional fields
207
+ if manifest.get('target_path'):
208
+ resource['target_path'] = manifest['target_path']
209
+ if manifest.get('prisma_client_path'):
210
+ resource['prisma_client_path'] = manifest['prisma_client_path']
211
+ if manifest.get('registry_host'):
212
+ resource['registry_host'] = manifest['registry_host']
213
+ if manifest.get('start_command'):
214
+ resource['start_command'] = manifest['start_command']
215
+
216
+ return resource
217
+
218
+ def get_validation_summary(manifests):
219
+ """
220
+ Generate validation summary for all manifests.
221
+
222
+ Args:
223
+ manifests: List of manifest dicts
224
+
225
+ Returns:
226
+ Dict with summary statistics
227
+ """
228
+ summary = {
229
+ 'total': len(manifests),
230
+ 'valid': 0,
231
+ 'invalid': 0,
232
+ 'errors': 0,
233
+ 'warnings': 0,
234
+ 'by_severity': {
235
+ 'CRITICAL': 0,
236
+ 'ERROR': 0,
237
+ 'WARNING': 0,
238
+ },
239
+ }
240
+
241
+ for manifest in manifests:
242
+ context = {'all_manifests': manifests}
243
+ result = ManifestValidator.validate(manifest, context, level='all')
244
+
245
+ if result.valid:
246
+ summary['valid'] += 1
247
+ else:
248
+ summary['invalid'] += 1
249
+
250
+ summary['errors'] += len([e for e in result.errors
251
+ if e.severity in ['ERROR', 'CRITICAL']])
252
+ summary['warnings'] += len(result.warnings)
253
+
254
+ for error in result.errors:
255
+ if error.severity in summary['by_severity']:
256
+ summary['by_severity'][error.severity] += 1
257
+
258
+ return summary
259
+
260
+ def check_port_conflicts(manifests):
261
+ """
262
+ Check for port conflicts across all manifests.
263
+
264
+ Args:
265
+ manifests: List of manifest dicts
266
+
267
+ Returns:
268
+ List of conflict error structs
269
+ """
270
+ conflicts = []
271
+ ports = {}
272
+
273
+ for manifest in manifests:
274
+ port = manifest.get('port')
275
+ app_name = manifest.get('appName', 'unknown')
276
+
277
+ if port:
278
+ if port in ports:
279
+ conflicts.append(ManifestErrors.new(
280
+ message="Port {} conflict: {} and {}".format(port, ports[port], app_name),
281
+ category=ManifestErrors.CATEGORY['VALIDATION'],
282
+ severity=ManifestErrors.SEVERITY['ERROR'],
283
+ context={'port': port, 'services': [ports[port], app_name]},
284
+ ))
285
+ else:
286
+ ports[port] = app_name
287
+
288
+ return conflicts
289
+
290
+ def check_dependencies_valid(manifests):
291
+ """
292
+ Check if all dependencies reference valid services.
293
+
294
+ Args:
295
+ manifests: List of manifest dicts
296
+
297
+ Returns:
298
+ List of dependency error structs
299
+ """
300
+ errors = []
301
+ app_names = {m.get('appName'): m for m in manifests if m.get('appName')}
302
+
303
+ for manifest in manifests:
304
+ app_name = manifest.get('appName', 'unknown')
305
+ internal_deps = manifest.get('dependsOn', [])
306
+
307
+ for dep in internal_deps:
308
+ if dep not in app_names:
309
+ errors.append(ManifestErrors.new(
310
+ message="Service '{}' depends on non-existent service '{}'".format(app_name, dep),
311
+ category=ManifestErrors.CATEGORY['DEPENDENCY'],
312
+ severity=ManifestErrors.SEVERITY['ERROR'],
313
+ context={'service': app_name, 'dependency': dep},
314
+ ))
315
+
316
+ # Check frontend backend references
317
+ if manifest.get('appType') == 'frontend':
318
+ backend_name = manifest.get('backendName', '')
319
+ if backend_name and backend_name not in app_names:
320
+ errors.append(ManifestErrors.new(
321
+ message="Frontend '{}' references non-existent backend '{}'".format(app_name, backend_name),
322
+ category=ManifestErrors.CATEGORY['DEPENDENCY'],
323
+ severity=ManifestErrors.SEVERITY['ERROR'],
324
+ context={'frontend': app_name, 'backend': backend_name},
325
+ ))
326
+
327
+ return errors
328
+
329
+ # Export integration functions
330
+ ManifestIntegration = struct(
331
+ load_and_validate=load_and_validate_manifest,
332
+ load_all=load_all_manifests,
333
+ convert_to_resource=convert_to_resource_format,
334
+ get_validation_summary=get_validation_summary,
335
+ check_port_conflicts=check_port_conflicts,
336
+ check_dependencies_valid=check_dependencies_valid,
337
+ )
338
+
339
+ VALIDATION = {}
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python3
2
+ """Convert JSON manifest to Tilt-compatible YAML resource"""
3
+ import sys
4
+ import json
5
+ import yaml
6
+ import datetime
7
+ import uuid
8
+
9
+ if len(sys.argv) < 2:
10
+ print("Usage: json_to_yaml.py <json_file>", file=sys.stderr)
11
+ sys.exit(1)
12
+
13
+ json_file = sys.argv[1]
14
+ try:
15
+ with open(json_file, 'r') as f:
16
+ data = json.load(f)
17
+
18
+ now = datetime.datetime.now(datetime.timezone.utc).isoformat().replace("+00:00", "Z")
19
+ uid = str(uuid.uuid4())
20
+
21
+ # Match exact Tilt get uiresources format
22
+ tilt_resource = {
23
+ "apiVersion": "tilt.dev/v1alpha1",
24
+ "kind": "UIResource",
25
+ "metadata": {
26
+ "annotations": {
27
+ "tilt.dev/resource": data.get("appName", "unknown")
28
+ },
29
+ "creationTimestamp": now,
30
+ "name": data.get("appName", "unknown"),
31
+ "resourceVersion": "1",
32
+ "uid": uid
33
+ },
34
+ "spec": data,
35
+ "status": {
36
+ "conditions": [
37
+ {
38
+ "lastTransitionTime": now,
39
+ "status": "True",
40
+ "type": "UpToDate"
41
+ }
42
+ ],
43
+ "runtimeStatus": "pending",
44
+ "updateStatus": "ok"
45
+ }
46
+ }
47
+
48
+ print(yaml.dump(tilt_resource,
49
+ default_flow_style=False,
50
+ sort_keys=False,
51
+ allow_unicode=True))
52
+ except Exception as e:
53
+ print(f"Error: {e}", file=sys.stderr)
54
+ sys.exit(1)