hap-cli 0.9.8__tar.gz → 0.9.10__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 (420) hide show
  1. {hap_cli-0.9.8 → hap_cli-0.9.10}/MANIFEST.in +6 -0
  2. {hap_cli-0.9.8 → hap_cli-0.9.10}/PKG-INFO +1 -1
  3. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/__init__.py +1 -1
  4. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/chat_cmd.py +118 -13
  5. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/v3_registry.py +41 -1
  6. hap_cli-0.9.10/hap_cli/core/record_discussions.py +137 -0
  7. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/upload.py +13 -2
  8. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/messages.md +1 -1
  9. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/messages.md +1 -1
  10. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/locale/messages.json +44 -20
  11. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli.egg-info/PKG-INFO +1 -1
  12. hap_cli-0.9.10/hap_cli.egg-info/SOURCES.txt +211 -0
  13. hap_cli-0.9.10/hap_cli.egg-info/top_level.txt +1 -0
  14. {hap_cli-0.9.8 → hap_cli-0.9.10}/setup.py +18 -7
  15. hap_cli-0.9.8/app_live_tests/__init__.py +0 -11
  16. hap_cli-0.9.8/app_live_tests/__main__.py +0 -32
  17. hap_cli-0.9.8/app_live_tests/config.py +0 -20
  18. hap_cli-0.9.8/app_live_tests/fixtures/__init__.py +0 -1
  19. hap_cli-0.9.8/app_live_tests/fixtures/feedback_scenario.py +0 -256
  20. hap_cli-0.9.8/app_live_tests/harness.py +0 -76
  21. hap_cli-0.9.8/app_live_tests/smoke.py +0 -4937
  22. hap_cli-0.9.8/app_live_tests/state.py +0 -91
  23. hap_cli-0.9.8/hap_cli/tests/__init__.py +0 -1
  24. hap_cli-0.9.8/hap_cli/tests/conftest.py +0 -234
  25. hap_cli-0.9.8/hap_cli/tests/test_action_mdpublic_parity.py +0 -289
  26. hap_cli-0.9.8/hap_cli/tests/test_advanced_setting_guard.py +0 -514
  27. hap_cli-0.9.8/hap_cli/tests/test_app_creator.py +0 -119
  28. hap_cli-0.9.8/hap_cli/tests/test_app_editor.py +0 -304
  29. hap_cli-0.9.8/hap_cli/tests/test_app_export_usage.py +0 -224
  30. hap_cli-0.9.8/hap_cli/tests/test_app_light_color.py +0 -42
  31. hap_cli-0.9.8/hap_cli/tests/test_app_section_name.py +0 -97
  32. hap_cli-0.9.8/hap_cli/tests/test_approval_submit_fill_cli.py +0 -143
  33. hap_cli-0.9.8/hap_cli/tests/test_approval_wire.py +0 -259
  34. hap_cli-0.9.8/hap_cli/tests/test_atomic_write.py +0 -202
  35. hap_cli-0.9.8/hap_cli/tests/test_attachment_share.py +0 -434
  36. hap_cli-0.9.8/hap_cli/tests/test_auth_prerelease.py +0 -154
  37. hap_cli-0.9.8/hap_cli/tests/test_batch_add_atomic.py +0 -381
  38. hap_cli-0.9.8/hap_cli/tests/test_bug_036430.py +0 -167
  39. hap_cli-0.9.8/hap_cli/tests/test_bug_036750.py +0 -130
  40. hap_cli-0.9.8/hap_cli/tests/test_calendar_date_range.py +0 -51
  41. hap_cli-0.9.8/hap_cli/tests/test_calendar_discussion_cli.py +0 -89
  42. hap_cli-0.9.8/hap_cli/tests/test_chart.py +0 -433
  43. hap_cli-0.9.8/hap_cli/tests/test_chart_filter_merge.py +0 -200
  44. hap_cli-0.9.8/hap_cli/tests/test_chat_attachment_send.py +0 -501
  45. hap_cli-0.9.8/hap_cli/tests/test_chat_messages_cli.py +0 -28
  46. hap_cli-0.9.8/hap_cli/tests/test_chat_recall_cli.py +0 -161
  47. hap_cli-0.9.8/hap_cli/tests/test_chat_send_socket.py +0 -122
  48. hap_cli-0.9.8/hap_cli/tests/test_cli_access.py +0 -738
  49. hap_cli-0.9.8/hap_cli/tests/test_coded_responses.py +0 -152
  50. hap_cli-0.9.8/hap_cli/tests/test_condition_dsl.py +0 -451
  51. hap_cli-0.9.8/hap_cli/tests/test_condition_dsl_entries.py +0 -239
  52. hap_cli-0.9.8/hap_cli/tests/test_condition_dsl_readback.py +0 -131
  53. hap_cli-0.9.8/hap_cli/tests/test_config_cmd.py +0 -217
  54. hap_cli-0.9.8/hap_cli/tests/test_content_language.py +0 -120
  55. hap_cli-0.9.8/hap_cli/tests/test_control_lookup_guard.py +0 -179
  56. hap_cli-0.9.8/hap_cli/tests/test_core.py +0 -11508
  57. hap_cli-0.9.8/hap_cli/tests/test_create_worksheet_partial.py +0 -231
  58. hap_cli-0.9.8/hap_cli/tests/test_destructive_confirm_cli.py +0 -178
  59. hap_cli-0.9.8/hap_cli/tests/test_dsl_existing_node_refs.py +0 -372
  60. hap_cli-0.9.8/hap_cli/tests/test_dsl_multi_record_guard.py +0 -444
  61. hap_cli-0.9.8/hap_cli/tests/test_editor_inline_subtable.py +0 -239
  62. hap_cli-0.9.8/hap_cli/tests/test_engine_core_parity.py +0 -121
  63. hap_cli-0.9.8/hap_cli/tests/test_fb_arg_consistency.py +0 -236
  64. hap_cli-0.9.8/hap_cli/tests/test_fb_bidirectional.py +0 -155
  65. hap_cli-0.9.8/hap_cli/tests/test_fb_discussion_mentions.py +0 -227
  66. hap_cli-0.9.8/hap_cli/tests/test_fb_entry_module.py +0 -122
  67. hap_cli-0.9.8/hap_cli/tests/test_fb_field_record_ref.py +0 -380
  68. hap_cli-0.9.8/hap_cli/tests/test_fb_http_error_body.py +0 -85
  69. hap_cli-0.9.8/hap_cli/tests/test_fb_json_anywhere.py +0 -123
  70. hap_cli-0.9.8/hap_cli/tests/test_fb_json_file_arg.py +0 -65
  71. hap_cli-0.9.8/hap_cli/tests/test_fb_layout_check.py +0 -206
  72. hap_cli-0.9.8/hap_cli/tests/test_fb_node_get_detail.py +0 -188
  73. hap_cli-0.9.8/hap_cli/tests/test_fb_node_summary.py +0 -226
  74. hap_cli-0.9.8/hap_cli/tests/test_fb_post_cursor.py +0 -119
  75. hap_cli-0.9.8/hap_cli/tests/test_fb_publish_reasons.py +0 -193
  76. hap_cli-0.9.8/hap_cli/tests/test_fb_replicate_workflow.py +0 -587
  77. hap_cli-0.9.8/hap_cli/tests/test_fb_save_fields_shape.py +0 -167
  78. hap_cli-0.9.8/hap_cli/tests/test_fb_subgroups.py +0 -73
  79. hap_cli-0.9.8/hap_cli/tests/test_fb_subtable_read.py +0 -281
  80. hap_cli-0.9.8/hap_cli/tests/test_fb_worksheet_references.py +0 -262
  81. hap_cli-0.9.8/hap_cli/tests/test_fb_worksheet_visibility.py +0 -133
  82. hap_cli-0.9.8/hap_cli/tests/test_fb_worksheet_workflows.py +0 -159
  83. hap_cli-0.9.8/hap_cli/tests/test_fields_mdpublic_parity.py +0 -335
  84. hap_cli-0.9.8/hap_cli/tests/test_full_e2e.py +0 -179
  85. hap_cli-0.9.8/hap_cli/tests/test_g1_chart_parity.py +0 -200
  86. hap_cli-0.9.8/hap_cli/tests/test_g1_record_parity.py +0 -206
  87. hap_cli-0.9.8/hap_cli/tests/test_g1_upload_parity.py +0 -163
  88. hap_cli-0.9.8/hap_cli/tests/test_g1_worksheet_parity.py +0 -237
  89. hap_cli-0.9.8/hap_cli/tests/test_g2_coverage_parity.py +0 -484
  90. hap_cli-0.9.8/hap_cli/tests/test_g3_workflow_parity.py +0 -348
  91. hap_cli-0.9.8/hap_cli/tests/test_g4_approval_parity.py +0 -403
  92. hap_cli-0.9.8/hap_cli/tests/test_g5_low_frequency_parity.py +0 -500
  93. hap_cli-0.9.8/hap_cli/tests/test_g6_advanced_fields.py +0 -465
  94. hap_cli-0.9.8/hap_cli/tests/test_g6_fields_roundtrip.py +0 -102
  95. hap_cli-0.9.8/hap_cli/tests/test_g7_misc_gaps.py +0 -342
  96. hap_cli-0.9.8/hap_cli/tests/test_g7b_permanent_delete.py +0 -348
  97. hap_cli-0.9.8/hap_cli/tests/test_g8_filter_operator.py +0 -305
  98. hap_cli-0.9.8/hap_cli/tests/test_g8b_pivot_operators.py +0 -106
  99. hap_cli-0.9.8/hap_cli/tests/test_g8c_empty_filter_and_help_truth.py +0 -329
  100. hap_cli-0.9.8/hap_cli/tests/test_g9_appid_resolve.py +0 -166
  101. hap_cli-0.9.8/hap_cli/tests/test_global_meta.py +0 -309
  102. hap_cli-0.9.8/hap_cli/tests/test_guide.py +0 -364
  103. hap_cli-0.9.8/hap_cli/tests/test_guide_sections.py +0 -322
  104. hap_cli-0.9.8/hap_cli/tests/test_i18n.py +0 -423
  105. hap_cli-0.9.8/hap_cli/tests/test_inner_flow_batch_add.py +0 -151
  106. hap_cli-0.9.8/hap_cli/tests/test_instance_envelope.py +0 -127
  107. hap_cli-0.9.8/hap_cli/tests/test_instance_history_cli.py +0 -89
  108. hap_cli-0.9.8/hap_cli/tests/test_integration.py +0 -866
  109. hap_cli-0.9.8/hap_cli/tests/test_integration_approval.py +0 -320
  110. hap_cli-0.9.8/hap_cli/tests/test_integration_approval_actions.py +0 -261
  111. hap_cli-0.9.8/hap_cli/tests/test_integration_calendar.py +0 -283
  112. hap_cli-0.9.8/hap_cli/tests/test_integration_destructive.py +0 -357
  113. hap_cli-0.9.8/hap_cli/tests/test_integration_misc.py +0 -171
  114. hap_cli-0.9.8/hap_cli/tests/test_integration_post.py +0 -118
  115. hap_cli-0.9.8/hap_cli/tests/test_integration_social.py +0 -191
  116. hap_cli-0.9.8/hap_cli/tests/test_integration_v3.py +0 -177
  117. hap_cli-0.9.8/hap_cli/tests/test_integration_workflow.py +0 -145
  118. hap_cli-0.9.8/hap_cli/tests/test_integration_worksheet_extra.py +0 -154
  119. hap_cli-0.9.8/hap_cli/tests/test_jsonschema_mini_copy.py +0 -84
  120. hap_cli-0.9.8/hap_cli/tests/test_member_relation_array_wrap.py +0 -103
  121. hap_cli-0.9.8/hap_cli/tests/test_multi_profile.py +0 -434
  122. hap_cli-0.9.8/hap_cli/tests/test_no_workflow_unsupported.py +0 -92
  123. hap_cli-0.9.8/hap_cli/tests/test_noninteractive_confirm.py +0 -153
  124. hap_cli-0.9.8/hap_cli/tests/test_org_approval_v3_semantic_cli.py +0 -266
  125. hap_cli-0.9.8/hap_cli/tests/test_org_id_cli.py +0 -123
  126. hap_cli-0.9.8/hap_cli/tests/test_org_id_docs.py +0 -35
  127. hap_cli-0.9.8/hap_cli/tests/test_page_filters_group_read.py +0 -243
  128. hap_cli-0.9.8/hap_cli/tests/test_page_filters_group_update.py +0 -290
  129. hap_cli-0.9.8/hap_cli/tests/test_page_save_page_id.py +0 -76
  130. hap_cli-0.9.8/hap_cli/tests/test_parameter_conventions.py +0 -41
  131. hap_cli-0.9.8/hap_cli/tests/test_parameter_mapping_registry.py +0 -96
  132. hap_cli-0.9.8/hap_cli/tests/test_post_attachments.py +0 -182
  133. hap_cli-0.9.8/hap_cli/tests/test_post_group_friction.py +0 -205
  134. hap_cli-0.9.8/hap_cli/tests/test_post_scope_cli.py +0 -203
  135. hap_cli-0.9.8/hap_cli/tests/test_record_batch_v3_semantic_cli.py +0 -279
  136. hap_cli-0.9.8/hap_cli/tests/test_record_business_rules.py +0 -999
  137. hap_cli-0.9.8/hap_cli/tests/test_record_defaults.py +0 -723
  138. hap_cli-0.9.8/hap_cli/tests/test_record_doc_id_hidden.py +0 -199
  139. hap_cli-0.9.8/hap_cli/tests/test_record_field_alias.py +0 -146
  140. hap_cli-0.9.8/hap_cli/tests/test_record_form_checks.py +0 -481
  141. hap_cli-0.9.8/hap_cli/tests/test_record_run_action.py +0 -345
  142. hap_cli-0.9.8/hap_cli/tests/test_record_v3_semantic_cli.py +0 -96
  143. hap_cli-0.9.8/hap_cli/tests/test_record_write_fixes.py +0 -125
  144. hap_cli-0.9.8/hap_cli/tests/test_relation_scope.py +0 -440
  145. hap_cli-0.9.8/hap_cli/tests/test_relogin.py +0 -234
  146. hap_cli-0.9.8/hap_cli/tests/test_rmw_mdpublic_parity.py +0 -183
  147. hap_cli-0.9.8/hap_cli/tests/test_role_app_scope.py +0 -101
  148. hap_cli-0.9.8/hap_cli/tests/test_rule_filters_and_field_warning.py +0 -199
  149. hap_cli-0.9.8/hap_cli/tests/test_save_action_silent_drop.py +0 -66
  150. hap_cli-0.9.8/hap_cli/tests/test_save_rule_spec.py +0 -274
  151. hap_cli-0.9.8/hap_cli/tests/test_select_add_option.py +0 -78
  152. hap_cli-0.9.8/hap_cli/tests/test_select_rejects_relation_value.py +0 -182
  153. hap_cli-0.9.8/hap_cli/tests/test_semantic_types_registry.py +0 -92
  154. hap_cli-0.9.8/hap_cli/tests/test_subtable_mdpublic_parity.py +0 -82
  155. hap_cli-0.9.8/hap_cli/tests/test_update.py +0 -424
  156. hap_cli-0.9.8/hap_cli/tests/test_update_mode.py +0 -90
  157. hap_cli-0.9.8/hap_cli/tests/test_upload_allow_down.py +0 -118
  158. hap_cli-0.9.8/hap_cli/tests/test_upload_host_resolution.py +0 -93
  159. hap_cli-0.9.8/hap_cli/tests/test_upload_mdpublic_parity.py +0 -105
  160. hap_cli-0.9.8/hap_cli/tests/test_v3_api_schema_loader.py +0 -359
  161. hap_cli-0.9.8/hap_cli/tests/test_v3_bool_flags.py +0 -195
  162. hap_cli-0.9.8/hap_cli/tests/test_v3_dispatcher.py +0 -410
  163. hap_cli-0.9.8/hap_cli/tests/test_v3_registry_coverage.py +0 -139
  164. hap_cli-0.9.8/hap_cli/tests/test_v3_response_format_json.py +0 -276
  165. hap_cli-0.9.8/hap_cli/tests/test_v3_session.py +0 -332
  166. hap_cli-0.9.8/hap_cli/tests/test_v3_yaml_translation.py +0 -322
  167. hap_cli-0.9.8/hap_cli/tests/test_view_mdpublic_parity.py +0 -197
  168. hap_cli-0.9.8/hap_cli/tests/test_wf_config_keys.py +0 -153
  169. hap_cli-0.9.8/hap_cli/tests/test_wf_inner_scope.py +0 -155
  170. hap_cli-0.9.8/hap_cli/tests/test_wf_json_file_arg.py +0 -86
  171. hap_cli-0.9.8/hap_cli/tests/test_wf_node_delete_missing.py +0 -98
  172. hap_cli-0.9.8/hap_cli/tests/test_wf_save_action_dsl_fields.py +0 -184
  173. hap_cli-0.9.8/hap_cli/tests/test_wf_structure_listing.py +0 -79
  174. hap_cli-0.9.8/hap_cli/tests/test_wf_trigger_outcome.py +0 -72
  175. hap_cli-0.9.8/hap_cli/tests/test_wf_trigger_preserve.py +0 -99
  176. hap_cli-0.9.8/hap_cli/tests/test_wo4_result_handling.py +0 -184
  177. hap_cli-0.9.8/hap_cli/tests/test_workflow_code_node.py +0 -324
  178. hap_cli-0.9.8/hap_cli/tests/test_workflow_condition_field_types.py +0 -360
  179. hap_cli-0.9.8/hap_cli/tests/test_workflow_condition_slots.py +0 -180
  180. hap_cli-0.9.8/hap_cli/tests/test_workflow_delete_cascade.py +0 -137
  181. hap_cli-0.9.8/hap_cli/tests/test_workflow_envelope_errors.py +0 -112
  182. hap_cli-0.9.8/hap_cli/tests/test_workflow_lifecycle_wire.py +0 -179
  183. hap_cli-0.9.8/hap_cli/tests/test_workflow_list_cli.py +0 -73
  184. hap_cli-0.9.8/hap_cli/tests/test_workflow_node_wire.py +0 -349
  185. hap_cli-0.9.8/hap_cli/tests/test_workflow_publish_inner.py +0 -349
  186. hap_cli-0.9.8/hap_cli/tests/test_workflow_read_write_keys.py +0 -71
  187. hap_cli-0.9.8/hap_cli/tests/test_workflow_v3_semantic_cli.py +0 -668
  188. hap_cli-0.9.8/hap_cli/tests/test_worksheet_create_section.py +0 -91
  189. hap_cli-0.9.8/hap_cli/tests/test_worksheet_crud_cli.py +0 -79
  190. hap_cli-0.9.8/hap_cli/tests/test_worksheet_filter_read.py +0 -203
  191. hap_cli-0.9.8/hap_cli/tests/test_worksheet_switch.py +0 -186
  192. hap_cli-0.9.8/hap_cli/tests/test_worksheet_v3_semantic_cli.py +0 -378
  193. hap_cli-0.9.8/hap_cli.egg-info/SOURCES.txt +0 -415
  194. hap_cli-0.9.8/hap_cli.egg-info/top_level.txt +0 -3
  195. hap_cli-0.9.8/live_tests/__init__.py +0 -16
  196. hap_cli-0.9.8/live_tests/__main__.py +0 -39
  197. hap_cli-0.9.8/live_tests/_wftest.py +0 -72
  198. hap_cli-0.9.8/live_tests/charts.py +0 -454
  199. hap_cli-0.9.8/live_tests/cleanup.py +0 -67
  200. hap_cli-0.9.8/live_tests/compiler.py +0 -129
  201. hap_cli-0.9.8/live_tests/config.py +0 -33
  202. hap_cli-0.9.8/live_tests/errors.py +0 -51
  203. hap_cli-0.9.8/live_tests/executor.py +0 -152
  204. hap_cli-0.9.8/live_tests/fields.py +0 -430
  205. hap_cli-0.9.8/live_tests/hap.py +0 -147
  206. hap_cli-0.9.8/live_tests/recording/__init__.py +0 -4
  207. hap_cli-0.9.8/live_tests/recording/console.py +0 -59
  208. hap_cli-0.9.8/live_tests/recording/jsonl.py +0 -41
  209. hap_cli-0.9.8/live_tests/recording/mirror.py +0 -45
  210. hap_cli-0.9.8/live_tests/recording/report.py +0 -127
  211. hap_cli-0.9.8/live_tests/schema.py +0 -223
  212. hap_cli-0.9.8/live_tests/seed/__init__.py +0 -21
  213. hap_cli-0.9.8/live_tests/seed/cli.py +0 -81
  214. hap_cli-0.9.8/live_tests/seed/executor.py +0 -264
  215. hap_cli-0.9.8/live_tests/seed/template.py +0 -154
  216. hap_cli-0.9.8/live_tests/selftest.py +0 -272
  217. hap_cli-0.9.8/live_tests/smoke.py +0 -123
  218. hap_cli-0.9.8/live_tests/step.py +0 -86
  219. hap_cli-0.9.8/live_tests/steps.py +0 -1125
  220. hap_cli-0.9.8/live_tests/store.py +0 -332
  221. hap_cli-0.9.8/live_tests/workflow_dsl.py +0 -456
  222. {hap_cli-0.9.8 → hap_cli-0.9.10}/README.md +0 -0
  223. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/README.md +0 -0
  224. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/README_CN.md +0 -0
  225. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/__main__.py +0 -0
  226. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/_entry.py +0 -0
  227. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/__init__.py +0 -0
  228. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/app_cmd.py +0 -0
  229. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/app_creator_cmd.py +0 -0
  230. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/app_editor_cmd.py +0 -0
  231. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/attachment_cmd.py +0 -0
  232. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/auth_cmd.py +0 -0
  233. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/calendar_cmd.py +0 -0
  234. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/chart_cmd.py +0 -0
  235. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/chatbot_cmd.py +0 -0
  236. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/config_cmd.py +0 -0
  237. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/contact_cmd.py +0 -0
  238. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/department_cmd.py +0 -0
  239. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/group_cmd.py +0 -0
  240. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/guide_cmd.py +0 -0
  241. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/icon_cmd.py +0 -0
  242. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/instance_cmd.py +0 -0
  243. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/node_cmd.py +0 -0
  244. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/optionset_cmd.py +0 -0
  245. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/page_cmd.py +0 -0
  246. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/post_cmd.py +0 -0
  247. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/record_cmd.py +0 -0
  248. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/region_cmd.py +0 -0
  249. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/role_cmd.py +0 -0
  250. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/update_cmd.py +0 -0
  251. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/upload_cmd.py +0 -0
  252. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/workflow_cmd.py +0 -0
  253. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/commands/worksheet_cmd.py +0 -0
  254. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/context.py +0 -0
  255. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/__init__.py +0 -0
  256. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/action_spec_adapter.py +0 -0
  257. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app.py +0 -0
  258. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/__init__.py +0 -0
  259. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/_hapmeta/__init__.py +0 -0
  260. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/_hapmeta/control_type_codes.py +0 -0
  261. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/_hapmeta/worksheet_templates.py +0 -0
  262. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/charts.py +0 -0
  263. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/cleanup.py +0 -0
  264. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/compiler.py +0 -0
  265. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/config.py +0 -0
  266. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/design/design.schema.json +0 -0
  267. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/errors.py +0 -0
  268. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/examples/minimal.design.json +0 -0
  269. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/executor.py +0 -0
  270. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/fields.py +0 -0
  271. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/hap.py +0 -0
  272. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/merge.py +0 -0
  273. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/recording/__init__.py +0 -0
  274. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/recording/console.py +0 -0
  275. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/recording/jsonl.py +0 -0
  276. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/recording/mirror.py +0 -0
  277. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/recording/report.py +0 -0
  278. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/schema.py +0 -0
  279. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/INSTRUCTIONS.md +0 -0
  280. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/__init__.py +0 -0
  281. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/cli.py +0 -0
  282. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/executor.py +0 -0
  283. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/resources/attachments.json +0 -0
  284. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/resources/sample.docx +0 -0
  285. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/resources/sample.pdf +0 -0
  286. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/resources/sample_images.json +0 -0
  287. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/seed/template.py +0 -0
  288. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/selftest.py +0 -0
  289. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/smoke.py +0 -0
  290. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/steps.py +0 -0
  291. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/store.py +0 -0
  292. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/validate.py +0 -0
  293. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/app_creator/workflow_dsl.py +0 -0
  294. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/attachment.py +0 -0
  295. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/auth.py +0 -0
  296. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/calendar_mod.py +0 -0
  297. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/chart.py +0 -0
  298. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/chat.py +0 -0
  299. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/chatbot.py +0 -0
  300. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/cli_access.py +0 -0
  301. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/condition_dsl.py +0 -0
  302. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/contact.py +0 -0
  303. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/control_type_codes.py +0 -0
  304. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/department.py +0 -0
  305. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/__init__.py +0 -0
  306. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
  307. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
  308. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/apply.py +0 -0
  309. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/componentlower.py +0 -0
  310. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/editspec/component.schema.json +0 -0
  311. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/editspec/custom-action.schema.json +0 -0
  312. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/editspec/envelope.schema.json +0 -0
  313. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/editspec/field.schema.json +0 -0
  314. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/editspec.py +0 -0
  315. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/errors.py +0 -0
  316. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/fieldlower.py +0 -0
  317. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/jsonschema_mini.py +0 -0
  318. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/models.py +0 -0
  319. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/ops.py +0 -0
  320. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/planner.py +0 -0
  321. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/editor/reader.py +0 -0
  322. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/field_normalizer.py +0 -0
  323. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/field_spec_adapter.py +0 -0
  324. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/filter_translator.py +0 -0
  325. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/filter_v3.py +0 -0
  326. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/flow_node.py +0 -0
  327. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/global_meta.py +0 -0
  328. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/group.py +0 -0
  329. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/guide.py +0 -0
  330. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/icon_index.py +0 -0
  331. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/instance.py +0 -0
  332. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/layout_check.py +0 -0
  333. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/logger.py +0 -0
  334. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/optionset.py +0 -0
  335. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/page.py +0 -0
  336. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/post.py +0 -0
  337. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/record.py +0 -0
  338. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/record_defaults.py +0 -0
  339. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/record_form_checks.py +0 -0
  340. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/record_lookups.py +0 -0
  341. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/record_rules.py +0 -0
  342. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/relation_scope.py +0 -0
  343. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/relogin.py +0 -0
  344. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/response_crypto.py +0 -0
  345. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/role.py +0 -0
  346. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/role_perm_builder.py +0 -0
  347. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/rule_spec_adapter.py +0 -0
  348. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/session.py +0 -0
  349. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/token_crypto.py +0 -0
  350. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/update.py +0 -0
  351. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/v3/__init__.py +0 -0
  352. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/v3/dispatcher.py +0 -0
  353. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/v3/render.py +0 -0
  354. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/v3/schema.py +0 -0
  355. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/view_spec_adapter.py +0 -0
  356. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/workflow.py +0 -0
  357. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/workflow_node_dsl.py +0 -0
  358. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/worksheet.py +0 -0
  359. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/worksheet_form.py +0 -0
  360. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/worksheet_reference.py +0 -0
  361. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/core/worksheet_templates.py +0 -0
  362. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/approval.md +0 -0
  363. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/chart.md +0 -0
  364. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/overview.md +0 -0
  365. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/post.md +0 -0
  366. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/record.md +0 -0
  367. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/setup.md +0 -0
  368. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/skills.md +0 -0
  369. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/workflow.md +0 -0
  370. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/en/worksheet.md +0 -0
  371. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/index.json +0 -0
  372. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/approval.md +0 -0
  373. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/chart.md +0 -0
  374. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/overview.md +0 -0
  375. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/post.md +0 -0
  376. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/record.md +0 -0
  377. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/setup.md +0 -0
  378. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/skills.md +0 -0
  379. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/workflow.md +0 -0
  380. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/guide/zh-Hans/worksheet.md +0 -0
  381. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/i18n.py +0 -0
  382. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/locale/__init__.py +0 -0
  383. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/locale/messages.schema.json +0 -0
  384. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/utils/__init__.py +0 -0
  385. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/utils/atomic_write.py +0 -0
  386. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/utils/confirm.py +0 -0
  387. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/utils/formatting.py +0 -0
  388. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/utils/options.py +0 -0
  389. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli/utils/parameter_mapping.py +0 -0
  390. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli.egg-info/dependency_links.txt +0 -0
  391. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli.egg-info/entry_points.txt +0 -0
  392. {hap_cli-0.9.8 → hap_cli-0.9.10}/hap_cli.egg-info/requires.txt +0 -0
  393. {hap_cli-0.9.8 → hap_cli-0.9.10}/setup.cfg +0 -0
  394. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/INDEX.json +0 -0
  395. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
  396. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
  397. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/create_optionset.yaml +0 -0
  398. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/create_role.yaml +0 -0
  399. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/delete_optionset.yaml +0 -0
  400. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/delete_record.yaml +0 -0
  401. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/delete_role.yaml +0 -0
  402. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
  403. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_app_info.yaml +0 -0
  404. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
  405. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
  406. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
  407. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_details.yaml +0 -0
  408. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
  409. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_list.yaml +0 -0
  410. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_logs.yaml +0 -0
  411. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
  412. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_relations.yaml +0 -0
  413. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
  414. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_regions.yaml +0 -0
  415. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_role_details.yaml +0 -0
  416. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/get_role_list.yaml +0 -0
  417. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/knowledge_search.yaml +0 -0
  418. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
  419. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
  420. {hap_cli-0.9.8 → hap_cli-0.9.10}/sources/v3-api-schema/update_optionset.yaml +0 -0
