substrate-setup 0.2.1__tar.gz → 0.2.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.
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/.gitignore +77 -74
- substrate_setup-0.2.2/PKG-INFO +69 -0
- substrate_setup-0.2.2/README.md +40 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/pyproject.toml +62 -62
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/scripts/lint_no_app_import.sh +10 -10
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/scripts/regenerate_fallback_catalog.py +68 -68
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/__init__.py +6 -6
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/__main__.py +5 -5
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/agents/__init__.py +20 -20
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/agents/base.py +56 -56
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/agents/cursor.py +90 -90
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/backup.py +32 -32
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/catalog.py +109 -109
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/cli.py +249 -225
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/credentials.py +82 -82
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/data/fallback_catalog.json +343 -343
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/markers.py +27 -27
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/agents/test_cursor.py +87 -87
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/conftest.py +1 -1
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/test_backup.py +38 -38
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/test_catalog.py +95 -95
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/test_cli.py +246 -175
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/test_credentials.py +80 -80
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/test_e2e.py +111 -111
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/test_markers.py +45 -45
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/uv.lock +1 -1
- substrate_setup-0.2.1/PKG-INFO +0 -40
- substrate_setup-0.2.1/README.md +0 -11
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/agents/aider.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/agents/continue_dev.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/substrate_setup/agents/hermes.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/__init__.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/agents/__init__.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/agents/test_aider.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/agents/test_continue_dev.py +0 -0
- {substrate_setup-0.2.1 → substrate_setup-0.2.2}/tests/agents/test_hermes.py +0 -0
|
@@ -1,74 +1,77 @@
|
|
|
1
|
-
# Secrets
|
|
2
|
-
.env
|
|
3
|
-
.env.local
|
|
4
|
-
.env.*.local
|
|
5
|
-
*.secret
|
|
6
|
-
secrets/
|
|
7
|
-
credentials.txt
|
|
8
|
-
credentials.*.txt
|
|
9
|
-
|
|
10
|
-
# Python
|
|
11
|
-
__pycache__/
|
|
12
|
-
*.py[cod]
|
|
13
|
-
*$py.class
|
|
14
|
-
*.so
|
|
15
|
-
.Python
|
|
16
|
-
.venv/
|
|
17
|
-
venv/
|
|
18
|
-
env/
|
|
19
|
-
.pytest_cache/
|
|
20
|
-
.mypy_cache/
|
|
21
|
-
.ruff_cache/
|
|
22
|
-
*.egg-info/
|
|
23
|
-
dist/
|
|
24
|
-
build/
|
|
25
|
-
|
|
26
|
-
# Node / Next.js
|
|
27
|
-
node_modules/
|
|
28
|
-
.next/
|
|
29
|
-
.vercel/
|
|
30
|
-
.turbo/
|
|
31
|
-
|
|
32
|
-
# CodeGraph (local-only code knowledge graph index)
|
|
33
|
-
.codegraph/
|
|
34
|
-
out/
|
|
35
|
-
*.tsbuildinfo
|
|
36
|
-
.npm/
|
|
37
|
-
.yarn/
|
|
38
|
-
|
|
39
|
-
# IDE
|
|
40
|
-
.vscode/
|
|
41
|
-
.idea/
|
|
42
|
-
*.swp
|
|
43
|
-
*.swo
|
|
44
|
-
|
|
45
|
-
# OS
|
|
46
|
-
.DS_Store
|
|
47
|
-
Thumbs.db
|
|
48
|
-
desktop.ini
|
|
49
|
-
|
|
50
|
-
# Logs
|
|
51
|
-
*.log
|
|
52
|
-
logs/
|
|
53
|
-
|
|
54
|
-
# Local databases
|
|
55
|
-
*.db
|
|
56
|
-
*.sqlite
|
|
57
|
-
*.sqlite3
|
|
58
|
-
|
|
59
|
-
# Editors
|
|
60
|
-
*~
|
|
61
|
-
.#*
|
|
62
|
-
|
|
63
|
-
# Coverage
|
|
64
|
-
.coverage
|
|
65
|
-
htmlcov/
|
|
66
|
-
coverage.xml
|
|
67
|
-
*.cover
|
|
68
|
-
|
|
69
|
-
# Claude Code project state (if any project-local)
|
|
70
|
-
.claude/
|
|
71
|
-
|
|
72
|
-
# Misc
|
|
73
|
-
*.bak
|
|
74
|
-
*.tmp
|
|
1
|
+
# Secrets
|
|
2
|
+
.env
|
|
3
|
+
.env.local
|
|
4
|
+
.env.*.local
|
|
5
|
+
*.secret
|
|
6
|
+
secrets/
|
|
7
|
+
credentials.txt
|
|
8
|
+
credentials.*.txt
|
|
9
|
+
|
|
10
|
+
# Python
|
|
11
|
+
__pycache__/
|
|
12
|
+
*.py[cod]
|
|
13
|
+
*$py.class
|
|
14
|
+
*.so
|
|
15
|
+
.Python
|
|
16
|
+
.venv/
|
|
17
|
+
venv/
|
|
18
|
+
env/
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
dist/
|
|
24
|
+
build/
|
|
25
|
+
|
|
26
|
+
# Node / Next.js
|
|
27
|
+
node_modules/
|
|
28
|
+
.next/
|
|
29
|
+
.vercel/
|
|
30
|
+
.turbo/
|
|
31
|
+
|
|
32
|
+
# CodeGraph (local-only code knowledge graph index)
|
|
33
|
+
.codegraph/
|
|
34
|
+
out/
|
|
35
|
+
*.tsbuildinfo
|
|
36
|
+
.npm/
|
|
37
|
+
.yarn/
|
|
38
|
+
|
|
39
|
+
# IDE
|
|
40
|
+
.vscode/
|
|
41
|
+
.idea/
|
|
42
|
+
*.swp
|
|
43
|
+
*.swo
|
|
44
|
+
|
|
45
|
+
# OS
|
|
46
|
+
.DS_Store
|
|
47
|
+
Thumbs.db
|
|
48
|
+
desktop.ini
|
|
49
|
+
|
|
50
|
+
# Logs
|
|
51
|
+
*.log
|
|
52
|
+
logs/
|
|
53
|
+
|
|
54
|
+
# Local databases
|
|
55
|
+
*.db
|
|
56
|
+
*.sqlite
|
|
57
|
+
*.sqlite3
|
|
58
|
+
|
|
59
|
+
# Editors
|
|
60
|
+
*~
|
|
61
|
+
.#*
|
|
62
|
+
|
|
63
|
+
# Coverage
|
|
64
|
+
.coverage
|
|
65
|
+
htmlcov/
|
|
66
|
+
coverage.xml
|
|
67
|
+
*.cover
|
|
68
|
+
|
|
69
|
+
# Claude Code project state (if any project-local)
|
|
70
|
+
.claude/
|
|
71
|
+
|
|
72
|
+
# Misc
|
|
73
|
+
*.bak
|
|
74
|
+
*.tmp
|
|
75
|
+
|
|
76
|
+
# brainstorming companion working dir
|
|
77
|
+
.superpowers/
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: substrate-setup
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: One-shot local configurator for coding agents against a Substrate gateway
|
|
5
|
+
Project-URL: Homepage, https://github.com/FrankXiaA/substrate-solutions
|
|
6
|
+
Project-URL: Source, https://github.com/FrankXiaA/substrate-solutions/tree/main/substrate-api/substrate_setup
|
|
7
|
+
Project-URL: Issues, https://github.com/FrankXiaA/substrate-solutions/issues
|
|
8
|
+
Author: Substrate Solutions
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: aider,continue,gateway,hermes,llm,openai-compatible,substrate
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Requires-Dist: httpx>=0.27
|
|
22
|
+
Requires-Dist: ruamel-yaml>=0.18
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: mypy<2,>=1.13; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: ruff<1,>=0.7; extra == 'dev'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# substrate-setup
|
|
31
|
+
|
|
32
|
+
One-shot configurator that points local coding agents at a Substrate gateway.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
`substrate-setup` requires Python 3.12+. The installers below pick the right interpreter automatically — you don't need a Python 3.12 already on your machine:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Option A — uv (recommended; downloads Python 3.12 on demand if missing)
|
|
40
|
+
uv tool install substrate-setup
|
|
41
|
+
|
|
42
|
+
# Option B — pipx
|
|
43
|
+
pipx install substrate-setup
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Don't have `uv`? Install it once with:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
|
|
50
|
+
# or on Windows:
|
|
51
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> **Why not `pip install substrate-setup`?** It works only if the `pip` on your PATH is bound to a Python 3.12+ interpreter. Anaconda's default `pip` (Python 3.9) is the common pitfall — PyPI hides every release from it with `Requires-Python >=3.12` and the error message is unhelpful. `uv` and `pipx` both create an isolated 3.12 venv for the tool, so they sidestep the issue entirely.
|
|
55
|
+
|
|
56
|
+
## Use
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
export SUBSTRATE_API_KEY="sk-substrate-..." # or be prompted
|
|
60
|
+
|
|
61
|
+
substrate-setup configure # detect installed agents and wire them up
|
|
62
|
+
substrate-setup verify # read-only: confirm everything points at the gateway
|
|
63
|
+
substrate-setup remove # strip the substrate-managed entries
|
|
64
|
+
substrate-setup --help
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Supported agents: `hermes`, `cursor`, `aider`, `continue`.
|
|
68
|
+
|
|
69
|
+
Subset with `--agents-only hermes,aider`. Preview without writing: `--dry-run`. Override the gateway base URL: `--base-url https://your-gateway.example.com`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# substrate-setup
|
|
2
|
+
|
|
3
|
+
One-shot configurator that points local coding agents at a Substrate gateway.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
`substrate-setup` requires Python 3.12+. The installers below pick the right interpreter automatically — you don't need a Python 3.12 already on your machine:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Option A — uv (recommended; downloads Python 3.12 on demand if missing)
|
|
11
|
+
uv tool install substrate-setup
|
|
12
|
+
|
|
13
|
+
# Option B — pipx
|
|
14
|
+
pipx install substrate-setup
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Don't have `uv`? Install it once with:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
|
|
21
|
+
# or on Windows:
|
|
22
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> **Why not `pip install substrate-setup`?** It works only if the `pip` on your PATH is bound to a Python 3.12+ interpreter. Anaconda's default `pip` (Python 3.9) is the common pitfall — PyPI hides every release from it with `Requires-Python >=3.12` and the error message is unhelpful. `uv` and `pipx` both create an isolated 3.12 venv for the tool, so they sidestep the issue entirely.
|
|
26
|
+
|
|
27
|
+
## Use
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
export SUBSTRATE_API_KEY="sk-substrate-..." # or be prompted
|
|
31
|
+
|
|
32
|
+
substrate-setup configure # detect installed agents and wire them up
|
|
33
|
+
substrate-setup verify # read-only: confirm everything points at the gateway
|
|
34
|
+
substrate-setup remove # strip the substrate-managed entries
|
|
35
|
+
substrate-setup --help
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Supported agents: `hermes`, `cursor`, `aider`, `continue`.
|
|
39
|
+
|
|
40
|
+
Subset with `--agents-only hermes,aider`. Preview without writing: `--dry-run`. Override the gateway base URL: `--base-url https://your-gateway.example.com`.
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
3
|
-
build-backend = "hatchling.build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "substrate-setup"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "One-shot local configurator for coding agents against a Substrate gateway"
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.12"
|
|
11
|
-
authors = [{ name = "Substrate Solutions" }]
|
|
12
|
-
license = { text = "MIT" }
|
|
13
|
-
keywords = ["substrate", "llm", "gateway", "aider", "continue", "hermes", "openai-compatible"]
|
|
14
|
-
classifiers = [
|
|
15
|
-
"Development Status :: 4 - Beta",
|
|
16
|
-
"Environment :: Console",
|
|
17
|
-
"Intended Audience :: Developers",
|
|
18
|
-
"License :: OSI Approved :: MIT License",
|
|
19
|
-
"Operating System :: OS Independent",
|
|
20
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
-
"Programming Language :: Python :: 3.12",
|
|
22
|
-
"Topic :: Software Development :: Code Generators",
|
|
23
|
-
"Topic :: Utilities",
|
|
24
|
-
]
|
|
25
|
-
dependencies = [
|
|
26
|
-
"httpx>=0.27",
|
|
27
|
-
"ruamel.yaml>=0.18",
|
|
28
|
-
]
|
|
29
|
-
|
|
30
|
-
[project.urls]
|
|
31
|
-
Homepage = "https://github.com/FrankXiaA/substrate-solutions"
|
|
32
|
-
Source = "https://github.com/FrankXiaA/substrate-solutions/tree/main/substrate-api/substrate_setup"
|
|
33
|
-
Issues = "https://github.com/FrankXiaA/substrate-solutions/issues"
|
|
34
|
-
|
|
35
|
-
[project.optional-dependencies]
|
|
36
|
-
dev = [
|
|
37
|
-
"pytest>=8.0",
|
|
38
|
-
"pytest-httpx>=0.30",
|
|
39
|
-
"ruff>=0.7,<1",
|
|
40
|
-
"mypy>=1.13,<2",
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
[project.scripts]
|
|
44
|
-
substrate-setup = "substrate_setup.cli:main"
|
|
45
|
-
|
|
46
|
-
[tool.hatch.build.targets.wheel]
|
|
47
|
-
packages = ["substrate_setup"]
|
|
48
|
-
|
|
49
|
-
[tool.pytest.ini_options]
|
|
50
|
-
testpaths = ["tests"]
|
|
51
|
-
|
|
52
|
-
[tool.mypy]
|
|
53
|
-
python_version = "3.12"
|
|
54
|
-
strict = true
|
|
55
|
-
ignore_missing_imports = true
|
|
56
|
-
packages = ["substrate_setup"]
|
|
57
|
-
|
|
58
|
-
[[tool.mypy.overrides]]
|
|
59
|
-
module = "tests.*"
|
|
60
|
-
disallow_untyped_defs = false
|
|
61
|
-
disallow_incomplete_defs = false
|
|
62
|
-
check_untyped_defs = false
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "substrate-setup"
|
|
7
|
+
version = "0.2.2"
|
|
8
|
+
description = "One-shot local configurator for coding agents against a Substrate gateway"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
authors = [{ name = "Substrate Solutions" }]
|
|
12
|
+
license = { text = "MIT" }
|
|
13
|
+
keywords = ["substrate", "llm", "gateway", "aider", "continue", "hermes", "openai-compatible"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Software Development :: Code Generators",
|
|
23
|
+
"Topic :: Utilities",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"httpx>=0.27",
|
|
27
|
+
"ruamel.yaml>=0.18",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/FrankXiaA/substrate-solutions"
|
|
32
|
+
Source = "https://github.com/FrankXiaA/substrate-solutions/tree/main/substrate-api/substrate_setup"
|
|
33
|
+
Issues = "https://github.com/FrankXiaA/substrate-solutions/issues"
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=8.0",
|
|
38
|
+
"pytest-httpx>=0.30",
|
|
39
|
+
"ruff>=0.7,<1",
|
|
40
|
+
"mypy>=1.13,<2",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
substrate-setup = "substrate_setup.cli:main"
|
|
45
|
+
|
|
46
|
+
[tool.hatch.build.targets.wheel]
|
|
47
|
+
packages = ["substrate_setup"]
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
testpaths = ["tests"]
|
|
51
|
+
|
|
52
|
+
[tool.mypy]
|
|
53
|
+
python_version = "3.12"
|
|
54
|
+
strict = true
|
|
55
|
+
ignore_missing_imports = true
|
|
56
|
+
packages = ["substrate_setup"]
|
|
57
|
+
|
|
58
|
+
[[tool.mypy.overrides]]
|
|
59
|
+
module = "tests.*"
|
|
60
|
+
disallow_untyped_defs = false
|
|
61
|
+
disallow_incomplete_defs = false
|
|
62
|
+
check_untyped_defs = false
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# CI lint: substrate_setup/ MUST NOT import anything from app/.
|
|
3
|
-
# The two packages share a source tree, not a dependency graph.
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
PKG_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
6
|
-
if grep -RIn --include='*.py' '^from app\b\|^import app\b' "$PKG_DIR/substrate_setup"; then
|
|
7
|
-
echo "ERROR: substrate_setup/ must not import from app/. See package boundary rule in spec."
|
|
8
|
-
exit 1
|
|
9
|
-
fi
|
|
10
|
-
echo "OK: no app/ imports in substrate_setup/"
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# CI lint: substrate_setup/ MUST NOT import anything from app/.
|
|
3
|
+
# The two packages share a source tree, not a dependency graph.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
PKG_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
6
|
+
if grep -RIn --include='*.py' '^from app\b\|^import app\b' "$PKG_DIR/substrate_setup"; then
|
|
7
|
+
echo "ERROR: substrate_setup/ must not import from app/. See package boundary rule in spec."
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
echo "OK: no app/ imports in substrate_setup/"
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
"""Regenerate the bundled fallback catalog snapshot.
|
|
2
|
-
|
|
3
|
-
Run manually before each PyPI release of substrate-setup. NOT run by CI cron —
|
|
4
|
-
a transient production glitch should NEVER be baked into the next release.
|
|
5
|
-
|
|
6
|
-
Usage:
|
|
7
|
-
SUBSTRATE_API_KEY=sk-substrate-... \
|
|
8
|
-
python scripts/regenerate_fallback_catalog.py [--base-url https://...]
|
|
9
|
-
|
|
10
|
-
Writes substrate_setup/data/fallback_catalog.json. Applies a sanity check
|
|
11
|
-
(>= 5 models, all five expected providers present) before writing.
|
|
12
|
-
"""
|
|
13
|
-
from __future__ import annotations
|
|
14
|
-
|
|
15
|
-
import argparse
|
|
16
|
-
import json
|
|
17
|
-
import os
|
|
18
|
-
import sys
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
|
|
21
|
-
import httpx
|
|
22
|
-
|
|
23
|
-
EXPECTED_PROVIDERS = {"anthropic", "openai", "google", "deepseek", "moonshot"}
|
|
24
|
-
DEFAULT_BASE_URL = "https://substrate-solutions-api.fly.dev/v1"
|
|
25
|
-
TARGET = Path(__file__).resolve().parents[1] / "substrate_setup" / "data" / "fallback_catalog.json"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def main(argv: list[str] | None = None) -> int:
|
|
29
|
-
parser = argparse.ArgumentParser()
|
|
30
|
-
parser.add_argument("--base-url", default=DEFAULT_BASE_URL)
|
|
31
|
-
args = parser.parse_args(argv)
|
|
32
|
-
|
|
33
|
-
api_key = os.environ.get("SUBSTRATE_API_KEY")
|
|
34
|
-
if not api_key:
|
|
35
|
-
print("ERROR: SUBSTRATE_API_KEY env var required.", file=sys.stderr)
|
|
36
|
-
return 1
|
|
37
|
-
|
|
38
|
-
# Tolerate --base-url with or without a trailing /v1 (same convention as
|
|
39
|
-
# substrate_setup.catalog.fetch_catalog).
|
|
40
|
-
normalized = args.base_url.rstrip("/")
|
|
41
|
-
if normalized.endswith("/v1"):
|
|
42
|
-
normalized = normalized[:-3]
|
|
43
|
-
|
|
44
|
-
resp = httpx.get(
|
|
45
|
-
f"{normalized}/v1/models",
|
|
46
|
-
headers={"Authorization": f"Bearer {api_key}"},
|
|
47
|
-
timeout=15.0,
|
|
48
|
-
)
|
|
49
|
-
resp.raise_for_status()
|
|
50
|
-
payload = resp.json()
|
|
51
|
-
|
|
52
|
-
data = payload.get("data") or []
|
|
53
|
-
providers = {item.get("owned_by") for item in data}
|
|
54
|
-
if len(data) < 5:
|
|
55
|
-
print(f"REFUSED: only {len(data)} models in catalog (expected >= 5).", file=sys.stderr)
|
|
56
|
-
return 2
|
|
57
|
-
if not EXPECTED_PROVIDERS.issubset(providers):
|
|
58
|
-
missing = EXPECTED_PROVIDERS - providers
|
|
59
|
-
print(f"REFUSED: missing providers {missing}.", file=sys.stderr)
|
|
60
|
-
return 2
|
|
61
|
-
|
|
62
|
-
TARGET.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
|
|
63
|
-
print(f"Wrote {len(data)} models to {TARGET}")
|
|
64
|
-
return 0
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if __name__ == "__main__":
|
|
68
|
-
raise SystemExit(main())
|
|
1
|
+
"""Regenerate the bundled fallback catalog snapshot.
|
|
2
|
+
|
|
3
|
+
Run manually before each PyPI release of substrate-setup. NOT run by CI cron —
|
|
4
|
+
a transient production glitch should NEVER be baked into the next release.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
SUBSTRATE_API_KEY=sk-substrate-... \
|
|
8
|
+
python scripts/regenerate_fallback_catalog.py [--base-url https://...]
|
|
9
|
+
|
|
10
|
+
Writes substrate_setup/data/fallback_catalog.json. Applies a sanity check
|
|
11
|
+
(>= 5 models, all five expected providers present) before writing.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import json
|
|
17
|
+
import os
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
import httpx
|
|
22
|
+
|
|
23
|
+
EXPECTED_PROVIDERS = {"anthropic", "openai", "google", "deepseek", "moonshot"}
|
|
24
|
+
DEFAULT_BASE_URL = "https://substrate-solutions-api.fly.dev/v1"
|
|
25
|
+
TARGET = Path(__file__).resolve().parents[1] / "substrate_setup" / "data" / "fallback_catalog.json"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def main(argv: list[str] | None = None) -> int:
|
|
29
|
+
parser = argparse.ArgumentParser()
|
|
30
|
+
parser.add_argument("--base-url", default=DEFAULT_BASE_URL)
|
|
31
|
+
args = parser.parse_args(argv)
|
|
32
|
+
|
|
33
|
+
api_key = os.environ.get("SUBSTRATE_API_KEY")
|
|
34
|
+
if not api_key:
|
|
35
|
+
print("ERROR: SUBSTRATE_API_KEY env var required.", file=sys.stderr)
|
|
36
|
+
return 1
|
|
37
|
+
|
|
38
|
+
# Tolerate --base-url with or without a trailing /v1 (same convention as
|
|
39
|
+
# substrate_setup.catalog.fetch_catalog).
|
|
40
|
+
normalized = args.base_url.rstrip("/")
|
|
41
|
+
if normalized.endswith("/v1"):
|
|
42
|
+
normalized = normalized[:-3]
|
|
43
|
+
|
|
44
|
+
resp = httpx.get(
|
|
45
|
+
f"{normalized}/v1/models",
|
|
46
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
47
|
+
timeout=15.0,
|
|
48
|
+
)
|
|
49
|
+
resp.raise_for_status()
|
|
50
|
+
payload = resp.json()
|
|
51
|
+
|
|
52
|
+
data = payload.get("data") or []
|
|
53
|
+
providers = {item.get("owned_by") for item in data}
|
|
54
|
+
if len(data) < 5:
|
|
55
|
+
print(f"REFUSED: only {len(data)} models in catalog (expected >= 5).", file=sys.stderr)
|
|
56
|
+
return 2
|
|
57
|
+
if not EXPECTED_PROVIDERS.issubset(providers):
|
|
58
|
+
missing = EXPECTED_PROVIDERS - providers
|
|
59
|
+
print(f"REFUSED: missing providers {missing}.", file=sys.stderr)
|
|
60
|
+
return 2
|
|
61
|
+
|
|
62
|
+
TARGET.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
|
|
63
|
+
print(f"Wrote {len(data)} models to {TARGET}")
|
|
64
|
+
return 0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
raise SystemExit(main())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"""substrate-setup — one-shot configurator for coding agents.
|
|
2
|
-
|
|
3
|
-
See https://github.com/FrankXiaA/substrate-solutions for the gateway it
|
|
4
|
-
configures against.
|
|
5
|
-
"""
|
|
6
|
-
__version__ = "0.2.
|
|
1
|
+
"""substrate-setup — one-shot configurator for coding agents.
|
|
2
|
+
|
|
3
|
+
See https://github.com/FrankXiaA/substrate-solutions for the gateway it
|
|
4
|
+
configures against.
|
|
5
|
+
"""
|
|
6
|
+
__version__ = "0.2.2"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"""Module entry point: ``python -m substrate_setup``."""
|
|
2
|
-
from substrate_setup.cli import main
|
|
3
|
-
|
|
4
|
-
if __name__ == "__main__":
|
|
5
|
-
raise SystemExit(main())
|
|
1
|
+
"""Module entry point: ``python -m substrate_setup``."""
|
|
2
|
+
from substrate_setup.cli import main
|
|
3
|
+
|
|
4
|
+
if __name__ == "__main__":
|
|
5
|
+
raise SystemExit(main())
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
"""Agent registry. Imports each agent module; exposes the list.
|
|
2
|
-
|
|
3
|
-
Order of this list is the order they print in the summary.
|
|
4
|
-
"""
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
|
|
7
|
-
from substrate_setup.agents.aider import AiderAgent
|
|
8
|
-
from substrate_setup.agents.base import Agent
|
|
9
|
-
from substrate_setup.agents.continue_dev import ContinueAgent
|
|
10
|
-
from substrate_setup.agents.cursor import CursorAgent
|
|
11
|
-
from substrate_setup.agents.hermes import HermesAgent
|
|
12
|
-
|
|
13
|
-
ALL_AGENTS: list[Agent] = [
|
|
14
|
-
HermesAgent(),
|
|
15
|
-
CursorAgent(),
|
|
16
|
-
AiderAgent(),
|
|
17
|
-
ContinueAgent(),
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
AGENT_NAMES: list[str] = [a.name for a in ALL_AGENTS]
|
|
1
|
+
"""Agent registry. Imports each agent module; exposes the list.
|
|
2
|
+
|
|
3
|
+
Order of this list is the order they print in the summary.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from substrate_setup.agents.aider import AiderAgent
|
|
8
|
+
from substrate_setup.agents.base import Agent
|
|
9
|
+
from substrate_setup.agents.continue_dev import ContinueAgent
|
|
10
|
+
from substrate_setup.agents.cursor import CursorAgent
|
|
11
|
+
from substrate_setup.agents.hermes import HermesAgent
|
|
12
|
+
|
|
13
|
+
ALL_AGENTS: list[Agent] = [
|
|
14
|
+
HermesAgent(),
|
|
15
|
+
CursorAgent(),
|
|
16
|
+
AiderAgent(),
|
|
17
|
+
ContinueAgent(),
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
AGENT_NAMES: list[str] = [a.name for a in ALL_AGENTS]
|