google-colab-cli 0.5.7__tar.gz → 0.5.8__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 (76) hide show
  1. google_colab_cli-0.5.8/PKG-INFO +203 -0
  2. google_colab_cli-0.5.8/README.md +181 -0
  3. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/04_automation_and_utility.md +27 -3
  4. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/pyproject.toml +4 -0
  5. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/auto_update.py +21 -5
  6. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/cli.py +4 -0
  7. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/run.py +1 -1
  8. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/session.py +3 -3
  9. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/utility.py +49 -3
  10. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/runtime.py +1 -1
  11. google_colab_cli-0.5.8/tests/test_readme.py +92 -0
  12. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_update.py +104 -9
  13. google_colab_cli-0.5.7/PKG-INFO +0 -126
  14. google_colab_cli-0.5.7/README.md +0 -104
  15. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/.githooks/pre-commit +0 -0
  16. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/.gitignore +0 -0
  17. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/.pre-commit-config.yaml +0 -0
  18. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/.python-version +0 -0
  19. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/AGENTS.md +0 -0
  20. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/COLAB_SKILL.md +0 -0
  21. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/CONTRIBUTING.md +0 -0
  22. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/LICENSE +0 -0
  23. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/cloudbuild.yaml +0 -0
  24. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/01_session_management.md +0 -0
  25. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/02_execution_and_interactive.md +0 -0
  26. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/03_file_management.md +0 -0
  27. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/05_run_command.md +0 -0
  28. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/3042ab12-2026-05-07.png +0 -0
  29. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/docs/demos.md +0 -0
  30. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/README.md +0 -0
  31. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/repro_keep_alive/test.sh +0 -0
  32. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/repro_keep_alive_scope/test.sh +0 -0
  33. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/repro_piped_console/test.sh +0 -0
  34. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/repro_plot_redirection/test.sh +0 -0
  35. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/repro_run_command/test.sh +0 -0
  36. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/integration/repro_variable_persistence/test.sh +0 -0
  37. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/auth.py +0 -0
  38. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/client.py +0 -0
  39. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/__init__.py +0 -0
  40. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/automation.py +0 -0
  41. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/execution.py +0 -0
  42. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/commands/files.py +0 -0
  43. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/common.py +0 -0
  44. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/console.py +0 -0
  45. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/contents.py +0 -0
  46. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/converter.py +0 -0
  47. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/history.py +0 -0
  48. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/repl.py +0 -0
  49. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/state.py +0 -0
  50. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/src/colab_cli/utils.py +0 -0
  51. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/conftest.py +0 -0
  52. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_auth.py +0 -0
  53. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_auth_adc.py +0 -0
  54. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_automation.py +0 -0
  55. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_cli.py +0 -0
  56. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_cli_log.py +0 -0
  57. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_client.py +0 -0
  58. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_console.py +0 -0
  59. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_contents.py +0 -0
  60. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_exec.py +0 -0
  61. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_history.py +0 -0
  62. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_ipynb_exec.py +0 -0
  63. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_keep_alive.py +0 -0
  64. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_log_export.py +0 -0
  65. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_pay.py +0 -0
  66. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_repl.py +0 -0
  67. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_resolution_logic.py +0 -0
  68. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_run.py +0 -0
  69. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_runtime.py +0 -0
  70. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_state.py +0 -0
  71. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_streaming.py +0 -0
  72. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_url.py +0 -0
  73. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_utils.py +0 -0
  74. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_version.py +0 -0
  75. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/tests/test_whoami.py +0 -0
  76. {google_colab_cli-0.5.7 → google_colab_cli-0.5.8}/uv.lock +0 -0
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: google-colab-cli
3
+ Version: 0.5.8
4
+ Summary: CLI for interacting with Colab.
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: click>=8.0
8
+ Requires-Dist: google-auth-oauthlib>=1.3.0
9
+ Requires-Dist: google-auth>=2.49.1
10
+ Requires-Dist: jupyter-kernel-client
11
+ Requires-Dist: nbformat>=5.10.4
12
+ Requires-Dist: packaging>=24.0
13
+ Requires-Dist: prompt-toolkit>=3.0.52
14
+ Requires-Dist: pydantic>=2.12.5
15
+ Requires-Dist: pygments>=2.19.2
16
+ Requires-Dist: requests>=2.32.5
17
+ Requires-Dist: rich>=14.3.3
18
+ Requires-Dist: typer>=0.24.1
19
+ Requires-Dist: typing-extensions>=4.0
20
+ Requires-Dist: websocket-client>=1.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Colab CLI
24
+
25
+ A command-line interface for Google Colab. Provision high-performance CPU, GPU, and TPU runtimes, execute local code, manage remote files, and orchestrate automated cloud pipelines — directly from your terminal.
26
+
27
+ Designed to support seamless developer productivity, headless automation, and AI agent integrations.
28
+
29
+ ---
30
+
31
+ ## Key Features
32
+
33
+ * **Instant VM Provisioning:** Spin up CPU, GPU (T4, L4, G4, H100, A100), or TPU (v5e1, v6e1) runtimes in seconds.
34
+ * **Robust Code Execution:** Run local Python scripts, Jupyter Notebooks (`.ipynb`), or piped `stdin` code; launch interactive REPLs or raw TTY console shells.
35
+ * **Ephemeral Job Runner (`colab run`):** Provision a fresh VM, execute a local script with forwarded arguments, retrieve output files, and automatically tear down the runtime in a single command.
36
+ * **Automatic Keep-Alive:** Built-in background daemon automatically prevents idle VM termination, keeping resource allocations active without requiring open browser tabs.
37
+ * **Seamless Workspace Automation:** Mount Google Drive, authenticate Google Cloud Platform (GCP) credentials, and install dependencies with high-performance `uv` package management.
38
+ * **State & Log Archival:** Inspect local session states or export interactive history logs to standard Jupyter Notebooks, Markdown, or structured JSONL.
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ Install the package using `uv` (recommended) or standard `pip`:
45
+
46
+ ```bash
47
+ # Using uv (recommended)
48
+ uv tool install google-colab-cli
49
+
50
+ # Using pip
51
+ pip install google-colab-cli
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quick Start
57
+
58
+ Run a CPU-based VM runtime, execute some code, and clean up:
59
+
60
+ ```bash
61
+ # 1. Provision a new session
62
+ colab new
63
+
64
+ # 2. Execute code from stdin
65
+ echo "print('Hello from Google Colab!')" | colab exec
66
+
67
+ # 3. Stop and release the VM resource
68
+ colab stop
69
+ ```
70
+
71
+ > [!NOTE]
72
+ > When only one session is active, you can omit the `-s, --session` option;
73
+ > the CLI automatically knows it.
74
+
75
+
76
+ ---
77
+
78
+ ## Command Index
79
+
80
+ Run `colab <command> --help` to view specific options, defaults, and detailed help.
81
+
82
+ ### Session Management
83
+ | Command | Description |
84
+ | --- | --- |
85
+ | `colab new [-s NAME] [--gpu GPU] [--tpu TPU]` | Allocate a new CPU, GPU, or TPU VM runtime |
86
+ | `colab sessions` | List all active sessions currently active on the backend |
87
+ | `colab status [-s NAME]` | Display hardware, status, and local metadata for active sessions |
88
+ | `colab restart-kernel [-s NAME]` | Restart the active session's Jupyter kernel |
89
+ | `colab stop [-s NAME]` | Terminate a session VM and tear down its keep-alive daemon |
90
+ | `colab url [-s NAME] [--open]` | Print or open a browser URL connecting to the active session |
91
+
92
+ ### Execution
93
+ | Command | Description |
94
+ | --- | --- |
95
+ | `colab run [--gpu GPU] [--tpu TPU] [--keep] SCRIPT [ARGS...]` | Run a local script on a fresh VM, forwarding arguments, then release it |
96
+ | `colab exec [-s NAME] [-f FILE] [--output-image PATH]` | Execute Python code from stdin, a local `.py` file, or a `.ipynb` notebook |
97
+ | `colab repl [-s NAME] [--output-image PATH]` | Start an interactive Python REPL on the VM (exits cleanly on piped EOF) |
98
+ | `colab console [-s NAME]` | Connect to a raw interactive TTY shell (tmux) on the remote VM |
99
+
100
+ ### File Operations
101
+ | Command | Description |
102
+ | --- | --- |
103
+ | `colab ls [-s NAME] [PATH]` | List remote files on the VM |
104
+ | `colab upload [-s NAME] LOCAL REMOTE` | Upload a local file to the VM filesystem |
105
+ | `colab download [-s NAME] REMOTE LOCAL` | Download a remote file from the VM filesystem |
106
+ | `colab rm [-s NAME] PATH` | Delete a remote file on the VM filesystem |
107
+ | `colab edit [-s NAME] PATH` | Edit a remote file in-place using your local `$EDITOR` |
108
+
109
+ ### Automation & Utilities
110
+ | Command | Description |
111
+ | --- | --- |
112
+ | `colab auth [-s NAME]` | Authenticate the VM for GCP services (BigQuery, GCS, etc.) |
113
+ | `colab drivemount [-s NAME] [PATH]` | Mount Google Drive on the VM (default: `/content/drive`) |
114
+ | `colab install [-s NAME] [-r FILE \| PKG...]` | Install packages on the VM using `uv` (falls back to `pip`) |
115
+ | `colab log [-s NAME] [-n N] [-o FILE]` | View or export session history (`.ipynb`, `.md`, `.txt`, `.jsonl`) |
116
+ | `colab pay` | Open the Colab subscription page to manage compute units |
117
+ | `colab version` | Print the installed version of the CLI |
118
+ | `colab update [--install]` | Check for a newer release (and optionally upgrade the CLI in place) |
119
+
120
+ ### Global Options
121
+ * `--auth {oauth2,adc}` — Authentication strategy for the Colab API (default: `adc`).
122
+ * `-c, --client-oauth-config PATH` — Path to public OAuth client credentials configuration (default: `~/.colab-cli-oauth-config.json`).
123
+ * `--config PATH` — Path to local session metadata storage (default: `~/.config/colab-cli/sessions.json`).
124
+ * `--logtostderr` — Direct debug logging output to stderr.
125
+
126
+ ---
127
+
128
+ ## Practical Examples
129
+
130
+ ### Accelerator Training with Checkpoint Retrieval
131
+
132
+ Provision an A100 GPU, install requirements, run a local training script, retrieve the resulting model weights, and terminate the VM:
133
+
134
+ ```bash
135
+ colab new -s trainer --gpu A100
136
+ colab install -s trainer torch transformers
137
+ colab exec -s trainer -f train.py
138
+ colab download -s trainer checkpoints/model.bin ./model.bin
139
+ colab stop -s trainer
140
+ ```
141
+
142
+ ### Workspace Notebook Execution with Drive Integration
143
+
144
+ Mount Google Drive, run a local notebook against the VM kernel (outputs are written back into `report_output.ipynb`), export a Markdown log of the execution, and clean up:
145
+
146
+ ```bash
147
+ colab new -s analysis
148
+ colab drivemount -s analysis
149
+ colab exec -s analysis -f report.ipynb
150
+ colab log -s analysis -o execution_log.md
151
+ colab stop -s analysis
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Usage Notes
157
+
158
+ * **TTY Requirements:** The interactive commands `repl` and `console` require a local TTY. When running inside automated scripts or pipelines, make sure to pipe stdin (e.g., `echo "print(1)" | colab repl`) to trigger non-interactive execution modes.
159
+ * **Transparent Code Execution:** When calling `colab exec -f file.py`, the CLI reads the file locally and transmits its content to the remote kernel. You do not need to manually upload files before execution.
160
+ * **Storage & State Paths:** Session tokens and metadata are stored at `~/.config/colab-cli/sessions.json`. Global CLI settings are located at `~/.config/colab-cli/settings.json`. These can be customized or isolated via the global `--config` flag.
161
+
162
+ ### Ephemeral Accelerator Jobs
163
+
164
+ Use `colab run` to run a local script on dedicated hardware without manual session lifecycle management. The CLI handles provisioning, script execution, and immediate VM teardown automatically:
165
+
166
+ ```bash
167
+ # Run train.py on a T4 GPU and release the VM on completion
168
+ colab run --gpu T4 train.py
169
+ ```
170
+
171
+ ### Shebang Execution Support
172
+
173
+ To execute a local file directly on a remote accelerator, place the `colab run` interpreter in the shebang line:
174
+
175
+ ```python
176
+ #!/usr/bin/env -S colab run --gpu L4 --keep
177
+ import torch
178
+
179
+ print("L4 GPU Available:", torch.cuda.is_available())
180
+ print("Device Name:", torch.cuda.get_device_name(0))
181
+ ```
182
+
183
+ Make the script executable (`chmod +x script.py`) and run it: `./script.py`. The `--keep` option tells the CLI to preserve the session VM on completion so you can re-execute or inspect logs.
184
+
185
+ ---
186
+
187
+ ## Deep Dive Documentation
188
+
189
+ For comprehensive architectural overviews and deep-dives into specific CLI sub-systems, refer to the detailed documentation:
190
+
191
+ * [Session Management & Keep-Alive Architecture](docs/01_session_management.md)
192
+ * [Interactive & Non-Interactive Execution Design](docs/02_execution_and_interactive.md)
193
+ * [File Management & Jupyter Contents API](docs/03_file_management.md)
194
+ * [Authentication Providers & VM Automation](docs/04_automation_and_utility.md)
195
+ * [Ephemeral Job Runner Design](docs/05_run_command.md)
196
+
197
+ To view interactive walkthroughs of eleven real-world automated scenarios, check out the [Demo Walkthroughs](docs/demos.md).
198
+
199
+ ---
200
+
201
+ ## Contributing
202
+
203
+ Feedback and contributions are welcome! Please read [`CONTRIBUTING.md`](./CONTRIBUTING.md) for details.
@@ -0,0 +1,181 @@
1
+ # Colab CLI
2
+
3
+ A command-line interface for Google Colab. Provision high-performance CPU, GPU, and TPU runtimes, execute local code, manage remote files, and orchestrate automated cloud pipelines — directly from your terminal.
4
+
5
+ Designed to support seamless developer productivity, headless automation, and AI agent integrations.
6
+
7
+ ---
8
+
9
+ ## Key Features
10
+
11
+ * **Instant VM Provisioning:** Spin up CPU, GPU (T4, L4, G4, H100, A100), or TPU (v5e1, v6e1) runtimes in seconds.
12
+ * **Robust Code Execution:** Run local Python scripts, Jupyter Notebooks (`.ipynb`), or piped `stdin` code; launch interactive REPLs or raw TTY console shells.
13
+ * **Ephemeral Job Runner (`colab run`):** Provision a fresh VM, execute a local script with forwarded arguments, retrieve output files, and automatically tear down the runtime in a single command.
14
+ * **Automatic Keep-Alive:** Built-in background daemon automatically prevents idle VM termination, keeping resource allocations active without requiring open browser tabs.
15
+ * **Seamless Workspace Automation:** Mount Google Drive, authenticate Google Cloud Platform (GCP) credentials, and install dependencies with high-performance `uv` package management.
16
+ * **State & Log Archival:** Inspect local session states or export interactive history logs to standard Jupyter Notebooks, Markdown, or structured JSONL.
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ Install the package using `uv` (recommended) or standard `pip`:
23
+
24
+ ```bash
25
+ # Using uv (recommended)
26
+ uv tool install google-colab-cli
27
+
28
+ # Using pip
29
+ pip install google-colab-cli
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Quick Start
35
+
36
+ Run a CPU-based VM runtime, execute some code, and clean up:
37
+
38
+ ```bash
39
+ # 1. Provision a new session
40
+ colab new
41
+
42
+ # 2. Execute code from stdin
43
+ echo "print('Hello from Google Colab!')" | colab exec
44
+
45
+ # 3. Stop and release the VM resource
46
+ colab stop
47
+ ```
48
+
49
+ > [!NOTE]
50
+ > When only one session is active, you can omit the `-s, --session` option;
51
+ > the CLI automatically knows it.
52
+
53
+
54
+ ---
55
+
56
+ ## Command Index
57
+
58
+ Run `colab <command> --help` to view specific options, defaults, and detailed help.
59
+
60
+ ### Session Management
61
+ | Command | Description |
62
+ | --- | --- |
63
+ | `colab new [-s NAME] [--gpu GPU] [--tpu TPU]` | Allocate a new CPU, GPU, or TPU VM runtime |
64
+ | `colab sessions` | List all active sessions currently active on the backend |
65
+ | `colab status [-s NAME]` | Display hardware, status, and local metadata for active sessions |
66
+ | `colab restart-kernel [-s NAME]` | Restart the active session's Jupyter kernel |
67
+ | `colab stop [-s NAME]` | Terminate a session VM and tear down its keep-alive daemon |
68
+ | `colab url [-s NAME] [--open]` | Print or open a browser URL connecting to the active session |
69
+
70
+ ### Execution
71
+ | Command | Description |
72
+ | --- | --- |
73
+ | `colab run [--gpu GPU] [--tpu TPU] [--keep] SCRIPT [ARGS...]` | Run a local script on a fresh VM, forwarding arguments, then release it |
74
+ | `colab exec [-s NAME] [-f FILE] [--output-image PATH]` | Execute Python code from stdin, a local `.py` file, or a `.ipynb` notebook |
75
+ | `colab repl [-s NAME] [--output-image PATH]` | Start an interactive Python REPL on the VM (exits cleanly on piped EOF) |
76
+ | `colab console [-s NAME]` | Connect to a raw interactive TTY shell (tmux) on the remote VM |
77
+
78
+ ### File Operations
79
+ | Command | Description |
80
+ | --- | --- |
81
+ | `colab ls [-s NAME] [PATH]` | List remote files on the VM |
82
+ | `colab upload [-s NAME] LOCAL REMOTE` | Upload a local file to the VM filesystem |
83
+ | `colab download [-s NAME] REMOTE LOCAL` | Download a remote file from the VM filesystem |
84
+ | `colab rm [-s NAME] PATH` | Delete a remote file on the VM filesystem |
85
+ | `colab edit [-s NAME] PATH` | Edit a remote file in-place using your local `$EDITOR` |
86
+
87
+ ### Automation & Utilities
88
+ | Command | Description |
89
+ | --- | --- |
90
+ | `colab auth [-s NAME]` | Authenticate the VM for GCP services (BigQuery, GCS, etc.) |
91
+ | `colab drivemount [-s NAME] [PATH]` | Mount Google Drive on the VM (default: `/content/drive`) |
92
+ | `colab install [-s NAME] [-r FILE \| PKG...]` | Install packages on the VM using `uv` (falls back to `pip`) |
93
+ | `colab log [-s NAME] [-n N] [-o FILE]` | View or export session history (`.ipynb`, `.md`, `.txt`, `.jsonl`) |
94
+ | `colab pay` | Open the Colab subscription page to manage compute units |
95
+ | `colab version` | Print the installed version of the CLI |
96
+ | `colab update [--install]` | Check for a newer release (and optionally upgrade the CLI in place) |
97
+
98
+ ### Global Options
99
+ * `--auth {oauth2,adc}` — Authentication strategy for the Colab API (default: `adc`).
100
+ * `-c, --client-oauth-config PATH` — Path to public OAuth client credentials configuration (default: `~/.colab-cli-oauth-config.json`).
101
+ * `--config PATH` — Path to local session metadata storage (default: `~/.config/colab-cli/sessions.json`).
102
+ * `--logtostderr` — Direct debug logging output to stderr.
103
+
104
+ ---
105
+
106
+ ## Practical Examples
107
+
108
+ ### Accelerator Training with Checkpoint Retrieval
109
+
110
+ Provision an A100 GPU, install requirements, run a local training script, retrieve the resulting model weights, and terminate the VM:
111
+
112
+ ```bash
113
+ colab new -s trainer --gpu A100
114
+ colab install -s trainer torch transformers
115
+ colab exec -s trainer -f train.py
116
+ colab download -s trainer checkpoints/model.bin ./model.bin
117
+ colab stop -s trainer
118
+ ```
119
+
120
+ ### Workspace Notebook Execution with Drive Integration
121
+
122
+ Mount Google Drive, run a local notebook against the VM kernel (outputs are written back into `report_output.ipynb`), export a Markdown log of the execution, and clean up:
123
+
124
+ ```bash
125
+ colab new -s analysis
126
+ colab drivemount -s analysis
127
+ colab exec -s analysis -f report.ipynb
128
+ colab log -s analysis -o execution_log.md
129
+ colab stop -s analysis
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Usage Notes
135
+
136
+ * **TTY Requirements:** The interactive commands `repl` and `console` require a local TTY. When running inside automated scripts or pipelines, make sure to pipe stdin (e.g., `echo "print(1)" | colab repl`) to trigger non-interactive execution modes.
137
+ * **Transparent Code Execution:** When calling `colab exec -f file.py`, the CLI reads the file locally and transmits its content to the remote kernel. You do not need to manually upload files before execution.
138
+ * **Storage & State Paths:** Session tokens and metadata are stored at `~/.config/colab-cli/sessions.json`. Global CLI settings are located at `~/.config/colab-cli/settings.json`. These can be customized or isolated via the global `--config` flag.
139
+
140
+ ### Ephemeral Accelerator Jobs
141
+
142
+ Use `colab run` to run a local script on dedicated hardware without manual session lifecycle management. The CLI handles provisioning, script execution, and immediate VM teardown automatically:
143
+
144
+ ```bash
145
+ # Run train.py on a T4 GPU and release the VM on completion
146
+ colab run --gpu T4 train.py
147
+ ```
148
+
149
+ ### Shebang Execution Support
150
+
151
+ To execute a local file directly on a remote accelerator, place the `colab run` interpreter in the shebang line:
152
+
153
+ ```python
154
+ #!/usr/bin/env -S colab run --gpu L4 --keep
155
+ import torch
156
+
157
+ print("L4 GPU Available:", torch.cuda.is_available())
158
+ print("Device Name:", torch.cuda.get_device_name(0))
159
+ ```
160
+
161
+ Make the script executable (`chmod +x script.py`) and run it: `./script.py`. The `--keep` option tells the CLI to preserve the session VM on completion so you can re-execute or inspect logs.
162
+
163
+ ---
164
+
165
+ ## Deep Dive Documentation
166
+
167
+ For comprehensive architectural overviews and deep-dives into specific CLI sub-systems, refer to the detailed documentation:
168
+
169
+ * [Session Management & Keep-Alive Architecture](docs/01_session_management.md)
170
+ * [Interactive & Non-Interactive Execution Design](docs/02_execution_and_interactive.md)
171
+ * [File Management & Jupyter Contents API](docs/03_file_management.md)
172
+ * [Authentication Providers & VM Automation](docs/04_automation_and_utility.md)
173
+ * [Ephemeral Job Runner Design](docs/05_run_command.md)
174
+
175
+ To view interactive walkthroughs of eleven real-world automated scenarios, check out the [Demo Walkthroughs](docs/demos.md).
176
+
177
+ ---
178
+
179
+ ## Contributing
180
+
181
+ Feedback and contributions are welcome! Please read [`CONTRIBUTING.md`](./CONTRIBUTING.md) for details.
@@ -1,5 +1,7 @@
1
1
  ---
