@hybridlabor-api/bdb-antigravity-skills 1.0.2 → 1.0.3
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.
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""One-paste TouchDesigner bridge bootstrap (no clone, no Preferences).
|
|
2
|
+
|
|
3
|
+
Paste this single line into the Textport (Dialogs -> Textport and DATs) and the
|
|
4
|
+
bridge installs itself and starts:
|
|
5
|
+
|
|
6
|
+
import urllib.request; exec(urllib.request.urlopen("https://github.com/Pantani/tdmcp/raw/v0.11.0/td/bootstrap.py").read().decode())
|
|
7
|
+
|
|
8
|
+
That release-pinned snippet downloads just the bridge modules to
|
|
9
|
+
~/tdmcp-bridge/modules, puts them on sys.path for this session, and runs
|
|
10
|
+
install.run() -> a tdmcp_bridge on port 9980.
|
|
11
|
+
|
|
12
|
+
Requires the GitHub repo (or release zip) to be reachable. If your repo is
|
|
13
|
+
private, point REPO_ZIP at a public release asset, or use `install-bridge`
|
|
14
|
+
(`node dist/index.js install-bridge`) from a local checkout instead.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import io
|
|
18
|
+
import os
|
|
19
|
+
import stat
|
|
20
|
+
import sys
|
|
21
|
+
import zipfile
|
|
22
|
+
import urllib.request
|
|
23
|
+
|
|
24
|
+
REPO_ZIP = "https://github.com/Pantani/tdmcp/archive/refs/tags/v0.11.0.zip"
|
|
25
|
+
DEST = os.path.expanduser("~/tdmcp-bridge")
|
|
26
|
+
_MARKER = "/td/modules/"
|
|
27
|
+
_SKIP_RUN_ENV = "TDMCP_BOOTSTRAP_SKIP_RUN"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _is_symlink(info):
|
|
31
|
+
return stat.S_ISLNK((info.external_attr >> 16) & 0o170000)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _safe_module_path(name, modules_dir):
|
|
35
|
+
idx = name.find(_MARKER)
|
|
36
|
+
if idx == -1:
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
rel = name[idx + len(_MARKER):].replace("\\", "/")
|
|
40
|
+
if not rel or rel.endswith("/"):
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
parts = rel.split("/")
|
|
44
|
+
if (
|
|
45
|
+
rel.startswith("/")
|
|
46
|
+
or rel.startswith("\\")
|
|
47
|
+
or (len(parts[0]) >= 2 and parts[0][1] == ":")
|
|
48
|
+
or any(part in ("", ".", "..") for part in parts)
|
|
49
|
+
):
|
|
50
|
+
raise RuntimeError("[tdmcp] Refusing unsafe archive entry: %s" % name)
|
|
51
|
+
|
|
52
|
+
root = os.path.realpath(modules_dir)
|
|
53
|
+
target = os.path.realpath(os.path.join(modules_dir, *parts))
|
|
54
|
+
if target != root and not target.startswith(root + os.sep):
|
|
55
|
+
raise RuntimeError("[tdmcp] Refusing archive entry outside modules: %s" % name)
|
|
56
|
+
|
|
57
|
+
return target
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def fetch_modules(repo_zip=REPO_ZIP, dest=DEST):
|
|
61
|
+
"""Download the repo zip and extract only its td/modules tree into dest/modules."""
|
|
62
|
+
modules_dir = os.path.join(dest, "modules")
|
|
63
|
+
try:
|
|
64
|
+
data = urllib.request.urlopen(repo_zip, timeout=30).read()
|
|
65
|
+
except Exception as exc: # noqa: BLE001 - surface a friendly hint in the Textport
|
|
66
|
+
raise RuntimeError(
|
|
67
|
+
"[tdmcp] Could not download the bridge from %r (%s). If the repo is "
|
|
68
|
+
"private, use a public release asset or the local 'install-bridge' "
|
|
69
|
+
"command instead." % (repo_zip, exc)
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
zf = zipfile.ZipFile(io.BytesIO(data))
|
|
73
|
+
os.makedirs(modules_dir, exist_ok=True)
|
|
74
|
+
extracted = 0
|
|
75
|
+
for info in zf.infolist():
|
|
76
|
+
name = info.filename
|
|
77
|
+
if name.endswith("/"):
|
|
78
|
+
continue
|
|
79
|
+
target = _safe_module_path(name, modules_dir)
|
|
80
|
+
if target is None:
|
|
81
|
+
continue
|
|
82
|
+
if _is_symlink(info):
|
|
83
|
+
raise RuntimeError("[tdmcp] Refusing symlink archive entry: %s" % name)
|
|
84
|
+
os.makedirs(os.path.dirname(target), exist_ok=True)
|
|
85
|
+
with zf.open(name) as src, open(target, "wb") as out:
|
|
86
|
+
out.write(src.read())
|
|
87
|
+
extracted += 1
|
|
88
|
+
|
|
89
|
+
if extracted == 0:
|
|
90
|
+
raise RuntimeError("[tdmcp] Downloaded archive had no td/modules — wrong REPO_ZIP?")
|
|
91
|
+
print("[tdmcp] bridge modules -> %s (%d files)" % (modules_dir, extracted))
|
|
92
|
+
return modules_dir
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def run(repo_zip=REPO_ZIP, dest=DEST, port=9980):
|
|
96
|
+
modules_dir = fetch_modules(repo_zip, dest)
|
|
97
|
+
if modules_dir not in sys.path:
|
|
98
|
+
sys.path.insert(0, modules_dir)
|
|
99
|
+
from mcp import install
|
|
100
|
+
|
|
101
|
+
return install.run(port=port, modules_dir=modules_dir)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# Running via exec(urlopen(...).read()) or as a script kicks off the install.
|
|
105
|
+
if os.environ.get(_SKIP_RUN_ENV) != "1":
|
|
106
|
+
run()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hybridlabor-api/bdb-antigravity-skills",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Optimized Antigravity skills and MCP pack for BDB DEV",
|
|
5
5
|
"main": "installer.sh",
|
|
6
6
|
"bin": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"mcp_config.json",
|
|
15
15
|
"GEMINI.md",
|
|
16
16
|
"skilloverview.html",
|
|
17
|
+
"assets/",
|
|
17
18
|
"skills/"
|
|
18
19
|
],
|
|
19
20
|
"author": "BDB DEV",
|