hap-cli 0.8.22__tar.gz → 0.8.23__tar.gz

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