hap-cli 0.5.0__py3-none-any.whl

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 (58) hide show
  1. hap_cli/README.md +194 -0
  2. hap_cli/README_CN.md +601 -0
  3. hap_cli/__init__.py +3 -0
  4. hap_cli/commands/__init__.py +1 -0
  5. hap_cli/commands/ai_cmd.py +224 -0
  6. hap_cli/commands/app_cmd.py +308 -0
  7. hap_cli/commands/calendar_cmd.py +138 -0
  8. hap_cli/commands/chat_cmd.py +101 -0
  9. hap_cli/commands/config_cmd.py +169 -0
  10. hap_cli/commands/contact_cmd.py +125 -0
  11. hap_cli/commands/department_cmd.py +168 -0
  12. hap_cli/commands/group_cmd.py +128 -0
  13. hap_cli/commands/instance_cmd.py +310 -0
  14. hap_cli/commands/node_cmd.py +538 -0
  15. hap_cli/commands/optionset_cmd.py +99 -0
  16. hap_cli/commands/page_cmd.py +102 -0
  17. hap_cli/commands/plugin_cmd.py +133 -0
  18. hap_cli/commands/post_cmd.py +155 -0
  19. hap_cli/commands/record_cmd.py +228 -0
  20. hap_cli/commands/role_cmd.py +221 -0
  21. hap_cli/commands/workflow_cmd.py +284 -0
  22. hap_cli/commands/worksheet_cmd.py +342 -0
  23. hap_cli/context.py +43 -0
  24. hap_cli/core/__init__.py +1 -0
  25. hap_cli/core/ai.py +133 -0
  26. hap_cli/core/app.py +307 -0
  27. hap_cli/core/auth.py +219 -0
  28. hap_cli/core/calendar_mod.py +114 -0
  29. hap_cli/core/chat.py +73 -0
  30. hap_cli/core/contact.py +85 -0
  31. hap_cli/core/department.py +131 -0
  32. hap_cli/core/flow_node.py +1001 -0
  33. hap_cli/core/group.py +99 -0
  34. hap_cli/core/instance.py +572 -0
  35. hap_cli/core/optionset.py +112 -0
  36. hap_cli/core/page.py +138 -0
  37. hap_cli/core/plugin.py +87 -0
  38. hap_cli/core/post.py +118 -0
  39. hap_cli/core/record.py +268 -0
  40. hap_cli/core/role.py +227 -0
  41. hap_cli/core/session.py +348 -0
  42. hap_cli/core/workflow.py +556 -0
  43. hap_cli/core/worksheet.py +403 -0
  44. hap_cli/hap_cli.py +105 -0
  45. hap_cli/skills/SKILL.md +383 -0
  46. hap_cli/skills/__init__.py +0 -0
  47. hap_cli/tests/__init__.py +1 -0
  48. hap_cli/tests/test_core.py +1824 -0
  49. hap_cli/tests/test_full_e2e.py +136 -0
  50. hap_cli/tests/test_integration.py +805 -0
  51. hap_cli/utils/__init__.py +1 -0
  52. hap_cli/utils/formatting.py +111 -0
  53. hap_cli/utils/options.py +10 -0
  54. hap_cli-0.5.0.dist-info/METADATA +223 -0
  55. hap_cli-0.5.0.dist-info/RECORD +58 -0
  56. hap_cli-0.5.0.dist-info/WHEEL +5 -0
  57. hap_cli-0.5.0.dist-info/entry_points.txt +2 -0
  58. hap_cli-0.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ """Utility modules for hap-cli harness."""
