@ornncompute/cli 0.1.0 → 0.1.1
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.
- package/README.md +48 -23
- package/package.json +3 -3
- package/src/api-client.mjs +29 -5
- package/src/cli.mjs +1523 -382
- package/src/device-auth.mjs +1 -1
package/README.md
CHANGED
|
@@ -1,44 +1,69 @@
|
|
|
1
1
|
# Ornn Fabric CLI
|
|
2
2
|
|
|
3
|
-
Command-line access for Ornn Fabric
|
|
4
|
-
|
|
3
|
+
Command-line access for Ornn Fabric bare-metal compute workflows: find
|
|
4
|
+
available capacity, buy or bid, manage reservations, activate SSH access,
|
|
5
|
+
resell capacity, and open billing.
|
|
6
|
+
|
|
7
|
+
For the end-user install, browser-login, command, and troubleshooting guide, see
|
|
8
|
+
the root [`CLI.md`](../../CLI.md).
|
|
5
9
|
|
|
6
10
|
## Install
|
|
7
11
|
|
|
8
12
|
```bash
|
|
9
|
-
curl -fsSL https://
|
|
13
|
+
curl -fsSL https://compute.ornn.com/cli/install | sh
|
|
10
14
|
```
|
|
11
15
|
|
|
12
16
|
The installer requires Node.js 20 or newer and npm. It installs `@ornncompute/cli`
|
|
13
17
|
globally, exposes both `fabric` and `ornn` binaries, adds the npm global bin
|
|
14
18
|
directory to the user's shell profile when needed, and writes
|
|
15
|
-
`ORNN_AUTH_BASE_URL` for the Fabric host that served the installer.
|
|
19
|
+
`ORNN_AUTH_BASE_URL` for the Fabric host that served the installer. The
|
|
20
|
+
installer prints a short Ornn Compute welcome banner and login prompt; set
|
|
21
|
+
`ORNN_INSTALL_BANNER=0` to skip it or `ORNN_INSTALL_ANIMATION=0` to keep it
|
|
22
|
+
static.
|
|
16
23
|
|
|
17
24
|
## Commands
|
|
18
25
|
|
|
19
26
|
```bash
|
|
20
|
-
fabric
|
|
21
|
-
fabric
|
|
22
|
-
fabric
|
|
23
|
-
fabric
|
|
24
|
-
fabric
|
|
25
|
-
fabric
|
|
26
|
-
fabric
|
|
27
|
-
fabric
|
|
28
|
-
fabric
|
|
29
|
-
fabric
|
|
30
|
-
fabric
|
|
31
|
-
fabric
|
|
32
|
-
fabric
|
|
33
|
-
fabric
|
|
34
|
-
fabric
|
|
27
|
+
fabric help [command]
|
|
28
|
+
fabric login [--auth-base <url>] [--no-browser] [--timeout <seconds>]
|
|
29
|
+
fabric whoami [--json]
|
|
30
|
+
fabric status [--json]
|
|
31
|
+
fabric availability list [--gpu-type <type>] [--facility <name>] [--operator <name>] [--json]
|
|
32
|
+
fabric availability show <listing-id> [--open] [--json]
|
|
33
|
+
fabric buy <listing-id> [--no-open] [--json]
|
|
34
|
+
fabric bid create <listing-id> --gpu-count <n> --min-gpu-count <n> --start-date <yyyy-mm-dd> --end-date <yyyy-mm-dd> --price <usd> [--no-open] [--json]
|
|
35
|
+
fabric bid list [--json]
|
|
36
|
+
fabric bid show <bid-id> [--open] [--json]
|
|
37
|
+
fabric bid update <bid-id> --gpu-count <n> --min-gpu-count <n> --start-date <yyyy-mm-dd> --end-date <yyyy-mm-dd> --price <usd>
|
|
38
|
+
fabric bid withdraw <bid-id>
|
|
39
|
+
fabric reservations list [--status <status>] [--json]
|
|
40
|
+
fabric reservations show <reservation-id> [--open] [--json]
|
|
41
|
+
fabric reservations checkout <reservation-id> [--no-open] [--json]
|
|
42
|
+
fabric access show <reservation-id> [--json]
|
|
43
|
+
fabric access activate <reservation-id> --ssh-key-id <id> [--username <name>] [--no-open] [--json]
|
|
44
|
+
fabric access push-keys <reservation-id> --ssh-key-id <id> [--json]
|
|
45
|
+
fabric resale browse [--json]
|
|
46
|
+
fabric resale list <reservation-id> --ask-price <usd> [--no-open] [--json]
|
|
47
|
+
fabric resale update <reservation-id> --ask-price <usd> [--no-open] [--json]
|
|
48
|
+
fabric resale delist <reservation-id> [--no-open] [--json]
|
|
49
|
+
fabric ssh-keys list [--json]
|
|
50
|
+
fabric ssh-keys add --public-key <key> [--label <label>] [--json]
|
|
51
|
+
fabric ssh-keys add --public-key-file <path> [--label <label>] [--json]
|
|
52
|
+
fabric ssh-keys delete <key-id> [--json]
|
|
53
|
+
fabric billing open [--no-open] [--json]
|
|
54
|
+
fabric api <get|post|patch|put|delete> <compute-path> [--data <json>] [--raw]
|
|
35
55
|
fabric logout
|
|
36
56
|
```
|
|
37
57
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
Commands print concise human-readable output by default. Use `--json` on
|
|
59
|
+
read/show/list commands and transaction handoffs when you need structured
|
|
60
|
+
stdout for scripts. Errors and login/browser progress go to stderr.
|
|
61
|
+
|
|
62
|
+
`fabric login` opens a browser to the Fabric auth origin, lets the user sign in
|
|
63
|
+
with the normal web account flow, and then completes automatically in the
|
|
64
|
+
terminal once the browser session approves the CLI device request. If the CLI
|
|
65
|
+
cannot open a browser, copy the printed URL into any browser and sign in there;
|
|
66
|
+
the terminal keeps polling until the login is approved or expires.
|
|
42
67
|
|
|
43
68
|
Run `fabric --help` for the full command list and `fabric api` for the
|
|
44
69
|
allowlisted compute API escape hatch.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ornncompute/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Command-line interface for Ornn Fabric
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Command-line interface for Ornn Fabric bare-metal compute workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"fabric": "bin/ornn.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"src",
|
|
13
13
|
"README.md"
|
|
14
14
|
],
|
|
15
|
-
"homepage": "https://
|
|
15
|
+
"homepage": "https://compute.ornn.com",
|
|
16
16
|
"bugs": {
|
|
17
17
|
"url": "https://github.com/Ornn-AI/fabric/issues"
|
|
18
18
|
},
|
package/src/api-client.mjs
CHANGED
|
@@ -76,10 +76,11 @@ export async function cliRequest({
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
const text = await response.text();
|
|
79
|
-
const data = text ? parseJson(text, url.toString()) : null;
|
|
79
|
+
const data = text ? parseJson(text, url.toString(), response) : null;
|
|
80
80
|
if (!response.ok) {
|
|
81
|
-
const detail = data?.detail
|
|
82
|
-
|
|
81
|
+
const detail = data?.detail ?? data?.error ?? response.statusText;
|
|
82
|
+
const message = detailMessage(detail) || response.statusText;
|
|
83
|
+
throw new CliApiError(`Fabric request failed: ${message}`, {
|
|
83
84
|
detail: data,
|
|
84
85
|
status: response.status,
|
|
85
86
|
});
|
|
@@ -103,10 +104,33 @@ export function normalizeComputePath(path) {
|
|
|
103
104
|
return trimmed;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
function parseJson(text, url) {
|
|
107
|
+
function parseJson(text, url, response) {
|
|
107
108
|
try {
|
|
108
109
|
return JSON.parse(text);
|
|
109
110
|
} catch {
|
|
110
|
-
|
|
111
|
+
const contentType = response?.headers?.get?.("content-type") || "";
|
|
112
|
+
const isHtml = /html/i.test(contentType) || /^\s*</.test(text);
|
|
113
|
+
const hint = isHtml
|
|
114
|
+
? " The Fabric host may not have this CLI endpoint deployed yet."
|
|
115
|
+
: "";
|
|
116
|
+
throw new CliApiError(`Fabric returned a non-JSON response from ${url}.${hint}`, {
|
|
117
|
+
status: response?.status,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function detailMessage(detail) {
|
|
123
|
+
if (typeof detail === "string") {
|
|
124
|
+
return detail;
|
|
125
|
+
}
|
|
126
|
+
if (!detail || typeof detail !== "object") {
|
|
127
|
+
return "";
|
|
128
|
+
}
|
|
129
|
+
if (typeof detail.summary === "string") {
|
|
130
|
+
return detail.summary;
|
|
131
|
+
}
|
|
132
|
+
if (typeof detail.code === "string") {
|
|
133
|
+
return detail.code;
|
|
111
134
|
}
|
|
135
|
+
return "";
|
|
112
136
|
}
|