Self-healing autopoietic shell: f(), tests, docs, interactive demo, fx fix-source layer
This commit is contained in:
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# Fuzzy-known source: surfaces fixes already taught for a command that
|
||||
# *starts the same way* as this one, since f()'s own p lookup only ever
|
||||
# matches the exact, literal string.
|
||||
[ -f p ] || exit 0
|
||||
cmd="$1"
|
||||
first_word=$(printf '%s' "$cmd" | awk '{print $1}')
|
||||
[ -n "$first_word" ] || exit 0
|
||||
grep -F "${first_word} " p 2>/dev/null | cut -d= -f2- | awk '!seen[$0]++'
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
# History source: suggests the closest-looking command you've actually
|
||||
# typed and moved on from before (thefuck's history.py idea). Reads
|
||||
# HISTFILE directly since a separate process doesn't inherit the parent
|
||||
# shell's in-memory history.
|
||||
cmd="$1"
|
||||
first_word=$(printf '%s' "$cmd" | awk '{print $1}')
|
||||
[ -n "$first_word" ] || exit 0
|
||||
hf="${HISTFILE:-$HOME/.bash_history}"
|
||||
[ -r "$hf" ] || exit 0
|
||||
tail -n 300 "$hf" 2>/dev/null | grep -F -- "$first_word " | grep -vF -- "$cmd" | awk '!seen[$0]++' | tail -5
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
# Self-diagnosis source: many CLIs print their own corrected invocation
|
||||
# in their error output (git's --set-upstream hint, apt's "did you
|
||||
# mean", etc.).
|
||||
#
|
||||
# IMPORTANT: this must NOT cache the literal suggested line -- that
|
||||
# reintroduces the exact-key staleness problem (e.g. "git push" learned
|
||||
# once on branch A silently misapplies its captured --set-upstream on
|
||||
# branch B, and B never actually gets pushed). Instead it emits a
|
||||
# function that shadows the whole program and re-derives the suggestion
|
||||
# from *live* output on every call, the same trick proven to generalize
|
||||
# correctly across branches/arguments in practice. One taught fix this
|
||||
# way covers every future self-diagnosing failure from that program, not
|
||||
# just the one instance that happened to trigger the teaching prompt.
|
||||
cmd="$1"
|
||||
prog=$(printf '%s' "$cmd" | awk '{print $1}')
|
||||
[ -n "$prog" ] || exit 0
|
||||
[ -n "$FX_OUTPUT" ] || exit 0
|
||||
printf '%s\n' "$FX_OUTPUT" | grep -qE "^[[:space:]]*${prog}[[:space:]]" || exit 0
|
||||
|
||||
cat <<FIX
|
||||
${prog}(){ out=\$(command ${prog} "\$@" 2>&1); ec=\$?; if [ \$ec -ne 0 ]; then sug=\$(printf '%s\\n' "\$out" | grep -E "^[[:space:]]*${prog}[[:space:]]" | sed 's/^[[:space:]]*//' | tail -1); if [ -n "\$sug" ]; then eval "command \$sug"; return \$?; fi; fi; printf '%s\\n' "\$out"; return \$ec; }
|
||||
FIX
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# PATH-fuzzy source: if the first word isn't a known command, alias, or
|
||||
# function, offer a function wrapping the closest-spelled real command
|
||||
# as a candidate -- as a fix you approve through the normal f() flow,
|
||||
# not a silently auto-installed hook. A function, not an alias: aliases
|
||||
# only expand in interactive shells (need `shopt -s expand_aliases`
|
||||
# otherwise), so an alias-based fix silently does nothing when f/fx run
|
||||
# inside a script.
|
||||
#
|
||||
# Uses Damerau-Levenshtein-lite (edit distance + adjacent transposition)
|
||||
# so the canonical "gti" -> "git" typo scores 1, not 2 -- plain Hamming
|
||||
# or substitution-only distance ties it with unrelated 3-letter commands
|
||||
# like "ftp" and can pick the wrong one.
|
||||
cmd="$1"
|
||||
first_word=$(printf '%s' "$cmd" | awk '{print $1}')
|
||||
[ -n "$first_word" ] || exit 0
|
||||
command -v "$first_word" >/dev/null 2>&1 && exit 0
|
||||
type "$first_word" >/dev/null 2>&1 && exit 0
|
||||
|
||||
compgen -c 2>/dev/null | sort -u | awk -v target="$first_word" '
|
||||
function min3(a, b, c) { return (a < b ? (a < c ? a : c) : (b < c ? b : c)) }
|
||||
function distance(a, b, n, m, i, j, ca, cb, cost, tmp) {
|
||||
n = length(a); m = length(b)
|
||||
if (n == 0) return m
|
||||
if (m == 0) return n
|
||||
for (j = 0; j <= m; j++) d[0, j] = j
|
||||
for (i = 1; i <= n; i++) {
|
||||
d[i, 0] = i
|
||||
ca = substr(a, i, 1)
|
||||
for (j = 1; j <= m; j++) {
|
||||
cb = substr(b, j, 1)
|
||||
cost = (ca == cb) ? 0 : 1
|
||||
tmp = min3(d[i-1, j] + 1, d[i, j-1] + 1, d[i-1, j-1] + cost)
|
||||
if (i > 1 && j > 1 && ca == substr(b, j-1, 1) && substr(a, i-1, 1) == cb) {
|
||||
tmp = (tmp < d[i-2, j-2] + 1) ? tmp : d[i-2, j-2] + 1
|
||||
}
|
||||
d[i, j] = tmp
|
||||
}
|
||||
}
|
||||
return d[n, m]
|
||||
}
|
||||
{
|
||||
lendiff = length($0) - length(target)
|
||||
if (lendiff > 2 || lendiff < -2) next
|
||||
dd = distance(target, $0)
|
||||
if (dd <= 2 && dd > 0 && (best == "" || dd < bestd)) { best = $0; bestd = dd }
|
||||
}
|
||||
END { if (best != "") print target "(){ command " best " \"$@\"; }" }
|
||||
'
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# thefuck bridge: only fires if thefuck is installed. Note that thefuck
|
||||
# --yes decides *and executes* its own suggestion, so by the time this
|
||||
# candidate is shown it may have already run once via thefuck -- treat
|
||||
# it as informational, not a dry-run.
|
||||
command -v thefuck >/dev/null 2>&1 || exit 0
|
||||
cmd="$1"
|
||||
[ -n "$cmd" ] || exit 0
|
||||
thefuck --yes "$cmd" 2>/dev/null | tr -d '\342\200\213' | tail -1
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# EXAMPLE custom source -- a template, not a real dependency. This is
|
||||
# the entire extension mechanism demonstrated: any executable dropped
|
||||
# into sources.d/ following the contract in fx.sh is picked up
|
||||
# automatically, no registration step anywhere else.
|
||||
#
|
||||
# Pulls a team-shared p-format corrections file and offers exact-key
|
||||
# matches. Off by default (no-ops unless FX_TEAM_URL is set) because a
|
||||
# match here becomes eval'd code the moment you select it -- point this
|
||||
# at a URL you trust the same way you'd trust an rc file, never a
|
||||
# random link.
|
||||
[ -n "$FX_TEAM_URL" ] || exit 0
|
||||
cmd="$1"
|
||||
[ -n "$cmd" ] || exit 0
|
||||
curl -fsSL "$FX_TEAM_URL" 2>/dev/null | grep -F "${cmd}=" | cut -d= -f2-
|
||||
Reference in New Issue
Block a user