Skip to content
Open
16 changes: 10 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
## lifebit-ai/cloudos-cli: changelog

## v2.92.0 (2026-05-28)

### Feat:

- Moves `cloudos link` into the `interactive-session` module as `cloudos interactive-session link`
- File Explorer paths now infer the project name from the first path segment (e.g. `my-project/Data/folder`); standard top-level folder names (`Data`, `AnalysesResults`, `Analyses_Results`, `Analyses-Results`, `Cohorts`) are treated as relative to the profile project
- Removes `--mount` from `cloudos interactive-session create`
- Introduces `--copy` as an optional flag of `--link` in `cloudos interactive-session create` to copy data into the session


## v2.91.0 (2026-05-28)

### Feat:

- Implements linking of files in interactive session creation
- Implements linking of files in `cloudos link`
- Removes support for linking while resuming a paused interactive session
- Enforces a maximum of 100 linked items per interactive session
- Adds clearer, actionable error messages when mounts fail (e.g. translates "prefix does not exist" / "access denied" into workspace-permission guidance)

### Breaking:

- `cloudos link` and `cloudos datasets link`: File Explorer paths must now be RELATIVE to `--project-name` (do NOT prepend the project name). Previously the leading `<project>/` segment was advertised but produced confusing errors; it is now rejected up front with a clear message pointing to the correct form. `cloudos interactive-session create --link` still uses `<project>/<folder-path>` format — see each command's `--help` for the explicit cross-reference.


## v2.90.2 (2026-05-07)
Expand Down
231 changes: 116 additions & 115 deletions README.md

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions cloudos_cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from cloudos_cli.procurement.cli import procurement
from cloudos_cli.datasets.cli import datasets
from cloudos_cli.configure.cli import configure
from cloudos_cli.link.cli import link
from cloudos_cli.interactive_session.cli import interactive_session


Expand Down Expand Up @@ -63,7 +62,6 @@ def run_cloudos_cli(ctx):
run_cloudos_cli.add_command(procurement)
run_cloudos_cli.add_command(datasets)
run_cloudos_cli.add_command(configure)
run_cloudos_cli.add_command(link)
run_cloudos_cli.add_command(interactive_session)

if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion cloudos_cli/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.91.0'
__version__ = '2.92.0'
28 changes: 11 additions & 17 deletions cloudos_cli/datasets/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import csv
import sys
from cloudos_cli.datasets import Datasets
from cloudos_cli.link import Link
from cloudos_cli.interactive_session.link import Link
from cloudos_cli.utils.resources import ssl_selector, format_bytes
from cloudos_cli.configure.configure import with_profile_config, CLOUDOS_URL
from cloudos_cli.logging.logger import update_command_context_from_click
Expand Down Expand Up @@ -326,17 +326,17 @@ def move_files(ctx, source_path, destination_path, apikey, cloudos_url, workspac
if folder_type in ("VirtualFolder", "Folder"):
target_kind = "Folder"
elif folder_type == "S3Folder":
raise ValueError(f"Unable to move item '{source_item_name}' to '{destination_path}'. " +
"The destination is an S3 folder, and only virtual folders can be selected as valid move destinations.")
raise ValueError(f"Unable to move item '{source_item_name}' to '{destination_path}'. "
"The destination is an S3 folder, and only virtual folders can be selected as valid move destinations.")
elif isinstance(folder_type, bool) and folder_type: # legacy dataset structure
target_kind = "Dataset"
else:
raise ValueError(f"Unrecognized folderType '{folder_type}' for destination '{destination_path}'")

except Exception as e:
raise ValueError(f"Could not resolve destination path '{destination_path}'. {str(e)}")
print(f"Moving {source_kind} '{source_item_name}' to '{destination_path}' " +
f"in project '{destination_project_name} ...")
print(f"Moving {source_kind} '{source_item_name}' to '{destination_path}' "
f"in project '{destination_project_name} ...")
# === Perform Move ===
try:
response = source_client.move_files_and_folders(
Expand Down Expand Up @@ -756,11 +756,10 @@ def link(ctx,
"""
Link a file or folder (S3 or File Explorer) to an active interactive analysis.

PATH [path]: the full path to the S3 file/folder, or a path RELATIVE to
the project named in --project-name for File Explorer items. Do NOT
prepend the project name to File Explorer paths.
PATH [path]: the full path to the S3 file/folder or relative path in File Explorer
(relative to the project specified by --project-name).
E.g.: 's3://bucket-name/folder/subfolder', 's3://bucket/data/file.csv',
'Data/Downloads', 'Data/file.csv'.
'Data/Downloads', 'Data', or 'Data/file.csv'.
"""
if not path.startswith("s3://") and project_name is None:
raise click.UsageError("When using File Explorer paths '--project-name' needs to be defined")
Expand All @@ -777,13 +776,8 @@ def link(ctx,
)

try:
succeeded = link_p.link_folder(path, session_id)
success = link_p.link_folder(path, session_id)
except Exception as e:
Comment thread
l-mansouri marked this conversation as resolved.
raise ValueError(f"Could not link item. {e}")

if not succeeded:
click.secho(
"Linking did not complete successfully. See errors above.",
fg='red', err=True,
)
raise SystemExit(1)
if not success:
raise click.ClickException("Linking failed: mount verification did not reach 'mounted' status.")
4 changes: 4 additions & 0 deletions cloudos_cli/interactive_session/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
"""CloudOS interactive session module."""

from .link import Link

__all__ = ['Link']
Loading
Loading