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.
Files changed (215) hide show
  1. {hap_cli-0.8.4 → hap_cli-0.8.6}/PKG-INFO +26 -3
  2. {hap_cli-0.8.4/hap_cli → hap_cli-0.8.6}/README.md +25 -2
  3. {hap_cli-0.8.4 → hap_cli-0.8.6/hap_cli}/README.md +25 -2
  4. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/README_CN.md +21 -2
  5. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/__init__.py +1 -1
  6. hap_cli-0.8.6/hap_cli/__main__.py +11 -0
  7. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/auth_cmd.py +6 -28
  8. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/icon_cmd.py +50 -5
  9. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/instance_cmd.py +3 -1
  10. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/node_cmd.py +30 -9
  11. hap_cli-0.8.6/hap_cli/commands/update_cmd.py +101 -0
  12. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/workflow_cmd.py +8 -1
  13. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/auth.py +123 -198
  14. hap_cli-0.8.6/hap_cli/core/cli_access.py +276 -0
  15. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/flow_node.py +103 -0
  16. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/icon_index.py +19 -0
  17. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/record.py +16 -4
  18. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/session.py +11 -0
  19. hap_cli-0.8.6/hap_cli/core/update.py +294 -0
  20. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/workflow.py +9 -3
  21. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/hap_cli.py +18 -0
  22. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/locale/messages.json +6 -3
  23. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/conftest.py +22 -0
  24. hap_cli-0.8.6/hap_cli/tests/test_auth_prerelease.py +154 -0
  25. hap_cli-0.8.6/hap_cli/tests/test_cli_access.py +320 -0
  26. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_core.py +217 -2
  27. hap_cli-0.8.6/hap_cli/tests/test_instance_history_cli.py +34 -0
  28. hap_cli-0.8.6/hap_cli/tests/test_record_field_alias.py +146 -0
  29. hap_cli-0.8.6/hap_cli/tests/test_update.py +423 -0
  30. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/PKG-INFO +26 -3
  31. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/SOURCES.txt +8 -0
  32. hap_cli-0.8.4/hap_cli/tests/test_auth_prerelease.py +0 -410
  33. {hap_cli-0.8.4 → hap_cli-0.8.6}/MANIFEST.in +0 -0
  34. {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/__init__.py +0 -0
  35. {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/__main__.py +0 -0
  36. {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/config.py +0 -0
  37. {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/harness.py +0 -0
  38. {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/smoke.py +0 -0
  39. {hap_cli-0.8.4 → hap_cli-0.8.6}/app_live_tests/state.py +0 -0
  40. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/__init__.py +0 -0
  41. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/app_cmd.py +0 -0
  42. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/app_editor_cmd.py +0 -0
  43. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/calendar_cmd.py +0 -0
  44. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/chart_cmd.py +0 -0
  45. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/chat_cmd.py +0 -0
  46. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/chatbot_cmd.py +0 -0
  47. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/config_cmd.py +0 -0
  48. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/contact_cmd.py +0 -0
  49. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/department_cmd.py +0 -0
  50. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/group_cmd.py +0 -0
  51. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/optionset_cmd.py +0 -0
  52. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/page_cmd.py +0 -0
  53. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/post_cmd.py +0 -0
  54. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/record_cmd.py +0 -0
  55. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/region_cmd.py +0 -0
  56. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/role_cmd.py +0 -0
  57. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/upload_cmd.py +0 -0
  58. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/v3_registry.py +0 -0
  59. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/commands/worksheet_cmd.py +0 -0
  60. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/context.py +0 -0
  61. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/__init__.py +0 -0
  62. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/action_spec_adapter.py +0 -0
  63. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/app.py +0 -0
  64. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/calendar_mod.py +0 -0
  65. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/chart.py +0 -0
  66. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/chat.py +0 -0
  67. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/chatbot.py +0 -0
  68. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/contact.py +0 -0
  69. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/control_type_codes.py +0 -0
  70. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/department.py +0 -0
  71. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/__init__.py +0 -0
  72. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
  73. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
  74. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/apply.py +0 -0
  75. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/componentlower.py +0 -0
  76. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/editspec.py +0 -0
  77. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/errors.py +0 -0
  78. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/fieldlower.py +0 -0
  79. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/jsonschema_mini.py +0 -0
  80. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/models.py +0 -0
  81. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/ops.py +0 -0
  82. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/planner.py +0 -0
  83. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/editor/reader.py +0 -0
  84. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/field_normalizer.py +0 -0
  85. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/field_spec_adapter.py +0 -0
  86. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/filter_translator.py +0 -0
  87. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/global_meta.py +0 -0
  88. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/group.py +0 -0
  89. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/instance.py +0 -0
  90. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/logger.py +0 -0
  91. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/optionset.py +0 -0
  92. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/page.py +0 -0
  93. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/post.py +0 -0
  94. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/response_crypto.py +0 -0
  95. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/role.py +0 -0
  96. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/role_perm_builder.py +0 -0
  97. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/token_crypto.py +0 -0
  98. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/upload.py +0 -0
  99. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/__init__.py +0 -0
  100. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/dispatcher.py +0 -0
  101. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/render.py +0 -0
  102. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/v3/schema.py +0 -0
  103. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/view_spec_adapter.py +0 -0
  104. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/workflow_node_dsl.py +0 -0
  105. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/worksheet.py +0 -0
  106. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/core/worksheet_templates.py +0 -0
  107. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/i18n.py +0 -0
  108. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/locale/__init__.py +0 -0
  109. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/locale/messages.schema.json +0 -0
  110. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/__init__.py +0 -0
  111. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_app_editor.py +0 -0
  112. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_app_export_usage.py +0 -0
  113. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_bug_036430.py +0 -0
  114. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_chart.py +0 -0
  115. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_config_cmd.py +0 -0
  116. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_destructive_confirm_cli.py +0 -0
  117. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_full_e2e.py +0 -0
  118. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_global_meta.py +0 -0
  119. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_i18n.py +0 -0
  120. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration.py +0 -0
  121. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_approval.py +0 -0
  122. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_approval_actions.py +0 -0
  123. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_calendar.py +0 -0
  124. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_destructive.py +0 -0
  125. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_misc.py +0 -0
  126. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_post.py +0 -0
  127. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_social.py +0 -0
  128. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_v3.py +0 -0
  129. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_workflow.py +0 -0
  130. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
  131. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_multi_profile.py +0 -0
  132. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_org_approval_v3_semantic_cli.py +0 -0
  133. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_org_id_cli.py +0 -0
  134. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_org_id_docs.py +0 -0
  135. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_parameter_conventions.py +0 -0
  136. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
  137. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_record_batch_v3_semantic_cli.py +0 -0
  138. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_record_v3_semantic_cli.py +0 -0
  139. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_semantic_types_registry.py +0 -0
  140. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_api_schema_loader.py +0 -0
  141. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_dispatcher.py +0 -0
  142. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_registry_coverage.py +0 -0
  143. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_session.py +0 -0
  144. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_v3_yaml_translation.py +0 -0
  145. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_workflow_v3_semantic_cli.py +0 -0
  146. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_worksheet_crud_cli.py +0 -0
  147. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/tests/test_worksheet_v3_semantic_cli.py +0 -0
  148. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/__init__.py +0 -0
  149. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/formatting.py +0 -0
  150. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/options.py +0 -0
  151. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli/utils/parameter_mapping.py +0 -0
  152. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/dependency_links.txt +0 -0
  153. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/entry_points.txt +0 -0
  154. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/requires.txt +0 -0
  155. {hap_cli-0.8.4 → hap_cli-0.8.6}/hap_cli.egg-info/top_level.txt +0 -0
  156. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/__init__.py +0 -0
  157. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/__main__.py +0 -0
  158. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/_wftest.py +0 -0
  159. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/charts.py +0 -0
  160. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/cleanup.py +0 -0
  161. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/compiler.py +0 -0
  162. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/config.py +0 -0
  163. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/errors.py +0 -0
  164. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/executor.py +0 -0
  165. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/fields.py +0 -0
  166. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/hap.py +0 -0
  167. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/__init__.py +0 -0
  168. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/console.py +0 -0
  169. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/jsonl.py +0 -0
  170. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/mirror.py +0 -0
  171. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/recording/report.py +0 -0
  172. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/schema.py +0 -0
  173. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/__init__.py +0 -0
  174. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/cli.py +0 -0
  175. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/executor.py +0 -0
  176. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/seed/template.py +0 -0
  177. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/selftest.py +0 -0
  178. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/smoke.py +0 -0
  179. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/step.py +0 -0
  180. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/steps.py +0 -0
  181. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/store.py +0 -0
  182. {hap_cli-0.8.4 → hap_cli-0.8.6}/live_tests/workflow_dsl.py +0 -0
  183. {hap_cli-0.8.4 → hap_cli-0.8.6}/setup.cfg +0 -0
  184. {hap_cli-0.8.4 → hap_cli-0.8.6}/setup.py +0 -0
  185. {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/component.schema.json +0 -0
  186. {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/custom-action.schema.json +0 -0
  187. {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/envelope.schema.json +0 -0
  188. {hap_cli-0.8.4 → hap_cli-0.8.6}/skills/hap-cli-app-editor/scripts/editspec/field.schema.json +0 -0
  189. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/INDEX.json +0 -0
  190. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
  191. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
  192. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/create_optionset.yaml +0 -0
  193. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/create_role.yaml +0 -0
  194. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_optionset.yaml +0 -0
  195. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_record.yaml +0 -0
  196. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_role.yaml +0 -0
  197. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
  198. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_app_info.yaml +0 -0
  199. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
  200. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
  201. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
  202. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_details.yaml +0 -0
  203. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
  204. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_list.yaml +0 -0
  205. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_logs.yaml +0 -0
  206. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
  207. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_relations.yaml +0 -0
  208. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
  209. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_regions.yaml +0 -0
  210. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_role_details.yaml +0 -0
  211. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/get_role_list.yaml +0 -0
  212. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/knowledge_search.yaml +0 -0
  213. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
  214. {hap_cli-0.8.4 → hap_cli-0.8.6}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
  215. {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.4
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 every icon with its keywords |
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 every icon with its keywords |
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 every icon with its keywords |
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` 的命令解析顺序:
@@ -1,3 +1,3 @@
1
1
  """CLI harness for MingDAO HAP (hap-cli)."""
2
2
 
3
- __version__ = "0.8.4"
3
+ __version__ = "0.8.6"
@@ -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 md_pss_id token and paste it below.")
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. Use the returned
44
- icon name with the --icon option of app/worksheet creation.
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 every icon in the catalogue with its keywords."""
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
- ctx.output(rows, _icon_table)
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
- @click.option("--process-id", default="", help="Filter by process")
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
- cond_list = json.loads(condition) if condition else None
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
- operate_condition=cond_list, sorts=sorts_list,
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="Query conditions JSON")
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
- cond_list = json.loads(condition) if condition else None
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, operate_condition=cond_list,
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
- cond_list = json.loads(condition) if condition else None
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, operate_condition=cond_list,
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