keystone-cli 0.3.0__tar.gz → 0.5.0__tar.gz
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.
- keystone_cli-0.5.0/PKG-INFO +161 -0
- keystone_cli-0.5.0/README.md +140 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/pyproject.toml +23 -6
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/__main__.py +8 -2
- keystone_cli-0.5.0/src/keystone_cli/auth/api_key.py +48 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/auth/device_flow.py +19 -5
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/auth/token_store.py +31 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/agent.py +49 -36
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/login.py +14 -3
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/tool_credentials.py +100 -12
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/whoami.py +34 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/workspace.py +16 -4
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/runner.py +121 -8
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/scaffold.py +11 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/data-space/README.md.tmpl +53 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/data-space/agent.yaml.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/data-space/pkg/graph.py.tmpl +124 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/data-space/pyproject.toml.tmpl +24 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/data-space/tests/test_graph.py.tmpl +130 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/file-tools/README.md.tmpl +57 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/file-tools/agent.yaml.tmpl +27 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/file-tools/pkg/graph.py.tmpl +99 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/file-tools/pyproject.toml.tmpl +24 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/file-tools/tests/test_graph.py.tmpl +141 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui/README.md.tmpl +49 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui/agent.yaml.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui/pkg/graph.py.tmpl +61 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui/pyproject.toml.tmpl +24 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui/tests/test_graph.py.tmpl +84 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/rag-qa/env.tmpl +10 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/rag-qa/gitignore.tmpl +7 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/rag-qa/pkg/__init__.py.tmpl +0 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/rag-qa/tests/conftest.py.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/skill/env.tmpl +10 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/skill/gitignore.tmpl +7 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/skill/pkg/__init__.py.tmpl +0 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/skill/tests/conftest.py.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/tool-agent/env.tmpl +10 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/tool-agent/gitignore.tmpl +7 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/tool-agent/pkg/__init__.py.tmpl +0 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/tool-agent/tests/conftest.py.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/README.md.tmpl +49 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/agent.yaml.tmpl +19 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/env.tmpl +10 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/gitignore.tmpl +7 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/pkg/__init__.py.tmpl +0 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/pkg/graph.py.tmpl +170 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/pyproject.toml.tmpl +24 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/tests/conftest.py.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/ui-card/tests/test_graph.py.tmpl +73 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/README.md.tmpl +54 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/agent.yaml.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/env.tmpl +10 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/gitignore.tmpl +7 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/pkg/__init__.py.tmpl +0 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/pkg/graph.py.tmpl +101 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/pyproject.toml.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/tests/conftest.py.tmpl +25 -0
- keystone_cli-0.5.0/src/keystone_cli/templates/user-tools/tests/test_graph.py.tmpl +117 -0
- keystone_cli-0.5.0/src/keystone_cli.egg-info/PKG-INFO +161 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli.egg-info/SOURCES.txt +48 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli.egg-info/requires.txt +1 -1
- keystone_cli-0.5.0/tests/test_api_key.py +284 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_deploy.py +32 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_doctor.py +25 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_hitl_approver_cli.py +8 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_init.py +11 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_offline.py +129 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_tool_credentials.py +62 -0
- keystone_cli-0.3.0/PKG-INFO +0 -15
- keystone_cli-0.3.0/src/keystone_cli.egg-info/PKG-INFO +0 -15
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/setup.cfg +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/__init__.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/_build_env.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/_jsonout.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/_stdio.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/_tls.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/_version.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/agent_logs.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/agent_skills.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/auth/__init__.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/__init__.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/dev.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/kb.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/kb_metadata.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/prompt.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/commands/skills.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/devloop.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/fetch.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/manifest_ref.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/platform_client.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/run_debug.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/skills/keystone-debug/SKILL.md +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/env.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/blank/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/guardrails → keystone_cli-0.5.0/src/keystone_cli/templates/data-space}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/guardrails → keystone_cli-0.5.0/src/keystone_cli/templates/data-space}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/guardrails → keystone_cli-0.5.0/src/keystone_cli/templates/data-space}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/guardrails → keystone_cli-0.5.0/src/keystone_cli/templates/data-space}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/hitl → keystone_cli-0.5.0/src/keystone_cli/templates/file-tools}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/hitl → keystone_cli-0.5.0/src/keystone_cli/templates/file-tools}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/hitl → keystone_cli-0.5.0/src/keystone_cli/templates/file-tools}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/hitl → keystone_cli-0.5.0/src/keystone_cli/templates/file-tools}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/kb-builder → keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/kb-builder → keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/kb-builder → keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/kb-builder → keystone_cli-0.5.0/src/keystone_cli/templates/generative-ui}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/guardrails/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/guardrails/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm-streaming → keystone_cli-0.5.0/src/keystone_cli/templates/guardrails}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm-streaming → keystone_cli-0.5.0/src/keystone_cli/templates/guardrails}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm-streaming → keystone_cli-0.5.0/src/keystone_cli/templates/guardrails}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/guardrails/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/guardrails/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm-streaming → keystone_cli-0.5.0/src/keystone_cli/templates/guardrails}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/guardrails/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/hitl/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/hitl/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm → keystone_cli-0.5.0/src/keystone_cli/templates/hitl}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm → keystone_cli-0.5.0/src/keystone_cli/templates/hitl}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm → keystone_cli-0.5.0/src/keystone_cli/templates/hitl}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/hitl/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/hitl/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/llm → keystone_cli-0.5.0/src/keystone_cli/templates/hitl}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/hitl/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/kb-builder/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/kb-builder/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory-service → keystone_cli-0.5.0/src/keystone_cli/templates/kb-builder}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory-service → keystone_cli-0.5.0/src/keystone_cli/templates/kb-builder}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory-service → keystone_cli-0.5.0/src/keystone_cli/templates/kb-builder}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/kb-builder/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/kb-builder/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory-service → keystone_cli-0.5.0/src/keystone_cli/templates/kb-builder}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/kb-builder/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/ocr → keystone_cli-0.5.0/src/keystone_cli/templates/llm}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/ocr → keystone_cli-0.5.0/src/keystone_cli/templates/llm}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/ocr → keystone_cli-0.5.0/src/keystone_cli/templates/llm}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm/system-prompt.txt.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/ocr → keystone_cli-0.5.0/src/keystone_cli/templates/llm}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm-streaming/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm-streaming/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory → keystone_cli-0.5.0/src/keystone_cli/templates/llm-streaming}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory → keystone_cli-0.5.0/src/keystone_cli/templates/llm-streaming}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory → keystone_cli-0.5.0/src/keystone_cli/templates/llm-streaming}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm-streaming/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm-streaming/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm-streaming/system-prompt.txt.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/memory → keystone_cli-0.5.0/src/keystone_cli/templates/llm-streaming}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/llm-streaming/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/skill → keystone_cli-0.5.0/src/keystone_cli/templates/memory}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/skill → keystone_cli-0.5.0/src/keystone_cli/templates/memory}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/skill → keystone_cli-0.5.0/src/keystone_cli/templates/memory}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/skill → keystone_cli-0.5.0/src/keystone_cli/templates/memory}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory-service/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory-service/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/rag-qa → keystone_cli-0.5.0/src/keystone_cli/templates/memory-service}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/rag-qa → keystone_cli-0.5.0/src/keystone_cli/templates/memory-service}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/rag-qa → keystone_cli-0.5.0/src/keystone_cli/templates/memory-service}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory-service/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory-service/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/rag-qa → keystone_cli-0.5.0/src/keystone_cli/templates/memory-service}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/memory-service/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/ocr/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/ocr/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/tool-agent → keystone_cli-0.5.0/src/keystone_cli/templates/ocr}/env.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/tool-agent → keystone_cli-0.5.0/src/keystone_cli/templates/ocr}/gitignore.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/tool-agent → keystone_cli-0.5.0/src/keystone_cli/templates/ocr}/pkg/__init__.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/ocr/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/ocr/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0/src/keystone_cli/templates/tool-agent → keystone_cli-0.5.0/src/keystone_cli/templates/ocr}/tests/conftest.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/ocr/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/rag-qa/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/rag-qa/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/rag-qa/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/rag-qa/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/rag-qa/system-prompt.txt.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/rag-qa/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/skill/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/skill/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/skill/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/skill/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/skill/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/tool-agent/README.md.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/tool-agent/agent.yaml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/tool-agent/pkg/graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/tool-agent/pyproject.toml.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/tool-agent/system-prompt.txt.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli/templates/tool-agent/tests/test_graph.py.tmpl +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli.egg-info/dependency_links.txt +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli.egg-info/entry_points.txt +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/src/keystone_cli.egg-info/top_level.txt +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_agent.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_agent_manifest_cmd.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_agent_test_cmd.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_assistant_provenance_and_flags.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_auth.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_build_progress.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_ci_token.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_config_env_mismatch.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_dev.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_encoding.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_fetch.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_help_quality.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_hitl_decisions_cli.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_invoke.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_invoke_stream.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_json_output.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_jsonout.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_kb_commands.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_kb_metadata_commands.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_login_command.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_logs.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_platform_client.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_prompt_commands.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_publish.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_retire_delete.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_run_debug.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_runs.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_skills.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_status.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_stdio.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_template_prompt_guard.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_template_unit_tests.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_threads.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_tls.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_traces.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_version.py +0 -0
- {keystone_cli-0.3.0 → keystone_cli-0.5.0}/tests/test_workspace.py +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: keystone-cli
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Keystone CLI — build, test, deploy and operate pro-code agents, and manage knowledge bases, prompts, tool credentials and skills on the Keystone platform.
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
7
|
+
Classifier: Environment :: Console
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: keystone-agent-sdk<0.14,>=0.13.27
|
|
12
|
+
Requires-Dist: keystone-request-context<0.4,>=0.3
|
|
13
|
+
Requires-Dist: typer<1,>=0.12
|
|
14
|
+
Requires-Dist: httpx<1,>=0.27
|
|
15
|
+
Requires-Dist: truststore<1,>=0.10
|
|
16
|
+
Requires-Dist: pytest<9,>=8
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest<9,>=8; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-cov<7,>=6; extra == "dev"
|
|
20
|
+
Requires-Dist: ruff==0.15.15; extra == "dev"
|
|
21
|
+
|
|
22
|
+
# keystone-cli
|
|
23
|
+
|
|
24
|
+
`keystone` is the command-line tool of the Keystone platform. Use it to build, test, deploy and operate
|
|
25
|
+
pro-code agents. You can also manage knowledge bases, prompts, tool credentials and skills with it.
|
|
26
|
+
|
|
27
|
+
The CLI includes the Keystone agent SDK (`keystone-agent-sdk`). An agent project that you create with
|
|
28
|
+
the CLI uses that SDK.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
The CLI needs Python 3.12 or later.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install keystone-cli
|
|
36
|
+
keystone --version
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Get started
|
|
40
|
+
|
|
41
|
+
1. Log in. The command opens your browser and keeps your session for later commands.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
keystone login
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
2. Select the workspace that your commands use.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
keystone workspace use <name>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
3. Create an agent project from a template, then check it.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
keystone agent init my-agent --template llm
|
|
57
|
+
keystone agent validate my-agent
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
4. Run the unit tests of the agent on your computer.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
keystone agent test my-agent
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
5. Deploy the agent, make the new version Live, and call it.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
keystone agent deploy my-agent --publish --wait
|
|
70
|
+
keystone agent invoke my-agent --input '{"prompt": "hi"}'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
To see the fields of `agent.yaml`, run `keystone agent manifest`. Every command has `--help`.
|
|
74
|
+
|
|
75
|
+
## CI with a service account
|
|
76
|
+
|
|
77
|
+
Use a platform service account in CI. The CLI sends its API key as `Authorization: Bearer <key>`.
|
|
78
|
+
A CI job does not run `keystone login`.
|
|
79
|
+
|
|
80
|
+
Before you start, an admin gives the service account three permissions on its workspace, one time:
|
|
81
|
+
|
|
82
|
+
| Permission | Resource | Why |
|
|
83
|
+
| --- | --- | --- |
|
|
84
|
+
| `agent:register` | the workspace of the service account | Register a new agent |
|
|
85
|
+
| `agent-vb:version:create` | the workspace of the service account | Upload a bundle |
|
|
86
|
+
| `agent:read` | the workspace of the service account | Find an agent by name (`delete`, `versions`, `status` and others) |
|
|
87
|
+
|
|
88
|
+
In the portal, open **Settings → Service Accounts**, open the access dialog of the account, and
|
|
89
|
+
select **This workspace** as the resource.
|
|
90
|
+
|
|
91
|
+
`deploy --publish`, `invoke`, `runs` and `threads` work without `agent:read` on the workspace. A
|
|
92
|
+
service account can not read agent logs: `keystone agent logs` needs `trace:read`, which only a user
|
|
93
|
+
can hold.
|
|
94
|
+
|
|
95
|
+
When the service account deploys a new agent, it gets all other permissions on that agent
|
|
96
|
+
automatically: read, invoke, and version create, deploy, publish and retire. To invoke an agent that
|
|
97
|
+
another user created, an admin must give `agent:invoke` on that agent.
|
|
98
|
+
|
|
99
|
+
Set these variables in the CI job:
|
|
100
|
+
|
|
101
|
+
| Variable | Value |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| `KEYSTONE_API_KEY` | The API key of the service account. Keep it in a masked CI secret. |
|
|
104
|
+
| `KEYSTONE_WORKSPACE_ID` | The UUID of the target workspace. |
|
|
105
|
+
| `KEYSTONE_API_BASE` | Optional. The platform API URL. The default is the URL of your CLI package. |
|
|
106
|
+
| `KEYSTONE_AGENT_API_BASE` | Optional. The agent API URL for `invoke`, `runs` and `threads`. |
|
|
107
|
+
|
|
108
|
+
Then do these steps:
|
|
109
|
+
|
|
110
|
+
1. Make sure that the CLI uses the service account.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
export KEYSTONE_API_KEY=<sa-api-key>
|
|
114
|
+
export KEYSTONE_WORKSPACE_ID=<workspace-uuid>
|
|
115
|
+
keystone whoami
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
2. Deploy the agent.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
keystone agent deploy my-agent --publish --wait
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
3. Call the agent.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
keystone agent invoke my-agent --input '{"prompt": "ping"}'
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Do not put the API key on the command line. The shell history and the CI log can show it.
|
|
131
|
+
|
|
132
|
+
These rules apply when `KEYSTONE_API_KEY` is set:
|
|
133
|
+
|
|
134
|
+
- The key has priority over `KEYSTONE_TOKEN` and over a saved login.
|
|
135
|
+
- The CLI does not save the key to a file, and it does not show the key.
|
|
136
|
+
`keystone whoami` shows only the key ID.
|
|
137
|
+
- The CLI does not select a workspace for you. `--workspace-id` has priority over `KEYSTONE_WORKSPACE_ID`.
|
|
138
|
+
`KEYSTONE_WORKSPACE_ID` has priority over the saved workspace.
|
|
139
|
+
- `keystone workspace list` and `keystone workspace use` do not operate with a key.
|
|
140
|
+
|
|
141
|
+
## Commands
|
|
142
|
+
|
|
143
|
+
| Command | What it does |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| `keystone login`, `keystone whoami` | Log in, and show your user. |
|
|
146
|
+
| `keystone workspace` | List and select the workspace that your commands use. |
|
|
147
|
+
| `keystone agent` | Develop and test an agent locally (`init`, `validate`, `run`, `test`, `manifest`), ship it (`deploy`, `publish`, `status`, `retire`, `delete`), and operate and debug it (`invoke`, `logs`, `fetch`, `doctor`, `runs`, `hitl`, `traces`, `threads`). |
|
|
148
|
+
| `keystone dev` | Run the graph of the agent locally again each time you save a file. |
|
|
149
|
+
| `keystone kb` | Create and manage knowledge bases. |
|
|
150
|
+
| `keystone prompt` | Manage the prompts of a workspace. |
|
|
151
|
+
| `keystone tool-credentials` | Manage the credentials that the catalogue tools of your agents use. |
|
|
152
|
+
| `keystone skills` | Install Claude Code skills for work on agents. |
|
|
153
|
+
| `keystone version` | Show the CLI version, the target environment and the version of the bundled agent SDK. |
|
|
154
|
+
|
|
155
|
+
## When a run fails
|
|
156
|
+
|
|
157
|
+
Start with this command. It shows the steps, the errors and the logs of one run.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
keystone agent runs debug <agent> <run_id>
|
|
161
|
+
```
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# keystone-cli
|
|
2
|
+
|
|
3
|
+
`keystone` is the command-line tool of the Keystone platform. Use it to build, test, deploy and operate
|
|
4
|
+
pro-code agents. You can also manage knowledge bases, prompts, tool credentials and skills with it.
|
|
5
|
+
|
|
6
|
+
The CLI includes the Keystone agent SDK (`keystone-agent-sdk`). An agent project that you create with
|
|
7
|
+
the CLI uses that SDK.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
The CLI needs Python 3.12 or later.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install keystone-cli
|
|
15
|
+
keystone --version
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Get started
|
|
19
|
+
|
|
20
|
+
1. Log in. The command opens your browser and keeps your session for later commands.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
keystone login
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
2. Select the workspace that your commands use.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
keystone workspace use <name>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
3. Create an agent project from a template, then check it.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
keystone agent init my-agent --template llm
|
|
36
|
+
keystone agent validate my-agent
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
4. Run the unit tests of the agent on your computer.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
keystone agent test my-agent
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
5. Deploy the agent, make the new version Live, and call it.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
keystone agent deploy my-agent --publish --wait
|
|
49
|
+
keystone agent invoke my-agent --input '{"prompt": "hi"}'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To see the fields of `agent.yaml`, run `keystone agent manifest`. Every command has `--help`.
|
|
53
|
+
|
|
54
|
+
## CI with a service account
|
|
55
|
+
|
|
56
|
+
Use a platform service account in CI. The CLI sends its API key as `Authorization: Bearer <key>`.
|
|
57
|
+
A CI job does not run `keystone login`.
|
|
58
|
+
|
|
59
|
+
Before you start, an admin gives the service account three permissions on its workspace, one time:
|
|
60
|
+
|
|
61
|
+
| Permission | Resource | Why |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| `agent:register` | the workspace of the service account | Register a new agent |
|
|
64
|
+
| `agent-vb:version:create` | the workspace of the service account | Upload a bundle |
|
|
65
|
+
| `agent:read` | the workspace of the service account | Find an agent by name (`delete`, `versions`, `status` and others) |
|
|
66
|
+
|
|
67
|
+
In the portal, open **Settings → Service Accounts**, open the access dialog of the account, and
|
|
68
|
+
select **This workspace** as the resource.
|
|
69
|
+
|
|
70
|
+
`deploy --publish`, `invoke`, `runs` and `threads` work without `agent:read` on the workspace. A
|
|
71
|
+
service account can not read agent logs: `keystone agent logs` needs `trace:read`, which only a user
|
|
72
|
+
can hold.
|
|
73
|
+
|
|
74
|
+
When the service account deploys a new agent, it gets all other permissions on that agent
|
|
75
|
+
automatically: read, invoke, and version create, deploy, publish and retire. To invoke an agent that
|
|
76
|
+
another user created, an admin must give `agent:invoke` on that agent.
|
|
77
|
+
|
|
78
|
+
Set these variables in the CI job:
|
|
79
|
+
|
|
80
|
+
| Variable | Value |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `KEYSTONE_API_KEY` | The API key of the service account. Keep it in a masked CI secret. |
|
|
83
|
+
| `KEYSTONE_WORKSPACE_ID` | The UUID of the target workspace. |
|
|
84
|
+
| `KEYSTONE_API_BASE` | Optional. The platform API URL. The default is the URL of your CLI package. |
|
|
85
|
+
| `KEYSTONE_AGENT_API_BASE` | Optional. The agent API URL for `invoke`, `runs` and `threads`. |
|
|
86
|
+
|
|
87
|
+
Then do these steps:
|
|
88
|
+
|
|
89
|
+
1. Make sure that the CLI uses the service account.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
export KEYSTONE_API_KEY=<sa-api-key>
|
|
93
|
+
export KEYSTONE_WORKSPACE_ID=<workspace-uuid>
|
|
94
|
+
keystone whoami
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
2. Deploy the agent.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
keystone agent deploy my-agent --publish --wait
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. Call the agent.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
keystone agent invoke my-agent --input '{"prompt": "ping"}'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Do not put the API key on the command line. The shell history and the CI log can show it.
|
|
110
|
+
|
|
111
|
+
These rules apply when `KEYSTONE_API_KEY` is set:
|
|
112
|
+
|
|
113
|
+
- The key has priority over `KEYSTONE_TOKEN` and over a saved login.
|
|
114
|
+
- The CLI does not save the key to a file, and it does not show the key.
|
|
115
|
+
`keystone whoami` shows only the key ID.
|
|
116
|
+
- The CLI does not select a workspace for you. `--workspace-id` has priority over `KEYSTONE_WORKSPACE_ID`.
|
|
117
|
+
`KEYSTONE_WORKSPACE_ID` has priority over the saved workspace.
|
|
118
|
+
- `keystone workspace list` and `keystone workspace use` do not operate with a key.
|
|
119
|
+
|
|
120
|
+
## Commands
|
|
121
|
+
|
|
122
|
+
| Command | What it does |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| `keystone login`, `keystone whoami` | Log in, and show your user. |
|
|
125
|
+
| `keystone workspace` | List and select the workspace that your commands use. |
|
|
126
|
+
| `keystone agent` | Develop and test an agent locally (`init`, `validate`, `run`, `test`, `manifest`), ship it (`deploy`, `publish`, `status`, `retire`, `delete`), and operate and debug it (`invoke`, `logs`, `fetch`, `doctor`, `runs`, `hitl`, `traces`, `threads`). |
|
|
127
|
+
| `keystone dev` | Run the graph of the agent locally again each time you save a file. |
|
|
128
|
+
| `keystone kb` | Create and manage knowledge bases. |
|
|
129
|
+
| `keystone prompt` | Manage the prompts of a workspace. |
|
|
130
|
+
| `keystone tool-credentials` | Manage the credentials that the catalogue tools of your agents use. |
|
|
131
|
+
| `keystone skills` | Install Claude Code skills for work on agents. |
|
|
132
|
+
| `keystone version` | Show the CLI version, the target environment and the version of the bundled agent SDK. |
|
|
133
|
+
|
|
134
|
+
## When a run fails
|
|
135
|
+
|
|
136
|
+
Start with this command. It shows the steps, the errors and the logs of one run.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
keystone agent runs debug <agent> <run_id>
|
|
140
|
+
```
|
|
@@ -4,13 +4,26 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "keystone-cli"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Keystone
|
|
7
|
+
version = "0.5.0"
|
|
8
|
+
description = "Keystone CLI — build, test, deploy and operate pro-code agents, and manage knowledge bases, prompts, tool credentials and skills on the Keystone platform."
|
|
9
|
+
# The PyPI project page shows this file (it had no description before 0.4.0). It is public: no internal
|
|
10
|
+
# hosts, entity ids or workspace ids in it.
|
|
11
|
+
readme = "README.md"
|
|
9
12
|
requires-python = ">=3.12"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.12",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
10
19
|
dependencies = [
|
|
11
20
|
# Pinned to a compatible range: on an index (Artifact Registry) an unpinned name resolves to
|
|
12
21
|
# ANY published version — the wheel's metadata is the only pin that travels with it.
|
|
13
|
-
|
|
22
|
+
# 0.4.2 needs 0.13.22: `ui.generative_ui_tools` for the generative-ui template (FDP-6967).
|
|
23
|
+
# 0.4.3 needs 0.13.23: the file-tools template's nine tools, `attachments_as_content()` and
|
|
24
|
+
# `testing.FakeFileArtifact` (FDP-6967).
|
|
25
|
+
# 0.4.5 needs 0.13.26: `clients.kb_tools()` gives two KB tools, kb_search + kb_read_around (FDP-7133).
|
|
26
|
+
"keystone-agent-sdk>=0.13.27,<0.14",
|
|
14
27
|
# Transitive (the SDK's building-block clients) + used directly by `run` to set a local
|
|
15
28
|
# caller-identity ContextVar and to patch the clients for --offline. uv sources are NOT
|
|
16
29
|
# transitive, so declare it directly (cf. services/llm-gateway).
|
|
@@ -34,14 +47,18 @@ dev = [
|
|
|
34
47
|
]
|
|
35
48
|
|
|
36
49
|
# The `keystone` command (binary) — `typer.Typer` instances are callable, so the entry points
|
|
37
|
-
# straight at the app.
|
|
38
|
-
# from the repo
|
|
50
|
+
# straight at the app. Published to PyPI as `keystone-cli` (prod) and to Artifact Registry per env
|
|
51
|
+
# (`keystone-cli-<env>`); from the repo: `uv tool install ./libs/python/keystone-cli`.
|
|
39
52
|
[project.scripts]
|
|
40
53
|
keystone = "keystone_cli.__main__:app"
|
|
41
54
|
|
|
42
55
|
[tool.uv.sources]
|
|
43
56
|
keystone-agent-sdk = { path = "../agent_sdk" }
|
|
44
57
|
keystone-request-context = { path = "../request_context" }
|
|
58
|
+
# The SDK's dependency since 0.13.22 (FDP-6967); uv sources are NOT transitive.
|
|
59
|
+
keystone-agui = { path = "../agui" }
|
|
60
|
+
# The SDK's dependency since 0.13.23 (FDP-6967); uv sources are NOT transitive.
|
|
61
|
+
keystone-agent-tools = { path = "../agent_tools" }
|
|
45
62
|
|
|
46
63
|
[tool.setuptools.packages.find]
|
|
47
64
|
where = ["src"]
|
|
@@ -51,7 +68,7 @@ where = ["src"]
|
|
|
51
68
|
keystone_cli = ["templates/*/*.tmpl", "templates/*/pkg/*.tmpl", "templates/*/tests/*.tmpl", "skills/*/SKILL.md"]
|
|
52
69
|
|
|
53
70
|
[tool.ruff]
|
|
54
|
-
target-version = "0.
|
|
71
|
+
target-version = "0.5.0"
|
|
55
72
|
line-length = 120
|
|
56
73
|
|
|
57
74
|
[tool.ruff.lint]
|
|
@@ -41,8 +41,11 @@ Environment:
|
|
|
41
41
|
use one file per environment
|
|
42
42
|
KEYSTONE_API_BASE platform API URL (overrides the saved one)
|
|
43
43
|
KEYSTONE_AGENT_API_BASE agent API URL: invoke, runs, hitl, threads
|
|
44
|
+
KEYSTONE_API_KEY service-account API key for CI; used as given,
|
|
45
|
+
never saved, wins over every other credential
|
|
46
|
+
KEYSTONE_WORKSPACE_ID workspace UUID (overrides the saved one;
|
|
47
|
+
required with KEYSTONE_API_KEY)
|
|
44
48
|
KEYSTONE_TOKEN access token, used as given and never renewed
|
|
45
|
-
(for CI)
|
|
46
49
|
KEYSTONE_ISSUER login: Keycloak realm URL
|
|
47
50
|
KEYSTONE_CLIENT_ID login: client id
|
|
48
51
|
KEYSTONE_CLIENT_SECRET login --client-credentials: client secret
|
|
@@ -61,7 +64,10 @@ Exit codes:
|
|
|
61
64
|
on stdout and the message on stderr."""
|
|
62
65
|
|
|
63
66
|
app = typer.Typer(
|
|
64
|
-
help=
|
|
67
|
+
help=(
|
|
68
|
+
"Keystone CLI — build, test, deploy and operate pro-code agents, and manage knowledge bases, "
|
|
69
|
+
"prompts, tool credentials and skills."
|
|
70
|
+
),
|
|
65
71
|
epilog=EPILOG,
|
|
66
72
|
no_args_is_help=True,
|
|
67
73
|
add_completion=False,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Platform service-account API key from the environment — the CI credential (FDP-7177 G6).
|
|
2
|
+
|
|
3
|
+
A platform SA API key (``ak_<env>_<id>.<secret>``, minted in the portal) goes on the wire as
|
|
4
|
+
``Authorization: Bearer <key>``. Kong validates it and stamps ``X-Service-Account-ID``; the CLI never
|
|
5
|
+
decodes it, renews it, or talks to Keycloak for it.
|
|
6
|
+
|
|
7
|
+
Rules this module exists to keep in ONE place:
|
|
8
|
+
|
|
9
|
+
* It is read ONLY from ``KEYSTONE_API_KEY`` — never a flag (argv shows up in ``ps``, shell history
|
|
10
|
+
and CI logs) and never the config file (a persisted key outlives the job that owns it).
|
|
11
|
+
* It is never printed. :func:`describe` returns the key id (the part before the dot, which the portal
|
|
12
|
+
and every audit event already show) or a short masked prefix — never the secret.
|
|
13
|
+
* An API key has no ``/users/me`` (platform refuses it), so the workspace cannot be picked
|
|
14
|
+
interactively: it must come from ``--workspace-id`` / ``KEYSTONE_WORKSPACE_ID`` / the config.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
from collections.abc import Mapping
|
|
21
|
+
|
|
22
|
+
# An env var NAME, not a value (same suppressions as device_flow.ENV_TOKEN, for the same reason).
|
|
23
|
+
ENV_API_KEY = "KEYSTONE_API_KEY" # noqa: S105 # pragma: allowlist secret # nosec B105
|
|
24
|
+
|
|
25
|
+
_MASKED_CHARS = 6
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def from_env(env: Mapping[str, str] | None = None) -> str:
|
|
29
|
+
"""The API key from ``KEYSTONE_API_KEY``, stripped; ``""`` when unset or blank."""
|
|
30
|
+
env = os.environ if env is None else env
|
|
31
|
+
return (env.get(ENV_API_KEY) or "").strip()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def in_use(env: Mapping[str, str] | None = None) -> bool:
|
|
35
|
+
"""True when this process authenticates with a service-account API key."""
|
|
36
|
+
return bool(from_env(env))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def describe(key: str) -> str:
|
|
40
|
+
"""A printable handle for ``key`` that never contains the secret.
|
|
41
|
+
|
|
42
|
+
Platform keys are ``<key id>.<secret>`` and the key id (``ak_<env>_<random>``) is public: the
|
|
43
|
+
portal lists it and audit events carry it. Anything else is shown as a short masked prefix.
|
|
44
|
+
"""
|
|
45
|
+
key_id, sep, secret = key.partition(".")
|
|
46
|
+
if sep and key_id.startswith("ak_") and secret:
|
|
47
|
+
return key_id
|
|
48
|
+
return f"{key[:_MASKED_CHARS]}…" if len(key) > _MASKED_CHARS * 2 else "…"
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Pure-ish transport logic (takes an ``httpx.Client`` + injectable ``sleep``/``now``/``env`` for tests).
|
|
4
4
|
The Typer command in ``commands/login`` handles printing + storing. :func:`get_access_token` is the
|
|
5
|
-
read path every command uses, and it knows
|
|
5
|
+
read path every command uses, and it knows four ways to produce a bearer:
|
|
6
6
|
|
|
7
|
+
0. ``KEYSTONE_API_KEY`` — a platform service-account API key (FDP-7177). Highest precedence, used
|
|
8
|
+
verbatim, never refreshed, never written to disk. The recommended CI path (see ``auth/api_key``).
|
|
7
9
|
1. ``KEYSTONE_TOKEN`` in the environment — used verbatim, never refreshed, never written to disk.
|
|
8
10
|
The CI escape hatch for when something else already minted a token.
|
|
9
11
|
2. the cached access token, while it is still fresh;
|
|
@@ -20,6 +22,7 @@ from typing import Any
|
|
|
20
22
|
|
|
21
23
|
import httpx
|
|
22
24
|
|
|
25
|
+
from keystone_cli.auth import api_key
|
|
23
26
|
from keystone_cli.auth.token_store import AuthConfig
|
|
24
27
|
|
|
25
28
|
_DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code"
|
|
@@ -35,6 +38,8 @@ ENV_TOKEN = "KEYSTONE_TOKEN" # noqa: S105 # nosec B105
|
|
|
35
38
|
# The client-credentials secret is read ONLY from the environment, never from a flag: a value on
|
|
36
39
|
# argv is visible in `ps`, lands in shell history, and CI runners echo command lines into build logs.
|
|
37
40
|
ENV_CLIENT_SECRET = "KEYSTONE_CLIENT_SECRET" # noqa: S105 # pragma: allowlist secret # nosec B105
|
|
41
|
+
# Platform service-account API key (FDP-7177) — re-exported so callers have one auth namespace.
|
|
42
|
+
ENV_API_KEY = api_key.ENV_API_KEY
|
|
38
43
|
|
|
39
44
|
MODE_DEVICE = "device"
|
|
40
45
|
MODE_CLIENT_CREDENTIALS = "client_credentials"
|
|
@@ -155,12 +160,20 @@ def get_access_token(
|
|
|
155
160
|
) -> str:
|
|
156
161
|
"""Return a valid bearer. Every command goes through here.
|
|
157
162
|
|
|
158
|
-
Order, and why:
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
Order, and why: a service-account ``KEYSTONE_API_KEY`` first (FDP-7177 — the CI identity is the
|
|
164
|
+
one the job was given, never a person's), then an explicitly injected ``KEYSTONE_TOKEN``. Both win
|
|
165
|
+
over the cache, because in CI a stale ``~/.keystone/config.json`` left in the image would
|
|
166
|
+
otherwise silently deploy as the wrong identity. Then the cache while fresh, then renewal per
|
|
167
|
+
:attr:`AuthConfig.auth_mode`.
|
|
161
168
|
"""
|
|
162
169
|
env = os.environ if env is None else env
|
|
163
170
|
|
|
171
|
+
key = api_key.from_env(env)
|
|
172
|
+
if key:
|
|
173
|
+
# Same contract as KEYSTONE_TOKEN below: verbatim, no request, nothing saved — not even onto
|
|
174
|
+
# the in-memory config, so a later save() for another reason cannot carry it to disk.
|
|
175
|
+
return key
|
|
176
|
+
|
|
164
177
|
injected = (env.get(ENV_TOKEN) or "").strip()
|
|
165
178
|
if injected:
|
|
166
179
|
# Used verbatim: we hold no refresh token for it and it is not ours to renew. Deliberately
|
|
@@ -185,7 +198,8 @@ def get_access_token(
|
|
|
185
198
|
else:
|
|
186
199
|
if not cfg.refresh_token:
|
|
187
200
|
raise DeviceFlowError(
|
|
188
|
-
f"not logged in — run `keystone login
|
|
201
|
+
f"not logged in — run `keystone login`; for CI set {ENV_API_KEY} (service account, "
|
|
202
|
+
f"recommended), or set {ENV_TOKEN} / use --client-credentials"
|
|
189
203
|
)
|
|
190
204
|
token = refresh_access_token(client, cfg.issuer, cfg.client_id, cfg.refresh_token)
|
|
191
205
|
finally:
|
|
@@ -14,6 +14,7 @@ from dataclasses import asdict, dataclass, fields
|
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
16
|
from keystone_cli._build_env import BUILD_ENV
|
|
17
|
+
from keystone_cli.auth import api_key
|
|
17
18
|
|
|
18
19
|
# Baked platform defaults so `keystone login` works with NO flags (like `aws sso login`), PER ENV.
|
|
19
20
|
# NOT secrets — client id is a public identifier, issuer/api are public URLs. The env is stamped into
|
|
@@ -155,6 +156,36 @@ def platform_base(cfg: AuthConfig, override: str | None = None) -> str:
|
|
|
155
156
|
return (override or os.environ.get("KEYSTONE_API_BASE") or cfg.api_base or DEFAULT_API_BASE).rstrip("/")
|
|
156
157
|
|
|
157
158
|
|
|
159
|
+
def agent_platform_base(cfg: AuthConfig, control_base: str) -> str:
|
|
160
|
+
"""Agent data-plane URL (invoke/runs/hitl/threads): ``KEYSTONE_AGENT_API_BASE``, then the saved
|
|
161
|
+
one, then ``control_base`` (FDP-3072 §11.4b)."""
|
|
162
|
+
return (os.environ.get("KEYSTONE_AGENT_API_BASE") or cfg.agent_api_base or control_base).rstrip("/")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# FDP-7177 — workspace from the environment, for CI. A service-account API key cannot reach
|
|
166
|
+
# `/users/me`, so it has no picker: this (or --workspace-id, or a saved one) is how it names its workspace.
|
|
167
|
+
ENV_WORKSPACE_ID = "KEYSTONE_WORKSPACE_ID"
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def resolve_workspace(cfg: AuthConfig, override: str | None = None) -> str:
|
|
171
|
+
"""Workspace a command targets: ``override`` (``--workspace-id``), then ``KEYSTONE_WORKSPACE_ID``,
|
|
172
|
+
then the one saved by ``keystone workspace use``. ``""`` when none. The one place this order is written."""
|
|
173
|
+
return (override or os.environ.get(ENV_WORKSPACE_ID, "").strip() or cfg.workspace_id).strip()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def no_workspace_message() -> str:
|
|
177
|
+
"""The error for "no workspace" — with an API key there is no picker, so say what to set instead."""
|
|
178
|
+
if api_key.in_use():
|
|
179
|
+
return (
|
|
180
|
+
f"✗ no workspace — {api_key.ENV_API_KEY} is set and a service account cannot pick one; "
|
|
181
|
+
f"set {ENV_WORKSPACE_ID}=<workspace-uuid> (or pass --workspace-id)."
|
|
182
|
+
)
|
|
183
|
+
return (
|
|
184
|
+
f"✗ no workspace selected — run `keystone workspace use <name|id>` "
|
|
185
|
+
f"(or pass --workspace-id, or set {ENV_WORKSPACE_ID})."
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
158
189
|
def load() -> AuthConfig:
|
|
159
190
|
path = config_path()
|
|
160
191
|
if not path.exists():
|