better-notion 2.2.0__py3-none-any.whl → 2.3.2__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.
@@ -956,6 +956,38 @@ class AgentsPlugin(CombinedPluginInterface):
956
956
  def tasks_list_unassigned_cmd():
957
957
  typer.echo(agents_cli.tasks_list_unassigned())
958
958
 
959
+ @tasks_app.command("search")
960
+ def tasks_search_cmd(
961
+ query: str = typer.Argument(..., help="Search query"),
962
+ status: str = typer.Option(None, "--status", "-s", help="Filter by status"),
963
+ priority: str = typer.Option(None, "--priority", "-p", help="Filter by priority"),
964
+ assignee: str = typer.Option(None, "--assignee", "-a", help="Filter by assignee"),
965
+ project_id: str = typer.Option(None, "--project-id", help="Filter by project ID"),
966
+ version_id: str = typer.Option(None, "--version-id", help="Filter by version ID"),
967
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
968
+ ):
969
+ typer.echo(agents_cli.tasks_search(query, status, priority, assignee, project_id, version_id, limit))
970
+
971
+ @tasks_app.command("pick")
972
+ def tasks_pick_cmd(
973
+ skills: str = typer.Option(None, "--skills", "-s", help="Comma-separated skills"),
974
+ max_priority: str = typer.Option(None, "--max-priority", help="Maximum priority"),
975
+ exclude: str = typer.Option(None, "--exclude", help="Comma-separated exclude patterns"),
976
+ count: int = typer.Option(5, "--count", "-n", help="Number of recommendations"),
977
+ project_id: str = typer.Option(None, "--project-id", help="Filter by project"),
978
+ version_id: str = typer.Option(None, "--version-id", help="Filter by version"),
979
+ ):
980
+ typer.echo(agents_cli.tasks_pick(skills, max_priority, exclude, count, project_id, version_id))
981
+
982
+ @tasks_app.command("suggest")
983
+ def tasks_suggest_cmd(
984
+ unassigned: bool = typer.Option(False, "--unassigned", "-u", help="Only suggest unassigned tasks"),
985
+ priority: str = typer.Option(None, "--priority", "-p", help="Comma-separated priorities"),
986
+ count: int = typer.Option(5, "--count", "-n", help="Number of suggestions"),
987
+ reason: bool = typer.Option(False, "--reason", "-r", help="Include reasoning"),
988
+ ):
989
+ typer.echo(agents_cli.tasks_suggest(unassigned, priority, count, reason))
990
+
959
991
  agents_app.add_typer(tasks_app)
960
992
 
961
993
  # Ideas commands (under agents)
@@ -1000,6 +1032,16 @@ class AgentsPlugin(CombinedPluginInterface):
1000
1032
  ):
1001
1033
  typer.echo(agents_cli.ideas_reject(idea_id, reason))
1002
1034
 
1035
+ @ideas_app.command("search")
1036
+ def ideas_search_cmd(
1037
+ query: str = typer.Argument(..., help="Search query"),
1038
+ status: str = typer.Option(None, "--status", "-s", help="Filter by status"),
1039
+ category: str = typer.Option(None, "--category", "-c", help="Filter by category"),
1040
+ project_id: str = typer.Option(None, "--project-id", help="Filter by project ID"),
1041
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
1042
+ ):
1043
+ typer.echo(agents_cli.ideas_search(query, status, category, project_id, limit))
1044
+
1003
1045
  agents_app.add_typer(ideas_app)
1004
1046
 
1005
1047
  # Work Issues commands (under agents)
@@ -1044,6 +1086,17 @@ class AgentsPlugin(CombinedPluginInterface):
1044
1086
  def work_issues_list_blocked_by_cmd(work_issue_id: str):
1045
1087
  typer.echo(agents_cli.work_issues_list_blocked_by(work_issue_id))
1046
1088
 