2
2
  log:
3
+ 2026-06-01: Enabled `colab update --install` self-update on macOS in addition to Linux. Refactored platform check logic to keep the implementation DRY and updated both tests and documentation. Also, on these platforms, an additional message is shown recommending `colab update --install` to upgrade in place, positioned above the standard `pip`/`uv` installation command.
4
+ 2026-05-27: Refactored `colab README` and `colab AGENT` to bundle `README.md` and `AGENTS.md` via Hatchling's `force-include` and read them using `importlib.resources` instead of `importlib.metadata`. `colab AGENT` now correctly prints `AGENTS.md`.
3
5
  2026-05-27: Extended `colab update --install` to detect if the CLI was installed via `uv tool install` (by checking if `sys.executable` contains `/uv/`) and if so, use `uv tool install -U google-colab-cli` to upgrade.
4
6
  2026-05-27: Updated auto-update upgrade hint to recommend `pip install --upgrade google-colab-cli` instead of `colab`, aligning with the PyPI package name.
5
7
  2026-05-27: `colab url` now emits BOTH the `?dbu=<urlencoded path>` query parameter (existing) AND a new `#datalabBackendUrl=<full URL>` hash fragment (new). Format: `https://<host>/notebooks/empty.ipynb?dbu=%2Ftun%2Fm%2F<endpoint>#datalabBackendUrl=<host>/tun/m/<endpoint>`. Why both: some Colab frontend code paths consult the hash fragment first and ignore `dbu` entirely, so the previously-emitted query-only form failed silently for those users (the frontend fell through to allocating a fresh VM via `/tun/m/assign`). The fragment value is a FULL URL with scheme + host (NOT just the path) and is emitted RAW (no URL encoding) because browsers don't decode the fragment before passing `location.hash` to page JS — Colab's parser calls `new URL(rawString)` directly. The fragment host always matches `--host` so Colab's same-origin enforcement on embedded backend URLs doesn't block the connection, and sandbox/dev users (`--host https://colab.sandbox.google.com`) get a sandbox fragment automatically. Three new test cases in `tests/test_url.py` cover the raw-encoding requirement (`%3A`/`%2F` must NOT appear in the fragment), the both-signals-present invariant, and `--open` propagating the fragment to `webbrowser.open()`. Integration-verified live against synthetic session state with three host shapes (default, sandbox, trailing-slash); all produced correctly-shaped URLs with no `//` artifacts.
