unique-sdk 2026.46.0.dev5__tar.gz → 2026.48.0.dev0__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 (92) hide show
  1. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/PKG-INFO +1 -1
  2. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/pyproject.toml +1 -1
  3. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/navigation.py +4 -8
  4. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/search.py +10 -0
  5. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/state.py +12 -4
  6. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/README.md +0 -0
  7. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/__init__.py +0 -0
  8. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_api_requestor.py +0 -0
  9. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_api_resource.py +0 -0
  10. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_api_version.py +0 -0
  11. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_error.py +0 -0
  12. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_http_client.py +0 -0
  13. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_list_object.py +0 -0
  14. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_object_classes.py +0 -0
  15. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_request_options.py +0 -0
  16. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_unique_object.py +0 -0
  17. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_unique_ql.py +0 -0
  18. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_unique_response.py +0 -0
  19. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_util.py +0 -0
  20. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_version.py +0 -0
  21. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/_webhook.py +0 -0
  22. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/__init__.py +0 -0
  23. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_acronyms.py +0 -0
  24. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_agentic_table.py +0 -0
  25. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_analytics_order.py +0 -0
  26. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_benchmarking.py +0 -0
  27. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_briefing.py +0 -0
  28. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_chat_completion.py +0 -0
  29. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_content.py +0 -0
  30. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_context_memory.py +0 -0
  31. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_elicitation.py +0 -0
  32. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_embedding.py +0 -0
  33. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_event.py +0 -0
  34. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_folder.py +0 -0
  35. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_group.py +0 -0
  36. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_integrated.py +0 -0
  37. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_llm_models.py +0 -0
  38. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_mcp.py +0 -0
  39. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_message.py +0 -0
  40. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_message_assessment.py +0 -0
  41. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_message_execution.py +0 -0
  42. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_message_log.py +0 -0
  43. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_message_tool.py +0 -0
  44. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_module.py +0 -0
  45. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_scheduled_task.py +0 -0
  46. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_search.py +0 -0
  47. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_search_string.py +0 -0
  48. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_short_term_memory.py +0 -0
  49. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_space.py +0 -0
  50. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_user.py +0 -0
  51. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/api_resources/_web_search.py +0 -0
  52. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/__init__.py +0 -0
  53. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/__main__.py +0 -0
  54. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/cli.py +0 -0
  55. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/__init__.py +0 -0
  56. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/_citation_manifest.py +0 -0
  57. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/agentic_table.py +0 -0
  58. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/agentic_table_write.py +0 -0
  59. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/browser.py +0 -0
  60. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/cite_file.py +0 -0
  61. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/elicitation.py +0 -0
  62. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/files.py +0 -0
  63. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/folders.py +0 -0
  64. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/mcp.py +0 -0
  65. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/read.py +0 -0
  66. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/scheduled_tasks.py +0 -0
  67. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/subagent.py +0 -0
  68. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/web_search.py +0 -0
  69. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/commands/web_search_config.py +0 -0
  70. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/config.py +0 -0
  71. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/formatting.py +0 -0
  72. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/identity.py +0 -0
  73. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/metadata_filter.py +0 -0
  74. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/paths.py +0 -0
  75. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/shell.py +0 -0
  76. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-agentic-table/SKILL.md +0 -0
  77. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-elicitation/SKILL.md +0 -0
  78. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-file-management/SKILL.md +0 -0
  79. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-mcp/SKILL.md +0 -0
  80. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-scheduled-tasks/SKILL.md +0 -0
  81. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-search/SKILL.md +0 -0
  82. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-subagent/SKILL.md +0 -0
  83. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-uploaded-search/SKILL.md +0 -0
  84. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/skills/unique-cli-web-search/SKILL.md +0 -0
  85. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/cli/workspace.py +0 -0
  86. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/analytics_order_run.py +0 -0
  87. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/benchmarking_run.py +0 -0
  88. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/chat_history.py +0 -0
  89. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/chat_in_space.py +0 -0
  90. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/file_io.py +0 -0
  91. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/sources.py +0 -0
  92. {unique_sdk-2026.46.0.dev5 → unique_sdk-2026.48.0.dev0}/unique_sdk/utils/token.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-sdk