1089
+ @work_issues_app.command("search")
1090
+ def work_issues_search_cmd(
1091
+ query: str = typer.Argument(..., help="Search query"),
1092
+ status: str = typer.Option(None, "--status", "-s", help="Filter by status"),
1093
+ type_: str = typer.Option(None, "--type", "-t", help="Filter by type"),
1094
+ severity: str = typer.Option(None, "--severity", help="Filter by severity"),
1095
+ project_id: str = typer.Option(None, "--project-id", help="Filter by project ID"),
1096
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
1097
+ ):
1098
+ typer.echo(agents_cli.work_issues_search(query, status, type_, severity, project_id, limit))
1099
+
1047
1100
  agents_app.add_typer(work_issues_app)
1048
1101
 
1049
1102
  # Incidents commands (under agents)
@@ -1103,6 +1156,21 @@ class AgentsPlugin(CombinedPluginInterface):
1103
1156
  def incidents_list_caused_by_cmd(work_issue_id: str):
1104
1157
  typer.echo(agents_cli.incidents_list_caused_by(work_issue_id))
1105
1158
 
1159
+ @incidents_app.command("search")
1160
+ def incidents_search_cmd(
1161
+ query: str = typer.Argument(..., help="Search query"),
1162
+ status: str = typer.Option(None, "--status", "-s", help="Filter by status"),
1163
+ severity: str = typer.Option(None, "--severity", help="Filter by severity"),
1164
+ type_: str = typer.Option(None, "--type", "-t", help="Filter by incident type"),
1165
+ project_id: str = typer.Option(None, "--project-id", help="Filter by project ID"),
1166
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
1167
+ ):
1168
+ typer.echo(agents_cli.incidents_search(query, status, severity, type_, project_id, limit))
1169
+
1170
+ @incidents_app.command("triage")
1171
+ def incidents_triage_cmd(incident_id: str = typer.Argument(..., help="Incident ID to triage")):
1172
+ typer.echo(agents_cli.incidents_triage(incident_id))
1173
+
1106
1174
  agents_app.add_typer(incidents_app)
1107
1175
 
1108
1176
  def register_sdk_models(self) -> dict[str, type]:
@@ -1101,6 +1101,167 @@ def tasks_list_unassigned() -> str:
1101
1101
  return asyncio.run(_list_unassigned())
1102
1102
 
1103
1103
 