@@ -184,10 +186,12 @@ remediation guidance) rather than silently after ~1 minute via the daemon.
184
186
  the cache.
185
187
  - **Notification**: If a new version is found, a non-intrusive message is
186
188
  printed to the console with a `Run 'pip install --upgrade google-colab-cli' to
187
- update.` hint. The cached banner shown between fetches uses the generic
188
- `Run 'colab update' to update.` hint.
189
+ update.` hint. On Linux and macOS platforms where `--install` self-update is supported,
190
+ an additional hint `You can run 'colab update --install' to upgrade in place.`
191
+ is displayed above the pip/uv install command. The cached banner shown between
192
+ fetches uses the generic `Run 'colab update' to update.` hint.
189
193
  - **Self-install (`--install`)**: An opt-in `--install` flag (default
190
- `False`) makes `colab update` upgrade the CLI in place (**Linux only**).
194
+ `False`) makes `colab update` upgrade the CLI in place (**Linux and macOS**).
191
195
  It detects how the CLI was installed:
192
196
  - If `sys.executable` contains `/uv/tools` (indicating it was installed via
193
197
  `uv tool install`), it runs `uv tool install -U google-colab-cli`.
@@ -241,6 +245,19 @@ remediation guidance) rather than silently after ~1 minute via the daemon.
241
245
  - openid
242
246
  ```
