@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.2",
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",