@@ -13,3 +13,9 @@ include hap_cli/README_CN.md
13
13
  recursive-include hap_cli/locale *.json
14
14
  include hap_cli/guide/index.json
15
15
  recursive-include hap_cli/guide *.md
16
+
17
+ # Development-only trees stay out of the sdist too (see setup.py _PACKAGES).
18
+ prune hap_cli/tests
19
+ prune live_tests
20
+ prune app_live_tests
21
+ global-exclude __pycache__ *.py[cod]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hap-cli
3
- Version: 0.9.8
3
+ Version: 0.9.10
4
4
  Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
5
5
  Author: hap-cli
6
6
  License: Apache-2.0
@@ -3,7 +3,7 @@
3
3
  import sys as _sys
4
4
  import types as _types
5
5
 
6
- __version__ = "0.9.8"
6
+ __version__ = "0.9.10"
7
7
 
8
8
  # The command tree used to live in hap_cli/hap_cli.py. A module named
9
9
  # after the package it sits in shadows that package: run python with the
@@ -1,6 +1,8 @@
1
1
  """CLI commands for chat and messaging management."""
2
2
 
3
+ import html
3
4
  import json
5
+ import re
4
6
 
5
7
  import click
6
8
 
@@ -73,6 +75,103 @@ def _output_chat_list_table(rows):
73
75
  )
