smbcloud-cli 0.4.13__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.
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/Cargo.lock +34 -16
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/Cargo.toml +14 -12
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/PKG-INFO +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/Cargo.toml +3 -1
- smbcloud_cli-0.5.0/crates/cli/src/cli/mod.rs +210 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/render.rs +6 -2
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/config.rs +3 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy_nextjs_ssr.rs +125 -19
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_migrate.rs +1 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-mail/cli.rs +34 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-mail/mod.rs +1 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-mail/process.rs +53 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-mail/render.rs +12 -0
- smbcloud_cli-0.5.0/crates/cli/src/cloud-mail/send.rs +188 -0
- smbcloud_cli-0.5.0/crates/cli/src/controlkit.rs +129 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/lib.rs +1 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/main.rs +4 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/mcp.rs +138 -7
- smbcloud_cli-0.5.0/crates/cli/src/mcp_xcrs.rs +156 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/Cargo.toml +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/Cargo.toml +1 -1
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/Cargo.toml +30 -0
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/README.md +81 -0
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/src/client.rs +111 -0
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/src/client_credentials.rs +23 -0
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/src/error.rs +15 -0
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/src/message.rs +150 -0
- smbcloud_cli-0.5.0/crates/smbcloud-email-sdk/src/smbcloud_email_sdk.rs +42 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/Cargo.toml +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/Cargo.toml +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/app_auth.rs +4 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/deploy_config.rs +5 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/project.rs +7 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-network/Cargo.toml +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking/Cargo.toml +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/Cargo.toml +1 -1
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-utils/Cargo.toml +1 -1
- smbcloud_cli-0.5.0/crates/xcrs/Cargo.toml +31 -0
- smbcloud_cli-0.5.0/crates/xcrs/README.md +30 -0
- smbcloud_cli-0.5.0/crates/xcrs/src/main.rs +111 -0
- smbcloud_cli-0.5.0/crates/xcrs/src/mcp.rs +2431 -0
- smbcloud_cli-0.5.0/crates/xcrs/src/xcrs.rs +1391 -0
- smbcloud_cli-0.4.13/crates/cli/src/cli/mod.rs +0 -104
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/cli.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/forgot/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/login/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/login/process.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/logout/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/me/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/signup/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/account/signup/process.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ci.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/auth_app.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/cli.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/process.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/request.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-auth/url_builder.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/git.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy_rails.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy_rust.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy_swift.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy_vite_spa.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/remote_messages.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/setup.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/setup_create_new_project.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/setup_project.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/setup_select_project.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-mail/current_project.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/interface.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/cli.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/crud_create.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/crud_delete.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/crud_read.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/crud_update.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/deploy_target.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/deployment.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/project/process.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/session_config.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/cli.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/process.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/render.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/request.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/tenant_client.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/tenant/url_builder.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/token/clear_smb_token.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/token/get_smb_token.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/token/is_logged_in.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/token/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/token/smb_token_file_path.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/confirm_dialog.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/deployment_detail_view.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/deployment_table.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/me_view.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/plain.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/project_detail_view.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/project_table.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/prompt.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/reporter.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/ui/theme.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/.gitignore +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/check_email.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/login.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/logout.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/me.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/oauth/get_account_status.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/oauth/get_consent_url.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/oauth/get_profile.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/oauth/get_token.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/oauth/mod.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/oauth/provider.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/remove.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/resend_email_verification.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/resend_reset_password_instruction.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/reset_password.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-auth/src/signup.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/build.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/error.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/known_hosts.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/report.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/runner.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-deploy/src/transport.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/src/mail_app.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/src/mail_inbox.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/src/mail_message.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/src/request.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/src/smbcloud_mail.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-mail/src/url_builder.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/account.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/deploy_config_update.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/error_codes.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/forgot.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/frontend_app.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/login.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/mail.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/oauth.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/repository.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/reset_password_response.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/runner.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/signup.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-model/src/tenant.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-network/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-network/src/environment.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-network/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-network/src/network.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking/src/constants.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking/src/smb_client.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_deploy_repo_create.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_frontend_app_create.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_frontend_app_deploy_config.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_frontend_app_read.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_frontend_app_update_deploy_config.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_create.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_delete.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_deployment_create.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_deployment_read.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_deployment_update.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_read.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/crud_project_update.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/request.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-networking-project/src/url_builder.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-utils/README.md +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-utils/src/config.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-utils/src/lib.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/smbcloud-utils/src/write_config.rs +0 -0
- {smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/pyproject.toml +0 -0
|
@@ -2528,7 +2528,7 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
|
|
|
2528
2528
|
|
|
2529
2529
|
[[package]]
|
|
2530
2530
|
name = "smbcloud-auth"
|
|
2531
|
-
version = "0.
|
|
2531
|
+
version = "0.5.0"
|
|
2532
2532
|
dependencies = [
|
|
2533
2533
|
"log",
|
|
2534
2534
|
"reqwest",
|
|
@@ -2543,7 +2543,7 @@ dependencies = [
|
|
|
2543
2543
|
|
|
2544
2544
|
[[package]]
|
|
2545
2545
|
name = "smbcloud-auth-sdk"
|
|
2546
|
-
version = "0.
|
|
2546
|
+
version = "0.5.0"
|
|
2547
2547
|
dependencies = [
|
|
2548
2548
|
"base64",
|
|
2549
2549
|
"reqwest",
|
|
@@ -2558,7 +2558,7 @@ dependencies = [
|
|
|
2558
2558
|
|
|
2559
2559
|
[[package]]
|
|
2560
2560
|
name = "smbcloud-auth-sdk-py"
|
|
2561
|
-
version = "0.
|
|
2561
|
+
version = "0.5.0"
|
|
2562
2562
|
dependencies = [
|
|
2563
2563
|
"pyo3",
|
|
2564
2564
|
"pythonize",
|
|
@@ -2572,7 +2572,7 @@ dependencies = [
|
|
|
2572
2572
|
|
|
2573
2573
|
[[package]]
|
|
2574
2574
|
name = "smbcloud-auth-sdk-wasm"
|
|
2575
|
-
version = "0.
|
|
2575
|
+
version = "0.5.0"
|
|
2576
2576
|
dependencies = [
|
|
2577
2577
|
"serde-wasm-bindgen",
|
|
2578
2578
|
"smbcloud-auth-sdk",
|
|
@@ -2585,7 +2585,7 @@ dependencies = [
|
|
|
2585
2585
|
|
|
2586
2586
|
[[package]]
|
|
2587
2587
|
name = "smbcloud-cli"
|
|
2588
|
-
version = "0.
|
|
2588
|
+
version = "0.5.0"
|
|
2589
2589
|
dependencies = [
|
|
2590
2590
|
"anyhow",
|
|
2591
2591
|
"chrono",
|
|
@@ -2611,6 +2611,7 @@ dependencies = [
|
|
|
2611
2611
|
"serde_repr",
|
|
2612
2612
|
"smbcloud-auth",
|
|
2613
2613
|
"smbcloud-deploy",
|
|
2614
|
+
"smbcloud-email-sdk",
|
|
2614
2615
|
"smbcloud-mail",
|
|
2615
2616
|
"smbcloud-model",
|
|
2616
2617
|
"smbcloud-network",
|
|
@@ -2627,11 +2628,12 @@ dependencies = [
|
|
|
2627
2628
|
"tracing-bunyan-formatter",
|
|
2628
2629
|
"tracing-subscriber",
|
|
2629
2630
|
"url-builder",
|
|
2631
|
+
"xcrs",
|
|
2630
2632
|
]
|
|
2631
2633
|
|
|
2632
2634
|
[[package]]
|
|
2633
2635
|
name = "smbcloud-deploy"
|
|
2634
|
-
version = "0.
|
|
2636
|
+
version = "0.5.0"
|
|
2635
2637
|
dependencies = [
|
|
2636
2638
|
"anyhow",
|
|
2637
2639
|
"smbcloud-model",
|
|
@@ -2643,7 +2645,7 @@ dependencies = [
|
|
|
2643
2645
|
|
|
2644
2646
|
[[package]]
|
|
2645
2647
|
name = "smbcloud-email-sdk"
|
|
2646
|
-
version = "0.
|
|
2648
|
+
version = "0.5.0"
|
|
2647
2649
|
dependencies = [
|
|
2648
2650
|
"anyhow",
|
|
2649
2651
|
"log",
|
|
@@ -2658,7 +2660,7 @@ dependencies = [
|
|
|
2658
2660
|
|
|
2659
2661
|
[[package]]
|
|
2660
2662
|
name = "smbcloud-gresiq"
|
|
2661
|
-
version = "0.
|
|
2663
|
+
version = "0.5.0"
|
|
2662
2664
|
dependencies = [
|
|
2663
2665
|
"native-tls",
|
|
2664
2666
|
"postgres-native-tls",
|
|
@@ -2672,7 +2674,7 @@ dependencies = [
|
|
|
2672
2674
|
|
|
2673
2675
|
[[package]]
|
|
2674
2676
|
name = "smbcloud-gresiq-sdk"
|
|
2675
|
-
version = "0.
|
|
2677
|
+
version = "0.5.0"
|
|
2676
2678
|
dependencies = [
|
|
2677
2679
|
"anyhow",
|
|
2678
2680
|
"log",
|
|
@@ -2686,7 +2688,7 @@ dependencies = [
|
|
|
2686
2688
|
|
|
2687
2689
|
[[package]]
|
|
2688
2690
|
name = "smbcloud-mail"
|
|
2689
|
-
version = "0.
|
|
2691
|
+
version = "0.5.0"
|
|
2690
2692
|
dependencies = [
|
|
2691
2693
|
"reqwest",
|
|
2692
2694
|
"serde",
|
|
@@ -2698,7 +2700,7 @@ dependencies = [
|
|
|
2698
2700
|
|
|
2699
2701
|
[[package]]
|
|
2700
2702
|
name = "smbcloud-model"
|
|
2701
|
-
version = "0.
|
|
2703
|
+
version = "0.5.0"
|
|
2702
2704
|
dependencies = [
|
|
2703
2705
|
"chrono",
|
|
2704
2706
|
"log",
|
|
@@ -2714,7 +2716,7 @@ dependencies = [
|
|
|
2714
2716
|
|
|
2715
2717
|
[[package]]
|
|
2716
2718
|
name = "smbcloud-network"
|
|
2717
|
-
version = "0.
|
|
2719
|
+
version = "0.5.0"
|
|
2718
2720
|
dependencies = [
|
|
2719
2721
|
"clap 4.6.2",
|
|
2720
2722
|
"log",
|
|
@@ -2727,7 +2729,7 @@ dependencies = [
|
|
|
2727
2729
|
|
|
2728
2730
|
[[package]]
|
|
2729
2731
|
name = "smbcloud-networking"
|
|
2730
|
-
version = "0.
|
|
2732
|
+
version = "0.5.0"
|
|
2731
2733
|
dependencies = [
|
|
2732
2734
|
"smbcloud-network",
|
|
2733
2735
|
"url-builder",
|
|
@@ -2735,7 +2737,7 @@ dependencies = [
|
|
|
2735
2737
|
|
|
2736
2738
|
[[package]]
|
|
2737
2739
|
name = "smbcloud-networking-project"
|
|
2738
|
-
version = "0.
|
|
2740
|
+
version = "0.5.0"
|
|
2739
2741
|
dependencies = [
|
|
2740
2742
|
"anyhow",
|
|
2741
2743
|
"async-trait",
|
|
@@ -2753,11 +2755,11 @@ dependencies = [
|
|
|
2753
2755
|
|
|
2754
2756
|
[[package]]
|
|
2755
2757
|
name = "smbcloud-s6n"
|
|
2756
|
-
version = "0.
|
|
2758
|
+
version = "0.5.0"
|
|
2757
2759
|
|
|
2758
2760
|
[[package]]
|
|
2759
2761
|
name = "smbcloud-utils"
|
|
2760
|
-
version = "0.
|
|
2762
|
+
version = "0.5.0"
|
|
2761
2763
|
dependencies = [
|
|
2762
2764
|
"anyhow",
|
|
2763
2765
|
"dirs",
|
|
@@ -3993,6 +3995,22 @@ version = "0.6.3"
|
|
|
3993
3995
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3994
3996
|
checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
|
|
3995
3997
|
|
|
3998
|
+
[[package]]
|
|
3999
|
+
name = "xcrs"
|
|
4000
|
+
version = "0.5.0"
|
|
4001
|
+
dependencies = [
|
|
4002
|
+
"anyhow",
|
|
4003
|
+
"base64",
|
|
4004
|
+
"clap 4.6.2",
|
|
4005
|
+
"reqwest",
|
|
4006
|
+
"rmcp",
|
|
4007
|
+
"schemars",
|
|
4008
|
+
"serde",
|
|
4009
|
+
"serde_json",
|
|
4010
|
+
"tempfile",
|
|
4011
|
+
"tokio",
|
|
4012
|
+
]
|
|
4013
|
+
|
|
3996
4014
|
[[package]]
|
|
3997
4015
|
name = "yoke"
|
|
3998
4016
|
version = "0.8.3"
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
[workspace]
|
|
2
2
|
resolver = "2"
|
|
3
|
-
members = ["crates/cli", "crates/smbcloud-*"]
|
|
3
|
+
members = ["crates/cli", "crates/smbcloud-*", "crates/xcrs"]
|
|
4
4
|
|
|
5
5
|
[workspace.dependencies]
|
|
6
6
|
anyhow = "1.0.58"
|
|
7
7
|
async-trait = "0.1.51"
|
|
8
|
+
base64 = "0.22"
|
|
8
9
|
chrono = "0.4"
|
|
9
10
|
clap = "4.1.6"
|
|
10
11
|
clap_mangen = "0.2.10"
|
|
@@ -28,17 +29,17 @@ schemars = "1"
|
|
|
28
29
|
serde = "1"
|
|
29
30
|
serde_json = "1.0.82"
|
|
30
31
|
serde_repr = "0.1"
|
|
31
|
-
smbcloud-auth = { version = "0.
|
|
32
|
-
smbcloud-auth-sdk = { version = "0.
|
|
33
|
-
smbcloud-deploy = { version = "0.
|
|
34
|
-
smbcloud-email-sdk = { version = "0.
|
|
35
|
-
smbcloud-gresiq-sdk = { version = "0.
|
|
36
|
-
smbcloud-mail = { version = "0.
|
|
37
|
-
smbcloud-model = { version = "0.
|
|
38
|
-
smbcloud-network = { version = "0.
|
|
39
|
-
smbcloud-networking = { version = "0.
|
|
40
|
-
smbcloud-networking-project = { version = "0.
|
|
41
|
-
smbcloud-utils = { version = "0.
|
|
32
|
+
smbcloud-auth = { version = "0.5.0", path = "crates/smbcloud-auth" }
|
|
33
|
+
smbcloud-auth-sdk = { version = "0.5.0", path = "crates/smbcloud-auth-sdk" }
|
|
34
|
+
smbcloud-deploy = { version = "0.5.0", path = "crates/smbcloud-deploy" }
|
|
35
|
+
smbcloud-email-sdk = { version = "0.5.0", path = "crates/smbcloud-email-sdk" }
|
|
36
|
+
smbcloud-gresiq-sdk = { version = "0.5.0", path = "crates/smbcloud-gresiq-sdk" }
|
|
37
|
+
smbcloud-mail = { version = "0.5.0", path = "crates/smbcloud-mail" }
|
|
38
|
+
smbcloud-model = { version = "0.5.0", path = "crates/smbcloud-model" }
|
|
39
|
+
smbcloud-network = { version = "0.5.0", path = "crates/smbcloud-network" }
|
|
40
|
+
smbcloud-networking = { version = "0.5.0", path = "crates/smbcloud-networking" }
|
|
41
|
+
smbcloud-networking-project = { version = "0.5.0", path = "crates/smbcloud-networking-project" }
|
|
42
|
+
smbcloud-utils = { version = "0.5.0", path = "crates/smbcloud-utils" }
|
|
42
43
|
spinners = "4.1.0"
|
|
43
44
|
strum = "0.27"
|
|
44
45
|
strum_macros = "0.27"
|
|
@@ -55,3 +56,4 @@ tsync = "2"
|
|
|
55
56
|
uniffi = "0.31"
|
|
56
57
|
url-builder = "0.1.1"
|
|
57
58
|
wasm-bindgen = "0.2"
|
|
59
|
+
xcrs = { version = "0.5.0", path = "crates/xcrs" }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "smbcloud-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
authors = ["Seto Elkahfi <seto@smbcloud.xyz>"]
|
|
6
6
|
description = "smbCloud command line interface."
|
|
@@ -47,6 +47,7 @@ serde_json = { workspace = true }
|
|
|
47
47
|
serde_repr = { workspace = true }
|
|
48
48
|
smbcloud-auth = { workspace = true }
|
|
49
49
|
smbcloud-deploy = { workspace = true }
|
|
50
|
+
smbcloud-email-sdk = { workspace = true }
|
|
50
51
|
smbcloud-mail = { workspace = true }
|
|
51
52
|
smbcloud-model = { workspace = true }
|
|
52
53
|
smbcloud-network = { workspace = true }
|
|
@@ -63,6 +64,7 @@ tracing = { workspace = true, features = ["log"] }
|
|
|
63
64
|
tracing-bunyan-formatter = { workspace = true }
|
|
64
65
|
tracing-subscriber = { workspace = true, features = ["registry", "env-filter"] }
|
|
65
66
|
url-builder = { workspace = true }
|
|
67
|
+
xcrs = { workspace = true }
|
|
66
68
|
|
|
67
69
|
[target.'cfg(not(windows))'.dependencies]
|
|
68
70
|
openssl = { workspace = true }
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
use {
|
|
2
|
+
crate::{account, cloud_auth, mail, project, tenant},
|
|
3
|
+
clap::{Parser, Subcommand, ValueEnum},
|
|
4
|
+
smbcloud_network::environment::Environment,
|
|
5
|
+
spinners::Spinner,
|
|
6
|
+
std::path::PathBuf,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
pub struct CommandResult {
|
|
10
|
+
pub spinner: Spinner,
|
|
11
|
+
pub symbol: String,
|
|
12
|
+
pub msg: String,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
impl CommandResult {
|
|
16
|
+
pub fn stop_and_persist(mut self) {
|
|
17
|
+
self.spinner.stop_and_persist(&self.symbol, self.msg);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, ValueEnum)]
|
|
22
|
+
pub enum McpScope {
|
|
23
|
+
#[default]
|
|
24
|
+
Cloud,
|
|
25
|
+
Automation,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#[derive(Parser)]
|
|
29
|
+
#[clap(author, version, about)]
|
|
30
|
+
pub struct Cli {
|
|
31
|
+
/// Environment: dev, production
|
|
32
|
+
#[arg(short, long, env = "ENVIRONMENT", default_value = "production")]
|
|
33
|
+
pub environment: Environment,
|
|
34
|
+
|
|
35
|
+
/// Log level: trace, debug, info, warn, error, off
|
|
36
|
+
#[clap(short, long, global = true)]
|
|
37
|
+
pub log_level: Option<String>,
|
|
38
|
+
|
|
39
|
+
/// Non-interactive mode for CI/automation: disable prompts. Confirmations
|
|
40
|
+
/// use their default; prompts that need real input fail fast instead of
|
|
41
|
+
/// blocking. Also enabled by SMB_CI=1 or the conventional CI env var.
|
|
42
|
+
#[arg(long, global = true, env = "SMB_CI")]
|
|
43
|
+
pub ci: bool,
|
|
44
|
+
|
|
45
|
+
/// Full-screen TUI mode: render read commands in an interactive ratatui
|
|
46
|
+
/// view instead of plain text. Mutually exclusive with --mcp.
|
|
47
|
+
#[arg(long, global = true, conflicts_with = "mcp")]
|
|
48
|
+
pub tui: bool,
|
|
49
|
+
|
|
50
|
+
/// Run as an MCP (Model Context Protocol) server over stdio instead of a
|
|
51
|
+
/// one-shot command. Implies non-interactive; the subcommand is ignored.
|
|
52
|
+
#[arg(long, global = true)]
|
|
53
|
+
pub mcp: bool,
|
|
54
|
+
|
|
55
|
+
/// MCP tool profile to expose. Cloud serves smbCloud resources; automation
|
|
56
|
+
/// serves cross-platform mobile and TV device tools.
|
|
57
|
+
#[arg(
|
|
58
|
+
long = "scope",
|
|
59
|
+
global = true,
|
|
60
|
+
value_enum,
|
|
61
|
+
default_value_t,
|
|
62
|
+
requires = "mcp"
|
|
63
|
+
)]
|
|
64
|
+
pub mcp_scope: McpScope,
|
|
65
|
+
|
|
66
|
+
#[command(subcommand)]
|
|
67
|
+
pub command: Option<Commands>,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
#[derive(Subcommand)]
|
|
71
|
+
pub enum Commands {
|
|
72
|
+
#[clap(about = "Your account info.", display_order = 3)]
|
|
73
|
+
Me {},
|
|
74
|
+
#[clap(
|
|
75
|
+
about = "Deploy project. This is smb main command. Requires an smbCloud account.",
|
|
76
|
+
display_order = 0
|
|
77
|
+
)]
|
|
78
|
+
Deploy {
|
|
79
|
+
/// Name of the sub-project to deploy (for monorepo configs with [[projects]]).
|
|
80
|
+
/// Matches the `name` field in .smb/config.toml. Omit to deploy the root project.
|
|
81
|
+
#[arg(short, long)]
|
|
82
|
+
project: Option<String>,
|
|
83
|
+
},
|
|
84
|
+
#[clap(
|
|
85
|
+
about = "Initialize project. Requires an smbCloud account.",
|
|
86
|
+
display_order = 1
|
|
87
|
+
)]
|
|
88
|
+
Init {},
|
|
89
|
+
#[clap(about = "Login to your account.", display_order = 2)]
|
|
90
|
+
Login {},
|
|
91
|
+
#[clap(about = "Logout from your account.", display_order = 3)]
|
|
92
|
+
Logout {},
|
|
93
|
+
#[clap(about = "Manage your account.")]
|
|
94
|
+
Account {
|
|
95
|
+
#[clap(subcommand)]
|
|
96
|
+
command: account::cli::Commands,
|
|
97
|
+
},
|
|
98
|
+
#[clap(about = "Manage your projects.")]
|
|
99
|
+
Project {
|
|
100
|
+
#[clap(subcommand)]
|
|
101
|
+
command: project::cli::Commands,
|
|
102
|
+
},
|
|
103
|
+
#[clap(about = "Manage your tenants.")]
|
|
104
|
+
Tenant {
|
|
105
|
+
#[clap(subcommand)]
|
|
106
|
+
command: tenant::cli::Commands,
|
|
107
|
+
},
|
|
108
|
+
#[clap(about = "Manage smbCloud Mail.")]
|
|
109
|
+
Mail {
|
|
110
|
+
#[clap(subcommand)]
|
|
111
|
+
command: mail::cli::Commands,
|
|
112
|
+
},
|
|
113
|
+
#[clap(about = "Manage smbCloud Auth apps.")]
|
|
114
|
+
Auth {
|
|
115
|
+
#[clap(subcommand)]
|
|
116
|
+
command: cloud_auth::cli::Commands,
|
|
117
|
+
},
|
|
118
|
+
#[clap(about = "Run and control XCRS ControlKit on Apple devices.")]
|
|
119
|
+
ControlKit {
|
|
120
|
+
#[clap(subcommand)]
|
|
121
|
+
command: ControlKitCommands,
|
|
122
|
+
},
|
|
123
|
+
#[clap(
|
|
124
|
+
about = "Migrate local .smb/config.toml deploy fields to the smbCloud server.",
|
|
125
|
+
display_order = 4
|
|
126
|
+
)]
|
|
127
|
+
Migrate {},
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#[cfg(test)]
|
|
131
|
+
mod tests {
|
|
132
|
+
use super::*;
|
|
133
|
+
|
|
134
|
+
#[test]
|
|
135
|
+
fn mcp_defaults_to_cloud_scope() {
|
|
136
|
+
let cli = Cli::try_parse_from(["smb", "--mcp"]).expect("MCP arguments should parse");
|
|
137
|
+
|
|
138
|
+
assert_eq!(cli.mcp_scope, McpScope::Cloud);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#[test]
|
|
142
|
+
fn mcp_accepts_automation_scope() {
|
|
143
|
+
let cli = Cli::try_parse_from(["smb", "--mcp", "--scope", "automation"])
|
|
144
|
+
.expect("automation MCP arguments should parse");
|
|
145
|
+
|
|
146
|
+
assert_eq!(cli.mcp_scope, McpScope::Automation);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#[test]
|
|
150
|
+
fn scope_requires_mcp_mode() {
|
|
151
|
+
// `Cli` has no `Debug` impl (clap's `Parser` doesn't require one), so
|
|
152
|
+
// `expect_err`/`unwrap_err` (which bound the `Ok` type on `Debug`)
|
|
153
|
+
// don't apply here; match the `Result` instead.
|
|
154
|
+
let result = Cli::try_parse_from(["smb", "--scope", "automation"]);
|
|
155
|
+
let error = match result {
|
|
156
|
+
Err(error) => error,
|
|
157
|
+
Ok(_) => panic!("scope without MCP mode should be rejected"),
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
assert_eq!(
|
|
161
|
+
error.kind(),
|
|
162
|
+
clap::error::ErrorKind::MissingRequiredArgument
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#[derive(Subcommand)]
|
|
168
|
+
pub enum ControlKitCommands {
|
|
169
|
+
#[clap(about = "Build a signed ControlKit XCTest runner for a physical device.")]
|
|
170
|
+
Build {
|
|
171
|
+
#[arg(long)]
|
|
172
|
+
project_path: PathBuf,
|
|
173
|
+
#[arg(long, default_value = "ControlKit")]
|
|
174
|
+
scheme: String,
|
|
175
|
+
#[arg(long, default_value = "Release")]
|
|
176
|
+
configuration: String,
|
|
177
|
+
#[arg(long)]
|
|
178
|
+
device_udid: String,
|
|
179
|
+
#[arg(long)]
|
|
180
|
+
derived_data_path: PathBuf,
|
|
181
|
+
},
|
|
182
|
+
#[clap(about = "Start a built ControlKit XCTest runner on a physical device.")]
|
|
183
|
+
Start {
|
|
184
|
+
#[arg(long)]
|
|
185
|
+
device_udid: String,
|
|
186
|
+
#[arg(long)]
|
|
187
|
+
xctestrun_path: PathBuf,
|
|
188
|
+
#[arg(long, default_value = "::")]
|
|
189
|
+
listen_host: String,
|
|
190
|
+
#[arg(long, default_value_t = 12004)]
|
|
191
|
+
listen_port: u16,
|
|
192
|
+
#[arg(long, default_value_t = 120)]
|
|
193
|
+
timeout_seconds: u64,
|
|
194
|
+
#[arg(long)]
|
|
195
|
+
log_path: Option<PathBuf>,
|
|
196
|
+
},
|
|
197
|
+
#[clap(about = "Call a running ControlKit JSON-RPC method.")]
|
|
198
|
+
Call {
|
|
199
|
+
#[arg(long, required_unless_present = "host", conflicts_with = "host")]
|
|
200
|
+
device_udid: Option<String>,
|
|
201
|
+
#[arg(long, conflicts_with = "device_udid")]
|
|
202
|
+
host: Option<String>,
|
|
203
|
+
#[arg(long, default_value_t = 12004)]
|
|
204
|
+
port: u16,
|
|
205
|
+
#[arg(long)]
|
|
206
|
+
method: String,
|
|
207
|
+
#[arg(long, default_value = "{}")]
|
|
208
|
+
params: String,
|
|
209
|
+
},
|
|
210
|
+
}
|
|
@@ -28,7 +28,9 @@ pub(crate) fn print_auth_apps(auth_apps: &[AuthApp]) {
|
|
|
28
28
|
"#{} {} project={}",
|
|
29
29
|
auth_app.id,
|
|
30
30
|
style(&auth_app.name).bold(),
|
|
31
|
-
auth_app
|
|
31
|
+
auth_app
|
|
32
|
+
.project_id
|
|
33
|
+
.map_or_else(|| "-".to_string(), |id| id.to_string())
|
|
32
34
|
);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -37,7 +39,9 @@ pub(crate) fn print_auth_app_detail(auth_app: &AuthApp) {
|
|
|
37
39
|
print_heading("Auth app");
|
|
38
40
|
print_field("ID", &auth_app.id);
|
|
39
41
|
print_field("Name", &auth_app.name);
|
|
40
|
-
|
|
42
|
+
if let Some(project_id) = auth_app.project_id {
|
|
43
|
+
print_field("Project ID", project_id.to_string());
|
|
44
|
+
}
|
|
41
45
|
print_optional_field("Support email", auth_app.support_email.as_deref());
|
|
42
46
|
print_optional_field("Secret", auth_app.secret.as_deref());
|
|
43
47
|
print_field("Created at", auth_app.created_at.to_rfc3339());
|
|
@@ -124,6 +124,9 @@ pub(crate) async fn overlay_server_config(
|
|
|
124
124
|
if let Some(remote_pm2_env) = deploy_config.pm2_env {
|
|
125
125
|
config.project.pm2_env = Some(remote_pm2_env);
|
|
126
126
|
}
|
|
127
|
+
if let Some(remote_process_manager) = deploy_config.process_manager {
|
|
128
|
+
config.project.process_manager = Some(remote_process_manager);
|
|
129
|
+
}
|
|
127
130
|
if let Some(remote_port) = deploy_config.port {
|
|
128
131
|
config.project.port = Some(remote_port);
|
|
129
132
|
}
|
{smbcloud_cli-0.4.13 → smbcloud_cli-0.5.0}/crates/cli/src/cloud-deploy/process_deploy_nextjs_ssr.rs
RENAMED
|
@@ -85,6 +85,83 @@ fn prune_dangling_symlinks(root: &std::path::Path) -> std::io::Result<usize> {
|
|
|
85
85
|
Ok(removed)
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/// Build the shell snippet that (re)starts the app after the standalone bundle
|
|
89
|
+
/// is on the server.
|
|
90
|
+
///
|
|
91
|
+
/// Two supervisors are supported, selected by `process_manager` (matched
|
|
92
|
+
/// case-insensitively):
|
|
93
|
+
/// - `None` / `"pm2"` → **pm2** (default): delete + start fresh, preferring an
|
|
94
|
+
/// operator-managed `ecosystem.config.cjs`/`.js`, else `pm2 start node --
|
|
95
|
+
/// server.js` with `PORT`/`HOSTNAME` inline.
|
|
96
|
+
/// - `"systemd"` → a **git-owned `systemctl --user` service** named
|
|
97
|
+
/// `<pm2_app>.service` (created out-of-band; see the smbcloud-deploy-nextjs
|
|
98
|
+
/// skill). Restarted with no sudo — the deploy SSHes as the git app-owner,
|
|
99
|
+
/// and `systemctl --user` (with `XDG_RUNTIME_DIR` set) drives that user's own
|
|
100
|
+
/// manager. Fails loudly if the unit does not exist.
|
|
101
|
+
///
|
|
102
|
+
/// Any other value is a hard error rather than a silent fall back to pm2: on an
|
|
103
|
+
/// app already migrated to systemd, a typo like `system` would otherwise start
|
|
104
|
+
/// a second pm2 process that collides with the systemd-owned port — the exact
|
|
105
|
+
/// double-supervisor outage this option exists to prevent.
|
|
106
|
+
///
|
|
107
|
+
/// The returned snippet references the shell var `$PM2_APP` (set earlier in the
|
|
108
|
+
/// deploy script). `port` is only used by the pm2 path.
|
|
109
|
+
fn restart_stanza(process_manager: Option<&str>, port: u16) -> Result<String> {
|
|
110
|
+
let use_systemd = match process_manager.map(str::trim) {
|
|
111
|
+
None | Some("") => false,
|
|
112
|
+
Some(m) if m.eq_ignore_ascii_case("pm2") => false,
|
|
113
|
+
Some(m) if m.eq_ignore_ascii_case("systemd") => true,
|
|
114
|
+
Some(other) => {
|
|
115
|
+
return Err(anyhow!(fail_message(&format!(
|
|
116
|
+
"Unknown process_manager '{other}' in .smb/config.toml. \
|
|
117
|
+
Expected \"pm2\" (default) or \"systemd\"."
|
|
118
|
+
))))
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
Ok(if use_systemd {
|
|
123
|
+
r#" echo "Restarting $PM2_APP via systemd --user…"
|
|
124
|
+
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
|
|
125
|
+
UNIT="$PM2_APP.service"
|
|
126
|
+
if ! systemctl --user cat "$UNIT" >/dev/null 2>&1; then
|
|
127
|
+
echo "Error: systemd --user unit $UNIT not found on the server."
|
|
128
|
+
echo "Create ~/.config/systemd/user/$UNIT and enable it (see the"
|
|
129
|
+
echo "smbcloud-deploy-nextjs skill, 'Process manager: systemd --user'),"
|
|
130
|
+
echo "or unset process_manager to stay on pm2. Then re-deploy."
|
|
131
|
+
exit 1
|
|
132
|
+
fi
|
|
133
|
+
systemctl --user restart "$UNIT"
|
|
134
|
+
sleep 3
|
|
135
|
+
if ! systemctl --user is-active "$UNIT" >/dev/null 2>&1; then
|
|
136
|
+
echo "Error: $UNIT failed to become active after restart."
|
|
137
|
+
systemctl --user status "$UNIT" --no-pager 2>&1 | head -20 || true
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
echo "Done."
|
|
141
|
+
"#
|
|
142
|
+
.to_string()
|
|
143
|
+
} else {
|
|
144
|
+
format!(
|
|
145
|
+
r#" echo "Starting $PM2_APP with pm2..."
|
|
146
|
+
if pm2 describe "$PM2_APP" > /dev/null 2>&1; then
|
|
147
|
+
pm2 delete "$PM2_APP"
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if [ -f ecosystem.config.cjs ]; then
|
|
151
|
+
pm2 start ecosystem.config.cjs --only "$PM2_APP" --env production
|
|
152
|
+
elif [ -f ecosystem.config.js ]; then
|
|
153
|
+
pm2 start ecosystem.config.js --only "$PM2_APP" --env production
|
|
154
|
+
else
|
|
155
|
+
NODE_ENV=production PORT={port} HOSTNAME=127.0.0.1 pm2 start node --name "$PM2_APP" -- server.js
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
pm2 save
|
|
159
|
+
echo "Done."
|
|
160
|
+
"#
|
|
161
|
+
)
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
88
165
|
/// Deploys a Next.js SSR app using standalone output mode.
|
|
89
166
|
///
|
|
90
167
|
/// Requires `output: 'standalone'` in next.config.js. This produces a
|
|
@@ -99,7 +176,8 @@ fn prune_dangling_symlinks(root: &std::path::Path) -> std::io::Result<usize> {
|
|
|
99
176
|
/// 4. rsync .next/standalone/ → server:path/ (server + bundled deps)
|
|
100
177
|
/// 5. rsync .next/static/ → server:path/.next/static/ (static chunks)
|
|
101
178
|
/// 6. rsync public/ → server:path/public/ (public assets)
|
|
102
|
-
/// 7. SSH:
|
|
179
|
+
/// 7. SSH: restart the app — pm2 (default) or a git-owned systemd --user
|
|
180
|
+
/// service when `process_manager = "systemd"` (see `restart_stanza`)
|
|
103
181
|
/// 8. PATCH deployment record as Done
|
|
104
182
|
pub async fn process_deploy_nextjs_ssr(env: Environment, config: Config) -> Result<CommandResult> {
|
|
105
183
|
let source = config.project.source.as_deref().unwrap_or(".");
|
|
@@ -530,6 +608,9 @@ pub async fn process_deploy_nextjs_ssr(env: Environment, config: Config) -> Resu
|
|
|
530
608
|
)
|
|
531
609
|
};
|
|
532
610
|
|
|
611
|
+
// Runtime supervisor: pm2 (default) or a git-owned systemd --user service.
|
|
612
|
+
let restart_stanza = restart_stanza(config.project.process_manager.as_deref(), port)?;
|
|
613
|
+
|
|
533
614
|
let deploy_script = format!(
|
|
534
615
|
r#"set -e
|
|
535
616
|
APP_PATH="{remote_path}"
|
|
@@ -662,26 +743,11 @@ EOF
|
|
|
662
743
|
ln -sfn ../../server.js .next/standalone/server.js
|
|
663
744
|
fi
|
|
664
745
|
|
|
665
|
-
|
|
666
|
-
if pm2 describe "$PM2_APP" > /dev/null 2>&1; then
|
|
667
|
-
pm2 delete "$PM2_APP"
|
|
668
|
-
fi
|
|
669
|
-
|
|
670
|
-
if [ -f ecosystem.config.cjs ]; then
|
|
671
|
-
pm2 start ecosystem.config.cjs --only "$PM2_APP" --env production
|
|
672
|
-
elif [ -f ecosystem.config.js ]; then
|
|
673
|
-
pm2 start ecosystem.config.js --only "$PM2_APP" --env production
|
|
674
|
-
else
|
|
675
|
-
NODE_ENV=production PORT={port} HOSTNAME=127.0.0.1 pm2 start node --name "$PM2_APP" -- server.js
|
|
676
|
-
fi
|
|
677
|
-
|
|
678
|
-
pm2 save
|
|
679
|
-
echo "Done."
|
|
680
|
-
"#,
|
|
746
|
+
{restart} "#,
|
|
681
747
|
remote_path = remote_path,
|
|
682
748
|
pm2_app = pm2_app,
|
|
683
749
|
runtime_subdir = runtime_subdir_for_shell,
|
|
684
|
-
|
|
750
|
+
restart = restart_stanza,
|
|
685
751
|
ecosystem_config = ecosystem_config_content,
|
|
686
752
|
);
|
|
687
753
|
|
|
@@ -828,7 +894,11 @@ async fn mark_failed(
|
|
|
828
894
|
|
|
829
895
|
#[cfg(all(test, unix))]
|
|
830
896
|
mod tests {
|
|
831
|
-
use {
|
|
897
|
+
use {
|
|
898
|
+
super::{prune_dangling_symlinks, restart_stanza},
|
|
899
|
+
std::os::unix::fs::symlink,
|
|
900
|
+
tempfile::tempdir,
|
|
901
|
+
};
|
|
832
902
|
|
|
833
903
|
/// Mirrors the real failure: a pnpm compat link points at a version dir that
|
|
834
904
|
/// was never traced into the bundle, so it dangles and must be pruned, while
|
|
@@ -915,4 +985,40 @@ mod tests {
|
|
|
915
985
|
"the dangling root symlink is gone"
|
|
916
986
|
);
|
|
917
987
|
}
|
|
988
|
+
|
|
989
|
+
#[test]
|
|
990
|
+
fn restart_stanza_defaults_to_pm2() {
|
|
991
|
+
for pm in [None, Some(""), Some("pm2"), Some("PM2"), Some(" pm2 ")] {
|
|
992
|
+
let s = restart_stanza(pm, 3025).expect("pm2 selector is valid");
|
|
993
|
+
assert!(s.contains("pm2 start"), "pm={pm:?} should use pm2");
|
|
994
|
+
assert!(s.contains("PORT=3025"), "pm={pm:?} injects the port");
|
|
995
|
+
assert!(!s.contains("systemctl"), "pm={pm:?} must not touch systemd");
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/// An unrecognized supervisor must abort the deploy, not quietly run pm2
|
|
1000
|
+
/// alongside a systemd-owned process and fight over the port.
|
|
1001
|
+
#[test]
|
|
1002
|
+
fn restart_stanza_rejects_unknown_process_manager() {
|
|
1003
|
+
for pm in ["system", "systemctl", "supervisord", "PM3"] {
|
|
1004
|
+
let err = restart_stanza(Some(pm), 3025)
|
|
1005
|
+
.expect_err("unknown process_manager must be rejected");
|
|
1006
|
+
let msg = err.to_string();
|
|
1007
|
+
assert!(msg.contains(pm), "error names the offending value: {msg}");
|
|
1008
|
+
assert!(msg.contains("systemd"), "error lists valid options: {msg}");
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
#[test]
|
|
1013
|
+
fn restart_stanza_systemd_uses_user_unit_no_sudo() {
|
|
1014
|
+
let s = restart_stanza(Some("systemd"), 3025).expect("systemd selector is valid");
|
|
1015
|
+
assert!(s.contains("systemctl --user restart \"$UNIT\""));
|
|
1016
|
+
assert!(s.contains("UNIT=\"$PM2_APP.service\""));
|
|
1017
|
+
assert!(s.contains("XDG_RUNTIME_DIR=\"/run/user/$(id -u)\""));
|
|
1018
|
+
// No sudo (git drives its own user manager) and no pm2 fallback.
|
|
1019
|
+
assert!(!s.contains("sudo"), "must not require sudo");
|
|
1020
|
+
assert!(!s.contains("pm2 "), "systemd path must not call pm2");
|
|
1021
|
+
// Case-insensitive selector.
|
|
1022
|
+
assert_eq!(s, restart_stanza(Some("SystemD"), 3025).unwrap());
|
|
1023
|
+
}
|
|
918
1024
|
}
|