hap-cli 0.8.4__tar.gz → 0.8.6__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.
- {hap_cli-0.8.4 → hap_cli-0.8.6}/PKG-INFO +26 -3
- {hap_cli-0.8.4/hap_cli → hap_cli-0.8.6}/README.md +25 -2
- {hap_cli-0.8.4 → hap_cli-0.8.6/hap_cli}/README.md +25 -2
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/README_CN.md +21 -2
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/__init__.py +1 -1
- hap_cli-0.8.6/hap_cli/__main__.py +11 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/auth_cmd.py +6 -28
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/icon_cmd.py +50 -5
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/instance_cmd.py +3 -1
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/node_cmd.py +30 -9
- hap_cli-0.8.6/hap_cli/commands/update_cmd.py +101 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/workflow_cmd.py +8 -1
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/auth.py +123 -198
- hap_cli-0.8.6/hap_cli/core/cli_access.py +276 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/flow_node.py +103 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/icon_index.py +19 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/record.py +16 -4
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/session.py +11 -0
- hap_cli-0.8.6/hap_cli/core/update.py +294 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/workflow.py +9 -3
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/hap_cli.py +18 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/locale/messages.json +6 -3
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/conftest.py +22 -0
- hap_cli-0.8.6/hap_cli/tests/test_auth_prerelease.py +154 -0
- hap_cli-0.8.6/hap_cli/tests/test_cli_access.py +320 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_core.py +217 -2
- hap_cli-0.8.6/hap_cli/tests/test_instance_history_cli.py +34 -0
- hap_cli-0.8.6/hap_cli/tests/test_record_field_alias.py +146 -0
- hap_cli-0.8.6/hap_cli/tests/test_update.py +423 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/PKG-INFO +26 -3
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/SOURCES.txt +8 -0
- hap_cli-0.8.4/hap_cli/tests/test_auth_prerelease.py +0 -410
- {hap_cli-0.8.4 → hap_cli-0.8.6}/MANIFEST.in +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/__main__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/config.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/harness.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/smoke.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/state.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/app_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/app_editor_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/calendar_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/chart_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/chat_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/chatbot_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/config_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/contact_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/department_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/group_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/optionset_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/page_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/post_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/record_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/region_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/role_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/upload_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/v3_registry.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/worksheet_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/context.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/action_spec_adapter.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/app.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/calendar_mod.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/chart.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/chat.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/chatbot.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/contact.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/control_type_codes.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/department.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/apply.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/componentlower.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/editspec.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/errors.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/fieldlower.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/jsonschema_mini.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/models.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/ops.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/planner.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/reader.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/field_normalizer.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/field_spec_adapter.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/filter_translator.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/global_meta.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/group.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/instance.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/logger.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/optionset.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/page.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/post.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/response_crypto.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/role.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/role_perm_builder.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/token_crypto.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/upload.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/dispatcher.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/render.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/schema.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/view_spec_adapter.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/workflow_node_dsl.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/worksheet.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/worksheet_templates.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/i18n.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/locale/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/locale/messages.schema.json +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_app_editor.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_app_export_usage.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_bug_036430.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_chart.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_config_cmd.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_destructive_confirm_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_full_e2e.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_global_meta.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_i18n.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_approval.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_approval_actions.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_calendar.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_destructive.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_misc.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_post.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_social.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_v3.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_workflow.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_multi_profile.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_org_approval_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_org_id_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_org_id_docs.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_parameter_conventions.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_record_batch_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_record_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_semantic_types_registry.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_api_schema_loader.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_dispatcher.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_registry_coverage.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_session.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_yaml_translation.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_workflow_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_worksheet_crud_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_worksheet_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/formatting.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/options.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/parameter_mapping.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/dependency_links.txt +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/entry_points.txt +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/requires.txt +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/top_level.txt +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/__main__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/_wftest.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/charts.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/cleanup.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/compiler.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/config.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/errors.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/executor.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/fields.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/hap.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/console.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/jsonl.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/mirror.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/report.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/schema.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/__init__.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/cli.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/executor.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/template.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/selftest.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/smoke.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/step.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/steps.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/store.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/workflow_dsl.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/setup.cfg +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/setup.py +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/component.schema.json +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/custom-action.schema.json +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/envelope.schema.json +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/field.schema.json +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/INDEX.json +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/create_optionset.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/create_role.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_optionset.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_record.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_role.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_app_info.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_details.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_list.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_logs.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_relations.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_regions.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_role_details.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_role_list.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/knowledge_search.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
- {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/update_optionset.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hap-cli
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.6
|
|
4
4
|
Summary: CLI harness for MingDAO HAP - Enterprise no-code platform
|
|
5
5
|
Author: hap-cli
|
|
6
6
|
License: Apache-2.0
|
|
@@ -285,8 +285,8 @@ discover every subcommand.
|
|
|
285
285
|
|
|
286
286
|
| Command | Description |
|
|
287
287
|
|---|---|
|
|
288
|
-
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); no keyword lists all |
|
|
289
|
-
| `icon list` | List
|
|
288
|
+
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); fewer than 10 matches get random suggestions appended; no keyword lists all |
|
|
289
|
+
| `icon list [-n SIZE] [-p PAGE]` | List icons page by page with keywords (50 per page by default) |
|
|
290
290
|
|
|
291
291
|
### upload — file upload
|
|
292
292
|
|
|
@@ -313,8 +313,31 @@ body, and a redacted `Authorization` header (first 16 chars). `password`
|
|
|
313
313
|
and other sensitive keys are masked. `HAP_LOG_LEVEL=DEBUG` temporarily
|
|
314
314
|
overrides the persisted level.
|
|
315
315
|
|
|
316
|
+
### update — keep the CLI current
|
|
317
|
+
|
|
318
|
+
| Command | Description |
|
|
319
|
+
|---|---|
|
|
320
|
+
| `update` | Check PyPI for a newer release and upgrade in place, using the same tool the CLI was installed with (pip / pipx / uv) |
|
|
321
|
+
| `update --check` | Only report whether a newer version exists, without installing |
|
|
322
|
+
|
|
316
323
|
---
|
|
317
324
|
|
|
325
|
+
## Organization CLI access control
|
|
326
|
+
|
|
327
|
+
Organizations can control whether CLI tools are allowed to call their
|
|
328
|
+
APIs. Before each command runs, `hap` checks this setting for the
|
|
329
|
+
current organization:
|
|
330
|
+
|
|
331
|
+
- **Enabled** — the command runs normally; the result is remembered for
|
|
332
|
+
5 minutes, so back-to-back commands stay fast.
|
|
333
|
+
- **Disabled** — the command is blocked with a message asking you to
|
|
334
|
+
contact an organization administrator to enable CLI access.
|
|
335
|
+
- **Setting not available** (older server versions) — the command runs
|
|
336
|
+
normally; the check is retried about once an hour.
|
|
337
|
+
|
|
338
|
+
If an administrator enables access after a command was blocked, just
|
|
339
|
+
re-run the command — the change takes effect immediately.
|
|
340
|
+
|
|
318
341
|
## Default app & organization
|
|
319
342
|
|
|
320
343
|
Every command that needs an `--app-id` resolves it in this order:
|
|
@@ -256,8 +256,8 @@ discover every subcommand.
|
|
|
256
256
|
|
|
257
257
|
| Command | Description |
|
|
258
258
|
|---|---|
|
|
259
|
-
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); no keyword lists all |
|
|
260
|
-
| `icon list` | List
|
|
259
|
+
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); fewer than 10 matches get random suggestions appended; no keyword lists all |
|
|
260
|
+
| `icon list [-n SIZE] [-p PAGE]` | List icons page by page with keywords (50 per page by default) |
|
|
261
261
|
|
|
262
262
|
### upload — file upload
|
|
263
263
|
|
|
@@ -284,8 +284,31 @@ body, and a redacted `Authorization` header (first 16 chars). `password`
|
|
|
284
284
|
and other sensitive keys are masked. `HAP_LOG_LEVEL=DEBUG` temporarily
|
|
285
285
|
overrides the persisted level.
|
|
286
286
|
|
|
287
|
+
### update — keep the CLI current
|
|
288
|
+
|
|
289
|
+
| Command | Description |
|
|
290
|
+
|---|---|
|
|
291
|
+
| `update` | Check PyPI for a newer release and upgrade in place, using the same tool the CLI was installed with (pip / pipx / uv) |
|
|
292
|
+
| `update --check` | Only report whether a newer version exists, without installing |
|
|
293
|
+
|
|
287
294
|
---
|
|
288
295
|
|
|
296
|
+
## Organization CLI access control
|
|
297
|
+
|
|
298
|
+
Organizations can control whether CLI tools are allowed to call their
|
|
299
|
+
APIs. Before each command runs, `hap` checks this setting for the
|
|
300
|
+
current organization:
|
|
301
|
+
|
|
302
|
+
- **Enabled** — the command runs normally; the result is remembered for
|
|
303
|
+
5 minutes, so back-to-back commands stay fast.
|
|
304
|
+
- **Disabled** — the command is blocked with a message asking you to
|
|
305
|
+
contact an organization administrator to enable CLI access.
|
|
306
|
+
- **Setting not available** (older server versions) — the command runs
|
|
307
|
+
normally; the check is retried about once an hour.
|
|
308
|
+
|
|
309
|
+
If an administrator enables access after a command was blocked, just
|
|
310
|
+
re-run the command — the change takes effect immediately.
|
|
311
|
+
|
|
289
312
|
## Default app & organization
|
|
290
313
|
|
|
291
314
|
Every command that needs an `--app-id` resolves it in this order:
|
|
@@ -256,8 +256,8 @@ discover every subcommand.
|
|
|
256
256
|
|
|
257
257
|
| Command | Description |
|
|
258
258
|
|---|---|
|
|
259
|
-
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); no keyword lists all |
|
|
260
|
-
| `icon list` | List
|
|
259
|
+
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); fewer than 10 matches get random suggestions appended; no keyword lists all |
|
|
260
|
+
| `icon list [-n SIZE] [-p PAGE]` | List icons page by page with keywords (50 per page by default) |
|
|
261
261
|
|
|
262
262
|
### upload — file upload
|
|
263
263
|
|
|
@@ -284,8 +284,31 @@ body, and a redacted `Authorization` header (first 16 chars). `password`
|
|
|
284
284
|
and other sensitive keys are masked. `HAP_LOG_LEVEL=DEBUG` temporarily
|
|
285
285
|
overrides the persisted level.
|
|
286
286
|
|
|
287
|
+
### update — keep the CLI current
|
|
288
|
+
|
|
289
|
+
| Command | Description |
|
|
290
|
+
|---|---|
|
|
291
|
+
| `update` | Check PyPI for a newer release and upgrade in place, using the same tool the CLI was installed with (pip / pipx / uv) |
|
|
292
|
+
| `update --check` | Only report whether a newer version exists, without installing |
|
|
293
|
+
|
|
287
294
|
---
|
|
288
295
|
|
|
296
|
+
## Organization CLI access control
|
|
297
|
+
|
|
298
|
+
Organizations can control whether CLI tools are allowed to call their
|
|
299
|
+
APIs. Before each command runs, `hap` checks this setting for the
|
|
300
|
+
current organization:
|
|
301
|
+
|
|
302
|
+
- **Enabled** — the command runs normally; the result is remembered for
|
|
303
|
+
5 minutes, so back-to-back commands stay fast.
|
|
304
|
+
- **Disabled** — the command is blocked with a message asking you to
|
|
305
|
+
contact an organization administrator to enable CLI access.
|
|
306
|
+
- **Setting not available** (older server versions) — the command runs
|
|
307
|
+
normally; the check is retried about once an hour.
|
|
308
|
+
|
|
309
|
+
If an administrator enables access after a command was blocked, just
|
|
310
|
+
re-run the command — the change takes effect immediately.
|
|
311
|
+
|
|
289
312
|
## Default app & organization
|
|
290
313
|
|
|
291
314
|
Every command that needs an `--app-id` resolves it in this order:
|
|
@@ -236,8 +236,8 @@ hap --json worksheet record list WORKSHEET_ID
|
|
|
236
236
|
|
|
237
237
|
| 命令 | 说明 |
|
|
238
238
|
|---|---|
|
|
239
|
-
| `icon search` |
|
|
240
|
-
| `icon list` |
|
|
239
|
+
| `icon search` | 按中英文关键词搜索图标(多关键词取并集,命中越多排越前);命中不足 10 个时随机补足推荐;无关键词列出全部 |
|
|
240
|
+
| `icon list [-n SIZE] [-p PAGE]` | 分页列出图标及其关键词(默认每页 50 个) |
|
|
241
241
|
|
|
242
242
|
### upload — 文件上传
|
|
243
243
|
|
|
@@ -260,8 +260,27 @@ hap --json worksheet record list WORKSHEET_ID
|
|
|
260
260
|
|
|
261
261
|
日志默认写入 `~/.hap-cli/hap-cli.log`,10 MB × 3 滚动。开启后每次 API 调用以 `INFO` 级别记录 URL、请求体、响应体,以及脱敏后的 `Authorization` 头(仅前 16 字符);`password` 等敏感字段会被自动打码。临时调试可设 `HAP_LOG_LEVEL=DEBUG`。
|
|
262
262
|
|
|
263
|
+
### update — 升级 CLI
|
|
264
|
+
|
|
265
|
+
| 命令 | 说明 |
|
|
266
|
+
|---|---|
|
|
267
|
+
| `update` | 检查 PyPI 上的最新版本,有新版则用安装时的工具(pip / pipx / uv)原地升级 |
|
|
268
|
+
| `update --check` | 只检查是否有新版本,不安装 |
|
|
269
|
+
|
|
263
270
|
---
|
|
264
271
|
|
|
272
|
+
## 组织 CLI 访问控制
|
|
273
|
+
|
|
274
|
+
组织可以控制是否允许 CLI 工具调用其接口。每条命令运行前,`hap`
|
|
275
|
+
会检查当前组织的这项设置:
|
|
276
|
+
|
|
277
|
+
- **已开启** — 命令正常执行;结果保留 5 分钟,连续命令不会变慢。
|
|
278
|
+
- **已关闭** — 命令被拦截,并提示联系组织管理员开启 CLI 访问权限。
|
|
279
|
+
- **服务器暂不支持该设置**(旧版本环境)— 命令正常执行,约每小时
|
|
280
|
+
重试一次检查。
|
|
281
|
+
|
|
282
|
+
如果命令被拦后管理员开启了权限,直接重跑命令即可,立即生效。
|
|
283
|
+
|
|
265
284
|
## 默认应用与组织
|
|
266
285
|
|
|
267
286
|
任何需要 `--app-id` 的命令解析顺序:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Allow ``python -m hap_cli`` — used by the detached background
|
|
2
|
+
update child (``hap update --background``), which is spawned with
|
|
3
|
+
``sys.executable -m hap_cli`` so it always runs in the same
|
|
4
|
+
environment as the parent process regardless of how the ``hap``
|
|
5
|
+
console script was installed.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from hap_cli.hap_cli import main
|
|
9
|
+
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
main()
|
|
@@ -54,7 +54,7 @@ def _paste_flow(ctx, server):
|
|
|
54
54
|
_api_host, webui = auth_mod.resolve_server(server)
|
|
55
55
|
if not ctx.json_mode:
|
|
56
56
|
click.echo(f"Log in at {webui} on a device with a browser,")
|
|
57
|
-
click.echo("then copy the
|
|
57
|
+
click.echo("then copy the token and paste it below.")
|
|
58
58
|
token = click.prompt("Paste token").strip()
|
|
59
59
|
return auth_mod.verify_token(server, token)
|
|
60
60
|
|
|
@@ -156,32 +156,6 @@ def auth_login(ctx, server, timeout, token_opt, profile_opt, force):
|
|
|
156
156
|
Use --token to supply a token non-interactively for scripts.
|
|
157
157
|
"""
|
|
158
158
|
try:
|
|
159
|
-
# Shared-credential warm switch: skip the browser when an
|
|
160
|
-
# existing session on a sibling host can be reused.
|
|
161
|
-
if not token_opt and auth_mod.can_warm_switch_to(server):
|
|
162
|
-
target_host = auth_mod._resolve_target_host(server)
|
|
163
|
-
if not ctx.json_mode:
|
|
164
|
-
click.echo(f"Switching to {target_host} using existing credentials...")
|
|
165
|
-
token, webui, user_info, meta, reused = (
|
|
166
|
-
auth_mod.shortcut_switch_shared_credential(server)
|
|
167
|
-
)
|
|
168
|
-
name = resolve_login_profile(profile_opt, webui, force)
|
|
169
|
-
_save_and_report(ctx, token, webui, user_info, meta, name)
|
|
170
|
-
if not ctx.json_mode and reused:
|
|
171
|
-
click.echo("(reused existing token — no browser opened)")
|
|
172
|
-
return
|
|
173
|
-
|
|
174
|
-
# Cold pre-release: no existing session, but target is meihua.
|
|
175
|
-
# The shortcut handles browser-to-prod-then-swap so users still
|
|
176
|
-
# land on meihua at the end.
|
|
177
|
-
if not token_opt and auth_mod.is_prerelease_login(server):
|
|
178
|
-
token, webui, user_info, meta, reused = (
|
|
179
|
-
auth_mod.shortcut_switch_shared_credential(server)
|
|
180
|
-
)
|
|
181
|
-
name = resolve_login_profile(profile_opt, webui, force)
|
|
182
|
-
_save_and_report(ctx, token, webui, user_info, meta, name)
|
|
183
|
-
return
|
|
184
|
-
|
|
185
159
|
if token_opt:
|
|
186
160
|
token, webui, user_info, meta = auth_mod.verify_token(server, token_opt)
|
|
187
161
|
else:
|
|
@@ -336,7 +310,11 @@ def auth_list_my_orgs(ctx):
|
|
|
336
310
|
@click.argument("org_id")
|
|
337
311
|
@pass_context
|
|
338
312
|
def auth_set_current_org(ctx, org_id):
|
|
339
|
-
"""Set the saved current organization.
|
|
313
|
+
"""Set the saved current organization.
|
|
314
|
+
|
|
315
|
+
Run 'hap auth list-my-orgs' first to see the organizations you
|
|
316
|
+
belong to and their IDs.
|
|
317
|
+
"""
|
|
340
318
|
try:
|
|
341
319
|
session = ctx.get_session()
|
|
342
320
|
org = auth_mod.switch_org(session, org_id)
|
|
@@ -40,25 +40,70 @@ def icon_search(ctx, query, limit):
|
|
|
40
40
|
"""Search icons by keyword (Chinese or English).
|
|
41
41
|
|
|
42
42
|
Pass one or more keywords; an icon must relate to every keyword to
|
|
43
|
-
match. With no keyword, lists the whole catalogue.
|
|
44
|
-
|
|
43
|
+
match. With no keyword, lists the whole catalogue. When fewer than
|
|
44
|
+
10 icons match, random suggestions top the list up to 10 so you
|
|
45
|
+
always have something to pick from. Use the returned icon name with
|
|
46
|
+
the --icon option of app/worksheet creation.
|
|
45
47
|
"""
|
|
46
48
|
try:
|
|
47
49
|
# With no keyword the command acts as "browse all"; the limit
|
|
48
50
|
# only narrows an actual keyword search.
|
|
49
51
|
effective_limit = limit if query else None
|
|
50
52
|
rows = ic_mod.search_icons(list(query), limit=effective_limit)
|
|
53
|
+
if query:
|
|
54
|
+
rows = ic_mod.pad_with_random_icons(
|
|
55
|
+
rows, target=min(10, max(0, limit))
|
|
56
|
+
)
|
|
51
57
|
ctx.output(rows, _icon_table)
|
|
52
58
|
except Exception as e:
|
|
53
59
|
ctx.handle_error(e)
|
|
54
60
|
|
|
55
61
|
|
|
56
62
|
@icon.command("list")
|
|
63
|
+
@click.option(
|
|
64
|
+
"--page-size",
|
|
65
|
+
"--size",
|
|
66
|
+
"-n",
|
|
67
|
+
"page_size",
|
|
68
|
+
type=int,
|
|
69
|
+
default=50,
|
|
70
|
+
show_default=True,
|
|
71
|
+
help="Icons per page.",
|
|
72
|
+
)
|
|
73
|
+
@click.option(
|
|
74
|
+
"--page",
|
|
75
|
+
"-p",
|
|
76
|
+
type=int,
|
|
77
|
+
default=1,
|
|
78
|
+
show_default=True,
|
|
79
|
+
help="Page number (1-based).",
|
|
80
|
+
)
|
|
57
81
|
@pass_context
|
|
58
|
-
def icon_list(ctx):
|
|
59
|
-
"""List
|
|
82
|
+
def icon_list(ctx, page_size, page):
|
|
83
|
+
"""List the icon catalogue page by page with keywords.
|
|
84
|
+
|
|
85
|
+
Shows 50 icons per page by default; use -p/--page to move through
|
|
86
|
+
the catalogue and -n/--page-size to change the page length.
|
|
87
|
+
"""
|
|
60
88
|
try:
|
|
61
89
|
rows = ic_mod.list_icons()
|
|
62
|
-
|
|
90
|
+
total = len(rows)
|
|
91
|
+
page_size = max(1, page_size)
|
|
92
|
+
pages = max(1, (total + page_size - 1) // page_size)
|
|
93
|
+
page = min(max(1, page), pages)
|
|
94
|
+
start = (page - 1) * page_size
|
|
95
|
+
data = {
|
|
96
|
+
"total": total,
|
|
97
|
+
"page": page,
|
|
98
|
+
"pages": pages,
|
|
99
|
+
"page_size": page_size,
|
|
100
|
+
"icons": rows[start : start + page_size],
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
def show(d):
|
|
104
|
+
_icon_table(d["icons"])
|
|
105
|
+
click.echo(f"Page {d['page']}/{d['pages']} · {d['total']} icons total")
|
|
106
|
+
|
|
107
|
+
ctx.output(data, show)
|
|
63
108
|
except Exception as e:
|
|
64
109
|
ctx.handle_error(e)
|
|
@@ -253,7 +253,9 @@ def instance_restart(ctx, instance_id, work_id):
|
|
|
253
253
|
|
|
254
254
|
|
|
255
255
|
@instance.command("history")
|
|
256
|
-
|
|
256
|
+
# getHistoryList requires processId server-side (instance.js:60-77 marks
|
|
257
|
+
# it *流程ID); omitting it returns HTTP 400 (bug #036490).
|
|
258
|
+
@click.option("--process-id", required=True, help="Workflow process ID")
|
|
257
259
|
@click.option("--status", "-s", default=0, type=int,
|
|
258
260
|
help="Status: 1=running, 2=completed, 3=rejected, 4=failed")
|
|
259
261
|
@click.option("--keyword", "-k", default="", help="Title search")
|
|
@@ -444,7 +444,7 @@ def node_create_code_template(ctx, name, code):
|
|
|
444
444
|
@click.option("--fields", "-f", default="", help="Field mapping JSON: [{fieldId,type,fieldValue}]")
|
|
445
445
|
@click.option("--name", "-n", default="", help="Node name")
|
|
446
446
|
@click.option("--select-node-id", "-s", default="", help="Source data node ID")
|
|
447
|
-
@click.option("--condition", default="", help="Filter conditions JSON")
|
|
447
|
+
@click.option("--condition", default="", help="Filter conditions JSON: [{fieldId, conditionId, value:[...]}] — field type is looked up automatically; AND within a list, wrap lists for OR groups")
|
|
448
448
|
@click.option("--sorts", default="", help="Sort rules JSON")
|
|
449
449
|
@pass_context
|
|
450
450
|
def node_save_action(ctx, process_id, node_id, action_id, app_id, fields,
|
|
@@ -465,12 +465,19 @@ def node_save_action(ctx, process_id, node_id, action_id, app_id, fields,
|
|
|
465
465
|
try:
|
|
466
466
|
session = ctx.get_session()
|
|
467
467
|
fields_list = json.loads(fields) if fields else None
|
|
468
|
-
|
|
468
|
+
filters_list = node_mod.condition_to_filters(
|
|
469
|
+
json.loads(condition) if condition else None)
|
|
470
|
+
if filters_list:
|
|
471
|
+
filters_list = node_mod.fill_condition_field_types(
|
|
472
|
+
session, process_id, node_id, filters_list,
|
|
473
|
+
app_id=app_id, select_node_id=select_node_id,
|
|
474
|
+
action_id=action_id,
|
|
475
|
+
)
|
|
469
476
|
sorts_list = json.loads(sorts) if sorts else None
|
|
470
477
|
data = node_mod.save_action_node(
|
|
471
478
|
session, process_id, node_id, action_id, app_id,
|
|
472
479
|
fields=fields_list, name=name, select_node_id=select_node_id,
|
|
473
|
-
|
|
480
|
+
filters=filters_list, sorts=sorts_list,
|
|
474
481
|
)
|
|
475
482
|
ctx.output(data, lambda d: click.echo("Action node saved."))
|
|
476
483
|
except json.JSONDecodeError as e:
|
|
@@ -489,7 +496,7 @@ def node_save_action(ctx, process_id, node_id, action_id, app_id, fields,
|
|
|
489
496
|
@click.option("--fields", "-f", default="", help="Return fields JSON")
|
|
490
497
|
@click.option("--name", "-n", default="", help="Node name")
|
|
491
498
|
@click.option("--select-node-id", "-s", default="", help="Source node ID (for 407)")
|
|
492
|
-
@click.option("--condition", default="", help="
|
|
499
|
+
@click.option("--condition", default="", help="Filter conditions JSON: [{fieldId, conditionId, value:[...]}] — field type is looked up automatically; AND within a list, wrap lists for OR groups")
|
|
493
500
|
@click.option("--sorts", default="", help="Sort rules JSON")
|
|
494
501
|
@click.option("--random", is_flag=True, help="Pick random record")
|
|
495
502
|
@click.option("--not-found", "execute_type", default=0, type=int,
|
|
@@ -515,12 +522,19 @@ def node_save_search(ctx, process_id, node_id, action_id, app_id, fields,
|
|
|
515
522
|
try:
|
|
516
523
|
session = ctx.get_session()
|
|
517
524
|
fields_list = json.loads(fields) if fields else None
|
|
518
|
-
|
|
525
|
+
filters_list = node_mod.condition_to_filters(
|
|
526
|
+
json.loads(condition) if condition else None)
|
|
527
|
+
if filters_list:
|
|
528
|
+
filters_list = node_mod.fill_condition_field_types(
|
|
529
|
+
session, process_id, node_id, filters_list,
|
|
530
|
+
app_id=app_id, select_node_id=select_node_id,
|
|
531
|
+
action_id=action_id,
|
|
532
|
+
)
|
|
519
533
|
sorts_list = json.loads(sorts) if sorts else None
|
|
520
534
|
data = node_mod.save_search_node(
|
|
521
535
|
session, process_id, node_id, action_id,
|
|
522
536
|
app_id=app_id, fields=fields_list, name=name,
|
|
523
|
-
select_node_id=select_node_id,
|
|
537
|
+
select_node_id=select_node_id, filters=filters_list,
|
|
524
538
|
sorts=sorts_list, random=random, execute_type=execute_type,
|
|
525
539
|
)
|
|
526
540
|
ctx.output(data, lambda d: click.echo("Search node saved."))
|
|
@@ -540,7 +554,7 @@ def node_save_search(ctx, process_id, node_id, action_id, app_id, fields,
|
|
|
540
554
|
@click.option("--fields", "-f", default="", help="Field mapping JSON")
|
|
541
555
|
@click.option("--name", "-n", default="", help="Node name")
|
|
542
556
|
@click.option("--select-node-id", "-s", default="", help="Source node ID (for 401)")
|
|
543
|
-
@click.option("--condition", default="", help="Filter conditions JSON")
|
|
557
|
+
@click.option("--condition", default="", help="Filter conditions JSON: [{fieldId, conditionId, value:[...]}] — field type is looked up automatically; AND within a list, wrap lists for OR groups")
|
|
544
558
|
@click.option("--sorts", default="", help="Sort rules JSON")
|
|
545
559
|
@click.option("--limit", "limit_json", default="", help="Record limit JSON: {fieldValue, fieldNodeId}")
|
|
546
560
|
@click.option("--random", is_flag=True, help="Pick random records")
|
|
@@ -565,13 +579,20 @@ def node_save_get_more(ctx, process_id, node_id, action_id, app_id, fields,
|
|
|
565
579
|
try:
|
|
566
580
|
session = ctx.get_session()
|
|
567
581
|
fields_list = json.loads(fields) if fields else None
|
|
568
|
-
|
|
582
|
+
filters_list = node_mod.condition_to_filters(
|
|
583
|
+
json.loads(condition) if condition else None)
|
|
584
|
+
if filters_list:
|
|
585
|
+
filters_list = node_mod.fill_condition_field_types(
|
|
586
|
+
session, process_id, node_id, filters_list,
|
|
587
|
+
app_id=app_id, select_node_id=select_node_id,
|
|
588
|
+
action_id=action_id,
|
|
589
|
+
)
|
|
569
590
|
sorts_list = json.loads(sorts) if sorts else None
|
|
570
591
|
limit_dict = json.loads(limit_json) if limit_json else None
|
|
571
592
|
data = node_mod.save_get_more_record_node(
|
|
572
593
|
session, process_id, node_id, action_id,
|
|
573
594
|
app_id=app_id, fields=fields_list, name=name,
|
|
574
|
-
select_node_id=select_node_id,
|
|
595
|
+
select_node_id=select_node_id, filters=filters_list,
|
|
575
596
|
sorts=sorts_list, number_field_value=limit_dict, random=random,
|
|
576
597
|
)
|
|
577
598
|
ctx.output(data, lambda d: click.echo("GetMoreRecord node saved."))
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""CLI command for self-updating hap-cli from PyPI.
|
|
2
|
+
|
|
3
|
+
The hidden ``--background`` flag is the entry point for the detached
|
|
4
|
+
child process spawned by the exit-time hook in ``hap_cli.py`` — it is
|
|
5
|
+
internal plumbing and intentionally absent from ``--help`` and docs.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
|
|
12
|
+
from hap_cli.context import pass_context
|
|
13
|
+
from hap_cli.core import update as upd
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.command("update")
|
|
17
|
+
@click.option(
|
|
18
|
+
"--check",
|
|
19
|
+
"check_only",
|
|
20
|
+
is_flag=True,
|
|
21
|
+
help="Only check whether a newer version exists; do not install.",
|
|
22
|
+
)
|
|
23
|
+
@click.option("--background", is_flag=True, hidden=True)
|
|
24
|
+
@pass_context
|
|
25
|
+
def update(ctx, check_only, background):
|
|
26
|
+
"""Upgrade hap-cli to the latest version from PyPI.
|
|
27
|
+
|
|
28
|
+
Checks for a newer release and installs it using the same tool the
|
|
29
|
+
CLI was installed with (pip, pipx, or uv). Installs that are not
|
|
30
|
+
managed from PyPI are left untouched.
|
|
31
|
+
"""
|
|
32
|
+
if background:
|
|
33
|
+
# Detached child: silent check-and-upgrade; results go to the
|
|
34
|
+
# state file and are surfaced on the next foreground run.
|
|
35
|
+
upd.run_background_update()
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
from hap_cli import __version__
|
|
39
|
+
|
|
40
|
+
kind = upd.get_install_kind()
|
|
41
|
+
if kind in ("editable", "unknown"):
|
|
42
|
+
ctx.output(
|
|
43
|
+
{"current": __version__, "install": kind, "updated": False},
|
|
44
|
+
lambda d: click.echo(
|
|
45
|
+
"This copy of hap-cli is not managed from PyPI "
|
|
46
|
+
f"(current version {__version__}) — nothing to update."
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
latest = upd.fetch_latest_version()
|
|
52
|
+
if latest is None:
|
|
53
|
+
ctx.handle_error(Exception("Could not reach PyPI to check for updates."))
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
if not upd.is_newer(latest, __version__):
|
|
57
|
+
upd.save_state(
|
|
58
|
+
{
|
|
59
|
+
"last_check_at": time.time(),
|
|
60
|
+
"latest_version": latest,
|
|
61
|
+
"last_result": "up_to_date",
|
|
62
|
+
"notified": True,
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
ctx.output(
|
|
66
|
+
{"current": __version__, "latest": latest, "updated": False},
|
|
67
|
+
lambda d: click.echo(
|
|
68
|
+
f"hap-cli {__version__} is already the latest version."
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
if check_only:
|
|
74
|
+
ctx.output(
|
|
75
|
+
{"current": __version__, "latest": latest, "updated": False},
|
|
76
|
+
lambda d: click.echo(
|
|
77
|
+
f"A newer version is available: {latest} "
|
|
78
|
+
f"(current {__version__}). Run `hap update` to upgrade."
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
click.echo(f"Upgrading hap-cli {__version__} -> {latest} ...")
|
|
84
|
+
ok, output = upd.perform_upgrade(kind)
|
|
85
|
+
upd.save_state(
|
|
86
|
+
{
|
|
87
|
+
"last_check_at": time.time(),
|
|
88
|
+
"latest_version": latest,
|
|
89
|
+
"last_result": "upgraded" if ok else "upgrade_failed",
|
|
90
|
+
"upgraded_to": latest if ok else None,
|
|
91
|
+
"notified": True,
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
if ok:
|
|
95
|
+
ctx.output(
|
|
96
|
+
{"current": __version__, "latest": latest, "updated": True},
|
|
97
|
+
lambda d: click.echo(f"Upgraded to hap-cli {latest}."),
|
|
98
|
+
)
|
|
99
|
+
else:
|
|
100
|
+
click.echo(output, err=True)
|
|
101
|
+
ctx.handle_error(Exception(f"Upgrade to {latest} failed."))
|
|
@@ -311,15 +311,22 @@ def workflow_trigger(ctx, process_id, source_id):
|
|
|
311
311
|
@click.option("--app-id", "-a", required=True, help="Application ID")
|
|
312
312
|
@click.option("--trigger-id", default="", help="Trigger ID")
|
|
313
313
|
@click.option("--title", default="", help="Instance title")
|
|
314
|
+
@click.option("--controls", default="",
|
|
315
|
+
help='Input parameter values JSON: [{controlId, value}]')
|
|
314
316
|
@pass_context
|
|
315
|
-
def workflow_trigger_pbp(ctx, process_id, app_id, trigger_id, title
|
|
317
|
+
def workflow_trigger_pbp(ctx, process_id, app_id, trigger_id, title,
|
|
318
|
+
controls):
|
|
316
319
|
"""Trigger a PBP (Packaged Business Process) workflow."""
|
|
317
320
|
try:
|
|
318
321
|
session = ctx.get_session()
|
|
322
|
+
controls_list = json.loads(controls) if controls else None
|
|
319
323
|
data = wf_mod.start_process_by_pbp(
|
|
320
324
|
session, process_id, app_id, trigger_id, title,
|
|
325
|
+
controls=controls_list,
|
|
321
326
|
)
|
|
322
327
|
ctx.output(data, lambda d: click.echo(f"PBP triggered: {d}"))
|
|
328
|
+
except json.JSONDecodeError as e:
|
|
329
|
+
ctx.handle_error(click.UsageError(f"Invalid JSON: {e}"))
|
|
323
330
|
except Exception as e:
|
|
324
331
|
ctx.handle_error(e)
|
|
325
332
|
|