reallink-cli 0.1.10 → 0.1.12

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 CHANGED
@@ -13,6 +13,8 @@ If a prebuilt binary is not available for your OS/arch, npm falls back to a one-
13
13
  After install, `reallink` runs the compiled binary directly (no per-command cargo compile step).
14
14
  CLI caches update metadata daily. To keep command startup fast, network update checks run during `reallink login` (or explicitly via `reallink self-update --check`) rather than every command.
15
15
 
16
+ Output defaults to JSON for agent-friendly automation. You can switch to human text with `--format text`.
17
+
16
18
  ## Commands
17
19
 
18
20
  ```bash
@@ -23,12 +25,28 @@ reallink self-update
23
25
  reallink whoami
24
26
  reallink logout
25
27
 
28
+ reallink org list
29
+ reallink org create --name "My Org"
30
+ reallink org get --org-id org_xxx
31
+ reallink org update --org-id org_xxx --name "Renamed Org"
32
+ reallink org delete --org-id org_xxx
33
+ reallink org invites --org-id org_xxx
34
+ reallink org invite --org-id org_xxx --email invitee@example.com --role member --expires-in-days 7
35
+ reallink org members --org-id org_xxx
36
+ reallink org add-member --org-id org_xxx --email member@example.com --role member
37
+ reallink org update-member --org-id org_xxx --user-id usr_xxx --role admin
38
+ reallink org remove-member --org-id org_xxx --user-id usr_xxx
39
+
26
40
  reallink project list --org-id org_xxx
27
41
  reallink project create --org-id org_xxx --name "new project" --description "optional"
28
42
  reallink project get --project-id prj_xxx
29
43
  reallink project update --project-id prj_xxx --name "renamed project"
30
44
  reallink project update --project-id prj_xxx --clear-description
31
45
  reallink project delete --project-id prj_xxx
46
+ reallink project members --project-id prj_xxx
47
+ reallink project add-member --project-id prj_xxx --email member@example.com --role viewer
48
+ reallink project update-member --project-id prj_xxx --user-id usr_xxx --role editor
49
+ reallink project remove-member --project-id prj_xxx --user-id usr_xxx
32
50
 
33
51
  reallink token list
34
52
  reallink token create --name "ci-token" --scope trace:read --scope trace:write
@@ -36,6 +54,9 @@ reallink token revoke --token-id tok_xxx
36
54
 
37
55
  reallink file list --project-id prj_xxx
38
56
  reallink file get --asset-id ast_xxx
57
+ reallink file stat --asset-id ast_xxx
58
+ reallink file download --asset-id ast_xxx --output ./downloads/report.json
59
+ reallink file download --asset-id ast_xxx --output ./downloads/report.json --resume
39
60
  reallink file upload --project-id prj_xxx --source ./local/report.json --path reports/daily
40
61
  reallink file mkdir --project-id prj_xxx --path reports/archive
41
62
  reallink file move --asset-id ast_xxx --file-name reports/archive/report.json
@@ -48,8 +69,30 @@ reallink tool enable --tool-id trace.placeholder --user-id usr_xxx
48
69
  reallink tool run --tool-id trace.placeholder --project-id prj_xxx --input-file ./run-input.jsonc --idempotency-key run-001
49
70
  reallink tool runs --project-id prj_xxx
50
71
  reallink tool get-run --run-id trun_xxx
72
+
73
+ reallink link unreal --project-id prj_xxx --uproject "D:/Games/MyGame/MyGame.uproject" --engine-root "D:/Epic/UE_5.4" --set-default
74
+ reallink link list
75
+ reallink link use --project-id prj_xxx
76
+ reallink link doctor --project-id prj_xxx
77
+ reallink link doctor --project-id prj_xxx --verify-remote
78
+ reallink link paths --project-id prj_xxx
79
+ reallink link open
80
+ reallink link open --project-id prj_xxx --arg "-game" --arg "-log"
81
+ reallink link run --project-id prj_xxx --commandlet ResavePackages --headless --log --arg "-AllowCommandletRendering"
82
+ reallink link run --project-id prj_xxx --no-wait --arg "-game"
83
+ reallink link remove --project-id prj_xxx
84
+ reallink link plugin list
85
+ reallink link plugin install --project-id prj_xxx --name RealLinkUnreal --version latest
86
+ reallink link plugin install --project-id prj_xxx --name RealLinkUnreal --version latest --use-index
87
+ reallink link plugin install --project-id prj_xxx --name RealLinkUnreal --version 0.1.0 --engine --force
88
+ reallink link plugin install --project-id prj_xxx --name RealLinkUnreal --url https://cdn.example.com/RealLinkUnreal.zip --sha256 <hex>
51
89
  ```
