moshcode 0.80.0 → 0.82.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/install.sh +68 -0
- package/package.json +1 -1
- package/src/dns-service.mjs +8 -0
- package/src/dns.mjs +27 -1
package/install.sh
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
# MOSHCODE_BIN=/path/dir wrapper bin dir (default: $HOME/.local/bin)
|
|
24
24
|
# MOSHCODE_REF=vX.Y.Z pin a tag/branch (default: latest release, else main)
|
|
25
25
|
# MOSHCODE_ALLOW_ROOT=1 install as root anyway (see below)
|
|
26
|
+
# MOSHCODE_NO_PROXY=1 skip the pinned-TLS proxy (https:// on a Moshpit
|
|
27
|
+
# name will not verify without it)
|
|
26
28
|
#
|
|
27
29
|
# Do not install this with sudo. moshcode is a user-level CLI, and every path
|
|
28
30
|
# here is derived from $HOME — under sudo that is /root, so the payload and the
|
|
@@ -41,6 +43,8 @@ MOSHCODE_BIN="${MOSHCODE_BIN:-$HOME/.local/bin}"
|
|
|
41
43
|
WRAPPER="$MOSHCODE_BIN/moshcode"
|
|
42
44
|
SCRIPT_WRAPPER="$MOSHCODE_BIN/moshscript"
|
|
43
45
|
|
|
46
|
+
PROXY_INSTALLER="${MOSHCODE_PROXY_INSTALLER:-https://raw.githubusercontent.com/profullstack/moshpit-proxy/main/install.sh}"
|
|
47
|
+
|
|
44
48
|
# ---- pretty output (acid-lime, matching the CLI) --------------------------
|
|
45
49
|
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
|
|
46
50
|
ACID=$(printf '\033[38;2;158;240;26m'); ASH=$(printf '\033[38;2;139;147;138m')
|
|
@@ -51,6 +55,9 @@ fi
|
|
|
51
55
|
info() { printf '%s·%s %s\n' "$ASH" "$RESET" "$*"; }
|
|
52
56
|
ok() { printf '%s✓%s %s\n' "$ACID" "$RESET" "$*"; }
|
|
53
57
|
fail() { printf '%s✗%s %s\n' "$RED" "$RESET" "$*" >&2; exit 1; }
|
|
58
|
+
# Unlike fail(), does not exit: an optional component that did not install is
|
|
59
|
+
# not a reason to leave the CLI half-written.
|
|
60
|
+
warn() { printf '%s!%s %s\n' "$RED" "$RESET" "$*" >&2; }
|
|
54
61
|
|
|
55
62
|
# ---- prerequisites --------------------------------------------------------
|
|
56
63
|
need() { command -v "$1" >/dev/null 2>&1 || fail "$1 is required but not found."; }
|
|
@@ -155,6 +162,66 @@ ensure_path() {
|
|
|
155
162
|
info "add $MOSHCODE_BIN to PATH in this shell: export PATH=\"$MOSHCODE_BIN:\$PATH\""
|
|
156
163
|
}
|
|
157
164
|
|
|
165
|
+
# ---- the pinned-TLS proxy -------------------------------------------------
|
|
166
|
+
# Without this, HTTPS on a Moshpit name cannot work. No public CA will ever sign
|
|
167
|
+
# for `.eggs`, so a name answers its origin's own self-signed leaf and a stock
|
|
168
|
+
# client refuses it — correctly. moshpit-proxy generates one local root and
|
|
169
|
+
# terminates TLS in the one language a browser accepts, which turns "trust this
|
|
170
|
+
# certificate" from a thing you do per name into a thing you do once.
|
|
171
|
+
#
|
|
172
|
+
# Installed here rather than left as a follow-up step because the alternative is
|
|
173
|
+
# `moshcode dns enable` finishing successfully, every name resolving, and every
|
|
174
|
+
# https:// URL still failing — which reads as broken, not as unfinished.
|
|
175
|
+
#
|
|
176
|
+
# This is the one part of the install that touches the system's trust store, so
|
|
177
|
+
# it is the one part with an opt-out: MOSHCODE_NO_PROXY=1 skips it entirely, and
|
|
178
|
+
# `moshpit-proxy install.sh --uninstall` undoes it later. It installs no DNS
|
|
179
|
+
# routing and starts no resolver -- `moshcode dns enable` stays a thing a person
|
|
180
|
+
# types deliberately.
|
|
181
|
+
install_proxy() {
|
|
182
|
+
if [ -n "${MOSHCODE_NO_PROXY:-}" ]; then
|
|
183
|
+
info "skipping the pinned-TLS proxy (MOSHCODE_NO_PROXY is set) — https:// on a Moshpit name will not verify"
|
|
184
|
+
return 0
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
info "installing the pinned-TLS proxy (so https:// on a Moshpit name verifies)"
|
|
188
|
+
|
|
189
|
+
# Downloaded first and run second, rather than `curl … | sh`.
|
|
190
|
+
#
|
|
191
|
+
# A pipeline reports the exit status of its LAST command, and a `sh` handed
|
|
192
|
+
# an empty stdin by a 404 exits 0 — so piping reports a successful install
|
|
193
|
+
# for a script that never arrived. Verified: pointed at a missing URL, the
|
|
194
|
+
# piped form printed "✓ pinned-TLS proxy installed, local root trusted".
|
|
195
|
+
_proxy_sh="$(mktemp 2>/dev/null)" || {
|
|
196
|
+
warn "could not create a temp file for the pinned-TLS proxy installer — skipping"
|
|
197
|
+
return 0
|
|
198
|
+
}
|
|
199
|
+
if ! curl -fsSL "$PROXY_INSTALLER" -o "$_proxy_sh" 2>/dev/null; then
|
|
200
|
+
rm -f "$_proxy_sh"
|
|
201
|
+
warn "could not download the pinned-TLS proxy — moshcode is fine, but https:// on a Moshpit name will not verify"
|
|
202
|
+
warn " retry: curl -fsSL $PROXY_INSTALLER | sh"
|
|
203
|
+
return 0
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
# `--yes` because this installer is normally reached through a pipe, where
|
|
207
|
+
# there is no terminal to answer its prompt on. Announced above rather than
|
|
208
|
+
# asked, and MOSHCODE_NO_PROXY is the opt-out.
|
|
209
|
+
if sh "$_proxy_sh" --yes >/dev/null 2>&1; then
|
|
210
|
+
ok "pinned-TLS proxy installed, local root trusted"
|
|
211
|
+
info " it covers .moshpit by default — for other endings:"
|
|
212
|
+
info " MOSHPIT_PROXY_TLDS=moshpit,eggs,hacker,2600"
|
|
213
|
+
info " undo just this: curl -fsSL $PROXY_INSTALLER | sh -s -- --uninstall"
|
|
214
|
+
else
|
|
215
|
+
# Never fatal. moshcode is a coding CLI first, and a machine that cannot
|
|
216
|
+
# finish an optional component still wants the CLI it asked for. Said out
|
|
217
|
+
# loud so it is not discovered later as a TLS error with no explanation.
|
|
218
|
+
warn "the pinned-TLS proxy did not install — moshcode is fine, but https:// on a Moshpit name will not verify"
|
|
219
|
+
warn " retry: curl -fsSL $PROXY_INSTALLER | sh"
|
|
220
|
+
fi
|
|
221
|
+
rm -f "$_proxy_sh"
|
|
222
|
+
unset _proxy_sh
|
|
223
|
+
}
|
|
224
|
+
|
|
158
225
|
# ---- commands -------------------------------------------------------------
|
|
159
226
|
run_install() {
|
|
160
227
|
printf '\n%smoshcode installer%s %s— code hard, mosh harder 🤘%s\n\n' "$BOLD" "$RESET" "$ASH" "$RESET"
|
|
@@ -165,6 +232,7 @@ run_install() {
|
|
|
165
232
|
fetch_and_unpack "$_ref"
|
|
166
233
|
write_wrapper
|
|
167
234
|
ensure_path
|
|
235
|
+
install_proxy
|
|
168
236
|
printf '\n%sdone.%s run:\n' "$ACID" "$RESET"
|
|
169
237
|
printf ' moshcode # open the TUI shell\n'
|
|
170
238
|
printf ' moshcode start claude # raw engine session (use agents for autonomous)\n'
|
package/package.json
CHANGED
package/src/dns-service.mjs
CHANGED
|
@@ -67,6 +67,7 @@ export function serviceUnit({
|
|
|
67
67
|
port,
|
|
68
68
|
registryBase = null,
|
|
69
69
|
upstreams = [],
|
|
70
|
+
proxy = null,
|
|
70
71
|
user = process.env.USER || process.env.LOGNAME,
|
|
71
72
|
} = {}) {
|
|
72
73
|
if (!entry) throw new Error("serviceUnit needs the entry script to run");
|
|
@@ -80,6 +81,13 @@ export function serviceUnit({
|
|
|
80
81
|
// registry. Recorded here, while a working resolver is still around to be
|
|
81
82
|
// asked, rather than rediscovered at boot when it cannot be.
|
|
82
83
|
if (upstreams.length) args.push("--upstream", upstreams.join(","));
|
|
84
|
+
// Without this the supervised bridge answers every name with its origin, and
|
|
85
|
+
// the origin serves a certificate no CA signed — so `https://` fails on a
|
|
86
|
+
// machine where the pinned-TLS proxy is installed, trusted and running.
|
|
87
|
+
// `dns enable` has always probed for the proxy and passed it through;
|
|
88
|
+
// `dns service` did not, which made a service-managed bridge the one way to
|
|
89
|
+
// run Moshpit where HTTPS could never work.
|
|
90
|
+
if (proxy) args.push("--proxy", proxy);
|
|
83
91
|
const exec = [execPath, ...args].map((part) => (/\s/.test(part) ? JSON.stringify(part) : part)).join(" ");
|
|
84
92
|
|
|
85
93
|
const lines = [
|
package/src/dns.mjs
CHANGED
|
@@ -2788,7 +2788,33 @@ export async function dnsCommand(args = [], out = console.log, deps = {}) {
|
|
|
2788
2788
|
const upstreams = upstreamsFromArgs(rest).servers.length
|
|
2789
2789
|
? upstreamsFromArgs(rest).servers
|
|
2790
2790
|
: await discoverUpstreams();
|
|
2791
|
-
|
|
2791
|
+
// Probed the same way `enable` probes it, and for the same reason: a name
|
|
2792
|
+
// that resolves but cannot complete a TLS handshake reads as broken to the
|
|
2793
|
+
// person who typed the URL. Asked now, while this command can ask; the unit
|
|
2794
|
+
// it writes runs at boot and has no way to find out later.
|
|
2795
|
+
let proxy = null;
|
|
2796
|
+
if (!rest.includes("--no-proxy")) {
|
|
2797
|
+
const claimed = await fetchTlds({ registryBase }).catch(() => []);
|
|
2798
|
+
const probeName = claimed[0] ? `a.${claimed[0]}` : null;
|
|
2799
|
+
if (probeName) {
|
|
2800
|
+
const local = await findLocalProxyImpl(probeName).catch(() => ({ found: false }));
|
|
2801
|
+
if (local.found) proxy = local.address.v4 || local.address.v6;
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
const unit = serviceUnit({ system, entry: cliEntry(), port, registryBase, upstreams, proxy });
|
|
2806
|
+
|
|
2807
|
+
if (proxy) {
|
|
2808
|
+
out(`ok pinned-TLS proxy on ${proxy}:${PROXY_PORT} — names will answer there, so https:// verifies`);
|
|
2809
|
+
out("");
|
|
2810
|
+
} else if (!rest.includes("--no-proxy")) {
|
|
2811
|
+
out("! no pinned-TLS proxy found on this machine");
|
|
2812
|
+
out(" names will answer their origin, and a stock client cannot verify those —");
|
|
2813
|
+
out(" https:// will fail even though the name resolves. Install it with:");
|
|
2814
|
+
out(" curl -fsSL https://raw.githubusercontent.com/profullstack/moshpit-proxy/main/install.sh | sh");
|
|
2815
|
+
out(" then re-run this command so the unit points names at it.");
|
|
2816
|
+
out("");
|
|
2817
|
+
}
|
|
2792
2818
|
|
|
2793
2819
|
if (!upstreams.length) {
|
|
2794
2820
|
out("! no upstream nameservers found, and none given");
|