hap-cli 0.8.22__tar.gz → 0.8.23__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.22 → hap_cli-0.8.23}/MANIFEST.in +2 -5
- {hap_cli-0.8.22 → hap_cli-0.8.23}/PKG-INFO +7 -1
- {hap_cli-0.8.22/hap_cli → hap_cli-0.8.23}/README.md +6 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23/hap_cli}/README.md +6 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/README_CN.md +6 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/__init__.py +1 -1
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/auth_cmd.py +5 -1
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/chat_cmd.py +5 -1
- hap_cli-0.8.23/hap_cli/commands/guide_cmd.py +36 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/record_cmd.py +8 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/worksheet_cmd.py +6 -1
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/editspec.py +15 -20
- hap_cli-0.8.23/hap_cli/core/guide.py +176 -0
- hap_cli-0.8.23/hap_cli/guide/en/messages.md +54 -0
- hap_cli-0.8.23/hap_cli/guide/en/overview.md +45 -0
- hap_cli-0.8.23/hap_cli/guide/en/record.md +289 -0
- hap_cli-0.8.23/hap_cli/guide/en/setup.md +99 -0
- hap_cli-0.8.23/hap_cli/guide/en/skills.md +48 -0
- hap_cli-0.8.23/hap_cli/guide/index.json +36 -0
- hap_cli-0.8.23/hap_cli/guide/zh-Hans/messages.md +52 -0
- hap_cli-0.8.23/hap_cli/guide/zh-Hans/overview.md +39 -0
- hap_cli-0.8.23/hap_cli/guide/zh-Hans/record.md +276 -0
- hap_cli-0.8.23/hap_cli/guide/zh-Hans/setup.md +91 -0
- hap_cli-0.8.23/hap_cli/guide/zh-Hans/skills.md +45 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/hap_cli.py +8 -1
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_app_editor.py +35 -0
- hap_cli-0.8.23/hap_cli/tests/test_guide.py +162 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli.egg-info/PKG-INFO +7 -1
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli.egg-info/SOURCES.txt +18 -4
- {hap_cli-0.8.22 → hap_cli-0.8.23}/setup.py +7 -15
- {hap_cli-0.8.22 → hap_cli-0.8.23}/app_live_tests/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/app_live_tests/__main__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/app_live_tests/config.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/app_live_tests/harness.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/app_live_tests/smoke.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/app_live_tests/state.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/__main__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/app_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/app_creator_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/app_editor_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/attachment_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/calendar_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/chart_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/chatbot_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/config_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/contact_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/department_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/group_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/icon_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/instance_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/node_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/optionset_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/page_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/post_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/region_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/role_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/update_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/upload_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/v3_registry.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/commands/workflow_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/context.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/action_spec_adapter.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/_hapmeta/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/_hapmeta/control_type_codes.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/_hapmeta/worksheet_templates.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/charts.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/cleanup.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/compiler.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/config.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/design/design.schema.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/errors.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/examples/minimal.design.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/executor.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/fields.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/hap.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/merge.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/recording/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/recording/console.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/recording/jsonl.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/recording/mirror.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/recording/report.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/schema.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/INSTRUCTIONS.md +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/executor.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/resources/attachments.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/resources/sample.docx +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/resources/sample.pdf +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/resources/sample_images.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/seed/template.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/selftest.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/smoke.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/steps.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/store.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/validate.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/app_creator/workflow_dsl.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/attachment.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/auth.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/calendar_mod.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/chart.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/chat.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/chatbot.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/cli_access.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/contact.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/control_type_codes.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/department.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/apply.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/componentlower.py +0 -0
- {hap_cli-0.8.22/skills/cli/hap-cli-app-editor/scripts → hap_cli-0.8.23/hap_cli/core/editor}/editspec/component.schema.json +0 -0
- {hap_cli-0.8.22/skills/cli/hap-cli-app-editor/scripts → hap_cli-0.8.23/hap_cli/core/editor}/editspec/custom-action.schema.json +0 -0
- {hap_cli-0.8.22/skills/cli/hap-cli-app-editor/scripts → hap_cli-0.8.23/hap_cli/core/editor}/editspec/envelope.schema.json +0 -0
- {hap_cli-0.8.22/skills/cli/hap-cli-app-editor/scripts → hap_cli-0.8.23/hap_cli/core/editor}/editspec/field.schema.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/errors.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/fieldlower.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/jsonschema_mini.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/models.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/ops.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/planner.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/editor/reader.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/field_normalizer.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/field_spec_adapter.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/filter_translator.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/flow_node.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/global_meta.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/group.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/icon_index.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/instance.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/logger.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/optionset.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/page.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/post.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/record.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/response_crypto.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/role.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/role_perm_builder.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/session.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/token_crypto.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/update.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/upload.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/v3/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/v3/dispatcher.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/v3/render.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/v3/schema.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/view_spec_adapter.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/workflow.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/workflow_node_dsl.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/worksheet.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/core/worksheet_templates.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/i18n.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/locale/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/locale/messages.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/locale/messages.schema.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/conftest.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_app_creator.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_app_export_usage.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_attachment_share.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_auth_prerelease.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_bug_036430.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_bug_036750.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_chart.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_chat_attachment_send.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_cli_access.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_config_cmd.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_content_language.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_control_lookup_guard.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_core.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_destructive_confirm_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_full_e2e.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_global_meta.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_i18n.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_instance_history_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_approval.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_approval_actions.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_calendar.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_destructive.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_misc.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_post.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_social.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_v3.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_workflow.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_member_relation_array_wrap.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_multi_profile.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_no_workflow_unsupported.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_org_approval_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_org_id_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_org_id_docs.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_parameter_conventions.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_record_batch_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_record_field_alias.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_record_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_select_rejects_relation_value.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_semantic_types_registry.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_update.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_update_mode.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_upload_host_resolution.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_v3_api_schema_loader.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_v3_dispatcher.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_v3_registry_coverage.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_v3_session.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_v3_yaml_translation.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_workflow_envelope_errors.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_workflow_list_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_workflow_read_write_keys.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_workflow_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_worksheet_create_section.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_worksheet_crud_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/tests/test_worksheet_v3_semantic_cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/utils/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/utils/formatting.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/utils/options.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli/utils/parameter_mapping.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli.egg-info/dependency_links.txt +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli.egg-info/entry_points.txt +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli.egg-info/requires.txt +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/hap_cli.egg-info/top_level.txt +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/__main__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/_wftest.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/charts.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/cleanup.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/compiler.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/config.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/errors.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/executor.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/fields.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/hap.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/recording/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/recording/console.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/recording/jsonl.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/recording/mirror.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/recording/report.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/schema.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/seed/__init__.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/seed/cli.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/seed/executor.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/seed/template.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/selftest.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/smoke.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/step.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/steps.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/store.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/live_tests/workflow_dsl.py +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/setup.cfg +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/INDEX.json +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/create_optionset.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/create_role.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/delete_optionset.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/delete_record.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/delete_role.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_app_info.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_details.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_list.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_logs.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_relations.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_regions.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_role_details.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/get_role_list.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/knowledge_search.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
- {hap_cli-0.8.22 → hap_cli-0.8.23}/sources/v3-api-schema/update_optionset.yaml +0 -0
|
@@ -11,8 +11,5 @@ include sources/v3-api-schema/INDEX.json
|
|
|
11
11
|
include hap_cli/README.md
|
|
12
12
|
include hap_cli/README_CN.md
|
|
13
13
|
recursive-include hap_cli/locale *.json
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# in the sdist so setup.py's build step can mirror them into
|
|
17
|
-
# hap_cli/core/editor/editspec/ for the ``hap app-editor`` runtime loader.
|
|
18
|
-
recursive-include skills/cli/hap-cli-app-editor/scripts/editspec *.json
|
|
14
|
+
include hap_cli/guide/index.json
|
|
15
|
+
recursive-include hap_cli/guide *.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hap-cli
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.23
|
|
4
4
|
Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
|
|
5
5
|
Author: hap-cli
|
|
6
6
|
License: Apache-2.0
|
|
@@ -306,6 +306,12 @@ discover every subcommand.
|
|
|
306
306
|
|
|
307
307
|
> ADDRESS is the file's link — one that has already stopped working is fine, paste it as-is — or just the path part of it. The file itself does not expire, only the link does, so a dead link can always be revived.
|
|
308
308
|
|
|
309
|
+
### guide — built-in usage guide
|
|
310
|
+
|
|
311
|
+
| Command | Description |
|
|
312
|
+
|---|---|
|
|
313
|
+
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong (`hap guide <topic>` for detail) |
|
|
314
|
+
|
|
309
315
|
### upload — file upload
|
|
310
316
|
|
|
311
317
|
| Command | Description |
|
|
@@ -277,6 +277,12 @@ discover every subcommand.
|
|
|
277
277
|
|
|
278
278
|
> ADDRESS is the file's link — one that has already stopped working is fine, paste it as-is — or just the path part of it. The file itself does not expire, only the link does, so a dead link can always be revived.
|
|
279
279
|
|
|
280
|
+
### guide — built-in usage guide
|
|
281
|
+
|
|
282
|
+
| Command | Description |
|
|
283
|
+
|---|---|
|
|
284
|
+
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong (`hap guide <topic>` for detail) |
|
|
285
|
+
|
|
280
286
|
### upload — file upload
|
|
281
287
|
|
|
282
288
|
| Command | Description |
|
|
@@ -277,6 +277,12 @@ discover every subcommand.
|
|
|
277
277
|
|
|
278
278
|
> ADDRESS is the file's link — one that has already stopped working is fine, paste it as-is — or just the path part of it. The file itself does not expire, only the link does, so a dead link can always be revived.
|
|
279
279
|
|
|
280
|
+
### guide — built-in usage guide
|
|
281
|
+
|
|
282
|
+
| Command | Description |
|
|
283
|
+
|---|---|
|
|
284
|
+
| `guide` | Built-in usage guide: what this version can do, and the value formats that are easy to get wrong (`hap guide <topic>` for detail) |
|
|
285
|
+
|
|
280
286
|
### upload — file upload
|
|
281
287
|
|
|
282
288
|
| Command | Description |
|
|
@@ -251,6 +251,12 @@ hap --json worksheet record list WORKSHEET_ID
|
|
|
251
251
|
|
|
252
252
|
> ADDRESS 传文件的链接即可——**已经失效的链接照样能传,原样粘贴**——也可以只传路径部分。文件本身不会过期,过期的只是链接,所以失效链接随时可以重新生成。
|
|
253
253
|
|
|
254
|
+
### guide — 内置使用指南
|
|
255
|
+
|
|
256
|
+
| 命令 | 说明 |
|
|
257
|
+
|---|---|
|
|
258
|
+
| `guide` | 内置使用指南:当前版本能做什么、哪些取值格式容易写错(`hap guide <主题>` 看细节) |
|
|
259
|
+
|
|
254
260
|
### upload — 文件上传
|
|
255
261
|
|
|
256
262
|
| 命令 | 说明 |
|
|
@@ -30,7 +30,11 @@ SERVER_HELP = (
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
@click.group(help=t(
|
|
33
|
+
@click.group(help=t(
|
|
34
|
+
'Manage authentication and session identity.\n\n'
|
|
35
|
+
'Signing in, keeping several environments and accounts, and choosing the '
|
|
36
|
+
'current organization are walked through in `hap guide setup`.'
|
|
37
|
+
))
|
|
34
38
|
def auth():
|
|
35
39
|
pass
|
|
36
40
|
|
|
@@ -73,7 +73,11 @@ def _output_chat_list_table(rows):
|
|
|
73
73
|
)
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
@click.group(help=t(
|
|
76
|
+
@click.group(help=t(
|
|
77
|
+
'Chat and messaging management.\n\n'
|
|
78
|
+
'To follow a notification back to the app record it belongs to, see '
|
|
79
|
+
'`hap guide messages`.'
|
|
80
|
+
))
|
|
77
81
|
def chat():
|
|
78
82
|
pass
|
|
79
83
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""CLI command for the built-in usage guide."""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
from hap_cli.context import pass_context
|
|
6
|
+
from hap_cli.core import guide as guide_mod
|
|
7
|
+
from hap_cli.i18n import t
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@click.command("guide")
|
|
11
|
+
@click.argument("topic", required=False)
|
|
12
|
+
@pass_context
|
|
13
|
+
def guide(ctx, topic):
|
|
14
|
+
"""How to use this tool: what it can do, and how to get the values right.
|
|
15
|
+
|
|
16
|
+
\b
|
|
17
|
+
hap guide what hap can do, and which topics go deeper
|
|
18
|
+
hap guide record writing records: what value each field type wants
|
|
19
|
+
|
|
20
|
+
Run this before composing commands — it describes the version of hap
|
|
21
|
+
installed on this machine, so it never disagrees with what you get.
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
from hap_cli.hap_cli import cli as root
|
|
25
|
+
|
|
26
|
+
if topic:
|
|
27
|
+
body = guide_mod.render_topic(topic)
|
|
28
|
+
ctx.output({"topic": topic, "text": body},
|
|
29
|
+
lambda d: click.echo(d["text"]))
|
|
30
|
+
return
|
|
31
|
+
payload = guide_mod.overview_payload(root)
|
|
32
|
+
ctx.output(payload, lambda d: click.echo(d["text"]))
|
|
33
|
+
except guide_mod.UnknownTopic as e:
|
|
34
|
+
ctx.handle_error(e)
|
|
35
|
+
except Exception as e:
|
|
36
|
+
ctx.handle_error(e)
|
|
@@ -90,6 +90,10 @@ def record_create(ctx, worksheet_id, field, fields_json, no_workflow):
|
|
|
90
90
|
|
|
91
91
|
Pass values either as repeated -f CONTROL_ID=VALUE pairs or as one
|
|
92
92
|
--fields-json array.
|
|
93
|
+
|
|
94
|
+
What to put in a value depends on the field type, and a wrong shape is
|
|
95
|
+
usually accepted and stored broken rather than rejected — see
|
|
96
|
+
`hap guide record` before writing, and read the record back after.
|
|
93
97
|
"""
|
|
94
98
|
if field and fields_json:
|
|
95
99
|
raise click.UsageError("Pass exactly one of -f or --fields-json.")
|
|
@@ -162,6 +166,10 @@ def record_update(ctx, worksheet_id, row_id, field, fields_json, no_workflow):
|
|
|
162
166
|
fields change), a child row without a "rowid" adds a new row, and a
|
|
163
167
|
child row with "_delete": true removes that row. Rows you don't list
|
|
164
168
|
are left untouched. An empty list (or null) clears the sub-table.
|
|
169
|
+
|
|
170
|
+
Every other field type replaces rather than merges: passing a new value
|
|
171
|
+
for a multi-select, attachment or relation field drops whatever was
|
|
172
|
+
there. Value formats per field type are in `hap guide record`.
|
|
165
173
|
"""
|
|
166
174
|
if field and fields_json:
|
|
167
175
|
raise click.UsageError("Pass exactly one of -f or --fields-json.")
|
|
@@ -11,7 +11,12 @@ from hap_cli.utils.options import org_id_option, require_api_project_id
|
|
|
11
11
|
from hap_cli.i18n import t
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
@click.group(help=t(
|
|
14
|
+
@click.group(help=t(
|
|
15
|
+
'Worksheet operations.\n\n'
|
|
16
|
+
'Writing records: the value each field type expects (options, members, '
|
|
17
|
+
'relations, sub-tables, attachments) is covered by `hap guide record` — '
|
|
18
|
+
'a wrong shape is usually accepted and stored broken.'
|
|
19
|
+
))
|
|
15
20
|
def worksheet():
|
|
16
21
|
pass
|
|
17
22
|
|
|
@@ -6,11 +6,10 @@ only the one module schema named by the op.type prefix is loaded and used
|
|
|
6
6
|
for deep validation (dispatched to the matching verb branch for precise
|
|
7
7
|
errors).
|
|
8
8
|
|
|
9
|
-
Schemas are canonical in
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
the same trick used for the V3 schemas).
|
|
9
|
+
Schemas are canonical in this package (``hap_cli/core/editor/editspec/``)
|
|
10
|
+
and ship with it, so they resolve identically in a checkout and in an
|
|
11
|
+
installed wheel — see :func:`schema_dir` for why they no longer live in
|
|
12
|
+
the hap-cli-app-editor skill.
|
|
14
13
|
"""
|
|
15
14
|
from __future__ import annotations
|
|
16
15
|
|
|
@@ -74,30 +73,26 @@ RETIRED_OPS = {
|
|
|
74
73
|
"section.delete": "hap app delete-section",
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
_SKILL_REL = ("skills", "cli", "hap-cli-app-editor", "scripts", "editspec")
|
|
78
|
-
|
|
79
|
-
|
|
80
76
|
@lru_cache(maxsize=1)
|
|
81
77
|
def schema_dir() -> Path:
|
|
82
78
|
"""Locate the edit-spec schema directory.
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
The schemas live next to this module and are tracked with the package,
|
|
81
|
+
so this resolves identically in a checkout and in an installed wheel.
|
|
82
|
+
|
|
83
|
+
They used to be canonical in the hap-cli-app-editor skill, mirrored in
|
|
84
|
+
at build time by setup.py. That broke when the skills moved to their
|
|
85
|
+
own repository and were linked back in: the build step found nothing
|
|
86
|
+
on a machine without that checkout, skipped silently, and shipped a
|
|
87
|
+
wheel whose ``hap app-editor`` could not load a single schema. A build
|
|
88
|
+
input has to be inside the repository that builds it.
|
|
89
89
|
"""
|
|
90
90
|
bundled = Path(__file__).resolve().parent / "editspec"
|
|
91
91
|
if bundled.is_dir() and any(bundled.glob("*.schema.json")):
|
|
92
92
|
return bundled
|
|
93
|
-
here = Path(__file__).resolve()
|
|
94
|
-
for parent in here.parents:
|
|
95
|
-
cand = parent.joinpath(*_SKILL_REL)
|
|
96
|
-
if cand.is_dir():
|
|
97
|
-
return cand
|
|
98
93
|
raise EditSpecError([
|
|
99
|
-
"could not locate edit-spec schemas
|
|
100
|
-
"
|
|
94
|
+
"could not locate the edit-spec schemas that ship with this "
|
|
95
|
+
"package (hap_cli/core/editor/editspec/)"])
|
|
101
96
|
|
|
102
97
|
|
|
103
98
|
def _load_schema(filename: str) -> dict[str, Any]:
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Usage guidance that ships with — and updates with — the CLI.
|
|
2
|
+
|
|
3
|
+
The hap-cli skill used to carry the command map as a static file on the
|
|
4
|
+
user's machine, frozen at install time. Guidance lives here instead, for
|
|
5
|
+
one reason: this package auto-updates, so whatever it says matches the
|
|
6
|
+
`hap` the caller is actually running. The skill shrinks to a stub that
|
|
7
|
+
says "run `hap guide`".
|
|
8
|
+
|
|
9
|
+
Two halves:
|
|
10
|
+
|
|
11
|
+
- **Generated** — the command map is walked off the live Click tree
|
|
12
|
+
(``command_map``). It cannot name a command that does not exist, and
|
|
13
|
+
it cannot omit one that does. Nothing about it is written down.
|
|
14
|
+
- **Written** — prose that the tree cannot express (how to log in, what
|
|
15
|
+
value shape each field type wants, which specialised skill to hand off
|
|
16
|
+
to) lives in ``hap_cli/guide/<lang>/<topic>.md``, declared in
|
|
17
|
+
``index.json``.
|
|
18
|
+
|
|
19
|
+
The bare overview enumerates its own topics so the skill stub never has
|
|
20
|
+
to name them; naming them there is exactly the detail that goes stale.
|
|
21
|
+
"""
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import json
|
|
25
|
+
import textwrap
|
|
26
|
+
from functools import lru_cache
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import Any, Optional
|
|
29
|
+
|
|
30
|
+
import click
|
|
31
|
+
|
|
32
|
+
GUIDE_DIR = Path(__file__).resolve().parent.parent / "guide"
|
|
33
|
+
BASE_LANG = "en"
|
|
34
|
+
|
|
35
|
+
# Two spaces of hanging indent under each group name, wide enough for the
|
|
36
|
+
# longest top-level group without the help column drifting.
|
|
37
|
+
_NAME_COL = 14
|
|
38
|
+
|
|
39
|
+
# Wrap the subcommand row so a wide group (worksheet has 27) stays
|
|
40
|
+
# readable in a normal terminal instead of running off the edge.
|
|
41
|
+
_WRAP_COL = 88
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class UnknownTopic(Exception):
|
|
45
|
+
"""Raised for a topic name the guide does not ship."""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@lru_cache(maxsize=1)
|
|
49
|
+
def _index() -> list[dict[str, Any]]:
|
|
50
|
+
with open(GUIDE_DIR / "index.json", encoding="utf-8") as fh:
|
|
51
|
+
return json.load(fh)["topics"]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _resolve_lang(lang: Optional[str]) -> str:
|
|
55
|
+
if lang is None:
|
|
56
|
+
from hap_cli.i18n import get_active_language
|
|
57
|
+
|
|
58
|
+
lang = get_active_language()
|
|
59
|
+
return lang
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _pick(entry: dict[str, Any], lang: str) -> str:
|
|
63
|
+
"""Localized string with the English base as fallback."""
|
|
64
|
+
return entry.get(lang) or entry[BASE_LANG]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def available_topics(lang: Optional[str] = None) -> list[dict[str, str]]:
|
|
68
|
+
"""Declared topics in display order: ``{name, title, summary}``."""
|
|
69
|
+
lang = _resolve_lang(lang)
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
"name": t["name"],
|
|
73
|
+
"title": _pick(t["title"], lang),
|
|
74
|
+
"summary": _pick(t["summary"], lang),
|
|
75
|
+
}
|
|
76
|
+
for t in _index()
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def render_topic(name: str, lang: Optional[str] = None) -> str:
|
|
81
|
+
"""Body of one topic, falling back to English when the active
|
|
82
|
+
language has no copy of it."""
|
|
83
|
+
known = [t["name"] for t in _index()]
|
|
84
|
+
if name not in known:
|
|
85
|
+
raise UnknownTopic(
|
|
86
|
+
f"No guide topic named '{name}'. Available topics: "
|
|
87
|
+
+ ", ".join(known)
|
|
88
|
+
)
|
|
89
|
+
lang = _resolve_lang(lang)
|
|
90
|
+
for candidate in (lang, BASE_LANG):
|
|
91
|
+
path = GUIDE_DIR / candidate / f"{name}.md"
|
|
92
|
+
if path.exists():
|
|
93
|
+
return path.read_text(encoding="utf-8").strip()
|
|
94
|
+
raise UnknownTopic(f"Guide topic '{name}' has no content installed.")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def command_map(root: click.Group) -> str:
|
|
98
|
+
"""Render the live command tree: every group, and the commands under it.
|
|
99
|
+
|
|
100
|
+
Generated rather than written so it always describes the installed
|
|
101
|
+
version. Hidden commands are omitted — they are not part of the
|
|
102
|
+
surface a caller should be pointed at.
|
|
103
|
+
"""
|
|
104
|
+
lines: list[str] = []
|
|
105
|
+
for name, cmd in sorted(root.commands.items()):
|
|
106
|
+
if cmd.hidden:
|
|
107
|
+
continue
|
|
108
|
+
summary = (cmd.get_short_help_str(limit=60) or "").strip()
|
|
109
|
+
lines.append(f" {name:<{_NAME_COL}}{summary}")
|
|
110
|
+
children = _child_names(cmd)
|
|
111
|
+
if children:
|
|
112
|
+
indent = " " * (2 + _NAME_COL)
|
|
113
|
+
lines.extend(textwrap.wrap(
|
|
114
|
+
" ".join(children), width=_WRAP_COL,
|
|
115
|
+
initial_indent=indent, subsequent_indent=indent,
|
|
116
|
+
break_long_words=False, break_on_hyphens=False,
|
|
117
|
+
))
|
|
118
|
+
return "\n".join(lines)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _child_names(cmd: click.Command) -> list[str]:
|
|
122
|
+
"""Direct subcommand names of a group, one nesting level only.
|
|
123
|
+
|
|
124
|
+
Deeper levels (``worksheet record create``) are reachable through
|
|
125
|
+
``--help`` and would drown the map; the point here is to show that
|
|
126
|
+
the capability exists, not to restate every signature.
|
|
127
|
+
"""
|
|
128
|
+
if not isinstance(cmd, click.Group):
|
|
129
|
+
return []
|
|
130
|
+
return sorted(n for n, c in cmd.commands.items() if not c.hidden)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _topic_lines(lang: str) -> str:
|
|
134
|
+
rows = available_topics(lang)
|
|
135
|
+
width = max(len(t["name"]) for t in rows) + len("hap guide ") + 2
|
|
136
|
+
return "\n".join(
|
|
137
|
+
f" {('hap guide ' + t['name']):<{width}}{t['summary']}" for t in rows
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def render_overview(root: click.Group, lang: Optional[str] = None) -> str:
|
|
142
|
+
"""The bare ``hap guide``: how to work, what exists, where to go next."""
|
|
143
|
+
lang = _resolve_lang(lang)
|
|
144
|
+
for candidate in (lang, BASE_LANG):
|
|
145
|
+
path = GUIDE_DIR / candidate / "overview.md"
|
|
146
|
+
if path.exists():
|
|
147
|
+
template = path.read_text(encoding="utf-8")
|
|
148
|
+
break
|
|
149
|
+
else: # pragma: no cover - shipped content is validated by tests
|
|
150
|
+
raise UnknownTopic("The guide overview has no content installed.")
|
|
151
|
+
from hap_cli import __version__
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
template.replace("{version}", __version__)
|
|
155
|
+
.replace("{command_map}", command_map(root))
|
|
156
|
+
.replace("{topics}", _topic_lines(lang))
|
|
157
|
+
.strip()
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def overview_payload(root: click.Group, lang: Optional[str] = None) -> dict[str, Any]:
|
|
162
|
+
"""Machine-readable form of the overview for ``--json`` callers."""
|
|
163
|
+
lang = _resolve_lang(lang)
|
|
164
|
+
return {
|
|
165
|
+
"text": render_overview(root, lang),
|
|
166
|
+
"topics": available_topics(lang),
|
|
167
|
+
"commands": [
|
|
168
|
+
{
|
|
169
|
+
"name": name,
|
|
170
|
+
"summary": (cmd.get_short_help_str(limit=60) or "").strip(),
|
|
171
|
+
"subcommands": _child_names(cmd),
|
|
172
|
+
}
|
|
173
|
+
for name, cmd in sorted(root.commands.items())
|
|
174
|
+
if not cmd.hidden
|
|
175
|
+
],
|
|
176
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# From a message or notification to its record
|
|
2
|
+
|
|
3
|
+
A lot of unread traffic is "someone commented on a record" or "a workflow copied you on
|
|
4
|
+
a record". To follow it back to the record, use this fixed path — **do not go hunting
|
|
5
|
+
through worksheets**.
|
|
6
|
+
|
|
7
|
+
## Three steps
|
|
8
|
+
|
|
9
|
+
**1. See which category the conversation belongs to**
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
hap --json chat list
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Every conversation carries a `category`: `system` / `post` / `calendar` / `task` / `kc` /
|
|
16
|
+
`hr` / `app` / `workflow`, plus `user` for one-to-one and `group` for group chats.
|
|
17
|
+
|
|
18
|
+
- **Record discussions inside an app or worksheet are `app`**
|
|
19
|
+
- Workflow notifications are `workflow`
|
|
20
|
+
|
|
21
|
+
**2. Pull the detail for that category**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
hap --json chat messages --category app # or workflow, etc.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- Record-discussion entries carry **`appId` + `worksheetId` + `rowId`** directly, along
|
|
28
|
+
with `viewId`, `comment.recordName` and `comment.entityName`.
|
|
29
|
+
- Workflow **cc / participant** notifications have the `appId` / `worksheetId` / `rowId`
|
|
30
|
+
resolved out of the record link for you.
|
|
31
|
+
- One-to-one and group chats do not use `--category`; use `--with-user <accountId>` or
|
|
32
|
+
`--group-id <groupId>` (the id is the conversation's `value`).
|
|
33
|
+
|
|
34
|
+
**3. Read the record and its discussion**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
hap worksheet record get <worksheetId> <rowId> -a <appId>
|
|
38
|
+
hap worksheet record discussions <worksheetId> <rowId> -a <appId>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## The one thing to get right
|
|
42
|
+
|
|
43
|
+
> Use the `appId` **on the message entry** (resolved from the discussion's `extendsId`
|
|
44
|
+
> or the record link) — **not the one on the conversation itself**. The conversation's
|
|
45
|
+
> appId belongs to the message centre and is frequently a deleted app; querying a record
|
|
46
|
+
> with it reports that the application has been deleted.
|
|
47
|
+
|
|
48
|
+
## Working backwards from a URL
|
|
49
|
+
|
|
50
|
+
A worksheet view page: `/app/<appId>/<sectionId>/<worksheetId>/<viewId>`
|
|
51
|
+
A record page: `/app/<appId>/<worksheetId>/<viewId>/row/<rowid>`
|
|
52
|
+
|
|
53
|
+
With worksheetId + rowid you can go straight to `record get` / `record update`;
|
|
54
|
+
`sectionId` and `viewId` are not needed to change data.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Using hap (hap-cli {version})
|
|
2
|
+
|
|
3
|
+
`hap` wraps the HAP enterprise platform as a command line. Sign in once and you can
|
|
4
|
+
look people up, send messages, post updates, manage calendars, read and write
|
|
5
|
+
worksheet records, handle approvals, and build or edit applications.
|
|
6
|
+
|
|
7
|
+
## How to work with it
|
|
8
|
+
|
|
9
|
+
1. **Check the environment is ready** — installed, signed in, current organization
|
|
10
|
+
chosen (and a default app if you will touch records). `hap auth whoami` confirms it;
|
|
11
|
+
`hap guide setup` covers the rest.
|
|
12
|
+
2. **Decide what kind of task this is**
|
|
13
|
+
- A single operation (find a person, send a message, read or write one record,
|
|
14
|
+
act on one approval) → use the matching top-level command below.
|
|
15
|
+
- Building a whole app, restructuring one, or complex filtering and pivots
|
|
16
|
+
→ hand off to a specialised skill, see `hap guide skills`.
|
|
17
|
+
3. **Read the options before composing** — `hap <command> --help` is the only
|
|
18
|
+
authority on arguments. **Do not compose commands from memory**: this tool
|
|
19
|
+
updates itself, so the version you remember may not be the one installed.
|
|
20
|
+
Add `--json` for structured output in scripts.
|
|
21
|
+
|
|
22
|
+
## Command map
|
|
23
|
+
|
|
24
|
+
This is the complete top-level surface of **the version installed on this machine**,
|
|
25
|
+
generated live rather than copied. Expand any of them with `hap <command> --help`.
|
|
26
|
+
|
|
27
|
+
{command_map}
|
|
28
|
+
|
|
29
|
+
## Topics
|
|
30
|
+
|
|
31
|
+
{topics}
|
|
32
|
+
|
|
33
|
+
## The traps people hit most
|
|
34
|
+
|
|
35
|
+
- `--json` and `--profile` are **global options and go between `hap` and the
|
|
36
|
+
subcommand**: `hap --json chat list` ✅, `hap chat list --json` ❌ ("No such option").
|
|
37
|
+
- To see a worksheet's fields use `hap worksheet fields WS_ID` — not get / structure.
|
|
38
|
+
- `record create/update/delete` **do not accept `--app-id`**; they use the default app.
|
|
39
|
+
Set it once with `hap app select <appId>` before writing.
|
|
40
|
+
- Field value shapes differ a lot and **a wrong one still reports success** —
|
|
41
|
+
read `hap guide record` before writing.
|
|
42
|
+
- Before touching workflow nodes run `hap workflow structure PROCESS_ID` and use the
|
|
43
|
+
real ids; do not invent node ids.
|
|
44
|
+
- To debug, turn on logging: `hap config log on` (written to `~/.hap-cli/hap-cli.log`,
|
|
45
|
+
with credentials redacted).
|