3
- Version: 2026.46.0.dev5
3
+ Version: 2026.48.0.dev0
4
4
  Summary:
5
5
  Author: Martin Fadler, Konstantin Krauss, Andreas Hauri
6
6
  Author-email: Martin Fadler <martin.fadler@unique.ch>, Konstantin Krauss <konstantin@unique.ch>, Andreas Hauri <andreas@unique.ch>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_sdk"
3
- version = "2026.46.0.dev5"
3
+ version = "2026.48.0.dev0"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -184,14 +184,10 @@ def cmd_ls(
184
184
  else:
185
185
  resolved_path, scope_id = state.cwd, state.scope_id
186
186
 
187
- # A non-root target must lie inside the per-message scope: without
188
- # this, `ls <path>` would enumerate out-of-scope folders/files that
189
- # read/cite correctly deny. See UN-21780.
190
- if (
191
- scope_id is not None
192
- and state.workspace_metadata_filter is not None
193
- and not state.folder_allowed_by_metadata_filter(scope_id)
194
- ):
187
+ # A non-root target must lie inside the task scope: without this,
188
+ # `ls <path>` would enumerate out-of-scope folders/files that
189
+ # read/cite correctly deny. See UN-21780 and UN-28458.
190
+ if scope_id is not None and not state.folder_navigable(scope_id):
195
191
  return (
196
192
  f"ls: permission denied: target is outside your task scope "
197
193
  f"({state.scope_denial_hint()})."
@@ -214,6 +214,16 @@ def cmd_search(
214
214
  folder_scope_id: str | None = None
215
215
  if folder:
216
216
  folder_scope_id = _resolve_folder_to_scope_id(state, folder)
217
+ # Without a per-message filter, --folder replaces the static
218
+ # scopeIds, so it must lie inside them. See UN-28458.
219
+ if (
220
+ not state.workspace_metadata_filter
221
+ and not state.is_folder_target_within_workspace(folder_scope_id)
222
+ ):
223
+ return (
224
+ f"{SEARCH_ERROR_PREFIX} permission denied: {folder} is "
225
+ f"outside your task scope ({state.scope_denial_hint()})."
226
+ )
217
227
  elif state.scope_id and not state.workspace_metadata_filter:
218
228
  # The incidental cwd narrows search only when there is no
219
229
  # per-message filter. With a filter active, only an explicit
@@ -468,6 +468,16 @@ class ShellState:
468
468
  return True
469
469
  return self._metadata_filter.allows_folder_scope(scope_id)
470
470
 
471
+ def folder_navigable(self, scope_id: str) -> bool:
472
+ """True if ``ls``/``cd`` may open *scope_id* under the active scope.
473
+
474
+ The per-message filter decides when present; otherwise a non-empty
475
+ ``scopeIds`` list admits only those folders and their descendants.
476
+ """
477
+ if self._metadata_filter is not None:
478
+ return self.folder_allowed_by_metadata_filter(scope_id)
479
+ return self.is_folder_target_within_workspace(scope_id)
480
+
471
481
  def folder_path_allowed_by_metadata_filter(self, folder_path: str) -> bool:
472
482
  """True if an absolute folder *path* lies within a navigable scope.
473
483
 
@@ -564,10 +574,8 @@ class ShellState:
564
574
  return f"{self._path}> "
565
575
 
566
576
  def _require_navigable_folder(self, scope_id: str) -> None:
567
- """Refuse a folder the per-message filter excludes. See UN-28458."""
568
- if self._metadata_filter is None:
569
- return
570
- if self.folder_allowed_by_metadata_filter(scope_id):
577
+ """Refuse a folder outside the active scope. See UN-28458."""
578
+ if self.folder_navigable(scope_id):
571
579
  return
572
580
  raise ValueError(
573
581
  "permission denied: target is outside your task scope "