yungle-cli 0.1.2 → 0.2.0
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/LICENSE +1 -1
- package/README.md +118 -68
- package/dist/yungle.mjs +2897 -568
- package/package.json +22 -17
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,96 +1,146 @@
|
|
|
1
1
|
# yungle-cli
|
|
2
2
|
|
|
3
|
-
Send and sync files with [Yungle](https://yungle.co) from
|
|
3
|
+
Send, receive and sync large files with [Yungle](https://yungle.co?ref=npm) from your terminal
|
|
4
|
+
or CI. Resumable uploads up to 100 GB, private and EU-hosted.
|
|
5
|
+
|
|
6
|
+
<img src="https://raw.githubusercontent.com/heindewilde/yungle-clients/main/.github/assets/demo.svg" alt="yungle send, yungle status and yungle get in a terminal" width="720">
|
|
4
7
|
|
|
5
8
|
```bash
|
|
6
9
|
npm install -g yungle-cli
|
|
7
|
-
yungle
|
|
8
|
-
yungle send ~/Shoot
|
|
10
|
+
yungle login # opens your browser, once
|
|
11
|
+
yungle send ~/Shoot # uploads resumably, prints the link
|
|
9
12
|
```
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Yungle's upload engine is resumable at part granularity and sized for 100 GB
|
|
14
|
-
transfers. Until this existed, the only thing that could drive it was a browser
|
|
15
|
-
tab that had to stay open — which is the wrong process to hand an eight-hour
|
|
16
|
-
upload to. This one survives a closed laptop lid: interrupt `yungle send`, run
|
|
17
|
-
the same command again, and it continues from the last committed part instead of
|
|
18
|
-
starting over.
|
|
14
|
+
Works on the free plan. Node 22 or newer.
|
|
19
15
|
|
|
20
16
|
## Commands
|
|
21
17
|
|
|
18
|
+
**Get started**
|
|
19
|
+
|
|
22
20
|
| | |
|
|
23
21
|
|---|---|
|
|
24
|
-
| `yungle
|
|
25
|
-
| `yungle
|
|
26
|
-
| `yungle
|
|
27
|
-
| `yungle push <paths…> --collection <id>` | Upload into a collection |
|
|
28
|
-
| `yungle ls transfers\|collections\|contacts` | List things |
|
|
29
|
-
| `yungle rm transfer <id>` | Revoke a transfer |
|
|
30
|
-
| `yungle mcp install` | Let an AI assistant read your Yungle |
|
|
31
|
-
| `yungle mcp status` | Show where that is installed |
|
|
22
|
+
| `yungle login` | Sign in with your browser. `--key` uses an API key instead (servers, CI) |
|
|
23
|
+
| `yungle whoami` | Who you are signed in as, and what you may do |
|
|
24
|
+
| `yungle logout` | Sign out and revoke the session |
|
|
32
25
|
|
|
33
|
-
|
|
34
|
-
goes to stderr, so `yungle send … --json \| jq` works.
|
|
26
|
+
**Send and receive**
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
| | |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `yungle send <paths…>` | Send files or folders and print the link. `--to`, `--message`, `--title`, `--password`, `--expires` |
|
|
31
|
+
| `yungle get <link>` | Download a transfer sent to you. No account needed. `--out`, `--zip`, `--password` |
|
|
32
|
+
| `yungle status [<id\|link>]` | Who opened and downloaded a transfer. Without an id, pick from your recent ones |
|
|
33
|
+
| `yungle transfers` | Your recent transfers |
|
|
34
|
+
| `yungle revoke <id>` | Stop a transfer's link for good (asks first) |
|
|
38
35
|
|
|
39
|
-
|
|
36
|
+
**Collections** (paid plans)
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
| | |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `yungle push <paths…> --collection <id>` | Upload into a collection, optionally `--folder <id>` |
|
|
41
|
+
| `yungle watch <dir> --collection <id>` | Keep uploading new files as they appear |
|
|
42
|
+
| `yungle collections` | Your collections |
|
|
43
|
+
| `yungle contacts` | Your contacts |
|
|
44
|
+
|
|
45
|
+
**Everything else**
|
|
46
|
+
|
|
47
|
+
| | |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `yungle open [<id>\|plan\|keys\|webhooks]` | Open the dashboard, or a transfer, in your browser |
|
|
50
|
+
| `yungle webhooks ls` · `listen` | List endpoints, or print events live and `--forward-to` a local server |
|
|
51
|
+
| `yungle mcp install` · `status` | Connect a local AI assistant (see below) |
|
|
52
|
+
| `yungle completion <zsh\|bash\|fish>` | Tab completion |
|
|
53
|
+
|
|
54
|
+
Ids can be shortened: the last 6–8 characters of a transfer id, or its link, work everywhere
|
|
55
|
+
an id does. `yungle <command> --help` shows examples. Old spellings (`auth login`,
|
|
56
|
+
`ls transfers`, `rm transfer`) keep working.
|
|
57
|
+
|
|
58
|
+
## For people, and for scripts
|
|
59
|
+
|
|
60
|
+
The same command behaves right in both places:
|
|
61
|
+
|
|
62
|
+
| | At a terminal | In a pipe or CI | With `--json` |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| Output | Colour, tables, a live progress bar | Plain text; `send` prints only the link | One JSON object on stdout |
|
|
65
|
+
| Missing arguments | Asks, step by step | Fails with a usage hint | Fails with a usage hint |
|
|
66
|
+
| Confirmations | Asks | Never asks | Never asks |
|
|
67
|
+
|
|
68
|
+
Progress always goes to stderr, so `yungle send dist/ | pbcopy` copies just the link and
|
|
69
|
+
`yungle send dist/ --json | jq -r .url` works. `--yes` means "never ask", for scripts that run at
|
|
70
|
+
a terminal. `NO_COLOR` and `FORCE_COLOR` are respected.
|
|
71
|
+
|
|
72
|
+
Every error says what happened and the command that fixes it:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
✖ Your sign-in is no longer valid (revoked, expired or mistyped).
|
|
76
|
+
→ yungle login
|
|
43
77
|
```
|
|
44
78
|
|
|
45
|
-
|
|
46
|
-
whichever clients you have — Claude Desktop, Claude Code, Cursor, Windsurf —
|
|
47
|
-
so you can ask *"what did I send last week?"* or *"did the client download it
|
|
48
|
-
yet?"* instead of opening the dashboard. Restart the client afterwards; they
|
|
49
|
-
read their MCP config at startup.
|
|
50
|
-
|
|
51
|
-
`--dry-run` shows what would change and writes nothing. `--client <id>` targets
|
|
52
|
-
one. Re-running is safe: it reports `already current` when nothing needs doing,
|
|
53
|
-
and updates the entry if your key has changed.
|
|
54
|
-
|
|
55
|
-
**It refuses a key that can write.** The MCP server has no tool that sends,
|
|
56
|
-
invites, revokes or deletes, so a write scope grants an assistant nothing it can
|
|
57
|
-
use — while putting a credential that *could* change your account into a file an
|
|
58
|
-
assistant reads. Create a read-only key at
|
|
59
|
-
[yungle.co/dashboard/settings/api](https://yungle.co/dashboard/settings/api);
|
|
60
|
-
reading the API is free on any plan.
|
|
61
|
-
|
|
62
|
-
Two things worth knowing. Your key ends up in that client's config file in plain
|
|
63
|
-
text — that is how stdio MCP servers receive credentials, and it is why the
|
|
64
|
-
read-only rule above is enforced rather than suggested. And a config file that
|
|
65
|
-
does not parse is **refused, never overwritten**: it holds every other MCP server
|
|
66
|
-
you have set up, and a trailing comma is not a reason to replace it. The previous
|
|
67
|
-
contents are copied to `<config>.yungle-bak` before any change.
|
|
79
|
+
Exit codes: `0` success, `1` failure, `2` usage error, `130` cancelled.
|
|
68
80
|
|
|
69
81
|
## Resuming
|
|
70
82
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
Interrupt `yungle send` (Ctrl-C, a dropped connection, a closed lid) and run the same command
|
|
84
|
+
again: it continues from the last committed part instead of starting over.
|
|
85
|
+
|
|
86
|
+
State lives in `~/.cache/yungle/`, keyed by the local files' paths, sizes and modification
|
|
87
|
+
times, since that is all the next run has to go on. Change a file and it starts over, because
|
|
88
|
+
a resumed upload whose declared size no longer matches would fail at the very end. Sessions
|
|
89
|
+
expire after two hours, matching the upload tokens they hold.
|
|
90
|
+
|
|
91
|
+
## Watching a folder
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
yungle watch ~/Renders --collection 01J8Z3M9Q0W4
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For a render box writing frames, a card reader, an export folder. It polls (every 10 seconds,
|
|
98
|
+
`--interval` to change) rather than using file-system events, which are unreliable on network
|
|
99
|
+
shares and external drives. A file is uploaded only once it has stopped changing, so a
|
|
100
|
+
half-written frame never goes up. What was uploaded is remembered, so a restart never uploads
|
|
101
|
+
twice. Files already there when it starts are left alone unless you pass `--existing`.
|
|
102
|
+
|
|
103
|
+
## Signing in
|
|
77
104
|
|
|
78
|
-
|
|
79
|
-
|
|
105
|
+
`yungle login` opens your browser, you confirm a code, done. The session is stored in
|
|
106
|
+
`~/.config/yungle/config.json` (mode `0600`) and renews itself.
|
|
80
107
|
|
|
81
|
-
|
|
108
|
+
**A browser sign-in makes links but never emails anyone.** Signing in by code can be phished
|
|
109
|
+
("enter this code" is the whole attack), so that session can't make Yungle mail strangers or
|
|
110
|
+
register a webhook. `yungle send --to` notices before uploading and offers to send a link
|
|
111
|
+
instead.
|
|
82
112
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Settings → API keys.
|
|
113
|
+
To email recipients, and on servers or in CI, use an API key: `yungle login --key` (asks for
|
|
114
|
+
it) or set `YUNGLE_API_KEY`, which always wins over the config file. Create keys under
|
|
115
|
+
[Settings → API keys](https://yungle.co/dashboard/settings/api) or with `yungle open keys`.
|
|
86
116
|
|
|
87
|
-
|
|
88
|
-
|
|
117
|
+
## Connecting a local AI assistant
|
|
118
|
+
|
|
119
|
+
The easiest way to connect Claude or Cursor is the hosted server at `https://yungle.co/mcp`:
|
|
120
|
+
add it in the client and sign in, no key involved.
|
|
121
|
+
|
|
122
|
+
To run the MCP server locally instead:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
yungle login --key # a read-only key is best
|
|
126
|
+
yungle mcp install # or --client claude-code, --dry-run
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This writes the [Yungle MCP server](https://www.npmjs.com/package/yungle-mcp) into Claude
|
|
130
|
+
Desktop, Claude Code, Cursor and Windsurf, whichever you have. Restart the client afterwards.
|
|
131
|
+
|
|
132
|
+
- **It wants a real API key**, not a browser session, which expires within the hour. The key
|
|
133
|
+
ends up in the client's config file in plain text, which is how local MCP servers receive
|
|
134
|
+
credentials.
|
|
135
|
+
- **It refuses a key that can write** unless you pass `--allow-write`, which lets the assistant
|
|
136
|
+
create share links (every one still needs your confirmation).
|
|
137
|
+
- **A config file that does not parse is refused, never overwritten.** It holds your other
|
|
138
|
+
MCP servers too. The previous contents are copied to `<config>.yungle-bak` before any change.
|
|
89
139
|
|
|
90
140
|
## What it cannot do
|
|
91
141
|
|
|
92
|
-
Your vault and end-to-end encrypted transfers are not reachable
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
142
|
+
Your vault and end-to-end encrypted transfers are not reachable: their keys are derived in the
|
|
143
|
+
browser and never sent to Yungle. `yungle get` on an end-to-end encrypted link says so and
|
|
144
|
+
points you to the browser. See <https://yungle.co/developers/unsupported>.
|
|
145
|
+
|
|
146
|
+
Docs: <https://yungle.co/developers/cli?ref=npm> · Source: <https://github.com/heindewilde/yungle-clients> · MIT
|