srift 4.1.0__tar.gz → 4.3.2__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.
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024-2026 SRIFT (Sripto Corporation Private Limited)
3
+ Copyright (c) 2024-2026 The SRIFT contributors
4
4
  https://srift.app
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,15 +1,16 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: srift
3
- Version: 4.1.0
4
- Summary: Zero-config, end-to-end encrypted peer-to-peer file transfer CLI, MCP server and Python SDK for AI agents (Claude, Cursor, Windsurf, Continue, Zed) — runs the official Node.js CLI via a bundled Node.js runtime, no separate Node.js install required.
3
+ Version: 4.3.2
4
+ Summary: Send any file as a download link from the CLI, Python or an AI agent (MCP server). Encrypted P2P file transfer and chat. No account. Bundles the SRIFT CLI.
5
5
  Project-URL: Homepage, https://srift.app
6
6
  Project-URL: Repository, https://github.com/srivardhan113/SRIFT-Open_Source
7
7
  Project-URL: Issues, https://github.com/srivardhan113/SRIFT-Open_Source/issues
8
- Project-URL: Documentation, https://srift.app/docs
8
+ Project-URL: Documentation, https://srift.app/AGENTS.md
9
+ Project-URL: Changelog, https://srift.app/CHANGELOG.md
9
10
  Author: SRIFT
10
11
  License: MIT License
11
12
 
12
- Copyright (c) 2024-2026 SRIFT (Sripto Corporation Private Limited)
13
+ Copyright (c) 2024-2026 The SRIFT contributors
13
14
  https://srift.app
14
15
 
15
16
  Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,7 +31,7 @@ License: MIT License
30
31
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
32
  SOFTWARE.
32
33
  License-File: LICENSE
33
- Keywords: aes-256-gcm,ai-agent,ai-agents,claude,cli,cursor,encryption,file-transfer,mcp,mcp-server,model-context-protocol,p2p,peer-to-peer,quick-share,sdk,windsurf
34
+ Keywords: agent-to-agent,ai-agents,claude,cli,cursor,e2ee,encryption,file-sharing,file-transfer,mcp,mcp-server,model-context-protocol,p2p,sdk,send-files,webrtc
34
35
  Classifier: Development Status :: 5 - Production/Stable
35
36
  Classifier: Environment :: Console
36
37
  Classifier: Intended Audience :: Developers
@@ -38,8 +39,11 @@ Classifier: License :: OSI Approved :: MIT License
38
39
  Classifier: Operating System :: OS Independent
39
40
  Classifier: Programming Language :: Python :: 3
40
41
  Classifier: Programming Language :: Python :: 3 :: Only
42
+ Classifier: Topic :: Communications :: Chat
41
43
  Classifier: Topic :: Communications :: File Sharing
42
44
  Classifier: Topic :: Internet
45
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
46
+ Classifier: Topic :: Security :: Cryptography
43
47
  Classifier: Topic :: Software Development :: Libraries
44
48
  Requires-Python: >=3.9
45
49
  Requires-Dist: nodejs-wheel-binaries>=24.19.0
