@maintainer-pro/ai-bridge 0.1.22 → 0.1.23
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/package.json +2 -2
- package/src/daemon.mjs +58 -3
- package/src/share-rewrite.mjs +47 -59
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maintainer-pro/ai-bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "Local bridge daemon that pairs a machine to Maintainer Pro and configures multiple client sandboxes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"maintainer-pro",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=22"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@maintainer-pro/ai-cli": "^0.1.
|
|
31
|
+
"@maintainer-pro/ai-cli": "^0.1.13",
|
|
32
32
|
"@maintainer-pro/ai-server": "^0.1.7"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/daemon.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import os from "node:os";
|
|
|
16
16
|
import path from "node:path";
|
|
17
17
|
import readline from "node:readline";
|
|
18
18
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
19
|
+
import { createRequire } from "node:module";
|
|
19
20
|
import { createLogger, ensureProjectDataDir } from "@maintainer-pro/ai-cli";
|
|
20
21
|
import { findIife, startAiServer } from "@maintainer-pro/ai-server";
|
|
21
22
|
import {
|
|
@@ -39,7 +40,9 @@ import {
|
|
|
39
40
|
} from "./discarded-tunnels.mjs";
|
|
40
41
|
|
|
41
42
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
43
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
42
44
|
const PACKAGE_VERSION = readPackageVersion();
|
|
45
|
+
const PACKAGE_VERSIONS = readPackageVersions();
|
|
43
46
|
const HEARTBEAT_MS = 15_000;
|
|
44
47
|
const WS_PING_MS = 10_000;
|
|
45
48
|
const WS_RECONNECT_MIN_MS = 1_000;
|
|
@@ -157,6 +160,53 @@ function readPackageVersion() {
|
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
162
|
|
|
163
|
+
function readDepPackageVersion(name) {
|
|
164
|
+
const files = [];
|
|
165
|
+
try {
|
|
166
|
+
files.push(requireFromHere.resolve(`${name}/package.json`));
|
|
167
|
+
} catch {
|
|
168
|
+
/* try nested next */
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const serverDir = path.dirname(
|
|
172
|
+
requireFromHere.resolve("@maintainer-pro/ai-server/package.json")
|
|
173
|
+
);
|
|
174
|
+
files.push(path.join(serverDir, "node_modules", name, "package.json"));
|
|
175
|
+
files.push(path.join(serverDir, "..", name.replace("@maintainer-pro/", ""), "package.json"));
|
|
176
|
+
} catch {
|
|
177
|
+
/* ignore */
|
|
178
|
+
}
|
|
179
|
+
for (const file of files) {
|
|
180
|
+
try {
|
|
181
|
+
const pkg = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
182
|
+
if (typeof pkg.version === "string" && pkg.version) return pkg.version;
|
|
183
|
+
} catch {
|
|
184
|
+
/* try next */
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function readPackageVersions() {
|
|
191
|
+
return {
|
|
192
|
+
bridge: PACKAGE_VERSION,
|
|
193
|
+
cli: readDepPackageVersion("@maintainer-pro/ai-cli"),
|
|
194
|
+
server: readDepPackageVersion("@maintainer-pro/ai-server"),
|
|
195
|
+
ui: readDepPackageVersion("@maintainer-pro/ai-ui"),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function formatPackageVersions(versions = PACKAGE_VERSIONS) {
|
|
200
|
+
return [
|
|
201
|
+
versions.bridge && `bridge ${versions.bridge}`,
|
|
202
|
+
versions.cli && `cli ${versions.cli}`,
|
|
203
|
+
versions.server && `server ${versions.server}`,
|
|
204
|
+
versions.ui && `ui ${versions.ui}`,
|
|
205
|
+
]
|
|
206
|
+
.filter(Boolean)
|
|
207
|
+
.join(" · ");
|
|
208
|
+
}
|
|
209
|
+
|
|
160
210
|
async function warnIfBridgeOutdated() {
|
|
161
211
|
const fromWorkspace = path
|
|
162
212
|
.normalize(__dirname)
|
|
@@ -2325,6 +2375,7 @@ function bridgeEmbedConfigJs(ws) {
|
|
|
2325
2375
|
logLevel: "debug",
|
|
2326
2376
|
maintainerProUrl: bridgeCfg?.adminUrl || "",
|
|
2327
2377
|
maintainerProApiKey: String(store.clientKey || "").trim(),
|
|
2378
|
+
versions: PACKAGE_VERSIONS,
|
|
2328
2379
|
};
|
|
2329
2380
|
return `window.__MAINTAINER_PRO__=${JSON.stringify(payload)};`;
|
|
2330
2381
|
}
|
|
@@ -4834,6 +4885,7 @@ async function sendHeartbeat(cfg, folders, localStates) {
|
|
|
4834
4885
|
hostname: os.hostname(),
|
|
4835
4886
|
platform: `${os.platform()}-${os.arch()}`,
|
|
4836
4887
|
bridgeVersion: PACKAGE_VERSION,
|
|
4888
|
+
packageVersions: PACKAGE_VERSIONS,
|
|
4837
4889
|
folders,
|
|
4838
4890
|
issues: await buildIssues(cfg, localStates),
|
|
4839
4891
|
workspaces: localStates.map((st) => ({
|
|
@@ -4866,6 +4918,7 @@ function buildLightHeartbeatPayload(cfg, folders) {
|
|
|
4866
4918
|
hostname: os.hostname(),
|
|
4867
4919
|
platform: `${os.platform()}-${os.arch()}`,
|
|
4868
4920
|
bridgeVersion: PACKAGE_VERSION,
|
|
4921
|
+
packageVersions: PACKAGE_VERSIONS,
|
|
4869
4922
|
folders,
|
|
4870
4923
|
};
|
|
4871
4924
|
}
|
|
@@ -4887,6 +4940,7 @@ async function buildHeartbeatPayload(cfg, folders, localStates) {
|
|
|
4887
4940
|
hostname: os.hostname(),
|
|
4888
4941
|
platform: `${os.platform()}-${os.arch()}`,
|
|
4889
4942
|
bridgeVersion: PACKAGE_VERSION,
|
|
4943
|
+
packageVersions: PACKAGE_VERSIONS,
|
|
4890
4944
|
folders,
|
|
4891
4945
|
issues: await buildIssues(cfg, localStates),
|
|
4892
4946
|
workspaces: localStates.map((st) => ({
|
|
@@ -5021,6 +5075,7 @@ async function pairFlow(args) {
|
|
|
5021
5075
|
hostname: os.hostname(),
|
|
5022
5076
|
platform: `${os.platform()}-${os.arch()}`,
|
|
5023
5077
|
bridgeVersion: PACKAGE_VERSION,
|
|
5078
|
+
packageVersions: PACKAGE_VERSIONS,
|
|
5024
5079
|
name: os.hostname(),
|
|
5025
5080
|
});
|
|
5026
5081
|
|
|
@@ -5048,9 +5103,9 @@ async function main() {
|
|
|
5048
5103
|
process.exit(0);
|
|
5049
5104
|
}
|
|
5050
5105
|
|
|
5051
|
-
logger.
|
|
5052
|
-
{
|
|
5053
|
-
|
|
5106
|
+
logger.info(
|
|
5107
|
+
{ versions: PACKAGE_VERSIONS },
|
|
5108
|
+
`bridge v${PACKAGE_VERSION} starting (${formatPackageVersions()})`
|
|
5054
5109
|
);
|
|
5055
5110
|
void warnIfBridgeOutdated();
|
|
5056
5111
|
|
package/src/share-rewrite.mjs
CHANGED
|
@@ -698,6 +698,19 @@ function isShareAssetPath(path) {
|
|
|
698
698
|
);
|
|
699
699
|
}
|
|
700
700
|
|
|
701
|
+
function rewriteShareAsLocalEnv(body) {
|
|
702
|
+
let out = String(body);
|
|
703
|
+
out = out.replace(
|
|
704
|
+
/(\/\.\*localhost\.\*\/\.test\()([^)]+)(\))/g,
|
|
705
|
+
"($1$2$3||location.pathname.indexOf(\"/p/\")===0)"
|
|
706
|
+
);
|
|
707
|
+
out = out.replace(
|
|
708
|
+
/((?:window\.)?location\.hostname)\s*===\s*(['"])localhost\2/g,
|
|
709
|
+
"($1===$2localhost$2||location.pathname.indexOf(\"/p/\")===0)"
|
|
710
|
+
);
|
|
711
|
+
return out;
|
|
712
|
+
}
|
|
713
|
+
|
|
701
714
|
function prefixQuotedAssetPaths(body, pathPrefix) {
|
|
702
715
|
if (!pathPrefix) return body;
|
|
703
716
|
return String(body).replace(/(["'`])(\/(?!\/)[^"'`]*)/g, (full, q, path) => {
|
|
@@ -844,6 +857,7 @@ function prefixRootPaths(body, publicBase, contentType = "") {
|
|
|
844
857
|
const css = mime === "text/css" || (!isCode && !html && /css/.test(mime));
|
|
845
858
|
if (!html && !css) {
|
|
846
859
|
let code = rewriteViteBaseLiterals(body, pathPrefix);
|
|
860
|
+
code = rewriteShareAsLocalEnv(code);
|
|
847
861
|
code = prefixQuotedAssetPaths(code, pathPrefix);
|
|
848
862
|
code = code.replace(
|
|
849
863
|
/(?<![A-Za-z0-9])\/__nextjs_/g,
|
|
@@ -913,7 +927,7 @@ function isHtmlDocument(headers, body) {
|
|
|
913
927
|
|
|
914
928
|
function isScriptRequestPath(path) {
|
|
915
929
|
const p = String(path || "").split("?")[0]?.toLowerCase() || "";
|
|
916
|
-
return /\.(?:m?
|
|
930
|
+
return /\.(?:m?[jt]sx?|cjs)$/.test(p);
|
|
917
931
|
}
|
|
918
932
|
|
|
919
933
|
function isScriptOrJsonBody(headers, path) {
|
|
@@ -1098,42 +1112,28 @@ function shareProxyShim(p, portMap, rewriteMappedLocalUrls) {
|
|
|
1098
1112
|
if (typeof v !== "string" || !v) return v;
|
|
1099
1113
|
var mapped = mapLocal(v);
|
|
1100
1114
|
if (mapped !== v) return mapped;
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
try {
|
|
1107
|
-
if (/^(https?:|wss?:)\/\//i.test(v)) {
|
|
1108
|
-
abs = new URL(v);
|
|
1109
|
-
var host = String(abs.hostname || "")
|
|
1110
|
-
.replace(/^\[|\]$/g, "")
|
|
1111
|
-
.toLowerCase();
|
|
1112
|
-
if (!loopback(host) && host !== String(location.hostname || "").toLowerCase()) {
|
|
1113
|
-
return v;
|
|
1114
|
-
}
|
|
1115
|
-
path = abs.pathname || "/";
|
|
1116
|
-
search = abs.search || "";
|
|
1117
|
-
hash = abs.hash || "";
|
|
1118
|
-
} else if (v.charAt(0) === "/" && v.charAt(1) !== "/") {
|
|
1119
|
-
var rel = new URL(v, location.href);
|
|
1120
|
-
path = rel.pathname || "/";
|
|
1121
|
-
search = rel.search || "";
|
|
1122
|
-
hash = rel.hash || "";
|
|
1123
|
-
} else {
|
|
1124
|
-
return addNav(v);
|
|
1125
|
-
}
|
|
1126
|
-
} catch (e) {
|
|
1127
|
-
return addNav(v);
|
|
1115
|
+
if (/^(https?:|wss?:)\/\//i.test(v)) {
|
|
1116
|
+
try {
|
|
1117
|
+
var abs = new URL(v);
|
|
1118
|
+
if (!loopback(abs.hostname)) return v;
|
|
1119
|
+
} catch (e) {}
|
|
1128
1120
|
}
|
|
1129
|
-
if (
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
if (
|
|
1136
|
-
|
|
1121
|
+
if (v.charAt(0) === "/" && v.charAt(1) !== "/") {
|
|
1122
|
+
var backend = backendBase();
|
|
1123
|
+
var path = v.split("?")[0];
|
|
1124
|
+
if (path === "/api/v1" || path.indexOf("/api/v1/") === 0 || path.indexOf("/p/") === 0) {
|
|
1125
|
+
return v;
|
|
1126
|
+
}
|
|
1127
|
+
if (
|
|
1128
|
+
backend &&
|
|
1129
|
+
!isAsset(path) &&
|
|
1130
|
+
(/^\/sreo(?:\/|$)/i.test(path) || /^\/api(?:\/|$)/i.test(path))
|
|
1131
|
+
) {
|
|
1132
|
+
try {
|
|
1133
|
+
var rel = new URL(v, location.href);
|
|
1134
|
+
return backend + rel.pathname + rel.search + rel.hash;
|
|
1135
|
+
} catch (e) {}
|
|
1136
|
+
}
|
|
1137
1137
|
}
|
|
1138
1138
|
return addNav(v);
|
|
1139
1139
|
}
|
|
@@ -1355,34 +1355,22 @@ function shareServiceWorkerMain(portMap, tokenRoot, rewriteMappedLocalUrls) {
|
|
|
1355
1355
|
function prefixWith(url, prefix) {
|
|
1356
1356
|
if (!prefix) return url;
|
|
1357
1357
|
try {
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
.replace(/^\[|\]$/g, "")
|
|
1362
|
-
.toLowerCase();
|
|
1363
|
-
var pageHost = String(self.location.hostname || "")
|
|
1364
|
-
.replace(/^\[|\]$/g, "")
|
|
1365
|
-
.toLowerCase();
|
|
1366
|
-
if (/^(https?:|wss?:)\/\//i.test(url) && !loopback(host) && host !== pageHost) {
|
|
1367
|
-
return url;
|
|
1358
|
+
if (/^(https?:|wss?:)\/\//i.test(url)) {
|
|
1359
|
+
var abs = new URL(url);
|
|
1360
|
+
if (!loopback(abs.hostname)) return url;
|
|
1368
1361
|
}
|
|
1369
|
-
var
|
|
1362
|
+
var u = new URL(url, self.location.href);
|
|
1363
|
+
var path = u.pathname || "/";
|
|
1364
|
+
var backend = backendBase();
|
|
1370
1365
|
if (path === "/api/v1" || path.indexOf("/api/v1/") === 0) return url;
|
|
1371
1366
|
if (path.indexOf("/p/") === 0) return url;
|
|
1372
1367
|
if (
|
|
1373
1368
|
backend &&
|
|
1374
|
-
|
|
1375
|
-
path
|
|
1376
|
-
!/\/(?:_next\/|__nextjs_|@vite(?:\/|$)|@react-refresh(?:\/|$)|@fs\/|@id\/|node_modules\/)/.test(
|
|
1377
|
-
path
|
|
1378
|
-
) &&
|
|
1379
|
-
!/\.(?:m?[jt]sx?|cjs|mjs|css|scss|sass|less|map|wasm|vue|svelte)$/i.test(path)
|
|
1369
|
+
!/^(https?:|wss?:)\/\//i.test(url) &&
|
|
1370
|
+
(/^\/sreo(?:\/|$)/i.test(path) || /^\/api(?:\/|$)/i.test(path))
|
|
1380
1371
|
) {
|
|
1381
|
-
|
|
1382
|
-
if (/^ws/i.test(parsed.protocol)) dest = dest.replace(/^http/i, "ws");
|
|
1383
|
-
return dest;
|
|
1372
|
+
return backend + path + (u.search || "") + (u.hash || "");
|
|
1384
1373
|
}
|
|
1385
|
-
var u = parsed;
|
|
1386
1374
|
if (u.origin !== self.location.origin) return url;
|
|
1387
1375
|
if (u.pathname === "/" || u.pathname === "") return url;
|
|
1388
1376
|
if (u.pathname === prefix || u.pathname.indexOf(prefix + "/") === 0) return url;
|
|
@@ -1550,14 +1538,14 @@ export function processShareHttpResponse(opts) {
|
|
|
1550
1538
|
text = prefixRootPaths(text, publicBase, headers["content-type"] || "");
|
|
1551
1539
|
mutated = true;
|
|
1552
1540
|
}
|
|
1553
|
-
if (Object.keys(portUrls).length && rewriteTextBody) {
|
|
1541
|
+
if (Object.keys(portUrls).length && rewriteTextBody && !isScriptOrJsonBody(headers, path)) {
|
|
1554
1542
|
const mapped = rewriteMappedLocalUrls(text, portUrls);
|
|
1555
1543
|
if (mapped !== text) {
|
|
1556
1544
|
text = mapped;
|
|
1557
1545
|
mutated = true;
|
|
1558
1546
|
}
|
|
1559
1547
|
}
|
|
1560
|
-
if (publicBase && rewriteTextBody) {
|
|
1548
|
+
if (publicBase && rewriteTextBody && !isScriptOrJsonBody(headers, path)) {
|
|
1561
1549
|
const prefixed = rewriteShareOriginPaths(text, publicBase, portUrls);
|
|
1562
1550
|
if (prefixed !== text) {
|
|
1563
1551
|
text = prefixed;
|