yungle-cli 0.1.2 → 0.2.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.
Files changed (4) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +119 -69
  3. package/dist/yungle.mjs +2897 -568
  4. package/package.json +22 -17
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Hein de Wilde
3
+ Copyright (c) 2026 Brainpower
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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 the command line.
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
- npm install -g yungle-cli
7
- yungle auth login
8
- yungle send ~/Shoot --to client@example.com
9
+ npm install -g yungle-cli # or: brew install heindewilde/yungle/yungle
10
+ yungle login # opens your browser, once
11
+ yungle send ~/Shoot # uploads resumably, prints the link
9
12
  ```
10
13
 
11
- ## Why a CLI
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 auth login` | Save an API key (or set `YUNGLE_API_KEY`) |
25
- | `yungle auth status` | Which key is in use, and what it may do |
26
- | `yungle send <paths…>` | Send files; prints the share link |
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
- `--json` on any command prints a machine-readable object on stdout; progress
34
- goes to stderr, so `yungle send … --json \| jq` works.
26
+ **Send and receive**
35
27
 
36
- Folders keep their structure. Hidden files are skipped when walking a directory
37
- and kept when named directly.
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 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
- ## Letting an assistant read your Yungle
36
+ **Collections** (paid plans)
40
37
 
41
- ```bash
42
- yungle mcp install
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
- Writes the [Yungle MCP server](https://www.npmjs.com/package/yungle-mcp) into
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
- State lives in `~/.cache/yungle/`. A session is keyed by the *local files* —
72
- their paths, sizes and modification times — because that is all the next
73
- invocation has to go on; it cannot know the transfer id of a process that was
74
- killed. Run the same command with the same files and it resumes; change a file
75
- and it starts over, because resuming into a row whose declared size no longer
76
- matches fails at the very end with an error that points nowhere useful.
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
- Sessions expire after two hours, matching the lifetime of the upload tokens
79
- they hold.
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
- ## Credentials
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
- Read from `YUNGLE_API_KEY` first, then `~/.config/yungle/config.json` (written
84
- `0600`). A key acts as one workspace and can be revoked at any time from
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
- The API is available on any paid Yungle plan. Full documentation:
88
- <https://yungle.co/developers>
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 through the API
93
- this is built on. Their keys are derived in the client and never sent to us, so
94
- a server-side API has nothing to offer — see
95
- <https://yungle.co/developers/unsupported>. Reaching them from a local client is
96
- possible in principle and is not built yet.
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