@@ -0,0 +1,111 @@
1
+ """Output formatting utilities for hap-cli."""
2
+
3
+ import json
4
+ import sys
5
+ from typing import Any
6
+
7
+
8
+ def output_json(data: Any) -> None:
9
+ """Print data as formatted JSON."""
10
+ print(json.dumps(data, indent=2, ensure_ascii=False, default=str))
11
+
12
+
13
+ def output_table(rows: list[dict], columns: list[str], headers: list[str] = None) -> None:
14
+ """Print data as a formatted table.
15
+
16
+ Args:
17
+ rows: List of row dicts
18
+ columns: Keys to extract from each row
19
+ headers: Display headers (defaults to column names)
20
+ """
21
+ if headers is None:
22
+ headers = columns
23
+
24
+ if not rows:
25
+ print("(no data)")
26
+ return
27
+
28
+ # Calculate column widths
29
+ col_widths = [len(h) for h in headers]
30
+ str_rows = []
31
+ for row in rows:
32
+ str_row = [str(row.get(col, "")) for col in columns]
33
+ for i, val in enumerate(str_row):
34
+ # Truncate long values
35
+ if len(val) > 60:
36
+ val = val[:57] + "..."
37
+ str_row[i] = val
38
+ col_widths[i] = max(col_widths[i], len(val))
39
+ str_rows.append(str_row)
40
+
41
+ # Print header
42
+ header_line = " ".join(h.ljust(col_widths[i]) for i, h in enumerate(headers))
43
+ print(header_line)
44
+ print(" ".join("-" * w for w in col_widths))
45
+
46
+ # Print rows
47
+ for str_row in str_rows:
48
+ line = " ".join(val.ljust(col_widths[i]) for i, val in enumerate(str_row))
49
+ print(line)
50
+
51
+
52
+ def output_kv(data: dict, keys: list[str] = None, labels: dict[str, str] = None) -> None:
53
+ """Print key-value pairs.
54
+
55
+ Args:
56
+ data: Data dict
57
+ keys: Keys to display (defaults to all)
58
+ labels: Display labels for keys
59
+ """
60
+ if keys is None:
61
+ keys = list(data.keys())
62
+ if labels is None:
63
+ labels = {}
64
+
65
+ max_label_len = max(len(labels.get(k, k)) for k in keys) if keys else 0
66
+
67
+ for key in keys:
68
+ label = labels.get(key, key)
69
+ value = data.get(key, "")
70
+ if isinstance(value, (dict, list)):
71
+ value = json.dumps(value, ensure_ascii=False, default=str)
72
+ print(f" {label.ljust(max_label_len)} {value}")
73
+
74
+
75
+ def format_record_row(record: dict, controls: list[dict] = None) -> dict:
76
+ """Format a record row for display.
77
+
78
+ Args:
79
+ record: Raw record data
80
+ controls: Control definitions for field name mapping
81
+
82
+ Returns:
83
+ Formatted dict with field names as keys
84
+ """
85
+ control_map = {}
86
+ if controls:
87
+ for ctrl in controls:
88
+ cid = ctrl.get("controlId", "")
89
+ name = ctrl.get("controlName", cid)
90
+ control_map[cid] = name
91
+
92
+ formatted = {"rowId": record.get("rowid", record.get("rowId", ""))}
93
+
94
+ # Process cell values
95
+ for key, value in record.items():
96
+ if key in ("rowid", "rowId", "allowedit", "allowdelete"):
97
+ continue
98
+ display_key = control_map.get(key, key)
99
+ if isinstance(value, str) and value.startswith("["):
100
+ try:
101
+ parsed = json.loads(value)
102
+ if isinstance(parsed, list) and parsed:
103
+ if isinstance(parsed[0], dict) and "name" in parsed[0]:
104
+ value = ", ".join(item.get("name", "") for item in parsed)
105
+ elif isinstance(parsed[0], dict) and "fullname" in parsed[0]:
106
+ value = ", ".join(item.get("fullname", "") for item in parsed)
107
+ except (json.JSONDecodeError, IndexError):
108
+ pass
109
+ formatted[display_key] = value
110
+
111
+ return formatted
@@ -0,0 +1,10 @@
1
+ """Reusable Click option decorators for hap-cli."""
2
+
3
+ import click
4
+
5
+
6
+ def pagination_options(f):
7
+ """Add --page-size and --page options to a command."""
8
+ f = click.option("--page-size", "-n", default=20, help="Items per page")(f)
9
+ f = click.option("--page", "-p", default=1, help="Page number")(f)
10
+ return f
@@ -0,0 +1,223 @@
1
+ Metadata-Version: 2.4
2
+ Name: hap-cli
3
+ Version: 0.5.0
4
+ Summary: CLI harness for MingDAO HAP - Enterprise no-code platform
5
+ Author: hap-cli
6
+ License: Apache-2.0
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: click>=8.0
17
+ Requires-Dist: requests>=2.28
18
+ Provides-Extra: crypto
19
+ Requires-Dist: pycryptodome>=3.15; extra == "crypto"
20
+ Dynamic: author
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: license
25
+ Dynamic: provides-extra
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ # hap-cli
31
+
32
+ CLI harness for **MingDAO HAP** (明道云) - an enterprise no-code platform (hap).
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install -e .
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ### 1. Login
43
+
44
+ **Option A: Browser login (recommended)**
45
+
46
+ ```bash
47
+ # MingDAO SaaS (default)
48
+ hap config login
49
+
50
+ # Specify server
51
+ hap config login mingdao # MingDAO
52
+ hap config login nocoly # Nocoly
53
+ hap config login https://hap.example.com # Self-hosted
54
+ ```
55
+
56
+ Opens your browser to the MingDAO login page. Token is saved automatically after login.
57
+
58
+ **Option B: Manual token**
59
+
60
+ ```bash
61
+ hap config set \
62
+ --server https://your-mingdao-server.com \
63
+ --token YOUR_MD_PSS_ID_TOKEN \
64
+ --app-id YOUR_DEFAULT_APP_ID \
65
+ --project-id YOUR_PROJECT_ID
66
+ ```
67
+
68
+ **Other auth commands**
69
+
70
+ ```bash
71
+ hap config whoami # Show current user info
72
+ hap config logout # Clear saved token
73
+ ```
74
+
75
+ ### 2. List worksheets
76
+
77
+ ```bash
78
+ hap app worksheets
79
+ ```
80
+
81
+ ### 3. Query records
82
+
83
+ ```bash
84
+ hap record list WORKSHEET_ID --page-size 10
85
+ ```
86
+
87
+ ### 4. JSON output (for automation)
88
+
89
+ ```bash
90
+ hap --json record list WORKSHEET_ID
91
+ ```
92
+
93
+ ## Command Groups
94
+
95
+ | Group | Description |
96
+ |-------|-------------|
97
+ | `config` | Server connection and auth |
98
+ | `app` | Application management |
99
+ | `worksheet` | Worksheet info, fields, views |
100
+ | `record` | Record CRUD (list, get, create, update, delete) |
101
+ | `workflow` | Process lifecycle (create, update, publish, trigger, rollback, config) |
102
+ | `node` | Node management (add, delete, save config, test code/webhook/AI) |
103
+ | `instance` | Approval & todo (approve, reject, forward, sign, batch, history) |
104
+ | `role` | Role management and members |
105
+ | `repl` | Interactive REPL mode |
106
+
107
+ ## Workflow Management
108
+
109
+ ```bash
110
+ # Create a workflow
111
+ hap workflow create --company-id CID --name "My Flow" --app-id APP_ID
112
+
113
+ # Add an approval node
114
+ hap node add PROCESS_ID --type 4 --name "Manager Approval"
115
+
116
+ # Configure the node
117
+ hap node save PROCESS_ID NODE_ID --type 4 --config '{"accounts":[...]}'
118
+
119
+ # Test a code node
120
+ hap node test-code PROCESS_ID NODE_ID --code "return 1+1"
121
+
122
+ # Test a webhook node
123
+ hap node test-webhook PROCESS_ID NODE_ID --url https://api.example.com
124
+
125
+ # Publish the workflow
126
+ hap workflow publish PROCESS_ID
127
+
128
+ # Trigger it
129
+ hap workflow trigger PROCESS_ID --source-id ROW_ID
130
+
131
+ # Check version history
132
+ hap workflow history PROCESS_ID
133
+
134
+ # Rollback to previous version
135
+ hap workflow rollback PROCESS_ID
136
+
137
+ # Get/set global config
138
+ hap workflow config-get PROCESS_ID
139
+ hap workflow config-set PROCESS_ID --config '{"allowRevoke":true}'
140
+ ```
141
+
142
+ ## Approval & Todo
143
+
144
+ ```bash
145
+ # Check pending task count
146
+ hap instance todo-count
147
+
148
+ # List pending approval tasks
149
+ hap instance todo --type 4
150
+
151
+ # View instance detail
152
+ hap instance get INSTANCE_ID
153
+
154
+ # Approve
155
+ hap instance approve INSTANCE_ID --opinion "Looks good"
156
+
157
+ # Reject with reason
158
+ hap instance reject INSTANCE_ID --opinion "Need revision"
159
+
160
+ # Forward to another user
161
+ hap instance forward INSTANCE_ID --to USER_ID
162
+
163
+ # Add co-signer
164
+ hap instance sign INSTANCE_ID --to USER_ID --before
165
+
166
+ # Batch approve
167
+ hap instance batch --action 4 -s ID1 -s ID2
168
+
169
+ # View execution history
170
+ hap instance history --process-id PROCESS_ID --status 2
171
+ ```
172
+
173
+ ## REPL Mode
174
+
175
+ ```bash
176
+ hap repl
177
+ hap> record list WORKSHEET_ID
178
+ hap> --json workflow list APP_ID
179
+ hap> instance todo-count
180
+ hap> quit
181
+ ```
182
+
183
+ ## API Authentication
184
+
185
+ The CLI uses MingDAO's `md_pss_id` session token. Use `hap config login` for
186
+ browser-based login, or `hap config set --token TOKEN` to set the token manually.
187
+
188
+ For private deployments with encrypted API responses, install crypto support:
189
+
190
+ ```bash
191
+ pip install hap-cli[crypto]
192
+ ```
193
+
194
+ ## More Examples
195
+
196
+ ```bash
197
+ # List apps
198
+ hap app list --project-id PROJECT_ID
199
+
200
+ # Get worksheet fields
201
+ hap worksheet fields WORKSHEET_ID
202
+
203
+ # Create a record
204
+ hap record create WORKSHEET_ID -f "c001=value1" -f "c002=value2"
205
+
206
+ # Copy a workflow
207
+ hap workflow copy PROCESS_ID --name "Copy of Flow"
208
+
209
+ # Move workflow to another app
210
+ hap workflow move PROCESS_ID TARGET_APP_ID
211
+
212
+ # List code templates
213
+ hap node code-templates --keyword "email"
214
+
215
+ # Test AI node
216
+ hap node test-ai PROCESS_ID NODE_ID --prompt "Summarize this" --model gpt-4
217
+
218
+ # Terminate a stuck instance
219
+ hap instance terminate INSTANCE_ID --yes
220
+
221
+ # Retry a failed instance
222
+ hap instance retry INSTANCE_ID
223
+ ```
@@ -0,0 +1,58 @@
1
+ hap_cli/README.md,sha256=ZNa1jS9V3Ogrbf-Cj3xq_1pPfajvDwp_bzJ7P6RWQ1k,4198
2
+ hap_cli/README_CN.md,sha256=ESKOGO1MKZYuY0nqCxVxZXx-GG4lDzOX83XUi9k15I4,16480
3
+ hap_cli/__init__.py,sha256=MqGiKri5mDb4ODM1qGzSqZLC4zXW3ySkw12CfXM2Jhc,68
4
+ hap_cli/context.py,sha256=KobmgGmFfz_rD6I8Vwc-vsOXz8OzxE2fh9N4knTVn8o,1101
5
+ hap_cli/hap_cli.py,sha256=ybEVAUxuml5jRmIkekm0rTJCz40GQtOqpB2Z1zFB75c,2781
6
+ hap_cli/commands/__init__.py,sha256=C4DTfkxROfw3HteqEF1ILMTZqdlqKueWSFYdViszbuk,39
7
+ hap_cli/commands/ai_cmd.py,sha256=PkFyeeXFnO2IIoFvMBJy4GekdWCYQXSO_h5xpLAqnks,7883
8
+ hap_cli/commands/app_cmd.py,sha256=9kb3F4H62C8mBKSgISGLSgx5_GaZdmT5JW1oMqXsYaA,10638
9
+ hap_cli/commands/calendar_cmd.py,sha256=IHqhHM5k8SzWBT8sezuk_8_8AHpFdYvbmFLo25yTt1U,4739
10
+ hap_cli/commands/chat_cmd.py,sha256=nbSmfD_MjgiDV3_repPVwTKoIUPg7FIXXX_YZgOzhqY,3211
11
+ hap_cli/commands/config_cmd.py,sha256=PJWm3Fo8_dMDjKMbNz-uMaID6MaObrOilCs_BgR49G8,5334
12
+ hap_cli/commands/contact_cmd.py,sha256=jMFbMUm2DCIPkCTLX-GpZgqOEB3xr5P4Syr77lFqhbg,4050
13
+ hap_cli/commands/department_cmd.py,sha256=vrcZaqsHqAYMeLK_X0GFsPxkvroVSkJtJ12seuhPmg8,6276
14
+ hap_cli/commands/group_cmd.py,sha256=TS7YJd30q1I8CPN66318EZB8S9T0NFobV49IPCaFdi0,4342
15
+ hap_cli/commands/instance_cmd.py,sha256=PET6Ql-H_9BeN7252BMxutUVATE8g6VZTEHufDEX4Qc,10924
16
+ hap_cli/commands/node_cmd.py,sha256=gMI-Q_3YRkfk0I_inlGhFsjYnnH8FLNdE3FnGQlCvp8,21872
17
+ hap_cli/commands/optionset_cmd.py,sha256=5keMHCEjwY8oM6axFi2aaUHsL1J9yN0MGG5GClDo5qM,3114
18
+ hap_cli/commands/page_cmd.py,sha256=yHyLTR962YY7Kcf9Fx0Im9PBspZNv8CjBwunPDTw4OI,3302
19
+ hap_cli/commands/plugin_cmd.py,sha256=GFZSdtV7EWHgrw_zqxcxFI9ZBHTHPdg7zSLZoCR1J0U,4277
20
+ hap_cli/commands/post_cmd.py,sha256=ESZaSAdBy7s3OR71Kr9EH8-cXZngvPBq6aFPIiNVz0I,5121
21
+ hap_cli/commands/record_cmd.py,sha256=tgqHZPFYj1D_sC9QgzLPKZSlTkZO7EIaFZxpjI46OM0,7922
22
+ hap_cli/commands/role_cmd.py,sha256=8mTaML0kqDSVxh135ehcYQ5X34axk_mv-xfwn9OMnpA,7054
23
+ hap_cli/commands/workflow_cmd.py,sha256=HNE59MpscpJdbw5qc8UskTXZ0Kn-PiTjBIq_RapGy88,9710
24
+ hap_cli/commands/worksheet_cmd.py,sha256=yA5x6J81rgegitPWmh-E-QzVRPpw783H8cfb-2qsQZA,12171
25
+ hap_cli/core/__init__.py,sha256=QDnIob9qhieAk5igzbftGd0OXUX4M8_zLMFFqELUws4,40
26
+ hap_cli/core/ai.py,sha256=l52glBoFF7qsCDWb7rcOI2niSFgCD6KgD-8NPGfG9yw,4024
27
+ hap_cli/core/app.py,sha256=tUwFyF7D9Woi5lZz35-7Jnla-BzfGxmRxjZvQ8qmkI0,9177
28
+ hap_cli/core/auth.py,sha256=-ZW0tUIPw1WFcuxnZbF3Od3yB_gpRtAPY5u_YxxoCvM,7107
29
+ hap_cli/core/calendar_mod.py,sha256=dadJ52EGYD8ZEnJ52u2ngH9FaEjTNvN_BpJUjqL_Fvc,2966
30
+ hap_cli/core/chat.py,sha256=fOEHC5U6HZoYrEJ0omKVTaYS8AsoTR7hAOudmCyO9DU,1740
31
+ hap_cli/core/contact.py,sha256=2t8T3yNaWlZd20IwQEv90BCdCeynM_FMBrNSZ20xPfU,2259
32
+ hap_cli/core/department.py,sha256=U4q4XSSmIDaw7XWQA1XVcVYc6xkpx35htuwpzwnDNFQ,3344
33
+ hap_cli/core/flow_node.py,sha256=keDt9owCI3-pDug9B-KokvGgTHM4G_T8l20drai-dos,27747
34
+ hap_cli/core/group.py,sha256=3_CMLy51H9bAHEG1YyVnGDlPjvjdP7Z4ojKMdvenN7Q,2347
35
+ hap_cli/core/instance.py,sha256=tsn3Elr896Nvx5MlaI0xvM8sEbQ_vSMam8dYcOho2wQ,14868
36
+ hap_cli/core/optionset.py,sha256=n-ZpWhnuHHhNVC1ACB4vgWaLCavb0C2jbrW7qMjsk70,2427
37
+ hap_cli/core/page.py,sha256=Yw4XPJcWFa3_crosFtkVx_SeuyeNntKkB01QUKA7qzM,3005
38
+ hap_cli/core/plugin.py,sha256=QAomQB4TXXeconERn2mguABvPE5TOkoovolrnU2DTJM,2170
39
+ hap_cli/core/post.py,sha256=vRPfPTBi86ZL2UlhWJgr1XQboJLGKtFKE0-Uc7NDCYE,2700
40
+ hap_cli/core/record.py,sha256=o9khqMNyIT4o6t25iUy49y8Bxk7DeCQ-gI5tKMeQuY4,6931
41
+ hap_cli/core/role.py,sha256=RTwCEkv7eNOlCxCNDQhKA2GuEvCrze_tV36IOv1ctAI,6021
42
+ hap_cli/core/session.py,sha256=3IOxX0n1gv1Dqj_PoLFDYW_c5TRB1BcfKOOA02H1-Do,11829
43
+ hap_cli/core/workflow.py,sha256=Vr3J1NltJdoMVW0wfbo-0yF0f3EQv-kxLKGDaRKxk3k,14542
44
+ hap_cli/core/worksheet.py,sha256=27XwUjAkWY1z5esj-Lzx2WNXdwhS75h-LqjQCCu2uJA,11625
45
+ hap_cli/skills/SKILL.md,sha256=ZMmDdTAXXZnRKKdfj4YzNKqvKThMdTCc4GU6RibVNE4,13148
46
+ hap_cli/skills/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ hap_cli/tests/__init__.py,sha256=b98cgHISMxNQl1lnouPoZV9uhIBqnny244JDEgrzI8I,33
48
+ hap_cli/tests/test_core.py,sha256=OqnaILD0dAErOpksJrG0qOh9NMLCM5yrXh3TiRJulPE,80516
49
+ hap_cli/tests/test_full_e2e.py,sha256=railt06XGUTdiHTrQfqlnIvJ7fFfzdI-9sbnze67QcM,4650
50
+ hap_cli/tests/test_integration.py,sha256=mCIUE5uZzTgkMR96XMRzuGW0A2_HdUzf9n-6lTtF8OU,32224
51
+ hap_cli/utils/__init__.py,sha256=XztROmU5Q740_qIpVnLFdrgTmUpA0CMiLQiJLVgL5SA,43
52
+ hap_cli/utils/formatting.py,sha256=gof19VDKPyKBzcyVor3IGcMw5K11TpNP_3MHN86yZbo,3508
53
+ hap_cli/utils/options.py,sha256=uk4KntWKOE6HQdXOpDBVKXKdRDn-__iJjTv8eCrEEdE,318
54
+ hap_cli-0.5.0.dist-info/METADATA,sha256=70HxPaQ8qd_myeuuHufi7Dl2Ec8kXOMqwrk79gzNZrw,5098
55
+ hap_cli-0.5.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
56
+ hap_cli-0.5.0.dist-info/entry_points.txt,sha256=gVlKHfx3_fAhrg_Ij6HzUGIF7HPRdsc2XRj0oTFlQY8,45
57
+ hap_cli-0.5.0.dist-info/top_level.txt,sha256=MwsuUjaUw85BEWvfAnSkgGeKh5c-dWcWDq3lUw1oZc4,8
58
+ hap_cli-0.5.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hap = hap_cli.hap_cli:main
@@ -0,0 +1 @@
1
+ hap_cli