74
76
 
75
77
 
78
+ def _one_line(text: str) -> str:
79
+ """Visible text of a message on one line: tags dropped, entities
80
+ decoded, runs of whitespace collapsed."""
81
+ text = html.unescape(re.sub(r"<[^>]*>", "", text or ""))
82
+ return " ".join(text.split())
83
+
84
+
85
+ def _conversation_preview(msg: dict) -> str:
86
+ body = msg.get("msg") or {}
87
+ text = _one_line(str(body.get("con") or ""))
88
+ files = body.get("files")
89
+ if isinstance(files, dict):
90
+ name = f"{files.get('originalFileName') or ''}{files.get('fileExt') or ''}"
91
+ label = "[image]" if msg.get("type") == 2 else "[file]"
92
+ text = " ".join(x for x in (label, name, text) if x)
93
+ return text
94
+
95
+
96
+ def _output_conversation_table(rows):
97
+ """One row per message of a 1-on-1 or group chat, in the order the
98
+ server returns them (newest first)."""
99
+ output_table(
100
+ [
101
+ {
102
+ "time": str(m.get("time") or "")[:19],
103
+ "from": (m.get("fromAccount") or {}).get("name") or m.get("from", ""),
104
+ "message": _conversation_preview(m),
105
+ "id": m.get("id", ""),
106
+ }
107
+ for m in rows or []
108
+ if isinstance(m, dict)
109
+ ],
110
+ ["time", "from", "message", "id"],
111
+ ["Time", "From", "Message", "Message ID"],
112
+ )
113
+
114
+
115
+ def _output_inbox_table(data):
116
+ rows = (data or {}).get("list") or []
117
+ output_table(
118
+ [
119
+ {
120
+ "time": r.get("createTime", ""),
121
+ "from": (r.get("sender") or {}).get("name")
122
+ or (r.get("app") or {}).get("name", ""),
123
+ "message": _one_line(str(r.get("message") or "")),
124
+ }
125
+ for r in rows
126
+ if isinstance(r, dict)
127
+ ],
128
+ ["time", "from", "message"],
129
+ ["Time", "From", "Message"],
130
+ )
131
+
132
+
133
+ def _output_messages(data):
134
+ if isinstance(data, dict) and "list" in data:
135
+ _output_inbox_table(data)
136
+ else:
137
+ _output_conversation_table(data)
138
+
139
+
140
+ def _output_chat_files(data):
141
+ rows = (data or {}).get("list") or []
142
+ output_table(
143
+ [
144
+ {
145
+ "time": r.get("time", ""),
146
+ "name": r.get("name", ""),
147
+ "size": _file_size(r.get("size")),
148
+ "from": (r.get("createAccount") or {}).get("fullname", ""),
149
+ "fileId": r.get("fileId", ""),
150
+ }
151
+ for r in rows
152
+ if isinstance(r, dict)
153
+ ],
154
+ ["time", "name", "size", "from", "fileId"],
155
+ ["Time", "Name", "Size", "From", "File ID"],
156
+ )
157
+ total = (data or {}).get("allCount")
158
+ if isinstance(total, int) and total > len(rows):
159
+ click.echo(f"Showing {len(rows)} of {total} files. Use -p for the "
160
+ f"next page.", err=True)
161
+
162
+
163
+ def _file_size(value) -> str:
164
+ try:
165
+ size = float(value)
166
+ except (TypeError, ValueError):
167
+ return ""
168
+ for unit in ("B", "KB", "MB", "GB"):
169
+ if size < 1024 or unit == "GB":
170
+ return f"{size:.0f} {unit}" if unit == "B" else f"{size:.1f} {unit}"
171
+ size /= 1024
172
+ return ""
173
+
174
+
76
175
  @click.group(help=t(
77
176
  'Chat and messaging management.\n\n'
78
177
  'To follow a notification back to the app record it belongs to, see '
@@ -97,7 +196,8 @@ def chat_list(ctx, page_size, page):
97
196
 
98
197
 
99
198
  @chat.command("files")
100
- @click.option("--with-user", "with_user", help="Peer accountId for 1-on-1 files")
199
+ @click.option("--account-id", "--with-user", "with_user",
200
+ help="Account id of the person, for the files of your 1-on-1 chat")
101
201
  @click.option("--group-id", "group_id", help="Group id for group chat files")
102
202
  @click.option("--page-size", "-n", default=20, help="Items per page")
103
203
  @click.option("--page", "-p", default=1, help="Page number")
@@ -114,11 +214,11 @@ def chat_list(ctx, page_size, page):
114
214
  def chat_files(ctx, with_user, group_id, page_size, page, keywords, file_type, start, end):
115
215
  """List files shared in a 1-on-1 or group chat.
116
216
 
117
- Provide exactly one of --with-user or --group-id.
217
+ Provide exactly one of --account-id or --group-id.
118
218
  """
119
219
  if bool(with_user) == bool(group_id):
120
220
  ctx.handle_error(click.UsageError(
121
- "Provide exactly one of --with-user or --group-id."
221
+ "Provide exactly one of --account-id or --group-id."
122
222
  ))
123
223
  return
124
224
  try:
@@ -145,13 +245,14 @@ def chat_files(ctx, with_user, group_id, page_size, page, keywords, file_type, s
145
245
  start=start,
146
246
  end=end,
147
247
  )
148
- ctx.output(data, lambda d: output_json(d))
248
+ ctx.output(data, _output_chat_files)
149
249
  except Exception as e:
150
250
  ctx.handle_error(e)
151
251
 
152
252
 
153
253
  @chat.command("messages")
154
- @click.option("--with-user", "with_user", help="Peer accountId for 1-on-1 messages")
254
+ @click.option("--account-id", "--with-user", "with_user",
255
+ help="Account id of the person, for your 1-on-1 chat with them")
155
256
  @click.option("--group-id", "group_id", help="Group id for group chat messages")
156
257
  @click.option(
157
258
  "--category",
@@ -202,7 +303,9 @@ def chat_messages(
202
303
  """Fetch chat message history.
203
304
 
204
305
  Provide exactly one of:
205
- --with-user 1-on-1 chat with a user
306
+
307
+ \b
308
+ --account-id 1-on-1 chat with a person
206
309
  --group-id a group chat
207
310
  --category inbox category (system / post / task / calendar /
208
311
  kc / hr / app / workflow)
@@ -211,7 +314,7 @@ def chat_messages(
211
314
  sources = [bool(with_user), bool(group_id), bool(category), bool(inbox_type)]
212
315
  if sum(sources) != 1:
213
316
  ctx.handle_error(click.UsageError(
214
- "Provide exactly one of --with-user / --group-id / --category / --inbox-type."
317
+ "Provide exactly one of --account-id / --group-id / --category / --inbox-type."
215
318
  ))
216
319
  return
217
320
  try:
@@ -250,13 +353,14 @@ def chat_messages(
250
353
  )
251
354
  if mark_read and category:
252
355
  chat_mod.mark_inbox_read(session, category)
253
- ctx.output(data, lambda d: output_json(d))
356
+ ctx.output(data, _output_messages)
254
357
  except Exception as e:
255
358
  ctx.handle_error(e)
256
359
 
257
360
 
258
361
  @chat.command("send-to-one")
259
- @click.option("--to", "-t", multiple=True, help="Target user account ID (can repeat)")
362
+ @click.option("--account-id", "--to", "-t", "to", multiple=True,
363
+ help="Account id of the person to message (repeatable)")
260
364
  @click.option("--message", "-m", default="", help="Message text")
261
365
  @click.option(
262
366
  "--file", "-f", "files", multiple=True,
@@ -282,7 +386,7 @@ def chat_send_to_one(ctx, to, message, files, dry_run):
282
386
  """
283
387
  if not to:
284
388
  ctx.handle_error(click.UsageError(
285
- "Provide at least one --to <accountId>."
389
+ "Provide at least one --account-id."
286
390
  ))
287
391
  return
288
392
  if not message and not files:
@@ -446,8 +550,9 @@ def chat_card_detail(ctx, task, post, calendar, kcfile, worksheet, worksheetrow)
446
550
  @chat.command("recall")
447
551
  @click.argument("message_id")
448
552
  @click.option("--group-id", "group_id", default="", help="Group id the message is in")
449
- @click.option("--with-user", "with_user", default="",
450
- help="Peer accountId for a 1-on-1 message")
553
+ @click.option("--account-id", "--with-user", "with_user", default="",
554
+ help="Account id of the person, for a message in your 1-on-1 "
555
+ "chat with them")
451
556
  @click.option("--time", "msg_time", default="",
452
557
  help="Send time of the message. Looked up from the conversation "
453
558
  "when omitted.")
@@ -465,7 +570,7 @@ def chat_recall(ctx, message_id, group_id, with_user, msg_time, as_admin, dry_ru
465
570
  cannot be undone.
466
571
  """
467
572
  if bool(group_id) == bool(with_user):
468
- raise click.UsageError("Pass exactly one of --group-id or --with-user.")
573
+ raise click.UsageError("Pass exactly one of --group-id or --account-id.")
469
574
  try:
470
575
  session = ctx.get_session()
471
576
  found = None
@@ -21,6 +21,8 @@ re-implementation on legacy endpoints.
21
21
 
22
22
  from __future__ import annotations
23
23
 
24
+ import logging
25
+
24
26
  import click
25
27
 
26
28
  from hap_cli.commands.app_cmd import app
@@ -34,8 +36,11 @@ from hap_cli.core.v3.render import render_v3_response
34
36
  from hap_cli.core import worksheet as _ws_mod
35
37
  from hap_cli.core import workflow as _wf_mod
36
38
  from hap_cli.core import record_lookups as _lookups
39
+ from hap_cli.core import record_discussions as _discussions
37
40
  from hap_cli.i18n import t
38
41
 
42
+ _logger = logging.getLogger("hap_cli.record")
43
+
39
44
 
40
45
  def _drop(group, *names):
41
46
  """Remove legacy commands from a Click group before re-registering.
@@ -324,7 +329,42 @@ register_v3(record, "get", tool="get_record_details", subtable_guard=True)
324
329
  # (record_cmd.py) — not V3.
325
330
  register_v3(record, "delete", tool="batch_delete_records", # multi-id via batch
326
331
  confirm="Delete the selected record(s) from worksheet {worksheet_id}?")
327
- register_v3(record, "discussions", tool="get_record_discussions")
332
+ def _record_discussions_mentions(ctx, response, options):
333
+ """Show mentions as @name, in both the JSON and the md form.
334
+
335
+ How the two forms differ, and why md may cost a second read, is in
336
+ ``hap_cli.core.record_discussions``."""
337
+ payload = response.get("data") if isinstance(response, dict) else None
338
+ if not isinstance(payload, dict):
339
+ return response
340
+ discussions = payload.get("discussions")
341
+ if isinstance(discussions, list):
342
+ _discussions.render_json(discussions)
343
+ return response
344
+ if not isinstance(discussions, str):
345
+ return response
346
+ names = _discussions.names_from_md(discussions)
347
+ if any(i not in names for i in _discussions.mentioned_ids(discussions)):
348
+ params = click.get_current_context().params
349
+ query = {
350
+ "pageIndex": params.get("page_index"),
351
+ "pageSize": params.get("page_size"),
352
+ "search": params.get("search"),
353
+ "onlyWithAttachments": params.get("only_with_attachments"),
354
+ }
355
+ try:
356
+ names.update(_discussions.fetch_names(
357
+ ctx.get_session(), params.get("worksheet_id") or "",
358
+ params.get("row_id") or "", app_id=_resolve_list_app_id(ctx),
359
+ query={k: v for k, v in query.items() if v not in (None, "")}))
360
+ except Exception as exc:
361
+ _logger.warning("Could not look up mentioned names: %s", exc)
362
+ payload["discussions"] = _discussions.render_md(discussions, names)
363
+ return response
364
+
365
+
366
+ register_v3(record, "discussions", tool="get_record_discussions",
367
+ post_process=_record_discussions_mentions)
328
368
  register_v3(record, "logs", tool="get_record_logs")
329
369
  register_v3(record, "relations", tool="get_record_relations")
330
370
  register_v3(record, "pivot", tool="get_record_pivot_data",
@@ -0,0 +1,137 @@
1
+ """Readable record discussions: mention markers rendered as ``@name``.
2
+
3
+ A discussion stores its mentions inside the text: ``[aid]<accountId>[/aid]``
4
+ per person (external portal users have ids like ``a#6805…``) and
5
+ ``[all]atAll[/all]`` for everyone. The web renders them through
6
+ ``createLinksForMessage`` (MDPublic src/components/comment/utils/
7
+ createLinksForMessage.js:86-109): a person becomes ``@<name>`` and the
8
+ everyone marker becomes ``@`` + AT_ALL_TEXT[WORKSHEETROW] = "全体参与者"
9
+ (src/components/comment/config.js:22). An id it cannot name stays as-is.
10
+
11
+ The V3 discussions endpoint answers JSON with a ``mentions`` list that
12
+ names every ``[aid]`` in the message, so the JSON form is rendered from
13
+ the response alone. Its ``md`` form drops that list and writes each author
14
+ as ``{"AccountId":…,"FullNmae":…}`` (sic — a server-side typo), so the md
15
+ form is rendered from a name map the caller supplies.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import re
22
+ from typing import Any, Iterable
23
+
24
+ AT_ALL_TEXT = "全体参与者"
25
+
26
+ _AID_RE = re.compile(r"\[aid\]([^\[\]]+?)\[/aid\]")
27
+ _ALL_RE = re.compile(r"\[all\]atAll\[/all\]", re.IGNORECASE)
28
+ # One author as the md form writes it; tolerant of the server ever fixing
29
+ # the misspelt key.
30
+ _MD_AUTHOR_RE = re.compile(
31
+ r'\{"AccountId":"([^"]*)","(?:FullNmae|FullName)":"((?:[^"\\]|\\.)*)"\}')
32
+
33
+
34
+ def render_markers(text: str, names: dict[str, str]) -> str:
35
+ """Replace mention markers with ``@name``; unknown ids stay visible."""
36
+ if not text:
37
+ return text or ""
38
+
39
+ def _person(m: re.Match) -> str:
40
+ name = names.get(m.group(1).strip())
41
+ return f"@{name}" if name else m.group(0)
42
+
43
+ return _AID_RE.sub(_person, _ALL_RE.sub(f"@{AT_ALL_TEXT}", text))
44
+
45
+
46
+ def mentioned_ids(text: str) -> list[str]:
47
+ seen: list[str] = []
48
+ for aid in _AID_RE.findall(text or ""):
49
+ aid = aid.strip()
50
+ if aid not in seen:
51
+ seen.append(aid)
52
+ return seen
53
+
54
+
55
+ def _people(item: dict) -> Iterable[dict]:
56
+ for key in ("_createdBy", "replyToAuthor"):
57
+ if isinstance(item.get(key), dict):
58
+ yield item[key]
59
+ for person in item.get("mentions") or []:
60
+ if isinstance(person, dict):
61
+ yield person
62
+
63
+
64
+ def names_from_json(discussions: Any) -> dict[str, str]:
65
+ """Account id → name from every author, reply target and mention."""
66
+ names: dict[str, str] = {}
67
+ for item in discussions or []:
68
+ if not isinstance(item, dict):
69
+ continue
70
+ for person in _people(item):
71
+ aid = person.get("accountId")
72
+ name = person.get("fullname") or person.get("name")
73
+ if aid and name:
74
+ names[aid] = name
75
+ return names
76
+
77
+
78
+ def render_json(discussions: Any) -> Any:
79
+ """Render each discussion's ``message`` in place.
80
+
81
+ The stored text moves to ``rawMessage``; ``mentionsEveryone`` is set
82
+ when the message mentions everyone. The server's ``mentions`` list
83
+ (id and name of each person mentioned) is left as it is."""
84
+ if not isinstance(discussions, list):
85
+ return discussions
86
+ names = names_from_json(discussions)
87
+ for item in discussions:
88
+ if not isinstance(item, dict) or not isinstance(item.get("message"), str):
89
+ continue
90
+ raw = item["message"]
91
+ rendered = render_markers(raw, names)
92
+ if rendered != raw:
93
+ item["rawMessage"] = raw
94
+ item["message"] = rendered
95
+ if _ALL_RE.search(raw):
96
+ item["mentionsEveryone"] = True
97
+ return discussions
98
+
99
+
100
+ def names_from_md(text: str) -> dict[str, str]:
101
+ names: dict[str, str] = {}
102
+ for aid, name in _MD_AUTHOR_RE.findall(text or ""):
103
+ if aid and name:
104
+ names[aid] = _unescape(name)
105
+ return names
106
+
107
+
108
+ def _unescape(value: str) -> str:
109
+ try:
110
+ return json.loads(f'"{value}"')
111
+ except ValueError:
112
+ return value
113
+
114
+
115
+ def render_md(text: str, names: dict[str, str]) -> str:
116
+ """Write authors as plain names and mentions as ``@name``."""
117
+ if not isinstance(text, str):
118
+ return text
119
+ text = _MD_AUTHOR_RE.sub(lambda m: _unescape(m.group(2)), text)
120
+ return render_markers(text, names)
121
+
122
+
123
+ DISCUSSIONS_PATH = "/v3/app/worksheets/{worksheet_id}/rows/{row_id}/discussions"
124
+
125
+
126
+ def fetch_names(
127
+ session: Any, worksheet_id: str, row_id: str, *, app_id: str,
128
+ query: dict[str, Any],
129
+ ) -> dict[str, str]:
130
+ """Names for the md form: the same page asked for again as JSON, whose
131
+ ``mentions`` list names everyone the md text only gives ids for."""
132
+ params = dict(query, responseFormat="json")
133
+ response = session.v3_call(
134
+ "GET", DISCUSSIONS_PATH, app_id=app_id, query=params,
135
+ path_params={"worksheet_id": worksheet_id, "row_id": row_id})
136
+ data = response.get("data") if isinstance(response, dict) else None
137
+ return names_from_json((data or {}).get("discussions"))
@@ -28,7 +28,7 @@ import re
28
28
  import time
29
29
  from datetime import datetime, timezone
30
30
  from typing import Any, Callable, Optional
31
- from urllib.parse import parse_qs, quote, urlparse
31
+ from urllib.parse import parse_qs, quote, unquote, urlparse
32
32
 
33
33
  import requests
34
34
 
@@ -267,6 +267,17 @@ def _encode_original_name(stem: str) -> str:
267
267
  return quote(stem, safe="")
268
268
 
269
269
 
270
+ def _decode_original_name(echoed: Any, fallback: str) -> str:
271
+ """The store echoes ``x:originalFileName`` exactly as posted — still
272
+ percent-encoded — and the uploader decodes it before handing the file
273
+ on (MDPublic createUploader.js:452). Passing the echo through as-is
274
+ left names like "HDP-%E5%B9%BF%E5%91%8A40s" on posts, chat files and
275
+ record attachments."""
276
+ if not echoed:
277
+ return fallback
278
+ return unquote(str(echoed))
279
+
280
+
270
281
  def _name_and_ext(source: str, *, name: str = "") -> tuple[str, str]:
271
282
  """Derive (originalName-without-ext, ext-with-dot) from a name or path/url.
272
283
 
@@ -368,7 +379,7 @@ def upload_bytes(
368
379
  "filePath": up.get("filePath"),
369
380
  "fileName": up.get("fileName"),
370
381
  "fileExt": up.get("fileExt"),
371
- "originalFileName": up.get("originalFileName"),
382
+ "originalFileName": _decode_original_name(up.get("originalFileName"), original),
372
383
  "key": up.get("key") or token.get("key"),
373
384
  "url": token.get("url"),
374
385
  # The signed URL above stops working at this instant — see
@@ -30,7 +30,7 @@ hap --json chat messages --category app # or workflow, etc.
30
30
  with `viewId`, `comment.recordName` and `comment.entityName`.
31
31
  - Workflow **cc / participant** notifications have the `appId` / `worksheetId` / `rowId`
32
32
  resolved out of the record link for you.
33
- - One-to-one and group chats do not use `--category`; use `--with-user <accountId>` or
33
+ - One-to-one and group chats do not use `--category`; use `--account-id <accountId>` or
34
34
  `--group-id <groupId>` (the id is the conversation's `value`).
35
35
 
36
36
  **3. Read the record and its discussion**
@@ -29,7 +29,7 @@ hap --json chat messages --category app # 或 workflow 等
29
29
  `comment.recordName`、`comment.entityName`。
30
30
  - 工作流**抄送 / 参与者**类通知会把记录链接里的 `appId` / `worksheetId` / `rowId`
31
31
  一并解析出来。
32
- - 单聊 / 群聊不走 `--category`,用 `--with-user <accountId>` 或 `--group-id <groupId>`
32
+ - 单聊 / 群聊不走 `--category`,用 `--account-id <accountId>` 或 `--group-id <groupId>`
33
33
  (id 取会话的 `value`)。
34
34
 
35
35
  **3. 拿三元组直接读记录和讨论**
@@ -3015,6 +3015,30 @@
3015
3015
  "en": "Output in JSON format",
3016
3016
  "zh-Hans": "以 JSON 格式输出"
3017
3017
  },
3018
+ "attachment download": {
3019
+ "en": "Download a file attached to a worksheet record.\n\nFILE_ID is listed in an attachment field or a record operation log.\nExisting local files are never overwritten.",
3020
+ "zh-Hans": "下载工作表记录里的附件。\n\nFILE_ID 可以在附件字段或记录操作日志中找到。不会覆盖本地已有的文件。"
3021
+ },
3022
+ "attachment download --control-id": {
3023
+ "en": "Attachment field containing the file.",
3024
+ "zh-Hans": "附件所在的附件字段。"
3025
+ },
3026
+ "attachment download --json": {
3027
+ "en": "Output in JSON format",
3028
+ "zh-Hans": "以 JSON 格式输出"
3029
+ },
3030
+ "attachment download --output": {
3031
+ "en": "Save as this path. By default, uses the attachment name.",
3032
+ "zh-Hans": "保存到此路径。默认使用附件原名。"
3033
+ },
3034
+ "attachment download --row-id": {
3035
+ "en": "Record containing the attachment.",
3036
+ "zh-Hans": "附件所在的记录。"
3037
+ },
3038
+ "attachment download --worksheet-id": {
3039
+ "en": "Worksheet containing the record.",
3040
+ "zh-Hans": "记录所在的工作表。"
3041
+ },
3018
3042
  "attachment share": {
3019
3043
  "en": "Create a link to a stored file that you can pass on.\n\n\b\n hap attachment share https://doc.example.com/doc/20260830/abc.html\n hap attachment share doc/20260830/abc.html --hours 168\n hap attachment share --file-id <id>\n\nADDRESS is the file's link — a link that has already stopped working\nis fine, paste it as-is — or just the path part of it.",
3020
3044
  "zh-Hans": "为已存储的文件创建可转发的链接。\n\n\b\n hap attachment share https://doc.example.com/doc/20260830/abc.html\n hap attachment share doc/20260830/abc.html --hours 168\n hap attachment share --file-id <id>\n\nADDRESS 是文件的链接——已经失效的链接也可以,原样粘贴即可——或者只传链接中的路径部分。"
@@ -3432,8 +3456,12 @@
3432
3456
  "zh-Hans": "工作表记录,格式 'wsId>rowId',以 '|' 分隔"
3433
3457
  },
3434
3458
  "chat files": {
3435
- "en": "List files shared in a 1-on-1 or group chat.\n\nProvide exactly one of --with-user or --group-id.",
3436
- "zh-Hans": "列出单聊或群聊中共享的文件。\n\n--with-user 与 --group-id 必须且只能提供一个"
3459
+ "en": "List files shared in a 1-on-1 or group chat.\n\nProvide exactly one of --account-id or --group-id.",
3460
+ "zh-Hans": "列出单聊或群聊中共享的文件。\n\n--account-id 与 --group-id 必须且只能提供一个。"
3461
+ },
3462
+ "chat files --account-id": {
3463
+ "en": "Account id of the person, for the files of your 1-on-1 chat",
3464
+ "zh-Hans": "对方的账号 ID,列出你和此人单聊中的文件"
3437
3465
  },
3438
3466
  "chat files --end": {
3439
3467
  "en": "End timestamp (inclusive)",
@@ -3467,10 +3495,6 @@
3467
3495
  "en": "Start timestamp (inclusive)",
3468
3496
  "zh-Hans": "开始时间戳(含)"
3469
3497
  },
3470
- "chat files --with-user": {
3471
- "en": "Peer accountId for 1-on-1 files",
3472
- "zh-Hans": "单聊文件的对方 accountId"
3473
- },
3474
3498
  "chat list": {
3475
3499
  "en": "List recent chat sessions.",
3476
3500
  "zh-Hans": "列出最近的聊天会话"
@@ -3488,8 +3512,12 @@
3488
3512
  "zh-Hans": "每页条数"
3489
3513
  },
3490
3514
  "chat messages": {
3491
- "en": "Fetch chat message history.\n\nProvide exactly one of:\n --with-user 1-on-1 chat with a user\n --group-id a group chat\n --category inbox category (system / post / task / calendar /\n kc / hr / app / workflow)\n --inbox-type raw inbox type code for advanced filters",
3492
- "zh-Hans": "获取聊天消息历史。\n\n以下选项必须且只能提供一个:\n --with-user 与某用户的单聊\n --group-id 群聊\n --category 收件箱分类(system / post / task / calendar /\n kc / hr / app / workflow)\n --inbox-type 原始收件箱类型代码,用于高级筛选"
3515
+ "en": "Fetch chat message history.\n\nProvide exactly one of:\n\n\b\n --account-id 1-on-1 chat with a person\n --group-id a group chat\n --category inbox category (system / post / task / calendar /\n kc / hr / app / workflow)\n --inbox-type raw inbox type code for advanced filters",
3516
+ "zh-Hans": "获取聊天消息历史。\n\n以下选项必须且只能提供一个:\n\n\b\n --account-id 与某人的单聊\n --group-id 群聊\n --category 收件箱分类(system / post / task / calendar /\n kc / hr / app / workflow)\n --inbox-type 原始收件箱类型代码,用于高级筛选"
3517
+ },
3518
+ "chat messages --account-id": {
3519
+ "en": "Account id of the person, for your 1-on-1 chat with them",
3520
+ "zh-Hans": "对方的账号 ID,查看你和此人的单聊"
3493
3521
  },
3494
3522
  "chat messages --category": {
3495
3523
  "en": "Inbox category: system, post, task, calendar, kc, hr, app, workflow",
@@ -3531,14 +3559,14 @@
3531
3559
  "en": "Anchor timestamp, e.g. '2026-04-07 19:06:53.038' (paginate around this)",
3532
3560
  "zh-Hans": "锚点时间戳,例如 '2026-04-07 19:06:53.038'(以此为基准分页)"
3533
3561
  },
3534
- "chat messages --with-user": {
3535
- "en": "Peer accountId for 1-on-1 messages",
3536
- "zh-Hans": "单聊消息的对方 accountId"
3537
- },
3538
3562
  "chat recall": {
3539
3563
  "en": "Recall a message you sent.\n\nYou can recall your own message within 5 minutes of sending it; a group\nadmin can recall another member's message with no time limit. A recall\ncannot be undone.",
3540
3564
  "zh-Hans": "撤回自己发送的消息。自己的消息限发送后 5 分钟内撤回;群管理员撤回其他成员的消息不限时间。撤回后无法恢复。"
3541
3565
  },
3566
+ "chat recall --account-id": {
3567
+ "en": "Account id of the person, for a message in your 1-on-1 chat with them",
3568
+ "zh-Hans": "对方的账号 ID,撤回你和此人单聊中的消息"
3569
+ },
3542
3570
  "chat recall --as-admin": {
3543
3571
  "en": "Recall as a group admin. Admins may recall another member's message; ordinary recall only covers your own.",
3544
3572
  "zh-Hans": "以群管理员身份撤回。管理员可撤回其他成员的消息;普通撤回只能撤回自己的。"
@@ -3559,10 +3587,6 @@
3559
3587
  "en": "Send time of the message. Looked up from the conversation when omitted.",
3560
3588
  "zh-Hans": "消息的发送时间。省略时自动从会话记录中查找。"
3561
3589
  },
3562
- "chat recall --with-user": {
3563
- "en": "Peer accountId for a 1-on-1 message",
3564
- "zh-Hans": "单聊消息的对方 accountId"
3565
- },
3566
3590
  "chat send-to-group": {
3567
3591
  "en": "Send a message, optionally with files, to a group chat.\n\n\b\n hap chat send-to-group -g <groupId> -m \"spec attached\" -f ./spec.pdf\n\nText and each file arrive as separate messages, in that order. An\n@-mention applies to the text line, so it needs --message.",
3568
3592
  "zh-Hans": "向群聊发送消息,可附带文件。\n\n\b\n hap chat send-to-group -g <groupId> -m \"spec attached\" -f ./spec.pdf\n\n文本和每个文件会依次作为独立消息送达。@提及作用于文本行,因此需要 --message"
@@ -3599,6 +3623,10 @@
3599
3623
  "en": "Send a message, optionally with files, to one or more users (1-on-1).\n\n\b\n hap chat send-to-one -t <accountId> -m \"spec attached\" -f ./spec.pdf\n\nText and each file arrive as separate messages, in that order.\n\nTo message yourself, send to the file-transfer assistant with\n-t file-transfer. Your own account id is not a valid target.",
3600
3624
  "zh-Hans": "向一个或多个用户发送消息(单聊),可附带文件。\n\n hap chat send-to-one -t <accountId> -m \"spec attached\" -f ./spec.pdf\n\n文本和每个文件会依次作为独立消息送达。\n\n给自己发消息请发到文件传输助手:-t file-transfer。自己的账号 ID 不是有效目标。"
3601
3625
  },
3626
+ "chat send-to-one --account-id": {
3627
+ "en": "Account id of the person to message (repeatable)",
3628
+ "zh-Hans": "接收消息的人的账号 ID(可重复)"
3629
+ },
3602
3630
  "chat send-to-one --dry-run": {
3603
3631
  "en": "Show what would be sent, without uploading or sending anything.",
3604
3632
  "zh-Hans": "仅显示将要发送的内容,不上传也不发送"
@@ -3615,10 +3643,6 @@
3615
3643
  "en": "Message text",
3616
3644
  "zh-Hans": "消息文本"
3617
3645
  },
3618
- "chat send-to-one --to": {
3619
- "en": "Target user account ID (can repeat)",
3620
- "zh-Hans": "目标用户账号 ID(可重复)"
3621
- },
3622
3646
  "completion": {
3623
3647
  "en": "Alias of `hap config completion`.",
3624
3648
  "zh-Hans": "`hap config completion` 的别名"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hap-cli
3
- Version: 0.9.8
3
+ Version: 0.9.10
4
4
  Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
5
5
  Author: hap-cli
6
6
  License: Apache-2.0