243
247
 
248
+ ### 9. README and AGENT (`colab README`, `colab AGENT`)
249
+
250
+ - **Action**: Print the bundled `README.md` or `AGENTS.md` file.
251
+ - **Implementation**:
252
+ - Uses `importlib.resources.files("colab_cli").joinpath(...)` to read the
253
+ bundled `README.md` (for `colab README`) or `AGENTS.md` (for `colab AGENT`)
254
+ from the package resources.
255
+ - The files are bundled into the package via Hatchling's `force-include`
256
+ configuration in `pyproject.toml`.
257
+ - If reading from resources fails (e.g. during development when not
258
+ installed), it falls back to reading the files from the project root.
259
+ - Prints the content to stdout.
260
+
244
261
  ## Implementation Details
245
262
 
246
263
  - **Code Injection**: Use a standard `run_code(session, code)` helper via
@@ -286,3 +303,10 @@ TDD is mandatory for all automation features.
286
303
  - **Test Case**: `creds.refresh()` is called before `creds.token` is read
287
304
  (regression against silently-`None` tokens for service-account /
288
305
  GCE-metadata creds).
306
+
307
+ ### 4. `README` and `AGENT` Commands
308
+
309
+ - **Test Case**: Verify `colab README` prints the expected content when package metadata is available.
310
+ - **Test Case**: Verify `colab AGENT` prints the same content.
311
+ - **Test Case**: Verify fallback to local `README.md` file when metadata is not available.
312
+ - **Test Case**: Verify error exit when both metadata and local file are unavailable.
@@ -34,6 +34,10 @@ source = "vcs"
34
34
  [tool.hatch.build.targets.wheel]
