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,195 @@
1
+ # Copyright 2026 Google LLC
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
+ """Synthesize Click commands that dispatch to an extension's run vector."""
16
+
17
+ from __future__ import annotations
18
+
19
+ import os
20
+ import sys
21
+ from pathlib import Path
22
+ from typing import TYPE_CHECKING
23
+
24
+ import click
25
+
26
+ from graph_agents_cli._project import find_project_root
27
+ from graph_agents_cli._runner import DISABLE_OVERRIDES_ENV, run_extension_command
28
+ from graph_agents_cli.extension._spec import ExtensionCommand
29
+
30
+ if TYPE_CHECKING:
31
+ from graph_agents_cli.extension._loader import ResolvedCommand
32
+
33
+
34
+ def installed_override(dotted: str) -> ResolvedCommand | None:
35
+ """The extension override installed for `dotted` (e.g. `eval.generate`), if any.
36
+
37
+ Click dispatch is where overrides normally take effect, so a built-in that
38
+ calls another command's callback in-process (`eval run` → `eval generate`)
39
+ would silently run the built-in. Such a command looks the override up here
40
+ and dispatches to it instead.
41
+ """
42
+ if os.environ.get(DISABLE_OVERRIDES_ENV) == "1":
43
+ return None
44
+ from graph_agents_cli.extension._loader import load_extension_set
45
+ from graph_agents_cli.extension._paths import user_config_root
46
+
47
+ extension_set = load_extension_set(find_project_root(Path.cwd()), user_config_root())
48
+ resolved = extension_set.commands.get(dotted)
49
+ if resolved is None or resolved.contribution.kind != "override":
50
+ return None
51
+ if resolved.blocked_requires:
52
+ raise click.ClickException(
53
+ f"{dotted!r} comes from extension {resolved.extension_name!r}, which "
54
+ f"requires graph-agents-cli {resolved.blocked_requires}.\n"
55
+ f" Update it: graph-agents-cli extension update {resolved.extension_name}\n"
56
+ f" Or remove it: graph-agents-cli extension remove {resolved.extension_name}"
57
+ )
58
+ return resolved
59
+
60
+
61
+ def run_override(resolved: ResolvedCommand, argv: list[str], *, display_path: str) -> None:
62
+ """Run a resolved override's vector, exiting with its code on failure."""
63
+ cwd = find_project_root() or Path.cwd()
64
+ try:
65
+ code = run_extension_command(
66
+ resolved.contribution.run,
67
+ argv,
68
+ cwd=cwd,
69
+ extension_root=resolved.extension_root,
70
+ )
71
+ except FileNotFoundError as e:
72
+ raise click.ClickException(
73
+ f"Extension '{resolved.extension_name}' command {display_path!r} could not "
74
+ f"run: executable {resolved.contribution.run[0]!r} not found. "
75
+ "Check the extension's `run:` entry."
76
+ ) from e
77
+ if code != 0:
78
+ # Exit with the child's code, matching what a direct `graph-agents-cli <cmd>`
79
+ # would return; a ClickException would flatten every failure to 1.
80
+ click.echo(
81
+ f"Error: {display_path} (extension '{resolved.extension_name}') failed with "
82
+ f"exit code {code}.",
83
+ err=True,
84
+ )
85
+ sys.exit(code)
86
+
87
+
88
+ def bypass_hint(display_path: str) -> str:
89
+ """How to run the built-in instead, in the shell the user is actually in.
90
+
91
+ `VAR=1 cmd` is not valid on cmd.exe or PowerShell, and this text is what
92
+ someone reads when an override has already broken something for them.
93
+ """
94
+ if os.name == "nt":
95
+ return f"set {DISABLE_OVERRIDES_ENV}=1 && graph-agents-cli {display_path}"
96
+ return f"{DISABLE_OVERRIDES_ENV}=1 graph-agents-cli {display_path}"
97
+
98
+
99
+ def make_blocked_command(
100
+ *,
101
+ extension_name: str,
102
+ leaf_name: str,
103
+ display_path: str,
104
+ requires: str,
105
+ running: str,
106
+ ) -> click.Command:
107
+ """Build a Click command that refuses to run and says why.
108
+
109
+ Used when an extension declared `on_incompatible: error` and the running CLI is
110
+ outside its range. Falling back to the built-in is not safe for an override
111
+ — it would quietly do something else — so the command fails and points at
112
+ the ways out. Only this command is affected; the rest of the CLI works.
113
+ """
114
+ short = f"unavailable: extension '{extension_name}' needs graph-agents-cli {requires}"
115
+
116
+ @click.command(
117
+ name=leaf_name,
118
+ short_help=short,
119
+ help=(
120
+ f"`{display_path}` is provided by extension '{extension_name}', which "
121
+ f"requires graph-agents-cli {requires}; you are running {running}. The "
122
+ "extension asked to fail rather than fall back (`on_incompatible: "
123
+ "error`), because the built-in would do something different.\n\n"
124
+ "Fix it by updating the extension, removing it, or running the "
125
+ "built-in explicitly:\n"
126
+ f" graph-agents-cli extension update {extension_name}\n"
127
+ f" graph-agents-cli extension remove {extension_name}\n"
128
+ f" {bypass_hint(display_path)}"
129
+ ),
130
+ context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
131
+ )
132
+ @click.argument("extra_args", nargs=-1, type=click.UNPROCESSED)
133
+ def _blocked(extra_args: tuple[str, ...]) -> None:
134
+ raise click.ClickException(
135
+ f"{display_path!r} comes from extension {extension_name!r}, which requires "
136
+ f"graph-agents-cli {requires} (running {running}).\n"
137
+ f" Update it: graph-agents-cli extension update {extension_name}\n"
138
+ f" Or remove it: graph-agents-cli extension remove {extension_name}\n"
139
+ f" Or bypass it: {bypass_hint(display_path)}"
140
+ )
141
+
142
+ return _blocked
143
+
144
+
145
+ def make_override_command(
146
+ contribution: ExtensionCommand,
147
+ *,
148
+ extension_name: str,
149
+ scope: str,
150
+ leaf_name: str,
151
+ display_path: str,
152
+ extension_root: Path,
153
+ ) -> click.Command:
154
+ """Build a Click command that runs an extension contribution.
155
+
156
+ `--help` is intercepted to describe the contribution; all other argv after
157
+ the command name passes verbatim to the run vector.
158
+ """
159
+ run_display = " ".join(contribution.run)
160
+ verb = "Overrides" if contribution.kind == "override" else "Adds"
161
+ help_text = (
162
+ f"{verb} `{display_path}` via extension '{extension_name}' ({scope} scope).\n\n"
163
+ f"{contribution.description}\n\n"
164
+ f"Runs: {run_display}\n\n"
165
+ "Argv after the command name passes through to the script verbatim.\n\n"
166
+ "To bypass extension overrides and run the built-in:\n"
167
+ f" {bypass_hint(display_path)}"
168
+ )
169
+ short = f"{contribution.description or run_display} [\u2191 {extension_name}]"
170
+
171
+ @click.command(
172
+ name=leaf_name,
173
+ short_help=short,
174
+ help=help_text,
175
+ context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
176
+ )
177
+ @click.argument("extra_args", nargs=-1, type=click.UNPROCESSED)
178
+ def _cmd(extra_args: tuple[str, ...]) -> None:
179
+ cwd = find_project_root() or Path.cwd()
180
+ try:
181
+ code = run_extension_command(
182
+ contribution.run,
183
+ list(extra_args),
184
+ cwd=cwd,
185
+ extension_root=extension_root,
186
+ )
187
+ except FileNotFoundError as e:
188
+ raise click.ClickException(
189
+ f"Extension '{extension_name}' command {display_path!r} could not run: "
190
+ f"executable {contribution.run[0]!r} not found. "
191
+ "Check the extension's `run:` entry."
192
+ ) from e
193
+ sys.exit(code)
194
+
195
+ return _cmd
@@ -0,0 +1,91 @@
1
+ # Copyright 2026 Google LLC
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
+ """Filesystem locations for extension scopes and caches."""
16
+
17
+ from __future__ import annotations
18
+
19
+ import hashlib
20
+ import os
21
+ import re
22
+ from collections.abc import Iterator
23
+ from pathlib import Path
24
+
25
+ from graph_agents_cli._project import find_project_root
26
+
27
+
28
+ def user_config_root() -> Path:
29
+ # Roaming (APPDATA): config that should follow the user between machines.
30
+ if os.name == "nt":
31
+ base = os.environ.get("APPDATA")
32
+ if base:
33
+ return Path(base) / "graph-agents-cli"
34
+ return Path.home() / "AppData" / "Roaming" / "graph-agents-cli"
35
+ return Path.home() / ".config" / "graph-agents-cli"
36
+
37
+
38
+ def vendored_extensions_dir(scope_root: Path) -> Path:
39
+ return scope_root / "extensions"
40
+
41
+
42
+ def scope_root(scope: str) -> Path | None:
43
+ """Root for an install scope, or None for project scope outside a project.
44
+
45
+ Returning None rather than raising leaves the wording of "you need a project"
46
+ to the caller, since only the install commands can say what to do about it.
47
+ """
48
+ if scope == "user":
49
+ return user_config_root()
50
+ return find_project_root(Path.cwd())
51
+
52
+
53
+ def installed_scope_roots() -> Iterator[tuple[str, Path]]:
54
+ """Yield (scope, root) for each resolvable scope, project before user.
55
+
56
+ Skips project scope when not inside a project, so callers can iterate both
57
+ scopes without repeating the "resolve root, skip if no project" boilerplate.
58
+ """
59
+ for scope in ("project", "user"):
60
+ root = scope_root(scope)
61
+ if root is not None:
62
+ yield scope, root
63
+
64
+
65
+ def git_cache_root() -> Path:
66
+ """Return the shared git cache root directory."""
67
+ # Local (LOCALAPPDATA), not Roaming: re-clonable, and not worth syncing.
68
+ if os.name == "nt":
69
+ base = os.environ.get("LOCALAPPDATA")
70
+ root = Path(base) if base else Path.home() / "AppData" / "Local"
71
+ return root / "graph-agents-cli" / "git"
72
+ return Path.home() / ".cache" / "graph-agents-cli" / "git"
73
+
74
+
75
+ def git_cache_dir_name(identity: str, url: str | None) -> str:
76
+ """Return the cache directory name for a repo, as a single path component.
77
+
78
+ ``identity`` is the readable ``org/repo``; ``url`` is the clone URL when the
79
+ reference was given as one, and None for the github.com shorthand.
80
+
81
+ A shorthand flattens to ``org__repo`` as it always has — the host is implied,
82
+ so the name is unambiguous. A URL cannot do that: two hosts can serve the
83
+ same ``org/repo``, and handing back one host's clone for the other's
84
+ extension would run the wrong code. So a URL's name carries a digest of the
85
+ URL, and the readable part is reduced to characters every filesystem accepts
86
+ (a URL holds ``:`` and ``/``, and Windows rejects both).
87
+ """
88
+ if url is None:
89
+ return identity.replace("/", "__")
90
+ slug = re.sub(r"[^A-Za-z0-9._-]+", "_", identity).strip("_") or "extension"
91
+ return f"{slug}__{hashlib.sha256(url.encode('utf-8')).hexdigest()[:12]}"
@@ -0,0 +1,193 @@
1
+ # Copyright 2026 Google LLC
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
+ """Parse extension references for `graph-agents-cli extension add`."""
16
+
17
+ from __future__ import annotations
18
+
19
+ import dataclasses
20
+ import os
21
+ import re
22
+ from dataclasses import dataclass
23
+ from pathlib import Path
24
+ from urllib.parse import urlsplit
25
+
26
+ # First-party public repository. Keep in sync with _tools.DEFAULT_SKILLS_SOURCE.
27
+ FIRST_PARTY_REPO = "ss7172/graph-agents-cli"
28
+
29
+ # Schemes an extension may be cloned from: the set `--agent` already accepts for
30
+ # a template repo (scaffold/utils/remote_template.py), plus ssh://, which is how
31
+ # a self-hosted host is usually reached, and file://, for a bare repo on a shared
32
+ # mount — `local@` copies a working tree and cannot pin a commit against one.
33
+ # `git://` is left out deliberately: it is unauthenticated, and an extension's
34
+ # commands run arbitrary code on the machine that installs it.
35
+ GIT_URL_SCHEMES = ("https", "http", "ssh", "file")
36
+
37
+ _SCHEME_RE = re.compile(r"^([A-Za-z][A-Za-z0-9+.-]*)://")
38
+ # scp-style, as offered by most hosts' "clone with SSH" button: git@host:org/repo.
39
+ _SCP_RE = re.compile(r"^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+:(?P<path>.+)$")
40
+ # A reference written as a filesystem path: absolute, ./ or ../ relative, ~, or a
41
+ # Windows drive. These are local sources even without the `local@` prefix
42
+ # (`org/repo` stays the github.com shorthand: it is not written as a path).
43
+ _PATH_RE = re.compile(r"^(?:/|\.{1,2}(?:[/\\]|$)|~|[A-Za-z]:[/\\])")
44
+
45
+
46
+ class RefParseError(Exception):
47
+ """Raised when an extension reference cannot be parsed."""
48
+
49
+
50
+ @dataclass(frozen=True)
51
+ class ExtensionRef:
52
+ raw: str
53
+ kind: str # "first_party" | "github" | "git" | "local"
54
+ repo: str | None
55
+ # Clone URL, set only for kind == "git". A github/first_party ref names a
56
+ # repo on github.com and lets the resolver build the URL from it.
57
+ url: str | None
58
+ local_path: Path | None
59
+ selector: str | None
60
+ ref: str | None
61
+
62
+
63
+ def looks_like_path(value: str) -> bool:
64
+ """True for a reference written as a filesystem path rather than a repo."""
65
+ return bool(_PATH_RE.match(value))
66
+
67
+
68
+ def anchor_local(ref: ExtensionRef, base: Path) -> ExtensionRef:
69
+ """``ref`` with a relative local path resolved against ``base`` (a scope root).
70
+
71
+ A recorded ``local@../team-tools`` is relative to the scope root it was
72
+ recorded in, so ``install``/``update`` find it from any working directory.
73
+ """
74
+ if ref.kind != "local" or ref.local_path is None or ref.local_path.is_absolute():
75
+ return ref
76
+ return dataclasses.replace(ref, local_path=base / ref.local_path)
77
+
78
+
79
+ def _split_selector(value: str) -> tuple[str, str | None]:
80
+ if "#" in value:
81
+ base, selector = value.split("#", 1)
82
+ return base, (selector or None)
83
+ return value, None
84
+
85
+
86
+ def _as_git_url(base: str) -> str | None:
87
+ """Return ``base`` unchanged if it is a clonable git URL, else None.
88
+
89
+ A string carrying a scheme git cannot clone is an error rather than a None,
90
+ so that `ftp://host/org/repo` is reported as a bad scheme instead of falling
91
+ through and being read as the `org/repo` shorthand `ftp:/host/org`.
92
+ """
93
+ scheme = _SCHEME_RE.match(base)
94
+ if scheme is not None:
95
+ if scheme.group(1).lower() not in GIT_URL_SCHEMES:
96
+ raise RefParseError(
97
+ f"unsupported scheme in {base!r}: use "
98
+ f"{', '.join(s + '://' for s in GIT_URL_SCHEMES)}, a 'git@host:org/repo' "
99
+ "URL, an 'org/repo' shorthand, or 'local@<path>'."
100
+ )
101
+ return base
102
+ return base if _SCP_RE.match(base) else None
103
+
104
+
105
+ def _repo_identity(url: str) -> str:
106
+ """Return an ``org/repo`` label for a clone URL.
107
+
108
+ Used for messages, for the vendored directory's fallback name and for the
109
+ readable part of the cache directory. The clone itself always uses the URL
110
+ as given, so nothing here has to round-trip.
111
+ """
112
+ scp = _SCP_RE.match(url)
113
+ path = scp.group("path") if scp is not None else urlsplit(url).path
114
+ parts = [p for p in path.split("/") if p]
115
+ if not parts:
116
+ raise RefParseError(f"no repository path in {url!r}.")
117
+ if parts[-1].endswith(".git"):
118
+ parts[-1] = parts[-1].removesuffix(".git")
119
+ if not parts[-1]:
120
+ raise RefParseError(f"no repository name in {url!r}.")
121
+ return "/".join(parts[-2:])
122
+
123
+
124
+ def parse_ref(raw: str, *, ref_override: str | None = None) -> ExtensionRef:
125
+ """Parse an extension reference string into a structured ExtensionRef.
126
+
127
+ Supported forms:
128
+ - ``soc2`` first-party shorthand
129
+ - ``acme/acli-extensions`` any org/repo on github.com
130
+ - ``acme/acli-extensions#soc2`` org/repo with extension selector
131
+ - ``https://git.example.com/acme/acli-extensions`` any git host
132
+ - ``git@git.example.com:acme/acli-extensions`` the same, over ssh
133
+ - ``local@../my-extension`` local path
134
+ - ``../my-extension``, ``/abs/dir``, ``~/dir`` a local path without ``local@``
135
+ - pass ``ref_override`` to pin a branch, tag, or SHA
136
+ """
137
+ raw = (raw or "").strip()
138
+ if not raw:
139
+ raise RefParseError("empty extension reference.")
140
+
141
+ if raw.startswith("local@") or looks_like_path(raw):
142
+ body = raw[len("local@") :] if raw.startswith("local@") else raw
143
+ path_part, selector = _split_selector(body)
144
+ if not path_part:
145
+ raise RefParseError(f"local reference missing a path: {raw!r}.")
146
+ return ExtensionRef(
147
+ raw=raw if raw.startswith("local@") else f"local@{raw}",
148
+ kind="local",
149
+ repo=None,
150
+ url=None,
151
+ local_path=Path(os.path.expanduser(path_part)),
152
+ selector=selector,
153
+ ref=ref_override,
154
+ )
155
+
156
+ base, selector = _split_selector(raw)
157
+
158
+ # Checked before the org/repo shorthand: a URL contains slashes too, and
159
+ # would otherwise be silently mangled into one.
160
+ url = _as_git_url(base)
161
+ if url is not None:
162
+ return ExtensionRef(
163
+ raw=raw,
164
+ kind="git",
165
+ repo=_repo_identity(url),
166
+ url=url,
167
+ local_path=None,
168
+ selector=selector,
169
+ ref=ref_override,
170
+ )
171
+
172
+ if "/" in base:
173
+ return ExtensionRef(
174
+ raw=raw,
175
+ kind="github",
176
+ repo=base,
177
+ url=None,
178
+ local_path=None,
179
+ selector=selector,
180
+ ref=ref_override,
181
+ )
182
+
183
+ # First-party shorthand: a bare name selects that extension from the
184
+ # first-party repo (ss7172/graph-agents-cli).
185
+ return ExtensionRef(
186
+ raw=raw,
187
+ kind="first_party",
188
+ repo=FIRST_PARTY_REPO,
189
+ url=None,
190
+ local_path=None,
191
+ selector=selector or base,
192
+ ref=ref_override,
193
+ )