lopebase 0.6.2 → 0.6.4
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/dist/lopebase.js +286 -278
- package/package.json +1 -1
package/dist/lopebase.js
CHANGED
|
@@ -14,7 +14,7 @@ var __toESMCache_node, __toESMCache_esm, __toESM = (mod, isNodeMode, target) =>
|
|
|
14
14
|
return cached;
|
|
15
15
|
}
|
|
16
16
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
17
|
-
let to = isNodeMode || !mod || !mod.__esModule
|
|
17
|
+
let to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target;
|
|
18
18
|
if (mod && typeof mod === "object" || typeof mod === "function") {
|
|
19
19
|
for (let key of __getOwnPropNames(mod))
|
|
20
20
|
if (!__hasOwnProp.call(to, key))
|
|
@@ -157,8 +157,8 @@ var require_windows = __commonJS(function(exports, module) {
|
|
|
157
157
|
if (pathext = pathext.split(";"), pathext.indexOf("") !== -1)
|
|
158
158
|
return !0;
|
|
159
159
|
for (var i = 0;i < pathext.length; i++) {
|
|
160
|
-
var
|
|
161
|
-
if (
|
|
160
|
+
var p2 = pathext[i].toLowerCase();
|
|
161
|
+
if (p2 && path.substr(-p2.length).toLowerCase() === p2)
|
|
162
162
|
return !0;
|
|
163
163
|
}
|
|
164
164
|
return !1;
|
|
@@ -195,7 +195,7 @@ var require_mode = __commonJS(function(exports, module) {
|
|
|
195
195
|
return stat.isFile() && checkMode(stat, options);
|
|
196
196
|
}
|
|
197
197
|
function checkMode(stat, options) {
|
|
198
|
-
var { mode: mod, uid, gid } = stat, myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid(), myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid(),
|
|
198
|
+
var { mode: mod, uid, gid } = stat, myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid(), myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid(), u2 = parseInt("100", 8), g2 = parseInt("010", 8), o2 = parseInt("001", 8), ug = u2 | g2, ret = mod & o2 || mod & g2 && gid === myGid || mod & u2 && uid === myUid || mod & ug && myUid === 0;
|
|
199
199
|
return ret;
|
|
200
200
|
}
|
|
201
201
|
});
|
|
@@ -268,19 +268,19 @@ var require_which = __commonJS(function(exports, module) {
|
|
|
268
268
|
let { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt), found = [], step = (i) => new Promise((resolve, reject) => {
|
|
269
269
|
if (i === pathEnv.length)
|
|
270
270
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
271
|
-
let ppRaw = pathEnv[i], pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw, pCmd = path.join(pathPart, cmd),
|
|
272
|
-
resolve(subStep(
|
|
273
|
-
}), subStep = (
|
|
271
|
+
let ppRaw = pathEnv[i], pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw, pCmd = path.join(pathPart, cmd), p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
272
|
+
resolve(subStep(p2, i, 0));
|
|
273
|
+
}), subStep = (p2, i, ii) => new Promise((resolve, reject) => {
|
|
274
274
|
if (ii === pathExt.length)
|
|
275
275
|
return resolve(step(i + 1));
|
|
276
276
|
let ext = pathExt[ii];
|
|
277
|
-
isexe(
|
|
277
|
+
isexe(p2 + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
278
278
|
if (!er && is)
|
|
279
279
|
if (opt.all)
|
|
280
|
-
found.push(
|
|
280
|
+
found.push(p2 + ext);
|
|
281
281
|
else
|
|
282
|
-
return resolve(
|
|
283
|
-
return resolve(subStep(
|
|
282
|
+
return resolve(p2 + ext);
|
|
283
|
+
return resolve(subStep(p2, i, ii + 1));
|
|
284
284
|
});
|
|
285
285
|
});
|
|
286
286
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -288,9 +288,9 @@ var require_which = __commonJS(function(exports, module) {
|
|
|
288
288
|
opt = opt || {};
|
|
289
289
|
let { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt), found = [];
|
|
290
290
|
for (let i = 0;i < pathEnv.length; i++) {
|
|
291
|
-
let ppRaw = pathEnv[i], pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw, pCmd = path.join(pathPart, cmd),
|
|
292
|
-
for (let
|
|
293
|
-
let cur =
|
|
291
|
+
let ppRaw = pathEnv[i], pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw, pCmd = path.join(pathPart, cmd), p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
292
|
+
for (let j2 = 0;j2 < pathExt.length; j2++) {
|
|
293
|
+
let cur = p2 + pathExt[j2];
|
|
294
294
|
try {
|
|
295
295
|
if (isexe.sync(cur, { pathExt: pathExtExe }))
|
|
296
296
|
if (opt.all)
|
|
@@ -337,7 +337,7 @@ var require_resolveCommand = __commonJS(function(exports, module) {
|
|
|
337
337
|
path: env[getPathKey({ env })],
|
|
338
338
|
pathExt: withoutPathExt ? path.delimiter : void 0
|
|
339
339
|
});
|
|
340
|
-
} catch (
|
|
340
|
+
} catch (e2) {} finally {
|
|
341
341
|
if (shouldSwitchCwd)
|
|
342
342
|
process.chdir(cwd);
|
|
343
343
|
}
|
|
@@ -392,7 +392,7 @@ var require_readShebang = __commonJS(function(exports, module) {
|
|
|
392
392
|
let buffer = Buffer.alloc(150), fd;
|
|
393
393
|
try {
|
|
394
394
|
fd = fs.openSync(command, "r"), fs.readSync(fd, buffer, 0, 150, 0), fs.closeSync(fd);
|
|
395
|
-
} catch (
|
|
395
|
+
} catch (e2) {}
|
|
396
396
|
return shebangCommand(buffer.toString());
|
|
397
397
|
}
|
|
398
398
|
module.exports = readShebang;
|
|
@@ -968,17 +968,17 @@ var V2 = ce(), u = (t, n) => V2 ? t : n, le = u("◆", "*"), L2 = u("■", "x"),
|
|
|
968
968
|
return import_picocolors2.default.green(C);
|
|
969
969
|
}
|
|
970
970
|
}, G2 = (t) => {
|
|
971
|
-
let { cursor: n, options:
|
|
972
|
-
n >=
|
|
973
|
-
let $ = a <
|
|
974
|
-
return
|
|
975
|
-
let
|
|
976
|
-
return
|
|
971
|
+
let { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5)), l2 = 0;
|
|
972
|
+
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
973
|
+
let $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
974
|
+
return r2.slice(l2, l2 + a).map((p2, v2, f) => {
|
|
975
|
+
let j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
|
|
976
|
+
return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
|
|
977
977
|
});
|
|
978
978
|
}, he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
979
979
|
let n = `${import_picocolors2.default.gray(o)}
|
|
980
980
|
${b2(this.state)} ${t.message}
|
|
981
|
-
`,
|
|
981
|
+
`, r2 = t.placeholder ? import_picocolors2.default.inverse(t.placeholder[0]) + import_picocolors2.default.dim(t.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : r2;
|
|
982
982
|
switch (this.state) {
|
|
983
983
|
case "error":
|
|
984
984
|
return `${n.trim()}
|
|
@@ -998,7 +998,7 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
998
998
|
} }).prompt(), ge = (t) => new MD({ validate: t.validate, mask: t.mask ?? $e, render() {
|
|
999
999
|
let n = `${import_picocolors2.default.gray(o)}
|
|
1000
1000
|
${b2(this.state)} ${t.message}
|
|
1001
|
-
`,
|
|
1001
|
+
`, r2 = this.valueWithCursor, i = this.masked;
|
|
1002
1002
|
switch (this.state) {
|
|
1003
1003
|
case "error":
|
|
1004
1004
|
return `${n.trim()}
|
|
@@ -1011,16 +1011,16 @@ ${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(th
|
|
|
1011
1011
|
return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(i ?? ""))}${i ? `
|
|
1012
1012
|
${import_picocolors2.default.gray(o)}` : ""}`;
|
|
1013
1013
|
default:
|
|
1014
|
-
return `${n}${import_picocolors2.default.cyan(o)} ${
|
|
1014
|
+
return `${n}${import_picocolors2.default.cyan(o)} ${r2}
|
|
1015
1015
|
${import_picocolors2.default.cyan(d2)}
|
|
1016
1016
|
`;
|
|
1017
1017
|
}
|
|
1018
1018
|
} }).prompt(), ye = (t) => {
|
|
1019
|
-
let n = t.active ?? "Yes",
|
|
1020
|
-
return new dD({ active: n, inactive:
|
|
1019
|
+
let n = t.active ?? "Yes", r2 = t.inactive ?? "No";
|
|
1020
|
+
return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? !0, render() {
|
|
1021
1021
|
let i = `${import_picocolors2.default.gray(o)}
|
|
1022
1022
|
${b2(this.state)} ${t.message}
|
|
1023
|
-
`, s = this.value ? n :
|
|
1023
|
+
`, s = this.value ? n : r2;
|
|
1024
1024
|
switch (this.state) {
|
|
1025
1025
|
case "submit":
|
|
1026
1026
|
return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
|
|
@@ -1028,19 +1028,19 @@ ${b2(this.state)} ${t.message}
|
|
|
1028
1028
|
return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
|
|
1029
1029
|
${import_picocolors2.default.gray(o)}`;
|
|
1030
1030
|
default:
|
|
1031
|
-
return `${i}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(
|
|
1031
|
+
return `${i}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.green(k2)} ${r2}`}
|
|
1032
1032
|
${import_picocolors2.default.cyan(d2)}
|
|
1033
1033
|
`;
|
|
1034
1034
|
}
|
|
1035
1035
|
} }).prompt();
|
|
1036
1036
|
}, ve = (t) => {
|
|
1037
|
-
let n = (
|
|
1038
|
-
let s =
|
|
1037
|
+
let n = (r2, i) => {
|
|
1038
|
+
let s = r2.label ?? String(r2.value);
|
|
1039
1039
|
switch (i) {
|
|
1040
1040
|
case "selected":
|
|
1041
1041
|
return `${import_picocolors2.default.dim(s)}`;
|
|
1042
1042
|
case "active":
|
|
1043
|
-
return `${import_picocolors2.default.green(k2)} ${s} ${
|
|
1043
|
+
return `${import_picocolors2.default.green(k2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}`;
|
|
1044
1044
|
case "cancelled":
|
|
1045
1045
|
return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}`;
|
|
1046
1046
|
default:
|
|
@@ -1048,17 +1048,17 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
1048
1048
|
}
|
|
1049
1049
|
};
|
|
1050
1050
|
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
1051
|
-
let
|
|
1051
|
+
let r2 = `${import_picocolors2.default.gray(o)}
|
|
1052
1052
|
${b2(this.state)} ${t.message}
|
|
1053
1053
|
`;
|
|
1054
1054
|
switch (this.state) {
|
|
1055
1055
|
case "submit":
|
|
1056
|
-
return `${
|
|
1056
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
1057
1057
|
case "cancel":
|
|
1058
|
-
return `${
|
|
1058
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
1059
1059
|
${import_picocolors2.default.gray(o)}`;
|
|
1060
1060
|
default:
|
|
1061
|
-
return `${
|
|
1061
|
+
return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
|
|
1062
1062
|
${import_picocolors2.default.cyan(o)} `)}
|
|
1063
1063
|
${import_picocolors2.default.cyan(d2)}
|
|
1064
1064
|
`;
|
|
@@ -1066,16 +1066,16 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
1066
1066
|
} }).prompt();
|
|
1067
1067
|
};
|
|
1068
1068
|
var fe = (t) => {
|
|
1069
|
-
let n = (
|
|
1070
|
-
let s =
|
|
1071
|
-
return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${
|
|
1069
|
+
let n = (r2, i) => {
|
|
1070
|
+
let s = r2.label ?? String(r2.value);
|
|
1071
|
+
return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T)} ${import_picocolors2.default.dim(s)} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
|
|
1072
1072
|
};
|
|
1073
|
-
return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? !0, cursorAt: t.cursorAt, validate(
|
|
1074
|
-
if (this.required &&
|
|
1073
|
+
return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? !0, cursorAt: t.cursorAt, validate(r2) {
|
|
1074
|
+
if (this.required && r2.length === 0)
|
|
1075
1075
|
return `Please select at least one option.
|
|
1076
1076
|
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
1077
1077
|
}, render() {
|
|
1078
|
-
let
|
|
1078
|
+
let r2 = `${import_picocolors2.default.gray(o)}
|
|
1079
1079
|
${b2(this.state)} ${t.message}
|
|
1080
1080
|
`, i = (s, c) => {
|
|
1081
1081
|
let a = this.value.includes(s.value);
|
|
@@ -1083,23 +1083,23 @@ ${b2(this.state)} ${t.message}
|
|
|
1083
1083
|
};
|
|
1084
1084
|
switch (this.state) {
|
|
1085
1085
|
case "submit":
|
|
1086
|
-
return `${
|
|
1086
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
1087
1087
|
case "cancel": {
|
|
1088
1088
|
let s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
1089
|
-
return `${
|
|
1089
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
|
|
1090
1090
|
${import_picocolors2.default.gray(o)}` : ""}`;
|
|
1091
1091
|
}
|
|
1092
1092
|
case "error": {
|
|
1093
1093
|
let s = this.error.split(`
|
|
1094
1094
|
`).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
|
|
1095
1095
|
`);
|
|
1096
|
-
return `${
|
|
1096
|
+
return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
1097
1097
|
${import_picocolors2.default.yellow(o)} `)}
|
|
1098
1098
|
${s}
|
|
1099
1099
|
`;
|
|
1100
1100
|
}
|
|
1101
1101
|
default:
|
|
1102
|
-
return `${
|
|
1102
|
+
return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
1103
1103
|
${import_picocolors2.default.cyan(o)} `)}
|
|
1104
1104
|
${import_picocolors2.default.cyan(d2)}
|
|
1105
1105
|
`;
|
|
@@ -1107,13 +1107,13 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
1107
1107
|
} }).prompt();
|
|
1108
1108
|
};
|
|
1109
1109
|
var Me = (t = "", n = "") => {
|
|
1110
|
-
let
|
|
1110
|
+
let r2 = `
|
|
1111
1111
|
${t}
|
|
1112
1112
|
`.split(`
|
|
1113
|
-
`), i = S2(n).length, s = Math.max(
|
|
1114
|
-
let $ = S2(
|
|
1115
|
-
return
|
|
1116
|
-
}, 0), i) + 2, c =
|
|
1113
|
+
`), i = S2(n).length, s = Math.max(r2.reduce((a, l2) => {
|
|
1114
|
+
let $2 = S2(l2);
|
|
1115
|
+
return $2.length > a ? $2.length : a;
|
|
1116
|
+
}, 0), i) + 2, c = r2.map((a) => `${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(a)}${" ".repeat(s - S2(a).length)}${import_picocolors2.default.gray(o)}`).join(`
|
|
1117
1117
|
`);
|
|
1118
1118
|
process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
1119
1119
|
${import_picocolors2.default.green(C)} ${import_picocolors2.default.reset(n)} ${import_picocolors2.default.gray(_2.repeat(Math.max(s - i - 1, 1)) + me)}
|
|
@@ -1133,13 +1133,13 @@ ${import_picocolors2.default.gray(d2)} ${t}
|
|
|
1133
1133
|
|
|
1134
1134
|
`);
|
|
1135
1135
|
}, M2 = { message: (t = "", { symbol: n = import_picocolors2.default.gray(o) } = {}) => {
|
|
1136
|
-
let
|
|
1136
|
+
let r2 = [`${import_picocolors2.default.gray(o)}`];
|
|
1137
1137
|
if (t) {
|
|
1138
1138
|
let [i, ...s] = t.split(`
|
|
1139
1139
|
`);
|
|
1140
|
-
|
|
1140
|
+
r2.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors2.default.gray(o)} ${c}`));
|
|
1141
1141
|
}
|
|
1142
|
-
process.stdout.write(`${
|
|
1142
|
+
process.stdout.write(`${r2.join(`
|
|
1143
1143
|
`)}
|
|
1144
1144
|
`);
|
|
1145
1145
|
}, info: (t) => {
|
|
@@ -1156,57 +1156,65 @@ ${import_picocolors2.default.gray(d2)} ${t}
|
|
|
1156
1156
|
M2.message(t, { symbol: import_picocolors2.default.red(K2) });
|
|
1157
1157
|
} }, J2 = `${import_picocolors2.default.gray(o)} `;
|
|
1158
1158
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
1159
|
-
let n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
|
|
1160
|
-
let
|
|
1161
|
-
a &&
|
|
1162
|
-
},
|
|
1163
|
-
process.on("uncaughtExceptionMonitor",
|
|
1159
|
+
let n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true", s, c, a = !1, l2 = "", $2, g2 = performance.now(), p2 = (m2) => {
|
|
1160
|
+
let h2 = m2 > 1 ? "Something went wrong" : "Canceled";
|
|
1161
|
+
a && N2(h2, m2);
|
|
1162
|
+
}, v2 = () => p2(2), f = () => p2(1), j2 = () => {
|
|
1163
|
+
process.on("uncaughtExceptionMonitor", v2), process.on("unhandledRejection", v2), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
|
|
1164
1164
|
}, E = () => {
|
|
1165
|
-
process.removeListener("uncaughtExceptionMonitor",
|
|
1166
|
-
},
|
|
1167
|
-
if ($ === void 0)
|
|
1165
|
+
process.removeListener("uncaughtExceptionMonitor", v2), process.removeListener("unhandledRejection", v2), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
|
|
1166
|
+
}, B2 = () => {
|
|
1167
|
+
if ($2 === void 0)
|
|
1168
1168
|
return;
|
|
1169
1169
|
i && process.stdout.write(`
|
|
1170
1170
|
`);
|
|
1171
|
-
let
|
|
1171
|
+
let m2 = $2.split(`
|
|
1172
1172
|
`);
|
|
1173
|
-
process.stdout.write(import_sisteransi2.cursor.move(-999,
|
|
1174
|
-
},
|
|
1175
|
-
let
|
|
1176
|
-
return
|
|
1177
|
-
},
|
|
1178
|
-
a = !0, s = fD(),
|
|
1173
|
+
process.stdout.write(import_sisteransi2.cursor.move(-999, m2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(m2.length));
|
|
1174
|
+
}, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
|
|
1175
|
+
let h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
1176
|
+
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
1177
|
+
}, H2 = (m2 = "") => {
|
|
1178
|
+
a = !0, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
1179
1179
|
`);
|
|
1180
|
-
let
|
|
1181
|
-
|
|
1182
|
-
if (i &&
|
|
1180
|
+
let h2 = 0, w2 = 0;
|
|
1181
|
+
j2(), c = setInterval(() => {
|
|
1182
|
+
if (i && l2 === $2)
|
|
1183
1183
|
return;
|
|
1184
|
-
|
|
1185
|
-
let
|
|
1184
|
+
B2(), $2 = l2;
|
|
1185
|
+
let I2 = import_picocolors2.default.magenta(n[h2]);
|
|
1186
1186
|
if (i)
|
|
1187
|
-
process.stdout.write(`${
|
|
1187
|
+
process.stdout.write(`${I2} ${l2}...`);
|
|
1188
1188
|
else if (t === "timer")
|
|
1189
|
-
process.stdout.write(`${
|
|
1189
|
+
process.stdout.write(`${I2} ${l2} ${O2(g2)}`);
|
|
1190
1190
|
else {
|
|
1191
|
-
let
|
|
1192
|
-
process.stdout.write(`${
|
|
1191
|
+
let z2 = ".".repeat(Math.floor(w2)).slice(0, 3);
|
|
1192
|
+
process.stdout.write(`${I2} ${l2}${z2}`);
|
|
1193
1193
|
}
|
|
1194
|
-
|
|
1195
|
-
},
|
|
1196
|
-
},
|
|
1197
|
-
a = !1, clearInterval(c),
|
|
1198
|
-
let
|
|
1199
|
-
|
|
1200
|
-
`) : process.stdout.write(`${
|
|
1194
|
+
h2 = h2 + 1 < n.length ? h2 + 1 : 0, w2 = w2 < n.length ? w2 + 0.125 : 0;
|
|
1195
|
+
}, r2);
|
|
1196
|
+
}, N2 = (m2 = "", h2 = 0) => {
|
|
1197
|
+
a = !1, clearInterval(c), B2();
|
|
1198
|
+
let w2 = h2 === 0 ? import_picocolors2.default.green(C) : h2 === 1 ? import_picocolors2.default.red(L2) : import_picocolors2.default.red(W2);
|
|
1199
|
+
l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
|
|
1200
|
+
`) : process.stdout.write(`${w2} ${l2}
|
|
1201
1201
|
`), E(), s();
|
|
1202
1202
|
};
|
|
1203
|
-
return { start:
|
|
1204
|
-
|
|
1203
|
+
return { start: H2, stop: N2, message: (m2 = "") => {
|
|
1204
|
+
l2 = R2(m2 ?? l2);
|
|
1205
1205
|
} };
|
|
1206
1206
|
};
|
|
1207
1207
|
|
|
1208
1208
|
// ../admin-adapter/src/releases.ts
|
|
1209
|
-
var ADAPTER_VERSION = "0.4.
|
|
1209
|
+
var ADAPTER_VERSION = "0.4.1", ADAPTER_RELEASES = [
|
|
1210
|
+
{
|
|
1211
|
+
version: "0.4.1",
|
|
1212
|
+
date: "2026-10-08",
|
|
1213
|
+
features: [
|
|
1214
|
+
"cachedCheck now keeps a failing result for 10 seconds, not the full 60, so a service that comes back up shows that within seconds."
|
|
1215
|
+
],
|
|
1216
|
+
steps: []
|
|
1217
|
+
},
|
|
1210
1218
|
{
|
|
1211
1219
|
version: "0.4.0",
|
|
1212
1220
|
date: "2026-10-08",
|
|
@@ -1265,29 +1273,29 @@ var ADAPTER_VERSION = "0.4.0", ADAPTER_RELEASES = [
|
|
|
1265
1273
|
steps: []
|
|
1266
1274
|
}
|
|
1267
1275
|
];
|
|
1268
|
-
function compareVersions(a,
|
|
1269
|
-
let parts = (
|
|
1270
|
-
if (
|
|
1271
|
-
return
|
|
1272
|
-
if (
|
|
1276
|
+
function compareVersions(a, b3) {
|
|
1277
|
+
let parts = (v2) => (v2.match(/^\D*(\d+)\.(\d+)\.(\d+)/) ?? []).slice(1).map(Number), [x2, y3] = [parts(a), parts(b3)];
|
|
1278
|
+
if (x2.length !== 3)
|
|
1279
|
+
return y3.length === 3 ? -1 : 0;
|
|
1280
|
+
if (y3.length !== 3)
|
|
1273
1281
|
return 1;
|
|
1274
1282
|
for (let i = 0;i < 3; i++)
|
|
1275
|
-
if (
|
|
1276
|
-
return
|
|
1283
|
+
if (x2[i] !== y3[i])
|
|
1284
|
+
return x2[i] < y3[i] ? -1 : 1;
|
|
1277
1285
|
return 0;
|
|
1278
1286
|
}
|
|
1279
1287
|
function releasesSince(version) {
|
|
1280
|
-
return ADAPTER_RELEASES.filter((
|
|
1288
|
+
return ADAPTER_RELEASES.filter((r2) => !version || compareVersions(r2.version, version) > 0).reverse();
|
|
1281
1289
|
}
|
|
1282
1290
|
function upgradePrompt(fromVersion) {
|
|
1283
|
-
let todo = releasesSince(fromVersion), breaking = todo.flatMap((
|
|
1291
|
+
let todo = releasesSince(fromVersion), breaking = todo.flatMap((r2) => r2.breaking ?? []), steps = todo.flatMap((r2) => r2.steps);
|
|
1284
1292
|
return [
|
|
1285
|
-
`Update this app's LopeBase adapter (@lopebase/adapter) from ${fromVersion ?? "its current version"} to 0.4.
|
|
1293
|
+
`Update this app's LopeBase adapter (@lopebase/adapter) from ${fromVersion ?? "its current version"} to 0.4.1.`,
|
|
1286
1294
|
"",
|
|
1287
1295
|
"1. Install it with this repo's package manager, for example `npm install @lopebase/adapter@latest`. A 0.x range like ^0.1.2 does not pick up 0.2 or later on its own.",
|
|
1288
1296
|
...breaking.length ? [
|
|
1289
1297
|
"2. These changes would stop the adapter from starting; handle each one:",
|
|
1290
|
-
...breaking.map((
|
|
1298
|
+
...breaking.map((b3) => ` - ${b3}`)
|
|
1291
1299
|
] : ["2. Nothing in this update stops an existing adapter from starting."],
|
|
1292
1300
|
...steps.length ? [
|
|
1293
1301
|
"3. Adopt what is new, asking the human before each change:",
|
|
@@ -1303,7 +1311,7 @@ function upgradePrompt(fromVersion) {
|
|
|
1303
1311
|
var SIGNATURE_HEADER = "lopebase-signature";
|
|
1304
1312
|
var enc = /* @__PURE__ */ new TextEncoder;
|
|
1305
1313
|
function hex(bytes) {
|
|
1306
|
-
return [...new Uint8Array(bytes)].map((
|
|
1314
|
+
return [...new Uint8Array(bytes)].map((b3) => b3.toString(16).padStart(2, "0")).join("");
|
|
1307
1315
|
}
|
|
1308
1316
|
async function sha256Hex(data) {
|
|
1309
1317
|
return hex(await crypto.subtle.digest("SHA-256", data));
|
|
@@ -1314,8 +1322,8 @@ async function hmacHex(secret, message) {
|
|
|
1314
1322
|
}
|
|
1315
1323
|
function newSigningSecret() {
|
|
1316
1324
|
let bytes = crypto.getRandomValues(new Uint8Array(32)), bin = "";
|
|
1317
|
-
for (let
|
|
1318
|
-
bin += String.fromCharCode(
|
|
1325
|
+
for (let b3 of bytes)
|
|
1326
|
+
bin += String.fromCharCode(b3);
|
|
1319
1327
|
return "lbs_" + btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1320
1328
|
}
|
|
1321
1329
|
function payload(t, method, pathAndQuery, bodyHash) {
|
|
@@ -1352,7 +1360,7 @@ var SENSITIVE_PARTS = /* @__PURE__ */ new Set([
|
|
|
1352
1360
|
]), SENSITIVE_JOINED = /apikey|privatekey|secretkey|accesskey|accountnumber|routingnumber|stripecustomer|paymentmethod|recoverycode/;
|
|
1353
1361
|
function isSensitiveFieldName(name) {
|
|
1354
1362
|
let parts = name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
1355
|
-
if (parts.some((
|
|
1363
|
+
if (parts.some((p2) => SENSITIVE_PARTS.has(p2)))
|
|
1356
1364
|
return !0;
|
|
1357
1365
|
return SENSITIVE_JOINED.test(parts.join(""));
|
|
1358
1366
|
}
|
|
@@ -1371,12 +1379,12 @@ function conformanceChecks(opts) {
|
|
|
1371
1379
|
let remote = !opts.adapter, base = opts.baseUrl ? opts.baseUrl.replace(/\/$/, "") : `${opts.origin ?? "https://property.test"}${(opts.basePath ?? opts.adapter?.config.basePath ?? DEFAULT_BASE_PATH).replace(/\/$/, "")}`, send = (req) => opts.adapter ? opts.adapter.handle(req) : fetch(req);
|
|
1372
1380
|
async function signedHeaders(url, method, bodyText, timestamp) {
|
|
1373
1381
|
if (opts.secret) {
|
|
1374
|
-
let
|
|
1382
|
+
let u2 = new URL(url);
|
|
1375
1383
|
return {
|
|
1376
1384
|
[SIGNATURE_HEADER]: await signRequest({
|
|
1377
1385
|
secret: opts.secret,
|
|
1378
1386
|
method,
|
|
1379
|
-
pathAndQuery:
|
|
1387
|
+
pathAndQuery: u2.pathname + u2.search,
|
|
1380
1388
|
body: bodyText,
|
|
1381
1389
|
timestamp
|
|
1382
1390
|
})
|
|
@@ -1394,14 +1402,14 @@ function conformanceChecks(opts) {
|
|
|
1394
1402
|
...init?.headers
|
|
1395
1403
|
}
|
|
1396
1404
|
}));
|
|
1397
|
-
}, resources = () => authed("/resources").then((
|
|
1405
|
+
}, resources = () => authed("/resources").then((r2) => body(r2)), checks = [
|
|
1398
1406
|
{
|
|
1399
1407
|
name: "GET /health returns { ok } without auth",
|
|
1400
1408
|
async run() {
|
|
1401
1409
|
let res = await send(new Request(`${base}/health`));
|
|
1402
1410
|
assert.equal(res.status, 200);
|
|
1403
|
-
let
|
|
1404
|
-
assert.equal(typeof
|
|
1411
|
+
let b3 = await body(res);
|
|
1412
|
+
assert.equal(typeof b3.ok, "boolean");
|
|
1405
1413
|
}
|
|
1406
1414
|
},
|
|
1407
1415
|
{
|
|
@@ -1416,10 +1424,10 @@ function conformanceChecks(opts) {
|
|
|
1416
1424
|
async run() {
|
|
1417
1425
|
let res = await authed("/resources");
|
|
1418
1426
|
assert.equal(res.status, 200);
|
|
1419
|
-
let
|
|
1420
|
-
assert.ok(Array.isArray(
|
|
1421
|
-
for (let
|
|
1422
|
-
assert.ok(
|
|
1427
|
+
let b3 = await body(res);
|
|
1428
|
+
assert.ok(Array.isArray(b3.resources));
|
|
1429
|
+
for (let r2 of b3.resources)
|
|
1430
|
+
assert.ok(r2.name && r2.label && r2.readCapability), assert.ok(Array.isArray(r2.fields));
|
|
1423
1431
|
}
|
|
1424
1432
|
},
|
|
1425
1433
|
{
|
|
@@ -1427,9 +1435,9 @@ function conformanceChecks(opts) {
|
|
|
1427
1435
|
async run() {
|
|
1428
1436
|
let res = await authed("/actions");
|
|
1429
1437
|
assert.equal(res.status, 200);
|
|
1430
|
-
let
|
|
1431
|
-
assert.ok(Array.isArray(
|
|
1432
|
-
for (let a of
|
|
1438
|
+
let b3 = await body(res);
|
|
1439
|
+
assert.ok(Array.isArray(b3.actions));
|
|
1440
|
+
for (let a of b3.actions)
|
|
1433
1441
|
assert.ok(a.name && a.label && a.capability), assert.ok(Array.isArray(a.params));
|
|
1434
1442
|
}
|
|
1435
1443
|
},
|
|
@@ -1448,7 +1456,7 @@ function conformanceChecks(opts) {
|
|
|
1448
1456
|
{
|
|
1449
1457
|
name: "GET /resources/:name/:id returns a row or 404-null",
|
|
1450
1458
|
async run() {
|
|
1451
|
-
let cat = await resources(), meta = opts.sampleResource ? cat.resources.find((
|
|
1459
|
+
let cat = await resources(), meta = opts.sampleResource ? cat.resources.find((r2) => r2.name === opts.sampleResource) : cat.resources[0];
|
|
1452
1460
|
if (!meta)
|
|
1453
1461
|
return;
|
|
1454
1462
|
let first = (await body(await authed(`/resources/${meta.name}?limit=1`))).rows[0];
|
|
@@ -1463,8 +1471,8 @@ function conformanceChecks(opts) {
|
|
|
1463
1471
|
async run() {
|
|
1464
1472
|
let res = await authed("/audit");
|
|
1465
1473
|
assert.equal(res.status, 200);
|
|
1466
|
-
let
|
|
1467
|
-
assert.ok(Array.isArray(
|
|
1474
|
+
let b3 = await body(res);
|
|
1475
|
+
assert.ok(Array.isArray(b3.rows));
|
|
1468
1476
|
}
|
|
1469
1477
|
},
|
|
1470
1478
|
{
|
|
@@ -1478,24 +1486,24 @@ function conformanceChecks(opts) {
|
|
|
1478
1486
|
name: "no field in the catalog looks like a secret unless marked safe",
|
|
1479
1487
|
async run() {
|
|
1480
1488
|
let cat = await resources();
|
|
1481
|
-
for (let
|
|
1482
|
-
for (let f of
|
|
1483
|
-
assert.ok(!isSensitiveFieldName(f.name) || f.sensitive === "allow", `${
|
|
1489
|
+
for (let r2 of cat.resources)
|
|
1490
|
+
for (let f of r2.fields)
|
|
1491
|
+
assert.ok(!isSensitiveFieldName(f.name) || f.sensitive === "allow", `${r2.name}.${f.name} looks sensitive`);
|
|
1484
1492
|
}
|
|
1485
1493
|
},
|
|
1486
1494
|
{
|
|
1487
1495
|
name: "rows contain only declared fields, and a page is at most 100",
|
|
1488
1496
|
async run() {
|
|
1489
1497
|
let cat = await resources();
|
|
1490
|
-
for (let
|
|
1491
|
-
let res = await authed(`/resources/${
|
|
1498
|
+
for (let r2 of cat.resources) {
|
|
1499
|
+
let res = await authed(`/resources/${r2.name}?limit=1000`);
|
|
1492
1500
|
assert.equal(res.status, 200);
|
|
1493
1501
|
let page = await body(res);
|
|
1494
|
-
assert.ok(page.rows.length <= 100, `${
|
|
1495
|
-
let declared = /* @__PURE__ */ new Set(["id", ...
|
|
1502
|
+
assert.ok(page.rows.length <= 100, `${r2.name} returned ${page.rows.length} rows`);
|
|
1503
|
+
let declared = /* @__PURE__ */ new Set(["id", ...r2.fields.map((f) => f.name)]);
|
|
1496
1504
|
for (let row of page.rows)
|
|
1497
|
-
for (let
|
|
1498
|
-
assert.ok(declared.has(
|
|
1505
|
+
for (let k3 of Object.keys(row))
|
|
1506
|
+
assert.ok(declared.has(k3), `${r2.name} returned undeclared field ${k3}`);
|
|
1499
1507
|
}
|
|
1500
1508
|
}
|
|
1501
1509
|
},
|
|
@@ -1513,7 +1521,7 @@ function conformanceChecks(opts) {
|
|
|
1513
1521
|
{
|
|
1514
1522
|
name: "a mutation writes an audit row (PATCH round-trips into /audit)",
|
|
1515
1523
|
async run() {
|
|
1516
|
-
let writable = (await resources()).resources.find((
|
|
1524
|
+
let writable = (await resources()).resources.find((r2) => r2.writeCapability && r2.fields.some((f) => f.editable));
|
|
1517
1525
|
if (!writable || remote)
|
|
1518
1526
|
return;
|
|
1519
1527
|
let row = (await body(await authed(`/resources/${writable.name}?limit=1`))).rows[0];
|
|
@@ -1549,8 +1557,8 @@ async function checkAdapter(input) {
|
|
|
1549
1557
|
})
|
|
1550
1558
|
} : { authorization: `Bearer ${input.token ?? ""}` };
|
|
1551
1559
|
status = (await fetch(url, { headers })).status;
|
|
1552
|
-
} catch (
|
|
1553
|
-
let error = `Could not reach ${base} (${
|
|
1560
|
+
} catch (e2) {
|
|
1561
|
+
let error = `Could not reach ${base} (${e2 instanceof Error ? e2.message : String(e2)}).`;
|
|
1554
1562
|
return log(`FAIL ${error}`), { passed, failed: [{ name: "reachable", error }] };
|
|
1555
1563
|
}
|
|
1556
1564
|
if (status === 401) {
|
|
@@ -1568,9 +1576,9 @@ async function checkAdapter(input) {
|
|
|
1568
1576
|
}))
|
|
1569
1577
|
try {
|
|
1570
1578
|
await c.run(), passed++, log(`pass ${c.name}`);
|
|
1571
|
-
} catch (
|
|
1572
|
-
let error =
|
|
1573
|
-
`)[0] : String(
|
|
1579
|
+
} catch (e2) {
|
|
1580
|
+
let error = e2 instanceof Error ? e2.message.split(`
|
|
1581
|
+
`)[0] : String(e2);
|
|
1574
1582
|
failed.push({ name: c.name, error }), log(`FAIL ${c.name}: ${error}`);
|
|
1575
1583
|
}
|
|
1576
1584
|
return { passed, failed };
|
|
@@ -1584,7 +1592,7 @@ var AGENTS = [
|
|
|
1584
1592
|
id: "claude",
|
|
1585
1593
|
label: "Claude Code",
|
|
1586
1594
|
bin: "claude",
|
|
1587
|
-
args: (
|
|
1595
|
+
args: (p2) => [p2],
|
|
1588
1596
|
mcpAdd: (argv) => [
|
|
1589
1597
|
"mcp",
|
|
1590
1598
|
"add",
|
|
@@ -1599,27 +1607,27 @@ var AGENTS = [
|
|
|
1599
1607
|
id: "codex",
|
|
1600
1608
|
label: "Codex",
|
|
1601
1609
|
bin: "codex",
|
|
1602
|
-
args: (
|
|
1610
|
+
args: (p2) => [p2],
|
|
1603
1611
|
mcpAdd: (argv) => ["mcp", "add", "lopebase", "--", ...argv]
|
|
1604
1612
|
},
|
|
1605
1613
|
{
|
|
1606
1614
|
id: "gemini",
|
|
1607
1615
|
label: "Gemini CLI",
|
|
1608
1616
|
bin: "gemini",
|
|
1609
|
-
args: (
|
|
1617
|
+
args: (p2) => ["-i", p2],
|
|
1610
1618
|
mcpAdd: (argv) => ["mcp", "add", "lopebase", ...argv]
|
|
1611
1619
|
},
|
|
1612
1620
|
{
|
|
1613
1621
|
id: "opencode",
|
|
1614
1622
|
label: "opencode",
|
|
1615
1623
|
bin: "opencode",
|
|
1616
|
-
args: (
|
|
1624
|
+
args: (p2) => ["--prompt", p2]
|
|
1617
1625
|
},
|
|
1618
1626
|
{
|
|
1619
1627
|
id: "cursor-agent",
|
|
1620
1628
|
label: "Cursor Agent",
|
|
1621
1629
|
bin: "cursor-agent",
|
|
1622
|
-
args: (
|
|
1630
|
+
args: (p2) => [p2]
|
|
1623
1631
|
}
|
|
1624
1632
|
];
|
|
1625
1633
|
function isInstalled(bin) {
|
|
@@ -1658,17 +1666,17 @@ import os from "node:os";
|
|
|
1658
1666
|
import path from "node:path";
|
|
1659
1667
|
var DEFAULT_URL = "https://app.lopebase.com";
|
|
1660
1668
|
function workspaceUrl(input) {
|
|
1661
|
-
let
|
|
1662
|
-
if (!
|
|
1669
|
+
let v2 = input.trim().replace(/\/+$/, "");
|
|
1670
|
+
if (!v2)
|
|
1663
1671
|
return null;
|
|
1664
|
-
if (/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(
|
|
1665
|
-
return `https://${
|
|
1666
|
-
let withScheme = /^https?:\/\//i.test(
|
|
1672
|
+
if (/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(v2))
|
|
1673
|
+
return `https://${v2.toLowerCase()}.lopebase.com`;
|
|
1674
|
+
let withScheme = /^https?:\/\//i.test(v2) ? v2 : `https://${v2}`;
|
|
1667
1675
|
try {
|
|
1668
|
-
let
|
|
1669
|
-
if (!
|
|
1676
|
+
let u2 = new URL(withScheme);
|
|
1677
|
+
if (!u2.hostname.includes(".") && u2.hostname !== "localhost")
|
|
1670
1678
|
return null;
|
|
1671
|
-
return `${
|
|
1679
|
+
return `${u2.origin}${u2.pathname.replace(/\/+$/, "")}`;
|
|
1672
1680
|
} catch {
|
|
1673
1681
|
return null;
|
|
1674
1682
|
}
|
|
@@ -1718,7 +1726,7 @@ var APP_SIDE_ENV = /^(NEXT_PUBLIC_|PUBLIC_|VITE_|NUXT_PUBLIC_|EXPO_PUBLIC_|REACT
|
|
|
1718
1726
|
function evidenceFor(facts, rule) {
|
|
1719
1727
|
let out = [], weak = [];
|
|
1720
1728
|
for (let re of rule.deps ?? []) {
|
|
1721
|
-
let hit = facts.dependencies.find((
|
|
1729
|
+
let hit = facts.dependencies.find((d3) => re.test(d3));
|
|
1722
1730
|
if (hit)
|
|
1723
1731
|
out.push(`uses ${hit.replace(/^(py|gem|composer|go|cargo):/, "")}`);
|
|
1724
1732
|
}
|
|
@@ -1728,7 +1736,7 @@ function evidenceFor(facts, rule) {
|
|
|
1728
1736
|
out.push(`has ${hit.replace(/#.*$/, "")}`);
|
|
1729
1737
|
}
|
|
1730
1738
|
for (let re of rule.env ?? []) {
|
|
1731
|
-
let hit = facts.envKeys.find((
|
|
1739
|
+
let hit = facts.envKeys.find((k3) => re.test(k3));
|
|
1732
1740
|
if (hit)
|
|
1733
1741
|
(APP_SIDE_ENV.test(hit) ? out : weak).push(`env ${hit}`);
|
|
1734
1742
|
}
|
|
@@ -2310,11 +2318,11 @@ var QUEUES = [
|
|
|
2310
2318
|
[/^py:celery$/, "Job queue (Celery)"],
|
|
2311
2319
|
[/^gem:sidekiq$/, "Job queue (Sidekiq)"]
|
|
2312
2320
|
], NOT_A_SERVICE = /* @__PURE__ */ new Set(["Prisma", "Drizzle"]);
|
|
2313
|
-
function watchList(
|
|
2321
|
+
function watchList(d3, facts) {
|
|
2314
2322
|
let slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""), out = [];
|
|
2315
|
-
if (
|
|
2323
|
+
if (d3.sources.some((s) => s.source === "uptime") || facts.siteUrl)
|
|
2316
2324
|
out.push({ id: "site", label: facts.siteUrl ?? "Website", how: "address" });
|
|
2317
|
-
for (let s of
|
|
2325
|
+
for (let s of d3.stack)
|
|
2318
2326
|
if (s.kind === "database" && !NOT_A_SERVICE.has(s.name))
|
|
2319
2327
|
out.push({ id: slug(s.name), label: s.name, how: "service" });
|
|
2320
2328
|
for (let [re, label] of QUEUES)
|
|
@@ -2324,7 +2332,7 @@ function watchList(d, facts) {
|
|
|
2324
2332
|
label,
|
|
2325
2333
|
how: "service"
|
|
2326
2334
|
});
|
|
2327
|
-
let email =
|
|
2335
|
+
let email = d3.stack.find((s) => s.kind === "email" && s.name !== "Nodemailer");
|
|
2328
2336
|
if (email)
|
|
2329
2337
|
out.push({
|
|
2330
2338
|
id: "email",
|
|
@@ -2332,7 +2340,7 @@ function watchList(d, facts) {
|
|
|
2332
2340
|
how: "service"
|
|
2333
2341
|
});
|
|
2334
2342
|
let seen = /* @__PURE__ */ new Set;
|
|
2335
|
-
return out.filter((
|
|
2343
|
+
return out.filter((w2) => !seen.has(w2.id) && seen.add(w2.id));
|
|
2336
2344
|
}
|
|
2337
2345
|
|
|
2338
2346
|
// src/device-login.ts
|
|
@@ -2349,27 +2357,27 @@ async function startDeviceLogin(url, opts = {}) {
|
|
|
2349
2357
|
});
|
|
2350
2358
|
if (!res.ok)
|
|
2351
2359
|
return null;
|
|
2352
|
-
let
|
|
2353
|
-
if (typeof
|
|
2360
|
+
let b3 = await res.json();
|
|
2361
|
+
if (typeof b3.device_code !== "string" || typeof b3.user_code !== "string")
|
|
2354
2362
|
return null;
|
|
2355
2363
|
return {
|
|
2356
|
-
deviceCode:
|
|
2357
|
-
userCode:
|
|
2358
|
-
verifyUrl: String(
|
|
2359
|
-
interval: Number(
|
|
2360
|
-
expiresIn: Number(
|
|
2364
|
+
deviceCode: b3.device_code,
|
|
2365
|
+
userCode: b3.user_code,
|
|
2366
|
+
verifyUrl: String(b3.verification_uri_complete ?? b3.verification_uri),
|
|
2367
|
+
interval: Number(b3.interval) || 5,
|
|
2368
|
+
expiresIn: Number(b3.expires_in) || 600
|
|
2361
2369
|
};
|
|
2362
2370
|
} catch {
|
|
2363
2371
|
return null;
|
|
2364
2372
|
}
|
|
2365
2373
|
}
|
|
2366
2374
|
async function pollDeviceLogin(url, start, opts = {}) {
|
|
2367
|
-
let f = opts.fetchImpl ?? fetch, sleep = opts.sleep ?? ((ms) => new Promise((
|
|
2375
|
+
let f = opts.fetchImpl ?? fetch, sleep = opts.sleep ?? ((ms) => new Promise((r2) => setTimeout(r2, ms))), interval = start.interval, deadline = Date.now() + start.expiresIn * 1000;
|
|
2368
2376
|
while (Date.now() < deadline) {
|
|
2369
2377
|
await sleep(interval * 1000);
|
|
2370
|
-
let
|
|
2378
|
+
let body2;
|
|
2371
2379
|
try {
|
|
2372
|
-
|
|
2380
|
+
body2 = await (await f(`${url}/api/oauth/token`, {
|
|
2373
2381
|
method: "POST",
|
|
2374
2382
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
2375
2383
|
body: new URLSearchParams({
|
|
@@ -2380,14 +2388,14 @@ async function pollDeviceLogin(url, start, opts = {}) {
|
|
|
2380
2388
|
} catch {
|
|
2381
2389
|
continue;
|
|
2382
2390
|
}
|
|
2383
|
-
if (typeof
|
|
2391
|
+
if (typeof body2.access_token === "string")
|
|
2384
2392
|
return {
|
|
2385
2393
|
ok: !0,
|
|
2386
|
-
token:
|
|
2387
|
-
url: typeof
|
|
2388
|
-
scope: String(
|
|
2394
|
+
token: body2.access_token,
|
|
2395
|
+
url: typeof body2.workspace_url === "string" ? body2.workspace_url : url,
|
|
2396
|
+
scope: String(body2.scope ?? "")
|
|
2389
2397
|
};
|
|
2390
|
-
switch (
|
|
2398
|
+
switch (body2.error) {
|
|
2391
2399
|
case "authorization_pending":
|
|
2392
2400
|
continue;
|
|
2393
2401
|
case "slow_down":
|
|
@@ -2409,7 +2417,7 @@ async function pollDeviceLogin(url, start, opts = {}) {
|
|
|
2409
2417
|
return {
|
|
2410
2418
|
ok: !1,
|
|
2411
2419
|
reason: "error",
|
|
2412
|
-
message: String(
|
|
2420
|
+
message: String(body2.error_description ?? body2.error ?? "Sign-in failed.")
|
|
2413
2421
|
};
|
|
2414
2422
|
}
|
|
2415
2423
|
}
|
|
@@ -2478,7 +2486,7 @@ async function runMcpProxy(auth, fetchImpl = fetch) {
|
|
|
2478
2486
|
}
|
|
2479
2487
|
process.stdout.write(`${text}
|
|
2480
2488
|
`);
|
|
2481
|
-
} catch (
|
|
2489
|
+
} catch (e2) {
|
|
2482
2490
|
if (id === null)
|
|
2483
2491
|
return;
|
|
2484
2492
|
write({
|
|
@@ -2486,7 +2494,7 @@ async function runMcpProxy(auth, fetchImpl = fetch) {
|
|
|
2486
2494
|
id,
|
|
2487
2495
|
error: {
|
|
2488
2496
|
code: -32000,
|
|
2489
|
-
message: `Could not reach LopeBase at ${endpoint}: ${String(
|
|
2497
|
+
message: `Could not reach LopeBase at ${endpoint}: ${String(e2)}`
|
|
2490
2498
|
}
|
|
2491
2499
|
});
|
|
2492
2500
|
}
|
|
@@ -2504,7 +2512,7 @@ function onboardingPrompt(input) {
|
|
|
2504
2512
|
`- Stack: ${stack}`,
|
|
2505
2513
|
`- Already in use: ${found.map((s) => s.label).join(", ") || "none of the sources LopeBase reads"}`,
|
|
2506
2514
|
`- The human wants connected: ${chosen.join(", ") || "whatever get_onboarding_status recommends"}`,
|
|
2507
|
-
`- Worth watching for uptime: ${(input.watch ?? []).map((
|
|
2515
|
+
`- Worth watching for uptime: ${(input.watch ?? []).map((w2) => `${w2.label} (${w2.how === "address" ? "uptime check on its address" : "adapter health service"})`).join(", ") || "the site, if it has one"}`,
|
|
2508
2516
|
`- LopeBase pageviews: ${input.pageviews ? "yes, the human wants them" : "not chosen; offer once, do not push"}`,
|
|
2509
2517
|
"",
|
|
2510
2518
|
"How to work:",
|
|
@@ -2578,15 +2586,15 @@ var MONOREPO_DIRS = ["apps", "packages", "services", "sites", "web", "site"], SK
|
|
|
2578
2586
|
".github/workflows",
|
|
2579
2587
|
"content/config.ts"
|
|
2580
2588
|
], EXAMPLE_ENV = /^(\.env\.(example|sample|template|dist|local\.example|development\.example|production\.example)|example\.env|\.dev\.vars\.example)$/;
|
|
2581
|
-
function readText(
|
|
2589
|
+
function readText(file2) {
|
|
2582
2590
|
try {
|
|
2583
|
-
return readFileSync2(
|
|
2591
|
+
return readFileSync2(file2, "utf8");
|
|
2584
2592
|
} catch {
|
|
2585
2593
|
return null;
|
|
2586
2594
|
}
|
|
2587
2595
|
}
|
|
2588
|
-
function readJson(
|
|
2589
|
-
let text = readText(
|
|
2596
|
+
function readJson(file2) {
|
|
2597
|
+
let text = readText(file2);
|
|
2590
2598
|
if (text === null)
|
|
2591
2599
|
return null;
|
|
2592
2600
|
try {
|
|
@@ -2595,9 +2603,9 @@ function readJson(file) {
|
|
|
2595
2603
|
return null;
|
|
2596
2604
|
}
|
|
2597
2605
|
}
|
|
2598
|
-
function isDir(
|
|
2606
|
+
function isDir(p2) {
|
|
2599
2607
|
try {
|
|
2600
|
-
return statSync(
|
|
2608
|
+
return statSync(p2).isDirectory();
|
|
2601
2609
|
} catch {
|
|
2602
2610
|
return !1;
|
|
2603
2611
|
}
|
|
@@ -2622,14 +2630,14 @@ function isPackage(dir) {
|
|
|
2622
2630
|
}
|
|
2623
2631
|
function workspaceGlobs(root) {
|
|
2624
2632
|
let globs = [], ws = readJson(path2.join(root, "package.json"))?.workspaces, list = Array.isArray(ws) ? ws : ws && typeof ws === "object" && Array.isArray(ws.packages) ? ws.packages : [];
|
|
2625
|
-
for (let
|
|
2626
|
-
if (typeof
|
|
2627
|
-
globs.push(
|
|
2633
|
+
for (let g2 of list)
|
|
2634
|
+
if (typeof g2 === "string")
|
|
2635
|
+
globs.push(g2);
|
|
2628
2636
|
let pnpm = readText(path2.join(root, "pnpm-workspace.yaml"));
|
|
2629
2637
|
if (pnpm)
|
|
2630
|
-
for (let
|
|
2631
|
-
globs.push(
|
|
2632
|
-
return globs.filter((
|
|
2638
|
+
for (let m2 of pnpm.matchAll(/^\s*-\s*["']?([^"'\s#]+)["']?/gm))
|
|
2639
|
+
globs.push(m2[1]);
|
|
2640
|
+
return globs.filter((g2) => !g2.startsWith("!"));
|
|
2633
2641
|
}
|
|
2634
2642
|
function expandGlob(root, glob) {
|
|
2635
2643
|
let clean = glob.replace(/\/\*\*$/, "/*").replace(/\/$/, "");
|
|
@@ -2638,24 +2646,24 @@ function expandGlob(root, glob) {
|
|
|
2638
2646
|
return isDir(dir) ? [dir] : [];
|
|
2639
2647
|
}
|
|
2640
2648
|
let [base] = clean.split("*"), parent = path2.join(root, base);
|
|
2641
|
-
return listDir(parent).filter((
|
|
2649
|
+
return listDir(parent).filter((e2) => !SKIP_DIRS.has(e2) && !e2.startsWith(".")).map((e2) => path2.join(parent, e2)).filter(isDir);
|
|
2642
2650
|
}
|
|
2643
2651
|
function packageDirs(root) {
|
|
2644
2652
|
let dirs = /* @__PURE__ */ new Set([root]);
|
|
2645
|
-
for (let
|
|
2646
|
-
for (let
|
|
2647
|
-
if (isPackage(
|
|
2648
|
-
dirs.add(
|
|
2653
|
+
for (let g2 of workspaceGlobs(root))
|
|
2654
|
+
for (let d3 of expandGlob(root, g2))
|
|
2655
|
+
if (isPackage(d3))
|
|
2656
|
+
dirs.add(d3);
|
|
2649
2657
|
for (let group of MONOREPO_DIRS) {
|
|
2650
|
-
let
|
|
2651
|
-
if (!isDir(
|
|
2658
|
+
let g2 = path2.join(root, group);
|
|
2659
|
+
if (!isDir(g2))
|
|
2652
2660
|
continue;
|
|
2653
|
-
if (isPackage(
|
|
2654
|
-
dirs.add(
|
|
2655
|
-
for (let entry of listDir(
|
|
2656
|
-
let
|
|
2657
|
-
if (!SKIP_DIRS.has(entry) && isDir(
|
|
2658
|
-
dirs.add(
|
|
2661
|
+
if (isPackage(g2))
|
|
2662
|
+
dirs.add(g2);
|
|
2663
|
+
for (let entry of listDir(g2)) {
|
|
2664
|
+
let d3 = path2.join(g2, entry);
|
|
2665
|
+
if (!SKIP_DIRS.has(entry) && isDir(d3) && isPackage(d3))
|
|
2666
|
+
dirs.add(d3);
|
|
2659
2667
|
}
|
|
2660
2668
|
}
|
|
2661
2669
|
return [...dirs].slice(0, MAX_PACKAGES);
|
|
@@ -2663,36 +2671,36 @@ function packageDirs(root) {
|
|
|
2663
2671
|
function pythonRequirements(text) {
|
|
2664
2672
|
let out = [];
|
|
2665
2673
|
for (let line of text.split(/\r?\n/)) {
|
|
2666
|
-
let
|
|
2667
|
-
if (
|
|
2668
|
-
out.push(
|
|
2674
|
+
let m2 = /^\s*([A-Za-z0-9][A-Za-z0-9._-]*)/.exec(line.replace(/#.*/, ""));
|
|
2675
|
+
if (m2 && !line.trim().startsWith("-"))
|
|
2676
|
+
out.push(m2[1].toLowerCase());
|
|
2669
2677
|
}
|
|
2670
2678
|
return out;
|
|
2671
2679
|
}
|
|
2672
2680
|
function pythonProjectDeps(text) {
|
|
2673
2681
|
let out = /* @__PURE__ */ new Set;
|
|
2674
2682
|
for (let block of text.matchAll(/(?:^|\n)\s*dependencies\s*=\s*\[([\s\S]*?)\]/g))
|
|
2675
|
-
for (let
|
|
2676
|
-
out.add(
|
|
2683
|
+
for (let m2 of block[1].matchAll(/["']([A-Za-z0-9][A-Za-z0-9._-]*)/g))
|
|
2684
|
+
out.add(m2[1].toLowerCase());
|
|
2677
2685
|
for (let table of text.matchAll(/\[(?:tool\.poetry\.(?:group\.[a-z]+\.)?dependencies|(?:dev-)?packages)\]([\s\S]*?)(?=\n\[|$)/g))
|
|
2678
|
-
for (let
|
|
2679
|
-
out.add(
|
|
2686
|
+
for (let m2 of table[1].matchAll(/^\s*([A-Za-z0-9][A-Za-z0-9._-]*)\s*=/gm))
|
|
2687
|
+
out.add(m2[1].toLowerCase());
|
|
2680
2688
|
return out.delete("python"), [...out];
|
|
2681
2689
|
}
|
|
2682
2690
|
function gemfileDeps(text) {
|
|
2683
|
-
return [...text.matchAll(/^\s*gem\s+["']([^"']+)["']/gm)].map((
|
|
2691
|
+
return [...text.matchAll(/^\s*gem\s+["']([^"']+)["']/gm)].map((m2) => m2[1]);
|
|
2684
2692
|
}
|
|
2685
2693
|
function goModDeps(text) {
|
|
2686
2694
|
let out = [];
|
|
2687
|
-
for (let
|
|
2688
|
-
out.push(
|
|
2695
|
+
for (let m2 of text.matchAll(/^\s*(?:require\s+)?([a-z0-9.-]+\.[a-z]+\/[^\s]+)\s+v[0-9]/gm))
|
|
2696
|
+
out.push(m2[1]);
|
|
2689
2697
|
return out;
|
|
2690
2698
|
}
|
|
2691
2699
|
function cargoDeps(text) {
|
|
2692
2700
|
let out = [];
|
|
2693
2701
|
for (let table of text.matchAll(/\[(?:dev-|build-)?dependencies\]([\s\S]*?)(?=\n\[|$)/g))
|
|
2694
|
-
for (let
|
|
2695
|
-
out.push(
|
|
2702
|
+
for (let m2 of table[1].matchAll(/^\s*([A-Za-z0-9_-]+)\s*=/gm))
|
|
2703
|
+
out.push(m2[1]);
|
|
2696
2704
|
return out;
|
|
2697
2705
|
}
|
|
2698
2706
|
function manifestDeps(dir) {
|
|
@@ -2711,10 +2719,10 @@ function manifestDeps(dir) {
|
|
|
2711
2719
|
if (gem)
|
|
2712
2720
|
add("gem", gemfileDeps(gem));
|
|
2713
2721
|
let composer = readJson(path2.join(dir, "composer.json"));
|
|
2714
|
-
for (let
|
|
2715
|
-
let
|
|
2716
|
-
if (
|
|
2717
|
-
add("composer", Object.keys(
|
|
2722
|
+
for (let k3 of ["require", "require-dev"]) {
|
|
2723
|
+
let d3 = composer?.[k3];
|
|
2724
|
+
if (d3 && typeof d3 === "object")
|
|
2725
|
+
add("composer", Object.keys(d3));
|
|
2718
2726
|
}
|
|
2719
2727
|
let gomod = readText(path2.join(dir, "go.mod"));
|
|
2720
2728
|
if (gomod)
|
|
@@ -2728,7 +2736,7 @@ function siteFromWrangler(text) {
|
|
|
2728
2736
|
let first = [
|
|
2729
2737
|
...text.matchAll(/(?:pattern|route)["']?\s*[:=]\s*["']([^"'*/\s]+)/g),
|
|
2730
2738
|
...text.matchAll(/custom_domain["']?\s*[:=]\s*["']([^"'*/\s]+)/g)
|
|
2731
|
-
].map((
|
|
2739
|
+
].map((m2) => m2[1].toLowerCase()).filter((h2) => h2.includes(".") && !h2.endsWith("workers.dev"))[0];
|
|
2732
2740
|
if (!first)
|
|
2733
2741
|
return;
|
|
2734
2742
|
return `https://${first.replace(/^(app|www|api|console)\./, "")}`;
|
|
@@ -2736,26 +2744,26 @@ function siteFromWrangler(text) {
|
|
|
2736
2744
|
var NOT_A_SITE = /(^|\.)(localhost|example\.(com|org)|your-?(site|domain)\.[a-z]+|vercel\.app|netlify\.app|pages\.dev|workers\.dev|github\.com|gitlab\.com|npmjs\.com)$/;
|
|
2737
2745
|
function publicSite(url) {
|
|
2738
2746
|
try {
|
|
2739
|
-
let
|
|
2740
|
-
if (!
|
|
2747
|
+
let u2 = new URL(url.startsWith("http") ? url : `https://${url}`);
|
|
2748
|
+
if (!u2.hostname.includes(".") || NOT_A_SITE.test(u2.hostname))
|
|
2741
2749
|
return;
|
|
2742
|
-
return `https://${
|
|
2750
|
+
return `https://${u2.hostname.replace(/^www\./, "")}`;
|
|
2743
2751
|
} catch {
|
|
2744
2752
|
return;
|
|
2745
2753
|
}
|
|
2746
2754
|
}
|
|
2747
2755
|
function siteFromConfig(text) {
|
|
2748
|
-
let
|
|
2749
|
-
return
|
|
2756
|
+
let m2 = /\b(?:site|siteUrl|baseURL|baseUrl|url)\s*[:=]\s*["'`](https?:\/\/[^"'`\s]+)["'`]/.exec(text);
|
|
2757
|
+
return m2 ? publicSite(m2[1]) : void 0;
|
|
2750
2758
|
}
|
|
2751
2759
|
function githubRepo(gitConfig) {
|
|
2752
2760
|
let remotes = [
|
|
2753
2761
|
...gitConfig.matchAll(/\[remote "([^"]+)"\][^[]*?url\s*=\s*(\S+)/g)
|
|
2754
|
-
].sort((a,
|
|
2762
|
+
].sort((a, b3) => Number(b3[1] === "origin") - Number(a[1] === "origin"));
|
|
2755
2763
|
for (let [, , url] of remotes) {
|
|
2756
|
-
let
|
|
2757
|
-
if (
|
|
2758
|
-
return `${
|
|
2764
|
+
let m2 = /github\.com[:/]([\w.-]+)\/([\w.-]+?)(?:\.git)?\/?$/.exec(url);
|
|
2765
|
+
if (m2)
|
|
2766
|
+
return `${m2[1]}/${m2[2]}`;
|
|
2759
2767
|
}
|
|
2760
2768
|
return;
|
|
2761
2769
|
}
|
|
@@ -2770,21 +2778,21 @@ function readGitConfig(root) {
|
|
|
2770
2778
|
return readText(path2.join(gitDir, "config")) ?? readText(path2.join(gitDir, "..", "..", "config"));
|
|
2771
2779
|
}
|
|
2772
2780
|
function siteFromHtml(html) {
|
|
2773
|
-
let
|
|
2774
|
-
return
|
|
2781
|
+
let m2 = /<link[^>]+rel=["']canonical["'][^>]+href=["'](https?:\/\/[^"']+)/i.exec(html) ?? /<link[^>]+href=["'](https?:\/\/[^"']+)["'][^>]+rel=["']canonical["']/i.exec(html) ?? /<meta[^>]+property=["']og:url["'][^>]+content=["'](https?:\/\/[^"']+)/i.exec(html);
|
|
2782
|
+
return m2 ? publicSite(m2[1]) : void 0;
|
|
2775
2783
|
}
|
|
2776
2784
|
function envKeyNames(text) {
|
|
2777
2785
|
let out = [];
|
|
2778
2786
|
for (let line of text.split(/\r?\n/)) {
|
|
2779
|
-
let
|
|
2780
|
-
if (
|
|
2781
|
-
out.push(
|
|
2787
|
+
let m2 = /^\s*(?:#\s*)?(?:export\s+)?([A-Z][A-Z0-9_]*)\s*=/.exec(line);
|
|
2788
|
+
if (m2)
|
|
2789
|
+
out.push(m2[1]);
|
|
2782
2790
|
}
|
|
2783
2791
|
return out;
|
|
2784
2792
|
}
|
|
2785
2793
|
var SITE_CONFIGS = /^(astro\.config\.\w+|next-sitemap\.config\.\w+|gatsby-config\.\w+|docusaurus\.config\.\w+|hugo\.toml|config\.toml|_config\.ya?ml|nuxt\.config\.\w+)$/;
|
|
2786
2794
|
function scanProject(root, onProgress) {
|
|
2787
|
-
let deps = /* @__PURE__ */ new Set, files = /* @__PURE__ */ new Set, envKeys = /* @__PURE__ */ new Set, name, siteUrl, dirs = packageDirs(root), relDir = (
|
|
2795
|
+
let deps = /* @__PURE__ */ new Set, files = /* @__PURE__ */ new Set, envKeys = /* @__PURE__ */ new Set, name, siteUrl, dirs = packageDirs(root), relDir = (d3) => path2.relative(root, d3).split(path2.sep).join("/") || ".";
|
|
2788
2796
|
onProgress?.({
|
|
2789
2797
|
label: `Found ${dirs.length} ${dirs.length === 1 ? "package" : "packages"}`,
|
|
2790
2798
|
detail: dirs.length > 1 ? dirs.map(relDir).join(", ") : void 0
|
|
@@ -2797,22 +2805,22 @@ function scanProject(root, onProgress) {
|
|
|
2797
2805
|
name = pkg.name;
|
|
2798
2806
|
if (!siteUrl && typeof pkg.homepage === "string")
|
|
2799
2807
|
siteUrl = publicSite(pkg.homepage);
|
|
2800
|
-
for (let
|
|
2801
|
-
let
|
|
2802
|
-
if (
|
|
2803
|
-
for (let n of Object.keys(
|
|
2808
|
+
for (let k3 of ["dependencies", "devDependencies"]) {
|
|
2809
|
+
let d3 = pkg[k3];
|
|
2810
|
+
if (d3 && typeof d3 === "object")
|
|
2811
|
+
for (let n of Object.keys(d3))
|
|
2804
2812
|
deps.add(n);
|
|
2805
2813
|
}
|
|
2806
2814
|
}
|
|
2807
|
-
for (let
|
|
2808
|
-
deps.add(
|
|
2815
|
+
for (let d3 of manifestDeps(dir))
|
|
2816
|
+
deps.add(d3);
|
|
2809
2817
|
for (let entry of listDir(dir)) {
|
|
2810
2818
|
if (EXAMPLE_ENV.test(entry)) {
|
|
2811
2819
|
let text = readText(path2.join(dir, entry));
|
|
2812
2820
|
if (text) {
|
|
2813
2821
|
envFiles++;
|
|
2814
|
-
for (let
|
|
2815
|
-
envKeys.add(
|
|
2822
|
+
for (let k3 of envKeyNames(text))
|
|
2823
|
+
envKeys.add(k3);
|
|
2816
2824
|
}
|
|
2817
2825
|
}
|
|
2818
2826
|
if (!MARKERS.some((re) => re.test(entry)))
|
|
@@ -2883,8 +2891,8 @@ function paint(rgb, text, bg = !1) {
|
|
|
2883
2891
|
return text;
|
|
2884
2892
|
if (!trueColor())
|
|
2885
2893
|
return bg ? import_picocolors3.default.bgMagenta(import_picocolors3.default.black(text)) : import_picocolors3.default.magenta(text);
|
|
2886
|
-
let [
|
|
2887
|
-
return `\x1B[${bg ? 48 : 38};2;${
|
|
2894
|
+
let [r2, g2, b3] = rgb;
|
|
2895
|
+
return `\x1B[${bg ? 48 : 38};2;${r2};${g2};${b3}m${text}\x1B[${bg ? 49 : 39}m`;
|
|
2888
2896
|
}
|
|
2889
2897
|
var brand = (text) => paint(BRAND, text), badge = (text) => paint(BRAND, import_picocolors3.default.black(import_picocolors3.default.bold(` ${text} `)), !0), ramp = (i, text) => paint(RAMP[Math.min(i, RAMP.length - 1)], text), MARK = [
|
|
2890
2898
|
" ▗▖ ▗▖ ",
|
|
@@ -2899,7 +2907,7 @@ var brand = (text) => paint(BRAND, text), badge = (text) => paint(BRAND, import_
|
|
|
2899
2907
|
function motionAllowed(argv = process.argv, env = process.env, isTTY = Boolean(process.stdout.isTTY)) {
|
|
2900
2908
|
return isTTY && !env.CI && !env.LOPEBASE_NO_MOTION && env.TERM !== "dumb" && !argv.includes("--no-motion");
|
|
2901
2909
|
}
|
|
2902
|
-
var sleep = (ms) => new Promise((
|
|
2910
|
+
var sleep = (ms) => new Promise((r2) => setTimeout(r2, ms));
|
|
2903
2911
|
function logoLines(opts) {
|
|
2904
2912
|
let right = {
|
|
2905
2913
|
3: `${import_picocolors3.default.bold("Lope")}${brand("Base")}${opts.version ? import_picocolors3.default.dim(` v${opts.version}`) : ""}`,
|
|
@@ -2920,7 +2928,7 @@ ${lines.join(`
|
|
|
2920
2928
|
`);
|
|
2921
2929
|
return;
|
|
2922
2930
|
}
|
|
2923
|
-
let blank = MARK.map((
|
|
2931
|
+
let blank = MARK.map((r2) => " ".repeat(r2.length)), frame = (shown) => MARK.map((row, i) => shown.has(i) ? HORIZON.has(i) ? import_picocolors3.default.dim(ramp(i, row)) : ramp(i, row) : blank[i]), up = `\x1B[${MARK.length}A`, onInterrupt = () => {
|
|
2924
2932
|
write(`\x1B[?25h
|
|
2925
2933
|
`), process.exit(130);
|
|
2926
2934
|
};
|
|
@@ -2974,8 +2982,8 @@ function stackRows(detection, facts) {
|
|
|
2974
2982
|
rows.push(["Repo", facts.repo]);
|
|
2975
2983
|
if (!rows.length)
|
|
2976
2984
|
return [import_picocolors3.default.dim("Nothing recognized yet. Your agent will look closer.")];
|
|
2977
|
-
let width = Math.max(...rows.map(([
|
|
2978
|
-
return rows.map(([
|
|
2985
|
+
let width = Math.max(...rows.map(([k3]) => k3.length));
|
|
2986
|
+
return rows.map(([k3, v2]) => `${import_picocolors3.default.dim(k3.padEnd(width))} ${v2}`);
|
|
2979
2987
|
}
|
|
2980
2988
|
var PLAN = [
|
|
2981
2989
|
{
|
|
@@ -3000,13 +3008,13 @@ function planLines() {
|
|
|
3000
3008
|
${import_picocolors3.default.dim(s.detail)}`);
|
|
3001
3009
|
}
|
|
3002
3010
|
function stepRail(n, total = PLAN.length) {
|
|
3003
|
-
return Array.from({ length: total }, (
|
|
3011
|
+
return Array.from({ length: total }, (_3, i) => i < n ? brand("◆") : import_picocolors3.default.dim("◇")).join(import_picocolors3.default.dim(" ── "));
|
|
3004
3012
|
}
|
|
3005
3013
|
function stepTitle(n) {
|
|
3006
3014
|
return `${stepRail(n)} ${import_picocolors3.default.dim(`Step ${n} of ${PLAN.length}`)} ${import_picocolors3.default.bold(PLAN[n - 1].title)}`;
|
|
3007
3015
|
}
|
|
3008
3016
|
async function horizon(opts) {
|
|
3009
|
-
let write = opts.write ?? ((s) => process.stdout.write(s)), width = opts.width ?? 28, line = (n) => Array.from({ length: n }, (
|
|
3017
|
+
let write = opts.write ?? ((s) => process.stdout.write(s)), width = opts.width ?? 28, line = (n) => Array.from({ length: n }, (_3, i) => ramp(Math.floor(i / width * RAMP.length), "━")).join("");
|
|
3010
3018
|
if (!opts.motion) {
|
|
3011
3019
|
write(` ${line(width)}
|
|
3012
3020
|
`);
|
|
@@ -3018,15 +3026,15 @@ async function horizon(opts) {
|
|
|
3018
3026
|
`);
|
|
3019
3027
|
}
|
|
3020
3028
|
function watchRows(items) {
|
|
3021
|
-
return items.map((
|
|
3029
|
+
return items.map((w2) => w2.how === "address" ? `${brand("◉")} ${import_picocolors3.default.bold(w2.label)} ${import_picocolors3.default.dim("uptime check, every 15 minutes")}` : `${brand("○")} ${import_picocolors3.default.bold(w2.label)} ${import_picocolors3.default.dim("a service in the adapter's health list")}`);
|
|
3022
3030
|
}
|
|
3023
3031
|
|
|
3024
3032
|
// src/update.ts
|
|
3025
3033
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
3026
3034
|
import path3 from "node:path";
|
|
3027
|
-
var readJson2 = (
|
|
3035
|
+
var readJson2 = (file2) => {
|
|
3028
3036
|
try {
|
|
3029
|
-
return JSON.parse(readFileSync3(
|
|
3037
|
+
return JSON.parse(readFileSync3(file2, "utf8"));
|
|
3030
3038
|
} catch {
|
|
3031
3039
|
return null;
|
|
3032
3040
|
}
|
|
@@ -3043,7 +3051,7 @@ function findAdapterInstalls(root) {
|
|
|
3043
3051
|
}["@lopebase/adapter"];
|
|
3044
3052
|
if (!range || range.startsWith("workspace:"))
|
|
3045
3053
|
continue;
|
|
3046
|
-
let installed = [dir, root].map((
|
|
3054
|
+
let installed = [dir, root].map((d3) => readJson2(path3.join(d3, "node_modules/@lopebase/adapter/package.json"))).find((p2) => typeof p2?.version === "string")?.version;
|
|
3047
3055
|
out.push({ dir: path3.relative(root, dir) || ".", range, installed });
|
|
3048
3056
|
}
|
|
3049
3057
|
return out;
|
|
@@ -3060,8 +3068,8 @@ async function latestOnNpm(name, timeoutMs = 1500, fetchImpl = fetch) {
|
|
|
3060
3068
|
});
|
|
3061
3069
|
if (!res.ok)
|
|
3062
3070
|
return;
|
|
3063
|
-
let
|
|
3064
|
-
return typeof
|
|
3071
|
+
let body2 = await res.json();
|
|
3072
|
+
return typeof body2.version === "string" ? body2.version : void 0;
|
|
3065
3073
|
} catch {
|
|
3066
3074
|
return;
|
|
3067
3075
|
}
|
|
@@ -3127,17 +3135,17 @@ async function checkToken(auth) {
|
|
|
3127
3135
|
jsonrpc: "2.0",
|
|
3128
3136
|
id: 1,
|
|
3129
3137
|
method: "tools/call",
|
|
3130
|
-
params: { name: "
|
|
3138
|
+
params: { name: "list_properties", arguments: {} }
|
|
3131
3139
|
})
|
|
3132
3140
|
});
|
|
3133
3141
|
if (res.status === 401)
|
|
3134
3142
|
return { ok: !1, message: "That token is not valid or has expired." };
|
|
3135
|
-
let
|
|
3136
|
-
return { ok: !0, products: JSON.parse(
|
|
3137
|
-
} catch (
|
|
3143
|
+
let body2 = await res.json();
|
|
3144
|
+
return { ok: !0, products: JSON.parse(body2.result?.content?.[0]?.text ?? "[]").length };
|
|
3145
|
+
} catch (e2) {
|
|
3138
3146
|
return {
|
|
3139
3147
|
ok: !1,
|
|
3140
|
-
message: `Could not reach ${auth.url} (${String(
|
|
3148
|
+
message: `Could not reach ${auth.url} (${String(e2)}).`
|
|
3141
3149
|
};
|
|
3142
3150
|
}
|
|
3143
3151
|
}
|
|
@@ -3165,8 +3173,8 @@ async function login() {
|
|
|
3165
3173
|
s.start("Waiting for you to approve in the browser");
|
|
3166
3174
|
let res = await pollDeviceLogin(url, device);
|
|
3167
3175
|
if (res.ok) {
|
|
3168
|
-
let
|
|
3169
|
-
return s.stop(`Connected to ${import_picocolors4.default.bold(res.url)}. Saved to ${import_picocolors4.default.dim(
|
|
3176
|
+
let file2 = saveAuth({ url: res.url, token: res.token });
|
|
3177
|
+
return s.stop(`Connected to ${import_picocolors4.default.bold(res.url)}. Saved to ${import_picocolors4.default.dim(file2)}`), { url: res.url, token: res.token };
|
|
3170
3178
|
}
|
|
3171
3179
|
if (s.stop(import_picocolors4.default.red(res.message)), res.reason === "denied")
|
|
3172
3180
|
bail("Nothing was connected.");
|
|
@@ -3179,7 +3187,7 @@ async function askWorkspace() {
|
|
|
3179
3187
|
return workspaceUrl(guard(await he({
|
|
3180
3188
|
message: "Your LopeBase workspace (name or address)",
|
|
3181
3189
|
placeholder: "yourteam or https://yourteam.lopebase.com",
|
|
3182
|
-
validate: (
|
|
3190
|
+
validate: (v2) => workspaceUrl(v2 ?? "") ? void 0 : "Type your workspace name, like yourteam, or its full address"
|
|
3183
3191
|
})));
|
|
3184
3192
|
}
|
|
3185
3193
|
async function pasteLogin(url) {
|
|
@@ -3193,33 +3201,33 @@ async function pasteLogin(url) {
|
|
|
3193
3201
|
for (;; ) {
|
|
3194
3202
|
let token = guard(await ge({
|
|
3195
3203
|
message: "Paste the agent token",
|
|
3196
|
-
validate: (
|
|
3204
|
+
validate: (v2) => v2?.startsWith("lb_agent_") ? void 0 : "Tokens start with lb_agent_"
|
|
3197
3205
|
})).trim(), s = Y2();
|
|
3198
3206
|
s.start("Checking the token");
|
|
3199
3207
|
let check = await checkToken({ url, token });
|
|
3200
3208
|
if (check.ok) {
|
|
3201
|
-
let
|
|
3202
|
-
return s.stop(`Signed in. ${check.products}
|
|
3209
|
+
let file2 = saveAuth({ url, token });
|
|
3210
|
+
return s.stop(`Signed in. ${check.products} ${check.products === 1 ? "property" : "properties"} in this workspace. Saved to ${import_picocolors4.default.dim(file2)}`), { url, token };
|
|
3203
3211
|
}
|
|
3204
3212
|
s.stop(import_picocolors4.default.red(check.message ?? "That did not work."));
|
|
3205
3213
|
}
|
|
3206
3214
|
}
|
|
3207
|
-
async function printDetection(
|
|
3208
|
-
Me(stackRows(
|
|
3215
|
+
async function printDetection(d3, facts) {
|
|
3216
|
+
Me(stackRows(d3, facts).join(`
|
|
3209
3217
|
`), "Your stack"), await pace(motion, 150);
|
|
3210
|
-
let found =
|
|
3218
|
+
let found = d3.sources.filter((s) => s.status === "found");
|
|
3211
3219
|
if (found.length)
|
|
3212
3220
|
Me(found.map((s) => `${import_picocolors4.default.green("●")} ${import_picocolors4.default.bold(s.label)} ${import_picocolors4.default.dim(s.evidence.join(", "))}`).join(`
|
|
3213
3221
|
`), "Already in your code, ready to connect"), await pace(motion, 150);
|
|
3214
|
-
let possible =
|
|
3222
|
+
let possible = d3.sources.filter((s) => s.status === "possible");
|
|
3215
3223
|
if (possible.length)
|
|
3216
3224
|
Me(possible.map((s) => `${import_picocolors4.default.yellow("?")} ${import_picocolors4.default.bold(s.label)} ${import_picocolors4.default.dim(`only ${s.evidence.join(", ")}`)}`).join(`
|
|
3217
3225
|
`), "Maybe in use, your agent will check"), await pace(motion, 150);
|
|
3218
|
-
let watch = watchList(
|
|
3226
|
+
let watch = watchList(d3, facts);
|
|
3219
3227
|
if (watch.length)
|
|
3220
3228
|
Me(watchRows(watch).join(`
|
|
3221
3229
|
`), "Worth watching for uptime"), await pace(motion, 150);
|
|
3222
|
-
for (let gap of
|
|
3230
|
+
for (let gap of d3.gaps)
|
|
3223
3231
|
M2.info(import_picocolors4.default.dim(gap));
|
|
3224
3232
|
}
|
|
3225
3233
|
async function scanWithProgress() {
|
|
@@ -3265,7 +3273,7 @@ async function init() {
|
|
|
3265
3273
|
s.start(`Checking your connection to ${auth.url}`);
|
|
3266
3274
|
let check = await checkToken(auth);
|
|
3267
3275
|
if (check.ok)
|
|
3268
|
-
s.stop(`Connected to ${import_picocolors4.default.bold(auth.url)}. ${check.products} ${check.products === 1 ? "
|
|
3276
|
+
s.stop(`Connected to ${import_picocolors4.default.bold(auth.url)}. ${check.products} ${check.products === 1 ? "property" : "properties"} so far.`);
|
|
3269
3277
|
else
|
|
3270
3278
|
s.stop(import_picocolors4.default.yellow("Your saved connection no longer works.")), auth = null;
|
|
3271
3279
|
}
|
|
@@ -3281,7 +3289,7 @@ async function init() {
|
|
|
3281
3289
|
label: src.status === "found" ? src.label : src.status === "possible" ? `${src.label} ${import_picocolors4.default.dim("(maybe in use, we'll check)")}` : `${src.label} ${import_picocolors4.default.dim("(not set up yet, we'll help)")}`,
|
|
3282
3290
|
hint: src.why
|
|
3283
3291
|
})),
|
|
3284
|
-
...watchList(detection, facts).some((
|
|
3292
|
+
...watchList(detection, facts).some((w2) => w2.how === "address") ? [
|
|
3285
3293
|
{
|
|
3286
3294
|
value: PAGEVIEWS,
|
|
3287
3295
|
label: `${PAGEVIEWS} ${import_picocolors4.default.dim("(one tag, no cookies)")}`,
|
|
@@ -3305,7 +3313,7 @@ async function init() {
|
|
|
3305
3313
|
`${import_picocolors4.default.bold(agent)} will now:`,
|
|
3306
3314
|
` ${brand("1.")} add ${import_picocolors4.default.bold(productName || "this product")} to your workspace`,
|
|
3307
3315
|
` ${brand("2.")} connect ${chosen.length ? chosen.join(", ") : "what it recommends"}`,
|
|
3308
|
-
` ${brand("3.")} pick what to watch for uptime: ${watchList(detection, facts).map((
|
|
3316
|
+
` ${brand("3.")} pick what to watch for uptime: ${watchList(detection, facts).map((w2) => w2.label).join(", ") || "the site"}`,
|
|
3309
3317
|
` ${brand("4.")} stop and ask you for any sign-in, key, or yes`,
|
|
3310
3318
|
"",
|
|
3311
3319
|
import_picocolors4.default.dim("You can follow along in your workspace as each one turns green.")
|
|
@@ -3343,7 +3351,7 @@ async function handOff(prompt, plan) {
|
|
|
3343
3351
|
stdio: "inherit",
|
|
3344
3352
|
cwd
|
|
3345
3353
|
});
|
|
3346
|
-
child.on("error", (
|
|
3354
|
+
child.on("error", (e2) => bail(`Could not start ${agent.label}: ${e2.message}`)), child.on("exit", (code) => process.exit(code ?? 0));
|
|
3347
3355
|
}
|
|
3348
3356
|
async function noticeNewerCli() {
|
|
3349
3357
|
let mine = version(), latest = await latestOnNpm("lopebase");
|
|
@@ -3369,11 +3377,11 @@ async function update() {
|
|
|
3369
3377
|
let latest = npmLatest && isBehind(ADAPTER_VERSION, npmLatest) ? npmLatest : ADAPTER_VERSION, behind = installs.filter((i) => isBehind(runningVersion(i), latest));
|
|
3370
3378
|
if (s.stop(installs.map((i) => `${i.dir === "." ? "This folder" : i.dir} runs ${import_picocolors4.default.bold(runningVersion(i))}`).join(", ")), !behind.length)
|
|
3371
3379
|
return Se(`Up to date with ${import_picocolors4.default.bold(latest)}.`);
|
|
3372
|
-
let from = behind.map(runningVersion).sort((a,
|
|
3373
|
-
if (Me(
|
|
3374
|
-
`${brand("◆")} ${import_picocolors4.default.bold(
|
|
3375
|
-
...
|
|
3376
|
-
...(
|
|
3380
|
+
let from = behind.map(runningVersion).sort((a, b3) => isBehind(a, b3) ? -1 : 1)[0], releases2 = releasesSince(from);
|
|
3381
|
+
if (Me(releases2.flatMap((r2) => [
|
|
3382
|
+
`${brand("◆")} ${import_picocolors4.default.bold(r2.version)} ${import_picocolors4.default.dim(r2.date)}`,
|
|
3383
|
+
...r2.features.map((f) => ` ${f}`),
|
|
3384
|
+
...(r2.breaking ?? []).map((b3) => ` ${import_picocolors4.default.yellow("!")} ${b3}`)
|
|
3377
3385
|
]).join(`
|
|
3378
3386
|
`), `New since ${from}`), npmLatest && isBehind(ADAPTER_VERSION, npmLatest))
|
|
3379
3387
|
M2.warn(`npm has ${npmLatest}, newer than these notes. Run ${brand("npx lopebase@latest update")} for its steps.`);
|
|
@@ -3425,7 +3433,7 @@ async function main() {
|
|
|
3425
3433
|
baseUrl: rest[1],
|
|
3426
3434
|
secret,
|
|
3427
3435
|
token: secret ? void 0 : token,
|
|
3428
|
-
log: (
|
|
3436
|
+
log: (l2) => console.log(l2.startsWith("FAIL") ? import_picocolors4.default.red(l2) : import_picocolors4.default.green(l2))
|
|
3429
3437
|
});
|
|
3430
3438
|
console.log(res.failed.length ? import_picocolors4.default.red(`${res.failed.length} failed, ${res.passed} passed`) : import_picocolors4.default.green(`All ${res.passed} checks passed. Ready to connect.`)), process.exit(res.failed.length ? 1 : 0);
|
|
3431
3439
|
}
|