rainskills 0.1.0-rc.0

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 (133) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +374 -0
  3. package/bin/rainskills.js +71 -0
  4. package/install.sh +1919 -0
  5. package/package.json +55 -0
  6. package/rainbond-app-assistant/SKILL.md +1319 -0
  7. package/rainbond-app-assistant/evals/01-linked-topology-missing.expected.yaml +21 -0
  8. package/rainbond-app-assistant/evals/01-linked-topology-missing.response.md +53 -0
  9. package/rainbond-app-assistant/evals/02-linked-topology-building.expected.yaml +19 -0
  10. package/rainbond-app-assistant/evals/02-linked-topology-building.response.md +53 -0
  11. package/rainbond-app-assistant/evals/03-runtime-healthy-delivery-unknown.expected.yaml +19 -0
  12. package/rainbond-app-assistant/evals/03-runtime-healthy-delivery-unknown.response.md +53 -0
  13. package/rainbond-app-assistant/evals/04-delivered-stop-without-promotion.expected.yaml +21 -0
  14. package/rainbond-app-assistant/evals/04-delivered-stop-without-promotion.response.md +58 -0
  15. package/rainbond-app-assistant/evals/05-delivered-explicit-dev-to-test.expected.yaml +21 -0
  16. package/rainbond-app-assistant/evals/05-delivered-explicit-dev-to-test.response.md +80 -0
  17. package/rainbond-app-assistant/evals/06-manual-validation-stop.expected.yaml +16 -0
  18. package/rainbond-app-assistant/evals/06-manual-validation-stop.response.md +58 -0
  19. package/rainbond-app-assistant/evals/07-cluster-capacity-blocked.expected.yaml +15 -0
  20. package/rainbond-app-assistant/evals/07-cluster-capacity-blocked.response.md +53 -0
  21. package/rainbond-app-assistant/evals/08-code-build-handoff-stop.expected.yaml +21 -0
  22. package/rainbond-app-assistant/evals/08-code-build-handoff-stop.response.md +56 -0
  23. package/rainbond-app-assistant/evals/09-source-backed-failure-no-fallback.expected.yaml +22 -0
  24. package/rainbond-app-assistant/evals/09-source-backed-failure-no-fallback.response.md +56 -0
  25. package/rainbond-app-assistant/evals/10-identity-ambiguous-stop.expected.yaml +21 -0
  26. package/rainbond-app-assistant/evals/10-identity-ambiguous-stop.response.md +45 -0
  27. package/rainbond-app-assistant/evals/11-delivered-with-proxy-and-local-binding.expected.yaml +28 -0
  28. package/rainbond-app-assistant/evals/11-delivered-with-proxy-and-local-binding.response.md +64 -0
  29. package/rainbond-app-assistant/evals/12-complex-suite-needs-descriptor-stop.expected.yaml +24 -0
  30. package/rainbond-app-assistant/evals/12-complex-suite-needs-descriptor-stop.response.md +45 -0
  31. package/rainbond-app-assistant/evals/13-explicit-git-url-locks-source.expected.yaml +28 -0
  32. package/rainbond-app-assistant/evals/13-explicit-git-url-locks-source.response.md +53 -0
  33. package/rainbond-app-assistant/evals/14-strategy-switch-cleans-residue.expected.yaml +22 -0
  34. package/rainbond-app-assistant/evals/14-strategy-switch-cleans-residue.response.md +53 -0
  35. package/rainbond-app-assistant/evals/15-turn-discipline-reuse-alias.expected.yaml +23 -0
  36. package/rainbond-app-assistant/evals/15-turn-discipline-reuse-alias.response.md +53 -0
  37. package/rainbond-app-assistant/schemas/app-assistant-result.schema.yaml +279 -0
  38. package/rainbond-app-assistant/scripts/run_app_assistant_evals.py +80 -0
  39. package/rainbond-app-assistant/scripts/validate_app_assistant_output.py +935 -0
  40. package/rainbond-app-version-assistant/SKILL.md +444 -0
  41. package/rainbond-delivery-verifier/SKILL.md +372 -0
  42. package/rainbond-delivery-verifier/evals/01-delivered-verified.expected.yaml +19 -0
  43. package/rainbond-delivery-verifier/evals/01-delivered-verified.response.md +31 -0
  44. package/rainbond-delivery-verifier/evals/02-delivered-manual-validation.expected.yaml +19 -0
  45. package/rainbond-delivery-verifier/evals/02-delivered-manual-validation.response.md +31 -0
  46. package/rainbond-delivery-verifier/evals/03-partially-delivered-building.expected.yaml +20 -0
  47. package/rainbond-delivery-verifier/evals/03-partially-delivered-building.response.md +31 -0
  48. package/rainbond-delivery-verifier/evals/04-blocked-capacity.expected.yaml +18 -0
  49. package/rainbond-delivery-verifier/evals/04-blocked-capacity.response.md +31 -0
  50. package/rainbond-delivery-verifier/evals/05-blocked-no-usable-url.expected.yaml +20 -0
  51. package/rainbond-delivery-verifier/evals/05-blocked-no-usable-url.response.md +31 -0
  52. package/rainbond-delivery-verifier/evals/06-blocked-runtime-unhealthy.expected.yaml +19 -0
  53. package/rainbond-delivery-verifier/evals/06-blocked-runtime-unhealthy.response.md +31 -0
  54. package/rainbond-delivery-verifier/schemas/delivery-verification-result.schema.yaml +84 -0
  55. package/rainbond-delivery-verifier/scripts/run_delivery_verifier_evals.py +78 -0
  56. package/rainbond-delivery-verifier/scripts/validate_delivery_verifier_output.py +728 -0
  57. package/rainbond-env-sync/SKILL.md +496 -0
  58. package/rainbond-fullstack-bootstrap/SKILL.md +262 -0
  59. package/rainbond-fullstack-bootstrap/evals/01-reuse-only.expected.yaml +27 -0
  60. package/rainbond-fullstack-bootstrap/evals/01-reuse-only.prompt.md +1 -0
  61. package/rainbond-fullstack-bootstrap/evals/01-reuse-only.response.md +43 -0
  62. package/rainbond-fullstack-bootstrap/evals/02-deferred-dependency.expected.yaml +27 -0
  63. package/rainbond-fullstack-bootstrap/evals/02-deferred-dependency.prompt.md +1 -0
  64. package/rainbond-fullstack-bootstrap/evals/02-deferred-dependency.response.md +44 -0
  65. package/rainbond-fullstack-bootstrap/evals/03-capacity-blocked.expected.yaml +26 -0
  66. package/rainbond-fullstack-bootstrap/evals/03-capacity-blocked.prompt.md +1 -0
  67. package/rainbond-fullstack-bootstrap/evals/03-capacity-blocked.response.md +43 -0
  68. package/rainbond-fullstack-bootstrap/evals/04-template-skip.expected.yaml +31 -0
  69. package/rainbond-fullstack-bootstrap/evals/04-template-skip.prompt.md +1 -0
  70. package/rainbond-fullstack-bootstrap/evals/04-template-skip.response.md +43 -0
  71. package/rainbond-fullstack-bootstrap/evals/05-source-ambiguity-stop.expected.yaml +33 -0
  72. package/rainbond-fullstack-bootstrap/evals/05-source-ambiguity-stop.prompt.md +1 -0
  73. package/rainbond-fullstack-bootstrap/evals/05-source-ambiguity-stop.response.md +43 -0
  74. package/rainbond-fullstack-bootstrap/evals/06-external-artifact-unreachable.expected.yaml +23 -0
  75. package/rainbond-fullstack-bootstrap/evals/06-external-artifact-unreachable.response.md +39 -0
  76. package/rainbond-fullstack-bootstrap/evals/07-provider-connection-contract.expected.yaml +29 -0
  77. package/rainbond-fullstack-bootstrap/evals/07-provider-connection-contract.response.md +43 -0
  78. package/rainbond-fullstack-bootstrap/evals/08-explicit-dependency-after-manual-components.expected.yaml +30 -0
  79. package/rainbond-fullstack-bootstrap/evals/08-explicit-dependency-after-manual-components.prompt.md +1 -0
  80. package/rainbond-fullstack-bootstrap/evals/08-explicit-dependency-after-manual-components.response.md +43 -0
  81. package/rainbond-fullstack-bootstrap/evals/09-inferred-provider-consumer-gate.expected.yaml +32 -0
  82. package/rainbond-fullstack-bootstrap/evals/09-inferred-provider-consumer-gate.prompt.md +1 -0
  83. package/rainbond-fullstack-bootstrap/evals/09-inferred-provider-consumer-gate.response.md +41 -0
  84. package/rainbond-fullstack-bootstrap/evals/10-compose-service-name-not-hostname.expected.yaml +34 -0
  85. package/rainbond-fullstack-bootstrap/evals/10-compose-service-name-not-hostname.prompt.md +1 -0
  86. package/rainbond-fullstack-bootstrap/evals/10-compose-service-name-not-hostname.response.md +43 -0
  87. package/rainbond-fullstack-bootstrap/evals/11-reverse-proxy-not-dropped.expected.yaml +46 -0
  88. package/rainbond-fullstack-bootstrap/evals/11-reverse-proxy-not-dropped.prompt.md +1 -0
  89. package/rainbond-fullstack-bootstrap/evals/11-reverse-proxy-not-dropped.response.md +48 -0
  90. package/rainbond-fullstack-bootstrap/evals/12-optional-services-disclose-not-deploy.expected.yaml +43 -0
  91. package/rainbond-fullstack-bootstrap/evals/12-optional-services-disclose-not-deploy.prompt.md +1 -0
  92. package/rainbond-fullstack-bootstrap/evals/12-optional-services-disclose-not-deploy.response.md +63 -0
  93. package/rainbond-fullstack-bootstrap/evals/13-env-reference-dependency-completeness.expected.yaml +47 -0
  94. package/rainbond-fullstack-bootstrap/evals/13-env-reference-dependency-completeness.prompt.md +1 -0
  95. package/rainbond-fullstack-bootstrap/evals/13-env-reference-dependency-completeness.response.md +60 -0
  96. package/rainbond-fullstack-bootstrap/modules/10-context-loading.md +157 -0
  97. package/rainbond-fullstack-bootstrap/modules/20-scope-and-boundaries.md +105 -0
  98. package/rainbond-fullstack-bootstrap/modules/30-creation-rules.md +337 -0
  99. package/rainbond-fullstack-bootstrap/modules/40-source-and-package-rules.md +245 -0
  100. package/rainbond-fullstack-bootstrap/modules/50-workflow-and-convergence.md +198 -0
  101. package/rainbond-fullstack-bootstrap/modules/60-verification-and-handoffs.md +143 -0
  102. package/rainbond-fullstack-bootstrap/modules/70-output-contract.md +152 -0
  103. package/rainbond-fullstack-bootstrap/references/manifest-v1-reference.md +150 -0
  104. package/rainbond-fullstack-bootstrap/references/quick-reference.md +101 -0
  105. package/rainbond-fullstack-bootstrap/references/source-build-parameter-guide.md +264 -0
  106. package/rainbond-fullstack-bootstrap/references/sql-init-recipe.md +83 -0
  107. package/rainbond-fullstack-bootstrap/schemas/bootstrap-result.schema.yaml +217 -0
  108. package/rainbond-fullstack-bootstrap/scripts/run_bootstrap_evals.py +74 -0
  109. package/rainbond-fullstack-bootstrap/scripts/validate_bootstrap_output.py +615 -0
  110. package/rainbond-fullstack-troubleshooter/SKILL.md +870 -0
  111. package/rainbond-fullstack-troubleshooter/evals/01-source-build-failed.expected.yaml +29 -0
  112. package/rainbond-fullstack-troubleshooter/evals/01-source-build-failed.response.md +55 -0
  113. package/rainbond-fullstack-troubleshooter/evals/02-source-build-still-running.expected.yaml +20 -0
  114. package/rainbond-fullstack-troubleshooter/evals/02-source-build-still-running.response.md +53 -0
  115. package/rainbond-fullstack-troubleshooter/evals/03-dependency-missing.expected.yaml +21 -0
  116. package/rainbond-fullstack-troubleshooter/evals/03-dependency-missing.response.md +59 -0
  117. package/rainbond-fullstack-troubleshooter/evals/04-wrong-connection-values.expected.yaml +19 -0
  118. package/rainbond-fullstack-troubleshooter/evals/04-wrong-connection-values.response.md +58 -0
  119. package/rainbond-fullstack-troubleshooter/evals/05-env-naming-incompatibility.expected.yaml +18 -0
  120. package/rainbond-fullstack-troubleshooter/evals/05-env-naming-incompatibility.response.md +59 -0
  121. package/rainbond-fullstack-troubleshooter/evals/06-frontend-access-path-issue.expected.yaml +21 -0
  122. package/rainbond-fullstack-troubleshooter/evals/06-frontend-access-path-issue.response.md +56 -0
  123. package/rainbond-fullstack-troubleshooter/evals/07-cluster-capacity-blocked.expected.yaml +20 -0
  124. package/rainbond-fullstack-troubleshooter/evals/07-cluster-capacity-blocked.response.md +57 -0
  125. package/rainbond-fullstack-troubleshooter/evals/08-code-or-build-handoff-needed.expected.yaml +21 -0
  126. package/rainbond-fullstack-troubleshooter/evals/08-code-or-build-handoff-needed.response.md +55 -0
  127. package/rainbond-fullstack-troubleshooter/evals/09-external-artifact-unreachable.expected.yaml +28 -0
  128. package/rainbond-fullstack-troubleshooter/evals/09-external-artifact-unreachable.response.md +53 -0
  129. package/rainbond-fullstack-troubleshooter/schemas/troubleshoot-result.schema.yaml +217 -0
  130. package/rainbond-fullstack-troubleshooter/scripts/run_troubleshooter_evals.py +80 -0
  131. package/rainbond-fullstack-troubleshooter/scripts/validate_troubleshoot_output.py +789 -0
  132. package/rainbond-project-init/SKILL.md +1001 -0
  133. package/rainbond-template-installer/SKILL.md +410 -0