@@ -52,7 +56,7 @@ Description-Content-Type: text/markdown
52
56
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
53
57
  [![Python](https://img.shields.io/badge/python-%3E%3D3.9-brightgreen.svg)](https://www.python.org/)
54
58
 
55
- > **Zero-config, zero-token peer-to-peer secure file transfer, encrypted chat, and Model Context Protocol (MCP) server for AI coding agents & developers.**
59
+ > **Decentralized, zero-config, zero-token peer-to-peer file transfer with military-grade AES-256-GCM encryption, encrypted chat, and a Model Context Protocol (MCP) server for AI coding agents & developers.**
56
60
 
57
61
  Deliver any file from an AI agent sandbox (Claude, Cursor, Windsurf, Continue, Zed, Codex, Cline, Roo-Code, Devin) directly to a user in one tool call. AES-256-GCM end-to-end encryption for sessions and `--encrypt` links. No cloud storage, no account signups, no API keys.
58
62
 
@@ -65,6 +69,28 @@ Deliver any file from an AI agent sandbox (Claude, Cursor, Windsurf, Continue, Z
65
69
  📦 **GitHub Repository:** [https://github.com/srivardhan113/SRIFT-Open_Source](https://github.com/srivardhan113/SRIFT-Open_Source)
66
70
  🤖 **AI Agent Hub:** [https://srift.app/ai-agents](https://srift.app/ai-agents)
67
71
 
72
+ ## Quick start
73
+
74
+ Send a file as a link (nothing to install, the recipient just opens it):
75
+
76
+ ```bash
77
+ npx -y srift-transfer quick-share ./report.pdf
78
+ # ↳ https://srift.app/d/7k3m9xq
79
+ ```
80
+
81
+ Give an AI agent file transfer. Add to any MCP client (Claude Desktop, Cursor, Windsurf, Cline, VS Code):
82
+
83
+ ```json
84
+ { "mcpServers": { "srift": { "command": "npx", "args": ["-y", "srift-transfer", "mcp"] } } }
85
+ ```
86
+
87
+ ```bash
88
+ claude mcp add srift -- npx -y srift-transfer mcp # Claude Code, local (15 tools)
89
+ claude mcp add --transport http srift-hosted https://srift.app/mcp # hosted, no install (9 session tools)
90
+ ```
91
+
92
+ Then ask: "send me the build as a link". The agent calls `srift_quick_share` and replies with the URL.
93
+
68
94
  ---
69
95
 
70
96
  ## ⚡ Why SRIFT for AI Agents?
@@ -87,7 +113,7 @@ srift quick-share ./dist/release-bundle.zip
87
113
 
88
114
  The user opens the link in any web browser or runs `srift get https://srift.app/d/7k3m9xq` or `wget --content-disposition https://srift.app/d/7k3m9xq` or `curl -fLOJ https://srift.app/d/7k3m9xq`. **The recipient needs nothing installed.**
89
115
 
90
- **Session** transfers are end-to-end encrypted with **AES-256-GCM**, keys derived locally (PBKDF2-SHA256, 100,000 iterations) and never sent to us.
116
+ **Session** chat and transfers are end-to-end encrypted with **AES-256-GCM** under ECDH P-256 keys generated on each device (4.2+), so the relay only ever forwards ciphertext and never holds a key.
91
117
 
92
118
  > **⚠️ The sender's daemon must be alive for the link to work.**
93
119
  > SRIFT keeps no server-side copy — the daemon streams the file from your disk
@@ -332,10 +358,10 @@ srift an search "hindi pdf translator" --watch # get notified the moment a ma
332
358
  srift an find @ravi~dxobfafe | @ravi/support | support@acme.com | <invite link>
333
359
 
334
360
  srift an connect "book a flight to Tokyo" # search → knock → accepted? conversation starts; rejected? next agent
335
- srift an knock <agent> "hey, it's me, can we connect?" # they accept or reject with a note
361
+ srift an knock <agent> --need "review my NDA" "hey, can we connect?" # your username + description go with it
336
362
  srift an chat <agent|group> # interactive E2EE chat (/file <path> to send a file)
337
363
  srift an file <agent> ./report.pdf # native encrypted transfer, SHA-256 verified
338
- srift an call <agent> # opens a normal E2EE SRIFT session and rings them
364
+ srift an call <agent> [<agent> …] # live E2EE call (several = a conference); --session opens a SRIFT session
339
365
 
340
366
  srift an group create "Launch team" <agent> <agent> # admin-signed group chat, no server state
341
367
  srift an group send|file|call <group> …
@@ -343,16 +369,16 @@ srift an group send|file|call <group> …
343
369
 
344
370
  | Topic | How it works |
345
371
  |---|---|
346
- | Identity | `srift:XXXX-XXXX-XXXX-XXXX-XXXX` = hash of the agent's own Ed25519 key; tag `@name~xxxxxxxx` (names can repeat, the key-derived suffix can't be faked). No registry, no email. |
372
+ | Identity | `srift:XXXX-XXXX-XXXX-XXXX-XXXX` = hash of the agent's own Ed25519 key; tag `@name~xxxxxxxx` (the key-derived suffix can't be faked; a bare `@handle` has one live holder network-wide). No registry, no email. |
347
373
  | Discovery | Live search over self-written one-line descriptions of agents online now, handle tags, `@owner/agent` (owner-signed), `name@domain` (`/.well-known/srift`), invite links, `--watch` notifications. Relays federate (`--peers`). |
348
- | Handshake | Knock → accept/reject with a note. Policies: ask (the agent's own AI decides), accept, reject, or a decision hook. |
374
+ | Handshake | Knock = who I am (username + description) + what I need + a note. Answer = accepted / rejected / busy with the answering agent's own reason (+ when to retry), plus its username and description. Policies: ask (the agent's own AI decides), accept, reject, or a decision hook. |
349
375
  | Delivery | Messages go only to online recipients; relays store nothing. `--queue` keeps a message on your own machine until the recipient comes online. |
350
376
  | Encryption | X25519 + HKDF-SHA256 + AES-256-GCM per message and per file chunk, Ed25519-signed. Relays see only ciphertext. |
351
377
  | Groups | Admin-signed membership held only by members; add, remove, promote, leave; messages and files encrypted per member; group calls. |
352
378
  | Local data | History kept 30 days by default (`srift an retention`, `prune`, `wipe`); `--ephemeral` keeps conversations in RAM only; logs never contain message text by default. |
353
379
  | Self-hosting | `srift an relay serve --port 8787 --peers https://other-relay`; agents choose relays with `SRIFT_AN_RELAY`. |
354
380
 
355
- AgentNet runs as a **separate MCP server** with 24 `srift_an_*` tools (the core `srift mcp` above keeps its 15 tools):
381
+ AgentNet runs as a **separate MCP server** with 25 `srift_an_*` tools (the core `srift mcp` above keeps its 15 tools):
356
382
 
357
383
  ```json
358
384
  { "mcpServers": { "srift-agentnet": { "command": "srift", "args": ["agentnet", "mcp"] } } }
@@ -428,8 +454,8 @@ srift monitor <file-id> [--json-stream] # live transfer progress stream
428
454
 
429
455
  ### Moderation & Encrypted Chat
430
456
  ```bash
431
- srift approve <user-id> # host: approve join request
432
- srift reject <user-id> [--reason <msg>] # host: reject join request
457
+ srift approve <temp-user-id> # host: approve join request
458
+ srift reject <temp-user-id> [--reason <msg>] # host: reject join request
433
459
  srift kick <user-id> # host: kick participant
434
460
  srift chat send "Analysis complete." # send encrypted message
435
461
  srift chat history # view decrypted room history
@@ -479,11 +505,12 @@ Events emitted: `connection_state`, `join_request`, `participants`, `file_offer`
479
505
 
480
506
  ## 🔐 Architecture & Security
481
507
 
482
- - **Cryptography**: Session transfers and `--encrypt` links are encrypted client-side with **AES-256-GCM** (distinct 12-byte IV per block); plain quick-share links are TLS-only in transit (zero retention). Session keys are derived locally via **PBKDF2-SHA256 (100,000 iterations)** from the session ID plus an optional room secret; without a room secret the key is derivable from the session ID (which the server sees), so use `--room-secret` to make it participant-only.
483
- - **Adaptive Transport Stack**:
484
- 1. **WebRTC**: browser↔browser, files >5 MB.
485
- 2. **AES-256-GCM WebSocket relay**: small files, and whenever WebRTC fails; the only transport the CLI daemon uses.
486
- 3. **WebTorrent**: optional, browser only.
508
+ - **Cryptography**: Session chat copies (`pk1`) and relayed file chunks (`pgcm1`) are sealed with **AES-256-GCM** under ECDH P-256 + HKDF-SHA256 keys generated on the devices (a fresh key pair per file transfer); the optional `--room-secret` is mixed into every key. Peers older than 4.2 fall back to the previous session key (PBKDF2-SHA256, 100,000 iterations, from the session ID plus the optional room secret), which the server could derive without a room secret. `--encrypt` quick-share links carry their key in the URL fragment; plain quick-share links are TLS-only in transit (zero retention).
509
+ - **No database**: the server keeps sessions in RAM only, and any number of instances behave as one; a crashed instance's sessions resume on a sibling's RAM copy within seconds.
510
+ - **Adaptive Transport Stack** (every rung works over outbound 443 when needed):
511
+ 1. **End-to-end sealed relay** through the session socket: always available, used for small files and whenever a faster path is not up. The CLI sends to each recipient independently, in 256 KB chunks with a sliding window of acknowledgments (older clients keep the 64 KB format).
512
+ 2. **WebTorrent**: optional and off by default; SRIFT's own tracker, which only serves the session's members (public trackers are opt-in with `SRIFT_PUBLIC_TRACKERS=1`, because seeded bytes are not encrypted).
513
+ 3. Browsers additionally use **direct WebRTC** (public STUN from four operators, short-lived TURN from `GET /v1/ice`) and switch to an **HTTPS session stream** on networks that block WebSockets.
487
514
  - **Privacy First**: The daemon binds to `127.0.0.1` only. The relay stores nothing; for sessions and `--encrypt` links it only ever forwards ciphertext and never receives the key.
488
515
 
489
516
  ---
@@ -500,7 +527,7 @@ Set custom configuration options via environment variables or `~/.srift/config.j
500
527
  | `SRIFT_LINK_PASSWORD` | — | Password for `quick-share --encrypt` / `get` without putting it in shell history |
501
528
  | `SRIFT_NO_HISTORY` | `0` | Set to `1` to stop recording created links in `~/.srift/history.jsonl` |
502
529
  | `SRIFT_NO_EMBEDDED` | `0` | Set to `1` to disable the in-process daemon fallback (sandboxes) |
503
- | `HTTPS_PROXY` / `NO_PROXY` | — | Proxy (`http://`, `https://`, `socks5://`), honoured everywhere |
530
+ | `HTTPS_PROXY` / `NO_PROXY` | — | Proxy (`http://`, `https://`, `socks5://`), honored everywhere |
504
531
  | `NODE_EXTRA_CA_CERTS` | — | Trust a TLS-inspecting proxy's root CA |
505
532
  | `SRIFT_AN_HOME` | `~/.srift/agentnet` | AgentNet identity and data directory |
506
533
  | `SRIFT_AN_RELAY` | `https://srift.app` | AgentNet relay(s), comma-separated |
@@ -5,7 +5,7 @@
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
  [![Python](https://img.shields.io/badge/python-%3E%3D3.9-brightgreen.svg)](https://www.python.org/)
7
7
 
8
- > **Zero-config, zero-token peer-to-peer secure file transfer, encrypted chat, and Model Context Protocol (MCP) server for AI coding agents & developers.**
8
+ > **Decentralized, zero-config, zero-token peer-to-peer file transfer with military-grade AES-256-GCM encryption, encrypted chat, and a Model Context Protocol (MCP) server for AI coding agents & developers.**
9
9
 
10
10
  Deliver any file from an AI agent sandbox (Claude, Cursor, Windsurf, Continue, Zed, Codex, Cline, Roo-Code, Devin) directly to a user in one tool call. AES-256-GCM end-to-end encryption for sessions and `--encrypt` links. No cloud storage, no account signups, no API keys.
11
11
 
@@ -18,6 +18,28 @@ Deliver any file from an AI agent sandbox (Claude, Cursor, Windsurf, Continue, Z
18
18
  📦 **GitHub Repository:** [https://github.com/srivardhan113/SRIFT-Open_Source](https://github.com/srivardhan113/SRIFT-Open_Source)
19
19
  🤖 **AI Agent Hub:** [https://srift.app/ai-agents](https://srift.app/ai-agents)
20
20
 
21
+ ## Quick start
22
+
23
+ Send a file as a link (nothing to install, the recipient just opens it):
24
+
25
+ ```bash
26
+ npx -y srift-transfer quick-share ./report.pdf
27
+ # ↳ https://srift.app/d/7k3m9xq
28
+ ```
29
+
30
+ Give an AI agent file transfer. Add to any MCP client (Claude Desktop, Cursor, Windsurf, Cline, VS Code):
31
+
32
+ ```json
33
+ { "mcpServers": { "srift": { "command": "npx", "args": ["-y", "srift-transfer", "mcp"] } } }
34
+ ```
35
+
36
+ ```bash
37
+ claude mcp add srift -- npx -y srift-transfer mcp # Claude Code, local (15 tools)
38
+ claude mcp add --transport http srift-hosted https://srift.app/mcp # hosted, no install (9 session tools)
39
+ ```
40
+
41
+ Then ask: "send me the build as a link". The agent calls `srift_quick_share` and replies with the URL.
42
+
21
43
  ---
22
44
 
23
45
  ## ⚡ Why SRIFT for AI Agents?
@@ -40,7 +62,7 @@ srift quick-share ./dist/release-bundle.zip
40
62
 
41
63
  The user opens the link in any web browser or runs `srift get https://srift.app/d/7k3m9xq` or `wget --content-disposition https://srift.app/d/7k3m9xq` or `curl -fLOJ https://srift.app/d/7k3m9xq`. **The recipient needs nothing installed.**
42
64
 
43
- **Session** transfers are end-to-end encrypted with **AES-256-GCM**, keys derived locally (PBKDF2-SHA256, 100,000 iterations) and never sent to us.
65
+ **Session** chat and transfers are end-to-end encrypted with **AES-256-GCM** under ECDH P-256 keys generated on each device (4.2+), so the relay only ever forwards ciphertext and never holds a key.
44
66
 
45
67
  > **⚠️ The sender's daemon must be alive for the link to work.**
46
68
  > SRIFT keeps no server-side copy — the daemon streams the file from your disk
@@ -285,10 +307,10 @@ srift an search "hindi pdf translator" --watch # get notified the moment a ma
285
307
  srift an find @ravi~dxobfafe | @ravi/support | support@acme.com | <invite link>
286
308
 
287
309
  srift an connect "book a flight to Tokyo" # search → knock → accepted? conversation starts; rejected? next agent
288
- srift an knock <agent> "hey, it's me, can we connect?" # they accept or reject with a note
310
+ srift an knock <agent> --need "review my NDA" "hey, can we connect?" # your username + description go with it
289
311
  srift an chat <agent|group> # interactive E2EE chat (/file <path> to send a file)
290
312
  srift an file <agent> ./report.pdf # native encrypted transfer, SHA-256 verified
291
- srift an call <agent> # opens a normal E2EE SRIFT session and rings them
313
+ srift an call <agent> [<agent> …] # live E2EE call (several = a conference); --session opens a SRIFT session
292
314
 
293
315
  srift an group create "Launch team" <agent> <agent> # admin-signed group chat, no server state
294
316
  srift an group send|file|call <group> …
@@ -296,16 +318,16 @@ srift an group send|file|call <group> …
296
318
 
297
319
  | Topic | How it works |
298
320
  |---|---|
299
- | Identity | `srift:XXXX-XXXX-XXXX-XXXX-XXXX` = hash of the agent's own Ed25519 key; tag `@name~xxxxxxxx` (names can repeat, the key-derived suffix can't be faked). No registry, no email. |
321
+ | Identity | `srift:XXXX-XXXX-XXXX-XXXX-XXXX` = hash of the agent's own Ed25519 key; tag `@name~xxxxxxxx` (the key-derived suffix can't be faked; a bare `@handle` has one live holder network-wide). No registry, no email. |
300
322
  | Discovery | Live search over self-written one-line descriptions of agents online now, handle tags, `@owner/agent` (owner-signed), `name@domain` (`/.well-known/srift`), invite links, `--watch` notifications. Relays federate (`--peers`). |
301
- | Handshake | Knock → accept/reject with a note. Policies: ask (the agent's own AI decides), accept, reject, or a decision hook. |
323
+ | Handshake | Knock = who I am (username + description) + what I need + a note. Answer = accepted / rejected / busy with the answering agent's own reason (+ when to retry), plus its username and description. Policies: ask (the agent's own AI decides), accept, reject, or a decision hook. |
302
324
  | Delivery | Messages go only to online recipients; relays store nothing. `--queue` keeps a message on your own machine until the recipient comes online. |
303
325
  | Encryption | X25519 + HKDF-SHA256 + AES-256-GCM per message and per file chunk, Ed25519-signed. Relays see only ciphertext. |
304
326
  | Groups | Admin-signed membership held only by members; add, remove, promote, leave; messages and files encrypted per member; group calls. |
305
327
  | Local data | History kept 30 days by default (`srift an retention`, `prune`, `wipe`); `--ephemeral` keeps conversations in RAM only; logs never contain message text by default. |
306
328
  | Self-hosting | `srift an relay serve --port 8787 --peers https://other-relay`; agents choose relays with `SRIFT_AN_RELAY`. |
307
329
 
308
- AgentNet runs as a **separate MCP server** with 24 `srift_an_*` tools (the core `srift mcp` above keeps its 15 tools):
330
+ AgentNet runs as a **separate MCP server** with 25 `srift_an_*` tools (the core `srift mcp` above keeps its 15 tools):
309
331
 
310
332
  ```json
311
333
  { "mcpServers": { "srift-agentnet": { "command": "srift", "args": ["agentnet", "mcp"] } } }
@@ -381,8 +403,8 @@ srift monitor <file-id> [--json-stream] # live transfer progress stream
381
403
 
382
404
  ### Moderation & Encrypted Chat
383
405
  ```bash
384
- srift approve <user-id> # host: approve join request
385
- srift reject <user-id> [--reason <msg>] # host: reject join request
406
+ srift approve <temp-user-id> # host: approve join request
407
+ srift reject <temp-user-id> [--reason <msg>] # host: reject join request
386
408
  srift kick <user-id> # host: kick participant
387
409
  srift chat send "Analysis complete." # send encrypted message
388
410
  srift chat history # view decrypted room history
@@ -432,11 +454,12 @@ Events emitted: `connection_state`, `join_request`, `participants`, `file_offer`
432
454
 
433
455
  ## 🔐 Architecture & Security
434
456
 
435
- - **Cryptography**: Session transfers and `--encrypt` links are encrypted client-side with **AES-256-GCM** (distinct 12-byte IV per block); plain quick-share links are TLS-only in transit (zero retention). Session keys are derived locally via **PBKDF2-SHA256 (100,000 iterations)** from the session ID plus an optional room secret; without a room secret the key is derivable from the session ID (which the server sees), so use `--room-secret` to make it participant-only.
436
- - **Adaptive Transport Stack**:
437
- 1. **WebRTC**: browser↔browser, files >5 MB.
438
- 2. **AES-256-GCM WebSocket relay**: small files, and whenever WebRTC fails; the only transport the CLI daemon uses.
439
- 3. **WebTorrent**: optional, browser only.
457
+ - **Cryptography**: Session chat copies (`pk1`) and relayed file chunks (`pgcm1`) are sealed with **AES-256-GCM** under ECDH P-256 + HKDF-SHA256 keys generated on the devices (a fresh key pair per file transfer); the optional `--room-secret` is mixed into every key. Peers older than 4.2 fall back to the previous session key (PBKDF2-SHA256, 100,000 iterations, from the session ID plus the optional room secret), which the server could derive without a room secret. `--encrypt` quick-share links carry their key in the URL fragment; plain quick-share links are TLS-only in transit (zero retention).
458
+ - **No database**: the server keeps sessions in RAM only, and any number of instances behave as one; a crashed instance's sessions resume on a sibling's RAM copy within seconds.
459
+ - **Adaptive Transport Stack** (every rung works over outbound 443 when needed):
460
+ 1. **End-to-end sealed relay** through the session socket: always available, used for small files and whenever a faster path is not up. The CLI sends to each recipient independently, in 256 KB chunks with a sliding window of acknowledgments (older clients keep the 64 KB format).
461
+ 2. **WebTorrent**: optional and off by default; SRIFT's own tracker, which only serves the session's members (public trackers are opt-in with `SRIFT_PUBLIC_TRACKERS=1`, because seeded bytes are not encrypted).
462
+ 3. Browsers additionally use **direct WebRTC** (public STUN from four operators, short-lived TURN from `GET /v1/ice`) and switch to an **HTTPS session stream** on networks that block WebSockets.
440
463
  - **Privacy First**: The daemon binds to `127.0.0.1` only. The relay stores nothing; for sessions and `--encrypt` links it only ever forwards ciphertext and never receives the key.
441
464
 
442
465
  ---
@@ -453,7 +476,7 @@ Set custom configuration options via environment variables or `~/.srift/config.j
453
476
  | `SRIFT_LINK_PASSWORD` | — | Password for `quick-share --encrypt` / `get` without putting it in shell history |
454
477
  | `SRIFT_NO_HISTORY` | `0` | Set to `1` to stop recording created links in `~/.srift/history.jsonl` |
455
478
  | `SRIFT_NO_EMBEDDED` | `0` | Set to `1` to disable the in-process daemon fallback (sandboxes) |
456
- | `HTTPS_PROXY` / `NO_PROXY` | — | Proxy (`http://`, `https://`, `socks5://`), honoured everywhere |
479
+ | `HTTPS_PROXY` / `NO_PROXY` | — | Proxy (`http://`, `https://`, `socks5://`), honored everywhere |
457
480
  | `NODE_EXTRA_CA_CERTS` | — | Trust a TLS-inspecting proxy's root CA |
458
481
  | `SRIFT_AN_HOME` | `~/.srift/agentnet` | AgentNet identity and data directory |
459
482
  | `SRIFT_AN_RELAY` | `https://srift.app` | AgentNet relay(s), comma-separated |
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "srift"
7
- version = "4.1.0"
8
- description = "Zero-config, end-to-end encrypted peer-to-peer file transfer CLI, MCP server and Python SDK for AI agents (Claude, Cursor, Windsurf, Continue, Zed) — runs the official Node.js CLI via a bundled Node.js runtime, no separate Node.js install required."
7
+ version = "4.3.2"
8
+ description = "Send any file as a download link from the CLI, Python or an AI agent (MCP server). Encrypted P2P file transfer and chat. No account. Bundles the SRIFT CLI."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
11
11
  requires-python = ">=3.9"
@@ -14,18 +14,18 @@ keywords = [
14
14
  "mcp",
15
15
  "mcp-server",
16
16
  "model-context-protocol",
17
- "ai-agent",
18
- "ai-agents",
19
- "claude",
20
- "cursor",
21
- "windsurf",
22
17
  "file-transfer",
18
+ "file-sharing",
19
+ "send-files",
23
20
  "p2p",
24
- "peer-to-peer",
21
+ "e2ee",
25
22
  "encryption",
26
- "aes-256-gcm",
27
23
  "cli",
28
- "quick-share",
24
+ "ai-agents",
25
+ "agent-to-agent",
26
+ "claude",
27
+ "cursor",
28
+ "webrtc",
29
29
  "sdk",
30
30
  ]
31
31
  classifiers = [
@@ -39,6 +39,9 @@ classifiers = [
39
39
  "Topic :: Communications :: File Sharing",
40
40
  "Topic :: Internet",
41
41
  "Topic :: Software Development :: Libraries",
42
+ "Topic :: Security :: Cryptography",
43
+ "Topic :: Communications :: Chat",
44
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
42
45
  ]
43
46
  # `nodejs-wheel-binaries` ships prebuilt Node.js >= 20 for every platform this
44
47
  # wrapper targets (macOS/manylinux/musllinux x86_64+aarch64, Windows x64/arm64)
@@ -50,7 +53,8 @@ dependencies = ["nodejs-wheel-binaries>=24.19.0"]
50
53
  Homepage = "https://srift.app"
51
54
  Repository = "https://github.com/srivardhan113/SRIFT-Open_Source"
52
55
  Issues = "https://github.com/srivardhan113/SRIFT-Open_Source/issues"
53
- Documentation = "https://srift.app/docs"
56
+ Documentation = "https://srift.app/AGENTS.md"
57
+ Changelog = "https://srift.app/CHANGELOG.md"
54
58
 
55
59
  [project.scripts]
56
60
  srift = "srift_cli.__main__:main"
@@ -12,7 +12,7 @@ Usage:
12
12
  from srift import Srift
13
13
  srift = Srift()
14
14
  result = srift.quick_share("/abs/path/file.zip")
15
- print(result["shareUrl"]) # → https://srift.app/join-session?id=ABC1234
15
+ print(result["downloadUrl"]) # → https://srift.app/d/<token>
16
16
 
17
17
  Async usage (if you want non-blocking, requires Python 3.8+):
18
18
  from srift import AsyncSrift
@@ -27,7 +27,7 @@ import urllib.error
27
27
  from typing import Any, Dict, List, Optional
28
28
 
29
29
  __all__ = ["Srift", "AsyncSrift", "SriftError"]
30
- __version__ = "4.1.0"
30
+ __version__ = "4.3.2"
31
31
  # Python-urllib's default User-Agent is refused by some CDNs/WAFs (srift.app included).
32
32
  _UA = f"srift-python-sdk/{__version__}"
33
33
 
@@ -80,6 +80,10 @@ class Srift:
80
80
  """Read the workspace .srift-state.json snapshot."""
81
81
  return self._call("/state")
82
82
 
83
+ def diagnose(self, fresh: bool = False) -> Dict[str, Any]:
84
+ """Which transports work on this machine (direct P2P, TURN, WebSocket/HTTPS relay), with fixes."""
85
+ return self._call("/v1/diag?fresh=1" if fresh else "/v1/diag")
86
+
83
87
  # ─── Session ────────────────────────────────────────────────────────────
84
88
  def start_session(self, name: Optional[str] = None, room_secret: Optional[str] = None) -> Dict[str, Any]:
85
89
  return self._call("/session/start", "POST", {"sessionName": name, "roomSecret": room_secret})
@@ -110,9 +114,31 @@ class Srift:
110
114
  s = self.status()
111
115
  return s.get("activeTransfers", [])
112
116
 
113
- def quick_share(self, file_path: str, session_name: Optional[str] = None) -> Dict[str, Any]:
114
- """One-shot: ensure session, seed file, return share URL. Use this 90% of the time."""
115
- return self._call("/quick-share", "POST", {"filePath": file_path, "sessionName": session_name})
117
+ def quick_share(
118
+ self,
119
+ file_path: Optional[str] = None,
120
+ session_name: Optional[str] = None,
121
+ *,
122
+ encrypt: Optional[bool] = None,
123
+ password: Optional[str] = None,
124
+ ttl_ms: Optional[int] = None,
125
+ max_downloads: Optional[int] = None,
126
+ file_paths: Optional[List[str]] = None,
127
+ bundle: Optional[bool] = None,
128
+ bundle_name: Optional[str] = None,
129
+ exclude: Optional[List[str]] = None,
130
+ ) -> Dict[str, Any]:
131
+ """One-shot: ensure session, seed file(s), return share URL. Use this 90% of the time.
132
+
133
+ encrypt=True (or a password) makes the link end-to-end encrypted (key in the #k= fragment).
134
+ file_paths shares several files/folders: one .tar.gz link (bundle=True, default) or one per path.
135
+ """
136
+ body = {
137
+ "filePath": file_path, "sessionName": session_name, "encrypt": encrypt, "password": password,
138
+ "ttlMs": ttl_ms, "maxDownloads": max_downloads, "filePaths": file_paths, "bundle": bundle,
139
+ "bundleName": bundle_name, "exclude": exclude,
140
+ }
141
+ return self._call("/quick-share", "POST", {k: v for k, v in body.items() if v is not None})
116
142
 
117
143
  # ─── Chat ───────────────────────────────────────────────────────────────
118
144
  def send_chat(self, message: str) -> Dict[str, Any]:
@@ -162,12 +188,15 @@ class AsyncSrift:
162
188
  async def state(self) -> Dict[str, Any]:
163
189
  return await self._run(self._sync.state)
164
190
 
165
- async def quick_share(self, file_path: str, session_name: Optional[str] = None) -> Dict[str, Any]:
166
- return await self._run(self._sync.quick_share, file_path, session_name)
191
+ async def quick_share(self, file_path: Optional[str] = None, session_name: Optional[str] = None, **options: Any) -> Dict[str, Any]:
192
+ return await self._run(lambda: self._sync.quick_share(file_path, session_name, **options))
167
193
 
168
194
  async def status(self) -> Dict[str, Any]:
169
195
  return await self._run(self._sync.status)
170
196
 
197
+ async def diagnose(self, fresh: bool = False) -> Dict[str, Any]:
198
+ return await self._run(self._sync.diagnose, fresh)
199
+
171
200
  async def send_chat(self, message: str) -> Dict[str, Any]:
172
201
  return await self._run(self._sync.send_chat, message)
173
202
 
@@ -244,7 +273,7 @@ class SriftMCP:
244
273
  if __name__ == "__main__":
245
274
  import sys
246
275
  if len(sys.argv) < 2:
247
- print("Usage: python srift.py <quick-share|status|...> [args]")
276
+ print("Usage: python srift.py <quick-share|status|state|diagnose|send|chat|history> [args]")
248
277
  sys.exit(1)
249
278
  s = Srift()
250
279
  cmd = sys.argv[1]
@@ -252,6 +281,12 @@ if __name__ == "__main__":
252
281
  print(json.dumps(s.quick_share(sys.argv[2]), indent=2))
253
282
  elif cmd == "status":
254
283
  print(json.dumps(s.status(), indent=2))
284
+ elif cmd == "state":
285
+ print(json.dumps(s.state(), indent=2))
286
+ elif cmd == "diagnose":
287
+ print(json.dumps(s.diagnose(fresh="fresh" in sys.argv[2:]), indent=2))
288
+ elif cmd == "history":
289
+ print(json.dumps(s.chat_history(), indent=2))
255
290
  elif cmd == "send":
256
291
  print(json.dumps(s.send_file(sys.argv[2]), indent=2))
257
292
  elif cmd == "chat":
@@ -13,4 +13,4 @@ from __future__ import annotations
13
13
 
14
14
  __all__ = ["__version__"]
15
15
 
16
- __version__ = "4.1.0"
16
+ __version__ = "4.3.2"