agentnode-sdk 0.18.0__tar.gz → 0.19.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.
Files changed (219) hide show
  1. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/CHANGELOG.md +35 -0
  2. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/PKG-INFO +1 -1
  3. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/__init__.py +1 -1
  4. agentnode_sdk-0.19.0/agentnode_sdk/cli/setup_wizard.py +522 -0
  5. agentnode_sdk-0.19.0/dist-0.19.0/.gitignore +1 -0
  6. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/pyproject.toml +1 -1
  7. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_setup_wizard.py +487 -397
  8. agentnode_sdk-0.18.0/agentnode_sdk/cli/setup_wizard.py +0 -370
  9. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/.env.example +0 -0
  10. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/.gitignore +0 -0
  11. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/README.md +0 -0
  12. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/REGISTRY_SIGNING_ACTIVATION.md +0 -0
  13. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/REGISTRY_SIGNING_SPEC.md +0 -0
  14. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/THREAT_MODEL.md +0 -0
  15. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/TRUST_STACK.md +0 -0
  16. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode.lock +0 -0
  17. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/_fileutil.py +0 -0
  18. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/async_client.py +0 -0
  19. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/capability_graph.py +0 -0
  20. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/capability_taxonomy.py +0 -0
  21. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/__init__.py +0 -0
  22. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/__main__.py +0 -0
  23. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/audit.py +0 -0
  24. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/auth.py +0 -0
  25. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/cassette_audit.py +0 -0
  26. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/commands.py +0 -0
  27. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/complements.py +0 -0
  28. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/init.py +0 -0
  29. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/main.py +0 -0
  30. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/mcp_commands.py +0 -0
  31. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/mcp_status.py +0 -0
  32. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/mcp_submit.py +0 -0
  33. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/mcp_verify.py +0 -0
  34. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/output.py +0 -0
  35. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/publish.py +0 -0
  36. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/record_cases.py +0 -0
  37. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/sandbox_commands.py +0 -0
  38. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/serve.py +0 -0
  39. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/smart_run.py +0 -0
  40. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/templates.py +0 -0
  41. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/validate.py +0 -0
  42. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/cli/verify_local.py +0 -0
  43. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/client.py +0 -0
  44. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/compatibility.py +0 -0
  45. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/config.py +0 -0
  46. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/credential_handle.py +0 -0
  47. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/credential_resolver.py +0 -0
  48. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/credential_store.py +0 -0
  49. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/detect.py +0 -0
  50. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/exceptions.py +0 -0
  51. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/guard.py +0 -0
  52. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/input_guard.py +0 -0
  53. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/installer.py +0 -0
  54. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/key_status.py +0 -0
  55. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/llm_providers.py +0 -0
  56. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/lock_integrity.py +0 -0
  57. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/mcp_server.py +0 -0
  58. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/models.py +0 -0
  59. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/planner.py +0 -0
  60. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/policy.py +0 -0
  61. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/references.py +0 -0
  62. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/registry_trust.py +0 -0
  63. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/resolve.py +0 -0
  64. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/resource_provider.py +0 -0
  65. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/risk_profile.py +0 -0
  66. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/run_log.py +0 -0
  67. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runner.py +0 -0
  68. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtime.py +0 -0
  69. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/__init__.py +0 -0
  70. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/agent_llm_broker.py +0 -0
  71. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/agent_llm_policy.py +0 -0
  72. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/agent_runner.py +0 -0
  73. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/agent_sandbox.py +0 -0
  74. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/mcp_consent.py +0 -0
  75. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/mcp_consent_store.py +0 -0
  76. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/mcp_runner.py +0 -0
  77. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/python_runner.py +0 -0
  78. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/runtimes/remote_runner.py +0 -0
  79. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/__init__.py +0 -0
  80. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/agent_container_wrapper.py +0 -0
  81. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/agent_rpc.py +0 -0
  82. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/agent_session.py +0 -0
  83. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/backend.py +0 -0
  84. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/container_backend.py +0 -0
  85. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/domain_policy.py +0 -0
  86. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/egress.py +0 -0
  87. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/egress_proxy.py +0 -0
  88. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/mcp_preinstall.py +0 -0
  89. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/policy.py +0 -0
  90. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/sandbox/types.py +0 -0
  91. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/signature.py +0 -0
  92. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/signing_key.py +0 -0
  93. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/agentnode_sdk/skill.py +0 -0
  94. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/data/compatibility/current.json +0 -0
  95. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/dist-0.18.0/.gitignore +0 -0
  96. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/sandbox-image/Dockerfile +0 -0
  97. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/sandbox-image/README.md +0 -0
  98. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/analyze_scores.py +0 -0
  99. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/batch_verify.py +0 -0
  100. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/ci_smoke_test.py +0 -0
  101. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/generate_compatibility_artifacts.py +0 -0
  102. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/merge_batches.py +0 -0
  103. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/verify_toolcalls.py +0 -0
  104. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/scripts/weekly_retest.sh +0 -0
  105. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/spikes/agent_sandbox_routing/README.md +0 -0
  106. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/spikes/agent_sandbox_routing/__init__.py +0 -0
  107. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/spikes/agent_sandbox_routing/container_agent_wrapper.py +0 -0
  108. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/spikes/agent_sandbox_routing/fake_llm.py +0 -0
  109. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/spikes/agent_sandbox_routing/host_driver.py +0 -0
  110. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/spikes/agent_sandbox_routing/trivial_agent.py +0 -0
  111. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/__init__.py +0 -0
  112. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/conftest.py +0 -0
  113. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/data/allowed_domains_vectors.json +0 -0
  114. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_llm_broker.py +0 -0
  115. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_llm_policy.py +0 -0
  116. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_rpc.py +0 -0
  117. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_runner.py +0 -0
  118. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_sandbox_e2e.py +0 -0
  119. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_sandbox_routing.py +0 -0
  120. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_sandbox_spike.py +0 -0
  121. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_agent_session_container.py +0 -0
  122. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_async_client.py +0 -0
  123. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_audit_ux.py +0 -0
  124. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_auth_cli_vault.py +0 -0
  125. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_auto_upgrade_policy.py +0 -0
  126. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_cli.py +0 -0
  127. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_cli_lock.py +0 -0
  128. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_cli_run_resolution.py +0 -0
  129. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_client.py +0 -0
  130. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_client_json_guard.py +0 -0
  131. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_client_sprint_b.py +0 -0
  132. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_config.py +0 -0
  133. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_consent_prompt.py +0 -0
  134. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_credential_handle.py +0 -0
  135. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_credential_integration.py +0 -0
  136. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_credential_resolver.py +0 -0
  137. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_credential_store.py +0 -0
  138. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_credential_vault.py +0 -0
  139. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_detect.py +0 -0
  140. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_detect_and_install.py +0 -0
  141. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_domain_policy.py +0 -0
  142. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_e2e_runtime.py +0 -0
  143. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_edge_cases.py +0 -0
  144. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_egress_domain_validation.py +0 -0
  145. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_egress_e2e.py +0 -0
  146. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_egress_lifecycle.py +0 -0
  147. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_egress_proxy_unit.py +0 -0
  148. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_egress_wrap.py +0 -0
  149. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_env_passthrough_wrap.py +0 -0
  150. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard.py +0 -0
  151. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_check.py +0 -0
  152. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_config_cache.py +0 -0
  153. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_policy.py +0 -0
  154. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_preview.py +0 -0
  155. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_schema.py +0 -0
  156. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_set.py +0 -0
  157. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_status.py +0 -0
  158. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_tool_override.py +0 -0
  159. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_tool_override_audit.py +0 -0
  160. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_tool_override_cli.py +0 -0
  161. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_guard_ux.py +0 -0
  162. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_host_trust_policy.py +0 -0
  163. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_host_trust_policy_routing.py +0 -0
  164. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_input_guard.py +0 -0
  165. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_input_guard_escalation.py +0 -0
  166. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_install_hardening.py +0 -0
  167. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_installer_sprint_b.py +0 -0
  168. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_intelligence.py +0 -0
  169. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_key_status.py +0 -0
  170. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_llm_binding.py +0 -0
  171. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_llm_call_runlog.py +0 -0
  172. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_llm_providers.py +0 -0
  173. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_llm_vault_binding.py +0 -0
  174. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_lock_integrity.py +0 -0
  175. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_lock_runtime.py +0 -0
  176. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_allowed_domains_seal.py +0 -0
  177. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_audit.py +0 -0
  178. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_consent.py +0 -0
  179. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_consent_resolver.py +0 -0
  180. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_consent_store.py +0 -0
  181. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_credentialed_launch.py +0 -0
  182. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_doctor.py +0 -0
  183. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_preinstall.py +0 -0
  184. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_preinstall_run.py +0 -0
  185. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_sandbox.py +0 -0
  186. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_mcp_server.py +0 -0
  187. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_observability.py +0 -0
  188. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_planner.py +0 -0
  189. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_policy.py +0 -0
  190. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_policy_integration.py +0 -0
  191. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_prompt_specs.py +0 -0
  192. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_provider_matrix.py +0 -0
  193. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_publish.py +0 -0
  194. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_references.py +0 -0
  195. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_registry_trust.py +0 -0
  196. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_remote_hardening.py +0 -0
  197. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_remote_runner.py +0 -0
  198. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_resource_provider.py +0 -0
  199. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_resource_specs.py +0 -0
  200. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_risk_profile.py +0 -0
  201. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_run_log.py +0 -0
  202. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_runner.py +0 -0
  203. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_runtime.py +0 -0
  204. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_runtime_audit.py +0 -0
  205. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_sandbox_backend.py +0 -0
  206. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_sandbox_doctor.py +0 -0
  207. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_sandbox_e2e.py +0 -0
  208. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_sandbox_gate.py +0 -0
  209. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_security_hardening.py +0 -0
  210. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_signature.py +0 -0
  211. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_signing_key.py +0 -0
  212. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_skill.py +0 -0
  213. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_smart.py +0 -0
  214. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_stability.py +0 -0
  215. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_toolpack_sandbox.py +0 -0
  216. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_v02.py +0 -0
  217. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_validate.py +0 -0
  218. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/test_validate_skill.py +0 -0
  219. {agentnode_sdk-0.18.0 → agentnode_sdk-0.19.0}/tests/validation_lockfile.json +0 -0
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.0 — Full setup wizard coverage
4
+
5
+ ### Added
6
+
7
+ - Expanded `agentnode setup` to cover the full first-class configuration surface
8
+ with multiple-choice prompts and clearly marked recommended defaults.
9
+ - Added a Guard posture step with Balanced, Strict, Permissive and Customize-each
10
+ options.
11
+ - Added setup support for `sandbox.host_trust_policy`.
12
+ - Added an optional Advanced gate for niche first-class settings.
13
+
14
+ ### Changed
15
+
16
+ - Promoted minimum trust level to a direct setup screen.
17
+ - Added consistent `(recommended)` labels across setup choices.
18
+ - A stored LLM key provider can now be offered as the default LLM provider,
19
+ matching the existing Ollama behavior.
20
+
21
+ ### Hardened
22
+
23
+ - Invalid interactive menu input now re-prompts instead of silently falling back
24
+ to the recommended option — a typo can no longer set a security choice unnoticed.
25
+ - Non-interactive (non-TTY) setup continues to take the recommended defaults and
26
+ never hangs.
27
+ - Accepting all recommended choices reproduces the current default configuration,
28
+ so upgrading changes nothing until you opt in.
29
+
30
+ ### Notes
31
+
32
+ - Deeply nested configuration (`llm.providers`, the `agent_sandbox.llm` ceiling,
33
+ and `guard` overrides / rate limits) remains CLI/manual-only by design and is
34
+ surfaced as follow-up commands rather than turned into a wizard editor.
35
+ - This release changes only the setup wizard; runtime behavior and the default
36
+ configuration are unchanged.
37
+
3
38
  ## 0.18.0 — User-controlled host-trust policy
