@mcptoolshop/backpropagate 1.2.0 → 1.3.0
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.
- package/README.es.md +216 -207
- package/README.fr.md +216 -207
- package/README.hi.md +216 -207
- package/README.it.md +217 -208
- package/README.ja.md +216 -207
- package/README.md +216 -207
- package/README.pt-BR.md +215 -206
- package/README.zh.md +215 -206
- package/bin/backpropagate.js +29 -196
- package/package.json +2 -5
package/bin/backpropagate.js
CHANGED
|
@@ -1,204 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
const { spawnSync } = require("child_process");
|
|
5
|
-
const path = require("path");
|
|
6
|
-
const fs = require("fs");
|
|
7
|
-
const os = require("os");
|
|
8
|
-
|
|
9
4
|
// ---------------------------------------------------------------------------
|
|
10
|
-
//
|
|
5
|
+
// npm distribution of backpropagate is deprecated as of v1.3.
|
|
11
6
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
7
|
+
// History: v1.0–v1.2 shipped PyInstaller binaries from a GitHub Release,
|
|
8
|
+
// pulled via @mcptoolshop/npm-launcher. Linux bootstrapped a managed venv
|
|
9
|
+
// instead because libtorch_cpu.so blew past GitHub's 2GB release-asset cap.
|
|
10
|
+
// The binary build pipeline failed three consecutive times in v1.2.0 and the
|
|
11
|
+
// release tag has zero attached assets — the launcher would 404 on download.
|
|
16
12
|
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const installRoot = process.env.BACKPROPAGATE_BOOTSTRAP_ROOT
|
|
29
|
-
|| path.join(dataHome, TOOL);
|
|
30
|
-
const venvDir = path.join(installRoot, "venv");
|
|
31
|
-
const metaPath = path.join(installRoot, "install.json");
|
|
32
|
-
const venvBin = path.join(venvDir, "bin", TOOL);
|
|
33
|
-
const venvPython = path.join(venvDir, "bin", "python3");
|
|
34
|
-
|
|
35
|
-
// -- helpers --------------------------------------------------------------
|
|
36
|
-
|
|
37
|
-
function findPython() {
|
|
38
|
-
// Prefer python3, fall back to python (if it's 3.x)
|
|
39
|
-
for (const cmd of ["python3", "python"]) {
|
|
40
|
-
const r = spawnSync(cmd, ["--version"], {
|
|
41
|
-
encoding: "utf8",
|
|
42
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
43
|
-
});
|
|
44
|
-
if (r.status === 0) {
|
|
45
|
-
const ver = (r.stdout || r.stderr || "").trim();
|
|
46
|
-
const match = ver.match(/Python\s+(\d+)\.(\d+)/);
|
|
47
|
-
if (match && parseInt(match[1], 10) >= 3 && parseInt(match[2], 10) >= 10) {
|
|
48
|
-
return cmd;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function readMeta() {
|
|
56
|
-
try {
|
|
57
|
-
return JSON.parse(fs.readFileSync(metaPath, "utf8"));
|
|
58
|
-
} catch {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function writeMeta(obj) {
|
|
64
|
-
fs.mkdirSync(installRoot, { recursive: true });
|
|
65
|
-
fs.writeFileSync(metaPath, JSON.stringify(obj, null, 2) + "\n");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function fail(message, hint) {
|
|
69
|
-
process.stderr.write(`\n${TOOL}: ${message}\n`);
|
|
70
|
-
if (hint) process.stderr.write(`\n${hint}\n`);
|
|
71
|
-
process.stderr.write("\n");
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// -- bootstrap ------------------------------------------------------------
|
|
76
|
-
|
|
77
|
-
function bootstrap() {
|
|
78
|
-
const forceReinstall = process.env.BACKPROPAGATE_FORCE_REINSTALL === "1";
|
|
79
|
-
const meta = readMeta();
|
|
80
|
-
|
|
81
|
-
const versionMatch = meta && meta.version === VERSION;
|
|
82
|
-
const binaryPresent = fs.existsSync(venvBin);
|
|
83
|
-
|
|
84
|
-
if (versionMatch && binaryPresent && !forceReinstall) {
|
|
85
|
-
return; // fast path — venv exists, version matches, no forced reinstall
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Decide what to tell the user
|
|
89
|
-
if (forceReinstall) {
|
|
90
|
-
process.stderr.write(`Forced reinstall requested (BACKPROPAGATE_FORCE_REINSTALL=1).\n`);
|
|
91
|
-
} else if (meta && !versionMatch) {
|
|
92
|
-
process.stderr.write(
|
|
93
|
-
`Updating ${TOOL}: ${meta.version} -> ${VERSION}\n`
|
|
94
|
-
);
|
|
95
|
-
} else if (meta && !binaryPresent) {
|
|
96
|
-
process.stderr.write(
|
|
97
|
-
`Repairing ${TOOL}: binary missing, reinstalling ${VERSION}...\n`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Find system Python
|
|
102
|
-
const python = findPython();
|
|
103
|
-
if (!python) {
|
|
104
|
-
fail(
|
|
105
|
-
"Python 3.10+ is required but not found.",
|
|
106
|
-
"Install Python and try again:\n" +
|
|
107
|
-
" Ubuntu/Debian: sudo apt install python3 python3-venv\n" +
|
|
108
|
-
" Fedora/RHEL: sudo dnf install python3\n" +
|
|
109
|
-
" Arch: sudo pacman -S python\n" +
|
|
110
|
-
" Or use pyenv: https://github.com/pyenv/pyenv"
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Recreate venv on force-reinstall (nuke corrupted state)
|
|
115
|
-
if (forceReinstall && fs.existsSync(venvDir)) {
|
|
116
|
-
process.stderr.write("Removing existing venv...\n");
|
|
117
|
-
fs.rmSync(venvDir, { recursive: true, force: true });
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Create venv if missing
|
|
121
|
-
if (!fs.existsSync(venvPython)) {
|
|
122
|
-
if (!meta) {
|
|
123
|
-
process.stderr.write(
|
|
124
|
-
`First run on Linux: setting up local Python environment for ${TOOL}...\n`
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
fs.mkdirSync(installRoot, { recursive: true });
|
|
128
|
-
const venvResult = spawnSync(python, ["-m", "venv", venvDir], {
|
|
129
|
-
stdio: "inherit",
|
|
130
|
-
});
|
|
131
|
-
if (venvResult.status !== 0) {
|
|
132
|
-
fail(
|
|
133
|
-
"Failed to create Python virtual environment.",
|
|
134
|
-
"The venv module may be missing. Try:\n" +
|
|
135
|
-
" Ubuntu/Debian: sudo apt install python3-venv\n" +
|
|
136
|
-
" Fedora/RHEL: sudo dnf install python3-libs"
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Install or upgrade backpropagate
|
|
142
|
-
// --force-reinstall needed for repair (binary missing but pip metadata intact)
|
|
143
|
-
// and force-reinstall (nuked venv rebuilt). Without it, pip sees the same
|
|
144
|
-
// version in metadata and skips recreating the entrypoint script.
|
|
145
|
-
const needsForce = !binaryPresent || forceReinstall;
|
|
146
|
-
const pipArgs = ["-m", "pip", "install", "--quiet", "--upgrade"];
|
|
147
|
-
if (needsForce) pipArgs.push("--force-reinstall");
|
|
148
|
-
pipArgs.push(`${TOOL}==${VERSION}`);
|
|
149
|
-
|
|
150
|
-
process.stderr.write(`Installing ${TOOL} ${VERSION}${needsForce ? " (force)" : ""}...\n`);
|
|
151
|
-
const pipResult = spawnSync(venvPython, pipArgs, { stdio: "inherit" });
|
|
152
|
-
if (pipResult.status !== 0) {
|
|
153
|
-
fail(
|
|
154
|
-
`pip install failed (exit ${pipResult.status}).`,
|
|
155
|
-
"Check your network connection and try again.\n" +
|
|
156
|
-
"You can also install manually:\n" +
|
|
157
|
-
` pip install ${TOOL}==${VERSION}`
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Verify the binary actually exists after install
|
|
162
|
-
if (!fs.existsSync(venvBin)) {
|
|
163
|
-
fail(
|
|
164
|
-
`Installation completed but ${TOOL} binary not found at expected path.`,
|
|
165
|
-
`Expected: ${venvBin}\n` +
|
|
166
|
-
"Try installing manually:\n" +
|
|
167
|
-
` pipx install ${TOOL}`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Record metadata
|
|
172
|
-
writeMeta({
|
|
173
|
-
version: VERSION,
|
|
174
|
-
installedAt: new Date().toISOString(),
|
|
175
|
-
python,
|
|
176
|
-
venvDir,
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
process.stderr.write("Ready.\n");
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// -- exec -----------------------------------------------------------------
|
|
183
|
-
|
|
184
|
-
bootstrap();
|
|
185
|
-
const result = spawnSync(venvBin, process.argv.slice(2), { stdio: "inherit" });
|
|
186
|
-
if (result.error) {
|
|
187
|
-
fail(`Failed to execute ${TOOL}: ${result.error.message}`);
|
|
188
|
-
}
|
|
189
|
-
process.exit(result.status ?? 1);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// ---------------------------------------------------------------------------
|
|
193
|
-
// macOS + Windows: download and launch prebuilt binary via npm-launcher
|
|
13
|
+
// Rather than ship a broken installer, the npm shim now prints install
|
|
14
|
+
// guidance for the supported channels. The package stays published so this
|
|
15
|
+
// message reaches operators who still have `npm install -g backpropagate`
|
|
16
|
+
// in their tooling.
|
|
17
|
+
//
|
|
18
|
+
// Tracked: D2 SPLIT in the v1.3 brief. Wave 1 landed the friendly-error
|
|
19
|
+
// hotfix; Wave 3.5 deleted .github/workflows/release-binaries.yml; Wave 6a
|
|
20
|
+
// removed the PyInstaller .spec files at the repo root and added the v1.2.x
|
|
21
|
+
// → v1.3 handbook migration page that walks operators from the
|
|
22
|
+
// pre-deprecation `npm install -g backpropagate` install line to the
|
|
23
|
+
// supported channels. The migration is complete in v1.3.
|
|
194
24
|
// ---------------------------------------------------------------------------
|
|
195
25
|
|
|
196
|
-
process.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
26
|
+
process.stderr.write(
|
|
27
|
+
"npm distribution of backpropagate is deprecated.\n" +
|
|
28
|
+
"\n" +
|
|
29
|
+
"Install via one of the supported channels:\n" +
|
|
30
|
+
" pipx install backpropagate (recommended — isolated venv)\n" +
|
|
31
|
+
" uv tool install backpropagate\n" +
|
|
32
|
+
" pip install backpropagate\n" +
|
|
33
|
+
"\n" +
|
|
34
|
+
"Optional extras (UI / GGUF export / monitoring) are documented at:\n" +
|
|
35
|
+
" https://github.com/mcp-tool-shop-org/backpropagate#installation\n"
|
|
36
|
+
);
|
|
37
|
+
process.exit(2);
|
package/package.json
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcptoolshop/backpropagate",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Deprecated npm distribution shim for backpropagate — prints install guidance for pipx/uv tool/pip. See https://github.com/mcp-tool-shop-org/backpropagate",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": { "node": ">=20" },
|
|
8
|
-
"dependencies": {
|
|
9
|
-
"@mcptoolshop/npm-launcher": "^1.0.0"
|
|
10
|
-
},
|
|
11
8
|
"bin": {
|
|
12
9
|
"backpropagate": "bin/backpropagate.js"
|
|
13
10
|
},
|