1104
+ def tasks_search(
1105
+ query: str = typer.Argument(..., help="Search query"),
1106
+ status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status"),
1107
+ priority: Optional[str] = typer.Option(None, "--priority", "-p", help="Filter by priority"),
1108
+ assignee: Optional[str] = typer.Option(None, "--assignee", "-a", help="Filter by assignee"),
1109
+ project_id: Optional[str] = typer.Option(None, "--project-id", help="Filter by project ID"),
1110
+ version_id: Optional[str] = typer.Option(None, "--version-id", help="Filter by version ID"),
1111
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
1112
+ ) -> str:
1113
+ """
1114
+ Search tasks by text query with optional filters.
1115
+
1116
+ Args:
1117
+ query: Text to search for in task titles and descriptions
1118
+ status: Optional status filter
1119
+ priority: Optional priority filter
1120
+ assignee: Optional assignee filter
1121
+ project_id: Optional project ID filter
1122
+ version_id: Optional version ID filter
1123
+ limit: Maximum number of results
1124
+
1125
+ Example:
1126
+ $ notion tasks search "authentication" --status Backlog --priority High
1127
+ """
1128
+ async def _search() -> str:
1129
+ try:
1130
+ client = get_client()
1131
+
1132
+ # Register SDK plugin
1133
+ register_agents_sdk_plugin(client)
1134
+
1135
+ # Search tasks
1136
+ manager = client.plugin_manager("tasks")
1137
+ results = await manager.search(
1138
+ query=query,
1139
+ status=status,
1140
+ priority=priority,
1141
+ assignee=assignee,
1142
+ project_id=project_id,
1143
+ version_id=version_id,
1144
+ limit=limit,
1145
+ )
1146
+
1147
+ return format_success({
1148
+ "results": results,
1149
+ "total": len(results),
1150
+ })
1151
+
1152
+ except Exception as e:
1153
+ return format_error("SEARCH_ERROR", str(e), retry=False)
1154
+
1155
+ return asyncio.run(_search())
1156
+
1157
+
1158
+ def tasks_pick(
1159
+ skills: Optional[str] = typer.Option(None, "--skills", "-s", help="Comma-separated skills"),
1160
+ max_priority: Optional[str] = typer.Option(None, "--max-priority", help="Maximum priority"),
1161
+ exclude: Optional[str] = typer.Option(None, "--exclude", help="Comma-separated exclude patterns"),
1162
+ count: int = typer.Option(5, "--count", "-n", help="Number of recommendations"),
1163
+ project_id: Optional[str] = typer.Option(None, "--project-id", help="Filter by project"),
1164
+ version_id: Optional[str] = typer.Option(None, "--version-id", help="Filter by version"),
1165
+ ) -> str:
1166
+ """
1167
+ Pick the best tasks for an agent to work on.
1168
+
1169
+ Args:
1170
+ skills: Comma-separated list of agent skills (e.g., "python,database")
1171
+ max_priority: Maximum priority to consider
1172
+ exclude: Comma-separated regex patterns to exclude
1173
+ count: Maximum number of recommendations
1174
+ project_id: Optional project filter
1175
+ version_id: Optional version filter
1176
+
1177
+ Example:
1178
+ $ notion tasks pick --skills "python,api" --max-priority High --count 3
1179
+ """
1180
+ async def _pick() -> str:
1181
+ try:
1182
+ client = get_client()
1183
+
1184
+ # Register SDK plugin
1185
+ register_agents_sdk_plugin(client)
1186
+
1187
+ # Parse skills and exclude patterns
1188
+ skills_list = skills.split(",") if skills else None
1189
+ exclude_patterns = exclude.split(",") if exclude else None
1190
+
1191
+ # Pick tasks
1192
+ manager = client.plugin_manager("tasks")
1193
+ recommendations = await manager.pick(
1194
+ skills=skills_list,
1195
+ max_priority=max_priority,
1196
+ exclude_patterns=exclude_patterns,
1197
+ count=count,
1198
+ project_id=project_id,
1199
+ version_id=version_id,
1200
+ )
1201
+
1202
+ return format_success({
1203
+ "recommended": recommendations,
1204
+ "total": len(recommendations),
1205
+ })
1206
+
1207
+ except Exception as e:
1208
+ return format_error("PICK_ERROR", str(e), retry=False)
1209
+
1210
+ return asyncio.run(_pick())
1211
+
1212
+
1213
+ def tasks_suggest(
1214
+ unassigned: bool = typer.Option(False, "--unassigned", "-u", help="Only suggest unassigned tasks"),
1215
+ priority: Optional[str] = typer.Option(None, "--priority", "-p", help="Comma-separated priorities"),
1216
+ count: int = typer.Option(5, "--count", "-n", help="Number of suggestions"),
1217
+ reason: bool = typer.Option(False, "--reason", "-r", help="Include reasoning"),
1218
+ ) -> str:
1219
+ """
1220
+ Suggest tasks based on criteria.
1221
+
1222
+ Args:
1223
+ unassigned: Only suggest unassigned tasks
1224
+ priority: Comma-separated priority levels (e.g., "Critical,High")
1225
+ count: Maximum number of suggestions
1226
+ reason: Include reasoning in output
1227
+
1228
+ Example:
1229
+ $ notion tasks suggest --unassigned --priority "Critical,High" --count 5
1230
+ """
1231
+ async def _suggest() -> str:
1232
+ try:
1233
+ client = get_client()
1234
+
1235
+ # Register SDK plugin
1236
+ register_agents_sdk_plugin(client)
1237
+
1238
+ # Parse priority list
1239
+ priority_list = priority.split(",") if priority else None
1240
+
1241
+ # Get suggestions
1242
+ manager = client.plugin_manager("tasks")
1243
+ suggestions = await manager.suggest(
1244
+ unassigned=unassigned,
1245
+ priority=priority_list,
1246
+ count=count,
1247
+ )
1248
+
1249
+ result = {
1250
+ "suggestions": suggestions,
1251
+ "total": len(suggestions),
1252
+ }
1253
+
1254
+ if reason:
1255
+ result["reasoning"] = f"Showing top {len(suggestions)} tasks matching criteria"
1256
+
1257
+ return format_success(result)
1258
+
1259
+ except Exception as e:
1260
+ return format_error("SUGGEST_ERROR", str(e), retry=False)
1261
+
1262
+ return asyncio.run(_suggest())
1263
+
1264
+
1104
1265
  # ===== IDEAS =====