52
90
 
91
+ `reallink login` scope behavior:
92
+ - By default it requests core/assets/trace/scheduler/admin scopes plus `tools:*`.
93
+ - If the server rejects `tools:*` as invalid, CLI automatically retries with compatible scopes.
94
+ - You can always pass explicit scopes via repeated `--scope`.
95
+
53
96
  `tool register`, `tool enable/disable` metadata, and `tool run --input-file` accept JSONC.
54
97
 
55
98
  ## Session Behavior
@@ -60,6 +103,90 @@ reallink tool get-run --run-id trun_xxx
60
103
  - You only need to log in again when the saved session is invalid/expired or you explicitly run `reallink logout`.
61
104
  - `reallink logout` revokes the current server session (`/auth/logout`) and clears the local session file.
62
105
 
106
+ ## Unreal Link Architecture
107
+
108
+ `reallink link ...` provides a Vercel-style "link local project to remote project" workflow for local Unreal development.
109
+
110
+ - `link unreal` creates/updates a binding between:
111
+ - remote Reallink `project_id`
112
+ - local `.uproject` path
113
+ - Unreal editor executable path
114
+ - optional engine root path
115
+ - `link use` sets default link target.
116
+ - `link open` launches local Unreal Editor using the stored mapping (plus optional forwarded args).
117
+ - `link run` executes editor/commandlet runs against the linked Unreal target.
118
+ - `link paths` resolves key local paths (uproject/editor/plugins/manifest) for scripting/agents.
119
+ - `link doctor` performs local health checks and optional remote project verification.
120
+ - `link list/remove` manage local bindings.
121
+ - `link plugin list/install` pulls plugins from a public bucket index/zip and installs into project or engine scope.
122
+
123
+ Local link metadata is stored at:
124
+ - Windows: `%APPDATA%\\reallink\\unreal-links.json`
125
+ - Linux/macOS: `${XDG_CONFIG_HOME:-~/.config}/reallink/unreal-links.json`
126
+
127
+ `link unreal` verifies remote project access by default (requires `reallink login`); use `--no-verify-remote` for offline setup.
128
+
129
+ `link unreal --sync-project` uploads a project-scoped manifest at:
130
+ - `.reallink/link/unreal-link.latest.json`
131
+
132
+ `link plugin install` default archive URL template:
133
+ - `<base_url>/<plugin_name>/<version>/<plugin_name>.zip`
134
+
135
+ Override with:
136
+ - `--url <full_zip_url>`
137
+
138
+ Index resolution:
139
+ - `--use-index --index-path index.json` resolves plugin version/url from public index JSON/JSONC.
140
+
141
+ Integrity:
142
+ - `--sha256 <hex>` verifies downloaded zip checksum.
143
+ - When `--use-index` is set and selected version contains `sha256`, CLI auto-verifies it.
144
+
145
+ ## Unreal Plugin Public Bucket Contract
146
+
147
+ Recommended public bucket layout:
148
+
149
+ ```text
150
+ plugins/unreal/
151
+ index.json
152
+ RealLinkUnreal/
153
+ latest/
154
+ RealLinkUnreal.zip
155
+ 0.1.0/
156
+ RealLinkUnreal.zip
157
+ ```
158
+
159
+ `index.json` / `index.jsonc` example:
160
+
161
+ ```jsonc
162
+ {
163
+ "schemaVersion": 1,
164
+ "plugins": [
165
+ {
166
+ "name": "RealLinkUnreal",
167
+ "latest": "0.1.0",
168
+ "versions": [
169
+ {
170
+ "version": "0.1.0",
171
+ "archiveUrl": "https://real-agent.link/plugins/unreal/RealLinkUnreal/0.1.0/RealLinkUnreal.zip",
172
+ "sha256": "optional-checksum"
173
+ }
174
+ ]
175
+ }
176
+ ]
177
+ }
178
+ ```
179
+
63
180
  ## Requirements