35
35
  packages = ["src/colab_cli"]
36
36
 
37
+ [tool.hatch.build.targets.wheel.force-include]
38
+ "README.md" = "colab_cli/README.md"
39
+ "COLAB_SKILL.md" = "colab_cli/COLAB_SKILL.md"
40
+
37
41
  [tool.uv]
38
42
  package = true
39
43
 
@@ -23,6 +23,7 @@ callback (``cli.py``) calls ``check_for_updates`` once per day and
23
23
  """
24
24
 
25
25
  import json
26
+ import platform
26
27
  import subprocess
27
28
  import urllib.request
28
29
  from datetime import datetime, timezone
@@ -35,10 +36,18 @@ import typer
35
36
  from colab_cli.common import state
36
37
  from colab_cli.state import Settings
37
38
 
39
+ # PyPI distribution name (different from the importable package name `colab`).
40
+ PYPI_PACKAGE_NAME = "google-colab-cli"
41
+
38
42
 
39
43
  # ---------- Version detection -------------------------------------------
40
44
 
41
45
 
46
+ def is_self_install_supported() -> bool:
47
+ """Return True if self-install (--install) is supported on the current platform."""
48
+ return platform.system() in ("Linux", "Darwin")
49
+
50
+
42
51
  def get_app_version() -> str:
43
52
  """Return the installed package version, falling back to the git short hash."""
44
53
  try:
@@ -109,6 +118,8 @@ def announce_upgrade(
109
118
  typer.echo(
110
119
  f"\n[colab] A new version of Colab CLI is available: {latest} (current: {current})"
111
120
  )
121
+ if is_self_install_supported() and ("pip" in install_cmd or "uv" in install_cmd):
122
+ typer.echo("[colab] You can run 'colab update --install' to upgrade in place.")
112
123
  typer.echo(f"[colab] Run '{install_cmd}' to update.")
113
124
  if show_disable_hint:
114
125
  typer.echo(
@@ -122,6 +133,15 @@ def announce_upgrade(
122
133
  # ---------- Orchestration -----------------------------------------------
123
134
 
124
135
 
136
+ def _get_install_command() -> str:
137
+ """Return the recommended installation command based on the environment."""
138
+ import sys
139
+
140
+ if is_self_install_supported() and "/uv/tools/" in sys.executable:
141
+ return f"uv tool install -U {PYPI_PACKAGE_NAME}"
142
+ return f"pip install --upgrade {PYPI_PACKAGE_NAME}"
143
+
144
+
125
145
  def check_for_updates(quiet: bool = False) -> None:
126
146
  """Check PyPI for updates and print a message if a new version is available.
