leashbyte 0.1.1__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.
- leashbyte-0.1.1/.dockerignore +19 -0
- leashbyte-0.1.1/.env.example +46 -0
- leashbyte-0.1.1/.github/workflows/ci.yaml +110 -0
- leashbyte-0.1.1/.gitignore +46 -0
- leashbyte-0.1.1/CHANGELOG.md +32 -0
- leashbyte-0.1.1/CODE_OF_CONDUCT.md +132 -0
- leashbyte-0.1.1/CONTRIBUTING.md +42 -0
- leashbyte-0.1.1/Dockerfile +43 -0
- leashbyte-0.1.1/LICENSE +203 -0
- leashbyte-0.1.1/NOTICE +29 -0
- leashbyte-0.1.1/PKG-INFO +456 -0
- leashbyte-0.1.1/README.md +428 -0
- leashbyte-0.1.1/SECURITY.md +23 -0
- leashbyte-0.1.1/ci/compose-smoke.sh +87 -0
- leashbyte-0.1.1/ci/fill_fixture.py +49 -0
- leashbyte-0.1.1/ci/http_fixture.py +40 -0
- leashbyte-0.1.1/ci/mcp_roundtrip.py +38 -0
- leashbyte-0.1.1/compose.yaml +365 -0
- leashbyte-0.1.1/docs/DESIGN.md +336 -0
- leashbyte-0.1.1/docs/ROADMAP.md +34 -0
- leashbyte-0.1.1/docs/THIRD_PARTY.md +68 -0
- leashbyte-0.1.1/docs/python-licenses.json +327 -0
- leashbyte-0.1.1/examples/quickstart.py +50 -0
- leashbyte-0.1.1/openapi.json +2049 -0
- leashbyte-0.1.1/pyproject.toml +64 -0
- leashbyte-0.1.1/scripts/generate_openapi.py +12 -0
- leashbyte-0.1.1/scripts/python_licenses.py +146 -0
- leashbyte-0.1.1/sdk/python/LICENSE +203 -0
- leashbyte-0.1.1/sdk/python/NOTICE +6 -0
- leashbyte-0.1.1/sdk/python/README.md +35 -0
- leashbyte-0.1.1/sdk/python/pyproject.toml +26 -0
- leashbyte-0.1.1/sdk/python/src/leashbyte_sdk/__init__.py +54 -0
- leashbyte-0.1.1/sdk/python/src/leashbyte_sdk/_models.py +264 -0
- leashbyte-0.1.1/sdk/python/src/leashbyte_sdk/client.py +345 -0
- leashbyte-0.1.1/sdk/typescript/LICENSE +203 -0
- leashbyte-0.1.1/sdk/typescript/NOTICE +5 -0
- leashbyte-0.1.1/sdk/typescript/README.md +47 -0
- leashbyte-0.1.1/sdk/typescript/THIRD_PARTY_LICENSES.json +461 -0
- leashbyte-0.1.1/sdk/typescript/package-lock.json +1042 -0
- leashbyte-0.1.1/sdk/typescript/package.json +46 -0
- leashbyte-0.1.1/sdk/typescript/scripts/licenses.mjs +42 -0
- leashbyte-0.1.1/sdk/typescript/src/index.ts +321 -0
- leashbyte-0.1.1/sdk/typescript/src/schema.ts +1380 -0
- leashbyte-0.1.1/sdk/typescript/test/redaction.test.ts +76 -0
- leashbyte-0.1.1/sdk/typescript/tsconfig.json +18 -0
- leashbyte-0.1.1/site/README.md +21 -0
- leashbyte-0.1.1/site/index.html +18 -0
- leashbyte-0.1.1/site/package-lock.json +2574 -0
- leashbyte-0.1.1/site/package.json +24 -0
- leashbyte-0.1.1/site/public/favicon.svg +4 -0
- leashbyte-0.1.1/site/src/App.tsx +384 -0
- leashbyte-0.1.1/site/src/main.tsx +10 -0
- leashbyte-0.1.1/site/src/styles.css +1128 -0
- leashbyte-0.1.1/site/tsconfig.json +22 -0
- leashbyte-0.1.1/site/vite.config.ts +11 -0
- leashbyte-0.1.1/src/leashbyte/__init__.py +3 -0
- leashbyte-0.1.1/src/leashbyte/agent_worker.py +488 -0
- leashbyte-0.1.1/src/leashbyte/browser.py +627 -0
- leashbyte-0.1.1/src/leashbyte/browser_service.py +241 -0
- leashbyte-0.1.1/src/leashbyte/config.py +186 -0
- leashbyte-0.1.1/src/leashbyte/errors.py +11 -0
- leashbyte-0.1.1/src/leashbyte/fetch.py +333 -0
- leashbyte-0.1.1/src/leashbyte/internal.py +58 -0
- leashbyte-0.1.1/src/leashbyte/main.py +470 -0
- leashbyte-0.1.1/src/leashbyte/mcp/__init__.py +1 -0
- leashbyte-0.1.1/src/leashbyte/mcp/server.py +290 -0
- leashbyte-0.1.1/src/leashbyte/model_adapter.py +206 -0
- leashbyte-0.1.1/src/leashbyte/model_relay.py +84 -0
- leashbyte-0.1.1/src/leashbyte/models.py +142 -0
- leashbyte-0.1.1/src/leashbyte/proxy.py +179 -0
- leashbyte-0.1.1/src/leashbyte/run_models.py +164 -0
- leashbyte-0.1.1/src/leashbyte/run_store.py +493 -0
- leashbyte-0.1.1/src/leashbyte/run_viewer.py +42 -0
- leashbyte-0.1.1/src/leashbyte/search.py +103 -0
- leashbyte-0.1.1/src/leashbyte/url_guard.py +137 -0
- leashbyte-0.1.1/src/leashbyte/vault.py +210 -0
- leashbyte-0.1.1/src/leashbyte/vault_service.py +136 -0
- leashbyte-0.1.1/src/leashbyte/worker_service.py +19 -0
- leashbyte-0.1.1/tests/test_agent_security.py +343 -0
- leashbyte-0.1.1/tests/test_browser_security.py +480 -0
- leashbyte-0.1.1/tests/test_mcp_sdk_security.py +107 -0
- leashbyte-0.1.1/tests/test_security.py +280 -0
- leashbyte-0.1.1/uv.lock +1181 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.git
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
!.env.example
|
|
5
|
+
.venv
|
|
6
|
+
venv
|
|
7
|
+
__pycache__
|
|
8
|
+
*.pyc
|
|
9
|
+
.pytest_cache
|
|
10
|
+
.ruff_cache
|
|
11
|
+
.github
|
|
12
|
+
ci
|
|
13
|
+
scripts
|
|
14
|
+
tests
|
|
15
|
+
docs/*
|
|
16
|
+
!docs/python-licenses.json
|
|
17
|
+
!docs/THIRD_PARTY.md
|
|
18
|
+
sdk/typescript/node_modules
|
|
19
|
+
sdk/typescript/dist
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copy this file to .env and give each of the eight secrets below its own random value.
|
|
2
|
+
# openssl rand -hex 32 generates a suitable one.
|
|
3
|
+
LEASHBYTE_API_KEY=replace-with-a-random-api-key
|
|
4
|
+
LEASHBYTE_SEARXNG_SECRET_KEY=replace-with-a-different-random-secret
|
|
5
|
+
LEASHBYTE_SERVICE_KEY=replace-with-a-random-service-key
|
|
6
|
+
LEASHBYTE_VAULT_MANAGE_KEY=replace-with-a-random-vault-manage-key
|
|
7
|
+
LEASHBYTE_VAULT_RESOLVE_KEY=replace-with-a-random-vault-resolve-key
|
|
8
|
+
LEASHBYTE_CDP_KEY=replace-with-a-random-cdp-capability-key
|
|
9
|
+
LEASHBYTE_VAULT_MASTER_KEY=replace-with-a-random-vault-master-key
|
|
10
|
+
LEASHBYTE_POSTGRES_PASSWORD=replace-with-a-random-postgres-password
|
|
11
|
+
|
|
12
|
+
LEASHBYTE_BIND_ADDRESS=127.0.0.1
|
|
13
|
+
LEASHBYTE_PORT=8080
|
|
14
|
+
LEASHBYTE_MCP_BIND_ADDRESS=127.0.0.1
|
|
15
|
+
LEASHBYTE_MCP_PORT=8081
|
|
16
|
+
LEASHBYTE_SEARXNG_BASE_URL=http://searxng:8080
|
|
17
|
+
LEASHBYTE_BROWSER_POOL_BASE_URL=http://browser-pool:8082
|
|
18
|
+
LEASHBYTE_VAULT_BASE_URL=http://vault:8081
|
|
19
|
+
LEASHBYTE_FETCH_TIMEOUT_SECONDS=20
|
|
20
|
+
LEASHBYTE_FETCH_MAX_BYTES=2000000
|
|
21
|
+
LEASHBYTE_FETCH_MAX_REDIRECTS=5
|
|
22
|
+
LEASHBYTE_SEARCH_MAX_RESULTS=10
|
|
23
|
+
LEASHBYTE_PRIVATE_NETWORK_ALLOWLIST=
|
|
24
|
+
LEASHBYTE_BROWSER_MAX_SESSIONS=2
|
|
25
|
+
LEASHBYTE_BROWSER_LEASE_SECONDS=900
|
|
26
|
+
LEASHBYTE_CDP_GRANT_SECONDS=60
|
|
27
|
+
LEASHBYTE_BROWSER_PLUGINS_ENABLED=false
|
|
28
|
+
LEASHBYTE_BROWSER_PLUGIN_MODULES=
|
|
29
|
+
LEASHBYTE_LOCAL_MODEL_BASE_URL=
|
|
30
|
+
LEASHBYTE_COMPOSE_SUBNET=172.29.250.0/24
|
|
31
|
+
LEASHBYTE_COMPOSE_GATEWAY=172.29.250.1
|
|
32
|
+
LEASHBYTE_LOCAL_MODEL_PORT=11434
|
|
33
|
+
# Needed for local agent runs: the model name your server exposes.
|
|
34
|
+
LEASHBYTE_LOCAL_MODEL_NAME=
|
|
35
|
+
LEASHBYTE_LOCAL_MODEL_API_KEY=
|
|
36
|
+
LEASHBYTE_LOCAL_MODEL_API_KEY_FILE=
|
|
37
|
+
LEASHBYTE_MODEL_TIMEOUT_SECONDS=120
|
|
38
|
+
LEASHBYTE_AGENT_POLL_SECONDS=0.5
|
|
39
|
+
# Optional: path to an Anthropic API key file (mode 600) outside this repository.
|
|
40
|
+
# Leave it empty if you only use local models.
|
|
41
|
+
LEASHBYTE_ANTHROPIC_API_KEY_HOST_FILE=
|
|
42
|
+
LEASHBYTE_WEB_BOT_AUTH_KEY_FILE=
|
|
43
|
+
LEASHBYTE_WEB_BOT_AUTH_HOST_KEY_FILE=
|
|
44
|
+
LEASHBYTE_WEB_BOT_AUTH_KEY_ID=
|
|
45
|
+
# Optional, for a controlled private HTTPS test fixture only: its SHA-256 SPKI value.
|
|
46
|
+
LEASHBYTE_BROWSER_TLS_SPKI_ALLOWLIST=
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
lint-and-test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
- name: Install uv
|
|
20
|
+
run: python -m pip install uv==0.13.4
|
|
21
|
+
- name: Install locked dependencies
|
|
22
|
+
run: uv sync --locked
|
|
23
|
+
- name: Lint
|
|
24
|
+
run: |
|
|
25
|
+
uv run ruff check src tests sdk/python/src examples ci/mcp_roundtrip.py scripts/python_licenses.py
|
|
26
|
+
uv run ruff format --check src tests sdk/python/src examples ci/mcp_roundtrip.py scripts/python_licenses.py
|
|
27
|
+
- name: Check the Python licence inventory
|
|
28
|
+
run: uv run python scripts/python_licenses.py --check
|
|
29
|
+
- name: Test essential security and API contracts
|
|
30
|
+
run: uv run pytest -q tests
|
|
31
|
+
- name: Set up Node
|
|
32
|
+
uses: actions/setup-node@v4
|
|
33
|
+
with:
|
|
34
|
+
node-version: "22"
|
|
35
|
+
cache: npm
|
|
36
|
+
cache-dependency-path: sdk/typescript/package-lock.json
|
|
37
|
+
- name: Check the TypeScript SDK and JavaScript licences
|
|
38
|
+
run: |
|
|
39
|
+
npm ci --prefix sdk/typescript
|
|
40
|
+
uv run python scripts/generate_openapi.py
|
|
41
|
+
uvx --from datamodel-code-generator==0.91.0 datamodel-codegen \
|
|
42
|
+
--input openapi.json \
|
|
43
|
+
--input-file-type openapi \
|
|
44
|
+
--output sdk/python/src/leashbyte_sdk/_models.py \
|
|
45
|
+
--output-model-type pydantic_v2.BaseModel \
|
|
46
|
+
--use-standard-collections \
|
|
47
|
+
--use-annotated \
|
|
48
|
+
--enum-field-as-literal all \
|
|
49
|
+
--target-python-version 3.13 \
|
|
50
|
+
--use-schema-description \
|
|
51
|
+
--use-field-description \
|
|
52
|
+
--disable-timestamp
|
|
53
|
+
uv run ruff format sdk/python/src/leashbyte_sdk/_models.py
|
|
54
|
+
npm --prefix sdk/typescript run generate
|
|
55
|
+
git diff --exit-code -- openapi.json sdk/python/src/leashbyte_sdk/_models.py sdk/typescript/src/schema.ts
|
|
56
|
+
npm --prefix sdk/typescript test
|
|
57
|
+
npm --prefix sdk/typescript run licenses
|
|
58
|
+
git diff --exit-code -- sdk/typescript/THIRD_PARTY_LICENSES.json
|
|
59
|
+
|
|
60
|
+
site:
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
- name: Set up Node
|
|
65
|
+
uses: actions/setup-node@v4
|
|
66
|
+
with:
|
|
67
|
+
node-version: "22"
|
|
68
|
+
cache: npm
|
|
69
|
+
cache-dependency-path: site/package-lock.json
|
|
70
|
+
- name: Install locked site dependencies
|
|
71
|
+
run: npm ci --prefix site
|
|
72
|
+
- name: Build the static site
|
|
73
|
+
run: npm --prefix site run build
|
|
74
|
+
|
|
75
|
+
compose-smoke:
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@v4
|
|
79
|
+
- uses: actions/setup-python@v5
|
|
80
|
+
with:
|
|
81
|
+
python-version: "3.13"
|
|
82
|
+
- name: Install uv
|
|
83
|
+
run: python -m pip install uv==0.13.4
|
|
84
|
+
- name: Install locked dependencies
|
|
85
|
+
run: uv sync --locked
|
|
86
|
+
- name: Create local configuration
|
|
87
|
+
run: |
|
|
88
|
+
cp .env.example .env
|
|
89
|
+
sed -i "s/replace-with-a-random-api-key/$(openssl rand -hex 32)/" .env
|
|
90
|
+
sed -i "s/replace-with-a-different-random-secret/$(openssl rand -hex 32)/" .env
|
|
91
|
+
sed -i "s/replace-with-a-random-service-key/$(openssl rand -hex 32)/" .env
|
|
92
|
+
sed -i "s/replace-with-a-random-vault-manage-key/$(openssl rand -hex 32)/" .env
|
|
93
|
+
sed -i "s/replace-with-a-random-vault-resolve-key/$(openssl rand -hex 32)/" .env
|
|
94
|
+
sed -i "s/replace-with-a-random-cdp-capability-key/$(openssl rand -hex 32)/" .env
|
|
95
|
+
sed -i "s/replace-with-a-random-vault-master-key/$(openssl rand -hex 32)/" .env
|
|
96
|
+
sed -i "s/replace-with-a-random-postgres-password/$(openssl rand -hex 32)/" .env
|
|
97
|
+
printf '%s\n' 'LEASHBYTE_PRIVATE_NETWORK_ALLOWLIST=host.docker.internal:18765' >> .env
|
|
98
|
+
- name: Start the controlled HTTP fixture
|
|
99
|
+
run: python ci/http_fixture.py &
|
|
100
|
+
- name: Start and check the Compose stack
|
|
101
|
+
run: |
|
|
102
|
+
docker compose up --build -d --wait
|
|
103
|
+
bash ci/compose-smoke.sh
|
|
104
|
+
LEASHBYTE_API_KEY="$(sed -n 's/^LEASHBYTE_API_KEY=//p' .env)" uv run python ci/mcp_roundtrip.py
|
|
105
|
+
- name: Show service logs after a failure
|
|
106
|
+
if: failure()
|
|
107
|
+
run: docker compose logs --no-color
|
|
108
|
+
- name: Stop the Compose stack
|
|
109
|
+
if: always()
|
|
110
|
+
run: docker compose down -v
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
.ruff_cache/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
|
|
13
|
+
# JavaScript
|
|
14
|
+
node_modules/
|
|
15
|
+
.npm/
|
|
16
|
+
*.tsbuildinfo
|
|
17
|
+
|
|
18
|
+
# Local configuration and secrets
|
|
19
|
+
.env
|
|
20
|
+
.env.*
|
|
21
|
+
!.env.example
|
|
22
|
+
*.pem
|
|
23
|
+
*.key
|
|
24
|
+
*.p12
|
|
25
|
+
*.pfx
|
|
26
|
+
secrets/
|
|
27
|
+
credentials/
|
|
28
|
+
|
|
29
|
+
# Runtime data
|
|
30
|
+
artifacts/
|
|
31
|
+
profiles/
|
|
32
|
+
runs/
|
|
33
|
+
*.sqlite
|
|
34
|
+
*.sqlite3
|
|
35
|
+
|
|
36
|
+
# Editors and operating systems
|
|
37
|
+
.idea/
|
|
38
|
+
.vscode/
|
|
39
|
+
.DS_Store
|
|
40
|
+
Thumbs.db
|
|
41
|
+
|
|
42
|
+
# Logs and coverage
|
|
43
|
+
*.log
|
|
44
|
+
coverage/
|
|
45
|
+
.coverage
|
|
46
|
+
htmlcov/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.1 - 2026-11-10
|
|
4
|
+
|
|
5
|
+
The first release on PyPI, as `leashbyte` and `leashbyte-sdk`. 0.1.0 was a GitHub-only release and was never uploaded to a package registry. There are no code changes.
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- The READMEs and the project site now give the PyPI install lines.
|
|
10
|
+
- `leashbyte` now requires `leashbyte-sdk>=0.1.1,<0.2`. Before, it accepted any version.
|
|
11
|
+
|
|
12
|
+
## 0.1.0 - 2026-11-10
|
|
13
|
+
|
|
14
|
+
First public source release.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Web search through a separate SearXNG service.
|
|
19
|
+
- Page fetch with Markdown, cleaned HTML and parsed JSON output, with time, size and redirect limits.
|
|
20
|
+
- Destination checks on fetch and browser traffic, so neither can reach internal addresses by default.
|
|
21
|
+
- Isolated Chrome sessions with named profiles, page actions and short-lived CDP access.
|
|
22
|
+
- An encrypted credential vault that only fills a credential on the exact origins it's granted to.
|
|
23
|
+
- Goal-driven agent runs with limits, cancellation, run records and artifacts.
|
|
24
|
+
- A local run viewer.
|
|
25
|
+
- An MCP server with stable search, fetch, browser and run tools.
|
|
26
|
+
- Python and TypeScript SDKs.
|
|
27
|
+
- A Docker Compose stack for local use, and a static project site.
|
|
28
|
+
- API key authentication, a security policy and Apache-2.0 licensing.
|
|
29
|
+
|
|
30
|
+
### Notes
|
|
31
|
+
|
|
32
|
+
LeashByte is pre-alpha. Install it from GitHub and run it with Docker Compose. The PyPI and npm packages aren't published yet and the project site isn't deployed. [Known limits and next steps](docs/ROADMAP.md) lists what's still open.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
10
|
+
identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
* Demonstrating empathy and kindness toward other people
|
|
21
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
* Giving and gracefully accepting constructive feedback
|
|
23
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
* Focusing on what is best not just for us as individuals, but for the overall
|
|
26
|
+
community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
* The use of sexualized language or imagery, and sexual attention or advances of
|
|
31
|
+
any kind
|
|
32
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
* Public or private harassment
|
|
34
|
+
* Publishing others' private information, such as a physical or email address,
|
|
35
|
+
without their explicit permission
|
|
36
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
49
|
+
decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
Examples of representing our community include using an official email address,
|
|
56
|
+
posting via an official social media account, or acting as an appointed
|
|
57
|
+
representative at an online or offline event.
|
|
58
|
+
|
|
59
|
+
## Enforcement
|
|
60
|
+
|
|
61
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
|
+
reported to the community leaders responsible for enforcement at
|
|
63
|
+
info@leashbyte.com.
|
|
64
|
+
All complaints will be reviewed and investigated promptly and fairly.
|
|
65
|
+
|
|
66
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
67
|
+
reporter of any incident.
|
|
68
|
+
|
|
69
|
+
## Enforcement Guidelines
|
|
70
|
+
|
|
71
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
72
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
73
|
+
|
|
74
|
+
### 1. Correction
|
|
75
|
+
|
|
76
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
77
|
+
unprofessional or unwelcome in the community.
|
|
78
|
+
|
|
79
|
+
**Consequence**: A private, written warning from community leaders, providing
|
|
80
|
+
clarity around the nature of the violation and an explanation of why the
|
|
81
|
+
behavior was inappropriate. A public apology may be requested.
|
|
82
|
+
|
|
83
|
+
### 2. Warning
|
|
84
|
+
|
|
85
|
+
**Community Impact**: A violation through a single incident or series of
|
|
86
|
+
actions.
|
|
87
|
+
|
|
88
|
+
**Consequence**: A warning with consequences for continued behavior. No
|
|
89
|
+
interaction with the people involved, including unsolicited interaction with
|
|
90
|
+
those enforcing the Code of Conduct, for a specified period of time. This
|
|
91
|
+
includes avoiding interactions in community spaces as well as external channels
|
|
92
|
+
like social media. Violating these terms may lead to a temporary or permanent
|
|
93
|
+
ban.
|
|
94
|
+
|
|
95
|
+
### 3. Temporary Ban
|
|
96
|
+
|
|
97
|
+
**Community Impact**: A serious violation of community standards, including
|
|
98
|
+
sustained inappropriate behavior.
|
|
99
|
+
|
|
100
|
+
**Consequence**: A temporary ban from any sort of public interaction or public
|
|
101
|
+
communication with the community for a specified period of time. No public or
|
|
102
|
+
private interaction with the people involved, including unsolicited interaction
|
|
103
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
104
|
+
Violating these terms may lead to a permanent ban.
|
|
105
|
+
|
|
106
|
+
### 4. Permanent Ban
|
|
107
|
+
|
|
108
|
+
**Community Impact**: Demonstrating a pattern of violation of community
|
|
109
|
+
standards, including sustained inappropriate behavior, harassment of an
|
|
110
|
+
individual, or aggression toward or disparagement of classes of individuals.
|
|
111
|
+
|
|
112
|
+
**Consequence**: A permanent ban from any sort of public interaction within the
|
|
113
|
+
community.
|
|
114
|
+
|
|
115
|
+
## Attribution
|
|
116
|
+
|
|
117
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
118
|
+
version 2.1, available at
|
|
119
|
+
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
|
120
|
+
|
|
121
|
+
Community Impact Guidelines were inspired by
|
|
122
|
+
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
|
123
|
+
|
|
124
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
|
125
|
+
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
|
126
|
+
[https://www.contributor-covenant.org/translations][translations].
|
|
127
|
+
|
|
128
|
+
[homepage]: https://www.contributor-covenant.org
|
|
129
|
+
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
|
130
|
+
[Mozilla CoC]: https://github.com/mozilla/diversity
|
|
131
|
+
[FAQ]: https://www.contributor-covenant.org/faq
|
|
132
|
+
[translations]: https://www.contributor-covenant.org/translations
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Contributing to LeashByte
|
|
2
|
+
|
|
3
|
+
LeashByte is pre-alpha and the API and security boundaries are still settling, so please open an issue before you start on anything substantial. It saves you writing a change that clashes with something already planned.
|
|
4
|
+
|
|
5
|
+
## Running the checks
|
|
6
|
+
|
|
7
|
+
You'll need Docker with the Compose plugin, Python 3.13 with uv 0.13.4, and Node 20 or later (22.12 or later if you build the site). From the repository root:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uv sync --locked
|
|
11
|
+
uv run ruff check src tests sdk/python/src examples ci/mcp_roundtrip.py scripts/python_licenses.py
|
|
12
|
+
uv run ruff format --check src tests sdk/python/src examples ci/mcp_roundtrip.py scripts/python_licenses.py
|
|
13
|
+
uv run python scripts/python_licenses.py --check
|
|
14
|
+
uv run pytest -q tests
|
|
15
|
+
npm ci --prefix sdk/typescript
|
|
16
|
+
npm --prefix sdk/typescript test
|
|
17
|
+
npm --prefix sdk/typescript run licenses
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
CI runs the same checks on every push to `main` and every pull request, builds the static site and starts the Compose stack for a smoke test. If you change a route's contract, regenerate `openapi.json` and the SDK models as the [README](README.md#development) describes.
|
|
21
|
+
|
|
22
|
+
## What a good pull request looks like
|
|
23
|
+
|
|
24
|
+
- It does one thing. Unrelated formatting changes and refactors make a change harder to review, so send those separately.
|
|
25
|
+
- The description says what changed, how you checked it and anything it doesn't cover yet. Link the issue it relates to.
|
|
26
|
+
- It comes with tests where they matter most: security boundaries, parsers of untrusted input and the fix for a bug, so the bug stays fixed.
|
|
27
|
+
- It fits the architecture in [docs/DESIGN.md](docs/DESIGN.md). If you think the design should change, say so in the issue first.
|
|
28
|
+
- It contains no credentials, private data, internal host names or internal paths, not even in test fixtures.
|
|
29
|
+
|
|
30
|
+
A maintainer reviews every pull request. Security-sensitive changes, and especially anything touching server-side fetch, browser access or the vault, get an extra security review.
|
|
31
|
+
|
|
32
|
+
## New dependencies
|
|
33
|
+
|
|
34
|
+
LeashByte is Apache-2.0, and we want anyone to be able to use, modify and redistribute it under those terms without picking up extra obligations. So new code and dependencies need Apache-2.0-compatible licences, such as Apache-2.0 or MIT. AGPL, SSPL and MPL projects stay outside the repository. The licence checks above fail on anything unknown, and when you add a dependency, please keep any copyright and NOTICE files it requires.
|
|
35
|
+
|
|
36
|
+
## Reporting a vulnerability
|
|
37
|
+
|
|
38
|
+
Please don't use a public issue or pull request for this. Email `security@leashbyte.com`. [SECURITY.md](SECURITY.md) has the details.
|
|
39
|
+
|
|
40
|
+
## Licence and conduct
|
|
41
|
+
|
|
42
|
+
By submitting a contribution, you agree that the project may distribute it under Apache-2.0. The [Contributor Covenant](CODE_OF_CONDUCT.md) applies in all project spaces and when you represent the project in public.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
FROM ghcr.io/astral-sh/uv:0.13.4 AS uv
|
|
2
|
+
|
|
3
|
+
FROM python:3.13-slim AS builder
|
|
4
|
+
COPY --from=uv /uv /uvx /bin/
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
|
|
7
|
+
COPY pyproject.toml uv.lock README.md LICENSE NOTICE ./
|
|
8
|
+
COPY sdk/python ./sdk/python
|
|
9
|
+
RUN uv sync --locked --no-dev --no-install-project --no-editable
|
|
10
|
+
COPY src ./src
|
|
11
|
+
RUN uv sync --locked --no-dev --no-editable
|
|
12
|
+
|
|
13
|
+
FROM python:3.13-slim AS runtime
|
|
14
|
+
RUN groupadd --gid 10001 leashbyte && useradd --uid 10001 --gid leashbyte --no-create-home leashbyte \
|
|
15
|
+
&& mkdir -p /data/profiles /data/vault /data/run-artifacts \
|
|
16
|
+
&& chown -R leashbyte:leashbyte /data
|
|
17
|
+
WORKDIR /app
|
|
18
|
+
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
|
|
19
|
+
COPY --from=builder --chown=leashbyte:leashbyte /app/.venv /app/.venv
|
|
20
|
+
COPY --from=builder --chown=leashbyte:leashbyte /app/src /app/src
|
|
21
|
+
COPY LICENSE NOTICE /app/
|
|
22
|
+
COPY docs/python-licenses.json docs/THIRD_PARTY.md /app/docs/
|
|
23
|
+
COPY sdk/typescript/THIRD_PARTY_LICENSES.json /app/sdk/typescript/
|
|
24
|
+
USER leashbyte
|
|
25
|
+
EXPOSE 8080
|
|
26
|
+
CMD ["uvicorn", "leashbyte.main:create_app", "--factory", "--host", "0.0.0.0", "--port", "8080"]
|
|
27
|
+
|
|
28
|
+
FROM python:3.13-slim AS browser
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1 PLAYWRIGHT_BROWSERS_PATH=/opt/playwright
|
|
31
|
+
COPY --from=builder /app/.venv /app/.venv
|
|
32
|
+
RUN playwright install --with-deps chrome \
|
|
33
|
+
&& groupadd --gid 10001 leashbyte \
|
|
34
|
+
&& useradd --uid 10001 --gid leashbyte --create-home leashbyte \
|
|
35
|
+
&& mkdir -p /data/profiles \
|
|
36
|
+
&& chown -R leashbyte:leashbyte /data /opt/playwright
|
|
37
|
+
COPY --from=builder --chown=leashbyte:leashbyte /app/src /app/src
|
|
38
|
+
COPY LICENSE NOTICE /app/
|
|
39
|
+
COPY docs/python-licenses.json docs/THIRD_PARTY.md /app/docs/
|
|
40
|
+
COPY sdk/typescript/THIRD_PARTY_LICENSES.json /app/sdk/typescript/
|
|
41
|
+
USER leashbyte
|
|
42
|
+
EXPOSE 8082
|
|
43
|
+
CMD ["uvicorn", "leashbyte.browser_service:create_browser_app", "--factory", "--host", "0.0.0.0", "--port", "8082"]
|