graph-agents-cli 0.3.1__py3-none-any.whl

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 (291) hide show
  1. graph_agents_cli/__init__.py +26 -0
  2. graph_agents_cli/_api_policy.py +2145 -0
  3. graph_agents_cli/_approvals.py +400 -0
  4. graph_agents_cli/_build.py +186 -0
  5. graph_agents_cli/_build_info.json +7 -0
  6. graph_agents_cli/_chat_client.py +462 -0
  7. graph_agents_cli/_click.py +157 -0
  8. graph_agents_cli/_defaults.py +139 -0
  9. graph_agents_cli/_experiments.py +64 -0
  10. graph_agents_cli/_http.py +192 -0
  11. graph_agents_cli/_output.py +83 -0
  12. graph_agents_cli/_project.py +462 -0
  13. graph_agents_cli/_remote.py +220 -0
  14. graph_agents_cli/_response_schema.py +264 -0
  15. graph_agents_cli/_runner.py +319 -0
  16. graph_agents_cli/_skills_check.py +274 -0
  17. graph_agents_cli/_tools.py +189 -0
  18. graph_agents_cli/_trust.py +66 -0
  19. graph_agents_cli/api/__init__.py +15 -0
  20. graph_agents_cli/api/_changes.py +506 -0
  21. graph_agents_cli/api/_files.py +658 -0
  22. graph_agents_cli/api/cmd_api.py +2480 -0
  23. graph_agents_cli/deploy/__init__.py +15 -0
  24. graph_agents_cli/deploy/_config.py +171 -0
  25. graph_agents_cli/deploy/_image.py +128 -0
  26. graph_agents_cli/deploy/_kube.py +286 -0
  27. graph_agents_cli/deploy/_modes.py +234 -0
  28. graph_agents_cli/deploy/_preflight.py +370 -0
  29. graph_agents_cli/deploy/_values.py +168 -0
  30. graph_agents_cli/deploy/cmd_deploy.py +1866 -0
  31. graph_agents_cli/deploy/gitops.py +562 -0
  32. graph_agents_cli/deploy/local_load.py +273 -0
  33. graph_agents_cli/dev/__init__.py +13 -0
  34. graph_agents_cli/dev/cmd_build.py +131 -0
  35. graph_agents_cli/dev/cmd_install.py +78 -0
  36. graph_agents_cli/dev/cmd_lint.py +119 -0
  37. graph_agents_cli/dev/cmd_playground.py +297 -0
  38. graph_agents_cli/dev/policy_check.py +1287 -0
  39. graph_agents_cli/eval/__init__.py +22 -0
  40. graph_agents_cli/eval/_client.py +670 -0
  41. graph_agents_cli/eval/_common.py +177 -0
  42. graph_agents_cli/eval/_judge.py +168 -0
  43. graph_agents_cli/eval/_judge_runner.py +238 -0
  44. graph_agents_cli/eval/_paths.py +212 -0
  45. graph_agents_cli/eval/checks.py +581 -0
  46. graph_agents_cli/eval/cmd_analyze.py +278 -0
  47. graph_agents_cli/eval/cmd_compare.py +284 -0
  48. graph_agents_cli/eval/cmd_eval_group.py +80 -0
  49. graph_agents_cli/eval/cmd_generate.py +558 -0
  50. graph_agents_cli/eval/cmd_grade.py +466 -0
  51. graph_agents_cli/eval/cmd_metric.py +156 -0
  52. graph_agents_cli/eval/cmd_run.py +370 -0
  53. graph_agents_cli/eval/cmd_submit.py +400 -0
  54. graph_agents_cli/eval/config.py +435 -0
  55. graph_agents_cli/eval/dataset.py +350 -0
  56. graph_agents_cli/eval/gate.py +420 -0
  57. graph_agents_cli/eval/transcript.py +192 -0
  58. graph_agents_cli/extension/__init__.py +13 -0
  59. graph_agents_cli/extension/_compat.py +86 -0
  60. graph_agents_cli/extension/_loader.py +293 -0
  61. graph_agents_cli/extension/_manifest.py +135 -0
  62. graph_agents_cli/extension/_overrides.py +195 -0
  63. graph_agents_cli/extension/_paths.py +91 -0
  64. graph_agents_cli/extension/_refs.py +193 -0
  65. graph_agents_cli/extension/_resolver.py +453 -0
  66. graph_agents_cli/extension/_schema.py +106 -0
  67. graph_agents_cli/extension/_spec.py +253 -0
  68. graph_agents_cli/extension/_sync.py +102 -0
  69. graph_agents_cli/extension/_trust.py +58 -0
  70. graph_agents_cli/extension/cmd_extension_add.py +259 -0
  71. graph_agents_cli/extension/cmd_extension_group.py +57 -0
  72. graph_agents_cli/extension/cmd_extension_list.py +56 -0
  73. graph_agents_cli/extension/cmd_extension_remove.py +61 -0
  74. graph_agents_cli/extension/cmd_extension_update.py +195 -0
  75. graph_agents_cli/info/__init__.py +13 -0
  76. graph_agents_cli/info/cmd_info.py +222 -0
  77. graph_agents_cli/infra/__init__.py +15 -0
  78. graph_agents_cli/infra/checks.py +1169 -0
  79. graph_agents_cli/infra/cmd_infra.py +103 -0
  80. graph_agents_cli/main.py +591 -0
  81. graph_agents_cli/peer/__init__.py +15 -0
  82. graph_agents_cli/peer/_generate.py +254 -0
  83. graph_agents_cli/peer/cmd_peer.py +1151 -0
  84. graph_agents_cli/run/__init__.py +13 -0
  85. graph_agents_cli/run/_local_server.py +1157 -0
  86. graph_agents_cli/run/_signals.py +141 -0
  87. graph_agents_cli/run/cmd_approvals.py +530 -0
  88. graph_agents_cli/run/cmd_run.py +1421 -0
  89. graph_agents_cli/scaffold/__init__.py +19 -0
  90. graph_agents_cli/scaffold/agents/README.md +24 -0
  91. graph_agents_cli/scaffold/agents/empty_py/.template/templateconfig.yaml +22 -0
  92. graph_agents_cli/scaffold/agents/langgraph/.env.example +292 -0
  93. graph_agents_cli/scaffold/agents/langgraph/.template/templateconfig.yaml +28 -0
  94. graph_agents_cli/scaffold/agents/langgraph/Dockerfile +59 -0
  95. graph_agents_cli/scaffold/agents/langgraph/Dockerfile.langgraph-server +59 -0
  96. graph_agents_cli/scaffold/agents/langgraph/README.md +571 -0
  97. graph_agents_cli/scaffold/agents/langgraph/api-policy.yaml +60 -0
  98. graph_agents_cli/scaffold/agents/langgraph/app/__init__.py +20 -0
  99. graph_agents_cli/scaffold/agents/langgraph/app/agent.py +174 -0
  100. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/__init__.py +15 -0
  101. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a.py +2162 -0
  102. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a_client.py +1167 -0
  103. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/api_client.py +4220 -0
  104. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/approvals.py +1349 -0
  105. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/auth.py +1986 -0
  106. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/chat.py +2962 -0
  107. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/checkpointer.py +432 -0
  108. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/content.py +569 -0
  109. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/db.py +580 -0
  110. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/limits.py +203 -0
  111. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/metrics.py +231 -0
  112. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/middleware.py +361 -0
  113. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/model.py +611 -0
  114. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/playground.py +230 -0
  115. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/run_locks.py +459 -0
  116. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/structured.py +755 -0
  117. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/telemetry.py +681 -0
  118. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/threads.py +493 -0
  119. graph_agents_cli/scaffold/agents/langgraph/app/app_utils/token_exchange.py +959 -0
  120. graph_agents_cli/scaffold/agents/langgraph/app/fast_api_app.py +770 -0
  121. graph_agents_cli/scaffold/agents/langgraph/app/policies/__init__.py +55 -0
  122. graph_agents_cli/scaffold/agents/langgraph/app/policies/custom.py +97 -0
  123. graph_agents_cli/scaffold/agents/langgraph/app/tools/__init__.py +46 -0
  124. graph_agents_cli/scaffold/agents/langgraph/app/tools/example_api.py +92 -0
  125. graph_agents_cli/scaffold/agents/langgraph/app/tools/weather.py +33 -0
  126. graph_agents_cli/scaffold/agents/langgraph/langgraph.json +14 -0
  127. graph_agents_cli/scaffold/agents/langgraph/pyproject.toml +78 -0
  128. graph_agents_cli/scaffold/agents/langgraph/tests/conftest.py +376 -0
  129. graph_agents_cli/scaffold/agents/langgraph/tests/eval/datasets/basic-dataset.json +53 -0
  130. graph_agents_cli/scaffold/agents/langgraph/tests/eval/eval_config.yaml +32 -0
  131. graph_agents_cli/scaffold/agents/langgraph/tests/integration/approval_graph.py +137 -0
  132. graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_issuer.py +216 -0
  133. graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_openai.py +357 -0
  134. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_outcomes.py +569 -0
  135. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_relay.py +479 -0
  136. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_api_surface.py +812 -0
  137. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals.py +1367 -0
  138. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals_server.py +794 -0
  139. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor.py +497 -0
  140. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor_server.py +247 -0
  141. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_history_repair.py +278 -0
  142. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_model_apis.py +242 -0
  143. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_postgres.py +637 -0
  144. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_resilience_postgres.py +770 -0
  145. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_runtime_guardrails.py +854 -0
  146. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_e2e.py +340 -0
  147. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_runtime.py +989 -0
  148. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_answers.py +584 -0
  149. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_server.py +222 -0
  150. graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_token_exchange_issuer.py +650 -0
  151. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/.results/.placeholder +0 -0
  152. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/README.md +22 -0
  153. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/conftest.py +21 -0
  154. graph_agents_cli/scaffold/agents/langgraph/tests/load_test/load_test.py +81 -0
  155. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_client.py +824 -0
  156. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_scoping.py +724 -0
  157. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client.py +1214 -0
  158. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client_hardening.py +716 -0
  159. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_policy_rpc.py +767 -0
  160. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_approval_ledger.py +1536 -0
  161. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_fake_model.py +115 -0
  162. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_jwt_policy.py +991 -0
  163. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_limits.py +310 -0
  164. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging.py +148 -0
  165. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging_hardening.py +271 -0
  166. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_policy.py +378 -0
  167. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_resilience.py +610 -0
  168. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_server_auth.py +702 -0
  169. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_structured.py +673 -0
  170. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_telemetry.py +404 -0
  171. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_thread_listing.py +255 -0
  172. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_threads.py +268 -0
  173. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_token_exchange.py +1320 -0
  174. graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_untrusted_content.py +393 -0
  175. graph_agents_cli/scaffold/agents/langgraph/uv-fastapi.lock +2084 -0
  176. graph_agents_cli/scaffold/agents/langgraph/uv-langgraph-server.lock +2106 -0
  177. graph_agents_cli/scaffold/agents/langgraph/{{cookiecutter.agent_guidance_filename}} +129 -0
  178. graph_agents_cli/scaffold/base_templates/_shared/graph-agents-cli-manifest.yaml +36 -0
  179. graph_agents_cli/scaffold/base_templates/python/.dockerignore +32 -0
  180. graph_agents_cli/scaffold/base_templates/python/.github/CODEOWNERS +30 -0
  181. graph_agents_cli/scaffold/base_templates/python/.github/agent.env +7 -0
  182. graph_agents_cli/scaffold/base_templates/python/.github/workflows/pr_checks.yaml +214 -0
  183. graph_agents_cli/scaffold/base_templates/python/.gitignore +209 -0
  184. graph_agents_cli/scaffold/base_templates/python/tests/unit/test_dummy.py +23 -0
  185. graph_agents_cli/scaffold/base_templates/python/{{cookiecutter.agent_guidance_filename}} +35 -0
  186. graph_agents_cli/scaffold/cmd_scaffold_group.py +49 -0
  187. graph_agents_cli/scaffold/commands/__init__.py +13 -0
  188. graph_agents_cli/scaffold/commands/create.py +1424 -0
  189. graph_agents_cli/scaffold/commands/enhance.py +1652 -0
  190. graph_agents_cli/scaffold/commands/upgrade.py +570 -0
  191. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/agent.env +12 -0
  192. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/promote-to-prod.yaml +371 -0
  193. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/staging.yaml +450 -0
  194. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-dev.yaml +43 -0
  195. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-prod.yaml +41 -0
  196. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-staging.yaml +43 -0
  197. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/.helmignore +14 -0
  198. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/Chart.yaml +21 -0
  199. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/examples/networkpolicy.yaml +103 -0
  200. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/NOTES.txt +48 -0
  201. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/_helpers.tpl +189 -0
  202. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/certificate.yaml +15 -0
  203. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/configmap.yaml +10 -0
  204. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/deployment.yaml +199 -0
  205. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/hpa.yaml +22 -0
  206. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/httproute.yaml +30 -0
  207. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/ingress.yaml +39 -0
  208. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/networkpolicy.yaml +48 -0
  209. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/pdb.yaml +13 -0
  210. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/postgresql-secret.yaml +37 -0
  211. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/service.yaml +15 -0
  212. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/serviceaccount.yaml +13 -0
  213. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/servicemonitor.yaml +42 -0
  214. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-dev.yaml +22 -0
  215. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-prod.yaml +45 -0
  216. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-staging.yaml +29 -0
  217. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values.yaml +396 -0
  218. graph_agents_cli/scaffold/deployment_targets/kubernetes/python/tests/integration/test_chart.py +269 -0
  219. graph_agents_cli/scaffold/deployment_targets/none/README.md +5 -0
  220. graph_agents_cli/scaffold/deployment_targets/none/python/README.md +6 -0
  221. graph_agents_cli/scaffold/utils/__init__.py +13 -0
  222. graph_agents_cli/scaffold/utils/backup.py +212 -0
  223. graph_agents_cli/scaffold/utils/build_record.py +257 -0
  224. graph_agents_cli/scaffold/utils/cli_options.py +184 -0
  225. graph_agents_cli/scaffold/utils/fs.py +83 -0
  226. graph_agents_cli/scaffold/utils/generate_locks.py +214 -0
  227. graph_agents_cli/scaffold/utils/generation_metadata.py +88 -0
  228. graph_agents_cli/scaffold/utils/keyedit.py +768 -0
  229. graph_agents_cli/scaffold/utils/keymerge.py +537 -0
  230. graph_agents_cli/scaffold/utils/language.py +138 -0
  231. graph_agents_cli/scaffold/utils/lock_utils.py +94 -0
  232. graph_agents_cli/scaffold/utils/logging.py +77 -0
  233. graph_agents_cli/scaffold/utils/manifest.py +292 -0
  234. graph_agents_cli/scaffold/utils/merge.py +970 -0
  235. graph_agents_cli/scaffold/utils/merge3.py +216 -0
  236. graph_agents_cli/scaffold/utils/openapi_seed.py +199 -0
  237. graph_agents_cli/scaffold/utils/remote_template.py +376 -0
  238. graph_agents_cli/scaffold/utils/template.py +1352 -0
  239. graph_agents_cli/scaffold/utils/upgrade.py +894 -0
  240. graph_agents_cli/scaffold/utils/version.py +438 -0
  241. graph_agents_cli/secrets/__init__.py +15 -0
  242. graph_agents_cli/secrets/_apply.py +954 -0
  243. graph_agents_cli/secrets/_required.py +188 -0
  244. graph_agents_cli/secrets/cmd_secrets.py +211 -0
  245. graph_agents_cli/setup/__init__.py +13 -0
  246. graph_agents_cli/setup/_antigravity.py +221 -0
  247. graph_agents_cli/setup/cmd_auth.py +1030 -0
  248. graph_agents_cli/setup/cmd_dev_token.py +513 -0
  249. graph_agents_cli/setup/cmd_setup.py +428 -0
  250. graph_agents_cli/setup/cmd_update.py +140 -0
  251. graph_agents_cli/skills/__init__.py +13 -0
  252. graph_agents_cli/skills/_bundle.py +65 -0
  253. graph_agents_cli/skills/data/README.md +19 -0
  254. graph_agents_cli/skills/data/graph-agents-cli-deploy/SKILL.md +357 -0
  255. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/github-settings.md +113 -0
  256. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/gitops.md +137 -0
  257. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/kubernetes.md +315 -0
  258. graph_agents_cli/skills/data/graph-agents-cli-deploy/references/secrets.md +160 -0
  259. graph_agents_cli/skills/data/graph-agents-cli-eval/SKILL.md +303 -0
  260. graph_agents_cli/skills/data/graph-agents-cli-eval/references/dataset_schema.md +282 -0
  261. graph_agents_cli/skills/data/graph-agents-cli-eval/references/metrics-guide.md +143 -0
  262. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/SKILL.md +659 -0
  263. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langchain-models.md +124 -0
  264. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langgraph.md +235 -0
  265. graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/template-contract.md +477 -0
  266. graph_agents_cli/skills/data/graph-agents-cli-observability/SKILL.md +231 -0
  267. graph_agents_cli/skills/data/graph-agents-cli-observability/references/langsmith.md +46 -0
  268. graph_agents_cli/skills/data/graph-agents-cli-observability/references/otel.md +59 -0
  269. graph_agents_cli/skills/data/graph-agents-cli-scaffold/SKILL.md +414 -0
  270. graph_agents_cli/skills/data/graph-agents-cli-scaffold/references/flags.md +134 -0
  271. graph_agents_cli/skills/data/graph-agents-cli-workflow/SKILL.md +478 -0
  272. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/brainstorming.md +118 -0
  273. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/commands.md +419 -0
  274. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/extension.md +156 -0
  275. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/internals.md +67 -0
  276. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/spec-template.md +56 -0
  277. graph_agents_cli/skills/data/graph-agents-cli-workflow/references/terminology.md +119 -0
  278. graph_agents_cli/system/__init__.py +15 -0
  279. graph_agents_cli/system/_apply.py +519 -0
  280. graph_agents_cli/system/_checks.py +1023 -0
  281. graph_agents_cli/system/_deploy.py +215 -0
  282. graph_agents_cli/system/_model.py +363 -0
  283. graph_agents_cli/system/_system.py +664 -0
  284. graph_agents_cli/system/_views.py +208 -0
  285. graph_agents_cli/system/cmd_system.py +423 -0
  286. graph_agents_cli-0.3.1.dist-info/METADATA +162 -0
  287. graph_agents_cli-0.3.1.dist-info/RECORD +291 -0
  288. graph_agents_cli-0.3.1.dist-info/WHEEL +4 -0
  289. graph_agents_cli-0.3.1.dist-info/entry_points.txt +2 -0
  290. graph_agents_cli-0.3.1.dist-info/licenses/LICENSE +201 -0
  291. graph_agents_cli-0.3.1.dist-info/licenses/NOTICE +19 -0