127
147
 
@@ -140,7 +160,7 @@ def check_for_updates(quiet: bool = False) -> None:
140
160
  announce_upgrade(
141
161
  pypi_v,
142
162
  current,
143
- "pip install --upgrade google-colab-cli",
163
+ _get_install_command(),
144
164
  show_disable_hint=quiet,
145
165
  )
146
166
  elif not quiet:
@@ -211,10 +231,6 @@ def run_background_check() -> None:
211
231
  # ---------- Self-install ------------------------------------------------
212
232
 
213
233
 
214
- # PyPI distribution name (different from the importable package name `colab`).
215
- PYPI_PACKAGE_NAME = "google-colab-cli"
216
-
217
-
218
234
  def self_install() -> None:
219
235
  """Upgrade the CLI in place, detecting uv vs pip."""
220
236
  import sys
@@ -105,6 +105,10 @@ def callback(
105
105
  "help",
106
106
  "url",
107
107
  "whoami",
108
+ "readme",
109
+ "README",
110
+ "skill",
111
+ "SKILL",
108
112
  }
109
113
  if ctx.invoked_subcommand not in _AUTO_UPDATE_SUPPRESSED:
110
114
  auto_update.run_background_check()
@@ -234,7 +234,7 @@ def run_command(
234
234
  ),