64
181
 
65
- - Rust toolchain (`cargo`) must be installed.
182
+ - Prebuilt platforms: no Rust toolchain required.
183
+ - Fallback build path (when no prebuilt binary exists): Rust toolchain (`cargo`) required.
184
+
185
+ ## Contributor Notes
186
+
187
+ - CLI login scope constants are generated from shared contract source:
188
+ - source: `packages/shared/src/api-contract.ts`
189
+ - generator: `packages/reallink-cli/scripts/generate-contract.mjs`
190
+ - output: `packages/reallink-cli/rust/src/generated/contract.rs`
191
+ - Run before build/release when scope contract changes:
192
+ - `pnpm --filter reallink-cli run contract:codegen`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reallink-cli",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Rust-based CLI for Reallink auth and API operations",
5
5
  "bin": {
6
6
  "reallink": "bin/reallink.cjs"
@@ -16,9 +16,10 @@
16
16
  "README.md"
17
17
  ],
18
18
  "scripts": {
19
- "prepack": "node ./scripts/prepare-prebuilt.cjs",
19
+ "contract:codegen": "node ./scripts/generate-contract.mjs",
20
+ "prepack": "pnpm run contract:codegen && node ./scripts/prepare-prebuilt.cjs",
20
21
  "postinstall": "node ./scripts/postinstall.cjs",
21
- "build": "cargo build --manifest-path ./rust/Cargo.toml --release",
22
+ "build": "pnpm run contract:codegen && cargo build --manifest-path ./rust/Cargo.toml --release",
22
23
  "dev": "node ./bin/reallink.cjs --help",
23
24
  "pack:local": "npm pack --json"
24
25
  },
Binary file
package/rust/Cargo.lock CHANGED
@@ -2,6 +2,12 @@
2
2
  # It is not intended for manual editing.
3
3
  version = 4
4
4
 
5
+ [[package]]
6
+ name = "adler2"
7
+ version = "2.0.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
10
+
5
11
  [[package]]
6
12
  name = "anstream"
7
13
  version = "0.6.21"
@@ -58,6 +64,15 @@ version = "1.0.102"
58
64
  source = "registry+https://github.com/rust-lang/crates.io-index"
59
65
  checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
60
66
 
67
+ [[package]]
68
+ name = "arbitrary"
69
+ version = "1.4.2"
70
+ source = "registry+https://github.com/rust-lang/crates.io-index"
71
+ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
72
+ dependencies = [
73
+ "derive_arbitrary",
74
+ ]
75
+
61
76
  [[package]]
62
77
  name = "atomic-waker"
63
78
  version = "1.1.2"
@@ -206,6 +221,21 @@ dependencies = [
206
221
  "libc",
207
222
  ]
208
223
 
224
+ [[package]]
225
+ name = "crc32fast"
226
+ version = "1.5.0"
227
+ source = "registry+https://github.com/rust-lang/crates.io-index"
228
+ checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
229
+ dependencies = [
230
+ "cfg-if",
231
+ ]
232
+
233
+ [[package]]
234
+ name = "crossbeam-utils"
235
+ version = "0.8.21"
236
+ source = "registry+https://github.com/rust-lang/crates.io-index"
237
+ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
238
+
209
239
  [[package]]
210
240
  name = "crypto-common"
211
241
  version = "0.1.7"
@@ -216,6 +246,17 @@ dependencies = [
216
246
  "typenum",
217
247
  ]
218
248
 