@@ -0,0 +1,450 @@
1
+ # Copyright 2026 Google LLC
2
+ # Modifications Copyright 2026 graph-agents-cli contributors
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # https://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # On every push to main: build and push the image tagged with the SHORT commit
17
+ # SHA (${GITHUB_SHA::7}, the same value `git rev-parse --short HEAD` gives a
18
+ # workstation `graph-agents-cli deploy --env <env>` in argocd mode), then land
19
+ # it in staging according to CD in .github/agent.env:
20
+ # argocd: update values-staging.yaml image.tag and open a PR with auto-merge
21
+ # (closing older staging PRs it supersedes); Argo CD rolls it out
22
+ # and its health checks (the readiness probe, /ready) show whether
23
+ # it landed (`graph-agents-cli deploy --env staging --status`).
24
+ # helm-push: run `graph-agents-cli deploy --env staging --image ...` on a
25
+ # self-hosted runner with the kubeconfig of the `staging`
26
+ # environment, then verify the rollout (rollout status, /health
27
+ # and /ready through a port-forward), both in one kube context
28
+ # (environments.staging.context, else the kubeconfig's current one).
29
+ # Pushes that only change the per-environment values files (the image tags
30
+ # this workflow, promote-to-prod and `graph-agents-cli deploy` write in argocd
31
+ # mode) do not start it, so a merged staging PR never triggers another build.
32
+ # Run it by hand (workflow_dispatch, main only) to re-deploy main, e.g. after
33
+ # changing only values-staging.yaml in helm-push mode.
34
+ # This file is copied verbatim into the project (not rendered).
35
+
36
+ name: staging
37
+
38
+ on:
39
+ push:
40
+ branches:
41
+ - main
42
+ paths-ignore:
43
+ - '**.md'
44
+ - 'docs/**'
45
+ - 'deployment/helm/*/values-dev.yaml'
46
+ - 'deployment/helm/*/values-staging.yaml'
47
+ - 'deployment/helm/*/values-prod.yaml'
48
+ workflow_dispatch:
49
+
50
+ concurrency:
51
+ group: staging
52
+ cancel-in-progress: false
53
+
54
+ jobs:
55
+ build:
56
+ runs-on: ubuntu-latest
57
+ # A manual run from another branch would deploy that branch to staging.
58
+ if: github.ref == 'refs/heads/main'
59
+ permissions:
60
+ contents: read
61
+ packages: write
62
+ outputs:
63
+ cd: ${{ steps.settings.outputs.cd }}
64
+ tag: ${{ steps.settings.outputs.tag }}
65
+ image: ${{ steps.settings.outputs.image }}
66
+ chart_path: ${{ steps.settings.outputs.chart_path }}
67
+ release: ${{ steps.settings.outputs.release }}
68
+ namespace: ${{ steps.settings.outputs.namespace }}
69
+ kube_context: ${{ steps.settings.outputs.kube_context }}
70
+ graph_agents_cli_spec: ${{ steps.settings.outputs.graph_agents_cli_spec }}
71
+ steps:
72
+ - name: Checkout code
73
+ uses: actions/checkout@v4
74
+
75
+ - name: Load project settings
76
+ run: |
77
+ # .github/agent.env is data and is never sourced: each NAME=VALUE line is
78
+ # checked and copied to GITHUB_ENV, so a value may hold spaces or shell
79
+ # metacharacters (a PEP 508 install spec, for example). Only the settings
80
+ # listed in `known` are accepted: any other name (BASH_ENV, SHELLOPTS, PS4,
81
+ # PATH, PYTHONPATH, ...) could change how later steps run. To add a setting,
82
+ # extend `known` in all three workflows. Comment and blank lines are skipped;
83
+ # blanks around the value, one pair of quotes around it and a trailing
84
+ # " # comment" are dropped (no escapes, no expansion). Nothing reaches
85
+ # GITHUB_ENV unless the whole file is valid.
86
+ file=.github/agent.env
87
+ known="IMAGE_REPOSITORY RELEASE_NAME CHART_PATH RUNTIME CD GRAPH_AGENTS_CLI_SPEC"
88
+ if [ ! -f "$file" ]; then
89
+ echo "::error file=$file::$file is missing: it holds the project settings these workflows read." >&2
90
+ exit 1
91
+ fi
92
+ lineno=0
93
+ seen=" "
94
+ settings=()
95
+ while IFS= read -r line || [ -n "$line" ]; do
96
+ lineno=$((lineno + 1))
97
+ line="${line%$'\r'}"
98
+ if [ "$lineno" -eq 1 ]; then
99
+ line="${line#$'\xef\xbb\xbf'}"
100
+ fi
101
+ if [[ "$line" =~ ^[[:space:]]*(#|$) ]]; then
102
+ continue
103
+ fi
104
+ if ! [[ "$line" =~ ^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)[[:space:]]*=(.*)$ ]]; then
105
+ echo "::error file=$file,line=$lineno::expected NAME=VALUE, got: $line" >&2
106
+ exit 1
107
+ fi
108
+ name="${BASH_REMATCH[1]}"
109
+ value="${BASH_REMATCH[2]}"
110
+ case " $known " in
111
+ *" $name "*) ;;
112
+ *)
113
+ hint=""
114
+ if [ "$name" = CLI_VERSION_PIN ]; then
115
+ hint=" (replaced by GRAPH_AGENTS_CLI_SPEC=<install spec>)"
116
+ fi
117
+ echo "::error file=$file,line=$lineno::$name is not a setting these workflows read${hint}; known: $known." >&2
118
+ exit 1
119
+ ;;
120
+ esac
121
+ case "$seen" in
122
+ *" $name "*)
123
+ echo "::error file=$file,line=$lineno::$name is set twice." >&2
124
+ exit 1
125
+ ;;
126
+ esac
127
+ seen="$seen$name "
128
+ value="${value#"${value%%[![:space:]]*}"}"
129
+ quote="${value:0:1}"
130
+ if [ "$quote" = '"' ] || [ "$quote" = "'" ]; then
131
+ rest="${value:1}"
132
+ if [[ "$rest" != *"$quote"* ]]; then
133
+ echo "::error file=$file,line=$lineno::$name: unterminated $quote quote." >&2
134
+ exit 1
135
+ fi
136
+ value="${rest%%"$quote"*}"
137
+ else
138
+ value="${value%%[[:space:]]#*}"
139
+ value="${value%"${value##*[![:space:]]}"}"
140
+ fi
141
+ if [[ "$value" == *[[:cntrl:]]* ]]; then
142
+ echo "::error file=$file,line=$lineno::$name: control characters are not allowed in a value." >&2
143
+ exit 1
144
+ fi
145
+ settings+=("$name=$value")
146
+ done < "$file"
147
+ if [ "${#settings[@]}" -gt 0 ]; then
148
+ printf '%s\n' "${settings[@]}" >> "$GITHUB_ENV"
149
+ fi
150
+
151
+ - name: Resolve the image and the target
152
+ id: settings
153
+ run: |
154
+ for var in IMAGE_REPOSITORY RELEASE_NAME CHART_PATH CD GRAPH_AGENTS_CLI_SPEC; do
155
+ if [ -z "${!var:-}" ]; then
156
+ echo "::error file=.github/agent.env::$var is not set in .github/agent.env." >&2
157
+ exit 1
158
+ fi
159
+ done
160
+ if [ "$CD" != argocd ] && [ "$CD" != helm-push ]; then
161
+ echo "::error file=.github/agent.env::CD must be argocd or helm-push for this workflow, got '$CD'." >&2
162
+ exit 1
163
+ fi
164
+ if [[ "$IMAGE_REPOSITORY" == *CHANGE-ME* ]] || ! [[ "$IMAGE_REPOSITORY" =~ ^[A-Za-z0-9.-]+(:[0-9]+)?(/[a-z0-9._-]+)+$ ]]; then
165
+ echo "::error file=.github/agent.env::IMAGE_REPOSITORY must be <registry>/<path> in lowercase with no placeholder, got '$IMAGE_REPOSITORY'." >&2
166
+ exit 1
167
+ fi
168
+ TAG="${GITHUB_SHA::7}"
169
+ manifest=graph-agents-cli-manifest.yaml
170
+ NAMESPACE="$(yq -r '.environments.staging.namespace // ""' "$manifest")"
171
+ if [ -z "$NAMESPACE" ]; then
172
+ NAMESPACE="$(yq -r '.name // ""' "$manifest")-staging"
173
+ fi
174
+ if ! [[ "$NAMESPACE" =~ ^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$ ]]; then
175
+ echo "::error file=$manifest::Invalid staging namespace '$NAMESPACE'." >&2
176
+ exit 1
177
+ fi
178
+ # The kube context `deploy` uses; empty = the kubeconfig's current one.
179
+ KUBE_CONTEXT="$(yq -r '.environments.staging.context // ""' "$manifest")"
180
+ if [ -n "$KUBE_CONTEXT" ] && { ! [[ "$KUBE_CONTEXT" =~ ^[[:graph:]]+$ ]] || [[ "$KUBE_CONTEXT" == -* ]]; }; then
181
+ echo "::error file=$manifest::Invalid staging kube context '$KUBE_CONTEXT'." >&2
182
+ exit 1
183
+ fi
184
+ if ! [[ "$RELEASE_NAME" =~ ^[a-z0-9]([-a-z0-9]{0,51}[a-z0-9])?$ ]]; then
185
+ echo "::error file=.github/agent.env::Invalid RELEASE_NAME '$RELEASE_NAME'." >&2
186
+ exit 1
187
+ fi
188
+ {
189
+ echo "cd=${CD}"
190
+ echo "tag=${TAG}"
191
+ echo "image=${IMAGE_REPOSITORY}:${TAG}"
192
+ echo "chart_path=${CHART_PATH}"
193
+ echo "release=${RELEASE_NAME}"
194
+ echo "namespace=${NAMESPACE}"
195
+ echo "kube_context=${KUBE_CONTEXT}"
196
+ echo "graph_agents_cli_spec=${GRAPH_AGENTS_CLI_SPEC}"
197
+ } >> "$GITHUB_OUTPUT"
198
+ echo "REGISTRY_HOST=${IMAGE_REPOSITORY%%/*}" >> "$GITHUB_ENV"
199
+ echo "IMAGE=${IMAGE_REPOSITORY}:${TAG}" >> "$GITHUB_ENV"
200
+
201
+ - name: Set up Docker Buildx
202
+ uses: docker/setup-buildx-action@v3
203
+
204
+ - name: Log in to the registry
205
+ # GHCR works with the workflow token; other registries take REGISTRY_USERNAME / REGISTRY_PASSWORD secrets.
206
+ uses: docker/login-action@v3
207
+ with:
208
+ registry: ${{ env.REGISTRY_HOST }}
209
+ username: ${{ secrets.REGISTRY_USERNAME || github.actor }}
210
+ password: ${{ secrets.REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
211
+
212
+ - name: Build and push
213
+ uses: docker/build-push-action@v6
214
+ with:
215
+ context: .
216
+ file: Dockerfile
217
+ push: true
218
+ tags: ${{ env.IMAGE }}
219
+ cache-from: type=gha
220
+ cache-to: type=gha,mode=max
221
+
222
+ land_argocd:
223
+ # Pull-based: write the desired state and let Argo CD reconcile from main.
224
+ needs: build
225
+ if: needs.build.outputs.cd == 'argocd'
226
+ runs-on: ubuntu-latest
227
+ permissions:
228
+ contents: write
229
+ pull-requests: write
230
+ env:
231
+ # A pull request opened with the workflow token does not trigger pr_checks
232
+ # (GitHub never starts workflows from GITHUB_TOKEN events), so auto-merge
233
+ # would wait forever on a required check. Store a fine-grained PAT or a
234
+ # GitHub App token as the GH_PR_TOKEN repository secret to lift that limit.
235
+ # The merge it enables is a push to main that changes only
236
+ # values-staging.yaml, which paths-ignore above keeps from re-running this
237
+ # workflow.
238
+ GH_TOKEN: ${{ secrets.GH_PR_TOKEN || secrets.GITHUB_TOKEN }}
239
+ TAG: ${{ needs.build.outputs.tag }}
240
+ IMAGE: ${{ needs.build.outputs.image }}
241
+ CHART_PATH: ${{ needs.build.outputs.chart_path }}
242
+ steps:
243
+ - name: Checkout code
244
+ uses: actions/checkout@v4
245
+ with:
246
+ # Full history: the next step orders staging builds by commit ancestry.
247
+ fetch-depth: 0
248
+ # Branch pushes with the PR token too, so a regenerated branch re-runs
249
+ # pr_checks (a push made with the workflow token starts no workflow).
250
+ token: ${{ secrets.GH_PR_TOKEN || secrets.GITHUB_TOKEN }}
251
+
252
+ - name: Open the staging PR with auto-merge
253
+ # Same branch name as a workstation `graph-agents-cli deploy --env staging`
254
+ # (deploy/<env>/<short sha>). Requires branch protection on main to permit
255
+ # auto-merge for the token and pr_checks to be green.
256
+ # Every staging PR edits the same line, so two quick pushes would leave
257
+ # the second PR conflicting once the first merged. Instead each run
258
+ # closes the older staging PRs still open (staging only needs the newest
259
+ # build), then builds its branch on the latest main, and does nothing
260
+ # when main, or an open PR, already carries this build or a newer one:
261
+ # a re-run of an older build never moves staging back. The branch is
262
+ # bot-owned, so a re-run replaces it (the PR is created only when none
263
+ # is open).
264
+ run: |
265
+ values="${CHART_PATH}/values-staging.yaml"
266
+ BRANCH="deploy/staging/${TAG}"
267
+ git config user.name "github-actions[bot]"
268
+ git config user.email "github-actions[bot]@users.noreply.github.com"
269
+
270
+ # True when commit $1 is an older ancestor of commit $2 (both known here).
271
+ older() {
272
+ local a b
273
+ a="$(git rev-parse --verify --quiet "${1}^{commit}")" || return 1
274
+ b="$(git rev-parse --verify --quiet "${2}^{commit}")" || return 1
275
+ [ "$a" != "$b" ] && git merge-base --is-ancestor "$a" "$b"
276
+ }
277
+ # Put the branch on the latest main; stop when main already deploys
278
+ # this build or a newer one.
279
+ sync_with_main() {
280
+ git fetch --quiet --no-tags origin +refs/heads/main:refs/remotes/origin/main
281
+ git checkout --quiet -B "$BRANCH" refs/remotes/origin/main
282
+ current="$(yq -r '.image.tag // ""' "$values")"
283
+ if [ "$current" = "$TAG" ]; then
284
+ echo "values-staging.yaml on main already deploys ${IMAGE}; nothing to open."
285
+ exit 0
286
+ fi
287
+ if [ -n "$current" ] && older "$GITHUB_SHA" "$current"; then
288
+ echo "main already deploys a newer build (${current}) to staging; nothing to open."
289
+ exit 0
290
+ fi
291
+ }
292
+
293
+ sync_with_main
294
+ open_prs="$(gh pr list --base main --state open --limit 200 --json number,headRefName --jq '.[] | "\(.number) \(.headRefName)"')"
295
+ while read -r number head; do
296
+ case "$head" in
297
+ deploy/staging/*) ;;
298
+ *) continue ;;
299
+ esac
300
+ if [ "$head" = "$BRANCH" ]; then
301
+ continue
302
+ fi
303
+ other="${head#deploy/staging/}"
304
+ if older "$GITHUB_SHA" "$other"; then
305
+ echo "A newer staging build is pending (#${number}, ${head}); nothing to open."
306
+ exit 0
307
+ fi
308
+ # A branch this step cannot order (a workstation tag) is left alone.
309
+ if older "$other" "$GITHUB_SHA"; then
310
+ gh pr close "$number" --delete-branch --comment "Superseded by ${IMAGE} (${BRANCH})." \
311
+ || echo "::warning::Could not close the superseded staging PR #${number} (${head})."
312
+ fi
313
+ done <<< "$open_prs"
314
+ # Whatever merged before those PRs closed is on main now.
315
+ sync_with_main
316
+ yq -i '.image.tag = strenv(TAG) | .image.tag style="double"' "$values"
317
+ git add "$values"
318
+ git commit --quiet -m "deploy(staging): image ${IMAGE}"
319
+ git push --force origin "$BRANCH"
320
+ if [ -z "$(gh pr list --head "$BRANCH" --base main --state open --json number --jq '.[].number')" ]; then
321
+ gh pr create --base main --head "$BRANCH" \
322
+ --title "deploy(staging): ${TAG}" \
323
+ --body "Automated staging promotion of ${IMAGE}. Merges automatically once pr_checks passes."
324
+ fi
325
+ # --auto merges directly when already mergeable and is a no-op once merged;
326
+ # an "already enabled" rejection of the enable mutation is a success too.
327
+ gh pr merge --auto --squash "$BRANCH" \
328
+ || [ -n "$(gh pr view "$BRANCH" --json autoMergeRequest --jq '.autoMergeRequest.enabledAt // empty')" ]
329
+
330
+ deploy_helm_push:
331
+ # Push-based: a self-hosted runner inside the network runs helm through the
332
+ # CLI (helm and kubectl on its PATH). The cluster credentials are the
333
+ # DEPLOY_KUBECONFIG secret of the `staging` environment: an environment
334
+ # secret, never a repository secret, so only jobs that run in that
335
+ # environment (main only, per its deployment-branch rule) can read it.
336
+ needs: build
337
+ if: needs.build.outputs.cd == 'helm-push'
338
+ runs-on: self-hosted
339
+ environment: staging
340
+ permissions:
341
+ contents: read
342
+ env:
343
+ GRAPH_AGENTS_CLI_NO_UPDATE_CHECK: "1"
344
+ # The CLI's own `deploy`: no extension (committed, or installed on the
345
+ # runner) can replace it while it holds the cluster credentials.
346
+ GRAPH_AGENTS_CLI_DISABLE_OVERRIDES: "1"
347
+ IMAGE: ${{ needs.build.outputs.image }}
348
+ RELEASE: ${{ needs.build.outputs.release }}
349
+ NAMESPACE: ${{ needs.build.outputs.namespace }}
350
+ MANIFEST_CONTEXT: ${{ needs.build.outputs.kube_context }}
351
+ GRAPH_AGENTS_CLI_SPEC: ${{ needs.build.outputs.graph_agents_cli_spec }}
352
+ steps:
353
+ - name: Checkout code
354
+ uses: actions/checkout@v4
355
+
356
+ - name: Install uv
357
+ uses: astral-sh/setup-uv@v6
358
+ with:
359
+ python-version: "3.12"
360
+
361
+ - name: Configure kubeconfig
362
+ # Written to the job's temporary directory (owner-only) and removed by
363
+ # the last step, whatever happens: nothing is left on the runner.
364
+ env:
365
+ DEPLOY_KUBECONFIG: ${{ secrets.DEPLOY_KUBECONFIG }}
366
+ run: |
367
+ if [ -z "$DEPLOY_KUBECONFIG" ]; then
368
+ echo "::error::DEPLOY_KUBECONFIG is empty: store the cluster credentials as the DEPLOY_KUBECONFIG secret of the staging environment (Settings > Environments > staging)." >&2
369
+ exit 1
370
+ fi
371
+ umask 077
372
+ printf '%s\n' "$DEPLOY_KUBECONFIG" > "$RUNNER_TEMP/kubeconfig"
373
+ echo "KUBECONFIG=$RUNNER_TEMP/kubeconfig" >> "$GITHUB_ENV"
374
+
375
+ - name: Resolve the kube context
376
+ # One context for the deploy and the checks after it, passed to both:
377
+ # the manifest's environments.staging.context when set, else the current
378
+ # context of DEPLOY_KUBECONFIG (what `deploy` itself would pick).
379
+ run: |
380
+ if ! command -v kubectl >/dev/null 2>&1; then
381
+ echo "::error::kubectl is not on the runner's PATH; the deploy and its checks need it." >&2
382
+ exit 1
383
+ fi
384
+ context="${MANIFEST_CONTEXT:-}"
385
+ if [ -z "$context" ]; then
386
+ context="$(kubectl config current-context 2>/dev/null || true)"
387
+ fi
388
+ if [ -z "$context" ]; then
389
+ echo "::error::No kube context: set environments.staging.context in graph-agents-cli-manifest.yaml or a current-context in DEPLOY_KUBECONFIG." >&2
390
+ exit 1
391
+ fi
392
+ if ! [[ "$context" =~ ^[[:graph:]]+$ ]] || [[ "$context" == -* ]]; then
393
+ echo "::error::Invalid kube context name '$context'." >&2
394
+ exit 1
395
+ fi
396
+ if ! kubectl config get-contexts "$context" >/dev/null 2>&1; then
397
+ echo "::error::Kube context '$context' is not in the DEPLOY_KUBECONFIG of the staging environment." >&2
398
+ exit 1
399
+ fi
400
+ echo "Kube context: $context"
401
+ echo "KUBE_CONTEXT=$context" >> "$GITHUB_ENV"
402
+
403
+ - name: Deploy to staging
404
+ # `deploy --image` in helm-push mode runs helm only (the image is already
405
+ # pushed), in the context resolved above; --yes: no prompt.
406
+ run: |
407
+ uvx --from "$GRAPH_AGENTS_CLI_SPEC" graph-agents-cli deploy --env staging --image "$IMAGE" --context "$KUBE_CONTEXT" --yes
408
+
409
+ - name: Verify the rollout
410
+ run: |
411
+ : "${NAMESPACE:?the build job resolved no namespace}" "${RELEASE:?the build job resolved no release}"
412
+ : "${KUBE_CONTEXT:?no kube context was resolved}"
413
+ # The cluster `deploy` just used (the same context).
414
+ kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" rollout status "deployment/$RELEASE" --timeout=300s
415
+ log="$RUNNER_TEMP/port-forward.log"
416
+ kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" port-forward "service/$RELEASE" :http > "$log" 2>&1 &
417
+ forward=$!
418
+ trap 'kill "$forward" 2>/dev/null || true' EXIT
419
+ port=""
420
+ for _ in $(seq 1 30); do
421
+ port="$(sed -n 's/^Forwarding from 127\.0\.0\.1:\([0-9][0-9]*\) .*/\1/p' "$log" | head -n 1)"
422
+ if [ -n "$port" ] || ! kill -0 "$forward" 2>/dev/null; then
423
+ break
424
+ fi
425
+ sleep 1
426
+ done
427
+ if [ -z "$port" ]; then
428
+ echo "::error::kubectl port-forward to service/$RELEASE failed: $(cat "$log")" >&2
429
+ exit 1
430
+ fi
431
+ for path in /health /ready; do
432
+ ok=""
433
+ for _ in $(seq 1 10); do
434
+ if curl --fail --silent --show-error --max-time 5 "http://127.0.0.1:${port}${path}"; then
435
+ ok=1
436
+ break
437
+ fi
438
+ sleep 3
439
+ done
440
+ echo
441
+ if [ -z "$ok" ]; then
442
+ echo "::error::${path} did not answer 2xx on the staging deployment ($NAMESPACE/$RELEASE)." >&2
443
+ exit 1
444
+ fi
445
+ done
446
+ echo "staging runs ${IMAGE} and answers /health and /ready."
447
+
448
+ - name: Remove kubeconfig
449
+ if: always()
450
+ run: rm -f "$RUNNER_TEMP/kubeconfig" "$RUNNER_TEMP/port-forward.log"
@@ -0,0 +1,43 @@
1
+ # Argo CD Application for the dev environment.
2
+ # Argo reconciles from main, so nothing reaches the cluster until a PR merges.
3
+ # The chart refuses to render until values-dev.yaml names an image tag
4
+ # (`graph-agents-cli deploy --env dev` opens the PR that sets it): until then
5
+ # Argo CD reports a comparison error and deploys nothing.
6
+ apiVersion: argoproj.io/v1alpha1
7
+ kind: Application
8
+ metadata:
9
+ name: {{cookiecutter.project_name}}-dev
10
+ namespace: argocd
11
+ finalizers:
12
+ - resources-finalizer.argocd.argoproj.io
13
+ spec:
14
+ project: default
15
+ source:
16
+ # CHANGE-ME: the git URL of this repository.
17
+ repoURL: https://github.com/CHANGE-ME/{{cookiecutter.project_name}}.git
18
+ targetRevision: main
19
+ path: deployment/helm/{{cookiecutter.project_name}}
20
+ helm:
21
+ releaseName: {{cookiecutter.project_name}}
22
+ valueFiles:
23
+ - values.yaml
24
+ - values-dev.yaml
25
+ destination:
26
+ server: https://kubernetes.default.svc
27
+ namespace: {{cookiecutter.project_name}}-dev
28
+ # The bundled Postgres's credentials Secret is generated on the first sync
29
+ # (Argo CD renders without cluster access, so every render would otherwise
30
+ # produce a new password the database volume no longer accepts): keep the
31
+ # live values. Only exists when postgresql.enabled (dev by default).
32
+ ignoreDifferences:
33
+ - kind: Secret
34
+ name: {{cookiecutter.project_name}}-postgresql-auth
35
+ jsonPointers:
36
+ - /data
37
+ syncPolicy:
38
+ automated:
39
+ prune: true
40
+ selfHeal: true
41
+ syncOptions:
42
+ - CreateNamespace=true
43
+ - RespectIgnoreDifferences=true
@@ -0,0 +1,41 @@
1
+ # Argo CD Application for the prod environment.
2
+ # Argo reconciles from main, so nothing reaches the cluster until a PR merges.
3
+ # The chart refuses to render until values-prod.yaml names an image tag
4
+ # (promote-to-prod opens the PR that sets it).
5
+ apiVersion: argoproj.io/v1alpha1
6
+ kind: Application
7
+ metadata:
8
+ name: {{cookiecutter.project_name}}-prod
9
+ namespace: argocd
10
+ finalizers:
11
+ - resources-finalizer.argocd.argoproj.io
12
+ spec:
13
+ project: default
14
+ source:
15
+ # CHANGE-ME: the git URL of this repository.
16
+ repoURL: https://github.com/CHANGE-ME/{{cookiecutter.project_name}}.git
17
+ targetRevision: main
18
+ path: deployment/helm/{{cookiecutter.project_name}}
19
+ helm:
20
+ releaseName: {{cookiecutter.project_name}}
21
+ valueFiles:
22
+ - values.yaml
23
+ - values-prod.yaml
24
+ destination:
25
+ server: https://kubernetes.default.svc
26
+ namespace: {{cookiecutter.project_name}}-prod
27
+ # The bundled Postgres's credentials Secret is generated on the first sync
28
+ # (Argo CD renders without cluster access, so every render would otherwise
29
+ # produce a new password the database volume no longer accepts): keep the
30
+ # live values. Only exists when postgresql.enabled (dev by default).
31
+ ignoreDifferences:
32
+ - kind: Secret
33
+ name: {{cookiecutter.project_name}}-postgresql-auth
34
+ jsonPointers:
35
+ - /data
36
+ # Production has NO automated sync (a human syncs it): after the values-prod.yaml
37
+ # PR merges, an operator syncs the application in Argo CD.
38
+ syncPolicy:
39
+ syncOptions:
40
+ - CreateNamespace=true
41
+ - RespectIgnoreDifferences=true
@@ -0,0 +1,43 @@
1
+ # Argo CD Application for the staging environment.
2
+ # Argo reconciles from main, so nothing reaches the cluster until a PR merges.
3
+ # The chart refuses to render until values-staging.yaml names an image tag
4
+ # (the staging workflow opens the PR that sets it): until then Argo CD reports
5
+ # a comparison error and deploys nothing.
6
+ apiVersion: argoproj.io/v1alpha1
7
+ kind: Application
8
+ metadata:
9
+ name: {{cookiecutter.project_name}}-staging
10
+ namespace: argocd
11
+ finalizers:
12
+ - resources-finalizer.argocd.argoproj.io
13
+ spec:
14
+ project: default
15
+ source:
16
+ # CHANGE-ME: the git URL of this repository.
17
+ repoURL: https://github.com/CHANGE-ME/{{cookiecutter.project_name}}.git
18
+ targetRevision: main
19
+ path: deployment/helm/{{cookiecutter.project_name}}
20
+ helm:
21
+ releaseName: {{cookiecutter.project_name}}
22
+ valueFiles:
23
+ - values.yaml
24
+ - values-staging.yaml
25
+ destination:
26
+ server: https://kubernetes.default.svc
27
+ namespace: {{cookiecutter.project_name}}-staging
28
+ # The bundled Postgres's credentials Secret is generated on the first sync
29
+ # (Argo CD renders without cluster access, so every render would otherwise
30
+ # produce a new password the database volume no longer accepts): keep the
31
+ # live values. Only exists when postgresql.enabled (dev by default).
32
+ ignoreDifferences:
33
+ - kind: Secret
34
+ name: {{cookiecutter.project_name}}-postgresql-auth
35
+ jsonPointers:
36
+ - /data
37
+ syncPolicy:
38
+ automated:
39
+ prune: true
40
+ selfHeal: true
41
+ syncOptions:
42
+ - CreateNamespace=true
43
+ - RespectIgnoreDifferences=true
@@ -0,0 +1,14 @@
1
+ .DS_Store
2
+ .git/
3
+ .gitignore
4
+ *.swp
5
+ *.bak
6
+ *.tmp
7
+ *.orig
8
+ *~
9
+ .project
10
+ .idea/
11
+ *.tmproj
12
+ .vscode/
13
+ # Documentation, not part of the packaged chart.
14
+ examples/
@@ -0,0 +1,21 @@
1
+ apiVersion: v2
2
+ name: {{cookiecutter.project_name}}
3
+ description: Helm chart for the {{cookiecutter.project_name}} LangGraph agent (graph-agents-cli)
4
+ type: application
5
+ version: 0.1.0
6
+ appVersion: "0.1.0"
7
+ # Exact versions, so every `helm dependency build` resolves the same charts.
8
+ # Their images are pinned by digest in values.yaml (see the note there on the
9
+ # Bitnami catalogue and how to use another chart or an external database).
10
+ dependencies:
11
+ # Optional in-cluster Postgres for dev (values-dev.yaml enables it). Staging
12
+ # and prod use an external database supplied through the Secret.
13
+ - name: postgresql
14
+ version: "18.11.6"
15
+ repository: oci://registry-1.docker.io/bitnamicharts
16
+ condition: postgresql.enabled
17
+ # Redis is only needed by the langgraph-server runtime.
18
+ - name: redis
19
+ version: "28.2.3"
20
+ repository: oci://registry-1.docker.io/bitnamicharts
21
+ condition: redis.enabled