Add Object B and self-growth canons with Cursor ledger rules; refresh connectivity and VPN runbooks.

Track day metrics/anamnesis HARD rules under .cursor/rules and personal docs so each screening updates days/{KIN}, dynamics, and big-data ledger.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ahauimix
2026-07-26 10:22:56 +08:00
parent 4bc9629a09
commit 0238aa7c02
214 changed files with 121312 additions and 388 deletions

View File

@@ -1,9 +1,10 @@
#!/bin/sh
# Стабильный URL для Joplin на телефоне при Android-хотспоте: http://<подсеть>.100:8080
# Alias *.100 на en0 (DHCP primary не трогаем). LaunchAgent поднимает alias после reconnect.
# Стабильный URL для Joplin: http://<подсеть>.100:8080
# Primary IP *.100 через networksetup (Android видит primary, alias — часто нет).
#
# ./joplin-hotspot-alias.sh status
# ./joplin-hotspot-alias.sh ensure
# ./joplin-hotspot-alias.sh ensure|repair
# ./joplin-hotspot-alias.sh dhcp # вернуть DHCP (перед домашним WiFi)
#
# Passwordless: ./joplin-hotspot-alias-install-sudo.sh
@@ -11,8 +12,10 @@ set -e
CONFIG="${JOPLIN_WEBDAV_CONFIG:-$HOME/.config/joplin-webdav/env}"
WIFI_DEV="${WIFI_DEVICE:-en0}"
WIFI_SERVICE="${WIFI_SERVICE:-Wi-Fi}"
PORT="${JOPLIN_WEBDAV_PORT:-8080}"
LOG="$HOME/Library/Logs/joplin-webdav/alias.log"
NS="/usr/sbin/networksetup"
ipv4_subnet() {
printf '%s\n' "$1" | awk -F. '{print $1"."$2"."$3}'
@@ -59,19 +62,34 @@ has_ip_on_dev() {
ifconfig "$dev" 2>/dev/null | grep -q "inet ${ip} "
}
# Убрать *.100 alias с других подсетей (после смены хотспота / WiFi)
prune_stale_aliases() {
target="$1"
dev="$2"
ifconfig "$dev" 2>/dev/null | awk '/inet / {print $2}' | while read -r ip; do
case "$ip" in
*.*.*.100)
[ "$ip" = "$target" ] && continue
ifconfig "$dev" -alias "$ip" 2>/dev/null || true
log_msg "removed stale alias $ip"
;;
esac
done
}
is_android_hotspot_gw() {
gw="$1"
case "$gw" in
10.*|172.20.10.*|192.168.43.*|192.168.44.*|192.168.49.*) return 0 ;;
*) return 1 ;;
esac
}
log_msg() {
mkdir -p "$(dirname "$LOG")"
printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG"
}
run_priv() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
else
sudo "$@"
fi
}
write_phone_url_env() {
url="$(phone_url 2>/dev/null || true)"
[ -n "$url" ] && [ -f "$CONFIG" ] || return 0
@@ -90,31 +108,45 @@ cmd_status() {
gw="$(default_gateway 2>/dev/null || true)"
url="$(phone_url 2>/dev/null || true)"
echo "mode: Android-хотспот (alias *.100)"
echo "mode: static primary *.100 ($WIFI_SERVICE)"
echo "device: $WIFI_DEV"
echo "primary: ${primary:-(none)}"
echo "gateway: ${gw:-(none)}"
echo "joplin IP: ${target:-(no gateway)}"
if [ -n "$target" ] && has_ip_on_dev "$target" "$WIFI_DEV"; then
echo "alias: OK"
elif [ -n "$target" ] && [ "$primary" = "$target" ]; then
echo "alias: OK (primary)"
if [ -n "$gw" ] && ! is_android_hotspot_gw "$gw"; then
echo "network: домашний/роутер WiFi (не Android-хотспот)"
echo " → телефон должен быть в той же WiFi сети, что Mac"
else
echo "network: похоже на Android-хотспот"
fi
if [ -n "$target" ]; then
ifconfig "$WIFI_DEV" 2>/dev/null | awk -v t="$target" '/inet / { if ($2 ~ /\.100$/ && $2 != t) print "stale ifconfig: " $2 " (repair)" }'
fi
if [ -n "$target" ] && [ "$primary" = "$target" ]; then
echo "static IP: OK (primary = $target)"
elif [ -n "$target" ]; then
echo "alias: MISSING — телефон не достучится"
echo " fix: $0 ensure"
echo "static IP: MISSING (primary $primary, нужен $target)"
echo " fix: $0 repair"
fi
if [ -n "$url" ]; then
echo ""
echo "URL на телефоне (работает с Android-хотспота):"
echo "URL на телефоне:"
echo " $url"
echo ""
echo "Проверка: браузер НА ТЕЛЕФОНЕ → URL → запрос логина за 23 сек"
echo "Если браузер висит — телефон не видит Mac (не Joplin)"
echo ""
echo "⚠ http://*.local:8080 с телефона НЕ работает (Android не резолвит mDNS клиентов хотспота)"
fi
}
cmd_ensure() {
force=0
[ "${1:-}" = --force ] && force=1
target="$(joplin_phone_ip 2>/dev/null || true)"
if [ -z "$target" ]; then
log_msg "skip: no gateway"
@@ -125,25 +157,56 @@ cmd_ensure() {
log_msg "skip: no primary IP"
exit 0
fi
if [ "$primary" = "$target" ] || has_ip_on_dev "$target" "$WIFI_DEV"; then
write_phone_url_env
if [ "$primary" = "$target" ] && [ "$force" -eq 0 ]; then
[ "$(id -u)" -ne 0 ] && write_phone_url_env
exit 0
fi
log_msg "add alias $target on $WIFI_DEV (primary $primary)"
run_priv ifconfig "$WIFI_DEV" inet "$target" netmask 255.255.255.0 alias
write_phone_url_env
echo "alias OK: $target"
echo "URL на телефоне: $(phone_url)"
if [ "$(id -u)" -ne 0 ]; then
log_msg "setmanual $target (was $primary)"
sudo_arg=ensure
[ "$force" -eq 1 ] && sudo_arg="ensure --force"
# shellcheck disable=SC2086
if ! sudo -n "$0" $sudo_arg; then
echo "static IP FAILED: нужен sudo." >&2
echo " один раз: ./docs/apps/joplin/scripts/joplin-hotspot-alias-install-sudo.sh" >&2
echo " затем: $0 repair" >&2
exit 1
fi
write_phone_url_env
echo "static IP OK: $target"
echo "URL на телефоне: $(phone_url)"
exit 0
fi
gw="$(default_gateway 2>/dev/null || true)"
[ -n "$gw" ] || { log_msg "skip: no gateway"; exit 1; }
prune_stale_aliases "$target" "$WIFI_DEV"
log_msg "networksetup -setmanual $target gw $gw [root]"
"$NS" -setmanual "$WIFI_SERVICE" "$target" "255.255.255.255.0" "$gw"
}
cmd_dhcp() {
if [ "$(id -u)" -ne 0 ]; then
if ! sudo -n "$0" dhcp; then
echo "Нужен sudo: sudo $NS -setdhcp \"$WIFI_SERVICE\"" >&2
exit 1
fi
echo "WiFi → DHCP"
exit 0
fi
"$NS" -setdhcp "$WIFI_SERVICE"
log_msg "setdhcp $WIFI_SERVICE"
}
usage() {
echo "Usage: $(basename "$0") status|ensure" >&2
echo "Usage: $(basename "$0") status|ensure|repair|dhcp" >&2
exit 1
}
case "${1:-ensure}" in
status) cmd_status ;;
ensure) cmd_ensure ;;
ensure) cmd_ensure "${2:-}" ;;
repair) "$0" ensure --force ;;
dhcp) cmd_dhcp ;;
-h|--help) usage ;;
*) usage ;;
esac