249
+ [[package]]
250
+ name = "derive_arbitrary"
251
+ version = "1.4.2"
252
+ source = "registry+https://github.com/rust-lang/crates.io-index"
253
+ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
254
+ dependencies = [
255
+ "proc-macro2",
256
+ "quote",
257
+ "syn",
258
+ ]
259
+
219
260
  [[package]]
220
261
  name = "digest"
221
262
  version = "0.10.7"
@@ -258,12 +299,28 @@ dependencies = [
258
299
  "syn",
259
300
  ]
260
301
 
302
+ [[package]]
303
+ name = "equivalent"
304
+ version = "1.0.2"
305
+ source = "registry+https://github.com/rust-lang/crates.io-index"
306
+ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
307
+
261
308
  [[package]]
262
309
  name = "find-msvc-tools"
263
310
  version = "0.1.9"
264
311
  source = "registry+https://github.com/rust-lang/crates.io-index"
265
312
  checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
266
313
 
314
+ [[package]]
315
+ name = "flate2"
316
+ version = "1.1.9"
317
+ source = "registry+https://github.com/rust-lang/crates.io-index"
318
+ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
319
+ dependencies = [
320
+ "crc32fast",
321
+ "miniz_oxide",
322
+ ]
323
+
267
324
  [[package]]
268
325
  name = "form_urlencoded"
269
326
  version = "1.2.2"
@@ -343,6 +400,12 @@ dependencies = [
343
400
  "wasm-bindgen",
344
401
  ]
345
402
 
403
+ [[package]]
404
+ name = "hashbrown"
405
+ version = "0.16.1"
406
+ source = "registry+https://github.com/rust-lang/crates.io-index"
407
+ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
408
+
346
409
  [[package]]
347
410
  name = "heck"
348
411
  version = "0.5.0"
@@ -551,6 +614,16 @@ dependencies = [
551
614
  "icu_properties",
552
615
  ]
553
616
 
617
+ [[package]]
618
+ name = "indexmap"
619
+ version = "2.13.0"
620
+ source = "registry+https://github.com/rust-lang/crates.io-index"
621
+ checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
622
+ dependencies = [
623
+ "equivalent",
624
+ "hashbrown",
625
+ ]
626
+
554
627
  [[package]]
555
628
  name = "ipnet"
556
629
  version = "2.11.0"
@@ -661,6 +734,16 @@ version = "2.8.0"
661
734
  source = "registry+https://github.com/rust-lang/crates.io-index"
662
735
  checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
663
736
 
737
+ [[package]]
738
+ name = "miniz_oxide"
739
+ version = "0.8.9"
740
+ source = "registry+https://github.com/rust-lang/crates.io-index"
741
+ checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
742
+ dependencies = [
743
+ "adler2",
744
+ "simd-adler32",
745
+ ]
746
+
664
747
  [[package]]
665
748
  name = "mio"
666
749
  version = "1.1.1"
