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,257 @@
1
+ # Copyright 2026 graph-agents-cli contributors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """The build that rendered a project, recorded in its manifest as ``cli_build``.
16
+
17
+ ``cli_version`` cannot tell apart the builds made between two releases, so
18
+ ``create`` also records::
19
+
20
+ cli_build:
21
+ id: 0.2.0+g1a2b3c4 # the build id (``graph-agents-cli --version``)
22
+ commit: 1a2b3c4... # its full commit; null when not built from git
23
+ template_digest: sha256:... # what it renders for the recorded settings; or null
24
+
25
+ ``template_digest`` is a digest of the snapshot ``scaffold upgrade`` renders
26
+ from the manifest's settings (every file except the manifest itself). Two
27
+ builds with the same digest render the same project, so an upgrade between
28
+ them has nothing to do; a different digest means the templates changed and the
29
+ upgrade needs the recorded build as its baseline. It is null when ``create``
30
+ rendered more than that snapshot (a seed ``--api-policy``, a local or remote
31
+ template); the upgrade then relies on the build id alone.
32
+
33
+ ``scaffold upgrade`` and ``scaffold enhance`` rewrite the block after a merge;
34
+ an in-folder re-render keeps it (it does not update the existing files).
35
+ """
36
+
37
+ from __future__ import annotations
38
+
39
+ import hashlib
40
+ import logging
41
+ import os
42
+ import pathlib
43
+ import re
44
+ from collections.abc import Mapping
45
+ from dataclasses import dataclass
46
+ from typing import Any
47
+
48
+ import yaml
49
+
50
+ from graph_agents_cli import _build
51
+
52
+ from .keyedit import EditError, YamlText
53
+
54
+ MANIFEST_FILENAME = "graph-agents-cli-manifest.yaml"
55
+ MANIFEST_KEY = "cli_build"
56
+ DIGEST_PREFIX = "sha256:"
57
+ _DIGEST_RE = re.compile(r"sha256:[0-9a-f]{64}")
58
+ _COMMIT_RE = re.compile(r"[0-9a-f]{40}([0-9a-f]{24})?")
59
+ # Never part of a render; skipped so a stray cache cannot change a digest.
60
+ _SKIPPED_DIRS = frozenset({".git", "__pycache__", ".venv", ".ruff_cache", ".pytest_cache"})
61
+ RECORD_COMMENT = (
62
+ "The build that rendered this project and a digest of it; `scaffold upgrade` reads both"
63
+ )
64
+
65
+
66
+ @dataclass(frozen=True)
67
+ class BuildRecord:
68
+ """The ``cli_build`` block of a manifest."""
69
+
70
+ id: str
71
+ commit: str | None = None
72
+ template_digest: str | None = None
73
+
74
+ @classmethod
75
+ def of(cls, build: _build.BuildInfo, template_digest: str | None) -> BuildRecord:
76
+ return cls(id=build.id, commit=build.commit, template_digest=template_digest)
77
+
78
+ @property
79
+ def dirty(self) -> bool:
80
+ """Built from a tree with uncommitted changes: no commit reproduces it."""
81
+ return self.id.endswith(".dirty")
82
+
83
+ @property
84
+ def is_release(self) -> bool:
85
+ """A release build: its id is the bare version and its commit is known."""
86
+ return self.commit is not None and "+" not in self.id
87
+
88
+ def same_build_as(self, build: _build.BuildInfo) -> bool:
89
+ """True when this is exactly ``build``: the same id and commit, both without local changes."""
90
+ return (
91
+ self.id == build.id
92
+ and self.commit is not None
93
+ and self.commit == build.commit
94
+ and not self.dirty
95
+ and not build.dirty
96
+ )
97
+
98
+ def as_manifest(self) -> dict[str, Any]:
99
+ return {"id": self.id, "commit": self.commit, "template_digest": self.template_digest}
100
+
101
+
102
+ def running_build() -> _build.BuildInfo:
103
+ """The running build, with the version the scaffold engine records.
104
+
105
+ ``cli_version`` comes from ``version.get_current_version`` (tests change
106
+ it); the commit facts from :func:`graph_agents_cli._build.current_build`.
107
+ """
108
+ from . import version as version_module
109
+
110
+ facts = _build.current_build()
111
+ return _build.BuildInfo(
112
+ version=version_module.get_current_version(),
113
+ commit=facts.commit,
114
+ dirty=facts.dirty,
115
+ release=facts.release,
116
+ )
117
+
118
+
119
+ class MalformedRecordError(ValueError):
120
+ """``cli_build`` is present but not a valid record."""
121
+
122
+
123
+ def parse_build_record(raw: Any) -> BuildRecord | None:
124
+ """The record in a manifest's ``cli_build`` value; None when absent.
125
+
126
+ Raises :class:`MalformedRecordError` for a value that is not a valid record,
127
+ so a hand-edited block is reported instead of being trusted.
128
+ """
129
+ if raw is None:
130
+ return None
131
+ if not isinstance(raw, Mapping):
132
+ raise MalformedRecordError(f"{MANIFEST_KEY} is not a mapping")
133
+ build_id = raw.get("id")
134
+ if not isinstance(build_id, str) or not build_id.strip() or any(c.isspace() for c in build_id):
135
+ raise MalformedRecordError(f"{MANIFEST_KEY}.id is not a build id")
136
+ commit = raw.get("commit")
137
+ if commit is not None and (not isinstance(commit, str) or not _COMMIT_RE.fullmatch(commit)):
138
+ raise MalformedRecordError(f"{MANIFEST_KEY}.commit is not a full git commit")
139
+ digest = raw.get("template_digest")
140
+ if digest is not None and (not isinstance(digest, str) or not _DIGEST_RE.fullmatch(digest)):
141
+ raise MalformedRecordError(f"{MANIFEST_KEY}.template_digest is not a sha256 digest")
142
+ return BuildRecord(id=build_id, commit=commit, template_digest=digest)
143
+
144
+
145
+ def recorded_build_for(config: Any) -> BuildRecord | None:
146
+ """The build a project's manifest records, when it belongs to its ``cli_version``.
147
+
148
+ ``config`` is a ``ProjectConfig``. A record of another version than
149
+ ``cli_version`` (the version was edited by hand, or the block copied from
150
+ another project) cannot describe the project: :class:`MalformedRecordError`
151
+ says so, and the caller falls back to the version.
152
+ """
153
+ record = parse_build_record(config.cli_build)
154
+ if record is not None and record.id.split("+", 1)[0] != config.cli_version:
155
+ raise MalformedRecordError(
156
+ f"{MANIFEST_KEY}.id {record.id!r} is not a build of cli_version {config.cli_version!r}"
157
+ )
158
+ return record
159
+
160
+
161
+ def read_manifest_data(project_dir: pathlib.Path) -> dict[str, Any]:
162
+ """The project's manifest as a mapping ({} when missing or unreadable)."""
163
+ try:
164
+ with open(project_dir / MANIFEST_FILENAME, encoding="utf-8") as f:
165
+ data = yaml.safe_load(f)
166
+ except (OSError, yaml.YAMLError):
167
+ return {}
168
+ return data if isinstance(data, dict) else {}
169
+
170
+
171
+ def read_build_record(project_dir: pathlib.Path) -> BuildRecord | None:
172
+ """The project's recorded build (None when absent; raises when malformed)."""
173
+ return parse_build_record(read_manifest_data(project_dir).get(MANIFEST_KEY))
174
+
175
+
176
+ def template_digest(tree: pathlib.Path) -> str:
177
+ """A digest of every file of a rendered tree except its manifest.
178
+
179
+ Paths and contents both count (a renamed file changes it); caches and
180
+ ``.git`` are skipped. Symbolic links count by their target.
181
+ """
182
+ entries: list[tuple[str, bytes]] = []
183
+ for dirpath, dirnames, filenames in os.walk(tree):
184
+ dirnames[:] = sorted(d for d in dirnames if d not in _SKIPPED_DIRS)
185
+ for name in filenames:
186
+ path = pathlib.Path(dirpath) / name
187
+ relative = path.relative_to(tree).as_posix()
188
+ if relative == MANIFEST_FILENAME:
189
+ continue
190
+ if path.is_symlink():
191
+ content = b"link:" + os.readlink(path).encode("utf-8", "surrogateescape")
192
+ elif path.is_file():
193
+ content = hashlib.sha256(path.read_bytes()).digest()
194
+ else:
195
+ continue
196
+ entries.append((relative, content))
197
+ digest = hashlib.sha256()
198
+ for relative, content in sorted(entries):
199
+ digest.update(relative.encode("utf-8", "surrogateescape") + b"\0")
200
+ digest.update(content + b"\0")
201
+ return DIGEST_PREFIX + digest.hexdigest()
202
+
203
+
204
+ def write_build_record(project_dir: pathlib.Path, record: BuildRecord | None) -> None:
205
+ """Set (or, with None, remove) ``cli_build`` in the project's manifest.
206
+
207
+ The text is edited in place, keeping comments and key order; a manifest the
208
+ edit cannot handle safely is rewritten through the YAML library instead. A
209
+ manifest that cannot be read or written is logged and skipped (callers
210
+ record the build as a side effect of work that already succeeded).
211
+ """
212
+ path = project_dir / MANIFEST_FILENAME
213
+ try:
214
+ text = path.read_text(encoding="utf-8")
215
+ except OSError as e:
216
+ logging.warning("Could not read %s to record the CLI build: %s", path, e)
217
+ return
218
+ try:
219
+ editor = YamlText(text)
220
+ if record is None:
221
+ if MANIFEST_KEY not in editor.data:
222
+ return
223
+ editor.delete((MANIFEST_KEY,))
224
+ # The comment this module wrote above the block goes with it.
225
+ editor.text = editor.text.replace(f"# {RECORD_COMMENT}\n", "", 1)
226
+ else:
227
+ editor.set(
228
+ (MANIFEST_KEY,),
229
+ record.as_manifest(),
230
+ after="cli_version",
231
+ comment=RECORD_COMMENT,
232
+ block=True,
233
+ )
234
+ new_text = editor.text
235
+ except EditError as e:
236
+ logging.debug("Rewriting %s without its comments: %s", path, e)
237
+ try:
238
+ data = yaml.safe_load(text) or {}
239
+ except yaml.YAMLError as load_error:
240
+ logging.warning(
241
+ "%s is not valid YAML; the CLI build was not recorded: %s", path, load_error
242
+ )
243
+ return
244
+ if not isinstance(data, dict):
245
+ logging.warning("%s is not a mapping; the CLI build was not recorded", path)
246
+ return
247
+ if record is None:
248
+ data.pop(MANIFEST_KEY, None)
249
+ else:
250
+ data[MANIFEST_KEY] = record.as_manifest()
251
+ new_text = yaml.safe_dump(data, default_flow_style=False, sort_keys=False)
252
+ if new_text == text:
253
+ return
254
+ try:
255
+ path.write_text(new_text, encoding="utf-8")
256
+ except OSError as e:
257
+ logging.warning("Could not record the CLI build in %s: %s", path, e)
@@ -0,0 +1,184 @@
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
+ """Shared Click options for ``create`` and ``scaffold enhance``."""
17
+
18
+ from collections.abc import Callable
19
+ from typing import Any
20
+
21
+ import click
22
+
23
+ from graph_agents_cli._defaults import (
24
+ AUTH_POLICIES,
25
+ CD_MODES,
26
+ CHECKPOINTERS,
27
+ DEFAULT_AGENT_GUIDANCE_FILENAME,
28
+ DEPLOYMENT_TARGETS,
29
+ LEGACY_AUTH_POLICY_ALIASES,
30
+ MODEL_PROVIDERS,
31
+ RUNTIMES,
32
+ )
33
+
34
+
35
+ class AuthPolicyChoice(click.Choice):
36
+ """``--auth-policy`` choices; a retired name is refused with a hint to its new name."""
37
+
38
+ def convert(self, value: Any, param: click.Parameter | None, ctx: click.Context | None) -> Any:
39
+ renamed = LEGACY_AUTH_POLICY_ALIASES.get(str(value).strip().lower())
40
+ if renamed:
41
+ self.fail(
42
+ f"'{value}' was renamed to '{renamed}'; use --auth-policy {renamed}.", param, ctx
43
+ )
44
+ return super().convert(value, param, ctx)
45
+
46
+
47
+ def _refuse_product_policy(ctx: click.Context, param: click.Parameter, value: Any) -> None:
48
+ """``--product-policy`` is the retired name of ``--api-policy``."""
49
+ if value is not None:
50
+ raise click.UsageError(
51
+ "--product-policy was renamed to --api-policy, and the file format changed "
52
+ "(api-policy.yaml declares apis: <name>: ... with required allowed_methods).",
53
+ ctx=ctx,
54
+ )
55
+
56
+
57
+ def shared_template_options(f: Callable) -> Callable:
58
+ """Decorator adding the options shared by template-based commands."""
59
+ # Apply options in reverse order since decorators are applied bottom-up
60
+ f = click.option("--debug", is_flag=True, help="Enable debug logging")(f)
61
+ f = click.option(
62
+ "--skip-deps",
63
+ is_flag=True,
64
+ help="Skip base template dependency installation (used when reusing saved config)",
65
+ default=False,
66
+ hidden=True,
67
+ )(f)
68
+ f = click.option(
69
+ "-s",
70
+ "--skip-checks",
71
+ is_flag=True,
72
+ help="Skip preflight checks (uv on PATH)",
73
+ default=False,
74
+ )(f)
75
+ f = click.option(
76
+ "--auto-approve",
77
+ "--yes",
78
+ "-y",
79
+ is_flag=True,
80
+ default=False,
81
+ help="Non-interactive: skip prompts and use defaults",
82
+ )(f)
83
+ f = click.option(
84
+ "--interactive",
85
+ "-i",
86
+ is_flag=True,
87
+ default=False,
88
+ help="Enable interactive prompts for human use",
89
+ )(f)
90
+ f = click.option(
91
+ "--base-template",
92
+ "-bt",
93
+ help="Base template to use (overrides template default, only for remote templates)",
94
+ )(f)
95
+ f = click.option(
96
+ "--agent-guidance-filename",
97
+ default=DEFAULT_AGENT_GUIDANCE_FILENAME,
98
+ show_default=True,
99
+ help="Filename for agent guidance (e.g. AGENTS.md, CLAUDE.md, GEMINI.md)",
100
+ )(f)
101
+ f = click.option(
102
+ "--agent-directory",
103
+ "-dir",
104
+ help="Name of the agent directory (overrides template default)",
105
+ )(f)
106
+ f = click.option(
107
+ "--prototype",
108
+ "-p",
109
+ is_flag=True,
110
+ help=(
111
+ "Minimal project: deployment target defaults to 'none' unless given, "
112
+ "CD is forced to 'skip'"
113
+ ),
114
+ default=False,
115
+ )(f)
116
+ f = click.option(
117
+ "--process",
118
+ "process",
119
+ help=(
120
+ "Governing process document (path or string) recorded as process: in the "
121
+ "manifest and rendered into the guidance file"
122
+ ),
123
+ )(f)
124
+ f = click.option(
125
+ "--product-policy",
126
+ hidden=True,
127
+ expose_value=False,
128
+ is_eager=True,
129
+ callback=_refuse_product_policy,
130
+ help="Renamed to --api-policy",
131
+ )(f)
132
+ f = click.option(
133
+ "--api-policy",
134
+ "api_policy",
135
+ type=click.Path(exists=True, dir_okay=False, resolve_path=True),
136
+ help=(
137
+ "Seed api-policy.yaml (the outbound APIs tools may call, and how) from this file; "
138
+ "validated before the project is created"
139
+ ),
140
+ )(f)
141
+ f = click.option(
142
+ "--auth-policy",
143
+ type=AuthPolicyChoice(list(AUTH_POLICIES)),
144
+ help=(
145
+ "Authentication policy (default: shared-bearer). jwt verifies per-user OIDC "
146
+ "tokens; custom is a fail-closed stub the project implements"
147
+ ),
148
+ )(f)
149
+ f = click.option(
150
+ "--cd",
151
+ "cd",
152
+ type=click.Choice(list(CD_MODES)),
153
+ help="Continuous delivery mode (default: skip; requires --deployment-target kubernetes)",
154
+ )(f)
155
+ f = click.option(
156
+ "--registry",
157
+ help="Container registry <url/org> (default: ghcr.io/<git origin owner>)",
158
+ )(f)
159
+ f = click.option(
160
+ "--deployment-target",
161
+ "-d",
162
+ type=click.Choice(list(DEPLOYMENT_TARGETS)),
163
+ help="Deployment target (default: kubernetes)",
164
+ )(f)
165
+ f = click.option(
166
+ "--checkpointer",
167
+ type=click.Choice(list(CHECKPOINTERS)),
168
+ help="Deployed checkpointer (default: postgres for kubernetes, memory for none)",
169
+ )(f)
170
+ f = click.option(
171
+ "--model",
172
+ help="Model name (default: the provider's default model)",
173
+ )(f)
174
+ f = click.option(
175
+ "--model-provider",
176
+ type=click.Choice(list(MODEL_PROVIDERS)),
177
+ help="Model provider (default: openai; prompted in interactive mode)",
178
+ )(f)
179
+ f = click.option(
180
+ "--runtime",
181
+ type=click.Choice(list(RUNTIMES)),
182
+ help="Application runtime (default: fastapi)",
183
+ )(f)
184
+ return f
@@ -0,0 +1,83 @@
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
+ """Shared filesystem helpers for copying project directories."""
17
+
18
+ import fnmatch
19
+
20
+ # Directories/files to exclude when copying a project tree (backups, local
21
+ # template copies, etc.).
22
+ STANDARD_IGNORE_PATTERNS = frozenset(
23
+ {
24
+ ".git",
25
+ ".venv",
26
+ "venv",
27
+ "__pycache__",
28
+ ".pytest_cache",
29
+ ".ruff_cache",
30
+ "node_modules",
31
+ ".next",
32
+ "dist",
33
+ "build",
34
+ ".DS_Store",
35
+ ".vscode",
36
+ ".idea",
37
+ "*.egg-info",
38
+ ".mypy_cache",
39
+ ".ty",
40
+ ".coverage",
41
+ "htmlcov",
42
+ ".tox",
43
+ ".cache",
44
+ # The CLI's run state in a project (pid file, artifacts): rebuilt on demand.
45
+ ".graph-agents-cli",
46
+ # `langgraph dev` local state.
47
+ ".langgraph_api",
48
+ }
49
+ )
50
+
51
+
52
+ def standard_ignore_patterns(dir: str, files: list[str]) -> list[str]:
53
+ """Return the entries in ``files`` to skip when copying a project tree.
54
+
55
+ Matches the signature expected by ``shutil.copytree(ignore=...)``.
56
+ """
57
+ return _matching(files, STANDARD_IGNORE_PATTERNS)
58
+
59
+
60
+ # Credentials, dropped on top of the standard patterns when a tree is copied
61
+ # *into another project* rather than kept for its owner. Deliberately not part
62
+ # of the set above: `create_project_backup` is the undo for `enhance` and
63
+ # `upgrade`, both of which merge `.env` from the template, and a generated
64
+ # project gitignores it, so the backup holds the only copy the user has.
65
+ SECRET_IGNORE_PATTERNS = frozenset({".env", ".env.*"})
66
+
67
+ # `.env.*` would otherwise take the documentation along with the secret. These
68
+ # hold no values, and a source that ships one means it to be read.
69
+ ENV_TEMPLATE_NAMES = frozenset({".env.example", ".env.sample", ".env.template"})
70
+
71
+
72
+ def source_ignore_patterns(dir: str, files: list[str]) -> set[str]:
73
+ """Return the entries in ``files`` to skip when copying a source tree.
74
+
75
+ A source is published into somebody else's project (an extension being
76
+ vendored, say), so it leaves behind the standard junk and its credentials.
77
+ """
78
+ patterns = STANDARD_IGNORE_PATTERNS | SECRET_IGNORE_PATTERNS
79
+ return set(_matching(files, patterns)) - ENV_TEMPLATE_NAMES
80
+
81
+
82
+ def _matching(files: list[str], patterns: frozenset[str]) -> list[str]:
83
+ return [f for f in files if any(fnmatch.fnmatch(f, p) for p in patterns)]