dailybot-cli 3.7.4__tar.gz → 3.9.0__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.
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/PKG-INFO +35 -6
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/README.md +34 -5
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/api_client.py +234 -1
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/chat.py +298 -21
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/checkin.py +3 -2
- dailybot_cli-3.9.0/dailybot_cli/commands/featured.py +147 -0
- dailybot_cli-3.9.0/dailybot_cli/commands/label.py +404 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/public_api_helpers.py +68 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/user_scoped_actions.py +2 -1
- dailybot_cli-3.9.0/dailybot_cli/commands/workflow.py +227 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/display.py +47 -2
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/main.py +4 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli.egg-info/PKG-INFO +35 -6
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli.egg-info/SOURCES.txt +2 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/pyproject.toml +1 -1
- dailybot_cli-3.7.4/dailybot_cli/commands/workflow.py +0 -129
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/LICENSE +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/__init__.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/__init__.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/agent.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/ask.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/auth.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/authoring_helpers.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/channels.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/config.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/conversation.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/env.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/form.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/hook.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/identity.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/interactive.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/interactive_chat.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/kudos.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/query_options.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/status.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/team.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/uninstall.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/update.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/upgrade.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/user.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/commands/version.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/config.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/install_method.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/ledger.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/tui/__init__.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/tui/app.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/tui/commands.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/tui/conversation.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli/tui/intents.py +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli.egg-info/dependency_links.txt +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli.egg-info/entry_points.txt +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli.egg-info/requires.txt +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/dailybot_cli.egg-info/top_level.txt +0 -0
- {dailybot_cli-3.7.4 → dailybot_cli-3.9.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dailybot-cli
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.9.0
|
|
4
4
|
Summary: Dailybot CLI - The command-line bridge between humans and agents. Progress reports, observability, and workflow automation for modern teams across Slack, Google Chat, Discord, MS Teams, and more.
|
|
5
5
|
Author-email: Dailybot <support@dailybot.com>
|
|
6
6
|
License: MIT
|
|
@@ -534,21 +534,33 @@ The `user list` table shows **Name** and **User UUID**. You can copy a UUID dire
|
|
|
534
534
|
|
|
535
535
|
## Workflows
|
|
536
536
|
|
|
537
|
-
Browse the workflows configured in your organization
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
537
|
+
Browse the workflows configured in your organization, and **trigger** ones whose
|
|
538
|
+
trigger type is `api_trigger` ("When triggered via API or button" in the
|
|
539
|
+
automations builder). Creating and editing workflow definitions remains in the
|
|
540
|
+
Dailybot web app. The feature is plan-gated; an org on a plan without workflows
|
|
541
|
+
gets a clear upgrade message.
|
|
541
542
|
|
|
542
543
|
```bash
|
|
543
544
|
# List workflows visible to you (paginated + searchable)
|
|
544
545
|
dailybot workflow list
|
|
545
546
|
dailybot workflow list --search "release" --all --json
|
|
547
|
+
# Find triggerable workflows
|
|
548
|
+
dailybot workflow list --filter api_trigger --all
|
|
546
549
|
|
|
547
550
|
# Get a single workflow by UUID
|
|
548
551
|
dailybot workflow get <workflow_uuid>
|
|
549
552
|
dailybot workflow get <workflow_uuid> --json
|
|
553
|
+
|
|
554
|
+
# Queue an api_trigger run (async — returns 202; no run output)
|
|
555
|
+
dailybot workflow trigger <workflow-uuid>
|
|
556
|
+
dailybot workflow trigger <workflow-uuid> \
|
|
557
|
+
--payload '{"env":"production","requested_by":"release-bot"}'
|
|
550
558
|
```
|
|
551
559
|
|
|
560
|
+
The optional `--payload` must be a JSON object ≤ 8 KiB; workflow steps read it
|
|
561
|
+
as `{{trigger.body.*}}`. The same `api_trigger` workflows can also be fired from
|
|
562
|
+
a chat button via `callback_workflow` (see Chat below).
|
|
563
|
+
|
|
552
564
|
`dailybot workflow list` accepts the shared list flags — see
|
|
553
565
|
[Listing, search, and pagination](#listing-search-and-pagination).
|
|
554
566
|
|
|
@@ -908,8 +920,9 @@ Replies to agent emails land as messages retrievable via `dailybot agent message
|
|
|
908
920
|
|
|
909
921
|
| Command | Description |
|
|
910
922
|
|---------|-------------|
|
|
911
|
-
| `dailybot workflow list` | List workflows visible to you (
|
|
923
|
+
| `dailybot workflow list` | List workflows visible to you (search + pagination; `--filter api_trigger`) |
|
|
912
924
|
| `dailybot workflow get <uuid>` | Show a single workflow by UUID |
|
|
925
|
+
| `dailybot workflow trigger <uuid>` | Queue an `api_trigger` workflow run (async 202; optional `--payload`) |
|
|
913
926
|
|
|
914
927
|
### Chat (send bot messages to Slack/Teams/Discord/Google Chat)
|
|
915
928
|
|
|
@@ -946,6 +959,22 @@ dailybot chat send -c C0123 -m "Build #421 ✅" \
|
|
|
946
959
|
--bot-name "Release Bot" --bot-icon-emoji ":rocket:" \
|
|
947
960
|
--link-button "Open report::https://app.company.com/report"
|
|
948
961
|
|
|
962
|
+
# Approval flow — callback_url buttons (+ optional bearer auth on the POST)
|
|
963
|
+
dailybot chat send -u <user-uuid> -m "Deploy to prod?" \
|
|
964
|
+
--approve-button "Yes=approve" --reject-button "No=deny" \
|
|
965
|
+
--callback-url https://hooks.example.com/req42 --callback-bearer "$TOKEN"
|
|
966
|
+
|
|
967
|
+
# Fire an api_trigger workflow from a button click
|
|
968
|
+
dailybot chat send -c C0123 -m "Ready to release?" \
|
|
969
|
+
--workflow-button "Run release=<workflow-uuid>"
|
|
970
|
+
|
|
971
|
+
# Full button contract (modals, response trees, callback_prompt, …) via JSON
|
|
972
|
+
dailybot chat send -u <user-uuid> -m "Need details" --buttons '[
|
|
973
|
+
{"label":"Open","button_type":"interactive","value":"open",
|
|
974
|
+
"callback_url":"https://hooks.example.com/x",
|
|
975
|
+
"modal_body":{"title":"Notes","blocks":[
|
|
976
|
+
{"type":"input","name":"notes","label":"Notes","multiline":true}]}}]'
|
|
977
|
+
|
|
949
978
|
# Send with another user's identity, or as yourself (Slack only, admin-only)
|
|
950
979
|
dailybot chat send -c C0123 -m "Posting for the team" --send-as-user <user-uuid>
|
|
951
980
|
dailybot chat send -c C0123 -m "This one is from me" --send-as-me
|
|
@@ -495,21 +495,33 @@ The `user list` table shows **Name** and **User UUID**. You can copy a UUID dire
|
|
|
495
495
|
|
|
496
496
|
## Workflows
|
|
497
497
|
|
|
498
|
-
Browse the workflows configured in your organization
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
Browse the workflows configured in your organization, and **trigger** ones whose
|
|
499
|
+
trigger type is `api_trigger` ("When triggered via API or button" in the
|
|
500
|
+
automations builder). Creating and editing workflow definitions remains in the
|
|
501
|
+
Dailybot web app. The feature is plan-gated; an org on a plan without workflows
|
|
502
|
+
gets a clear upgrade message.
|
|
502
503
|
|
|
503
504
|
```bash
|
|
504
505
|
# List workflows visible to you (paginated + searchable)
|
|
505
506
|
dailybot workflow list
|
|
506
507
|
dailybot workflow list --search "release" --all --json
|
|
508
|
+
# Find triggerable workflows
|
|
509
|
+
dailybot workflow list --filter api_trigger --all
|
|
507
510
|
|
|
508
511
|
# Get a single workflow by UUID
|
|
509
512
|
dailybot workflow get <workflow_uuid>
|
|
510
513
|
dailybot workflow get <workflow_uuid> --json
|
|
514
|
+
|
|
515
|
+
# Queue an api_trigger run (async — returns 202; no run output)
|
|
516
|
+
dailybot workflow trigger <workflow-uuid>
|
|
517
|
+
dailybot workflow trigger <workflow-uuid> \
|
|
518
|
+
--payload '{"env":"production","requested_by":"release-bot"}'
|
|
511
519
|
```
|
|
512
520
|
|
|
521
|
+
The optional `--payload` must be a JSON object ≤ 8 KiB; workflow steps read it
|
|
522
|
+
as `{{trigger.body.*}}`. The same `api_trigger` workflows can also be fired from
|
|
523
|
+
a chat button via `callback_workflow` (see Chat below).
|
|
524
|
+
|
|
513
525
|
`dailybot workflow list` accepts the shared list flags — see
|
|
514
526
|
[Listing, search, and pagination](#listing-search-and-pagination).
|
|
515
527
|
|
|
@@ -869,8 +881,9 @@ Replies to agent emails land as messages retrievable via `dailybot agent message
|
|
|
869
881
|
|
|
870
882
|
| Command | Description |
|
|
871
883
|
|---------|-------------|
|
|
872
|
-
| `dailybot workflow list` | List workflows visible to you (
|
|
884
|
+
| `dailybot workflow list` | List workflows visible to you (search + pagination; `--filter api_trigger`) |
|
|
873
885
|
| `dailybot workflow get <uuid>` | Show a single workflow by UUID |
|
|
886
|
+
| `dailybot workflow trigger <uuid>` | Queue an `api_trigger` workflow run (async 202; optional `--payload`) |
|
|
874
887
|
|
|
875
888
|
### Chat (send bot messages to Slack/Teams/Discord/Google Chat)
|
|
876
889
|
|
|
@@ -907,6 +920,22 @@ dailybot chat send -c C0123 -m "Build #421 ✅" \
|
|
|
907
920
|
--bot-name "Release Bot" --bot-icon-emoji ":rocket:" \
|
|
908
921
|
--link-button "Open report::https://app.company.com/report"
|
|
909
922
|
|
|
923
|
+
# Approval flow — callback_url buttons (+ optional bearer auth on the POST)
|
|
924
|
+
dailybot chat send -u <user-uuid> -m "Deploy to prod?" \
|
|
925
|
+
--approve-button "Yes=approve" --reject-button "No=deny" \
|
|
926
|
+
--callback-url https://hooks.example.com/req42 --callback-bearer "$TOKEN"
|
|
927
|
+
|
|
928
|
+
# Fire an api_trigger workflow from a button click
|
|
929
|
+
dailybot chat send -c C0123 -m "Ready to release?" \
|
|
930
|
+
--workflow-button "Run release=<workflow-uuid>"
|
|
931
|
+
|
|
932
|
+
# Full button contract (modals, response trees, callback_prompt, …) via JSON
|
|
933
|
+
dailybot chat send -u <user-uuid> -m "Need details" --buttons '[
|
|
934
|
+
{"label":"Open","button_type":"interactive","value":"open",
|
|
935
|
+
"callback_url":"https://hooks.example.com/x",
|
|
936
|
+
"modal_body":{"title":"Notes","blocks":[
|
|
937
|
+
{"type":"input","name":"notes","label":"Notes","multiline":true}]}}]'
|
|
938
|
+
|
|
910
939
|
# Send with another user's identity, or as yourself (Slack only, admin-only)
|
|
911
940
|
dailybot chat send -c C0123 -m "Posting for the team" --send-as-user <user-uuid>
|
|
912
941
|
dailybot chat send -c C0123 -m "This one is from me" --send-as-me
|
|
@@ -106,6 +106,37 @@ def _merge_list_query(
|
|
|
106
106
|
return params
|
|
107
107
|
|
|
108
108
|
|
|
109
|
+
def _merge_dashboard_enrichment_query(
|
|
110
|
+
params: dict[str, Any],
|
|
111
|
+
*,
|
|
112
|
+
labels: list[str] | None = None,
|
|
113
|
+
featured: bool | None = None,
|
|
114
|
+
prioritize_featured: bool | None = None,
|
|
115
|
+
) -> dict[str, Any]:
|
|
116
|
+
"""Merge Labels / Featured dashboard enrichment query params."""
|
|
117
|
+
if labels:
|
|
118
|
+
params["labels"] = ",".join(labels)
|
|
119
|
+
if featured is not None:
|
|
120
|
+
params["featured"] = "true" if featured else "false"
|
|
121
|
+
if prioritize_featured is not None:
|
|
122
|
+
params["prioritize_featured"] = "true" if prioritize_featured else "false"
|
|
123
|
+
return params
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _label_entity_collection(entity_type: str) -> str:
|
|
127
|
+
"""Map CLI entity type (including web 'automations') to the public API path."""
|
|
128
|
+
normalized: str = entity_type.strip().lower()
|
|
129
|
+
if normalized in {"automations", "workflows", "workflow"}:
|
|
130
|
+
return "workflows"
|
|
131
|
+
if normalized in {"forms", "form"}:
|
|
132
|
+
return "forms"
|
|
133
|
+
if normalized in {"checkins", "checkin", "check-ins"}:
|
|
134
|
+
return "checkins"
|
|
135
|
+
raise ValueError(
|
|
136
|
+
f"entity type must be one of: forms, checkins, workflows (got {entity_type!r})"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
109
140
|
def _fill_meta(meta: dict[str, Any] | None, result: "PaginatedResult") -> None:
|
|
110
141
|
"""Populate a caller-provided meta dict with pagination totals, if given."""
|
|
111
142
|
if meta is not None:
|
|
@@ -640,6 +671,9 @@ class DailyBotClient:
|
|
|
640
671
|
fetch_all: bool = True,
|
|
641
672
|
limit: int | None = None,
|
|
642
673
|
meta: dict[str, Any] | None = None,
|
|
674
|
+
labels: list[str] | None = None,
|
|
675
|
+
featured: bool | None = None,
|
|
676
|
+
prioritize_featured: bool | None = None,
|
|
643
677
|
) -> list[dict[str, Any]]:
|
|
644
678
|
"""GET /v1/checkins/ — fetch visible check-ins with optional search/paging."""
|
|
645
679
|
params: dict[str, Any] = {}
|
|
@@ -652,6 +686,12 @@ class DailyBotClient:
|
|
|
652
686
|
if include_archived:
|
|
653
687
|
params["include_archived"] = "true"
|
|
654
688
|
_merge_list_query(params, search=search, start_date=start_date, end_date=end_date)
|
|
689
|
+
_merge_dashboard_enrichment_query(
|
|
690
|
+
params,
|
|
691
|
+
labels=labels,
|
|
692
|
+
featured=featured,
|
|
693
|
+
prioritize_featured=prioritize_featured,
|
|
694
|
+
)
|
|
655
695
|
result: PaginatedResult = self._paginated_get(
|
|
656
696
|
f"{self.api_url}/v1/checkins/",
|
|
657
697
|
params=params,
|
|
@@ -963,6 +1003,9 @@ class DailyBotClient:
|
|
|
963
1003
|
fetch_all: bool = True,
|
|
964
1004
|
limit: int | None = None,
|
|
965
1005
|
meta: dict[str, Any] | None = None,
|
|
1006
|
+
labels: list[str] | None = None,
|
|
1007
|
+
featured: bool | None = None,
|
|
1008
|
+
prioritize_featured: bool | None = None,
|
|
966
1009
|
) -> list[dict[str, Any]]:
|
|
967
1010
|
"""GET /v1/forms/ — optionally expand questions, search, and page.
|
|
968
1011
|
|
|
@@ -990,6 +1033,12 @@ class DailyBotClient:
|
|
|
990
1033
|
if is_ascend:
|
|
991
1034
|
params["is_ascend"] = "true"
|
|
992
1035
|
_merge_list_query(params, search=search, start_date=start_date, end_date=end_date)
|
|
1036
|
+
_merge_dashboard_enrichment_query(
|
|
1037
|
+
params,
|
|
1038
|
+
labels=labels,
|
|
1039
|
+
featured=featured,
|
|
1040
|
+
prioritize_featured=prioritize_featured,
|
|
1041
|
+
)
|
|
993
1042
|
result: PaginatedResult = self._paginated_get(
|
|
994
1043
|
f"{self.api_url}/v1/forms/",
|
|
995
1044
|
params=params,
|
|
@@ -1442,10 +1491,19 @@ class DailyBotClient:
|
|
|
1442
1491
|
fetch_all: bool = True,
|
|
1443
1492
|
limit: int | None = None,
|
|
1444
1493
|
meta: dict[str, Any] | None = None,
|
|
1494
|
+
labels: list[str] | None = None,
|
|
1495
|
+
featured: bool | None = None,
|
|
1496
|
+
prioritize_featured: bool | None = None,
|
|
1445
1497
|
) -> list[dict[str, Any]]:
|
|
1446
|
-
"""GET /v1/workflows/ — list workflows (
|
|
1498
|
+
"""GET /v1/workflows/ — list workflows (plan-gated feature)."""
|
|
1447
1499
|
params: dict[str, Any] = {}
|
|
1448
1500
|
_merge_list_query(params, search=search, start_date=start_date, end_date=end_date)
|
|
1501
|
+
_merge_dashboard_enrichment_query(
|
|
1502
|
+
params,
|
|
1503
|
+
labels=labels,
|
|
1504
|
+
featured=featured,
|
|
1505
|
+
prioritize_featured=prioritize_featured,
|
|
1506
|
+
)
|
|
1449
1507
|
result: PaginatedResult = self._paginated_get(
|
|
1450
1508
|
f"{self.api_url}/v1/workflows/",
|
|
1451
1509
|
params=params,
|
|
@@ -1464,6 +1522,30 @@ class DailyBotClient:
|
|
|
1464
1522
|
)
|
|
1465
1523
|
return self._handle_response(response)
|
|
1466
1524
|
|
|
1525
|
+
def trigger_workflow(
|
|
1526
|
+
self,
|
|
1527
|
+
workflow_uuid: str,
|
|
1528
|
+
*,
|
|
1529
|
+
payload: dict[str, Any] | None = None,
|
|
1530
|
+
) -> dict[str, Any]:
|
|
1531
|
+
"""POST /v1/workflows/<uuid>/trigger/ — queue an ``api_trigger`` workflow.
|
|
1532
|
+
|
|
1533
|
+
Only workflows whose trigger type is ``api_trigger`` ("When triggered via
|
|
1534
|
+
API or button") can be fired this way. The run is asynchronous — success
|
|
1535
|
+
is ``202 {queued: true, workflow_uuid, detail}`` with no run output.
|
|
1536
|
+
Optional *payload* (a JSON object ≤ 8 KiB) is exposed to workflow steps
|
|
1537
|
+
as ``{{trigger.body.*}}`` variables.
|
|
1538
|
+
"""
|
|
1539
|
+
body: dict[str, Any] = {}
|
|
1540
|
+
if payload is not None:
|
|
1541
|
+
body["payload"] = payload
|
|
1542
|
+
response: httpx.Response = self._request(
|
|
1543
|
+
"POST",
|
|
1544
|
+
f"{self.api_url}/v1/workflows/{workflow_uuid}/trigger/",
|
|
1545
|
+
json=body,
|
|
1546
|
+
)
|
|
1547
|
+
return self._handle_response(response)
|
|
1548
|
+
|
|
1467
1549
|
def list_kudos_organization(
|
|
1468
1550
|
self,
|
|
1469
1551
|
*,
|
|
@@ -1765,6 +1847,157 @@ class DailyBotClient:
|
|
|
1765
1847
|
)
|
|
1766
1848
|
return self._handle_response(response)
|
|
1767
1849
|
|
|
1850
|
+
# --- Organization Labels (/v1/labels/) ---
|
|
1851
|
+
|
|
1852
|
+
def get_labels_entitlement(self) -> dict[str, Any]:
|
|
1853
|
+
"""GET /v1/labels/entitlement/ — org Labels feature flags for the caller."""
|
|
1854
|
+
response: httpx.Response = self._request("GET", f"{self.api_url}/v1/labels/entitlement/")
|
|
1855
|
+
return self._handle_response(response)
|
|
1856
|
+
|
|
1857
|
+
def list_labels(
|
|
1858
|
+
self,
|
|
1859
|
+
*,
|
|
1860
|
+
search: str | None = None,
|
|
1861
|
+
is_archived: bool = False,
|
|
1862
|
+
limit: int = 20,
|
|
1863
|
+
offset: int = 0,
|
|
1864
|
+
) -> dict[str, Any]:
|
|
1865
|
+
"""GET /v1/labels/ — paginated org Labels (limit/offset)."""
|
|
1866
|
+
params: dict[str, Any] = {
|
|
1867
|
+
"limit": max(1, min(limit, 100)),
|
|
1868
|
+
"offset": max(0, offset),
|
|
1869
|
+
"is_archived": is_archived,
|
|
1870
|
+
}
|
|
1871
|
+
if search:
|
|
1872
|
+
params["search"] = search
|
|
1873
|
+
response: httpx.Response = self._request("GET", f"{self.api_url}/v1/labels/", params=params)
|
|
1874
|
+
return self._handle_response(response)
|
|
1875
|
+
|
|
1876
|
+
def get_label(self, label_uuid: str) -> dict[str, Any]:
|
|
1877
|
+
"""GET /v1/labels/<uuid>/ — one organization Label."""
|
|
1878
|
+
response: httpx.Response = self._request("GET", f"{self.api_url}/v1/labels/{label_uuid}/")
|
|
1879
|
+
return self._handle_response(response)
|
|
1880
|
+
|
|
1881
|
+
def create_label(
|
|
1882
|
+
self,
|
|
1883
|
+
*,
|
|
1884
|
+
name: str,
|
|
1885
|
+
color: str | None = None,
|
|
1886
|
+
description: str | None = None,
|
|
1887
|
+
) -> dict[str, Any]:
|
|
1888
|
+
"""POST /v1/labels/ — create an organization Label."""
|
|
1889
|
+
body: dict[str, Any] = {"name": name}
|
|
1890
|
+
if color is not None:
|
|
1891
|
+
body["color"] = color
|
|
1892
|
+
if description is not None:
|
|
1893
|
+
body["description"] = description
|
|
1894
|
+
response: httpx.Response = self._request("POST", f"{self.api_url}/v1/labels/", json=body)
|
|
1895
|
+
return self._handle_response(response)
|
|
1896
|
+
|
|
1897
|
+
def update_label(self, label_uuid: str, body: dict[str, Any]) -> dict[str, Any]:
|
|
1898
|
+
"""PATCH /v1/labels/<uuid>/ — update an organization Label."""
|
|
1899
|
+
response: httpx.Response = self._request(
|
|
1900
|
+
"PATCH", f"{self.api_url}/v1/labels/{label_uuid}/", json=body
|
|
1901
|
+
)
|
|
1902
|
+
return self._handle_response(response)
|
|
1903
|
+
|
|
1904
|
+
def delete_label(self, label_uuid: str) -> None:
|
|
1905
|
+
"""DELETE /v1/labels/<uuid>/ — hard-delete (elevated only)."""
|
|
1906
|
+
response: httpx.Response = self._request(
|
|
1907
|
+
"DELETE", f"{self.api_url}/v1/labels/{label_uuid}/"
|
|
1908
|
+
)
|
|
1909
|
+
if response.status_code == 204:
|
|
1910
|
+
return
|
|
1911
|
+
self._handle_response(response)
|
|
1912
|
+
|
|
1913
|
+
def archive_label(self, label_uuid: str) -> dict[str, Any]:
|
|
1914
|
+
"""POST /v1/labels/<uuid>/archive/ — archive a Label."""
|
|
1915
|
+
response: httpx.Response = self._request(
|
|
1916
|
+
"POST", f"{self.api_url}/v1/labels/{label_uuid}/archive/"
|
|
1917
|
+
)
|
|
1918
|
+
return self._handle_response(response)
|
|
1919
|
+
|
|
1920
|
+
def assign_entity_labels(
|
|
1921
|
+
self,
|
|
1922
|
+
entity_type: str,
|
|
1923
|
+
entity_uuid: str,
|
|
1924
|
+
label_uuids: list[str],
|
|
1925
|
+
) -> dict[str, Any]:
|
|
1926
|
+
"""POST /v1/{forms|checkins|workflows}/{uuid}/labels/ — replace-set Labels."""
|
|
1927
|
+
collection: str = _label_entity_collection(entity_type)
|
|
1928
|
+
response: httpx.Response = self._request(
|
|
1929
|
+
"POST",
|
|
1930
|
+
f"{self.api_url}/v1/{collection}/{entity_uuid}/labels/",
|
|
1931
|
+
json={"label_uuids": label_uuids},
|
|
1932
|
+
)
|
|
1933
|
+
return self._handle_response(response)
|
|
1934
|
+
|
|
1935
|
+
def batch_entity_labels(
|
|
1936
|
+
self,
|
|
1937
|
+
*,
|
|
1938
|
+
entity_type: str,
|
|
1939
|
+
entity_uuids: list[str],
|
|
1940
|
+
label_uuids: list[str],
|
|
1941
|
+
mode: str,
|
|
1942
|
+
) -> dict[str, Any]:
|
|
1943
|
+
"""POST /v1/{forms|checkins|workflows}/labels/batch/ — add/remove/replace."""
|
|
1944
|
+
collection: str = _label_entity_collection(entity_type)
|
|
1945
|
+
response: httpx.Response = self._request(
|
|
1946
|
+
"POST",
|
|
1947
|
+
f"{self.api_url}/v1/{collection}/labels/batch/",
|
|
1948
|
+
json={
|
|
1949
|
+
"entity_uuids": entity_uuids,
|
|
1950
|
+
"label_uuids": label_uuids,
|
|
1951
|
+
"mode": mode,
|
|
1952
|
+
},
|
|
1953
|
+
)
|
|
1954
|
+
return self._handle_response(response)
|
|
1955
|
+
|
|
1956
|
+
# --- Private Featured stars (/v1/me/featured/) ---
|
|
1957
|
+
|
|
1958
|
+
def list_featured(self, *, entity_type: str) -> dict[str, Any]:
|
|
1959
|
+
"""GET /v1/me/featured/?entity_type= — list Featured entity UUIDs for the caller."""
|
|
1960
|
+
response: httpx.Response = self._request(
|
|
1961
|
+
"GET",
|
|
1962
|
+
f"{self.api_url}/v1/me/featured/",
|
|
1963
|
+
params={"entity_type": entity_type},
|
|
1964
|
+
)
|
|
1965
|
+
return self._handle_response(response)
|
|
1966
|
+
|
|
1967
|
+
def set_featured(
|
|
1968
|
+
self,
|
|
1969
|
+
entity_type: str,
|
|
1970
|
+
entity_uuid: str,
|
|
1971
|
+
*,
|
|
1972
|
+
featured: bool,
|
|
1973
|
+
) -> dict[str, Any]:
|
|
1974
|
+
"""PUT /v1/me/featured/{entity_type}/{uuid}/ — toggle Featured for one entity."""
|
|
1975
|
+
response: httpx.Response = self._request(
|
|
1976
|
+
"PUT",
|
|
1977
|
+
f"{self.api_url}/v1/me/featured/{entity_type}/{entity_uuid}/",
|
|
1978
|
+
json={"featured": featured},
|
|
1979
|
+
)
|
|
1980
|
+
return self._handle_response(response)
|
|
1981
|
+
|
|
1982
|
+
def batch_featured(
|
|
1983
|
+
self,
|
|
1984
|
+
*,
|
|
1985
|
+
entity_type: str,
|
|
1986
|
+
entity_uuids: list[str],
|
|
1987
|
+
featured: bool,
|
|
1988
|
+
) -> dict[str, Any]:
|
|
1989
|
+
"""POST /v1/me/featured/batch/ — batch feature/unfeature entities."""
|
|
1990
|
+
response: httpx.Response = self._request(
|
|
1991
|
+
"POST",
|
|
1992
|
+
f"{self.api_url}/v1/me/featured/batch/",
|
|
1993
|
+
json={
|
|
1994
|
+
"entity_type": entity_type,
|
|
1995
|
+
"entity_uuids": entity_uuids,
|
|
1996
|
+
"featured": featured,
|
|
1997
|
+
},
|
|
1998
|
+
)
|
|
1999
|
+
return self._handle_response(response)
|
|
2000
|
+
|
|
1768
2001
|
# --- Agent registration endpoints ---
|
|
1769
2002
|
|
|
1770
2003
|
def get_registration_challenge(self) -> dict[str, Any]:
|