albus-cli 0.1.0__tar.gz → 0.2.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.
- albus_cli-0.2.0/.github/ISSUE_TEMPLATE/bug.yml +61 -0
- albus_cli-0.2.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- albus_cli-0.2.0/.github/pull_request_template.md +10 -0
- albus_cli-0.2.0/.github/workflows/close-pull-requests.yml +51 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/.gitignore +0 -1
- albus_cli-0.2.0/AGENTS.md +85 -0
- albus_cli-0.2.0/CONTRIBUTING.md +32 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/Makefile +2 -0
- albus_cli-0.2.0/PKG-INFO +180 -0
- albus_cli-0.2.0/README.md +165 -0
- albus_cli-0.2.0/RELEASING.md +101 -0
- albus_cli-0.2.0/SECURITY.md +21 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/install.ps1 +15 -5
- {albus_cli-0.1.0 → albus_cli-0.2.0}/install.sh +17 -7
- {albus_cli-0.1.0 → albus_cli-0.2.0}/pyproject.toml +4 -2
- albus_cli-0.2.0/pyrightconfig.json +17 -0
- albus_cli-0.2.0/setup.sh +22 -0
- albus_cli-0.2.0/src/albus_cli/client.py +288 -0
- albus_cli-0.2.0/src/albus_cli/commands/auth.py +98 -0
- albus_cli-0.2.0/src/albus_cli/commands/invites.py +33 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/src/albus_cli/commands/sessions.py +37 -7
- albus_cli-0.2.0/src/albus_cli/commands/status.py +101 -0
- albus_cli-0.2.0/src/albus_cli/commands/tokens.py +43 -0
- albus_cli-0.2.0/src/albus_cli/context.py +41 -0
- albus_cli-0.2.0/src/albus_cli/credentials.py +245 -0
- albus_cli-0.2.0/src/albus_cli/docs.py +21 -0
- albus_cli-0.2.0/src/albus_cli/main.py +177 -0
- albus_cli-0.2.0/src/albus_cli/oauth.py +373 -0
- albus_cli-0.2.0/src/albus_cli/output.py +92 -0
- albus_cli-0.2.0/tests/conftest.py +164 -0
- albus_cli-0.2.0/tests/test_auth.py +657 -0
- albus_cli-0.2.0/tests/test_cli.py +362 -0
- albus_cli-0.2.0/tests/test_credentials.py +391 -0
- albus_cli-0.2.0/tests/test_health.py +45 -0
- albus_cli-0.2.0/tests/test_invites.py +63 -0
- albus_cli-0.2.0/tests/test_oauth.py +379 -0
- albus_cli-0.2.0/tests/test_status.py +162 -0
- albus_cli-0.2.0/tests/test_tokens.py +108 -0
- albus_cli-0.2.0/tools/mirror-release +215 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/tools/publish +12 -51
- albus_cli-0.2.0/tools/release_state.sh +60 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/uv.lock +5 -5
- albus_cli-0.1.0/.github/workflows/check.yml +0 -32
- albus_cli-0.1.0/PKG-INFO +0 -98
- albus_cli-0.1.0/README.md +0 -83
- albus_cli-0.1.0/RELEASING.md +0 -59
- albus_cli-0.1.0/src/albus_cli/client.py +0 -30
- albus_cli-0.1.0/src/albus_cli/context.py +0 -24
- albus_cli-0.1.0/src/albus_cli/main.py +0 -63
- albus_cli-0.1.0/src/albus_cli/output.py +0 -16
- albus_cli-0.1.0/tests/conftest.py +0 -78
- albus_cli-0.1.0/tests/test_cli.py +0 -186
- {albus_cli-0.1.0 → albus_cli-0.2.0}/LICENSE +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/src/albus_cli/__init__.py +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/src/albus_cli/__main__.py +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/src/albus_cli/commands/__init__.py +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/src/albus_cli/commands/agents.py +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/src/albus_cli/commands/secrets.py +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/tests/__init__.py +0 -0
- {albus_cli-0.1.0 → albus_cli-0.2.0}/tools/check +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report incorrect or unexpected behavior in the albus command
|
|
3
|
+
body:
|
|
4
|
+
- type: markdown
|
|
5
|
+
attributes:
|
|
6
|
+
value: |
|
|
7
|
+
The CLI is maintained upstream, and this repository is a mirror of each
|
|
8
|
+
release. Fixes land upstream and arrive in the next published version,
|
|
9
|
+
which closes the issue.
|
|
10
|
+
|
|
11
|
+
**Never paste access tokens, API keys, secret values, or customer data
|
|
12
|
+
into this issue.** Redact them from commands, logs, and tracebacks.
|
|
13
|
+
Report suspected vulnerabilities privately through
|
|
14
|
+
[SECURITY.md](https://github.com/albusgroup/albus-cli/blob/master/SECURITY.md)
|
|
15
|
+
instead of opening an issue.
|
|
16
|
+
|
|
17
|
+
- type: input
|
|
18
|
+
id: cli-version
|
|
19
|
+
attributes:
|
|
20
|
+
label: albus-cli version
|
|
21
|
+
description: Output of `pip show albus-cli` or `uv tool list`.
|
|
22
|
+
placeholder: "0.2.0"
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
|
|
26
|
+
- type: input
|
|
27
|
+
id: python-version
|
|
28
|
+
attributes:
|
|
29
|
+
label: Python version
|
|
30
|
+
description: Output of `python --version`.
|
|
31
|
+
placeholder: "3.12.4"
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
|
|
35
|
+
- type: textarea
|
|
36
|
+
id: reproduction
|
|
37
|
+
attributes:
|
|
38
|
+
label: Command and output
|
|
39
|
+
description: >
|
|
40
|
+
The command you ran and what it printed, with credentials and customer
|
|
41
|
+
data removed.
|
|
42
|
+
render: shell
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
|
|
46
|
+
- type: textarea
|
|
47
|
+
id: expected
|
|
48
|
+
attributes:
|
|
49
|
+
label: Expected behavior
|
|
50
|
+
validations:
|
|
51
|
+
required: true
|
|
52
|
+
|
|
53
|
+
- type: textarea
|
|
54
|
+
id: actual
|
|
55
|
+
attributes:
|
|
56
|
+
label: Actual behavior
|
|
57
|
+
description: >
|
|
58
|
+
What happened instead, including the exit status, the HTTP status, and
|
|
59
|
+
redacted output when relevant.
|
|
60
|
+
validations:
|
|
61
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Report a security vulnerability
|
|
4
|
+
url: https://github.com/albusgroup/albus-cli/blob/master/SECURITY.md
|
|
5
|
+
about: Report privately. Do not open a public issue for a vulnerability.
|
|
6
|
+
- name: How this repository is maintained
|
|
7
|
+
url: https://github.com/albusgroup/albus-cli/blob/master/CONTRIBUTING.md
|
|
8
|
+
about: This is a release mirror. It accepts issues, not pull requests.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
**This repository does not accept pull requests, and this one will be closed
|
|
2
|
+
automatically.**
|
|
3
|
+
|
|
4
|
+
It is a mirror of the Albus CLI: every release overwrites the whole tree, so a
|
|
5
|
+
merge here is deleted by the next published version.
|
|
6
|
+
|
|
7
|
+
Open an [issue](https://github.com/albusgroup/albus-cli/issues/new/choose)
|
|
8
|
+
instead and include your patch in the body. Maintainers apply the fix upstream,
|
|
9
|
+
and it ships in the next release, which closes the issue. See
|
|
10
|
+
[CONTRIBUTING.md](https://github.com/albusgroup/albus-cli/blob/master/CONTRIBUTING.md).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Close pull requests
|
|
2
|
+
|
|
3
|
+
# This repository is a mirror: every release overwrites its tree, so a merged
|
|
4
|
+
# pull request is deleted by the next release. GitHub cannot disable pull
|
|
5
|
+
# requests, so opened ones are closed here with a pointer to issues.
|
|
6
|
+
#
|
|
7
|
+
# pull_request_target runs this file from the default branch with a read/write
|
|
8
|
+
# token, so it also works for pull requests opened from forks.
|
|
9
|
+
on:
|
|
10
|
+
pull_request_target:
|
|
11
|
+
types: [opened, reopened]
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
pull-requests: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
close:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- env:
|
|
22
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
23
|
+
GH_REPO: ${{ github.repository }}
|
|
24
|
+
PULL_REQUEST: ${{ github.event.number }}
|
|
25
|
+
AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
26
|
+
run: |
|
|
27
|
+
cat > comment.md <<EOF
|
|
28
|
+
Thanks for taking the time to write this, @${AUTHOR} — but this
|
|
29
|
+
repository is a read-only mirror of the Albus CLI, and every release
|
|
30
|
+
overwrites its entire tree. A pull request merged here would be
|
|
31
|
+
deleted by the next published version, so this one is being closed
|
|
32
|
+
unmerged.
|
|
33
|
+
|
|
34
|
+
Please open an issue instead:
|
|
35
|
+
https://github.com/${GH_REPO}/issues/new/choose
|
|
36
|
+
|
|
37
|
+
Describe the behavior you expected, and include the diff or patch
|
|
38
|
+
from this pull request in the issue body. Maintainers apply the fix
|
|
39
|
+
in the private upstream repository, and it reaches you in the next
|
|
40
|
+
release, which closes the issue.
|
|
41
|
+
|
|
42
|
+
Report suspected vulnerabilities privately through
|
|
43
|
+
[SECURITY.md](https://github.com/${GH_REPO}/blob/master/SECURITY.md),
|
|
44
|
+
not as a public issue.
|
|
45
|
+
|
|
46
|
+
See [CONTRIBUTING.md](https://github.com/${GH_REPO}/blob/master/CONTRIBUTING.md)
|
|
47
|
+
for how this repository is maintained.
|
|
48
|
+
EOF
|
|
49
|
+
|
|
50
|
+
gh pr comment "$PULL_REQUEST" --body-file comment.md
|
|
51
|
+
gh pr close "$PULL_REQUEST"
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# albus-cli
|
|
2
|
+
|
|
3
|
+
Source of truth for the public `albus-cli` Python package: the `albus`
|
|
4
|
+
command-line client for the Albus REST API, built on `albus-sdk`. Releases are
|
|
5
|
+
published to PyPI and copied out to the public `albusgroup/albus-cli`
|
|
6
|
+
repository, which is a mirror. See
|
|
7
|
+
[`.agents/plans/sdk-publishing-from-monorepo.md`](../../.agents/plans/sdk-publishing-from-monorepo.md)
|
|
8
|
+
and the repository-wide
|
|
9
|
+
[engineering style guide](../../.agents/style-guide.md).
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
Run everything from `clients/albus-cli/`. `uv` owns the virtualenv and
|
|
14
|
+
`uv.lock`.
|
|
15
|
+
|
|
16
|
+
| Command | Purpose |
|
|
17
|
+
|---|---|
|
|
18
|
+
| `./setup.sh` | Install `uv`, Python 3.11, and the development environment |
|
|
19
|
+
| `make install` | `uv sync` |
|
|
20
|
+
| `make lint` | `ruff check` + `ruff format --check` |
|
|
21
|
+
| `make typecheck` | `mypy --strict` |
|
|
22
|
+
| `make test` | `pytest` |
|
|
23
|
+
| `make check` | all of the above |
|
|
24
|
+
| `./tools/check` | `make check`, and what a release runs |
|
|
25
|
+
| `./tools/publish --dry-run <version>` | Validate a release without uploading |
|
|
26
|
+
| `./tools/publish [--testpypi] <version>` | Upload, after explicit authorization |
|
|
27
|
+
| `./tools/mirror-release [--dry-run] <version> <checkout>` | Copy the released tree to the public mirror |
|
|
28
|
+
|
|
29
|
+
See [`RELEASING.md`](RELEASING.md). Publishing is never implied by a merge: a
|
|
30
|
+
version reaches PyPI only when it was explicitly authorized, and published
|
|
31
|
+
versions are immutable.
|
|
32
|
+
|
|
33
|
+
## Conventions
|
|
34
|
+
|
|
35
|
+
- The CLI owns argument parsing, output, and error reporting only. Request
|
|
36
|
+
building, retries, and response types belong to `albus-sdk`; never hand-roll
|
|
37
|
+
HTTP calls or redefine SDK models.
|
|
38
|
+
- Every command maps to exactly one SDK operation and prints its response as
|
|
39
|
+
JSON via `output.emit`. Do not add per-command formatting or extra
|
|
40
|
+
round trips.
|
|
41
|
+
- `login` and `logout` are the one exception: they sign in to Auth0 rather
|
|
42
|
+
than call Albus, so they drive `oauth.py` and the credential store, and
|
|
43
|
+
print prose. `login` also reads back `/whoami` to name the account it
|
|
44
|
+
signed in as. Any further exception needs the same kind of reason.
|
|
45
|
+
- `output.py` owns every colour the CLI emits, prose included: a command
|
|
46
|
+
composes its report from `progress`, `done`, `field`, `link`, and `note`
|
|
47
|
+
rather than calling `typer.secho` itself. Styling must survive being
|
|
48
|
+
piped, which means letting Typer drop the escapes and never writing them
|
|
49
|
+
by hand.
|
|
50
|
+
- `client.py` is the single owner of credential and transport configuration.
|
|
51
|
+
It resolves `ALBUS_API_KEY` first, then the stored browser session for the
|
|
52
|
+
base URL — renewing it when it has expired — and otherwise fails with a
|
|
53
|
+
message naming both ways to get a credential.
|
|
54
|
+
- A command wrapping an operation whose `security` in `api/openapi.yaml`
|
|
55
|
+
lists `bearerAuth` only (`whoami`, `tokens`, `invites`) builds its client
|
|
56
|
+
with `signed_in_client`, which uses the browser session and never an API
|
|
57
|
+
key: the key would be a 401 the caller cannot act on.
|
|
58
|
+
- Never print or log a token. Every sentence about a credential — not signed
|
|
59
|
+
in, expired, rejected, shadowed by an API key — is written in `client.py`,
|
|
60
|
+
which is the only place that knows which credential was sent. An
|
|
61
|
+
instruction for the credential the command did not use is worse than none.
|
|
62
|
+
- Renewing a stored session goes through `credentials.renew`, which holds the
|
|
63
|
+
store's lock across the Auth0 call. Two processes spending one refresh
|
|
64
|
+
token is a rotation reuse, and Auth0 revokes the family.
|
|
65
|
+
- Nothing from the credential store or `oauth.py` reaches the terminal as a
|
|
66
|
+
traceback; `main.py` turns it into an instruction naming the file.
|
|
67
|
+
- Tests drive commands through `typer.testing.CliRunner` with a fake SDK; they
|
|
68
|
+
never reach the network.
|
|
69
|
+
- Keep lines at 81 characters or fewer (`ruff` enforces it).
|
|
70
|
+
- The `albus-sdk` dependency is pinned to one version. The published CLI has
|
|
71
|
+
to name an SDK version that exists on PyPI, so the pin is bumped
|
|
72
|
+
deliberately in the pull request that needs the newer SDK — never floated to
|
|
73
|
+
whatever is latest at install time.
|
|
74
|
+
- The public repository accepts issues, not pull requests. A user-reported bug
|
|
75
|
+
is fixed here and reaches them in the next release, which closes the issue
|
|
76
|
+
via a `Mirror-Issue: albusgroup/albus-cli#<n>` trailer on the fix's commit.
|
|
77
|
+
- `.github/` is the mirror's, not this repository's: GitHub only runs workflows
|
|
78
|
+
and reads templates from a repository root, so these files are inert here and
|
|
79
|
+
active once the release copies the tree out. Anything the mirror needs
|
|
80
|
+
belongs here, since the release overwrites its entire tree. This repository's
|
|
81
|
+
own CI for the CLI is `.github/workflows/cli-test.yml` at the root.
|
|
82
|
+
- `install.sh` and `install.ps1` are what the public install instructions pipe
|
|
83
|
+
into a shell. They install the published package from PyPI and must keep
|
|
84
|
+
working against the mirror's `master`, which is where the documented URLs
|
|
85
|
+
point.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Contributing to albus-cli
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve the Albus CLI.
|
|
4
|
+
|
|
5
|
+
## Report a problem
|
|
6
|
+
|
|
7
|
+
Open a [GitHub issue](https://github.com/albusgroup/albus-cli/issues) with:
|
|
8
|
+
|
|
9
|
+
- The installed `albus-cli` and Python versions.
|
|
10
|
+
- The command you ran and the exact output.
|
|
11
|
+
- The expected and actual behavior.
|
|
12
|
+
|
|
13
|
+
Do not include access tokens, organization keys, secret values, or other
|
|
14
|
+
sensitive data. `albus` never prints a credential; if you have pasted one into
|
|
15
|
+
a log, redact it and rotate the credential.
|
|
16
|
+
|
|
17
|
+
Report suspected vulnerabilities privately by following
|
|
18
|
+
[SECURITY.md](SECURITY.md), not by opening a public issue.
|
|
19
|
+
|
|
20
|
+
## This repository is a mirror
|
|
21
|
+
|
|
22
|
+
The CLI is developed in the private Albus repository, alongside the
|
|
23
|
+
`api/openapi.yaml` contract and the SDK it is built on, and each release is
|
|
24
|
+
copied here. This repository does not accept pull requests: a change merged
|
|
25
|
+
here is removed by the next release, so one opened here is commented on and
|
|
26
|
+
closed automatically.
|
|
27
|
+
|
|
28
|
+
Issues are the right channel, and they are read. Maintainers fix the problem
|
|
29
|
+
upstream, and the fix arrives in the next published version, which closes the
|
|
30
|
+
issue.
|
|
31
|
+
|
|
32
|
+
See [RELEASING.md](RELEASING.md) for how a version is produced and published.
|
albus_cli-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: albus-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Command-line client for the Albus REST API
|
|
5
|
+
Project-URL: Homepage, https://github.com/albusgroup/albus-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/albusgroup/albus-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/albusgroup/albus-cli/issues
|
|
8
|
+
Author: Albus
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Requires-Dist: albus-sdk==0.6.0
|
|
13
|
+
Requires-Dist: typer<0.28,>=0.26.8
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# albus CLI
|
|
17
|
+
|
|
18
|
+
Command-line client for the Albus REST API, built on the public
|
|
19
|
+
[`albus-sdk`](https://pypi.org/project/albus-sdk/) Python SDK. It is a thin
|
|
20
|
+
shell over the SDK: every command that calls Albus maps to one API operation
|
|
21
|
+
and prints the JSON response, so output pipes into `jq`.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
macOS / Linux:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
curl -fsSL https://raw.githubusercontent.com/albusgroup/albus-cli/master/install.sh | sh
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Windows (PowerShell):
|
|
32
|
+
|
|
33
|
+
```powershell
|
|
34
|
+
irm https://raw.githubusercontent.com/albusgroup/albus-cli/master/install.ps1 | iex
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Pin a version:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
curl -fsSL https://raw.githubusercontent.com/albusgroup/albus-cli/master/install.sh | ALBUS_CLI_VERSION=0.2.0 sh
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The installer uses, in order: `uv tool install`, `pip install --user`, or
|
|
44
|
+
`pip` inside a conda environment. It does not download OS-specific binaries.
|
|
45
|
+
To install directly instead:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv tool install albus-cli
|
|
49
|
+
# or
|
|
50
|
+
pip install --user albus-cli
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Authentication
|
|
54
|
+
|
|
55
|
+
Sign in with a browser, which stores a session per base URL and renews it as
|
|
56
|
+
it expires:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
albus login
|
|
60
|
+
albus whoami
|
|
61
|
+
albus logout
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`albus health` is the one command that needs no credential, matching its empty
|
|
65
|
+
`security` in `api/openapi.yaml`: run it first to tell an unreachable API from
|
|
66
|
+
an unauthenticated one. `albus status` reports which credential is in effect
|
|
67
|
+
and whether Albus accepts it, as JSON, exiting 0 either way — it is the one
|
|
68
|
+
command to run to find out where you stand. `albus login --no-browser` prints
|
|
69
|
+
the authorization URL instead of opening it, for a coding agent signing in the
|
|
70
|
+
user in front of it.
|
|
71
|
+
|
|
72
|
+
Or export an organization API key, which wins over a stored session so CI and
|
|
73
|
+
agent harnesses need not touch disk:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
export ALBUS_API_KEY=... # organization API key
|
|
77
|
+
export ALBUS_BASE_URL=http://localhost:8080/api # optional; defaults to prod
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`--base-url` overrides `ALBUS_BASE_URL`, and `--timeout` bounds each request
|
|
81
|
+
(a waiting `sessions run` long-polls and is exempt).
|
|
82
|
+
|
|
83
|
+
`albus login` opens a browser on this machine and listens on
|
|
84
|
+
`127.0.0.1:8484-8487`; on a headless host, forward those ports or export
|
|
85
|
+
`ALBUS_API_KEY` instead. The
|
|
86
|
+
session is written to `$ALBUS_CONFIG_DIR/credentials.json`, else
|
|
87
|
+
`$XDG_CONFIG_HOME/albus/credentials.json`, else `~/.config/albus/`.
|
|
88
|
+
|
|
89
|
+
Operations whose `security` in `api/openapi.yaml` lists `bearerAuth` only,
|
|
90
|
+
such as `/whoami`, `/tokens`, and `/invites`, need the browser session.
|
|
91
|
+
`albus whoami`, `albus tokens`, and `albus invites` use it even when
|
|
92
|
+
`ALBUS_API_KEY` is exported, and say to run `albus login` when there is none.
|
|
93
|
+
Sign in first, then `albus tokens create` to mint the key that
|
|
94
|
+
`ALBUS_API_KEY` carries.
|
|
95
|
+
|
|
96
|
+
## Commands
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
albus health
|
|
100
|
+
albus --version
|
|
101
|
+
albus login
|
|
102
|
+
albus login --no-browser
|
|
103
|
+
albus whoami
|
|
104
|
+
albus logout
|
|
105
|
+
albus status
|
|
106
|
+
|
|
107
|
+
albus sessions run my-session -p "summarize the incident" \
|
|
108
|
+
--agent-name support-triage --model gemini-3.6-flash \
|
|
109
|
+
--provider gemini --credential albus.sh/secrets/gemini-key
|
|
110
|
+
albus sessions run my-session -p "and the follow-up?" \
|
|
111
|
+
--agent-name support-triage --agent-file agent.json --no-wait
|
|
112
|
+
albus sessions list
|
|
113
|
+
albus sessions get my-session --limit 20
|
|
114
|
+
albus sessions audit my-session --after "$cursor"
|
|
115
|
+
albus sessions delete my-session
|
|
116
|
+
|
|
117
|
+
albus secrets list
|
|
118
|
+
albus secrets create gemini-key --value ... # or pipe the value on stdin
|
|
119
|
+
albus secrets get gemini-key
|
|
120
|
+
albus secrets update gemini-key < value.txt
|
|
121
|
+
albus secrets delete gemini-key
|
|
122
|
+
|
|
123
|
+
albus agents list
|
|
124
|
+
albus agents get support-triage
|
|
125
|
+
albus agents revision support-triage "$revision"
|
|
126
|
+
|
|
127
|
+
albus tokens list
|
|
128
|
+
albus tokens create ci
|
|
129
|
+
albus tokens get "$id"
|
|
130
|
+
albus tokens delete "$id"
|
|
131
|
+
|
|
132
|
+
albus invites create teammate@example.com
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`tokens create` prints the only copy of the key value the API ever returns;
|
|
136
|
+
`list` and `get` return metadata alone.
|
|
137
|
+
|
|
138
|
+
`invites create` invites a person by email, and they get their own
|
|
139
|
+
organization on first sign-in. `CreateInviteRequest`'s `role` and
|
|
140
|
+
`organization_id` have no flags: one user is one organization for the beta.
|
|
141
|
+
|
|
142
|
+
`sessions run` waits for the assistant response by default; pass `--no-wait`
|
|
143
|
+
to return as soon as the invocation is accepted, or `--wait-timeout` to bound
|
|
144
|
+
the wait server-side. Pass `--idempotency-key` to make a run retry-safe. The
|
|
145
|
+
JSON output carries the effective `idempotency_key`, whether supplied by the
|
|
146
|
+
caller or generated by the server — absent only if something between the CLI
|
|
147
|
+
and Albus strips the response header on a run that supplied no key.
|
|
148
|
+
|
|
149
|
+
`--agent-file` takes a JSON object shaped like the API's `AgentConfig` and
|
|
150
|
+
covers what the flags do not (MCP servers, provider URL overrides):
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"model": { "name": "gemini-3.6-flash" },
|
|
155
|
+
"mcp_servers": [
|
|
156
|
+
{ "name": "github", "url": "https://mcp.example.com/mcp" }
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Documentation
|
|
162
|
+
|
|
163
|
+
| Reader | URL |
|
|
164
|
+
|---|---|
|
|
165
|
+
| A person | <https://docs.albus.sh> |
|
|
166
|
+
| A coding agent | <https://docs.albus.sh/agents/docs.md> |
|
|
167
|
+
|
|
168
|
+
The CLI prints both, so whoever is reading its output has the URL that is
|
|
169
|
+
theirs.
|
|
170
|
+
|
|
171
|
+
## Development
|
|
172
|
+
|
|
173
|
+
The CLI is developed in the private Albus repository, next to the
|
|
174
|
+
`api/openapi.yaml` contract and the SDK it is built on, and each release is
|
|
175
|
+
copied to the public `albusgroup/albus-cli` repository. That repository accepts
|
|
176
|
+
issues, not pull requests — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
make check # ruff, mypy --strict, pytest
|
|
180
|
+
```
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# albus CLI
|
|
2
|
+
|
|
3
|
+
Command-line client for the Albus REST API, built on the public
|
|
4
|
+
[`albus-sdk`](https://pypi.org/project/albus-sdk/) Python SDK. It is a thin
|
|
5
|
+
shell over the SDK: every command that calls Albus maps to one API operation
|
|
6
|
+
and prints the JSON response, so output pipes into `jq`.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
macOS / Linux:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
curl -fsSL https://raw.githubusercontent.com/albusgroup/albus-cli/master/install.sh | sh
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Windows (PowerShell):
|
|
17
|
+
|
|
18
|
+
```powershell
|
|
19
|
+
irm https://raw.githubusercontent.com/albusgroup/albus-cli/master/install.ps1 | iex
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Pin a version:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
curl -fsSL https://raw.githubusercontent.com/albusgroup/albus-cli/master/install.sh | ALBUS_CLI_VERSION=0.2.0 sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The installer uses, in order: `uv tool install`, `pip install --user`, or
|
|
29
|
+
`pip` inside a conda environment. It does not download OS-specific binaries.
|
|
30
|
+
To install directly instead:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv tool install albus-cli
|
|
34
|
+
# or
|
|
35
|
+
pip install --user albus-cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Authentication
|
|
39
|
+
|
|
40
|
+
Sign in with a browser, which stores a session per base URL and renews it as
|
|
41
|
+
it expires:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
albus login
|
|
45
|
+
albus whoami
|
|
46
|
+
albus logout
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`albus health` is the one command that needs no credential, matching its empty
|
|
50
|
+
`security` in `api/openapi.yaml`: run it first to tell an unreachable API from
|
|
51
|
+
an unauthenticated one. `albus status` reports which credential is in effect
|
|
52
|
+
and whether Albus accepts it, as JSON, exiting 0 either way — it is the one
|
|
53
|
+
command to run to find out where you stand. `albus login --no-browser` prints
|
|
54
|
+
the authorization URL instead of opening it, for a coding agent signing in the
|
|
55
|
+
user in front of it.
|
|
56
|
+
|
|
57
|
+
Or export an organization API key, which wins over a stored session so CI and
|
|
58
|
+
agent harnesses need not touch disk:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
export ALBUS_API_KEY=... # organization API key
|
|
62
|
+
export ALBUS_BASE_URL=http://localhost:8080/api # optional; defaults to prod
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`--base-url` overrides `ALBUS_BASE_URL`, and `--timeout` bounds each request
|
|
66
|
+
(a waiting `sessions run` long-polls and is exempt).
|
|
67
|
+
|
|
68
|
+
`albus login` opens a browser on this machine and listens on
|
|
69
|
+
`127.0.0.1:8484-8487`; on a headless host, forward those ports or export
|
|
70
|
+
`ALBUS_API_KEY` instead. The
|
|
71
|
+
session is written to `$ALBUS_CONFIG_DIR/credentials.json`, else
|
|
72
|
+
`$XDG_CONFIG_HOME/albus/credentials.json`, else `~/.config/albus/`.
|
|
73
|
+
|
|
74
|
+
Operations whose `security` in `api/openapi.yaml` lists `bearerAuth` only,
|
|
75
|
+
such as `/whoami`, `/tokens`, and `/invites`, need the browser session.
|
|
76
|
+
`albus whoami`, `albus tokens`, and `albus invites` use it even when
|
|
77
|
+
`ALBUS_API_KEY` is exported, and say to run `albus login` when there is none.
|
|
78
|
+
Sign in first, then `albus tokens create` to mint the key that
|
|
79
|
+
`ALBUS_API_KEY` carries.
|
|
80
|
+
|
|
81
|
+
## Commands
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
albus health
|
|
85
|
+
albus --version
|
|
86
|
+
albus login
|
|
87
|
+
albus login --no-browser
|
|
88
|
+
albus whoami
|
|
89
|
+
albus logout
|
|
90
|
+
albus status
|
|
91
|
+
|
|
92
|
+
albus sessions run my-session -p "summarize the incident" \
|
|
93
|
+
--agent-name support-triage --model gemini-3.6-flash \
|
|
94
|
+
--provider gemini --credential albus.sh/secrets/gemini-key
|
|
95
|
+
albus sessions run my-session -p "and the follow-up?" \
|
|
96
|
+
--agent-name support-triage --agent-file agent.json --no-wait
|
|
97
|
+
albus sessions list
|
|
98
|
+
albus sessions get my-session --limit 20
|
|
99
|
+
albus sessions audit my-session --after "$cursor"
|
|
100
|
+
albus sessions delete my-session
|
|
101
|
+
|
|
102
|
+
albus secrets list
|
|
103
|
+
albus secrets create gemini-key --value ... # or pipe the value on stdin
|
|
104
|
+
albus secrets get gemini-key
|
|
105
|
+
albus secrets update gemini-key < value.txt
|
|
106
|
+
albus secrets delete gemini-key
|
|
107
|
+
|
|
108
|
+
albus agents list
|
|
109
|
+
albus agents get support-triage
|
|
110
|
+
albus agents revision support-triage "$revision"
|
|
111
|
+
|
|
112
|
+
albus tokens list
|
|
113
|
+
albus tokens create ci
|
|
114
|
+
albus tokens get "$id"
|
|
115
|
+
albus tokens delete "$id"
|
|
116
|
+
|
|
117
|
+
albus invites create teammate@example.com
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`tokens create` prints the only copy of the key value the API ever returns;
|
|
121
|
+
`list` and `get` return metadata alone.
|
|
122
|
+
|
|
123
|
+
`invites create` invites a person by email, and they get their own
|
|
124
|
+
organization on first sign-in. `CreateInviteRequest`'s `role` and
|
|
125
|
+
`organization_id` have no flags: one user is one organization for the beta.
|
|
126
|
+
|
|
127
|
+
`sessions run` waits for the assistant response by default; pass `--no-wait`
|
|
128
|
+
to return as soon as the invocation is accepted, or `--wait-timeout` to bound
|
|
129
|
+
the wait server-side. Pass `--idempotency-key` to make a run retry-safe. The
|
|
130
|
+
JSON output carries the effective `idempotency_key`, whether supplied by the
|
|
131
|
+
caller or generated by the server — absent only if something between the CLI
|
|
132
|
+
and Albus strips the response header on a run that supplied no key.
|
|
133
|
+
|
|
134
|
+
`--agent-file` takes a JSON object shaped like the API's `AgentConfig` and
|
|
135
|
+
covers what the flags do not (MCP servers, provider URL overrides):
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"model": { "name": "gemini-3.6-flash" },
|
|
140
|
+
"mcp_servers": [
|
|
141
|
+
{ "name": "github", "url": "https://mcp.example.com/mcp" }
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
| Reader | URL |
|
|
149
|
+
|---|---|
|
|
150
|
+
| A person | <https://docs.albus.sh> |
|
|
151
|
+
| A coding agent | <https://docs.albus.sh/agents/docs.md> |
|
|
152
|
+
|
|
153
|
+
The CLI prints both, so whoever is reading its output has the URL that is
|
|
154
|
+
theirs.
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
The CLI is developed in the private Albus repository, next to the
|
|
159
|
+
`api/openapi.yaml` contract and the SDK it is built on, and each release is
|
|
160
|
+
copied to the public `albusgroup/albus-cli` repository. That repository accepts
|
|
161
|
+
issues, not pull requests — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
make check # ruff, mypy --strict, pytest
|
|
165
|
+
```
|