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,57 @@
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
+ """graph-agents-cli extension command group."""
16
+
17
+ import click
18
+
19
+ from graph_agents_cli._click import LazyGroup
20
+
21
+
22
+ @click.group("extension", cls=LazyGroup)
23
+ def extension_group():
24
+ """Manage graph-agents-cli extensions (experimental).
25
+
26
+ Experimental: the manifest schema and the command surface may still change
27
+ in a breaking way. Pin the CLI version if you depend on either.
28
+
29
+ \b
30
+ Subcommands:
31
+ add Add an extension from a git reference or local path
32
+ list List active extensions and the commands they contribute
33
+ update Advance extension pins to the latest tracked ref
34
+ remove Remove an installed extension
35
+ """
36
+
37
+
38
+ extension_group.add_lazy_command(
39
+ "add",
40
+ "graph_agents_cli.extension.cmd_extension_add:cmd_add",
41
+ "Add an extension from a git reference or local path.",
42
+ )
43
+ extension_group.add_lazy_command(
44
+ "list",
45
+ "graph_agents_cli.extension.cmd_extension_list:cmd_list",
46
+ "List active extensions and the commands they contribute.",
47
+ )
48
+ extension_group.add_lazy_command(
49
+ "update",
50
+ "graph_agents_cli.extension.cmd_extension_update:cmd_update",
51
+ "Advance extension pins (re-resolve the tracked ref).",
52
+ )
53
+ extension_group.add_lazy_command(
54
+ "remove",
55
+ "graph_agents_cli.extension.cmd_extension_remove:cmd_remove",
56
+ "Remove an installed extension (checks project then user scope).",
57
+ )
@@ -0,0 +1,56 @@
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
+ """graph-agents-cli extension list command."""
16
+
17
+ from __future__ import annotations
18
+
19
+ from pathlib import Path
20
+
21
+ import click
22
+
23
+ from graph_agents_cli._project import find_project_root
24
+ from graph_agents_cli.extension._loader import load_extension_set
25
+ from graph_agents_cli.extension._paths import user_config_root
26
+
27
+
28
+ @click.command("list")
29
+ def cmd_list() -> None:
30
+ """List active extensions and the commands they contribute."""
31
+ project_root = find_project_root(Path.cwd())
32
+ ps = load_extension_set(project_root, user_config_root())
33
+ if not ps.extensions:
34
+ click.echo("No extensions installed.")
35
+ return
36
+ click.echo("Extensions:")
37
+ # A spec can appear more than once in ps.extensions (e.g. inline manifest plus a
38
+ # vendored copy from the same root); deduplicate for display.
39
+ seen: set[tuple[str, str]] = set()
40
+ for spec in ps.extensions:
41
+ if (spec.name, spec.scope) in seen:
42
+ continue
43
+ seen.add((spec.name, spec.scope))
44
+ cmds = ", ".join(sorted(c.name for c in spec.commands)) or "(none)"
45
+ line = f" {spec.name} {spec.scope} (commands: {cmds})"
46
+ if spec.requires_agents_cli:
47
+ line += f" requires: {spec.requires_agents_cli}"
48
+ click.echo(line)
49
+ for c in ps.conflict_rows():
50
+ click.echo(f" ! conflict: {c}")
51
+ for inc in ps.incompatible_rows():
52
+ effect = "its commands will not run" if inc["mode"] == "error" else "applied anyway"
53
+ click.echo(
54
+ f" ! incompatible: {inc['extension']} requires graph-agents-cli "
55
+ f"{inc['requires']} (running {inc['running']}) — {effect}"
56
+ )
@@ -0,0 +1,61 @@
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
+ """graph-agents-cli extension remove command."""
16
+
17
+ from __future__ import annotations
18
+
19
+ import shutil
20
+
21
+ import click
22
+
23
+ from graph_agents_cli._trust import require_confirmation
24
+ from graph_agents_cli.extension._manifest import (
25
+ EXTENSIONS_FILE,
26
+ read_extension_entries,
27
+ remove_extension_entry,
28
+ )
29
+ from graph_agents_cli.extension._paths import (
30
+ installed_scope_roots,
31
+ vendored_extensions_dir,
32
+ )
33
+ from graph_agents_cli.extension._resolver import (
34
+ ResolverError,
35
+ validate_extension_name,
36
+ )
37
+
38
+
39
+ @click.command("remove")
40
+ @click.argument("name")
41
+ @require_confirmation("Remove this extension (deletes its vendored copy)?")
42
+ def cmd_remove(name: str, auto_approve: bool) -> None:
43
+ """Remove an installed extension (checks project then user scope)."""
44
+ for scope, root in installed_scope_roots():
45
+ manifest = root / EXTENSIONS_FILE
46
+ entries = {e.name for e in read_extension_entries(manifest)}
47
+ if name not in entries:
48
+ continue
49
+ # The name comes from a committed manifest and decides what gets
50
+ # rmtree'd, so check it before touching anything.
51
+ try:
52
+ safe_name = validate_extension_name(name)
53
+ except ResolverError as e:
54
+ raise click.ClickException(f"Refusing to remove extension {name!r}: {e}") from e
55
+ remove_extension_entry(manifest, name)
56
+ extension_dir = vendored_extensions_dir(root) / safe_name
57
+ if extension_dir.exists():
58
+ shutil.rmtree(extension_dir)
59
+ click.secho(f"Removed extension {name!r} ({scope} scope).", fg="green")
60
+ return
61
+ raise click.ClickException(f"Extension {name!r} is not installed.")
@@ -0,0 +1,195 @@
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
+ """graph-agents-cli extension update command."""
17
+
18
+ from __future__ import annotations
19
+
20
+ import logging
21
+ from pathlib import Path
22
+
23
+ import click
24
+
25
+ from graph_agents_cli.__init__ import __version__
26
+ from graph_agents_cli._trust import require_confirmation
27
+ from graph_agents_cli.extension._loader import incompatible_spec
28
+ from graph_agents_cli.extension._manifest import (
29
+ EXTENSIONS_FILE,
30
+ ExtensionEntry,
31
+ read_extension_entries,
32
+ upsert_extension_entry,
33
+ )
34
+ from graph_agents_cli.extension._paths import (
35
+ installed_scope_roots,
36
+ vendored_extensions_dir,
37
+ )
38
+ from graph_agents_cli.extension._refs import RefParseError, anchor_local, parse_ref
39
+ from graph_agents_cli.extension._resolver import (
40
+ ResolverError,
41
+ expected_stamp,
42
+ materialize,
43
+ read_stamp,
44
+ resolve_sha,
45
+ )
46
+ from graph_agents_cli.extension._spec import ExtensionSpecError
47
+ from graph_agents_cli.extension._trust import confirm_trust, stdin_is_interactive
48
+
49
+
50
+ def _restore_pin(entry: ExtensionEntry, root: Path) -> None:
51
+ """Put the previously pinned copy back after refusing to advance to a new one."""
52
+ try:
53
+ materialize(
54
+ anchor_local(parse_ref(entry.source, ref_override=entry.sha), root),
55
+ entry.sha,
56
+ vendored_extensions_dir(root),
57
+ name=entry.name,
58
+ )
59
+ except ResolverError as e:
60
+ logging.warning("Could not restore the previous pin for %r: %s", entry.name, e)
61
+
62
+
63
+ @click.command("update")
64
+ @click.argument("name", required=False)
65
+ @require_confirmation("Update extension(s) to the latest pinned ref?")
66
+ def cmd_update(
67
+ name: str | None,
68
+ auto_approve: bool,
69
+ ) -> None:
70
+ """Advance extension pins (re-resolve the tracked ref).
71
+
72
+ Updates every installed extension when NAME is omitted. The tracked ref is
73
+ resolved first: an extension whose code did not change is reported as up
74
+ to date without a trust prompt. New third-party code needs your trust
75
+ (a prompt, or -y); without a terminal to ask on it keeps its pin and the
76
+ command exits 1.
77
+ """
78
+ updated: list[str] = []
79
+ current: list[str] = []
80
+ skipped: list[str] = []
81
+ untrusted: list[str] = []
82
+ for scope, root in installed_scope_roots():
83
+ manifest = root / EXTENSIONS_FILE
84
+ for entry in read_extension_entries(manifest):
85
+ if name is not None and entry.name != name:
86
+ continue
87
+ try:
88
+ ref = anchor_local(
89
+ parse_ref(
90
+ entry.source,
91
+ # "HEAD" means "follow latest"; pass None so resolve_sha re-resolves.
92
+ ref_override=(None if entry.ref == "HEAD" else entry.ref),
93
+ ),
94
+ root,
95
+ )
96
+ except RefParseError as e:
97
+ logging.warning("Skipping extension %r: %s", entry.name, e)
98
+ skipped.append(entry.name)
99
+ continue
100
+ try:
101
+ # Resolving reads the source (the remote's refs, or a local tree's
102
+ # hash); it runs none of the extension's code, so it needs no trust.
103
+ new_sha = resolve_sha(ref)
104
+ extension_dir = vendored_extensions_dir(root) / entry.name
105
+ if (
106
+ new_sha == entry.sha
107
+ and extension_dir.exists()
108
+ and read_stamp(extension_dir) == expected_stamp(ref, new_sha)
109
+ ):
110
+ # Same commit (or, for a local source, the same tree) as the
111
+ # copy on disk: nothing to do, nothing to claim, nothing to trust.
112
+ current.append(entry.name)
113
+ continue
114
+ except ResolverError as e:
115
+ logging.warning("Could not update %r: %s", entry.name, e)
116
+ skipped.append(entry.name)
117
+ continue
118
+ if not confirm_trust(ref, auto_approve=auto_approve):
119
+ click.secho(
120
+ f"Skipped {entry.name!r} (not trusted; the installed copy is kept).",
121
+ fg="yellow",
122
+ )
123
+ skipped.append(entry.name)
124
+ untrusted.append(entry.name)
125
+ continue
126
+ try:
127
+ # name=entry.name pins the vendored dir to the stable id (see
128
+ # materialize) so an update survives an upstream rename.
129
+ materialize(
130
+ ref,
131
+ new_sha,
132
+ vendored_extensions_dir(root),
133
+ name=entry.name,
134
+ )
135
+ except ResolverError as e:
136
+ # One unreachable source must not abandon the others, or the
137
+ # command reports failure after already advancing a pin.
138
+ logging.warning("Could not update %r: %s", entry.name, e)
139
+ skipped.append(entry.name)
140
+ continue
141
+ # Compat gate: if the new pin declares an `error`-mode range the
142
+ # running CLI is outside, keep the old pin (restore its working
143
+ # copy) instead of advancing to a version that won't run here.
144
+ try:
145
+ spec = incompatible_spec(vendored_extensions_dir(root) / entry.name)
146
+ except ExtensionSpecError as e:
147
+ _restore_pin(entry, root)
148
+ click.secho(
149
+ f"Skipped {entry.name!r}: the new version's manifest is not "
150
+ f"valid ({e}); kept {entry.sha[:7]}.",
151
+ fg="yellow",
152
+ )
153
+ skipped.append(entry.name)
154
+ continue
155
+ if spec is not None:
156
+ if spec.error_on_incompatible:
157
+ _restore_pin(entry, root)
158
+ click.secho(
159
+ f"Skipped {entry.name!r}: new version requires graph-agents-cli "
160
+ f"{spec.requires_agents_cli}, running {__version__} (kept {entry.sha[:7]}).",
161
+ fg="yellow",
162
+ )
163
+ skipped.append(entry.name)
164
+ continue
165
+ logging.warning(
166
+ "Updated %r to a version requiring graph-agents-cli %s (running %s).",
167
+ entry.name,
168
+ spec.requires_agents_cli,
169
+ __version__,
170
+ )
171
+ upsert_extension_entry(
172
+ manifest,
173
+ ExtensionEntry(
174
+ name=entry.name,
175
+ source=entry.source,
176
+ ref=entry.ref,
177
+ sha=new_sha,
178
+ scope=scope,
179
+ ),
180
+ )
181
+ updated.append(entry.name)
182
+ if not updated and not skipped and not current:
183
+ raise click.ClickException(
184
+ f"No extension named {name!r} found." if name else "No extensions to update."
185
+ )
186
+ if updated:
187
+ click.secho(f"Updated: {', '.join(updated)}.", fg="green")
188
+ if current:
189
+ click.secho(f"Already up to date: {', '.join(current)}.", dim=True)
190
+ if untrusted and not stdin_is_interactive():
191
+ # Nobody could answer: a script must not take "kept the old pin" for success.
192
+ raise click.ClickException(
193
+ f"Not updated: {', '.join(untrusted)} changed and needs your trust; rerun with -y "
194
+ "to trust the new code."
195
+ )
@@ -0,0 +1,13 @@
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
+ # http://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.
@@ -0,0 +1,222 @@
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
+ """Show project configuration, paths, and CLI version."""
17
+
18
+ from __future__ import annotations
19
+
20
+ import platform
21
+ from pathlib import Path
22
+ from typing import Any
23
+
24
+ import click
25
+
26
+ import graph_agents_cli as _cli_pkg
27
+ from graph_agents_cli.__init__ import __version__
28
+ from graph_agents_cli._build import BuildInfo, current_build
29
+ from graph_agents_cli._output import emit
30
+ from graph_agents_cli._project import (
31
+ ProjectConfig,
32
+ check_cli_version,
33
+ find_project_root,
34
+ read_project_config,
35
+ )
36
+ from graph_agents_cli._skills_check import get_installed_skills, skills_listing_skipped
37
+ from graph_agents_cli.extension._loader import ExtensionSet, load_extension_set
38
+ from graph_agents_cli.extension._paths import user_config_root
39
+
40
+ _CLI_INSTALL_PATH = str(Path(_cli_pkg.__file__).parent)
41
+
42
+
43
+ def _print_extensions(extension_set: ExtensionSet) -> None:
44
+ rows = extension_set.command_rows()
45
+ conflicts = extension_set.conflict_rows()
46
+ incompatible = extension_set.incompatible_rows()
47
+ if not rows and not conflicts and not incompatible:
48
+ return
49
+ click.echo()
50
+ click.echo("Extensions (experimental):")
51
+ for r in rows:
52
+ line = (
53
+ f" {r['command']} ({r['kind']}, {r['scope']}) "
54
+ f"<- {r['extension']}: {' '.join(r['run'])}"
55
+ )
56
+ if r.get("requires"):
57
+ line += f" [requires graph-agents-cli {r['requires']}]"
58
+ if r.get("blocked"):
59
+ line += " [BLOCKED: out of range, this command will not run]"
60
+ click.echo(line)
61
+ for c in conflicts:
62
+ click.echo(f" ! conflict: {c} (claimed by multiple same-scope extensions)")
63
+ for inc in incompatible:
64
+ click.echo(
65
+ f" ! incompatible: {inc['extension']} requires graph-agents-cli "
66
+ f"{inc['requires']} (running {inc['running']})"
67
+ )
68
+
69
+
70
+ def _print_installed_skills(skills: list[dict] | None, skipped: str | None = None) -> None:
71
+ """Print installed skills summary."""
72
+ if skipped:
73
+ click.echo(f"Installed skills: not listed ({skipped} skips `npx skills list`)")
74
+ return
75
+ if skills is None:
76
+ click.echo("Installed skills: (could not query)")
77
+ return
78
+ if not skills:
79
+ click.echo("Installed skills: none")
80
+ return
81
+ # Group by scope
82
+ by_scope: dict[str, list[str]] = {}
83
+ for s in skills:
84
+ scope = s.get("scope", "unknown")
85
+ by_scope.setdefault(scope, []).append(s["name"])
86
+ for scope, names in sorted(by_scope.items()):
87
+ click.echo(f"Installed skills: {len(names)} ({scope})")
88
+ for name in sorted(names):
89
+ click.echo(f" - {name}")
90
+
91
+
92
+ def build_info_json(build: BuildInfo) -> dict[str, Any]:
93
+ """The ``cli_build`` block of ``info --json``."""
94
+ return {
95
+ "id": build.id,
96
+ "commit": build.commit,
97
+ "dirty": build.dirty,
98
+ "release": build.is_release,
99
+ }
100
+
101
+
102
+ def project_info(project_root: Path, cfg: ProjectConfig) -> dict[str, Any]:
103
+ """The project block of ``info``: what the manifest records."""
104
+ return {
105
+ "project_root": str(project_root),
106
+ "project_name": cfg.project_name,
107
+ "cli_version": cfg.cli_version,
108
+ "cli_build": cfg.cli_build if isinstance(cfg.cli_build, dict) else None,
109
+ "language": cfg.language,
110
+ "base_template": cfg.base_template,
111
+ "agent_directory": cfg.agent_directory,
112
+ "runtime": cfg.runtime,
113
+ "model_provider": cfg.model_provider,
114
+ "model": cfg.model,
115
+ "checkpointer": cfg.checkpointer,
116
+ "deployment_target": cfg.deployment_target,
117
+ "registry": cfg.registry,
118
+ "cd": cfg.cd,
119
+ "auth_policy": cfg.auth_policy,
120
+ "auth_policy_implemented": cfg.auth_policy_implemented,
121
+ "api_policy_file": cfg.api_policy_file,
122
+ "process": cfg.process,
123
+ "environments": cfg.environments,
124
+ "secret_keys": cfg.secret_keys,
125
+ "secrets_owner": cfg.secrets.owner,
126
+ }
127
+
128
+
129
+ def _scaffolded_with(cfg: ProjectConfig) -> str:
130
+ """The version and, when the manifest records it, the build that rendered the project."""
131
+ version = cfg.cli_version or "(unknown)"
132
+ build = cfg.cli_build.get("id") if isinstance(cfg.cli_build, dict) else None
133
+ if not build:
134
+ return f"{version} (no build recorded)" if cfg.cli_version else version
135
+ return version if build == cfg.cli_version else f"{version} (build {build})"
136
+
137
+
138
+ def _print_project(project_root: Path, cfg: ProjectConfig) -> None:
139
+ click.echo()
140
+ click.echo(f"Project root: {project_root}")
141
+ click.echo(f"Project name: {cfg.project_name or '(not set)'}")
142
+ click.echo(f"Scaffolded with: {_scaffolded_with(cfg)}")
143
+ click.echo(f"Base template: {cfg.base_template}")
144
+ click.echo(f"Agent directory: {cfg.agent_directory}")
145
+ click.echo(f"Runtime: {cfg.runtime}")
146
+ click.echo(f"Model provider: {cfg.model_provider}")
147
+ click.echo(f"Model: {cfg.model}")
148
+ click.echo(f"Checkpointer: {cfg.checkpointer}")
149
+ click.echo(f"Deployment target: {cfg.deployment_target}")
150
+ click.echo(f"Registry: {cfg.registry or '(none)'}")
151
+ click.echo(f"CD: {cfg.cd}")
152
+ implemented = "" if cfg.auth_policy_implemented else " (stub, not yet implemented)"
153
+ click.echo(f"Auth policy: {cfg.auth_policy}{implemented}")
154
+ click.echo(f"API policy: {cfg.api_policy_file or 'none'}")
155
+ click.echo(f"Process: {cfg.process or 'none'}")
156
+ if cfg.environments:
157
+ click.echo("Environments:")
158
+ for env_name, env in cfg.environments.items():
159
+ context = env.get("context") or "(current context)"
160
+ click.echo(f" - {env_name}: namespace={env.get('namespace')} context={context}")
161
+ else:
162
+ click.echo("Environments: none")
163
+
164
+
165
+ @click.command()
166
+ @click.option("--json", "as_json", is_flag=True, default=False, help="Output as JSON.")
167
+ def cmd_info(as_json: bool) -> None:
168
+ """Show project configuration, paths, and CLI version.
169
+
170
+ The installed skills come from `npx skills list`, which is not run (and
171
+ reported as not listed) with GRAPH_AGENTS_CLI_NO_UPDATE_CHECK=1 or in CI.
172
+ """
173
+ installed_skills = get_installed_skills()
174
+ # Why there is no listing: the opt-out, not a failure (None from a failed query too).
175
+ skills_skipped = skills_listing_skipped() if installed_skills is None else None
176
+ project_root = find_project_root()
177
+ os_info = platform.platform()
178
+ extension_set = load_extension_set(project_root, user_config_root())
179
+
180
+ build = current_build()
181
+ base: dict[str, Any] = {
182
+ "cli_version": __version__,
183
+ "cli_build": build_info_json(build),
184
+ "cli_install_path": _CLI_INSTALL_PATH,
185
+ "os_info": os_info,
186
+ "installed_skills": installed_skills,
187
+ "installed_skills_skipped": skills_skipped,
188
+ "extensions": extension_set.command_rows(),
189
+ "extension_conflicts": extension_set.conflict_rows(),
190
+ "extension_incompatible": extension_set.incompatible_rows(),
191
+ }
192
+
193
+ if project_root is None:
194
+ if as_json:
195
+ emit({**base, "project": None})
196
+ else:
197
+ click.echo(f"CLI version: {__version__}")
198
+ click.echo(f"CLI build: {build.describe()}")
199
+ click.echo(f"CLI install path: {_CLI_INSTALL_PATH}")
200
+ click.echo(f"OS info: {os_info}")
201
+ _print_installed_skills(installed_skills, skills_skipped)
202
+ _print_extensions(extension_set)
203
+ click.echo()
204
+ click.echo("No agent project found in the current directory or any parent.")
205
+ click.echo(" Run this command from within a project, or create one:")
206
+ click.echo(" graph-agents-cli create my-agent")
207
+ return
208
+
209
+ cfg = read_project_config(str(project_root))
210
+ check_cli_version(cfg)
211
+
212
+ if as_json:
213
+ emit({**base, "project": project_info(project_root, cfg)})
214
+ return
215
+
216
+ click.echo(f"CLI version: {__version__}")
217
+ click.echo(f"CLI build: {build.describe()}")
218
+ click.echo(f"CLI install path: {_CLI_INSTALL_PATH}")
219
+ click.echo(f"OS info: {os_info}")
220
+ _print_installed_skills(installed_skills, skills_skipped)
221
+ _print_project(project_root, cfg)
222
+ _print_extensions(extension_set)
@@ -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 infra commands."""