srift 4.0.0__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.
- srift-4.0.0/.gitignore +13 -0
- srift-4.0.0/LICENSE +22 -0
- srift-4.0.0/PKG-INFO +177 -0
- srift-4.0.0/README.md +130 -0
- srift-4.0.0/build.py +89 -0
- srift-4.0.0/pyproject.toml +77 -0
- srift-4.0.0/scripts/bundle.mjs +86 -0
- srift-4.0.0/src/srift_cli/__init__.py +16 -0
- srift-4.0.0/src/srift_cli/__main__.py +111 -0
- srift-4.0.0/src/srift_cli/_vendor/daemon.js +33929 -0
- srift-4.0.0/src/srift_cli/_vendor/index.js +44113 -0
- srift-4.0.0/src/srift_cli/_vendor/package.json +3 -0
srift-4.0.0/.gitignore
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Generated by build.py — bundled JS runtime, never hand-edited, must not be
|
|
2
|
+
# committed (it is regenerated from cli/index.ts + cli/daemon.ts on every
|
|
3
|
+
# build), but IS included inside the built wheel via [tool.hatch.build]
|
|
4
|
+
# artifacts in pyproject.toml.
|
|
5
|
+
src/srift_cli/_vendor/
|
|
6
|
+
|
|
7
|
+
# Standard Python build/packaging output.
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
__pycache__/
|
|
12
|
+
*.pyc
|
|
13
|
+
.venv/
|
srift-4.0.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 SRIFT (Sripto Corporation Private Limited)
|
|
4
|
+
https://srift.app
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
srift-4.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: srift
|
|
3
|
+
Version: 4.0.0
|
|
4
|
+
Summary: Zero-config, end-to-end encrypted peer-to-peer file transfer CLI and MCP server 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.
|
|
5
|
+
Project-URL: Homepage, https://srift.app
|
|
6
|
+
Project-URL: Repository, https://github.com/srivardhan113/SRIFT-Open_Source
|
|
7
|
+
Project-URL: Issues, https://github.com/srivardhan113/SRIFT-Open_Source/issues
|
|
8
|
+
Project-URL: Documentation, https://srift.app/docs
|
|
9
|
+
Author: SRIFT
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2024-2026 SRIFT (Sripto Corporation Private Limited)
|
|
13
|
+
https://srift.app
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
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,windsurf
|
|
34
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
35
|
+
Classifier: Environment :: Console
|
|
36
|
+
Classifier: Intended Audience :: Developers
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Operating System :: OS Independent
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
41
|
+
Classifier: Topic :: Communications :: File Sharing
|
|
42
|
+
Classifier: Topic :: Internet
|
|
43
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
44
|
+
Requires-Python: >=3.9
|
|
45
|
+
Requires-Dist: nodejs-wheel-binaries>=24.19.0
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
48
|
+
# srift (Python)
|
|
49
|
+
|
|
50
|
+
[](https://pypi.org/project/srift/)
|
|
51
|
+
[](https://opensource.org/licenses/MIT)
|
|
52
|
+
[](https://modelcontextprotocol.io)
|
|
53
|
+
|
|
54
|
+
A **thin wrapper** that runs the official [SRIFT](https://srift.app) Node.js CLI
|
|
55
|
+
(npm: [`srift-transfer`](https://www.npmjs.com/package/srift-transfer)) via a
|
|
56
|
+
bundled Node.js runtime, so `uvx srift` / `pipx install srift` / `pip install
|
|
57
|
+
srift` work in Python-only environments — **no separate Node.js install
|
|
58
|
+
required**.
|
|
59
|
+
|
|
60
|
+
This package does not reimplement SRIFT in Python. It vendors the same
|
|
61
|
+
JavaScript bundle published to npm and executes it with either:
|
|
62
|
+
|
|
63
|
+
1. your system `node`, if a `node` >= 20 is already on `PATH`, or
|
|
64
|
+
2. the prebuilt Node.js runtime pulled in transitively via the
|
|
65
|
+
[`nodejs-wheel-binaries`](https://pypi.org/project/nodejs-wheel-binaries/)
|
|
66
|
+
dependency, as a zero-install fallback.
|
|
67
|
+
|
|
68
|
+
Your process's argv, stdin, stdout, stderr, and exit code are all forwarded
|
|
69
|
+
straight through — including for `srift mcp`'s JSON-RPC-over-stdio transport,
|
|
70
|
+
which requires byte-exact, unbuffered passthrough.
|
|
71
|
+
|
|
72
|
+
Looking for the Python **SDK** (a zero-dependency client for the local SRIFT
|
|
73
|
+
daemon's HTTP API, for scripting file transfers from Python) instead of the
|
|
74
|
+
CLI? See [`srift-sdk`](https://pypi.org/project/srift-sdk/) /
|
|
75
|
+
[`sdk/python/`](https://github.com/srivardhan113/SRIFT-Open_Source/tree/main/sdk/python)
|
|
76
|
+
in the same repo.
|
|
77
|
+
|
|
78
|
+
## Install
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Run it once, with no persistent install (recommended for MCP hosts):
|
|
82
|
+
uvx srift mcp
|
|
83
|
+
|
|
84
|
+
# Or install a persistent CLI:
|
|
85
|
+
pipx install srift
|
|
86
|
+
pip install srift
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## AgentNet: agent-to-agent messaging
|
|
90
|
+
|
|
91
|
+
The same `srift` command includes AgentNet: permanent agent addresses, live search of online agents, knocks (accept/reject with a note), end-to-end encrypted chat, file transfer, calls and group chats, with no central database.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
srift an id --name "My Agent" --skills "pdf,summaries"
|
|
95
|
+
srift an host "I summarise PDFs" # go online and discoverable
|
|
96
|
+
srift an search "summarise a pdf" # find agents online right now
|
|
97
|
+
srift an connect "summarise a pdf" # knock the best match; the conversation starts on accept
|
|
98
|
+
srift an file <agent> report.pdf # encrypted, SHA-256 verified
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
MCP (24 tools): {"command": "srift", "args": ["agentnet", "mcp"]}. Run `srift an help` for everything.
|
|
102
|
+
|
|
103
|
+
## Usage
|
|
104
|
+
|
|
105
|
+
Once installed, `srift` behaves exactly like the npm CLI — see
|
|
106
|
+
[`srift-transfer` on npm](https://www.npmjs.com/package/srift-transfer) or
|
|
107
|
+
`srift help` for the full command reference:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
srift --version
|
|
111
|
+
srift quick-share ./report.pdf
|
|
112
|
+
srift quick-share ./report.pdf --wait # CI / sandboxes: block until downloaded
|
|
113
|
+
srift session start
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## MCP (Model Context Protocol)
|
|
117
|
+
|
|
118
|
+
Add to your MCP host config (Claude Desktop, Cursor, Windsurf, etc.):
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"mcpServers": {
|
|
123
|
+
"srift": {
|
|
124
|
+
"command": "uvx",
|
|
125
|
+
"args": ["srift", "mcp"]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
No `uv`? Use `pipx run` instead:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"mcpServers": {
|
|
136
|
+
"srift": {
|
|
137
|
+
"command": "pipx",
|
|
138
|
+
"args": ["run", "srift", "mcp"]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## How it works / what it is not
|
|
145
|
+
|
|
146
|
+
- It is **not** a Python reimplementation of SRIFT's client or its
|
|
147
|
+
AES-256-GCM + PBKDF2-SHA256 encryption — that logic lives entirely in the
|
|
148
|
+
vendored Node.js bundle, identical to what npm ships.
|
|
149
|
+
- The vendored bundle is built from the same `cli/index.ts` + `cli/daemon.ts`
|
|
150
|
+
sources as the npm package, via `esbuild` (see `build.py` /
|
|
151
|
+
`scripts/bundle.mjs` in this directory), with its runtime dependencies
|
|
152
|
+
(`express`, `cors`, `ws`, `dotenv`, `uuid`) inlined so no `node_modules`
|
|
153
|
+
directory ships in the wheel.
|
|
154
|
+
- `webtorrent` (SRIFT's optional large-file transfer accelerator) is not
|
|
155
|
+
bundled — it pulls in native addons that don't cross-compile portably.
|
|
156
|
+
SRIFT already treats it as optional and falls back to WebSocket-chunked
|
|
157
|
+
transfer when it's unavailable, so this package's behavior is unaffected
|
|
158
|
+
beyond that fallback.
|
|
159
|
+
- The background transfer daemon started by `srift` binds only to
|
|
160
|
+
`127.0.0.1` and is unauthenticated-by-design (localhost-only) — identical
|
|
161
|
+
to the npm CLI's behavior.
|
|
162
|
+
|
|
163
|
+
## Publishing (maintainers)
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
python packages/pypi/build.py # bundle + build sdist/wheel into dist/
|
|
167
|
+
python -m twine upload packages/pypi/dist/*
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
or configure [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
|
|
171
|
+
for this project so CI can publish without a long-lived API token.
|
|
172
|
+
|
|
173
|
+
## Links
|
|
174
|
+
|
|
175
|
+
- Homepage: <https://srift.app>
|
|
176
|
+
- Source: <https://github.com/srivardhan113/SRIFT-Open_Source>
|
|
177
|
+
- Issues: <https://github.com/srivardhan113/SRIFT-Open_Source/issues>
|
srift-4.0.0/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# srift (Python)
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/srift/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://modelcontextprotocol.io)
|
|
6
|
+
|
|
7
|
+
A **thin wrapper** that runs the official [SRIFT](https://srift.app) Node.js CLI
|
|
8
|
+
(npm: [`srift-transfer`](https://www.npmjs.com/package/srift-transfer)) via a
|
|
9
|
+
bundled Node.js runtime, so `uvx srift` / `pipx install srift` / `pip install
|
|
10
|
+
srift` work in Python-only environments — **no separate Node.js install
|
|
11
|
+
required**.
|
|
12
|
+
|
|
13
|
+
This package does not reimplement SRIFT in Python. It vendors the same
|
|
14
|
+
JavaScript bundle published to npm and executes it with either:
|
|
15
|
+
|
|
16
|
+
1. your system `node`, if a `node` >= 20 is already on `PATH`, or
|
|
17
|
+
2. the prebuilt Node.js runtime pulled in transitively via the
|
|
18
|
+
[`nodejs-wheel-binaries`](https://pypi.org/project/nodejs-wheel-binaries/)
|
|
19
|
+
dependency, as a zero-install fallback.
|
|
20
|
+
|
|
21
|
+
Your process's argv, stdin, stdout, stderr, and exit code are all forwarded
|
|
22
|
+
straight through — including for `srift mcp`'s JSON-RPC-over-stdio transport,
|
|
23
|
+
which requires byte-exact, unbuffered passthrough.
|
|
24
|
+
|
|
25
|
+
Looking for the Python **SDK** (a zero-dependency client for the local SRIFT
|
|
26
|
+
daemon's HTTP API, for scripting file transfers from Python) instead of the
|
|
27
|
+
CLI? See [`srift-sdk`](https://pypi.org/project/srift-sdk/) /
|
|
28
|
+
[`sdk/python/`](https://github.com/srivardhan113/SRIFT-Open_Source/tree/main/sdk/python)
|
|
29
|
+
in the same repo.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Run it once, with no persistent install (recommended for MCP hosts):
|
|
35
|
+
uvx srift mcp
|
|
36
|
+
|
|
37
|
+
# Or install a persistent CLI:
|
|
38
|
+
pipx install srift
|
|
39
|
+
pip install srift
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## AgentNet: agent-to-agent messaging
|
|
43
|
+
|
|
44
|
+
The same `srift` command includes AgentNet: permanent agent addresses, live search of online agents, knocks (accept/reject with a note), end-to-end encrypted chat, file transfer, calls and group chats, with no central database.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
srift an id --name "My Agent" --skills "pdf,summaries"
|
|
48
|
+
srift an host "I summarise PDFs" # go online and discoverable
|
|
49
|
+
srift an search "summarise a pdf" # find agents online right now
|
|
50
|
+
srift an connect "summarise a pdf" # knock the best match; the conversation starts on accept
|
|
51
|
+
srift an file <agent> report.pdf # encrypted, SHA-256 verified
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
MCP (24 tools): {"command": "srift", "args": ["agentnet", "mcp"]}. Run `srift an help` for everything.
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
Once installed, `srift` behaves exactly like the npm CLI — see
|
|
59
|
+
[`srift-transfer` on npm](https://www.npmjs.com/package/srift-transfer) or
|
|
60
|
+
`srift help` for the full command reference:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
srift --version
|
|
64
|
+
srift quick-share ./report.pdf
|
|
65
|
+
srift quick-share ./report.pdf --wait # CI / sandboxes: block until downloaded
|
|
66
|
+
srift session start
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## MCP (Model Context Protocol)
|
|
70
|
+
|
|
71
|
+
Add to your MCP host config (Claude Desktop, Cursor, Windsurf, etc.):
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"srift": {
|
|
77
|
+
"command": "uvx",
|
|
78
|
+
"args": ["srift", "mcp"]
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
No `uv`? Use `pipx run` instead:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"srift": {
|
|
90
|
+
"command": "pipx",
|
|
91
|
+
"args": ["run", "srift", "mcp"]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## How it works / what it is not
|
|
98
|
+
|
|
99
|
+
- It is **not** a Python reimplementation of SRIFT's client or its
|
|
100
|
+
AES-256-GCM + PBKDF2-SHA256 encryption — that logic lives entirely in the
|
|
101
|
+
vendored Node.js bundle, identical to what npm ships.
|
|
102
|
+
- The vendored bundle is built from the same `cli/index.ts` + `cli/daemon.ts`
|
|
103
|
+
sources as the npm package, via `esbuild` (see `build.py` /
|
|
104
|
+
`scripts/bundle.mjs` in this directory), with its runtime dependencies
|
|
105
|
+
(`express`, `cors`, `ws`, `dotenv`, `uuid`) inlined so no `node_modules`
|
|
106
|
+
directory ships in the wheel.
|
|
107
|
+
- `webtorrent` (SRIFT's optional large-file transfer accelerator) is not
|
|
108
|
+
bundled — it pulls in native addons that don't cross-compile portably.
|
|
109
|
+
SRIFT already treats it as optional and falls back to WebSocket-chunked
|
|
110
|
+
transfer when it's unavailable, so this package's behavior is unaffected
|
|
111
|
+
beyond that fallback.
|
|
112
|
+
- The background transfer daemon started by `srift` binds only to
|
|
113
|
+
`127.0.0.1` and is unauthenticated-by-design (localhost-only) — identical
|
|
114
|
+
to the npm CLI's behavior.
|
|
115
|
+
|
|
116
|
+
## Publishing (maintainers)
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
python packages/pypi/build.py # bundle + build sdist/wheel into dist/
|
|
120
|
+
python -m twine upload packages/pypi/dist/*
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
or configure [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
|
|
124
|
+
for this project so CI can publish without a long-lived API token.
|
|
125
|
+
|
|
126
|
+
## Links
|
|
127
|
+
|
|
128
|
+
- Homepage: <https://srift.app>
|
|
129
|
+
- Source: <https://github.com/srivardhan113/SRIFT-Open_Source>
|
|
130
|
+
- Issues: <https://github.com/srivardhan113/SRIFT-Open_Source/issues>
|
srift-4.0.0/build.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Build the `srift` PyPI wheel + sdist.
|
|
3
|
+
|
|
4
|
+
Steps:
|
|
5
|
+
1. Bundle cli/{index,daemon}.ts (esbuild, deps inlined) into
|
|
6
|
+
src/srift_cli/_vendor/{index,daemon}.js — see scripts/bundle.mjs.
|
|
7
|
+
2. Assert this package's version matches packages/cli/package.json (the
|
|
8
|
+
source of truth for the CLI's version across every published surface).
|
|
9
|
+
3. Run `python -m build` to produce dist/*.whl and dist/*.tar.gz.
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
python packages/pypi/build.py [--skip-bundle] [--skip-build]
|
|
13
|
+
|
|
14
|
+
Requires: Node.js + this repo's node_modules (for step 1), and the `build`
|
|
15
|
+
package (`pip install build`) for step 3.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
import json
|
|
22
|
+
import re
|
|
23
|
+
import subprocess
|
|
24
|
+
import sys
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
PYPI_ROOT = Path(__file__).resolve().parent
|
|
28
|
+
REPO_ROOT = PYPI_ROOT.parent.parent
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def run(cmd: list[str], **kwargs) -> None:
|
|
32
|
+
print(f"[build.py] $ {' '.join(cmd)}")
|
|
33
|
+
subprocess.run(cmd, check=True, cwd=str(REPO_ROOT), **kwargs)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def bundle() -> None:
|
|
37
|
+
run(["node", str(PYPI_ROOT / "scripts" / "bundle.mjs")])
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def check_version_sync() -> str:
|
|
41
|
+
cli_pkg = json.loads((REPO_ROOT / "packages" / "cli" / "package.json").read_text("utf-8"))
|
|
42
|
+
cli_version = cli_pkg["version"]
|
|
43
|
+
|
|
44
|
+
pyproject_src = (PYPI_ROOT / "pyproject.toml").read_text("utf-8")
|
|
45
|
+
match = re.search(r'(?m)^version\s*=\s*"([^"]+)"', pyproject_src)
|
|
46
|
+
if not match:
|
|
47
|
+
print("[build.py] could not find version= in packages/pypi/pyproject.toml", file=sys.stderr)
|
|
48
|
+
raise SystemExit(1)
|
|
49
|
+
pypi_version = match.group(1)
|
|
50
|
+
|
|
51
|
+
if pypi_version != cli_version:
|
|
52
|
+
print(
|
|
53
|
+
f"[build.py] version drift: packages/pypi/pyproject.toml version="
|
|
54
|
+
f"'{pypi_version}' but packages/cli/package.json version='{cli_version}'. "
|
|
55
|
+
"Sync them before building/publishing.",
|
|
56
|
+
file=sys.stderr,
|
|
57
|
+
)
|
|
58
|
+
raise SystemExit(1)
|
|
59
|
+
|
|
60
|
+
return cli_version
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def build_dist() -> None:
|
|
64
|
+
run([sys.executable, "-m", "build", str(PYPI_ROOT)])
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def main() -> None:
|
|
68
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
69
|
+
parser.add_argument("--skip-bundle", action="store_true", help="reuse an existing _vendor/ bundle")
|
|
70
|
+
parser.add_argument("--skip-build", action="store_true", help="bundle + verify only, skip `python -m build`")
|
|
71
|
+
args = parser.parse_args()
|
|
72
|
+
|
|
73
|
+
version = check_version_sync()
|
|
74
|
+
print(f"[build.py] version {version} (matches packages/cli/package.json)")
|
|
75
|
+
|
|
76
|
+
if not args.skip_bundle:
|
|
77
|
+
bundle()
|
|
78
|
+
else:
|
|
79
|
+
print("[build.py] --skip-bundle: reusing existing src/srift_cli/_vendor/")
|
|
80
|
+
|
|
81
|
+
if not args.skip_build:
|
|
82
|
+
build_dist()
|
|
83
|
+
print(f"[build.py] done -> {PYPI_ROOT / 'dist'}")
|
|
84
|
+
else:
|
|
85
|
+
print("[build.py] --skip-build: skipped `python -m build`")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "srift"
|
|
7
|
+
version = "4.0.0"
|
|
8
|
+
description = "Zero-config, end-to-end encrypted peer-to-peer file transfer CLI and MCP server 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."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [{ name = "SRIFT" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"mcp",
|
|
15
|
+
"mcp-server",
|
|
16
|
+
"model-context-protocol",
|
|
17
|
+
"ai-agent",
|
|
18
|
+
"ai-agents",
|
|
19
|
+
"claude",
|
|
20
|
+
"cursor",
|
|
21
|
+
"windsurf",
|
|
22
|
+
"file-transfer",
|
|
23
|
+
"p2p",
|
|
24
|
+
"peer-to-peer",
|
|
25
|
+
"encryption",
|
|
26
|
+
"aes-256-gcm",
|
|
27
|
+
"cli",
|
|
28
|
+
"quick-share",
|
|
29
|
+
]
|
|
30
|
+
classifiers = [
|
|
31
|
+
"Development Status :: 5 - Production/Stable",
|
|
32
|
+
"Environment :: Console",
|
|
33
|
+
"Intended Audience :: Developers",
|
|
34
|
+
"License :: OSI Approved :: MIT License",
|
|
35
|
+
"Operating System :: OS Independent",
|
|
36
|
+
"Programming Language :: Python :: 3",
|
|
37
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
38
|
+
"Topic :: Communications :: File Sharing",
|
|
39
|
+
"Topic :: Internet",
|
|
40
|
+
"Topic :: Software Development :: Libraries",
|
|
41
|
+
]
|
|
42
|
+
# `nodejs-wheel-binaries` ships prebuilt Node.js >= 20 for every platform this
|
|
43
|
+
# wrapper targets (macOS/manylinux/musllinux x86_64+aarch64, Windows x64/arm64)
|
|
44
|
+
# and is only ever imported as a *fallback* when no system `node` >= 20 is on
|
|
45
|
+
# PATH — see src/srift_cli/__main__.py.
|
|
46
|
+
dependencies = ["nodejs-wheel-binaries>=24.19.0"]
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://srift.app"
|
|
50
|
+
Repository = "https://github.com/srivardhan113/SRIFT-Open_Source"
|
|
51
|
+
Issues = "https://github.com/srivardhan113/SRIFT-Open_Source/issues"
|
|
52
|
+
Documentation = "https://srift.app/docs"
|
|
53
|
+
|
|
54
|
+
[project.scripts]
|
|
55
|
+
srift = "srift_cli.__main__:main"
|
|
56
|
+
|
|
57
|
+
[tool.hatch.build]
|
|
58
|
+
# `_vendor/` is generated by build.py (esbuild bundle of cli/index.ts and
|
|
59
|
+
# cli/daemon.ts) and is .gitignore'd. Plain `include`/`packages` globs still
|
|
60
|
+
# respect VCS-ignore rules in hatchling — only `artifacts` bypasses them —
|
|
61
|
+
# so this must be `artifacts`, and it must apply to *both* build targets:
|
|
62
|
+
# `python -m build` builds the wheel FROM the sdist by default, so if the
|
|
63
|
+
# sdist target lacks this too, the wheel-from-sdist step silently ends up
|
|
64
|
+
# with no vendored JS at all.
|
|
65
|
+
artifacts = ["src/srift_cli/_vendor/**/*"]
|
|
66
|
+
|
|
67
|
+
[tool.hatch.build.targets.wheel]
|
|
68
|
+
packages = ["src/srift_cli"]
|
|
69
|
+
|
|
70
|
+
[tool.hatch.build.targets.sdist]
|
|
71
|
+
include = [
|
|
72
|
+
"src/srift_cli/**/*.py",
|
|
73
|
+
"scripts/**/*.mjs",
|
|
74
|
+
"build.py",
|
|
75
|
+
"README.md",
|
|
76
|
+
"LICENSE",
|
|
77
|
+
]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Bundle cli/{index,daemon}.ts into packages/pypi/src/srift_cli/_vendor/.
|
|
4
|
+
*
|
|
5
|
+
* Unlike packages/cli/build.mjs (which keeps express/cors/ws/dotenv/uuid
|
|
6
|
+
* external so npm resolves them from that package's own dependency list),
|
|
7
|
+
* this bundle inlines them: the PyPI wrapper ships no node_modules, so
|
|
8
|
+
* everything the CLI needs at runtime must be in the JS file itself.
|
|
9
|
+
*
|
|
10
|
+
* `webtorrent` stays external and absent — cli/daemon.ts already loads it
|
|
11
|
+
* via a lazy `await import('webtorrent')` wrapped in try/catch (see the
|
|
12
|
+
* "WebTorrent: lazy load" comment there) and degrades to WebSocket-chunked
|
|
13
|
+
* transfer if it's missing, which is exactly the case here.
|
|
14
|
+
*
|
|
15
|
+
* `bufferutil` / `utf-8-validate` are `ws`'s optional native-addon
|
|
16
|
+
* accelerators, also `require()`d from inside a try/catch in `ws/lib/*.js`.
|
|
17
|
+
* They're native binaries and can't be bundled into portable JS, so they
|
|
18
|
+
* too stay external+absent; `ws` falls back to its pure-JS mask/validate
|
|
19
|
+
* implementations.
|
|
20
|
+
*
|
|
21
|
+
* Format is ESM (cli/index.ts uses `import.meta.url` for __dirname, which
|
|
22
|
+
* only works natively in ESM output — CJS output silently empties it).
|
|
23
|
+
* Inlining express's dependency tree also inlines nested CJS modules (e.g.
|
|
24
|
+
* `debug`) that call plain `require('tty')` for Node builtins; in ESM
|
|
25
|
+
* output esbuild wraps those in a runtime `__require` shim that only
|
|
26
|
+
* delegates to a *real* `require` if one is in module scope — which plain
|
|
27
|
+
* ESM doesn't have — otherwise throwing `Dynamic require of "tty" is not
|
|
28
|
+
* supported`. The `banner` below shims a real `require` via
|
|
29
|
+
* `module.createRequire`, which is the standard esbuild workaround for
|
|
30
|
+
* exactly this combination (ESM output + bundled CJS deps needing Node
|
|
31
|
+
* builtins).
|
|
32
|
+
*/
|
|
33
|
+
import { build } from 'esbuild';
|
|
34
|
+
import { fileURLToPath } from 'node:url';
|
|
35
|
+
import path from 'node:path';
|
|
36
|
+
import fs from 'node:fs';
|
|
37
|
+
|
|
38
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
39
|
+
const pypiRoot = path.resolve(__dirname, '..');
|
|
40
|
+
const repoRoot = path.resolve(pypiRoot, '..', '..');
|
|
41
|
+
const outdir = path.join(pypiRoot, 'src', 'srift_cli', '_vendor');
|
|
42
|
+
|
|
43
|
+
const external = ['webtorrent', 'bufferutil', 'utf-8-validate'];
|
|
44
|
+
|
|
45
|
+
fs.rmSync(outdir, { recursive: true, force: true });
|
|
46
|
+
fs.mkdirSync(outdir, { recursive: true });
|
|
47
|
+
|
|
48
|
+
const entries = [
|
|
49
|
+
{ in: path.join(repoRoot, 'cli', 'index.ts'), out: 'index' },
|
|
50
|
+
{ in: path.join(repoRoot, 'cli', 'daemon.ts'), out: 'daemon' },
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
await build({
|
|
55
|
+
entryPoints: [entry.in],
|
|
56
|
+
outfile: path.join(outdir, `${entry.out}.js`),
|
|
57
|
+
bundle: true,
|
|
58
|
+
platform: 'node',
|
|
59
|
+
format: 'esm',
|
|
60
|
+
target: 'node20',
|
|
61
|
+
external,
|
|
62
|
+
logLevel: 'info',
|
|
63
|
+
banner: {
|
|
64
|
+
js:
|
|
65
|
+
"import { createRequire as __srift_createRequire } from 'node:module';\n" +
|
|
66
|
+
'const require = __srift_createRequire(import.meta.url);',
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Strip any shebang esbuild/source may have carried over — this bundle is
|
|
72
|
+
// never executed directly (Python always invokes `node <path>/index.js`),
|
|
73
|
+
// so a shebang is unnecessary and a stray duplicate would be invalid JS.
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const f = path.join(outdir, `${entry.out}.js`);
|
|
76
|
+
const src = fs.readFileSync(f, 'utf8');
|
|
77
|
+
fs.writeFileSync(f, src.replace(/^\s*#!.*\n/, ''));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Without a package.json declaring `"type": "module"`, Node has to sniff
|
|
81
|
+
// each file's syntax to realize it's ESM (since the extension is plain
|
|
82
|
+
// `.js`), which prints a MODULE_TYPELESS_PACKAGE_JSON warning to stderr and
|
|
83
|
+
// adds parse overhead on every invocation.
|
|
84
|
+
fs.writeFileSync(path.join(outdir, 'package.json'), JSON.stringify({ type: 'module' }, null, 2) + '\n');
|
|
85
|
+
|
|
86
|
+
console.log('[srift-pypi] bundle complete ->', outdir);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""srift — thin Python wrapper around the Node.js SRIFT CLI.
|
|
2
|
+
|
|
3
|
+
This package does not reimplement SRIFT in Python. It vendors the same
|
|
4
|
+
JavaScript bundle published to npm as `srift-transfer` (see
|
|
5
|
+
``packages/cli/`` in the SRIFT monorepo) and runs it under a Node.js
|
|
6
|
+
runtime — either the system `node` (if >= 20 is on PATH) or the
|
|
7
|
+
prebuilt runtime pulled in via the `nodejs-wheel-binaries` dependency.
|
|
8
|
+
|
|
9
|
+
See :mod:`srift_cli.__main__` for the entry point.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
__all__ = ["__version__"]
|
|
15
|
+
|
|
16
|
+
__version__ = "4.0.0"
|