@@ -910,7 +993,7 @@ dependencies = [
910
993
 
911
994
  [[package]]
912
995
  name = "reallink-cli"
913
- version = "0.1.10"
996
+ version = "0.1.12"
914
997
  dependencies = [
915
998
  "anyhow",
916
999
  "clap",
@@ -919,8 +1002,10 @@ dependencies = [
919
1002
  "reqwest",
920
1003
  "serde",
921
1004
  "serde_json",
1005
+ "sha2",
922
1006
  "tokio",
923
1007
  "webbrowser",
1008
+ "zip",
924
1009
  ]
925
1010
 
926
1011
  [[package]]
@@ -1120,6 +1205,12 @@ version = "1.3.0"
1120
1205
  source = "registry+https://github.com/rust-lang/crates.io-index"
1121
1206
  checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1122
1207
 
1208
+ [[package]]
1209
+ name = "simd-adler32"
1210
+ version = "0.3.8"
1211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1212
+ checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
1213
+
1123
1214
  [[package]]
1124
1215
  name = "slab"
1125
1216
  version = "0.4.12"
@@ -1972,8 +2063,37 @@ dependencies = [
1972
2063
  "syn",
1973
2064
  ]
1974
2065
 
2066
+ [[package]]
2067
+ name = "zip"
2068
+ version = "2.4.2"
2069
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2070
+ checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50"
2071
+ dependencies = [
2072
+ "arbitrary",
2073
+ "crc32fast",
2074
+ "crossbeam-utils",
2075
+ "displaydoc",
2076
+ "flate2",
2077
+ "indexmap",
2078
+ "memchr",
2079
+ "thiserror 2.0.18",
2080
+ "zopfli",
2081
+ ]
2082
+
1975
2083
  [[package]]
1976
2084
  name = "zmij"
1977
2085
  version = "1.0.21"
1978
2086
  source = "registry+https://github.com/rust-lang/crates.io-index"
1979
2087
  checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
2088
+
2089
+ [[package]]
2090
+ name = "zopfli"
2091
+ version = "0.8.3"
2092
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2093
+ checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
2094
+ dependencies = [
2095
+ "bumpalo",
2096
+ "crc32fast",
2097
+ "log",
2098
+ "simd-adler32",
2099
+ ]
package/rust/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "reallink-cli"
3
- version = "0.1.10"
3
+ version = "0.1.12"
4
4
  edition = "2021"
5
5
  description = "CLI for Reallink auth and token workflows"
6
6
  license = "MIT"
@@ -13,5 +13,7 @@ reqwest = { version = "0.12", default-features = false, features = ["json", "rus
13
13
  serde = { version = "1.0", features = ["derive"] }
14
14
  serde_json = "1.0"
15
15
  json5 = "0.4"
16
- tokio = { version = "1.42", features = ["macros", "rt-multi-thread", "time"] }
16
+ sha2 = "0.10"
17
+ tokio = { version = "1.42", features = ["macros", "rt-multi-thread", "time", "fs", "io-util"] }
17
18
  webbrowser = "1.0"
19
+ zip = { version = "2.2", default-features = false, features = ["deflate"] }
@@ -0,0 +1,52 @@
1
+ // This file is auto-generated by packages/reallink-cli/scripts/generate-contract.mjs.
2
+ // Do not edit by hand. Update packages/shared/src/api-contract.ts and re-run codegen.
3
+ #![allow(dead_code)]
4
+
5
+ pub const API_CONTRACT_VERSION: &str = "2026.03.0";
6
+ pub const API_TOKEN_SCOPES: &[&str] = &[
7
+ "core:read",
8
+ "core:write",
9
+ "org:admin",
10
+ "project:admin",
11
+ "assets:read",
12
+ "assets:write",
13
+ "trace:read",
14
+ "trace:write",
15
+ "tools:read",
16
+ "tools:write",
17
+ "tools:run",
18
+ "scheduler:read",
19
+ "scheduler:write",
20
+ ];
21
+ pub const CLI_DEFAULT_LOGIN_SCOPES: &[&str] = &[
22
+ "core:read",
23
+ "core:write",
24
+ "assets:read",
25
+ "assets:write",
26
+ "trace:read",
27
+ "trace:write",
28
+ "scheduler:read",
29
+ "scheduler:write",
30
+ "org:admin",
31
+ "project:admin",
32
+ ];
33
+ pub const CLI_TOOL_SCOPES: &[&str] = &[
34
+ "tools:read",
35
+ "tools:write",
36
+ "tools:run",
37
+ ];
38
+ pub const CLI_DEFAULT_LOGIN_SCOPES_WITH_TOOLS: &[&str] = &[
39
+ "core:read",
40
+ "core:write",
41
+ "assets:read",
42
+ "assets:write",
43
+ "trace:read",
44
+ "trace:write",
45
+ "scheduler:read",
46
+ "scheduler:write",
47
+ "org:admin",
48
+ "project:admin",
49
+ "tools:read",
50
+ "tools:write",
51
+ "tools:run",
52
+ ];
@@ -0,0 +1 @@
1
+ pub mod contract;