hap-cli 0.8.5__tar.gz → 0.8.7__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.5 → hap_cli-0.8.7}/PKG-INFO +19 -9
- {hap_cli-0.8.5/hap_cli → hap_cli-0.8.7}/README.md +18 -8
- {hap_cli-0.8.5 → hap_cli-0.8.7/hap_cli}/README.md +18 -8
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/README_CN.md +10 -6
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/__init__.py +1 -1
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/auth_cmd.py +55 -36
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/icon_cmd.py +50 -5
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/instance_cmd.py +3 -1
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/node_cmd.py +30 -9
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/record_cmd.py +6 -1
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/workflow_cmd.py +9 -2
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/worksheet_cmd.py +19 -2
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/action_spec_adapter.py +17 -6
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/auth.py +129 -198
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/chat.py +28 -2
- hap_cli-0.8.7/hap_cli/core/cli_access.py +344 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/apply.py +12 -1
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/flow_node.py +103 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/icon_index.py +19 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/record.py +130 -33
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/session.py +42 -22
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/update.py +3 -9
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/upload.py +9 -5
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/view_spec_adapter.py +61 -4
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/workflow.py +43 -15
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/workflow_node_dsl.py +124 -8
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/worksheet.py +174 -14
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/locale/messages.json +6 -3
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/conftest.py +22 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_app_editor.py +20 -0
- hap_cli-0.8.7/hap_cli/tests/test_auth_prerelease.py +154 -0
- hap_cli-0.8.7/hap_cli/tests/test_cli_access.py +663 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_core.py +851 -10
- hap_cli-0.8.7/hap_cli/tests/test_instance_history_cli.py +34 -0
- hap_cli-0.8.7/hap_cli/tests/test_record_field_alias.py +146 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_update.py +4 -3
- hap_cli-0.8.7/hap_cli/tests/test_workflow_list_cli.py +73 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_worksheet_v3_semantic_cli.py +10 -4
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli.egg-info/PKG-INFO +19 -9
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli.egg-info/SOURCES.txt +5 -0
- hap_cli-0.8.5/hap_cli/tests/test_auth_prerelease.py +0 -410
- {hap_cli-0.8.5 → hap_cli-0.8.7}/MANIFEST.in +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/app_live_tests/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/app_live_tests/__main__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/app_live_tests/config.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/app_live_tests/harness.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/app_live_tests/smoke.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/app_live_tests/state.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/__main__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/app_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/app_editor_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/calendar_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/chart_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/chat_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/chatbot_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/config_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/contact_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/department_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/group_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/optionset_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/page_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/post_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/region_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/role_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/update_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/upload_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/commands/v3_registry.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/context.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/app.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/calendar_mod.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/chart.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/chatbot.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/contact.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/control_type_codes.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/department.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/componentlower.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/editspec.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/errors.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/fieldlower.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/jsonschema_mini.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/models.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/ops.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/planner.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/editor/reader.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/field_normalizer.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/field_spec_adapter.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/filter_translator.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/global_meta.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/group.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/instance.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/logger.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/optionset.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/page.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/post.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/response_crypto.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/role.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/role_perm_builder.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/token_crypto.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/v3/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/v3/dispatcher.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/v3/render.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/v3/schema.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/core/worksheet_templates.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/hap_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/i18n.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/locale/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/locale/messages.schema.json +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_app_export_usage.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_bug_036430.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_chart.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_config_cmd.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_destructive_confirm_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_full_e2e.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_global_meta.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_i18n.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_approval.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_approval_actions.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_calendar.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_destructive.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_misc.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_post.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_social.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_v3.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_workflow.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_multi_profile.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_org_approval_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_org_id_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_org_id_docs.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_parameter_conventions.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_record_batch_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_record_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_semantic_types_registry.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_v3_api_schema_loader.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_v3_dispatcher.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_v3_registry_coverage.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_v3_session.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_v3_yaml_translation.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_workflow_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/tests/test_worksheet_crud_cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/utils/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/utils/formatting.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/utils/options.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli/utils/parameter_mapping.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli.egg-info/dependency_links.txt +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli.egg-info/entry_points.txt +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli.egg-info/requires.txt +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/hap_cli.egg-info/top_level.txt +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/__main__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/_wftest.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/charts.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/cleanup.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/compiler.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/config.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/errors.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/executor.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/fields.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/hap.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/recording/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/recording/console.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/recording/jsonl.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/recording/mirror.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/recording/report.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/schema.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/seed/__init__.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/seed/cli.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/seed/executor.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/seed/template.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/selftest.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/smoke.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/step.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/steps.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/store.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/live_tests/workflow_dsl.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/setup.cfg +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/setup.py +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/skills/hap-cli-app-editor/scripts/editspec/component.schema.json +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/skills/hap-cli-app-editor/scripts/editspec/custom-action.schema.json +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/skills/hap-cli-app-editor/scripts/editspec/envelope.schema.json +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/skills/hap-cli-app-editor/scripts/editspec/field.schema.json +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/INDEX.json +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/create_optionset.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/create_role.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/delete_optionset.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/delete_record.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/delete_role.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_app_info.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_details.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_list.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_logs.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_relations.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_regions.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_role_details.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/get_role_list.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/knowledge_search.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
- {hap_cli-0.8.5 → hap_cli-0.8.7}/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.7
|
|
4
4
|
Summary: CLI harness for MingDAO HAP - Enterprise no-code platform
|
|
5
5
|
Author: hap-cli
|
|
6
6
|
License: Apache-2.0
|
|
@@ -40,6 +40,15 @@ pip install hap-cli
|
|
|
40
40
|
The package ships with the v3 tool schemas it needs, so no extra setup is
|
|
41
41
|
required after `pip install`.
|
|
42
42
|
|
|
43
|
+
## Prerequisite: enable CLI access for your organization
|
|
44
|
+
|
|
45
|
+
**`hap` can only access an organization's data after the organization has
|
|
46
|
+
enabled CLI access.** Ask an organization administrator to turn on the
|
|
47
|
+
switch under Organization Admin → Security → Data & Access → CLI access
|
|
48
|
+
policy. Commands are blocked until it is enabled; once an administrator
|
|
49
|
+
turns it on, just re-run the command. Use `hap auth list-my-orgs` to see
|
|
50
|
+
each organization's status (`CLI:on/off`).
|
|
51
|
+
|
|
43
52
|
## Quick start
|
|
44
53
|
|
|
45
54
|
### 1. Login
|
|
@@ -102,8 +111,9 @@ hap app select APP_ID
|
|
|
102
111
|
hap app unselect # clear it
|
|
103
112
|
```
|
|
104
113
|
|
|
105
|
-
`hap auth set-current-org`
|
|
106
|
-
|
|
114
|
+
`hap auth set-current-org` switches the default organization; moving to a
|
|
115
|
+
different organization also clears the default app (apps belong to an
|
|
116
|
+
organization). Pick a new one with `hap app select`.
|
|
107
117
|
|
|
108
118
|
### 3. Explore worksheets and records
|
|
109
119
|
|
|
@@ -140,8 +150,8 @@ discover every subcommand.
|
|
|
140
150
|
| `auth use NAME` | Switch the environment/account used next |
|
|
141
151
|
| `auth logout` | Log out the current account (`-p NAME` for a specific one, `-a/--all` for every one) |
|
|
142
152
|
| `auth whoami` | Show current user, current environment/account, and current organization |
|
|
143
|
-
| `auth list-my-orgs` | List every org for the current account (current marked
|
|
144
|
-
| `auth set-current-org ORG_ID` | Switch the saved current organization |
|
|
153
|
+
| `auth list-my-orgs` | List every org for the current account (current marked `*`; each row shows whether the org allows CLI access, `CLI:on/off`, checked live; omitted where the environment has no such switch) |
|
|
154
|
+
| `auth set-current-org ORG_ID` | Switch the saved current organization (clears the default app when the org changes) |
|
|
145
155
|
|
|
146
156
|
### app — application management
|
|
147
157
|
|
|
@@ -285,8 +295,8 @@ discover every subcommand.
|
|
|
285
295
|
|
|
286
296
|
| Command | Description |
|
|
287
297
|
|---|---|
|
|
288
|
-
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); no keyword lists all |
|
|
289
|
-
| `icon list` | List
|
|
298
|
+
| `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 |
|
|
299
|
+
| `icon list [-n SIZE] [-p PAGE]` | List icons page by page with keywords (50 per page by default) |
|
|
290
300
|
|
|
291
301
|
### upload — file upload
|
|
292
302
|
|
|
@@ -330,8 +340,8 @@ Every command that needs an `--app-id` resolves it in this order:
|
|
|
330
340
|
2. The default app saved by `hap app select`;
|
|
331
341
|
3. Otherwise the command exits with an error suggesting `hap app select APP_ID`.
|
|
332
342
|
|
|
333
|
-
`hap auth set-current-org`
|
|
334
|
-
|
|
343
|
+
`hap auth set-current-org` switches the default *organization*; switching to a
|
|
344
|
+
different organization also clears the default app.
|
|
335
345
|
|
|
336
346
|
## REPL mode
|
|
337
347
|
|
|
@@ -11,6 +11,15 @@ pip install hap-cli
|
|
|
11
11
|
The package ships with the v3 tool schemas it needs, so no extra setup is
|
|
12
12
|
required after `pip install`.
|
|
13
13
|
|
|
14
|
+
## Prerequisite: enable CLI access for your organization
|
|
15
|
+
|
|
16
|
+
**`hap` can only access an organization's data after the organization has
|
|
17
|
+
enabled CLI access.** Ask an organization administrator to turn on the
|
|
18
|
+
switch under Organization Admin → Security → Data & Access → CLI access
|
|
19
|
+
policy. Commands are blocked until it is enabled; once an administrator
|
|
20
|
+
turns it on, just re-run the command. Use `hap auth list-my-orgs` to see
|
|
21
|
+
each organization's status (`CLI:on/off`).
|
|
22
|
+
|
|
14
23
|
## Quick start
|
|
15
24
|
|
|
16
25
|
### 1. Login
|
|
@@ -73,8 +82,9 @@ hap app select APP_ID
|
|
|
73
82
|
hap app unselect # clear it
|
|
74
83
|
```
|
|
75
84
|
|
|
76
|
-
`hap auth set-current-org`
|
|
77
|
-
|
|
85
|
+
`hap auth set-current-org` switches the default organization; moving to a
|
|
86
|
+
different organization also clears the default app (apps belong to an
|
|
87
|
+
organization). Pick a new one with `hap app select`.
|
|
78
88
|
|
|
79
89
|
### 3. Explore worksheets and records
|
|
80
90
|
|
|
@@ -111,8 +121,8 @@ discover every subcommand.
|
|
|
111
121
|
| `auth use NAME` | Switch the environment/account used next |
|
|
112
122
|
| `auth logout` | Log out the current account (`-p NAME` for a specific one, `-a/--all` for every one) |
|
|
113
123
|
| `auth whoami` | Show current user, current environment/account, and current organization |
|
|
114
|
-
| `auth list-my-orgs` | List every org for the current account (current marked
|
|
115
|
-
| `auth set-current-org ORG_ID` | Switch the saved current organization |
|
|
124
|
+
| `auth list-my-orgs` | List every org for the current account (current marked `*`; each row shows whether the org allows CLI access, `CLI:on/off`, checked live; omitted where the environment has no such switch) |
|
|
125
|
+
| `auth set-current-org ORG_ID` | Switch the saved current organization (clears the default app when the org changes) |
|
|
116
126
|
|
|
117
127
|
### app — application management
|
|
118
128
|
|
|
@@ -256,8 +266,8 @@ discover every subcommand.
|
|
|
256
266
|
|
|
257
267
|
| Command | Description |
|
|
258
268
|
|---|---|
|
|
259
|
-
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); no keyword lists all |
|
|
260
|
-
| `icon list` | List
|
|
269
|
+
| `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 |
|
|
270
|
+
| `icon list [-n SIZE] [-p PAGE]` | List icons page by page with keywords (50 per page by default) |
|
|
261
271
|
|
|
262
272
|
### upload — file upload
|
|
263
273
|
|
|
@@ -301,8 +311,8 @@ Every command that needs an `--app-id` resolves it in this order:
|
|
|
301
311
|
2. The default app saved by `hap app select`;
|
|
302
312
|
3. Otherwise the command exits with an error suggesting `hap app select APP_ID`.
|
|
303
313
|
|
|
304
|
-
`hap auth set-current-org`
|
|
305
|
-
|
|
314
|
+
`hap auth set-current-org` switches the default *organization*; switching to a
|
|
315
|
+
different organization also clears the default app.
|
|
306
316
|
|
|
307
317
|
## REPL mode
|
|
308
318
|
|
|
@@ -11,6 +11,15 @@ pip install hap-cli
|
|
|
11
11
|
The package ships with the v3 tool schemas it needs, so no extra setup is
|
|
12
12
|
required after `pip install`.
|
|
13
13
|
|
|
14
|
+
## Prerequisite: enable CLI access for your organization
|
|
15
|
+
|
|
16
|
+
**`hap` can only access an organization's data after the organization has
|
|
17
|
+
enabled CLI access.** Ask an organization administrator to turn on the
|
|
18
|
+
switch under Organization Admin → Security → Data & Access → CLI access
|
|
19
|
+
policy. Commands are blocked until it is enabled; once an administrator
|
|
20
|
+
turns it on, just re-run the command. Use `hap auth list-my-orgs` to see
|
|
21
|
+
each organization's status (`CLI:on/off`).
|
|
22
|
+
|
|
14
23
|
## Quick start
|
|
15
24
|
|
|
16
25
|
### 1. Login
|
|
@@ -73,8 +82,9 @@ hap app select APP_ID
|
|
|
73
82
|
hap app unselect # clear it
|
|
74
83
|
```
|
|
75
84
|
|
|
76
|
-
`hap auth set-current-org`
|
|
77
|
-
|
|
85
|
+
`hap auth set-current-org` switches the default organization; moving to a
|
|
86
|
+
different organization also clears the default app (apps belong to an
|
|
87
|
+
organization). Pick a new one with `hap app select`.
|
|
78
88
|
|
|
79
89
|
### 3. Explore worksheets and records
|
|
80
90
|
|
|
@@ -111,8 +121,8 @@ discover every subcommand.
|
|
|
111
121
|
| `auth use NAME` | Switch the environment/account used next |
|
|
112
122
|
| `auth logout` | Log out the current account (`-p NAME` for a specific one, `-a/--all` for every one) |
|
|
113
123
|
| `auth whoami` | Show current user, current environment/account, and current organization |
|
|
114
|
-
| `auth list-my-orgs` | List every org for the current account (current marked
|
|
115
|
-
| `auth set-current-org ORG_ID` | Switch the saved current organization |
|
|
124
|
+
| `auth list-my-orgs` | List every org for the current account (current marked `*`; each row shows whether the org allows CLI access, `CLI:on/off`, checked live; omitted where the environment has no such switch) |
|
|
125
|
+
| `auth set-current-org ORG_ID` | Switch the saved current organization (clears the default app when the org changes) |
|
|
116
126
|
|
|
117
127
|
### app — application management
|
|
118
128
|
|
|
@@ -256,8 +266,8 @@ discover every subcommand.
|
|
|
256
266
|
|
|
257
267
|
| Command | Description |
|
|
258
268
|
|---|---|
|
|
259
|
-
| `icon search` | Search icons by Chinese/English keyword (OR across terms, more matches rank higher); no keyword lists all |
|
|
260
|
-
| `icon list` | List
|
|
269
|
+
| `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 |
|
|
270
|
+
| `icon list [-n SIZE] [-p PAGE]` | List icons page by page with keywords (50 per page by default) |
|
|
261
271
|
|
|
262
272
|
### upload — file upload
|
|
263
273
|
|
|
@@ -301,8 +311,8 @@ Every command that needs an `--app-id` resolves it in this order:
|
|
|
301
311
|
2. The default app saved by `hap app select`;
|
|
302
312
|
3. Otherwise the command exits with an error suggesting `hap app select APP_ID`.
|
|
303
313
|
|
|
304
|
-
`hap auth set-current-org`
|
|
305
|
-
|
|
314
|
+
`hap auth set-current-org` switches the default *organization*; switching to a
|
|
315
|
+
different organization also clears the default app.
|
|
306
316
|
|
|
307
317
|
## REPL mode
|
|
308
318
|
|
|
@@ -10,6 +10,10 @@ pip install hap-cli
|
|
|
10
10
|
|
|
11
11
|
安装包内已附带 CLI 启动需要的 v3 工具 schema,`pip install` 之后无需额外配置。
|
|
12
12
|
|
|
13
|
+
## 使用前提:开启组织的 CLI 访问权限
|
|
14
|
+
|
|
15
|
+
**只有组织开启了 CLI 访问权限,`hap` 才能访问该组织的数据。** 请组织管理员前往「组织管理后台 → 安全 → 数据与访问 → CLI 访问策略」开启允许访问开关。未开启时命令会被拦截;管理员开启后直接重跑命令即可。可用 `hap auth list-my-orgs` 查看各组织的开启状态(`CLI:on/off`)。
|
|
16
|
+
|
|
13
17
|
## 快速上手
|
|
14
18
|
|
|
15
19
|
### 1. 登录
|
|
@@ -67,7 +71,7 @@ hap app select APP_ID
|
|
|
67
71
|
hap app unselect # 清除默认应用
|
|
68
72
|
```
|
|
69
73
|
|
|
70
|
-
`hap auth set-current-org`
|
|
74
|
+
`hap auth set-current-org` 切换默认组织;切换到不同组织时会同时清除默认应用(应用从属于组织)。之后用 `hap app select` 重新选择默认应用。
|
|
71
75
|
|
|
72
76
|
### 3. 浏览工作表与记录
|
|
73
77
|
|
|
@@ -102,8 +106,8 @@ hap --json worksheet record list WORKSHEET_ID
|
|
|
102
106
|
| `auth use NAME` | 切换当前使用的环境/账号 |
|
|
103
107
|
| `auth logout` | 登出当前账号(`-p NAME` 指定,`-a/--all` 全部) |
|
|
104
108
|
| `auth whoami` | 当前用户、当前环境/账号与当前组织 |
|
|
105
|
-
| `auth list-my-orgs` | 当前账号所属组织(当前组织标
|
|
106
|
-
| `auth set-current-org ORG_ID` |
|
|
109
|
+
| `auth list-my-orgs` | 当前账号所属组织(当前组织标 `*`,并实时显示各组织是否开启 CLI 访问权限 `CLI:on/off`,环境不支持该开关时不显示) |
|
|
110
|
+
| `auth set-current-org ORG_ID` | 切换默认组织(切到不同组织时会清除默认应用) |
|
|
107
111
|
|
|
108
112
|
### app — 应用管理
|
|
109
113
|
|
|
@@ -236,8 +240,8 @@ hap --json worksheet record list WORKSHEET_ID
|
|
|
236
240
|
|
|
237
241
|
| 命令 | 说明 |
|
|
238
242
|
|---|---|
|
|
239
|
-
| `icon search` |
|
|
240
|
-
| `icon list` |
|
|
243
|
+
| `icon search` | 按中英文关键词搜索图标(多关键词取并集,命中越多排越前);命中不足 10 个时随机补足推荐;无关键词列出全部 |
|
|
244
|
+
| `icon list [-n SIZE] [-p PAGE]` | 分页列出图标及其关键词(默认每页 50 个) |
|
|
241
245
|
|
|
242
246
|
### upload — 文件上传
|
|
243
247
|
|
|
@@ -277,7 +281,7 @@ hap --json worksheet record list WORKSHEET_ID
|
|
|
277
281
|
2. 否则使用 `hap app select APP_ID` 保存的默认应用;
|
|
278
282
|
3. 仍为空时报错并提示设置默认应用。
|
|
279
283
|
|
|
280
|
-
`hap auth set-current-org`
|
|
284
|
+
`hap auth set-current-org` 切换默认**组织**;切到不同组织时会同时清除默认应用。
|
|
281
285
|
|
|
282
286
|
## REPL 模式
|
|
283
287
|
|
|
@@ -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
|
|
|
@@ -102,6 +102,21 @@ def _save_and_report(ctx, token, webui, user_info, meta, profile_name):
|
|
|
102
102
|
session.save(profile=profile_name)
|
|
103
103
|
set_active_profile(profile_name)
|
|
104
104
|
|
|
105
|
+
# Probe the org CLI-access switch for the org we just saved as
|
|
106
|
+
# current, so the user learns right away that commands will be
|
|
107
|
+
# blocked. Only an explicit "off" verdict prints the warning
|
|
108
|
+
# (404 / network trouble stays silent — same fail-open policy as
|
|
109
|
+
# the request gate). Covers all login paths (browser, paste,
|
|
110
|
+
# --token), unlike the browser success page.
|
|
111
|
+
from hap_cli.core import cli_access
|
|
112
|
+
|
|
113
|
+
access_denied = False
|
|
114
|
+
if cli_access.GATE_ENABLED and current_org.get("projectId"):
|
|
115
|
+
access_denied = (
|
|
116
|
+
cli_access.probe_cli_access(webui, token, current_org["projectId"])
|
|
117
|
+
is False
|
|
118
|
+
)
|
|
119
|
+
|
|
105
120
|
data = {
|
|
106
121
|
"status": "ok",
|
|
107
122
|
"profile": profile_name,
|
|
@@ -109,17 +124,24 @@ def _save_and_report(ctx, token, webui, user_info, meta, profile_name):
|
|
|
109
124
|
"user": user_info,
|
|
110
125
|
"current_org": current_org,
|
|
111
126
|
}
|
|
112
|
-
|
|
113
|
-
data
|
|
114
|
-
|
|
127
|
+
if access_denied:
|
|
128
|
+
data["cli_access_denied"] = True
|
|
129
|
+
|
|
130
|
+
def _human(_d):
|
|
131
|
+
click.echo(
|
|
115
132
|
f"Logged in as: {user_info.get('name', '')} "
|
|
116
133
|
f"({user_info.get('email', '')})\n"
|
|
117
134
|
f"Saved as: {profile_name}\n"
|
|
118
135
|
f"Server: {webui}\n"
|
|
119
136
|
f"Current org: {current_org.get('projectId', '')} "
|
|
120
137
|
f"{current_org.get('companyName', '')}".rstrip()
|
|
121
|
-
)
|
|
122
|
-
|
|
138
|
+
)
|
|
139
|
+
if access_denied:
|
|
140
|
+
# Deliberately NOT localized: the surrounding login summary
|
|
141
|
+
# is English-only, so this line stays English too.
|
|
142
|
+
click.echo(f"Error: {cli_access.DENIED_MESSAGE_EN}")
|
|
143
|
+
|
|
144
|
+
ctx.output(data, _human)
|
|
123
145
|
|
|
124
146
|
|
|
125
147
|
@auth.command("login")
|
|
@@ -156,32 +178,6 @@ def auth_login(ctx, server, timeout, token_opt, profile_opt, force):
|
|
|
156
178
|
Use --token to supply a token non-interactively for scripts.
|
|
157
179
|
"""
|
|
158
180
|
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
181
|
if token_opt:
|
|
186
182
|
token, webui, user_info, meta = auth_mod.verify_token(server, token_opt)
|
|
187
183
|
else:
|
|
@@ -316,17 +312,33 @@ def _print_orgs(session, data):
|
|
|
316
312
|
pid = p.get("projectId", "")
|
|
317
313
|
name = p.get("companyName", p.get("name", ""))
|
|
318
314
|
role = p.get("roleName", "")
|
|
319
|
-
|
|
320
|
-
|
|
315
|
+
# Only render the CLI column when the server gave an explicit
|
|
316
|
+
# verdict; environments without the org switch show no column.
|
|
317
|
+
enabled = p.get("cliAccessEnabled")
|
|
318
|
+
cli_col = ""
|
|
319
|
+
if isinstance(enabled, bool):
|
|
320
|
+
cli_col = "CLI:on" if enabled else "CLI:off"
|
|
321
|
+
click.echo(
|
|
322
|
+
f"{'*' if pid and pid == current_org_id else ' '} "
|
|
323
|
+
f"{pid} {name} {role} {cli_col}".rstrip()
|
|
324
|
+
)
|
|
321
325
|
|
|
322
326
|
|
|
323
327
|
@auth.command("list-my-orgs")
|
|
324
328
|
@pass_context
|
|
325
329
|
def auth_list_my_orgs(ctx):
|
|
326
|
-
"""List all organizations the current user belongs to.
|
|
330
|
+
"""List all organizations the current user belongs to.
|
|
331
|
+
|
|
332
|
+
Each row also shows whether the organization currently allows
|
|
333
|
+
CLI access (checked live against the server).
|
|
334
|
+
"""
|
|
327
335
|
try:
|
|
336
|
+
from hap_cli.core import cli_access
|
|
337
|
+
|
|
328
338
|
session = ctx.get_session()
|
|
329
339
|
data = auth_mod.list_my_orgs(session)
|
|
340
|
+
if cli_access.GATE_ENABLED:
|
|
341
|
+
cli_access.annotate_orgs_cli_access(session, data)
|
|
330
342
|
ctx.output(data, lambda d: _print_orgs(session, d))
|
|
331
343
|
except Exception as e:
|
|
332
344
|
ctx.handle_error(e)
|
|
@@ -336,7 +348,14 @@ def auth_list_my_orgs(ctx):
|
|
|
336
348
|
@click.argument("org_id")
|
|
337
349
|
@pass_context
|
|
338
350
|
def auth_set_current_org(ctx, org_id):
|
|
339
|
-
"""Set the saved current organization.
|
|
351
|
+
"""Set the saved current organization.
|
|
352
|
+
|
|
353
|
+
Run 'hap auth list-my-orgs' first to see the organizations you
|
|
354
|
+
belong to and their IDs.
|
|
355
|
+
|
|
356
|
+
Switching to a different organization also clears the saved
|
|
357
|
+
default app — pick a new one with 'hap app select' afterwards.
|
|
358
|
+
"""
|
|
340
359
|
try:
|
|
341
360
|
session = ctx.get_session()
|
|
342
361
|
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."))
|
|
@@ -155,6 +155,10 @@ def record_update(ctx, worksheet_id, row_id, field, fields_json, no_workflow):
|
|
|
155
155
|
|
|
156
156
|
Pass values either as repeated -f CONTROL_ID=VALUE pairs or as one
|
|
157
157
|
--fields-json array.
|
|
158
|
+
|
|
159
|
+
A sub-table value is the full list of child rows (each a dict keyed
|
|
160
|
+
by child field name) and replaces the existing rows; an empty list
|
|
161
|
+
clears the sub-table.
|
|
158
162
|
"""
|
|
159
163
|
if field and fields_json:
|
|
160
164
|
raise click.UsageError("Pass exactly one of -f or --fields-json.")
|
|
@@ -164,7 +168,8 @@ def record_update(ctx, worksheet_id, row_id, field, fields_json, no_workflow):
|
|
|
164
168
|
raw = _fields_json_to_raw(fields_json)
|
|
165
169
|
else:
|
|
166
170
|
raw = _parse_fields(field)
|
|
167
|
-
controls = rec_mod.encode_controls_by_id(
|
|
171
|
+
controls = rec_mod.encode_controls_by_id(
|
|
172
|
+
session, worksheet_id, raw, for_update=True)
|
|
168
173
|
data = rec_mod.update_record(
|
|
169
174
|
session, worksheet_id, row_id, controls,
|
|
170
175
|
trigger_workflow=not no_workflow,
|
|
@@ -63,7 +63,7 @@ def workflow_list(ctx, app_id, keyword, enabled, page_size, page):
|
|
|
63
63
|
if not aid:
|
|
64
64
|
raise click.UsageError("App ID required.")
|
|
65
65
|
result = wf_mod.get_process_list(
|
|
66
|
-
session, aid, keyword=keyword,
|
|
66
|
+
session, aid, keyword=keyword, enabled=enabled,
|
|
67
67
|
page_index=page, page_size=page_size,
|
|
68
68
|
)
|
|
69
69
|
ctx.output(
|
|
@@ -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
|
|