@@ -0,0 +1,279 @@
1
+ $schema: "https://json-schema.org/draft/2020-12/schema"
2
+ title: AppAssistantResult
3
+ type: object
4
+ additionalProperties: false
5
+ required:
6
+ - AppAssistantResult
7
+ $defs:
8
+ non_empty_string:
9
+ type: string
10
+ minLength: 1
11
+ nullable_non_empty_string:
12
+ anyOf:
13
+ - $ref: "#/$defs/non_empty_string"
14
+ - type: "null"
15
+ environment_name:
16
+ type: string
17
+ enum:
18
+ - preview
19
+ - production
20
+ environment_source:
21
+ type: string
22
+ enum:
23
+ - explicit
24
+ - local_preference
25
+ - default
26
+ request_intent:
27
+ type: string
28
+ enum:
29
+ - source_app_delivery
30
+ - dev_to_test_promotion
31
+ execution_kind:
32
+ type: string
33
+ enum:
34
+ - source
35
+ - image
36
+ - package
37
+ - template
38
+ - unknown
39
+ runtime_phase:
40
+ type: string
41
+ enum:
42
+ - topology_missing
43
+ - topology_building
44
+ - runtime_unhealthy
45
+ - runtime_healthy
46
+ - capacity_blocked
47
+ - code_or_build_handoff_needed
48
+ # source-backed build/detection failed and the run is handing off to the
49
+ # troubleshooter on the same source path instead of falling back to
50
+ # package/image/template; delivery_state must stay null in this phase.
51
+ - source_build_failed
52
+ component_status:
53
+ anyOf:
54
+ - enum:
55
+ - building
56
+ - waiting
57
+ - running
58
+ - abnormal
59
+ - capacity-blocked
60
+ - type: "null"
61
+ delivery_status:
62
+ type: string
63
+ enum:
64
+ - delivered
65
+ - delivered-but-needs-manual-validation
66
+ - partially-delivered
67
+ - blocked
68
+ delivery_verification_mode:
69
+ anyOf:
70
+ - enum:
71
+ - verified
72
+ - inferred
73
+ - manual_validation_needed
74
+ - type: "null"
75
+ delivery_next_action:
76
+ anyOf:
77
+ - enum:
78
+ - stop
79
+ - manual_url_validation
80
+ - run_troubleshooter
81
+ - fix_cluster_capacity_first
82
+ - code_build_handoff
83
+ - type: "null"
84
+ delivery_summary:
85
+ type: object
86
+ additionalProperties: false
87
+ required:
88
+ - status
89
+ - preferred_access_url
90
+ - verification_mode
91
+ - blocker
92
+ - verifier_next_action
93
+ properties:
94
+ status:
95
+ $ref: "#/$defs/delivery_status"
96
+ preferred_access_url:
97
+ $ref: "#/$defs/nullable_non_empty_string"
98
+ verification_mode:
99
+ $ref: "#/$defs/delivery_verification_mode"
100
+ blocker:
101
+ $ref: "#/$defs/nullable_non_empty_string"
102
+ verifier_next_action:
103
+ $ref: "#/$defs/delivery_next_action"
104
+ promotion_status:
105
+ type: string
106
+ enum:
107
+ - snapshot_created
108
+ - testing_app_created
109
+ - testing_app_verified
110
+ - blocked
111
+ app_identity:
112
+ type: object
113
+ additionalProperties: false
114
+ required:
115
+ - team_name
116
+ - region_name
117
+ - app_name
118
+ - app_id
119
+ properties:
120
+ team_name:
121
+ $ref: "#/$defs/nullable_non_empty_string"
122
+ region_name:
123
+ $ref: "#/$defs/nullable_non_empty_string"
124
+ app_name:
125
+ $ref: "#/$defs/nullable_non_empty_string"
126
+ app_id:
127
+ $ref: "#/$defs/nullable_non_empty_string"
128
+ runtime_state:
129
+ type: object
130
+ additionalProperties: false
131
+ required:
132
+ - phase
133
+ - db_status
134
+ - api_status
135
+ - frontend_status
136
+ - blocker
137
+ properties:
138
+ phase:
139
+ anyOf:
140
+ - $ref: "#/$defs/runtime_phase"
141
+ - type: "null"
142
+ db_status:
143
+ $ref: "#/$defs/component_status"
144
+ api_status:
145
+ $ref: "#/$defs/component_status"
146
+ frontend_status:
147
+ $ref: "#/$defs/component_status"
148
+ blocker:
149
+ $ref: "#/$defs/nullable_non_empty_string"
150
+ action_record:
151
+ type: object
152
+ additionalProperties: false
153
+ required:
154
+ - skill
155
+ - status
156
+ - details
157
+ properties:
158
+ skill:
159
+ $ref: "#/$defs/non_empty_string"
160
+ status:
161
+ $ref: "#/$defs/non_empty_string"
162
+ details:
163
+ $ref: "#/$defs/non_empty_string"
164
+ promotion_result:
165
+ type: object
166
+ additionalProperties: false
167
+ required:
168
+ - status
169
+ - snapshot
170
+ - testing_app
171
+ - testing_delivery_state
172
+ properties:
173
+ status:
174
+ $ref: "#/$defs/promotion_status"
175
+ snapshot:
176
+ type: object
177
+ additionalProperties: false
178
+ required:
179
+ - version_id
180
+ - version
181
+ - alias
182
+ properties:
183
+ version_id:
184
+ $ref: "#/$defs/nullable_non_empty_string"
185
+ version:
186
+ $ref: "#/$defs/nullable_non_empty_string"
187
+ alias:
188
+ $ref: "#/$defs/nullable_non_empty_string"
189
+ testing_app:
190
+ $ref: "#/$defs/app_identity"
191
+ testing_delivery_state:
192
+ anyOf:
193
+ - $ref: "#/$defs/delivery_summary"
194
+ - type: "null"
195
+ properties:
196
+ AppAssistantResult:
197
+ type: object
198
+ additionalProperties: false
199
+ required:
200
+ - project
201
+ - environment
202
+ - request_intent
203
+ - execution_path
204
+ - orchestration_state
205
+ - runtime_state
206
+ - delivery_state
207
+ - promotion_result
208
+ - actions_performed
209
+ - next_action
210
+ properties:
211
+ project:
212
+ type: object
213
+ additionalProperties: false
214
+ required:
215
+ - identity
216
+ - linked
217
+ - selected_environment
218
+ properties:
219
+ identity:
220
+ $ref: "#/$defs/app_identity"
221
+ linked:
222
+ anyOf:
223
+ - type: boolean
224
+ - type: "null"
225
+ selected_environment:
226
+ anyOf:
227
+ - $ref: "#/$defs/environment_name"
228
+ - type: "null"
229
+ environment:
230
+ type: object
231
+ additionalProperties: false
232
+ required:
233
+ - name
234
+ - source
235
+ - env_delta_present
236
+ - secrets_provided
237
+ properties:
238
+ name:
239
+ $ref: "#/$defs/environment_name"
240
+ source:
241
+ $ref: "#/$defs/environment_source"
242
+ env_delta_present:
243
+ type: boolean
244
+ secrets_provided:
245
+ type: boolean
246
+ request_intent:
247
+ $ref: "#/$defs/request_intent"
248
+ execution_path:
249
+ type: object
250
+ additionalProperties: false
251
+ required:
252
+ - requested_kind
253
+ - resolved_kind
254
+ properties:
255
+ requested_kind:
256
+ $ref: "#/$defs/execution_kind"
257
+ resolved_kind:
258
+ $ref: "#/$defs/execution_kind"
259
+ orchestration_state:
260
+ $ref: "#/$defs/non_empty_string"
261
+ runtime_state:
262
+ anyOf:
263
+ - $ref: "#/$defs/runtime_state"
264
+ - type: "null"
265
+ delivery_state:
266
+ anyOf:
267
+ - $ref: "#/$defs/delivery_summary"
268
+ - type: "null"
269
+ promotion_result:
270
+ anyOf:
271
+ - $ref: "#/$defs/promotion_result"
272
+ - type: "null"
273
+ actions_performed:
274
+ type: array
275
+ minItems: 1
276
+ items:
277
+ $ref: "#/$defs/action_record"
278
+ next_action:
279
+ $ref: "#/$defs/non_empty_string"
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Run all app-assistant deterministic eval fixtures."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import argparse
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ sys.dont_write_bytecode = True
12
+
13
+ SCRIPT_DIR = Path(__file__).resolve().parent
14
+ if str(SCRIPT_DIR) not in sys.path:
15
+ sys.path.insert(0, str(SCRIPT_DIR))
16
+
17
+ from validate_app_assistant_output import validate_response_file # noqa: E402
18
+
19
+
20
+ def main() -> int:
21
+ parser = argparse.ArgumentParser(
22
+ description="Run all app-assistant response fixtures through the deterministic validator."
23
+ )
24
+ parser.add_argument(
25
+ "--eval-dir",
26
+ type=Path,
27
+ default=Path(__file__).resolve().parents[1] / "evals",
28
+ help="Directory containing *.response.md and *.expected.yaml fixture pairs.",
29
+ )
30
+ parser.add_argument(
31
+ "--schema",
32
+ type=Path,
33
+ default=Path(__file__).resolve().parents[1] / "schemas" / "app-assistant-result.schema.yaml",
34
+ help="Path to app-assistant-result.schema.yaml.",
35
+ )
36
+ args = parser.parse_args()
37
+
38
+ eval_dir = args.eval_dir.resolve()
39
+ schema_path = args.schema.resolve()
40
+ response_paths = sorted(eval_dir.glob("*.response.md"))
41
+
42
+ if not response_paths:
43
+ print(f"No response fixtures found in {eval_dir}")
44
+ return 1
45
+
46
+ failures = 0
47
+ for response_path in response_paths:
48
+ base_name = response_path.name.replace(".response.md", "")
49
+ expected_path = eval_dir / f"{base_name}.expected.yaml"
50
+ if not expected_path.exists():
51
+ print(f"FAIL {response_path}")
52
+ print(f" - missing expected fixture: {expected_path}")
53
+ failures += 1
54
+ continue
55
+
56
+ errors = validate_response_file(
57
+ response_path=response_path,
58
+ schema_path=schema_path,
59
+ expected_path=expected_path,
60
+ )
61
+
62
+ if errors:
63
+ print(f"FAIL {response_path}")
64
+ for error in errors:
65
+ print(f" - {error}")
66
+ failures += 1
67
+ continue
68
+
69
+ print(f"PASS {response_path}")
70
+
71
+ if failures:
72
+ print(f"\n{failures} fixture set(s) failed.")
73
+ return 1
74
+
75
+ print(f"\nAll {len(response_paths)} app-assistant fixture set(s) passed.")
76
+ return 0
77
+
78
+
79
+ if __name__ == "__main__":
80
+ sys.exit(main())