hap-cli 0.6.0__tar.gz → 0.6.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. {hap_cli-0.6.0 → hap_cli-0.6.6}/PKG-INFO +30 -41
  2. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/README.md +29 -40
  3. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/README_CN.md +24 -46
  4. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/__init__.py +1 -1
  5. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/auth_cmd.py +85 -72
  6. hap_cli-0.6.6/hap_cli/commands/calendar_cmd.py +546 -0
  7. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/chat_cmd.py +119 -91
  8. hap_cli-0.6.6/hap_cli/commands/contact_cmd.py +353 -0
  9. hap_cli-0.6.6/hap_cli/commands/department_cmd.py +266 -0
  10. hap_cli-0.6.6/hap_cli/commands/post_cmd.py +921 -0
  11. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/context.py +1 -1
  12. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/auth.py +37 -7
  13. hap_cli-0.6.6/hap_cli/core/chat.py +672 -0
  14. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/contact.py +9 -5
  15. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/department.py +26 -9
  16. hap_cli-0.6.6/hap_cli/core/post.py +344 -0
  17. hap_cli-0.6.6/hap_cli/core/response_crypto.py +77 -0
  18. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/session.py +27 -7
  19. hap_cli-0.6.6/hap_cli/core/token_crypto.py +128 -0
  20. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/hap_cli.py +1 -3
  21. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/skills/SKILL.md +17 -22
  22. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_core.py +994 -408
  23. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_full_e2e.py +10 -34
  24. hap_cli-0.6.6/hap_cli/tests/test_integration_calendar.py +283 -0
  25. hap_cli-0.6.6/hap_cli/tests/test_integration_post.py +118 -0
  26. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration_social.py +46 -64
  27. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_org_id_cli.py +3 -3
  28. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_org_id_docs.py +3 -5
  29. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli.egg-info/PKG-INFO +30 -41
  30. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli.egg-info/SOURCES.txt +4 -1
  31. {hap_cli-0.6.0 → hap_cli-0.6.6}/setup.py +1 -1
  32. hap_cli-0.6.0/hap_cli/commands/calendar_cmd.py +0 -291
  33. hap_cli-0.6.0/hap_cli/commands/contact_cmd.py +0 -222
  34. hap_cli-0.6.0/hap_cli/commands/department_cmd.py +0 -129
  35. hap_cli-0.6.0/hap_cli/commands/group_cmd.py +0 -240
  36. hap_cli-0.6.0/hap_cli/commands/post_cmd.py +0 -280
  37. hap_cli-0.6.0/hap_cli/core/chat.py +0 -284
  38. hap_cli-0.6.0/hap_cli/core/post.py +0 -240
  39. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/__init__.py +0 -0
  40. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/app_cmd.py +0 -0
  41. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/instance_cmd.py +0 -0
  42. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/node_cmd.py +0 -0
  43. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/optionset_cmd.py +0 -0
  44. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/page_cmd.py +0 -0
  45. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/record_cmd.py +0 -0
  46. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/role_cmd.py +0 -0
  47. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/workflow_cmd.py +0 -0
  48. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/commands/worksheet_cmd.py +0 -0
  49. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/__init__.py +0 -0
  50. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/app.py +0 -0
  51. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/calendar_mod.py +0 -0
  52. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/flow_node.py +0 -0
  53. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/group.py +0 -0
  54. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/instance.py +0 -0
  55. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/optionset.py +0 -0
  56. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/page.py +0 -0
  57. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/record.py +0 -0
  58. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/role.py +0 -0
  59. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/workflow.py +0 -0
  60. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/core/worksheet.py +0 -0
  61. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/skills/__init__.py +0 -0
  62. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/__init__.py +0 -0
  63. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/conftest.py +0 -0
  64. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration.py +0 -0
  65. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration_approval.py +0 -0
  66. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration_destructive.py +0 -0
  67. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration_misc.py +0 -0
  68. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration_workflow.py +0 -0
  69. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
  70. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_parameter_conventions.py +0 -0
  71. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
  72. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/utils/__init__.py +0 -0
  73. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/utils/formatting.py +0 -0
  74. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/utils/options.py +0 -0
  75. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli/utils/parameter_mapping.py +0 -0
  76. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli.egg-info/dependency_links.txt +0 -0
  77. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli.egg-info/entry_points.txt +0 -0
  78. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli.egg-info/requires.txt +0 -0
  79. {hap_cli-0.6.0 → hap_cli-0.6.6}/hap_cli.egg-info/top_level.txt +0 -0
  80. {hap_cli-0.6.0 → hap_cli-0.6.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hap-cli
3
- Version: 0.6.0
3
+ Version: 0.6.6
4
4
  Summary: CLI harness for MingDAO HAP - Enterprise no-code platform
5
5
  Author: hap-cli
6
6
  License: Apache-2.0
@@ -53,16 +53,19 @@ hap auth login nocoly # Nocoly
53
53
  hap auth login https://hap.example.com # Self-hosted
54
54
  ```
55
55
 
56
- Opens your browser to the MingDAO login page. After login, the token is saved automatically, your organizations are fetched immediately, and the first org is stored as the current org.
56
+ Opens your browser to the MingDAO login page. After login, your organizations are fetched immediately, and the first org is stored as the current org.
57
57
 
58
- **Option B: Manual token**
58
+ **Option B: Manual token (headless / scripted)**
59
59
 
60
60
  ```bash
61
- hap auth set \
62
- --server https://your-mingdao-server.com \
63
- --token YOUR_MD_PSS_ID_TOKEN
61
+ hap auth login https://your-mingdao-server.com --token YOUR_PERSONAL_ACCESS_TOKEN
64
62
  ```
65
63
 
64
+ If the browser flow is running but the callback never reaches the CLI (e.g. remote
65
+ server, restrictive firewall), interrupt the command (the usual shell interrupt
66
+ shortcut for your terminal) to fall back to an interactive paste prompt for the
67
+ token shown on the success page.
68
+
66
69
  **Other auth commands**
67
70
 
68
71
  ```bash
@@ -105,11 +108,9 @@ hap --json worksheet record list WORKSHEET_ID
105
108
 
106
109
  | Command | Description |
107
110
  |---|---|
108
- | `auth login` | Login via browser |
111
+ | `auth login` | Login via browser (use `--token` for scripted login) |
109
112
  | `auth logout` | Clear saved auth token |
110
- | `auth set` | Set server address and auth token |
111
- | `auth show` | Show current configuration |
112
- | `auth whoami` | Show current logged-in user info |
113
+ | `auth whoami` | Show current logged-in user and current organization |
113
114
  | `auth list-my-orgs` | List all organizations for current user |
114
115
  | `auth switch-org` | Switch saved current organization |
115
116
 
@@ -308,7 +309,7 @@ hap --json worksheet record list WORKSHEET_ID
308
309
 
309
310
  | Command | Description |
310
311
  |---|---|
311
- | `contact search` | Search contacts and departments |
312
+ | `contact search` | Search contacts by keyword within an organization |
312
313
  | `contact resolve` | Resolve accountId by name/email/phone |
313
314
  | `contact friends` | List contacts in address book |
314
315
  | `contact friend-requests` | List pending friend requests |
@@ -332,18 +333,22 @@ hap --json worksheet record list WORKSHEET_ID
332
333
 
333
334
  | Command | Description |
334
335
  |---|---|
335
- | `post list` | List feed posts |
336
- | `post get` | Get post details |
336
+ | `post list` | List feed posts (`--topic-id` filters by topic tag) |
337
+ | `post search` | Search posts by keyword and date range (`--topic-id` filters by topic tag) |
338
+ | `post get` | Show a post with its comment thread |
337
339
  | `post create` | Create a new post |
338
- | `post update` | Update a post |
340
+ | `post update` | Edit a post's content |
339
341
  | `post delete` | Delete a post |
340
- | `post search` | Search posts by keyword and date range |
341
- | `post pinned` | List pinned posts |
342
- | `post top` | Pin or unpin a post |
343
- | `post like` | Like or unlike a post |
344
- | `post favorite` | Favorite or unfavorite a post |
345
- | `post comments` | List comments on a post |
346
342
  | `post comment` | Add a comment to a post |
343
+ | `post comments` | List all comments on a post |
344
+ | `post comment-delete` | Delete a comment |
345
+ | `post like` | Like a post (`--remove` to unlike) |
346
+ | `post likes` | List users who liked a post |
347
+ | `post favorite` | Favorite a post (`--remove` to unfavorite) |
348
+ | `post pin` | Pin a post (`--hours` for duration) |
349
+ | `post unpin` | Unpin a post |
350
+ | `post pinned` | List pinned posts |
351
+ | `post topics` | List topic tags (autocomplete) |
347
352
 
348
353
  ### calendar — Calendar Management
349
354
 
@@ -363,25 +368,11 @@ hap --json worksheet record list WORKSHEET_ID
363
368
  | Command | Description |
364
369
  |---|---|
365
370
  | `chat list` | List recent chat sessions |
366
- | `chat history` | Get 1-on-1 or group chat history |
371
+ | `chat files` | List files shared in a 1-on-1 or group chat |
372
+ | `chat messages` | Fetch 1-on-1, group, or inbox (system / app / workflow / ...) messages |
367
373
  | `chat send` | Send a message to one or more users |
368
- | `chat send-file` | Send a file to a chat (supports both 1-on-1 and group) |
369
- | `chat send-card` | Send a card to a chat (supports both 1-on-1 and group) |
374
+ | `chat group-info` | Get information about a chat group |
370
375
  | `chat card-detail` | Resolve card references embedded in chat messages |
371
- | `chat start` | Start a 1-on-1 chat with another user |
372
-
373
- #### chat group — Group Management
374
-
375
- | Command | Description |
376
- |---|---|
377
- | `chat group list` | List groups |
378
- | `chat group info` | Get group information |
379
- | `chat group create` | Create a group chat (supports keyword member resolution, at least 2 members) |
380
- | `chat group update` | Update group name and/or announcement |
381
- | `chat group delete` | Disband a group |
382
- | `chat group members` | List group members |
383
- | `chat group remove-member` | Remove member from a group |
384
- | `chat group files` | List files in a group |
385
376
 
386
377
  ## Workflow Management
387
378
 
@@ -462,7 +453,8 @@ hap> quit
462
453
  ## API Authentication
463
454
 
464
455
  The CLI uses MingDAO's `md_pss_id` session token. Use `hap auth login` for
465
- browser-based login, or `hap auth set --token TOKEN` to set the token manually.
456
+ browser-based login, or `hap auth login --token TOKEN` to supply a token
457
+ non-interactively (e.g. on a headless server).
466
458
 
467
459
  Commands that expose `--org-id` will use the saved current org when you omit the option.
468
460
 
@@ -506,9 +498,6 @@ hap app role add-member APP_ID ROLE_ID -u USER_ID
506
498
  # Manage option sets
507
499
  hap app optionset list APP_ID
508
500
 
509
- # Manage chat groups
510
- hap chat group list
511
-
512
501
  # Terminate a stuck instance
513
502
  hap approval terminate INSTANCE_ID --yes
514
503
 
@@ -24,16 +24,19 @@ hap auth login nocoly # Nocoly
24
24
  hap auth login https://hap.example.com # Self-hosted
25
25
  ```
26
26
 
27
- Opens your browser to the MingDAO login page. After login, the token is saved automatically, your organizations are fetched immediately, and the first org is stored as the current org.
27
+ Opens your browser to the MingDAO login page. After login, your organizations are fetched immediately, and the first org is stored as the current org.
28
28
 
29
- **Option B: Manual token**
29
+ **Option B: Manual token (headless / scripted)**
30
30
 
31
31
  ```bash
32
- hap auth set \
33
- --server https://your-mingdao-server.com \
34
- --token YOUR_MD_PSS_ID_TOKEN
32
+ hap auth login https://your-mingdao-server.com --token YOUR_PERSONAL_ACCESS_TOKEN
35
33
  ```
36
34
 
35
+ If the browser flow is running but the callback never reaches the CLI (e.g. remote
36
+ server, restrictive firewall), interrupt the command (the usual shell interrupt
37
+ shortcut for your terminal) to fall back to an interactive paste prompt for the
38
+ token shown on the success page.
39
+
37
40
  **Other auth commands**
38
41
 
39
42
  ```bash
@@ -76,11 +79,9 @@ hap --json worksheet record list WORKSHEET_ID
76
79
 
77
80
  | Command | Description |
78
81
  |---|---|
79
- | `auth login` | Login via browser |
82
+ | `auth login` | Login via browser (use `--token` for scripted login) |
80
83
  | `auth logout` | Clear saved auth token |
81
- | `auth set` | Set server address and auth token |
82
- | `auth show` | Show current configuration |
83
- | `auth whoami` | Show current logged-in user info |
84
+ | `auth whoami` | Show current logged-in user and current organization |
84
85
  | `auth list-my-orgs` | List all organizations for current user |
85
86
  | `auth switch-org` | Switch saved current organization |
86
87
 
@@ -279,7 +280,7 @@ hap --json worksheet record list WORKSHEET_ID
279
280
 
280
281
  | Command | Description |
281
282
  |---|---|
282
- | `contact search` | Search contacts and departments |
283
+ | `contact search` | Search contacts by keyword within an organization |
283
284
  | `contact resolve` | Resolve accountId by name/email/phone |
284
285
  | `contact friends` | List contacts in address book |
285
286
  | `contact friend-requests` | List pending friend requests |
@@ -303,18 +304,22 @@ hap --json worksheet record list WORKSHEET_ID
303
304
 
304
305
  | Command | Description |
305
306
  |---|---|
306
- | `post list` | List feed posts |
307
- | `post get` | Get post details |
307
+ | `post list` | List feed posts (`--topic-id` filters by topic tag) |
308
+ | `post search` | Search posts by keyword and date range (`--topic-id` filters by topic tag) |
309
+ | `post get` | Show a post with its comment thread |
308
310
  | `post create` | Create a new post |
309
- | `post update` | Update a post |
311
+ | `post update` | Edit a post's content |
310
312
  | `post delete` | Delete a post |
311
- | `post search` | Search posts by keyword and date range |
312
- | `post pinned` | List pinned posts |
313
- | `post top` | Pin or unpin a post |
314
- | `post like` | Like or unlike a post |
315
- | `post favorite` | Favorite or unfavorite a post |
316
- | `post comments` | List comments on a post |
317
313
  | `post comment` | Add a comment to a post |
314
+ | `post comments` | List all comments on a post |
315
+ | `post comment-delete` | Delete a comment |
316
+ | `post like` | Like a post (`--remove` to unlike) |
317
+ | `post likes` | List users who liked a post |
318
+ | `post favorite` | Favorite a post (`--remove` to unfavorite) |
319
+ | `post pin` | Pin a post (`--hours` for duration) |
320
+ | `post unpin` | Unpin a post |
321
+ | `post pinned` | List pinned posts |
322
+ | `post topics` | List topic tags (autocomplete) |
318
323
 
319
324
  ### calendar — Calendar Management
320
325
 
@@ -334,25 +339,11 @@ hap --json worksheet record list WORKSHEET_ID
334
339
  | Command | Description |
335
340
  |---|---|
336
341
  | `chat list` | List recent chat sessions |
337
- | `chat history` | Get 1-on-1 or group chat history |
342
+ | `chat files` | List files shared in a 1-on-1 or group chat |
343
+ | `chat messages` | Fetch 1-on-1, group, or inbox (system / app / workflow / ...) messages |
338
344
  | `chat send` | Send a message to one or more users |
339
- | `chat send-file` | Send a file to a chat (supports both 1-on-1 and group) |
340
- | `chat send-card` | Send a card to a chat (supports both 1-on-1 and group) |
345
+ | `chat group-info` | Get information about a chat group |
341
346
  | `chat card-detail` | Resolve card references embedded in chat messages |
342
- | `chat start` | Start a 1-on-1 chat with another user |
343
-
344
- #### chat group — Group Management
345
-
346
- | Command | Description |
347
- |---|---|
348
- | `chat group list` | List groups |
349
- | `chat group info` | Get group information |
350
- | `chat group create` | Create a group chat (supports keyword member resolution, at least 2 members) |
351
- | `chat group update` | Update group name and/or announcement |
352
- | `chat group delete` | Disband a group |
353
- | `chat group members` | List group members |
354
- | `chat group remove-member` | Remove member from a group |
355
- | `chat group files` | List files in a group |
356
347
 
357
348
  ## Workflow Management
358
349
 
@@ -433,7 +424,8 @@ hap> quit
433
424
  ## API Authentication
434
425
 
435
426
  The CLI uses MingDAO's `md_pss_id` session token. Use `hap auth login` for
436
- browser-based login, or `hap auth set --token TOKEN` to set the token manually.
427
+ browser-based login, or `hap auth login --token TOKEN` to supply a token
428
+ non-interactively (e.g. on a headless server).
437
429
 
438
430
  Commands that expose `--org-id` will use the saved current org when you omit the option.
439
431
 
@@ -477,9 +469,6 @@ hap app role add-member APP_ID ROLE_ID -u USER_ID
477
469
  # Manage option sets
478
470
  hap app optionset list APP_ID
479
471
 
480
- # Manage chat groups
481
- hap chat group list
482
-
483
472
  # Terminate a stuck instance
484
473
  hap approval terminate INSTANCE_ID --yes
485
474
 
@@ -26,17 +26,16 @@ hap auth login nocoly # nocoly
26
26
  hap auth login https://hap.example.com # 私有部署
27
27
  ```
28
28
 
29
- 执行后会自动打开浏览器,在明道云页面完成登录后,token 会自动保存到本地配置,并立即拉取你所属的组织列表,将第一个组织保存为当前组织。
29
+ 执行后会自动打开浏览器,在明道云页面完成登录后,token 会自动保存,并立即拉取你所属的组织列表,将第一个组织保存为当前组织。
30
30
 
31
- **方式二:手动配置 Token**
31
+ **方式二:手动粘贴 Token(无浏览器 / 脚本化场景)**
32
32
 
33
33
  ```bash
34
- hap auth set \
35
- --server https://你的明道云服务器地址 \
36
- --token 你的_MD_PSS_ID_令牌
34
+ hap auth login https://你的明道云服务器地址 --token 你的个人访问令牌
37
35
  ```
38
36
 
39
- > `md_pss_id` 令牌可从浏览器登录明道云后的 Cookie 中获取。
37
+ 如果浏览器登录已完成但回调没能送回 CLI(比如远程服务器、防火墙拦截),
38
+ 在等待界面使用终端的中断快捷键打断当前命令,CLI 会自动切换到交互式粘贴模式,把登录成功页上的 token 贴回命令行即可。
40
39
 
41
40
  > 所有带 `--org-id` 的命令,在未显式传参时都会默认使用当前保存的组织。
42
41
 
@@ -87,11 +86,9 @@ hap --json worksheet record list 工作表ID
87
86
 
88
87
  | 命令 | 说明 |
89
88
  |---|---|
90
- | `auth login` | 通过浏览器登录 |
89
+ | `auth login` | 通过浏览器登录(加 `--token` 可非交互式登录) |
91
90
  | `auth logout` | 清除已保存的认证令牌 |
92
- | `auth set` | 设置服务器地址和认证令牌 |
93
- | `auth show` | 显示当前配置 |
94
- | `auth whoami` | 显示当前登录用户信息 |
91
+ | `auth whoami` | 显示当前登录用户及当前组织 |
95
92
  | `auth list-my-orgs` | 列出当前用户所属的所有组织 |
96
93
  | `auth switch-org` | 切换已保存的当前组织 |
97
94
 
@@ -290,7 +287,7 @@ hap --json worksheet record list 工作表ID
290
287
 
291
288
  | 命令 | 说明 |
292
289
  |---|---|
293
- | `contact search` | 搜索联系人和部门 |
290
+ | `contact search` | 在组织内按关键词搜索联系人 |
294
291
  | `contact resolve` | 根据姓名/邮箱/手机号解析 accountId |
295
292
  | `contact friends` | 列出通讯录中的联系人 |
296
293
  | `contact friend-requests` | 列出待处理的好友请求 |
@@ -314,18 +311,22 @@ hap --json worksheet record list 工作表ID
314
311
 
315
312
  | 命令 | 说明 |
316
313
  |---|---|
317
- | `post list` | 列出动态帖子 |
318
- | `post get` | 获取帖子详情 |
314
+ | `post list` | 列出动态帖子(`--topic-id` 按话题标签过滤) |
315
+ | `post search` | 按关键词和日期范围搜索帖子(`--topic-id` 按话题标签过滤) |
316
+ | `post get` | 查看帖子详情(含评论) |
319
317
  | `post create` | 创建新帖子 |
320
- | `post update` | 更新帖子 |
318
+ | `post update` | 编辑帖子内容 |
321
319
  | `post delete` | 删除帖子 |
322
- | `post search` | 按关键词和日期范围搜索帖子 |
323
- | `post pinned` | 列出置顶帖子 |
324
- | `post top` | 置顶或取消置顶帖子 |
325
- | `post like` | 点赞或取消点赞帖子 |
326
- | `post favorite` | 收藏或取消收藏帖子 |
327
- | `post comments` | 列出帖子的评论 |
328
320
  | `post comment` | 为帖子添加评论 |
321
+ | `post comments` | 列出帖子的所有评论 |
322
+ | `post comment-delete` | 删除一条评论 |
323
+ | `post like` | 点赞帖子(`--remove` 取消) |
324
+ | `post likes` | 列出点赞该帖子的用户 |
325
+ | `post favorite` | 收藏帖子(`--remove` 取消) |
326
+ | `post pin` | 置顶帖子(`--hours` 指定时长) |
327
+ | `post unpin` | 取消置顶 |
328
+ | `post pinned` | 列出置顶帖子 |
329
+ | `post topics` | 列出话题标签(自动补全) |
329
330
 
330
331
  ### calendar — 日程管理
331
332
 
@@ -345,25 +346,11 @@ hap --json worksheet record list 工作表ID
345
346
  | 命令 | 说明 |
346
347
  |---|---|
347
348
  | `chat list` | 列出最近的聊天会话 |
348
- | `chat history` | 获取单聊或群聊的聊天记录 |
349
+ | `chat files` | 列出单聊或群聊中分享的文件 |
350
+ | `chat messages` | 获取单聊、群聊或收件箱(系统/应用/工作流等)消息 |
349
351
  | `chat send` | 向一个或多个用户发送消息 |
350
- | `chat send-file` | 向聊天发送文件(支持单聊和群聊) |
351
- | `chat send-card` | 向聊天发送卡片(支持单聊和群聊) |
352
+ | `chat group-info` | 获取群组信息 |
352
353
  | `chat card-detail` | 解析聊天消息中嵌入的卡片引用 |
353
- | `chat start` | 发起与另一用户的单聊 |
354
-
355
- #### chat group — 群组管理
356
-
357
- | 命令 | 说明 |
358
- |---|---|
359
- | `chat group list` | 列出群组 |
360
- | `chat group info` | 获取群组信息 |
361
- | `chat group create` | 创建群聊(支持关键词解析成员,至少两个成员) |
362
- | `chat group update` | 更新群组名称和/或公告 |
363
- | `chat group delete` | 解散群组 |
364
- | `chat group members` | 列出群组成员 |
365
- | `chat group remove-member` | 从群组移除成员 |
366
- | `chat group files` | 列出群组中的文件 |
367
354
 
368
355
  ## 工作流管理
369
356
 
@@ -874,12 +861,3 @@ hap approval approve 实例ID --opinion "费用合理,同意报销"
874
861
  # 查看执行结果
875
862
  hap --json approval history-detail 实例ID
876
863
  ```
877
-
878
- ## 认证说明
879
-
880
- 本工具使用明道云的 `md_pss_id` 会话令牌进行认证。获取方式:
881
-
882
- 1. 在浏览器中登录明道云
883
- 2. 打开开发者工具 (F12)
884
- 3. 在 Application > Cookies 中找到 `md_pss_id`
885
- 4. 复制其值作为 `--token` 参数
@@ -1,3 +1,3 @@
1
1
  """CLI harness for MingDAO HAP (hap-cli)."""
2
2
 
3
- __version__ = "0.6.0"
3
+ __version__ = "0.6.6"
@@ -1,5 +1,7 @@
1
1
  """CLI commands for authentication and session management."""
2
2
 
3
+ import sys
4
+
3
5
  import click
4
6
 
5
7
  from hap_cli.context import pass_context
@@ -20,96 +22,87 @@ def auth():
20
22
  pass
21
23
 
22
24
 
23
- @auth.command("set")
24
- @click.option("--server", "-s", required=True, help="MingDAO server URL")
25
- @click.option("--token", "-t", required=True, help="Authentication token (md_pss_id)")
26
- @pass_context
27
- def auth_set(ctx, server, token):
28
- """Set server URL and authentication token."""
29
- session = Session(server_url=server, auth_token=token)
30
- session.save()
31
- ctx.output(
32
- {"status": "ok", "server": server},
33
- lambda d: click.echo(f"Auth config saved. Server: {server}"),
34
- )
25
+ def _print_browser_hint(ctx, server, timeout):
26
+ api_host, webui = auth_mod.resolve_server(server)
27
+ port = auth_mod.get_available_port()
28
+ auth_url = auth_mod.build_auth_url(webui, port)
29
+ if not ctx.json_mode:
30
+ click.echo("Opening browser for login...")
31
+ click.echo(f" Server: {webui}")
32
+ click.echo(" If browser doesn't open, visit:")
33
+ click.echo(f" {auth_url}")
34
+ click.echo(f" Waiting for login (timeout: {timeout}s)...")
35
+ click.echo(" If the callback doesn't come back, interrupt to paste the token manually.")
35
36
 
36
37
 
37
- @auth.command("show")
38
- @pass_context
39
- def auth_show(ctx):
40
- """Show current configuration."""
38
+ def _paste_flow(ctx, server):
39
+ if not sys.stdin.isatty():
40
+ raise SessionError("No TTY available; use --token instead")
41
+ _api_host, webui = auth_mod.resolve_server(server)
42
+ if not ctx.json_mode:
43
+ click.echo(f"Log in at {webui} on a device with a browser,")
44
+ click.echo("then copy the md_pss_id token and paste it below.")
45
+ token = click.prompt("Paste token").strip()
46
+ return auth_mod.verify_token(server, token)
47
+
48
+
49
+ def _save_and_report(ctx, token, webui, user_info):
41
50
  session = ctx.get_session()
51
+ session.server_url = webui
52
+ session.auth_token = token
53
+ session.default_app_id = ""
54
+ session.default_project_id = ""
55
+ orgs = auth_mod.list_my_orgs(session)
56
+ current_org = orgs[0] if orgs else {}
57
+ if current_org.get("projectId"):
58
+ session.default_project_id = current_org["projectId"]
59
+ session.save()
60
+
42
61
  data = {
43
- "server_url": session.server_url,
44
- "auth_token": session.auth_token[:8] + "..." if session.auth_token else "",
45
- "configured": session.is_configured(),
46
- "current_org_id": session.default_project_id,
62
+ "status": "ok",
63
+ "server_url": webui,
64
+ "user": user_info,
65
+ "current_org": current_org,
47
66
  }
48
67
  ctx.output(
49
68
  data,
50
- lambda d: output_kv(d, labels={
51
- "server_url": "Server URL",
52
- "auth_token": "Auth Token",
53
- "configured": "Configured",
54
- "current_org_id": "Current Org ID",
55
- }),
69
+ lambda d: click.echo(
70
+ f"Logged in as: {user_info.get('name', '')} "
71
+ f"({user_info.get('email', '')})\n"
72
+ f"Server: {webui}\n"
73
+ f"Current org: {current_org.get('projectId', '')} "
74
+ f"{current_org.get('companyName', '')}".rstrip()
75
+ ),
56
76
  )
57
77
 
58
78
 
59
79
  @auth.command("login")
60
80
  @click.argument("server", default="mingdao")
61
81
  @click.option("--timeout", "-t", default=300, help="Login timeout in seconds")
82
+ @click.option("--token", "token_opt", default=None, help="Non-interactive: use this token")
62
83
  @pass_context
63
- def auth_login(ctx, server, timeout):
84
+ def auth_login(ctx, server, timeout, token_opt):
64
85
  """Login via browser. Opens HAP login page and captures token.
65
86
 
66
87
  SERVER can be 'mingdao', 'nocoly', or a self-hosted URL.
67
88
  Default is 'mingdao'.
89
+
90
+ If the browser flow can't complete (no GUI, callback never fires),
91
+ interrupt the command to fall back to pasting the token manually.
92
+ Use --token to supply a token non-interactively for scripts.
68
93
  """
69
94
  try:
70
- api_host, webui = auth_mod.resolve_server(server)
71
- port = auth_mod.get_available_port()
72
- auth_url = auth_mod.build_auth_url(webui, port)
73
-
74
- if not ctx.json_mode:
75
- click.echo(f"Opening browser for login...")
76
- click.echo(f" Server: {webui}")
77
- click.echo(f" If browser doesn't open, visit:")
78
- click.echo(f" {auth_url}")
79
- click.echo(f" Waiting for login (timeout: {timeout}s)...")
80
-
81
- token, api_host, user_info = auth_mod.login(server, timeout=timeout)
82
-
83
- # Save to config
84
- session = ctx.get_session()
85
- session.server_url = api_host
86
- session.auth_token = token
87
- session.default_app_id = ""
88
- session.default_project_id = ""
89
- orgs = auth_mod.list_my_orgs(session)
90
- current_org = orgs[0] if orgs else {}
91
- if current_org.get("projectId"):
92
- session.default_project_id = current_org["projectId"]
93
- session.save()
94
-
95
- data = {
96
- "status": "ok",
97
- "server_url": api_host,
98
- "user": user_info,
99
- "current_org": current_org,
100
- }
101
- ctx.output(
102
- data,
103
- lambda d: click.echo(
104
- f"Logged in as: {user_info.get('name', '')} "
105
- f"({user_info.get('email', '')})\n"
106
- f"Server: {api_host}\n"
107
- f"Current org: {current_org.get('projectId', '')} "
108
- f"{current_org.get('companyName', '')}".rstrip()
109
- ),
110
- )
111
- except TimeoutError:
112
- ctx.handle_error(SessionError("Login timed out. Please try again."))
95
+ if token_opt:
96
+ token, webui, user_info = auth_mod.verify_token(server, token_opt)
97
+ else:
98
+ try:
99
+ _print_browser_hint(ctx, server, timeout)
100
+ token, webui, user_info = auth_mod.login(server, timeout=timeout)
101
+ except (TimeoutError, KeyboardInterrupt):
102
+ if not ctx.json_mode:
103
+ click.echo("\nSwitching to manual paste mode...")
104
+ token, webui, user_info = _paste_flow(ctx, server)
105
+ _save_and_report(ctx, token, webui, user_info)
113
106
  except ImportError as e:
114
107
  ctx.handle_error(SessionError(str(e)))
115
108
  except Exception as e:
@@ -176,20 +169,40 @@ def auth_switch_org(ctx, org_id):
176
169
  @auth.command("whoami")
177
170
  @pass_context
178
171
  def auth_whoami(ctx):
179
- """Show current logged-in user info."""
172
+ """Show current logged-in user info and current organization."""
180
173
  try:
181
174
  session = ctx.get_session()
182
175
  if not session.is_configured():
183
176
  raise SessionError("Not logged in. Run 'auth login' first.")
184
177
 
185
178
  user_info = auth_mod.get_user_info(session.server_url, session.auth_token)
179
+
180
+ current_org = {}
181
+ current_org_id = session.default_project_id
182
+ if current_org_id:
183
+ try:
184
+ for org in auth_mod.list_my_orgs(session):
185
+ if org.get("projectId") == current_org_id:
186
+ current_org = org
187
+ break
188
+ except Exception:
189
+ # Fetching orgs is best-effort; whoami should still work
190
+ current_org = {"projectId": current_org_id}
191
+
192
+ data = {
193
+ **user_info,
194
+ "current_org_id": current_org.get("projectId", ""),
195
+ "current_org_name": current_org.get("companyName", ""),
196
+ }
186
197
  ctx.output(
187
- user_info,
198
+ data,
188
199
  lambda d: output_kv(d, labels={
189
200
  "id": "Account ID",
190
201
  "name": "Name",
191
202
  "email": "Email",
192
203
  "lang": "Language",
204
+ "current_org_id": "Current Org ID",
205
+ "current_org_name": "Current Org",
193
206
  }),
194
207
  )
195
208
  except Exception as e: