urun-cli 0.7.7__tar.gz → 0.8.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.
Files changed (40) hide show
  1. {urun_cli-0.7.7 → urun_cli-0.8.0}/CHANGELOG.md +48 -2
  2. urun_cli-0.8.0/PKG-INFO +164 -0
  3. urun_cli-0.8.0/README.md +140 -0
  4. {urun_cli-0.7.7 → urun_cli-0.8.0}/pyproject.toml +7 -4
  5. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/api.py +12 -0
  6. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/catalog.py +4 -4
  7. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/cli.py +165 -104
  8. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/deps.py +193 -28
  9. urun_cli-0.8.0/src/urun/feature_flags.py +252 -0
  10. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/fleet.py +2 -1
  11. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/hub_builds.py +27 -0
  12. urun_cli-0.8.0/src/urun/kubectl_plugin.py +705 -0
  13. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/rust.py +1 -1
  14. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/serve.py +72 -2
  15. urun_cli-0.7.7/PKG-INFO +0 -627
  16. urun_cli-0.7.7/README.md +0 -602
  17. {urun_cli-0.7.7 → urun_cli-0.8.0}/.gitignore +0 -0
  18. {urun_cli-0.7.7 → urun_cli-0.8.0}/LICENSE +0 -0
  19. {urun_cli-0.7.7 → urun_cli-0.8.0}/SECURITY.md +0 -0
  20. {urun_cli-0.7.7 → urun_cli-0.8.0}/hatch_build.py +0 -0
  21. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/__init__.py +0 -0
  22. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/_bin/README.md +0 -0
  23. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/buildlogs.py +0 -0
  24. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/client_tokens.py +0 -0
  25. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/config.py +0 -0
  26. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/dev.py +0 -0
  27. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/devconsole.py +0 -0
  28. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/devstream.py +0 -0
  29. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/discovery.py +0 -0
  30. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/errors.py +0 -0
  31. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/frontend_launch.py +0 -0
  32. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/launch_auth.py +0 -0
  33. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/manifest.py +0 -0
  34. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/nodes.py +0 -0
  35. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/openai_proxy_bin.py +0 -0
  36. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/repo_deps.py +0 -0
  37. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/reserve.py +0 -0
  38. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/retry.py +0 -0
  39. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/runtime_health.py +0 -0
  40. {urun_cli-0.7.7 → urun_cli-0.8.0}/src/urun/scratch.py +0 -0
@@ -1,5 +1,51 @@
1
- ## Unreleased
2
-
1
+ ## 0.8.0
2
+
3
+ MVP launch release (URU-673). The CLI ships only its launch surface, gated by
4
+ release feature flags (`src/urun/feature_flags.py`, conventions in
5
+ [FLAGS.md](FLAGS.md)): `login`, `org`, `account`
6
+ (`org`/`usage`/`credit`/`quota`), `member`, `api-key`, `credit-ledger`,
7
+ `feedback`, and `open billing` register; every other command stays in the
8
+ tree but unregistered, failing exactly like an unknown command (argparse's
9
+ own invalid-choice error, exit 2 — no "not available" text, no flag names,
10
+ and no mention of a gated surface in any launch `--help` or in `login`'s
11
+ output). Hidden means nonexistent. Re-introducing a capability is a flag
12
+ flip in `feature_flags.py` plus the launch-pin update in
13
+ `tests/test_feature_flags.py` (see FLAGS.md, "Re-introducing a
14
+ capability") — no re-implementation.
15
+
16
+ Also in this release's code, but gated OFF in the launch surface (flipping
17
+ their flags re-introduces them):
18
+
19
+ - `urun release promote <release_id> [--environment main]` — make an existing
20
+ release current again (clean rollback, no marker commits). Server side it
21
+ takes the same path as a same-content `urun deploy`: the control plane
22
+ re-registers the release and republishes the release pointer.
23
+ - Deploy deps collector: `@app.function(deps=...)` may now reference a
24
+ module-level `Dependencies(...)` constant imported from a file shipped with
25
+ the app (`from sense_deploy import SENSE_DEPS`) — resolved statically by the
26
+ same side-effect-free evaluator, including re-export chains and the
27
+ `import mod` + `mod.SYM` attribute form. An attached `deps=` that cannot be
28
+ statically resolved now FAILS THE DEPLOY LOUDLY naming `file:line`, the
29
+ import it came through, and the fix — previously it silently shipped an
30
+ EMPTY manifest (no python pins, no files) and the app's boot self-test died
31
+ with `No module named ...` after fleet rollout (sense, 2026-10-27/28).
32
+ - `kubectl urun` — a kubectl plugin (the `urun.kubectl_plugin` module ships
33
+ in the wheel; the `kubectl-urun` entry point is NOT installed in this
34
+ release — restoring it takes the `feat-byo-nodes` flip plus re-registering
35
+ the entry point in `[project.scripts]` and updating
36
+ `test_launch_wheel_ships_no_kubectl_urun_entry_point`, per FLAGS.md's
37
+ re-introduction procedure) with four verbs over the
38
+ `gpu.urun.sh/v1alpha1` GPUWorker surface:
39
+ `logs` (the `logs.urun.sh/v1` log subresource, with `-f` follow
40
+ passthrough, `--since`, `--tail`, `-s <service>`), `cordon`/`uncordon`
41
+ (`spec.unschedulable`), `drain` (cordon, then wait for the `Draining`
42
+ condition to reach `False`/`Drained`, nonzero on `--timeout`), and
43
+ `describe` (node block, services, conditions, events, liveness lease,
44
+ claim summary). Claim-owned workers are cordoned through their OWNING
45
+ GPUWorkerClaim (resolved via `spec.claimRef`) because the claim
46
+ reconciler re-renders the worker's spec; the patched object is printed.
47
+ All verbs ride a bounded `kubectl proxy --port=0` child, so
48
+ `--kubeconfig`/`--context`/`-n` resolve exactly as kubectl resolves them.
3
49
  - Security (ENG-570 / pentest urun-cli-01, mirrored in urun-python
4
50
  `urun/core/store/repo.py`): `store.repo(...)` specs parsed from untrusted
5
51
  app source are validated before any git call. The `@<ref>` pin must be a
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: urun-cli
3
+ Version: 0.8.0
4
+ Summary: CLI for the urun platform — login, billing & usage. More capabilities coming soon.
5
+ Project-URL: Homepage, https://urun.sh
6
+ Project-URL: Repository, https://github.com/urun-sh/urun-cli
7
+ Project-URL: Issues, https://github.com/urun-sh/urun-cli/issues
8
+ Author: urun
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,urun
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.11
20
+ Provides-Extra: rust
21
+ Requires-Dist: tree-sitter-rust==0.24.0; extra == 'rust'
22
+ Requires-Dist: tree-sitter==0.25.2; extra == 'rust'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # urun CLI
26
+
27
+ Command-line access to your urun org: log in, inspect billing, usage, and
28
+ cost information, and jump to the billing console. More capabilities are on
29
+ the way — see [What's next](#whats-next).
30
+
31
+ [![PyPI](https://img.shields.io/pypi/v/urun-cli.svg)](https://pypi.org/project/urun-cli/)
32
+ [![Python](https://img.shields.io/pypi/pyversions/urun-cli.svg)](https://pypi.org/project/urun-cli/)
33
+
34
+ ## Install
35
+
36
+ ```bash
37
+ uv tool install urun-cli
38
+ # or
39
+ pip install urun-cli
40
+ ```
41
+
42
+ The package installs the `urun` command:
43
+
44
+ ```bash
45
+ urun --version
46
+ ```
47
+
48
+ For one-off `uvx` usage:
49
+
50
+ ```bash
51
+ uvx --from urun-cli urun --version
52
+ # or the package-matching command alias
53
+ uvx urun-cli --version
54
+ ```
55
+
56
+ ## Log in
57
+
58
+ Save an org-scoped API key locally with `urun login`:
59
+
60
+ ```bash
61
+ urun login
62
+ ```
63
+
64
+ If `URUN_API_KEY` is not already set, `urun login` opens the urun console API
65
+ keys page, prompts you to paste the generated `urun_sk_...` key, verifies it
66
+ with the urun API, and stores credentials for later commands.
67
+
68
+ If you already have a key, you can pass it directly:
69
+
70
+ ```bash
71
+ urun login --api-key urun_sk_<secret>
72
+ ```
73
+
74
+ For CI or one-off commands, you can use the environment variable instead:
75
+
76
+ ```bash
77
+ export URUN_API_KEY=urun_sk_<secret>
78
+ ```
79
+
80
+ ## Billing & usage
81
+
82
+ Every command is org-scoped via your API key.
83
+
84
+ Your org identity (use `--id` in scripts: `ORG=$(urun org --id)`):
85
+
86
+ ```bash
87
+ urun org
88
+ ```
89
+
90
+ Usage summary and credit balance:
91
+
92
+ ```bash
93
+ urun account usage
94
+ urun account credit
95
+ urun account quota
96
+ ```
97
+
98
+ The credit ledger — every credit grant and charge to your org, newest first:
99
+
100
+ ```bash
101
+ urun credit-ledger list
102
+ ```
103
+
104
+ Org config, members, and API keys:
105
+
106
+ ```bash
107
+ urun account org
108
+ urun member list
109
+ urun api-key list
110
+ ```
111
+
112
+ Open the billing page in the urun console:
113
+
114
+ ```bash
115
+ urun open billing
116
+ ```
117
+
118
+ `urun feedback` raises and tracks issues with the urun team from your
119
+ terminal.
120
+
121
+ ## Common options
122
+
123
+ | Option | Description |
124
+ | --- | --- |
125
+ | `--api-url` | Override the API URL; defaults to `URUN_API_URL`, saved login credentials, or `https://api.urun.sh/v1`. |
126
+ | `--api-key` | API key; defaults to `URUN_API_KEY` or saved login credentials. |
127
+ | `--json` | Machine-readable output, where supported. |
128
+
129
+ ## Troubleshooting
130
+
131
+ | Error | Fix |
132
+ | --- | --- |
133
+ | `missing API key` | Run `urun login`, set `URUN_API_KEY`, or pass `--api-key`. |
134
+ | `invalid API key format` | Use `urun_<32 lowercase hex chars>`. |
135
+
136
+ ## What's next
137
+
138
+ This release focuses on account access: login, billing, usage, and cost
139
+ information. Additional capabilities — deploy tooling, app management, and
140
+ more — are in development and will arrive in upcoming releases.
141
+
142
+ ## Development
143
+
144
+ Contributing and test instructions are in [CONTRIBUTING.md](CONTRIBUTING.md).
145
+ The CLI gates unreleased surfaces behind release feature flags — see
146
+ [FLAGS.md](FLAGS.md) for the conventions and how to exercise them from a
147
+ source checkout.
148
+
149
+ This repo has a Nix/direnv/devcontainer baseline:
150
+
151
+ ```bash
152
+ direnv allow
153
+ just sync
154
+ just check
155
+ ```
156
+
157
+ Use VS Code Dev Containers to open the repository with the same toolchain in a
158
+ container. Copy `devcontainer.env.example` to `.devcontainer.env` if you need
159
+ to pass local git identity or other non-secret development settings into the
160
+ container.
161
+
162
+ ## License
163
+
164
+ MIT.
@@ -0,0 +1,140 @@
1
+ # urun CLI
2
+
3
+ Command-line access to your urun org: log in, inspect billing, usage, and
4
+ cost information, and jump to the billing console. More capabilities are on
5
+ the way — see [What's next](#whats-next).
6
+
7
+ [![PyPI](https://img.shields.io/pypi/v/urun-cli.svg)](https://pypi.org/project/urun-cli/)
8
+ [![Python](https://img.shields.io/pypi/pyversions/urun-cli.svg)](https://pypi.org/project/urun-cli/)
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ uv tool install urun-cli
14
+ # or
15
+ pip install urun-cli
16
+ ```
17
+
18
+ The package installs the `urun` command:
19
+
20
+ ```bash
21
+ urun --version
22
+ ```
23
+
24
+ For one-off `uvx` usage:
25
+
26
+ ```bash
27
+ uvx --from urun-cli urun --version
28
+ # or the package-matching command alias
29
+ uvx urun-cli --version
30
+ ```
31
+
32
+ ## Log in
33
+
34
+ Save an org-scoped API key locally with `urun login`:
35
+
36
+ ```bash
37
+ urun login
38
+ ```
39
+
40
+ If `URUN_API_KEY` is not already set, `urun login` opens the urun console API
41
+ keys page, prompts you to paste the generated `urun_sk_...` key, verifies it
42
+ with the urun API, and stores credentials for later commands.
43
+
44
+ If you already have a key, you can pass it directly:
45
+
46
+ ```bash
47
+ urun login --api-key urun_sk_<secret>
48
+ ```
49
+
50
+ For CI or one-off commands, you can use the environment variable instead:
51
+
52
+ ```bash
53
+ export URUN_API_KEY=urun_sk_<secret>
54
+ ```
55
+
56
+ ## Billing & usage
57
+
58
+ Every command is org-scoped via your API key.
59
+
60
+ Your org identity (use `--id` in scripts: `ORG=$(urun org --id)`):
61
+
62
+ ```bash
63
+ urun org
64
+ ```
65
+
66
+ Usage summary and credit balance:
67
+
68
+ ```bash
69
+ urun account usage
70
+ urun account credit
71
+ urun account quota
72
+ ```
73
+
74
+ The credit ledger — every credit grant and charge to your org, newest first:
75
+
76
+ ```bash
77
+ urun credit-ledger list
78
+ ```
79
+
80
+ Org config, members, and API keys:
81
+
82
+ ```bash
83
+ urun account org
84
+ urun member list
85
+ urun api-key list
86
+ ```
87
+
88
+ Open the billing page in the urun console:
89
+
90
+ ```bash
91
+ urun open billing
92
+ ```
93
+
94
+ `urun feedback` raises and tracks issues with the urun team from your
95
+ terminal.
96
+
97
+ ## Common options
98
+
99
+ | Option | Description |
100
+ | --- | --- |
101
+ | `--api-url` | Override the API URL; defaults to `URUN_API_URL`, saved login credentials, or `https://api.urun.sh/v1`. |
102
+ | `--api-key` | API key; defaults to `URUN_API_KEY` or saved login credentials. |
103
+ | `--json` | Machine-readable output, where supported. |
104
+
105
+ ## Troubleshooting
106
+
107
+ | Error | Fix |
108
+ | --- | --- |
109
+ | `missing API key` | Run `urun login`, set `URUN_API_KEY`, or pass `--api-key`. |
110
+ | `invalid API key format` | Use `urun_<32 lowercase hex chars>`. |
111
+
112
+ ## What's next
113
+
114
+ This release focuses on account access: login, billing, usage, and cost
115
+ information. Additional capabilities — deploy tooling, app management, and
116
+ more — are in development and will arrive in upcoming releases.
117
+
118
+ ## Development
119
+
120
+ Contributing and test instructions are in [CONTRIBUTING.md](CONTRIBUTING.md).
121
+ The CLI gates unreleased surfaces behind release feature flags — see
122
+ [FLAGS.md](FLAGS.md) for the conventions and how to exercise them from a
123
+ source checkout.
124
+
125
+ This repo has a Nix/direnv/devcontainer baseline:
126
+
127
+ ```bash
128
+ direnv allow
129
+ just sync
130
+ just check
131
+ ```
132
+
133
+ Use VS Code Dev Containers to open the repository with the same toolchain in a
134
+ container. Copy `devcontainer.env.example` to `.devcontainer.env` if you need
135
+ to pass local git identity or other non-secret development settings into the
136
+ container.
137
+
138
+ ## License
139
+
140
+ MIT.
@@ -20,14 +20,14 @@ name = "urun-cli"
20
20
  # so every merge remains on the already-published version until this value is
21
21
  # advanced. Wiring semantic-release into CI remains separate work; this patch
22
22
  # bump is the minimal release unblock (post-v0.6.3 fixes + the Rust feature minor).
23
- version = "0.7.7"
24
- description = "End-user CLI for deploying apps to urun"
23
+ version = "0.8.0"
24
+ description = "CLI for the urun platform — login, billing & usage. More capabilities coming soon."
25
25
  readme = "README.md"
26
26
  requires-python = ">=3.11"
27
27
  license = "MIT"
28
28
  license-files = ["LICENSE"]
29
29
  authors = [{ name = "urun" }]
30
- keywords = ["urun", "deploy", "cli"]
30
+ keywords = ["urun", "cli"]
31
31
  classifiers = [
32
32
  "Development Status :: 3 - Alpha",
33
33
  "Environment :: Console",
@@ -36,7 +36,6 @@ classifiers = [
36
36
  "Programming Language :: Python :: 3",
37
37
  "Programming Language :: Python :: 3.11",
38
38
  "Programming Language :: Python :: 3.12",
39
- "Topic :: Software Development :: Build Tools",
40
39
  ]
41
40
  dependencies = []
42
41
 
@@ -48,6 +47,10 @@ Issues = "https://github.com/urun-sh/urun-cli/issues"
48
47
  [project.scripts]
49
48
  urun = "urun.cli:main"
50
49
  urun-cli = "urun.cli:main"
50
+ # No kubectl-urun entry point at launch (URU-673): the GPUWorker surface is
51
+ # flag-hidden (feat-byo-nodes, FLAGS.md) and the wheel must not install an
52
+ # operator binary whose every verb errors. The module stays, gated; the entry
53
+ # point returns when the flag flips on in a future release.
51
54
 
52
55
  [project.optional-dependencies]
53
56
  # Rust app discovery (urun/rust.py) parses with the pinned native
@@ -461,6 +461,18 @@ class ApiClient:
461
461
  def get_release(self, release_id: str) -> dict[str, Any]:
462
462
  return self._get(f"/cli/releases/{urllib.parse.quote(release_id, safe='')}")
463
463
 
464
+ def promote_release(self, release_id: str, environment: str) -> dict[str, Any]:
465
+ """Make an EXISTING release current for ``environment`` (rollback).
466
+
467
+ ``POST /cli/releases/<id>/promote`` re-fires the release's deploy event —
468
+ the same path a same-content ``urun deploy`` takes — so the control plane
469
+ re-registers it and republishes the release pointer.
470
+ """
471
+ return self._post(
472
+ f"/cli/releases/{urllib.parse.quote(release_id, safe='')}/promote",
473
+ {"environment": environment},
474
+ )
475
+
464
476
  def query_logs(self, params: dict[str, Any] | None = None) -> dict[str, Any]:
465
477
  return self._get("/cli/logs", params)
466
478
 
@@ -120,7 +120,7 @@ ENGINE_DEPS: dict[str, list[str]] = {
120
120
  "nvidia-cuda-crt==13.0.88",
121
121
  "nvidia-cuda-cccl==13.0.85",
122
122
  "nvidia-nvvm==13.0.88",
123
- "nvidia-cuda-runtime==13.0.96",
123
+ "nvidia-cuda-runtime==13.0.*",
124
124
  "numpy<2",
125
125
  "pillow>=10.0.0",
126
126
  "orjson",
@@ -162,7 +162,7 @@ ENGINE_DEPS: dict[str, list[str]] = {
162
162
  "nvidia-cuda-crt==13.0.88",
163
163
  "nvidia-cuda-cccl==13.0.85",
164
164
  "nvidia-nvvm==13.0.88",
165
- "nvidia-cuda-runtime==13.0.96",
165
+ "nvidia-cuda-runtime==13.0.*",
166
166
  "numpy<2",
167
167
  "pillow>=10.0.0",
168
168
  "orjson",
@@ -368,7 +368,7 @@ ENGINE_DEPS: dict[str, list[str]] = {
368
368
  "nvidia-cuda-crt==13.0.88",
369
369
  "nvidia-cuda-cccl==13.0.85",
370
370
  "nvidia-nvvm==13.0.88",
371
- "nvidia-cuda-runtime==13.0.96",
371
+ "nvidia-cuda-runtime==13.0.*",
372
372
  "numpy<2",
373
373
  "pillow>=10.0.0",
374
374
  "orjson",
@@ -446,7 +446,7 @@ ENGINE_DEPS: dict[str, list[str]] = {
446
446
  "nvidia-cuda-crt==13.0.88",
447
447
  "nvidia-cuda-cccl==13.0.85",
448
448
  "nvidia-nvvm==13.0.88",
449
- "nvidia-cuda-runtime==13.0.96",
449
+ "nvidia-cuda-runtime==13.0.*",
450
450
  "ninja",
451
451
  "pip",
452
452
  "nvidia-cutlass-dsl>=4.6.0.dev0,<5",