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,274 @@
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
+ """Skills version drift detection for graph-agents-cli.
17
+
18
+ Owns the ``graph-agents-cli-`` skills prefix filter that ``info`` relies on.
19
+ The check is opt-out for disconnected installs: it is
20
+ skipped when ``GRAPH_AGENTS_CLI_NO_UPDATE_CHECK=1`` or a CI marker is set, and
21
+ it degrades silently (debug log only) when ``npx`` or the network is absent.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import logging
27
+ import os
28
+ import time
29
+ from pathlib import Path
30
+
31
+ import click
32
+ import yaml
33
+
34
+ # Pin the skills npm package to avoid executing an unverified version.
35
+ SKILLS_NPX_PACKAGE = "skills@1.5.9"
36
+
37
+ SKILL_PREFIX = "graph-agents-cli-"
38
+
39
+ # Opt-out for the update and skills-version checks (disconnected installs). `main.py` reads the
40
+ # same variable before importing this module; the check re-reads it so that a
41
+ # direct call honours the opt-out too.
42
+ NO_UPDATE_CHECK_ENV = "GRAPH_AGENTS_CLI_NO_UPDATE_CHECK"
43
+
44
+ _SKILLS_CHECK_INTERVAL = 12 * 60 * 60 # 12 hours in seconds
45
+ _SKILLS_CHECK_STAMP = Path.home() / ".agents" / ".graph_agents_cli_skills_check"
46
+
47
+
48
+ def _parse_skill_version(skill_md: Path) -> str | None:
49
+ """Extract ``metadata.version`` from a SKILL.md YAML frontmatter.
50
+
51
+ Returns the version string, or ``None`` on any failure.
52
+ Logs at debug level when the file exists but cannot be parsed.
53
+ """
54
+ try:
55
+ content = skill_md.read_text(encoding="utf-8")
56
+ except OSError:
57
+ return None
58
+
59
+ if not content.startswith("---"):
60
+ logging.debug("Malformed skill file (no frontmatter): %s", skill_md)
61
+ return None
62
+ parts = content.split("---", 2)
63
+ if len(parts) < 3:
64
+ logging.debug("Malformed skill file (incomplete frontmatter): %s", skill_md)
65
+ return None
66
+ try:
67
+ frontmatter = yaml.safe_load(parts[1])
68
+ except yaml.YAMLError:
69
+ logging.debug("Malformed skill file (invalid YAML): %s", skill_md)
70
+ return None
71
+
72
+ metadata = (frontmatter or {}).get("metadata") or {}
73
+ version = metadata.get("version") if isinstance(metadata, dict) else None
74
+ if not version:
75
+ logging.debug("Malformed skill file (missing metadata.version): %s", skill_md)
76
+ return str(version) if version else None
77
+
78
+
79
+ def _find_installed_skills() -> dict[str, str]:
80
+ """Return ``{skill_name: version}`` for every installed graph-agents-cli skill.
81
+
82
+ Fast path (~8 ms): scan ``~/.agents/skills/graph-agents-cli-*/SKILL.md``
83
+ directly. Falls back to ``npx skills list --json`` (~400 ms+) if
84
+ the well-known directory is empty or missing, which is more robust
85
+ when skills are installed to a non-default location.
86
+ """
87
+ import json
88
+
89
+ result: dict[str, str] = {}
90
+
91
+ # Fast path: well-known global install location
92
+ skills_dir = Path.home() / ".agents" / "skills"
93
+ if skills_dir.is_dir():
94
+ for skill_dir in sorted(skills_dir.iterdir()):
95
+ if not skill_dir.name.startswith(SKILL_PREFIX):
96
+ continue
97
+ version = _parse_skill_version(skill_dir / "SKILL.md")
98
+ if version:
99
+ result[skill_dir.name] = version
100
+
101
+ if result:
102
+ return result
103
+
104
+ # Slow path: ask npx skills for actual install locations
105
+ try:
106
+ from graph_agents_cli._runner import run_resolved
107
+
108
+ proc = run_resolved(
109
+ ["npx", "-y", SKILLS_NPX_PACKAGE, "list", "--json"],
110
+ capture_output=True,
111
+ text=True,
112
+ encoding="utf-8",
113
+ errors="replace",
114
+ timeout=15,
115
+ )
116
+ if proc.returncode != 0:
117
+ return {}
118
+ entries = json.loads(proc.stdout)
119
+ except Exception as e:
120
+ # Broad by design: this freshness check runs on every CLI invocation and
121
+ # must never abort a user's command, so any failure (no npx, no network)
122
+ # degrades silently to "no skills found" rather than propagating.
123
+ logging.debug("Could not query installed skills via npx: %s", e)
124
+ return {}
125
+
126
+ if not isinstance(entries, list):
127
+ return {}
128
+
129
+ for entry in entries:
130
+ if not isinstance(entry, dict):
131
+ logging.debug("Skipping malformed skills entry (expected an object): %r", entry)
132
+ continue
133
+ name = entry.get("name", "")
134
+ if not name.startswith(SKILL_PREFIX):
135
+ continue
136
+ path = entry.get("path")
137
+ if not path:
138
+ continue
139
+ version = _parse_skill_version(Path(path) / "SKILL.md")
140
+ if version:
141
+ result[name] = version
142
+
143
+ return result
144
+
145
+
146
+ def get_installed_skills() -> list[dict] | None:
147
+ """Return installed graph-agents-cli skills as a list of dicts.
148
+
149
+ Returns None if the query fails (no ``npx``, no network, malformed output),
150
+ and without running it when :func:`skills_listing_skipped` names a reason:
151
+ ``npx -y skills@... list`` may download the package, which a disconnected
152
+ install (``GRAPH_AGENTS_CLI_NO_UPDATE_CHECK=1``) and CI opt out of.
153
+ """
154
+ import json
155
+
156
+ if skills_listing_skipped():
157
+ return None
158
+ try:
159
+ from graph_agents_cli._runner import run_resolved
160
+
161
+ result = run_resolved(
162
+ ["npx", "-y", SKILLS_NPX_PACKAGE, "list", "--json"],
163
+ capture_output=True,
164
+ text=True,
165
+ encoding="utf-8",
166
+ errors="replace",
167
+ timeout=15,
168
+ )
169
+ if result.returncode != 0:
170
+ logging.debug(
171
+ "npx skills list failed (exit %d): %s",
172
+ result.returncode,
173
+ (result.stderr or "").strip(),
174
+ )
175
+ return None
176
+ skills = json.loads(result.stdout)
177
+ return [
178
+ s
179
+ for s in skills
180
+ if isinstance(s, dict) and str(s.get("name", "")).startswith(SKILL_PREFIX)
181
+ ]
182
+ except Exception as e:
183
+ logging.debug("Could not query installed skills: %s", e)
184
+ return None
185
+
186
+
187
+ def skills_listing_skipped() -> str | None:
188
+ """Why the skills listing (``npx skills list``) is not run, or None when it is.
189
+
190
+ The same opt-out as :func:`check_skills_version`: ``GRAPH_AGENTS_CLI_NO_UPDATE_CHECK=1``
191
+ (the disconnected profile) or a CI marker.
192
+ """
193
+ if _is_opted_out():
194
+ return f"{NO_UPDATE_CHECK_ENV}=1"
195
+ marker = next((var for var in _CI_MARKERS if os.environ.get(var)), None)
196
+ return f"{marker} is set (CI)" if marker else None
197
+
198
+
199
+ _CI_MARKERS = ("CI", "BUILD_ID", "GITHUB_ACTIONS", "GITLAB_CI")
200
+
201
+
202
+ def _is_ci() -> bool:
203
+ """Return True when running in a CI/automation environment.
204
+
205
+ The skills version-drift warning is a local developer-experience nicety: in
206
+ CI there is no human to act on it and skills are not installed, so the check
207
+ only adds noise (and may spawn a doomed ``npx`` subprocess). We skip it when
208
+ a well-known CI marker is present.
209
+ """
210
+ return any(os.environ.get(var) for var in _CI_MARKERS)
211
+
212
+
213
+ def _is_opted_out() -> bool:
214
+ """Return True when the user disabled the check."""
215
+ return os.environ.get(NO_UPDATE_CHECK_ENV) == "1"
216
+
217
+
218
+ def _skills_check_is_due() -> bool:
219
+ """Return True if enough time has elapsed since the last check."""
220
+ try:
221
+ last = float(_SKILLS_CHECK_STAMP.read_text().strip())
222
+ return (time.time() - last) > _SKILLS_CHECK_INTERVAL
223
+ except (OSError, ValueError):
224
+ return True
225
+
226
+
227
+ def _record_skills_check() -> None:
228
+ """Write the current timestamp to the stamp file."""
229
+ try:
230
+ _SKILLS_CHECK_STAMP.parent.mkdir(parents=True, exist_ok=True)
231
+ _SKILLS_CHECK_STAMP.write_text(str(time.time()))
232
+ except OSError:
233
+ pass
234
+
235
+
236
+ def check_skills_version() -> None:
237
+ """Warn if any installed skill version doesn't match the running CLI version.
238
+
239
+ Rate-limited to once per 12 hours via a timestamp file so it can
240
+ run globally on every command without adding latency.
241
+
242
+ Scans all installed ``graph-agents-cli-*`` skills, compares each
243
+ ``metadata.version`` with the running ``__version__``, and lists
244
+ the mismatched ones. Never blocks execution. Skipped entirely in CI
245
+ and when ``GRAPH_AGENTS_CLI_NO_UPDATE_CHECK=1``. Silent offline.
246
+ """
247
+ if _is_opted_out() or _is_ci() or not _skills_check_is_due():
248
+ return
249
+
250
+ try:
251
+ installed = _find_installed_skills()
252
+ except Exception as e: # never abort the user's command
253
+ logging.debug("Skills check skipped: %s", e)
254
+ return
255
+ if not installed:
256
+ return
257
+
258
+ from graph_agents_cli import __version__
259
+
260
+ _record_skills_check()
261
+
262
+ mismatched = {name: ver for name, ver in installed.items() if ver != __version__}
263
+ if not mismatched:
264
+ return
265
+
266
+ lines = [f" - {name} (v{ver})" for name, ver in mismatched.items()]
267
+ click.echo(
268
+ f"\n⚠️ Skills version mismatch — CLI is v{__version__}, "
269
+ f"but {len(mismatched)} skill(s) differ:\n"
270
+ + "\n".join(lines)
271
+ + "\n Run 'graph-agents-cli setup' to install the skills of this version (or "
272
+ "'graph-agents-cli update' to move the CLI and the skills to the latest release).\n",
273
+ err=True,
274
+ )
@@ -0,0 +1,189 @@
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
+ """Tool resolution utilities.
17
+
18
+ Every external program the CLI shells out to (helm, kubectl, docker, gh, uv,
19
+ npx, ...) is resolved through :func:`require_tool`, which caches the resolved
20
+ path and, on Windows, retries with a cleaned PATH. Nothing here imports a
21
+ model SDK, LangChain, LangGraph, or a Kubernetes/Docker client.
22
+ """
23
+
24
+ import os
25
+ import re
26
+ import shlex
27
+ import shutil
28
+ from functools import cache
29
+
30
+ import click
31
+
32
+ _tool_paths: dict[str, str] = {}
33
+
34
+ # Matches ANSI escape sequences (CSI/SGR), used to scrub any residual color
35
+ # codes from captured subprocess output. We disable color at the source via
36
+ # NO_COLOR/FORCE_COLOR, but strip defensively in case the tool emits them anyway
37
+ # (e.g. on Windows PowerShell, where embedded escapes have caused error lines
38
+ # to render as the previous line's color).
39
+ _ANSI_RE = re.compile(r"\x1b\[[0-9;?]*[a-zA-Z]")
40
+
41
+ # Where `graph-agents-cli setup` fetches the skills from by default (pinned to the
42
+ # running release's tag, see `default_skills_source`).
43
+ # Keep in sync with extension._refs.FIRST_PARTY_REPO.
44
+ DEFAULT_SKILLS_SOURCE = "https://github.com/ss7172/graph-agents-cli"
45
+
46
+
47
+ def default_skills_source(version: str | None) -> str:
48
+ """The first-party skills matching CLI ``version``: ``<repo>#v<version>``.
49
+
50
+ A release installs the skills of its own tag, so they never drift from the
51
+ CLI when the default branch moves on. A development build (a source
52
+ checkout, ``0.0.0-dev``, an unknown ``0.0.0``, a ``.devN`` or ``+local``
53
+ version) has no matching tag and uses the default branch.
54
+ """
55
+ from packaging.version import InvalidVersion, Version
56
+
57
+ try:
58
+ parsed = Version(version or "")
59
+ except InvalidVersion:
60
+ return DEFAULT_SKILLS_SOURCE
61
+ if parsed.is_devrelease or parsed.local or parsed == Version("0.0.0"):
62
+ return DEFAULT_SKILLS_SOURCE
63
+ return f"{DEFAULT_SKILLS_SOURCE}#v{version}"
64
+
65
+
66
+ _UV_HINT = "Install uv (https://docs.astral.sh/uv/getting-started/installation/) and ensure it is in your PATH."
67
+ _NODE_HINT = "Install Node.js (https://nodejs.org/en/download) and ensure it is in your PATH."
68
+
69
+ # Default installation hints for the tools the CLI shells out to.
70
+ # These are used as fallbacks in require_tool when no specific hint is provided,
71
+ # ensuring helpful error messages even when tools are resolved implicitly (e.g. via run_resolved).
72
+ DEFAULT_INSTALL_HINTS = {
73
+ "helm": "Install Helm (https://helm.sh/docs/intro/install/) and ensure it is in your PATH.",
74
+ "kubectl": "Install kubectl (https://kubernetes.io/docs/tasks/tools/) and ensure it is in your PATH.",
75
+ "docker": "Install Docker (https://docs.docker.com/get-docker/) or a Docker-compatible CLI named 'docker' and ensure it is in your PATH.",
76
+ "argocd": "Install the Argo CD CLI (https://argo-cd.readthedocs.io/en/stable/cli_installation/) and ensure it is in your PATH.",
77
+ "gh": "Install the GitHub CLI (https://cli.github.com/) and ensure it is in your PATH.",
78
+ "uv": _UV_HINT,
79
+ # uvx is shipped by uv, so the install instructions are the same.
80
+ "uvx": f"uvx is part of uv. {_UV_HINT}",
81
+ "npx": f"npx is part of Node.js. {_NODE_HINT}",
82
+ "npm": f"npm is part of Node.js. {_NODE_HINT}",
83
+ "node": _NODE_HINT,
84
+ "git": "Install Git (https://git-scm.com/downloads) and ensure it is in your PATH.",
85
+ "langgraph": (
86
+ "langgraph is a project dependency (langgraph-cli), not a global tool: run "
87
+ "'graph-agents-cli install' inside the project, then invoke it as 'uv run langgraph'."
88
+ ),
89
+ }
90
+
91
+
92
+ class ToolNotFoundError(click.ClickException):
93
+ """Raised when a required external tool is not found on PATH."""
94
+
95
+ pass
96
+
97
+
98
+ @cache
99
+ def _get_cleaned_path() -> str:
100
+ """Returns a cleaned and expanded version of the PATH environment variable.
101
+
102
+ This function performs the following steps:
103
+ 1. Splits the PATH environment variable using the OS-specific path separator.
104
+ 2. Strips quotes from each path segment.
105
+ 3. Filters out empty path segments.
106
+ 4. Expands environment variables (like $HOME or %USERPROFILE%) within each segment.
107
+ 5. Reconstructs the PATH string with the cleaned segments.
108
+ """
109
+ raw_path = os.environ.get("PATH", "")
110
+ parts = raw_path.split(os.pathsep)
111
+ cleaned_parts = []
112
+
113
+ for part in parts:
114
+ # Strip quotes from each path segment.
115
+ part = part.strip('"').strip("'")
116
+ if not part:
117
+ continue
118
+ cleaned_parts.append(os.path.expandvars(part))
119
+ return os.pathsep.join(cleaned_parts)
120
+
121
+
122
+ def is_windows() -> bool:
123
+ """Returns True if the current operating system is Windows."""
124
+ return os.name == "nt"
125
+
126
+
127
+ def install_hint(name: str) -> str:
128
+ """Return the default installation hint for ``name`` (empty when unknown)."""
129
+ return DEFAULT_INSTALL_HINTS.get(name, "")
130
+
131
+
132
+ def require_tool(name: str, install_hint: str = "") -> str:
133
+ """Finds a required external tool on the system PATH and returns its path.
134
+
135
+ This function performs the following steps:
136
+ 1. Checks if the tool's path is already cached in `_tool_paths`.
137
+ 2. If not cached, searches for the tool using `shutil.which` with the default PATH.
138
+ 3. If not found and running on Windows, searches again using `shutil.which` with a cleaned PATH.
139
+ 4. If still not found, raises a `ToolNotFoundError` with an install hint
140
+ (the explicit ``install_hint`` or the default for that tool).
141
+ 5. If found, caches the path and returns it.
142
+ """
143
+ if name in _tool_paths:
144
+ return _tool_paths[name]
145
+
146
+ path = shutil.which(name)
147
+
148
+ if path is None and is_windows():
149
+ path = shutil.which(name, path=_get_cleaned_path())
150
+
151
+ if path is None:
152
+ msg = f"'{name}' is not installed or not on PATH."
153
+ hint = install_hint or DEFAULT_INSTALL_HINTS.get(name, "")
154
+ if hint:
155
+ msg += f"\n {hint}"
156
+ raise ToolNotFoundError(msg)
157
+
158
+ _tool_paths[name] = path
159
+ return path
160
+
161
+
162
+ def tool_available(name: str) -> bool:
163
+ """Return True when ``name`` resolves on PATH, without raising."""
164
+ try:
165
+ require_tool(name)
166
+ except ToolNotFoundError:
167
+ return False
168
+ return True
169
+
170
+
171
+ def run_npx_skills(args: list[str], spinner_msg: str):
172
+ """Run an npx skills command, streaming output in real-time.
173
+
174
+ Always starts with ``["npx", "-y", SKILLS_NPX_PACKAGE]`` and appends
175
+ the additional ``args`` provided.
176
+
177
+ Raises:
178
+ click.ClickException: If the npx process exits non-zero.
179
+ """
180
+ from graph_agents_cli._runner import run_resolved
181
+ from graph_agents_cli._skills_check import SKILLS_NPX_PACKAGE
182
+
183
+ full_args = ["npx", "-y", SKILLS_NPX_PACKAGE, *args]
184
+ click.secho(f" ▸ {shlex.join(full_args)}", fg="cyan", dim=True)
185
+
186
+ try:
187
+ run_resolved(full_args, check=True, encoding="utf-8", errors="replace")
188
+ except Exception as e:
189
+ raise click.ClickException("Error running npx skills") from e
@@ -0,0 +1,66 @@
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
+ """Trust tier decorators for agents CLI commands."""
16
+
17
+ import functools
18
+
19
+ import click
20
+
21
+
22
+ def require_confirmation(message: str):
23
+ """Decorator that adds --yes/-y and --interactive/-i options to destructive commands.
24
+
25
+ In interactive mode (-i), the user is prompted to confirm the action.
26
+ In auto-approve mode (-y) or strict programmatic mode (no flags), proceeds silently.
27
+ The decorated function receives an 'auto_approve' parameter.
28
+
29
+ Args:
30
+ message: Confirmation prompt shown to the user.
31
+ """
32
+
33
+ def decorator(f):
34
+ @click.option(
35
+ "--interactive",
36
+ "-i",
37
+ is_flag=True,
38
+ default=False,
39
+ help="Enable interactive confirmation prompt.",
40
+ )
41
+ @click.option(
42
+ "-y",
43
+ "--yes",
44
+ "--auto-approve",
45
+ "auto_approve",
46
+ is_flag=True,
47
+ default=False,
48
+ help="Skip confirmation prompt.",
49
+ )
50
+ @functools.wraps(f)
51
+ def wrapper(*args, interactive=False, auto_approve=False, **kwargs):
52
+ if interactive and not auto_approve:
53
+ click.echo()
54
+ if not click.confirm(f" {message}", default=False):
55
+ click.echo()
56
+ click.secho(" Aborted.", fg="yellow")
57
+ return
58
+ click.echo()
59
+ # In strict programmatic mode (no -i, no -y): auto-proceed silently.
60
+ # `interactive` is not passed on: the prompt happens here, and no
61
+ # decorated command has ever read it.
62
+ return f(*args, auto_approve=auto_approve, **kwargs)
63
+
64
+ return wrapper
65
+
66
+ return decorator
@@ -0,0 +1,15 @@
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
+ """``graph-agents-cli api``: declare and change a project's outbound API access policy."""