235
235
  ] = False,
236
236
  ):
237
- """Run a Python script on a fresh Colab VM, then release the VM.
237
+ """Run a Python script on a fresh Colab VM, then release the VM
238
238
 
239
239
  Designed to be used as a shebang interpreter, e.g.
240
240
 
@@ -27,7 +27,6 @@ from colab_cli.client import (
27
27
  PostAssignmentResponse,
28
28
  Variant,
29
29
  )
30
- from colab_cli.commands.automation import INTERACTIVE_AUTOMATION_TIMEOUT_SEC
31
30
  from colab_cli.utils import get_status_code
32
31
  from colab_cli.state import SessionState
33
32
  from colab_cli.runtime import ColabRuntime
@@ -247,11 +246,12 @@ def new(
247
246
  typer.echo("[colab] Session READY.")
248
247
 
249
248
 
250
- def restart(
249
+ def restart_kernel(
251
250
  session: Annotated[
252
251
  Optional[str], typer.Option("-s", "--session", help="Session name")
253
252
  ] = None,
254
253
  ):
254
+ """Restart a session's kernel"""
255
255
  from colab_cli.common import state
256
256
 
257
257
  name = state.resolve_session(session)
@@ -505,7 +505,7 @@ def keep_alive(
505
505
  def register(app: typer.Typer):
506
506
  app.command()(new)
507
507
  app.command(name="sessions")(sessions_command)
508
- app.command()(restart)
508
+ app.command(name="restart-kernel")(restart_kernel)
509
509
  app.command()(status)
510
510
  app.command()(stop)
511
511
  app.command(hidden=True)(keep_alive)
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import platform
16
15
  from typing import Optional
17
16
 
18
17
  import typer
@@ -362,9 +361,10 @@ def update_command(
362
361
  if not install:
363
362
  return
364
363
 
365
- if platform.system() != "Linux":
364
+ if not auto_update.is_self_install_supported():
366
365
  typer.echo(
367
- "[colab] '--install' self-install is only supported on Linux.", err=True
366
+ "[colab] '--install' self-install is only supported on Linux and macOS.",
367
+ err=True,
368
368
  )
369
369
  raise typer.Exit(code=1)
370
370
 
@@ -379,6 +379,48 @@ def update_command(
379
379
  auto_update.self_install()
380
380
 
381
381
 
382
+ def _print_resource(filename: str) -> None:
383
+ import importlib.resources
384
+ import os
385
+
386
+ content = None
387
+ try:
388
+ # Try reading from package resources
389
+ ref = importlib.resources.files("colab_cli").joinpath(filename)
390
+ if ref.is_file():
391
+ content = ref.read_text(encoding="utf-8")
392
+ except Exception:
393
+ pass
394
+
395
+ if not content:
396
+ # Fallback to local file for development
397
+ local_path = os.path.abspath(
398
+ os.path.join(os.path.dirname(__file__), f"../../../{filename}")
399
+ )
400
+ if os.path.exists(local_path):
401
+ try:
402
+ with open(local_path, "r", encoding="utf-8") as f:
403
+ content = f.read()
404
+ except Exception:
405
+ pass
406
+
407
+ if content:
408
+ typer.echo(content)
409
+ else:
410
+ typer.echo(f"[colab] {filename} content not available.", err=True)
411
+ raise typer.Exit(code=1)
412
+
413
+
414
+ def readme():
415
+ """Print the bundled README.md file"""
416
+ _print_resource("README.md")
417
+
418
+
419
+ def skill():
420
+ """Print the bundled COLAB_SKILL.md file"""
421
+ _print_resource("COLAB_SKILL.md")
422
+
423
+
382
424
  def register(app: typer.Typer):
383
425
  app.command()(pay)
384
426
  app.command()(log)
@@ -388,3 +430,7 @@ def register(app: typer.Typer):
388
430
  # Developer-only debugging aid; hidden from `colab --help` but still
389
431
  # reachable via `colab whoami` / `colab whoami --help`.
390
432
  app.command(name="whoami", hidden=True)(whoami)
433
+ app.command(name="readme")(readme)
434
+ app.command(name="README", hidden=True)(readme)
435
+ app.command(name="skill")(skill)
436
+ app.command(name="SKILL", hidden=True)(skill)
@@ -154,7 +154,7 @@ class ColabRuntime:
154
154
  raise e
155
155
 
156
156
  return self._kernel_client
157
-
157
+
158
158
  def restart(
159
159
  self,
160
160
  timeout: Optional[float] = None,