1105
1266
 
1106
1267
  def ideas_list(
@@ -1404,6 +1565,54 @@ def ideas_reject(idea_id: str, reason: str = "") -> str:
1404
1565
  return asyncio.run(_reject())
1405
1566
 
1406
1567
 
1568
+ def ideas_search(
1569
+ query: str = typer.Argument(..., help="Search query"),
1570
+ status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status"),
1571
+ category: Optional[str] = typer.Option(None, "--category", "-c", help="Filter by category"),
1572
+ project_id: Optional[str] = typer.Option(None, "--project-id", help="Filter by project ID"),
1573
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
1574
+ ) -> str:
1575
+ """
1576
+ Search ideas by text query with optional filters.
1577
+
1578
+ Args:
1579
+ query: Text to search for in idea titles and descriptions
1580
+ status: Optional status filter
1581
+ category: Optional category filter
1582
+ project_id: Optional project ID filter
1583
+ limit: Maximum number of results
1584
+
1585
+ Example:
1586
+ $ notion ideas search "dark mode" --status Accepted --category Feature
1587
+ """
1588
+ async def _search() -> str:
1589
+ try:
1590
+ client = get_client()
1591
+
1592
+ # Register SDK plugin
1593
+ register_agents_sdk_plugin(client)
1594
+
1595
+ # Search ideas
1596
+ manager = client.plugin_manager("ideas")
1597
+ results = await manager.search(
1598
+ query=query,
1599
+ status=status,
1600
+ category=category,
1601
+ project_id=project_id,
1602
+ limit=limit,
1603
+ )
1604
+
1605
+ return format_success({
1606
+ "results": results,
1607
+ "total": len(results),
1608
+ })
1609
+
1610
+ except Exception as e:
1611
+ return format_error("SEARCH_ERROR", str(e), retry=False)
1612
+
1613
+ return asyncio.run(_search())
1614
+
1615
+
1407
1616
  # ===== WORK ISSUES =====
1408
1617
 
1409
1618
  def work_issues_list(
@@ -1702,6 +1911,57 @@ def work_issues_list_blocked_by(work_issue_id: str) -> str:
1702
1911
  return asyncio.run(_list_blocked_by())
1703
1912
 
1704
1913
 
1914
+ def work_issues_search(
1915
+ query: str = typer.Argument(..., help="Search query"),
1916
+ status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status"),
1917
+ type_: Optional[str] = typer.Option(None, "--type", "-t", help="Filter by type"),
1918
+ severity: Optional[str] = typer.Option(None, "--severity", help="Filter by severity"),
1919
+ project_id: Optional[str] = typer.Option(None, "--project-id", help="Filter by project ID"),
1920
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
1921
+ ) -> str:
1922
+ """
1923
+ Search work issues by text query with optional filters.
1924
+
1925
+ Args:
1926
+ query: Text to search for in work issue titles and descriptions
1927
+ status: Optional status filter
1928
+ type_: Optional type filter
1929
+ severity: Optional severity filter
1930
+ project_id: Optional project ID filter
1931
+ limit: Maximum number of results
1932
+
1933
+ Example:
1934
+ $ notion work-issues search "memory leak" --severity High --status Open
1935
+ """
1936
+ async def _search() -> str:
1937
+ try:
1938
+ client = get_client()
1939
+
1940
+ # Register SDK plugin
1941
+ register_agents_sdk_plugin(client)
1942
+
1943
+ # Search work issues
1944
+ manager = client.plugin_manager("work_issues")
1945
+ results = await manager.search(
1946
+ query=query,
1947
+ status=status,
1948
+ type_=type_,
1949
+ severity=severity,
1950
+ project_id=project_id,
1951
+ limit=limit,
1952
+ )
1953
+
1954
+ return format_success({
1955
+ "results": results,
1956
+ "total": len(results),
1957
+ })
1958
+
1959
+ except Exception as e:
1960
+ return format_error("SEARCH_ERROR", str(e), retry=False)
1961
+
1962
+ return asyncio.run(_search())
1963
+
1964
+
1705
1965
  # ===== INCIDENTS =====
1706
1966
 
1707
1967
  def incidents_list(
@@ -2095,3 +2355,90 @@ def incidents_list_caused_by(work_issue_id: str) -> str:
2095
2355
  return format_error("LIST_CAUSED_BY_ERROR", str(e), retry=False)
2096
2356
 
2097
2357
  return asyncio.run(_list_caused_by())
2358
+
2359
+
2360
+ def incidents_search(
2361
+ query: str = typer.Argument(..., help="Search query"),
2362
+ status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status"),
2363
+ severity: Optional[str] = typer.Option(None, "--severity", help="Filter by severity"),
2364
+ type_: Optional[str] = typer.Option(None, "--type", "-t", help="Filter by incident type"),
2365
+ project_id: Optional[str] = typer.Option(None, "--project-id", help="Filter by project ID"),
2366
+ limit: int = typer.Option(50, "--limit", "-n", help="Maximum results"),
2367
+ ) -> str:
2368
+ """
2369
+ Search incidents by text query with optional filters.
2370
+
2371
+ Args:
2372
+ query: Text to search for in incident titles and descriptions
2373
+ status: Optional status filter
2374
+ severity: Optional severity filter
2375
+ type_: Optional incident type filter
2376
+ project_id: Optional project ID filter
2377
+ limit: Maximum number of results
2378
+
2379
+ Example:
2380
+ $ notion incidents search "database" --severity Critical --status Open
2381
+ """
2382
+ async def _search() -> str:
2383
+ try:
2384
+ client = get_client()
2385
+
2386
+ # Register SDK plugin
2387
+ register_agents_sdk_plugin(client)
2388
+
2389
+ # Search incidents
2390
+ manager = client.plugin_manager("incidents")
2391
+ results = await manager.search(
2392
+ query=query,
2393
+ status=status,
2394
+ severity=severity,
2395
+ incident_type=type_,
2396
+ project_id=project_id,
2397
+ limit=limit,
2398
+ )
2399
+
2400
+ return format_success({
2401
+ "results": results,
2402
+ "total": len(results),
2403
+ })
2404
+
2405
+ except Exception as e:
2406
+ return format_error("SEARCH_ERROR", str(e), retry=False)
2407
+
2408
+ return asyncio.run(_search())
2409
+
2410
+
2411
+ def incidents_triage(
2412
+ incident_id: str = typer.Argument(..., help="Incident ID to triage"),
2413
+ ) -> str:
2414
+ """
2415
+ Triage and classify an incident.
2416
+
2417
+ Uses AI to classify the incident by severity, type, and suggest team assignment.
2418
+
2419
+ Args:
2420
+ incident_id: Incident ID to triage
2421
+
2422
+ Example:
2423
+ $ notion incidents triage inc_123
2424
+ """
2425
+ async def _triage() -> str:
2426
+ try:
2427
+ client = get_client()
2428
+
2429
+ # Register SDK plugin
2430
+ register_agents_sdk_plugin(client)
2431
+
2432
+ # Triage incident
2433
+ manager = client.plugin_manager("incidents")
2434
+ result = await manager.triage(incident_id)
2435
+
2436
+ return format_success({
2437
+ "incident_id": incident_id,
2438
+ "triage": result,
2439
+ })
2440
+
2441
+ except Exception as e:
2442
+ return format_error("TRIAGE_ERROR", str(e), retry=False)
2443
+
2444
+ return asyncio.run(_triage())