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.
- graph_agents_cli/__init__.py +26 -0
- graph_agents_cli/_api_policy.py +2145 -0
- graph_agents_cli/_approvals.py +400 -0
- graph_agents_cli/_build.py +186 -0
- graph_agents_cli/_build_info.json +7 -0
- graph_agents_cli/_chat_client.py +462 -0
- graph_agents_cli/_click.py +157 -0
- graph_agents_cli/_defaults.py +139 -0
- graph_agents_cli/_experiments.py +64 -0
- graph_agents_cli/_http.py +192 -0
- graph_agents_cli/_output.py +83 -0
- graph_agents_cli/_project.py +462 -0
- graph_agents_cli/_remote.py +220 -0
- graph_agents_cli/_response_schema.py +264 -0
- graph_agents_cli/_runner.py +319 -0
- graph_agents_cli/_skills_check.py +274 -0
- graph_agents_cli/_tools.py +189 -0
- graph_agents_cli/_trust.py +66 -0
- graph_agents_cli/api/__init__.py +15 -0
- graph_agents_cli/api/_changes.py +506 -0
- graph_agents_cli/api/_files.py +658 -0
- graph_agents_cli/api/cmd_api.py +2480 -0
- graph_agents_cli/deploy/__init__.py +15 -0
- graph_agents_cli/deploy/_config.py +171 -0
- graph_agents_cli/deploy/_image.py +128 -0
- graph_agents_cli/deploy/_kube.py +286 -0
- graph_agents_cli/deploy/_modes.py +234 -0
- graph_agents_cli/deploy/_preflight.py +370 -0
- graph_agents_cli/deploy/_values.py +168 -0
- graph_agents_cli/deploy/cmd_deploy.py +1866 -0
- graph_agents_cli/deploy/gitops.py +562 -0
- graph_agents_cli/deploy/local_load.py +273 -0
- graph_agents_cli/dev/__init__.py +13 -0
- graph_agents_cli/dev/cmd_build.py +131 -0
- graph_agents_cli/dev/cmd_install.py +78 -0
- graph_agents_cli/dev/cmd_lint.py +119 -0
- graph_agents_cli/dev/cmd_playground.py +297 -0
- graph_agents_cli/dev/policy_check.py +1287 -0
- graph_agents_cli/eval/__init__.py +22 -0
- graph_agents_cli/eval/_client.py +670 -0
- graph_agents_cli/eval/_common.py +177 -0
- graph_agents_cli/eval/_judge.py +168 -0
- graph_agents_cli/eval/_judge_runner.py +238 -0
- graph_agents_cli/eval/_paths.py +212 -0
- graph_agents_cli/eval/checks.py +581 -0
- graph_agents_cli/eval/cmd_analyze.py +278 -0
- graph_agents_cli/eval/cmd_compare.py +284 -0
- graph_agents_cli/eval/cmd_eval_group.py +80 -0
- graph_agents_cli/eval/cmd_generate.py +558 -0
- graph_agents_cli/eval/cmd_grade.py +466 -0
- graph_agents_cli/eval/cmd_metric.py +156 -0
- graph_agents_cli/eval/cmd_run.py +370 -0
- graph_agents_cli/eval/cmd_submit.py +400 -0
- graph_agents_cli/eval/config.py +435 -0
- graph_agents_cli/eval/dataset.py +350 -0
- graph_agents_cli/eval/gate.py +420 -0
- graph_agents_cli/eval/transcript.py +192 -0
- graph_agents_cli/extension/__init__.py +13 -0
- graph_agents_cli/extension/_compat.py +86 -0
- graph_agents_cli/extension/_loader.py +293 -0
- graph_agents_cli/extension/_manifest.py +135 -0
- graph_agents_cli/extension/_overrides.py +195 -0
- graph_agents_cli/extension/_paths.py +91 -0
- graph_agents_cli/extension/_refs.py +193 -0
- graph_agents_cli/extension/_resolver.py +453 -0
- graph_agents_cli/extension/_schema.py +106 -0
- graph_agents_cli/extension/_spec.py +253 -0
- graph_agents_cli/extension/_sync.py +102 -0
- graph_agents_cli/extension/_trust.py +58 -0
- graph_agents_cli/extension/cmd_extension_add.py +259 -0
- graph_agents_cli/extension/cmd_extension_group.py +57 -0
- graph_agents_cli/extension/cmd_extension_list.py +56 -0
- graph_agents_cli/extension/cmd_extension_remove.py +61 -0
- graph_agents_cli/extension/cmd_extension_update.py +195 -0
- graph_agents_cli/info/__init__.py +13 -0
- graph_agents_cli/info/cmd_info.py +222 -0
- graph_agents_cli/infra/__init__.py +15 -0
- graph_agents_cli/infra/checks.py +1169 -0
- graph_agents_cli/infra/cmd_infra.py +103 -0
- graph_agents_cli/main.py +591 -0
- graph_agents_cli/peer/__init__.py +15 -0
- graph_agents_cli/peer/_generate.py +254 -0
- graph_agents_cli/peer/cmd_peer.py +1151 -0
- graph_agents_cli/run/__init__.py +13 -0
- graph_agents_cli/run/_local_server.py +1157 -0
- graph_agents_cli/run/_signals.py +141 -0
- graph_agents_cli/run/cmd_approvals.py +530 -0
- graph_agents_cli/run/cmd_run.py +1421 -0
- graph_agents_cli/scaffold/__init__.py +19 -0
- graph_agents_cli/scaffold/agents/README.md +24 -0
- graph_agents_cli/scaffold/agents/empty_py/.template/templateconfig.yaml +22 -0
- graph_agents_cli/scaffold/agents/langgraph/.env.example +292 -0
- graph_agents_cli/scaffold/agents/langgraph/.template/templateconfig.yaml +28 -0
- graph_agents_cli/scaffold/agents/langgraph/Dockerfile +59 -0
- graph_agents_cli/scaffold/agents/langgraph/Dockerfile.langgraph-server +59 -0
- graph_agents_cli/scaffold/agents/langgraph/README.md +571 -0
- graph_agents_cli/scaffold/agents/langgraph/api-policy.yaml +60 -0
- graph_agents_cli/scaffold/agents/langgraph/app/__init__.py +20 -0
- graph_agents_cli/scaffold/agents/langgraph/app/agent.py +174 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/__init__.py +15 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a.py +2162 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/a2a_client.py +1167 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/api_client.py +4220 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/approvals.py +1349 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/auth.py +1986 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/chat.py +2962 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/checkpointer.py +432 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/content.py +569 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/db.py +580 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/limits.py +203 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/metrics.py +231 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/middleware.py +361 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/model.py +611 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/playground.py +230 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/run_locks.py +459 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/structured.py +755 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/telemetry.py +681 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/threads.py +493 -0
- graph_agents_cli/scaffold/agents/langgraph/app/app_utils/token_exchange.py +959 -0
- graph_agents_cli/scaffold/agents/langgraph/app/fast_api_app.py +770 -0
- graph_agents_cli/scaffold/agents/langgraph/app/policies/__init__.py +55 -0
- graph_agents_cli/scaffold/agents/langgraph/app/policies/custom.py +97 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/__init__.py +46 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/example_api.py +92 -0
- graph_agents_cli/scaffold/agents/langgraph/app/tools/weather.py +33 -0
- graph_agents_cli/scaffold/agents/langgraph/langgraph.json +14 -0
- graph_agents_cli/scaffold/agents/langgraph/pyproject.toml +78 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/conftest.py +376 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/eval/datasets/basic-dataset.json +53 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/eval/eval_config.yaml +32 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/approval_graph.py +137 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_issuer.py +216 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/fake_openai.py +357 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_outcomes.py +569 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_a2a_relay.py +479 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_api_surface.py +812 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals.py +1367 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_approvals_server.py +794 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor.py +497 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_cross_actor_server.py +247 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_history_repair.py +278 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_model_apis.py +242 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_postgres.py +637 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_resilience_postgres.py +770 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_runtime_guardrails.py +854 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_e2e.py +340 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_server_runtime.py +989 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_answers.py +584 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_structured_server.py +222 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/integration/test_token_exchange_issuer.py +650 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/.results/.placeholder +0 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/README.md +22 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/conftest.py +21 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/load_test/load_test.py +81 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_client.py +824 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_a2a_scoping.py +724 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client.py +1214 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_client_hardening.py +716 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_api_policy_rpc.py +767 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_approval_ledger.py +1536 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_fake_model.py +115 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_jwt_policy.py +991 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_limits.py +310 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging.py +148 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_logging_hardening.py +271 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_policy.py +378 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_resilience.py +610 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_server_auth.py +702 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_structured.py +673 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_telemetry.py +404 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_thread_listing.py +255 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_threads.py +268 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_token_exchange.py +1320 -0
- graph_agents_cli/scaffold/agents/langgraph/tests/unit/test_untrusted_content.py +393 -0
- graph_agents_cli/scaffold/agents/langgraph/uv-fastapi.lock +2084 -0
- graph_agents_cli/scaffold/agents/langgraph/uv-langgraph-server.lock +2106 -0
- graph_agents_cli/scaffold/agents/langgraph/{{cookiecutter.agent_guidance_filename}} +129 -0
- graph_agents_cli/scaffold/base_templates/_shared/graph-agents-cli-manifest.yaml +36 -0
- graph_agents_cli/scaffold/base_templates/python/.dockerignore +32 -0
- graph_agents_cli/scaffold/base_templates/python/.github/CODEOWNERS +30 -0
- graph_agents_cli/scaffold/base_templates/python/.github/agent.env +7 -0
- graph_agents_cli/scaffold/base_templates/python/.github/workflows/pr_checks.yaml +214 -0
- graph_agents_cli/scaffold/base_templates/python/.gitignore +209 -0
- graph_agents_cli/scaffold/base_templates/python/tests/unit/test_dummy.py +23 -0
- graph_agents_cli/scaffold/base_templates/python/{{cookiecutter.agent_guidance_filename}} +35 -0
- graph_agents_cli/scaffold/cmd_scaffold_group.py +49 -0
- graph_agents_cli/scaffold/commands/__init__.py +13 -0
- graph_agents_cli/scaffold/commands/create.py +1424 -0
- graph_agents_cli/scaffold/commands/enhance.py +1652 -0
- graph_agents_cli/scaffold/commands/upgrade.py +570 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/agent.env +12 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/promote-to-prod.yaml +371 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/.github/workflows/staging.yaml +450 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-dev.yaml +43 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-prod.yaml +41 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/argocd/application-staging.yaml +43 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/.helmignore +14 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/Chart.yaml +21 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/examples/networkpolicy.yaml +103 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/NOTES.txt +48 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/_helpers.tpl +189 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/certificate.yaml +15 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/configmap.yaml +10 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/deployment.yaml +199 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/hpa.yaml +22 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/httproute.yaml +30 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/ingress.yaml +39 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/networkpolicy.yaml +48 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/pdb.yaml +13 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/postgresql-secret.yaml +37 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/service.yaml +15 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/serviceaccount.yaml +13 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/templates/servicemonitor.yaml +42 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-dev.yaml +22 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-prod.yaml +45 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values-staging.yaml +29 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/deployment/helm/{{cookiecutter.project_name}}/values.yaml +396 -0
- graph_agents_cli/scaffold/deployment_targets/kubernetes/python/tests/integration/test_chart.py +269 -0
- graph_agents_cli/scaffold/deployment_targets/none/README.md +5 -0
- graph_agents_cli/scaffold/deployment_targets/none/python/README.md +6 -0
- graph_agents_cli/scaffold/utils/__init__.py +13 -0
- graph_agents_cli/scaffold/utils/backup.py +212 -0
- graph_agents_cli/scaffold/utils/build_record.py +257 -0
- graph_agents_cli/scaffold/utils/cli_options.py +184 -0
- graph_agents_cli/scaffold/utils/fs.py +83 -0
- graph_agents_cli/scaffold/utils/generate_locks.py +214 -0
- graph_agents_cli/scaffold/utils/generation_metadata.py +88 -0
- graph_agents_cli/scaffold/utils/keyedit.py +768 -0
- graph_agents_cli/scaffold/utils/keymerge.py +537 -0
- graph_agents_cli/scaffold/utils/language.py +138 -0
- graph_agents_cli/scaffold/utils/lock_utils.py +94 -0
- graph_agents_cli/scaffold/utils/logging.py +77 -0
- graph_agents_cli/scaffold/utils/manifest.py +292 -0
- graph_agents_cli/scaffold/utils/merge.py +970 -0
- graph_agents_cli/scaffold/utils/merge3.py +216 -0
- graph_agents_cli/scaffold/utils/openapi_seed.py +199 -0
- graph_agents_cli/scaffold/utils/remote_template.py +376 -0
- graph_agents_cli/scaffold/utils/template.py +1352 -0
- graph_agents_cli/scaffold/utils/upgrade.py +894 -0
- graph_agents_cli/scaffold/utils/version.py +438 -0
- graph_agents_cli/secrets/__init__.py +15 -0
- graph_agents_cli/secrets/_apply.py +954 -0
- graph_agents_cli/secrets/_required.py +188 -0
- graph_agents_cli/secrets/cmd_secrets.py +211 -0
- graph_agents_cli/setup/__init__.py +13 -0
- graph_agents_cli/setup/_antigravity.py +221 -0
- graph_agents_cli/setup/cmd_auth.py +1030 -0
- graph_agents_cli/setup/cmd_dev_token.py +513 -0
- graph_agents_cli/setup/cmd_setup.py +428 -0
- graph_agents_cli/setup/cmd_update.py +140 -0
- graph_agents_cli/skills/__init__.py +13 -0
- graph_agents_cli/skills/_bundle.py +65 -0
- graph_agents_cli/skills/data/README.md +19 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/SKILL.md +357 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/github-settings.md +113 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/gitops.md +137 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/kubernetes.md +315 -0
- graph_agents_cli/skills/data/graph-agents-cli-deploy/references/secrets.md +160 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/SKILL.md +303 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/references/dataset_schema.md +282 -0
- graph_agents_cli/skills/data/graph-agents-cli-eval/references/metrics-guide.md +143 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/SKILL.md +659 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langchain-models.md +124 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/langgraph.md +235 -0
- graph_agents_cli/skills/data/graph-agents-cli-langgraph-code/references/template-contract.md +477 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/SKILL.md +231 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/references/langsmith.md +46 -0
- graph_agents_cli/skills/data/graph-agents-cli-observability/references/otel.md +59 -0
- graph_agents_cli/skills/data/graph-agents-cli-scaffold/SKILL.md +414 -0
- graph_agents_cli/skills/data/graph-agents-cli-scaffold/references/flags.md +134 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/SKILL.md +478 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/brainstorming.md +118 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/commands.md +419 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/extension.md +156 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/internals.md +67 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/spec-template.md +56 -0
- graph_agents_cli/skills/data/graph-agents-cli-workflow/references/terminology.md +119 -0
- graph_agents_cli/system/__init__.py +15 -0
- graph_agents_cli/system/_apply.py +519 -0
- graph_agents_cli/system/_checks.py +1023 -0
- graph_agents_cli/system/_deploy.py +215 -0
- graph_agents_cli/system/_model.py +363 -0
- graph_agents_cli/system/_system.py +664 -0
- graph_agents_cli/system/_views.py +208 -0
- graph_agents_cli/system/cmd_system.py +423 -0
- graph_agents_cli-0.3.1.dist-info/METADATA +162 -0
- graph_agents_cli-0.3.1.dist-info/RECORD +291 -0
- graph_agents_cli-0.3.1.dist-info/WHEEL +4 -0
- graph_agents_cli-0.3.1.dist-info/entry_points.txt +2 -0
- graph_agents_cli-0.3.1.dist-info/licenses/LICENSE +201 -0
- 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."""
|