4
39
 
5
40
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentnode-sdk
3
- Version: 0.18.0
3
+ Version: 0.19.0
4
4
  Summary: Python SDK for AgentNode — the open upgrade and discovery infrastructure for AI agents.
5
5
  Project-URL: Homepage, https://agentnode.net
6
6
  Project-URL: Repository, https://github.com/agentnode-ai/agentnode
@@ -38,7 +38,7 @@ from agentnode_sdk.runtime import AgentNodeRuntime
38
38
  Client = AgentNodeClient
39
39
  ToolError = AgentNodeToolError
40
40
 
41
- __version__ = "0.18.0"
41
+ __version__ = "0.19.0"
42
42
  __all__ = [
43
43
  "AgentNode",
44
44
  "AsyncAgentNode",
@@ -0,0 +1,522 @@
1
+ """AgentNode setup wizard — interactive configuration.
2
+
3
+ Covers the full first-class config surface with multiple-choice prompts; the
4
+ recommended option is marked "(recommended)" and is the default (Enter / non-TTY).
5
+ Accepting every recommendation reproduces ``default_config()`` exactly, so the
6
+ wizard is non-breaking by construction.
7
+
8
+ Deeply nested config (``llm.providers``, the ``agent_sandbox.llm`` ceiling, and
9
+ ``guard.tool_overrides`` / ``agent_overrides`` / ``rate_limits``) stays CLI/manual
10
+ only BY DESIGN and is surfaced only as follow-up hints — the wizard is a
11
+ first-class-settings tool, not a nested YAML editor.
12
+
13
+ UX invariants preserved:
14
+ - Config is built by mutating ``default_config()`` + one ``save_config(cfg)`` — not
15
+ per-key config setters (booleans persist as real bools).
16
+ - No docker calls here; the only sandbox action is the reused ``cmd_sandbox_pull``.
17
+ - Credentials via getpass/env-import only, masked output, honest storage labels.
18
+ - Non-TTY never hangs: every prompt falls back to its recommended/default. An
19
+ invalid *interactive* choice re-prompts — a typo must not set a security choice.
20
+ """
21
+ from __future__ import annotations
22
+
23
+ import sys
24
+
25
+ from agentnode_sdk.config import (
26
+ default_config,
27
+ installation_behavior_label,
28
+ save_config,
29
+ )
30
+ from agentnode_sdk.cli.output import bold, dim, kv, section
31
+
32
+ # Key-provider menu (grouped for readability); choice 8 = ollama (keyless,
33
+ # handled separately — never a key prompt), choice 9 = skip (the default).
34
+ _LLM_CHOICES = {
35
+ "1": "openai", "2": "anthropic", "3": "openrouter",
36
+ "4": "deepseek", "5": "mistral", "6": "qwen", "7": "gemini",
37
+ }
38
+ _OLLAMA_CHOICE = "8"
39
+ _SKIP_CHOICE = "9"
40
+
41
+ # Guard action types in a risk-ordered display order + friendly labels.
42
+ _GUARD_ORDER = [
43
+ "delete", "write_external", "execute", "credential_use",
44
+ "network_egress", "write_local", "read", "compute", "unknown",
45
+ ]
46
+ _GUARD_LABELS = {
47
+ "delete": "Delete resources",
48
+ "write_external": "Write / send externally",
49
+ "execute": "Execute code",
50
+ "credential_use": "Use credentials",
51
+ "network_egress": "Network egress",
52
+ "write_local": "Write locally",
53
+ "read": "Read data",
54
+ "compute": "Compute",
55
+ "unknown": "Unknown action type",
56
+ }
57
+
58
+
59
+ def run_wizard() -> int:
60
+ """Run the setup wizard. Returns exit code."""
61
+ try:
62
+ cfg = _wizard_flow()
63
+ return 0 if cfg is not None else 1
64
+ except (KeyboardInterrupt, EOFError):
65
+ print("\n\nSetup cancelled.")
66
+ return 130
67
+
68
+
69
+ def _prompt(text: str, default: str = "") -> str:
70
+ result = input(text).strip()
71
+ return result if result else default
72
+
73
+
74
+ def _pick(title: str, options: list[tuple[str, object]], recommended: int,
75
+ notes: list[str] | None = None) -> object:
76
+ """Multiple-choice menu. ``options`` = ``[(label, value), ...]`` (1-indexed);
77
+ ``recommended`` is the 1-based index of the recommended option (also the
78
+ Enter/non-TTY default). ``notes`` (optional, same length) renders each option
79
+ on its own line with a dim hint.
80
+
81
+ Empty input → recommended. Non-TTY → recommended (never hangs). An INVALID
82
+ interactive choice re-prompts (``Please choose 1–N.``) — it never silently
83
+ falls back to the recommended value, so a typo cannot set a security choice.
84
+ """
85
+ n = len(options)
86
+ print(f" {title}")
87
+ if notes:
88
+ width = max(len(label) for label, _ in options) + 18
89
+ for i, (label, _v) in enumerate(options, 1):
90
+ tag = " (recommended)" if i == recommended else ""
91
+ left = f" [{i}] {label}{tag}"
92
+ print(f"{left:<{width}}{dim(notes[i - 1])}")
93
+ else:
94
+ cells = []
95
+ for i, (label, _v) in enumerate(options, 1):
96
+ tag = " (recommended)" if i == recommended else ""
97
+ cells.append(f"[{i}] {label}{tag}")
98
+ print(" " + " ".join(cells))
99
+
100
+ if not sys.stdin.isatty():
101
+ return options[recommended - 1][1]
102
+ while True:
103
+ raw = _prompt(f" Choice [{recommended}]: ")
104
+ if not raw:
105
+ return options[recommended - 1][1]
106
+ if raw.isdigit() and 1 <= int(raw) <= n:
107
+ return options[int(raw) - 1][1]
108
+ print(f" Please choose 1–{n}.")
109
+
110
+
111
+ def _store_llm_key(provider: str) -> str | None:
112
+ """Store one provider key via the vault. Returns the short storage label
113
+ ("OS keychain"/"plaintext file") on success, None when skipped.
114
+
115
+ Key entry is getpass-only (hidden, never argv); if the provider's env var
116
+ is already set (incl. ~/.agentnode/.env), offers to import it instead.
117
+ Output shows only the masked tail and the honest storage label."""
118
+ import getpass
119
+ import os
120
+
121
+ from agentnode_sdk.cli.auth import _masked, _storage_short, cmd_auth_test
122
+ from agentnode_sdk.credential_store import set_credential
123
+
124
+ from agentnode_sdk.llm_providers import resolve_provider_spec
125
+ env_var = (resolve_provider_spec(provider) or {}).get("api_key_env") or ""
126
+ try:
127
+ from agentnode_sdk.runtimes.agent_runner import _load_agentnode_env
128
+ _load_agentnode_env()
129
+ except Exception:
130
+ pass
131
+ env_val = (os.environ.get(env_var) or "").strip() if env_var else ""
132
+
133
+ token = ""
134
+ if env_val:
135
+ print(f" Found {env_var} in your environment (env always overrides stored keys).")
136
+ imp = _prompt(f" Store this key from {env_var}? [Y/n]: ", "y")
137
+ if imp.lower() != "n":
138
+ token = env_val
139
+ if not token:
140
+ token = getpass.getpass(f" Enter API key for {provider} (input hidden): ").strip()
141
+ if not token:
142
+ print(" No key entered — skipped.")
143
+ return None
144
+
145
+ storage = set_credential(provider, token, auth_type="api_key")
146
+ if storage == "keyring":
147
+ where = "OS keychain"
148
+ else:
149
+ where = "plaintext file (0600) — OS keychain unavailable on this system"
150
+ print(f" Credential stored for {provider} ({_masked(token)}) — storage: {where}.")
151
+
152
+ t = _prompt(" Test the key now? (free endpoint, no completion call) [Y/n]: ", "y")
153
+ if t.lower() != "n":
154
+ try:
155
+ rc = cmd_auth_test(provider)
156
+ except Exception:
157
+ rc = 3
158
+ if rc not in (0, 1):
159
+ # indeterminate/network — never block the wizard on it
160
+ print(dim(f" Could not verify right now — test later with "
161
+ f"`agentnode auth test {provider}`."))
162
+ return _storage_short(storage)
163
+
164
+
165
+ def _credentials_screen(cfg: dict) -> list[tuple[str, str]]:
166
+ """Screen: LLM credentials (optional, default = skip). Key providers come
167
+ from the registry-backed menu; ollama is a keyless CONFIG selection. After a
168
+ key provider is stored, offers to make it the default provider (mirrors the
169
+ ollama path). Returns the (provider, storage label) pairs selected."""
170
+ print()
171
+ print(bold(" LLM credentials (optional)"))
172
+ print()
173
+ print(" Agents and the sandboxed-agent LLM broker need a provider API key.")
174
+ print(" Keys are stored in your OS keychain when available; otherwise in a")
175
+ print(" plaintext file (0600) — AgentNode will tell you which.")
176
+ print()
177
+
178
+ if not sys.stdin.isatty():
179
+ print(dim(" Non-interactive session — skipping. Add keys later with"))
180
+ print(dim(" `agentnode auth set <provider>`."))
181
+ return []
182
+
183
+ stored: list[tuple[str, str]] = []
184
+ all_options = list(_LLM_CHOICES) + [_OLLAMA_CHOICE, _SKIP_CHOICE]
185
+ while True:
186
+ print(" Recommended: [1] OpenAI [2] Anthropic [3] OpenRouter")
187
+ print(" More: [4] DeepSeek [5] Mistral [6] Qwen [7] Gemini")
188
+ print(" Local: [8] Ollama — keyless, requires a running Ollama")
189
+ print(" [9] Skip for now (recommended)")
190
+ c = _prompt(" Choice [9]: ", _SKIP_CHOICE)
191
+ if c not in all_options:
192
+ print(" Please choose 1–9.")
193
+ continue
194
+ if c == _SKIP_CHOICE:
195
+ break
196
+ if c == _OLLAMA_CHOICE:
197
+ # keyless local provider: a config selection, NOT a credential.
198
+ if any(p == "ollama" for p, _ in stored):
199
+ print(" ollama already selected in this run.")
200
+ else:
201
+ print(" Ollama runs models locally — no API key, no per-token cost.")
202
+ print(dim(" Requires a running Ollama (https://ollama.com); the wizard"))
203
+ print(dim(" does not start or probe it."))
204
+ use = _prompt(" Use Ollama as your default LLM provider? [Y/n]: ", "y")
205
+ if use.lower() != "n":
206
+ cfg["llm"]["default_provider"] = "ollama"
207
+ stored.append(("ollama", "local, keyless"))
208
+ print(dim(" Selected. Test later with `agentnode auth test ollama`."))
209
+ else:
210
+ provider = _LLM_CHOICES[c]
211
+ if any(p == provider for p, _ in stored):
212
+ print(f" {provider} already added in this run.")
213
+ else:
214
+ label = _store_llm_key(provider)
215
+ if label is not None:
216
+ stored.append((provider, label))
217
+ if len(stored) >= len(_LLM_CHOICES) + 1:
218
+ break
219
+ more = _prompt(" Add another provider? [y/N]: ", "n")
220
+ if more.lower() != "y":
221
+ break
222
+
223
+ # Offer to make a stored KEY provider the default (ollama already sets it above).
224
+ key_providers = [p for p, _ in stored if p != "ollama"]
225
+ if key_providers and cfg["llm"]["default_provider"] not in key_providers:
226
+ first = key_providers[0]
227
+ ans = _prompt(f" Use {first} as your default LLM provider? [Y/n]: ", "y")
228
+ if ans.lower() != "n":
229
+ cfg["llm"]["default_provider"] = first
230
+ return stored
231
+
232
+
233
+ def _guard_screen(cfg: dict) -> str:
234
+ """Screen: Guard posture. Sets the 9 ``guard.<action>`` keys from a preset
235
+ bundle, or drills into all 9 individually on "Customize each". Reuses
236
+ guard.py's shipped Balanced (== defaults) and Strict bundles. Returns the
237
+ chosen posture label for the Summary."""
238
+ from agentnode_sdk.guard import _DEFAULT_GUARD_POLICY, _STRICT_GUARD_POLICY
239
+
240
+ print()
241
+ print(bold(" Guard posture"))
242
+ print()
243
+ print(" How tools are gated at run time (the pre-execution policy).")
244
+ posture = _pick("Choose a posture", [
245
+ ("Balanced", "balanced"),
246
+ ("Strict", "strict"),
247
+ ("Permissive", "permissive"),
248
+ ("Customize each", "custom"),
249
+ ], recommended=1, notes=[
250
+ "risky actions ask, safe ones allow",
251
+ "destructive actions denied, more prompts",
252
+ "allow everything, ask only on unknown",
253
+ "set all 9 action types yourself",
254
+ ])
255
+
256
+ if posture == "balanced":
257
+ pass # cfg["guard"] is already the shipped default == Balanced
258
+ elif posture == "strict":
259
+ cfg["guard"].update(_STRICT_GUARD_POLICY)
260
+ elif posture == "permissive":
261
+ cfg["guard"].update({a: "allow" for a in _GUARD_ORDER})
262
+ cfg["guard"]["unknown"] = "prompt"
263
+ else: # custom — recommended per action = the Balanced value
264
+ print()
265
+ print(dim(" Set each action type (allow / prompt / deny):"))
266
+ pol = ("allow", "allow"), ("prompt", "prompt"), ("deny", "deny")
267
+ idx = {"allow": 1, "prompt": 2, "deny": 3}
268
+ for action in _GUARD_ORDER:
269
+ rec = idx[_DEFAULT_GUARD_POLICY[action]]
270
+ cfg["guard"][action] = _pick(_GUARD_LABELS[action], list(pol), recommended=rec)
271
+ return posture
272
+
273
+
274
+ def _sandbox_screen(cfg: dict) -> tuple[str, bool]:
275
+ """Screen: host-trust policy + local sandbox.
276
+
277
+ Sets ``sandbox.host_trust_policy`` (which trust tiers may run on the host),
278
+ then diagnoses the container runtime via the doctor's read-only
279
+ ``_build_env_checks``. The ONLY action is an optional, TTY-confirmed image
280
+ pull via the existing ``cmd_sandbox_pull`` — the wizard never talks to docker.
281
+ The agent-sandbox enable prompt (default No) is offered only when the sandbox
282
+ is fully ready. Returns (status line for Summary/Success, image_still_missing).
283
+ """
284
+ from agentnode_sdk.cli.sandbox_commands import _build_env_checks, cmd_sandbox_pull
285
+
286
+ print()
287
+ print(bold(" Sandbox & host-trust policy"))
288
+ print()
289
+ print(" Community packages always run in an isolated container sandbox.")
290
+ print(" Trusted/curated packages run on the host under the default policy —")
291
+ print(" the host-trust policy can sandbox them too.")
292
+ print()
293
+
294
+ htp = _pick("Which trust tiers may run directly on your host?", [
295
+ ("Default", "default"),
296
+ ("Curated only", "curated_only"),
297
+ ("None", "none"),
298
+ ], recommended=1, notes=[
299
+ "curated + trusted on host (today's behavior)",
300
+ "trusted is sandboxed; only curated on host",
301
+ "everything sandboxed; nothing on the host",
302
+ ])
303
+ cfg["sandbox"]["host_trust_policy"] = htp
304
+ if htp != "default":
305
+ print(dim(" Note: stronger isolation can break trusted/curated packages that"))
306
+ print(dim(" expect host FS, broad tools, LLM keys or network — a reinstall may"))
307
+ print(dim(" be needed. Check with `agentnode sandbox doctor <slug>`."))
308
+ print()
309
+
310
+ checks, ready, image_missing = _build_env_checks()
311
+
312
+ def _render(check_list):
313
+ for c in check_list:
314
+ mark = "[OK]" if c["ok"] else ("[--]" if c["ok"] is None else "[!!]")
315
+ print(f" {mark} {c['check']}: {c['detail']}")
316
+ if c["ok"] is False and c.get("fix"):
317
+ print(dim(f" -> {c['fix']}"))
318
+
319
+ _render(checks)
320
+ print()
321
+
322
+ if image_missing and not ready:
323
+ if sys.stdin.isatty():
324
+ print(" Pull the pinned AgentNode sandbox image now? [y/N]")
325
+ print(dim(" This downloads the digest-pinned sandbox image."))
326
+ print(dim(" It does not install Docker/Podman."))
327
+ print(dim(" It does not enable auto-pull."))
328
+ answer = _prompt(" > ", "n")
329
+ if answer.lower() == "y":
330
+ rc = cmd_sandbox_pull()
331
+ if rc == 0:
332
+ checks, ready, image_missing = _build_env_checks()
333
+ else:
334
+ print(dim(" Pull failed or was skipped — the wizard continues."))
335
+ print(dim(" Run `agentnode sandbox pull` later."))
336
+ else:
337
+ print(dim(" Skipped. Run `agentnode sandbox pull` when ready."))
338
+ else:
339
+ print(dim(" Non-interactive session — run `agentnode sandbox doctor` later."))
340
+
341
+ if ready:
342
+ print()
343
+ print(" Sandbox ready — community packages run isolated.")
344
+ print()
345
+ print(" Sandboxed community agents are currently disabled (default).")
346
+ print(" Enabling lets verified/unverified community agents run isolated;")
347
+ print(" without it they are refused.")
348
+ if sys.stdin.isatty():
349
+ en = _prompt(" Enable sandboxed community agents now? [y/N]: ", "n")
350
+ if en.lower() == "y":
351
+ cfg["agent_sandbox"]["enabled"] = True
352
+ else:
353
+ print(dim(" You can enable it later with "
354
+ "`agentnode config set agent_sandbox.enabled true`."))
355
+ else:
356
+ print(dim(" Enable later with "
357
+ "`agentnode config set agent_sandbox.enabled true`."))
358
+ return "ready", False
359
+
360
+ from agentnode_sdk.cli.sandbox_commands import _first_failure
361
+ fail = _first_failure(checks)
362
+ detail = (fail or {}).get("detail", "not ready")
363
+ print(dim(" Not ready — details and guidance: agentnode sandbox doctor"))
364
+ return f"not ready — {detail}", image_missing
365
+
366
+
367
+ def _advanced_screen(cfg: dict) -> None:
368
+ """Screen: advanced settings (opt-in gate, default No, non-TTY skip). Covers
369
+ the two niche first-class keys; deeper nested config stays CLI-only."""
370
+ print()
371
+ print(bold(" Advanced settings (optional)"))
372
+ print()
373
+ if not sys.stdin.isatty():
374
+ return
375
+ if _prompt(" Configure advanced settings? [y/N]: ", "n").lower() != "y":
376
+ return
377
+
378
+ cfg["credentials"]["require_before_auto_install"] = _pick(
379
+ "During auto-install, skip packages needing credentials you don't have?",
380
+ [("Yes", True), ("No", False)], recommended=1,
381
+ notes=["skip them (recommended)", "try anyway"])
382
+ cfg["risk_policies"]["external_write_capable"] = _pick(
383
+ "Packages that can write or send data externally",
384
+ [("log", "log"), ("allow", "allow"), ("prompt", "prompt"), ("deny", "deny")],
385
+ recommended=1)
386
+
387
+
388
+ def _wizard_flow() -> dict | None:
389
+ cfg = default_config()
390
+
391
+ # Screen 1: Intro
392
+ print()
393
+ print(section("AgentNode Setup"))
394
+ print(" Configure how AgentNode manages capabilities for your agents.")
395
+ print(" Each choice marks our (recommended) default — press Enter to accept it.")
396
+ print(" You can change everything later with `agentnode setup` or `config set`.")
397
+ print()
398
+ print(dim(" Press Enter to continue..."))
399
+ _prompt("")
400
+
401
+ # Screen 2: Installation behavior (one choice -> two keys)
402
+ print()
403
+ print(bold(" Installation behavior"))
404
+ print()
405
+ behavior = _pick("How should capabilities be installed?", [
406
+ ("Automatic", "auto"),
407
+ ("Review before install", "review"),
408
+ ("Manual only", "manual"),
409
+ ], recommended=1, notes=[
410
+ "install verified capabilities without asking",
411
+ "ask before each installation",
412
+ "never install automatically",
413
+ ])
414
+ if behavior == "auto":
415
+ cfg["auto_upgrade_policy"] = "safe"
416
+ cfg["install_confirmation"] = "auto"
417
+ elif behavior == "review":
418
+ cfg["auto_upgrade_policy"] = "safe"
419
+ cfg["install_confirmation"] = "prompt"
420
+ else:
421
+ cfg["auto_upgrade_policy"] = "off"
422
+ cfg["install_confirmation"] = "auto"
423
+
424
+ # Screen 3: Trust level (now a direct screen)
425
+ print()
426
+ print(bold(" Minimum trust level"))
427
+ print()
428
+ cfg["trust"]["minimum_trust_level"] = _pick("Minimum trust tier to install/run", [
429
+ ("verified", "verified"),
430
+ ("trusted", "trusted"),
431
+ ("curated", "curated"),
432
+ ], recommended=1, notes=[
433
+ "community-reviewed packages",
434
+ "manually approved by the AgentNode team",
435
+ "official AgentNode packages only",
436
+ ])
437
+
438
+ # Screen 4: Permission defaults
439
+ print()
440
+ print(bold(" Permission defaults"))
441
+ print()
442
+ cfg["permissions"]["network"] = _pick(
443
+ "Network access", [("allow", "allow"), ("prompt", "prompt"), ("deny", "deny")],
444
+ recommended=2)
445
+ cfg["permissions"]["filesystem"] = _pick(
446
+ "Filesystem access", [("allow", "allow"), ("prompt", "prompt"), ("deny", "deny")],
447
+ recommended=2)
448
+ cfg["permissions"]["code_execution"] = _pick(
449
+ "Code execution",
450
+ [("sandboxed", "sandboxed"), ("prompt", "prompt"), ("deny", "deny")],
451
+ recommended=1)
452
+
453
+ # Screen 5: Guard posture (sets the 9 guard.* keys)
454
+ guard_posture = _guard_screen(cfg)
455
+
456
+ # Screen 6: LLM credentials (optional)
457
+ stored_providers = _credentials_screen(cfg)
458
+
459
+ # Screen 7: Sandbox + host-trust policy
460
+ sandbox_status, image_missing = _sandbox_screen(cfg)
461
+
462
+ # Screen 8: Advanced (opt-in)
463
+ _advanced_screen(cfg)
464
+
465
+ # Screen 9: Summary
466
+ print()
467
+ print(section("Summary"))
468
+ print(kv("Installation behavior", installation_behavior_label(cfg)))
469
+ print(kv("Trust level", cfg["trust"]["minimum_trust_level"]))
470
+ print(kv("Guard posture", guard_posture))
471
+ if stored_providers:
472
+ creds_line = ", ".join(f"{p} ({label})" for p, label in stored_providers)
473
+ else:
474
+ creds_line = "none — add later with `agentnode auth set <provider>`"
475
+ print(kv("LLM credentials", creds_line))
476
+ print(kv("LLM default provider", cfg["llm"]["default_provider"]))
477
+ print(kv("Host-trust policy", cfg["sandbox"]["host_trust_policy"]))
478
+ print(kv("Sandbox", sandbox_status))
479
+ print(kv("Agent sandbox",
480
+ "enabled" if cfg["agent_sandbox"]["enabled"] else "disabled"))
481
+ print()
482
+ print(" Permissions")
483
+ print(" " + "-" * 11)
484
+ print(kv("Network", cfg["permissions"]["network"]))
485
+ print(kv("Filesystem", cfg["permissions"]["filesystem"]))
486
+ print(kv("Code execution", cfg["permissions"]["code_execution"]))
487
+ print()
488
+ confirm = _prompt(" Save? [Y/n]: ", "y")
489
+ if confirm.lower() == "n":
490
+ print("\n Setup cancelled. No changes saved.")
491
+ return None
492
+
493
+ save_config(cfg)
494
+
495
+ # Screen 10: Success
496
+ print()
497
+ print(bold(" Configuration saved."))
498
+ print()
499
+ print(kv("Sandbox", sandbox_status))
500
+ print(kv("Host-trust policy", cfg["sandbox"]["host_trust_policy"]))
501
+ print(dim(" Community packages need a local sandbox. Trusted/curated packages"))
502
+ print(dim(" run on the host unless the host-trust policy sandboxes them."))
503
+ print()
504
+ print(dim(" Next steps:"))
505
+ print(dim(" agentnode auth status check your credentials"))
506
+ print(dim(" agentnode sandbox doctor check the sandbox runtime"))
507
+ if image_missing:
508
+ print(dim(" agentnode sandbox pull fetch the sandbox image"))
509
+ if not cfg["agent_sandbox"]["enabled"]:
510
+ print(dim(" agentnode config set agent_sandbox.enabled true"))
511
+ print(dim(" enable sandboxed community agents"))
512
+ print(dim(" agentnode install word-counter-pack install a first capability"))
513
+ print(dim(" agentnode run word-counter-pack --input '{\"text\":\"hello\"}'"))
514
+ print(dim(" agentnode doctor check your whole setup"))
515
+ print()
516
+ print(dim(" Fine-tuning beyond these settings (CLI):"))
517
+ print(dim(" agentnode guard set <action> <policy> per-action guard overrides"))
518
+ print(dim(" agentnode config set sandbox.host_trust_policy <default|curated_only|none>"))
519
+ print(dim(" agentnode config set llm.default_provider <provider> (custom endpoints via config)"))
520
+ print()
521
+
522
+ return cfg
@@ -0,0 +1 @@
1
+ *
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentnode-sdk"
7
- version = "0.18.0"
7
+ version = "0.19.0"
8
8
  description = "Python SDK for AgentNode — the open upgrade and discovery infrastructure for AI agents."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"