remove s/, u/, x/ script namespaces and 9P backing

All session scripts (s/sh, s/b, s/bfg, s/bbg, s/ls, s/kill, s/cleanup),
utility scripts (u/optimize, u/complete, u/cascade, u/escalate), and
internal scripts (x/bd, x/prime, x/freeloader, x/task) are removed.

These are replaced by:
- generate, complete, route files (ollie-9p rdwr)
- integrated elevation broker
- D-Bus/9P session management

Also removes:
- 9P rootFileOrder entries and permission map for script files
- Script-serving catch-all in rootOpen
- prependOlliePath (no x/ scripts to shadow PATH with)

ollie-watchdog moved to contrib/scripts/ alongside ollie-remount.
This commit is contained in:
Ollie Agent 2026-07-30 21:36:54 +02:00
parent ffe45c4f1f
commit ddddb1f53b
16 changed files with 3 additions and 625 deletions

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
# s/cleanup: kill all idle sessions.
set -euo pipefail
OLLIE=${OLLIE:-$HOME/mnt/ollie}
remount_once() { ollie-remount 2>/dev/null; }
for sess in "$OLLIE"/s/*/; do
[ -d "$sess" ] || { remount_once; [ -d "$sess" ] || continue; }
state=$(awk -F= '$1=="state"{print $2; exit}' "$sess/cfg" 2>/dev/null | tr -d '[:space:]') || continue
[ "$state" = "idle" ] && rm -r "$sess"
done

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
OLLIE=${OLLIE:-$HOME/mnt/ollie}
rm -r "${OLLIE}/s/$1" 2>/dev/null || { ollie-remount && rm -r "${OLLIE}/s/$1"; }

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
OLLIE=${OLLIE:-$HOME/mnt/ollie}
cat "$OLLIE/s/idx" 2>/dev/null || { ollie-remount && cat "$OLLIE/s/idx"; }

View File

@ -1,176 +0,0 @@
#!/usr/bin/env bash
# u/cascade — script-driven hub-and-spoke cascading orchestrator.
#
# An expensive model decomposes a task into mechanical subtasks, then cheap
# models execute them in parallel. The script (not an agent) coordinates.
#
# Usage: cascade [flags] [prompt...]
# echo "prompt" | cascade [flags]
#
# Flags:
# -pb BACKEND planner backend (default: $OLLIE_CASCADE_PLAN_BACKEND or anthropic)
# -pm MODEL planner model (default: $OLLIE_CASCADE_PLAN_MODEL or claude-sonnet-4-20250514)
# -wb BACKEND worker backend (default: $OLLIE_CASCADE_BACKEND or ollama)
# -wm MODEL worker model (default: $OLLIE_CASCADE_MODEL or qwen2.5-coder:14b)
# -max-workers N max concurrent workers (default: 8)
# -retries N max attempts per worker (default: 1, no retry)
# -synthesize collect worker results and ask the planner to produce a summary
# -json-output structured JSON synthesis (implies -synthesize)
set -euo pipefail
OLLIE="${OLLIE:-$HOME/mnt/ollie}"
B="$OLLIE/s/b"
PB="${OLLIE_CASCADE_PLAN_BACKEND:-openrouter}"
PM="${OLLIE_CASCADE_PLAN_MODEL:-deepseek/deepseek-v4-pro}"
WB="${OLLIE_CASCADE_BACKEND:-openrouter}"
WM="${OLLIE_CASCADE_MODEL:-deepseek/deepseek-v4-flash}"
die() { printf 'cascade: %s\n' "$*" >&2; exit 1; }
synthesize=0
json_output=0
max_workers=8
retries=1
while [ $# -gt 0 ]; do
case $1 in
-pb) PB=$2; shift ;;
-pm) PM=$2; shift ;;
-wb) WB=$2; shift ;;
-wm) WM=$2; shift ;;
-max-workers) max_workers=$2; shift ;;
-retries) retries=$2; shift ;;
-synthesize) synthesize=1 ;;
-json-output) json_output=1; synthesize=1 ;;
--) shift; break ;;
-*) die "unknown flag: $1" ;;
*) break ;;
esac
shift
done
if [ $# -gt 0 ]; then
task="$*"
elif ! [ -t 0 ]; then
task=$(cat)
else
die "prompt required"
fi
[ -z "$task" ] && die "empty prompt"
case "$max_workers" in
''|*[!0-9]*|0) die "-max-workers must be a positive integer" ;;
esac
case "$retries" in
''|*[!0-9]*|0) die "-retries must be a positive integer" ;;
esac
# Step 1: Ask the planner to decompose into subtasks (JSON array).
plan=$("$B" -backend "$PB" -model "$PM" -json \
"Decompose this task into independent, mechanical subtasks that a weak model can execute without judgment. Each subtask must be fully self-contained (include all needed context). Output a JSON array of objects with \"id\" (short string) and \"instruction\" (complete task description). Keep it minimal — only decompose what benefits from parallelism.
TASK:
$task")
# Validate we got JSON with correct schema.
printf '%s' "$plan" | jq empty 2>/dev/null || die "planner did not return valid JSON: $plan"
printf '%s' "$plan" | jq -e 'type=="array" and length>0 and all(.[]; (.id|type=="string" and length>0) and (.instruction|type=="string" and length>0))' >/dev/null \
|| die "plan schema invalid (need array of {id: string, instruction: string})"
# Step 2: Spawn workers in parallel, collect session paths.
count=$(printf '%s' "$plan" | jq 'length')
[ "$count" -eq 0 ] && die "planner returned empty plan"
pids=()
workers=()
base="cascade-$(date +%s%N)"
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
for i in $(seq 0 $((count - 1))); do
id=$(printf '%s' "$plan" | jq -r ".[$i].id")
instruction=$(printf '%s' "$plan" | jq -r ".[$i].instruction")
sid="${base}-${id}"
workers+=("$sid")
# Throttle: wait for a slot if at max concurrency.
while [ "$(jobs -rp | wc -l)" -ge "$max_workers" ]; do sleep 0.5; done
(
attempt=0
while [ "$attempt" -lt "$retries" ]; do
attempt=$((attempt + 1))
name="${sid}$( [ "$attempt" -gt 1 ] && echo "-r${attempt}" || true)"
"$B" -name "$name" -backend "$WB" -model "$WM" -keep \
"You are a worker agent. Execute the following task exactly. Output only the result.
$instruction" > "${tmpdir}/${sid}.out" 2>&1 && touch "${tmpdir}/${sid}.ok" && break
# Backoff before retry.
sleep "$((attempt * 2))"
done
echo "$attempt" > "${tmpdir}/${sid}.attempts"
echo "$name" > "${tmpdir}/${sid}.session"
) &
pids+=($!)
done
# Step 3: Wait for all workers.
for pid in "${pids[@]}"; do wait "$pid" || true; done
# Step 4: Gather results as structured JSON array.
MAX_OUTPUT=${OLLIE_CASCADE_MAX_OUTPUT:-8000} # max chars per worker output
failures=0
results_json="["
first=1
for sid in "${workers[@]}"; do
if [ -f "${tmpdir}/${sid}.ok" ]; then
status="done"
else
status="failed"
failures=$((failures + 1))
fi
out=$(cat "${tmpdir}/${sid}.out" 2>/dev/null || echo "(no output)")
attempts=$(cat "${tmpdir}/${sid}.attempts" 2>/dev/null || echo 1)
session_name=$(cat "${tmpdir}/${sid}.session" 2>/dev/null || echo "$sid")
if [ "${#out}" -gt "$MAX_OUTPUT" ]; then
out="${out:0:$MAX_OUTPUT}
...(truncated, ${#out} chars total)"
fi
[ "$first" -eq 1 ] && first=0 || results_json="${results_json},"
results_json="${results_json}$(jq -n --arg id "$sid" --arg status "$status" --arg output "$out" --argjson attempts "$attempts" --arg session "$session_name" \
'{id: $id, status: $status, attempts: $attempts, session: $session, output: $output}')"
done
results_json="${results_json}]"
# Step 5: Synthesize or just print results.
# Exit code contract:
# No synthesis: exit 1 if any worker failed (caller must handle partial results).
# Synthesis: exit 0 — the planner accounts for failures in its answer.
if [ "$synthesize" -eq 0 ]; then
printf '%s\n' "$results_json" | jq .
[ "$failures" -gt 0 ] && exit 1
else
synth_flags=(-backend "$PB" -model "$PM")
if [ "$json_output" -eq 1 ]; then
synth_flags+=(-json)
synth_prompt="Synthesize these worker results into a structured JSON response for the original task. Note: workers with status \"failed\" did not complete successfully — include them in errors.
Output schema: {\"summary\": \"<one-line summary>\", \"answer\": \"<full synthesized answer>\", \"worker_results\": [{\"id\": \"<worker-id>\", \"status\": \"done|failed\", \"attempts\": <int>, \"session\": \"<session-name>\", \"output\": \"<worker output>\"}], \"errors\": [\"<description of any failures>\"]}
ORIGINAL TASK:
$task
WORKER RESULTS (JSON):
$results_json"
else
synth_prompt="Synthesize these worker results into a final, coherent answer to the original task. Note: workers with status \"failed\" did not complete successfully — account for this in your synthesis.
ORIGINAL TASK:
$task
WORKER RESULTS (JSON):
$results_json"
fi
"$B" "${synth_flags[@]}" "$synth_prompt"
fi

View File

@ -1,95 +0,0 @@
#!/usr/bin/env bash
# u/complete: AI code completion via /complete endpoint.
# Reads prefix from stdin, prints completion to stdout.
set -euo pipefail
PREFIX_MAX=12000
SUFFIX_MAX=1000
cmd=${0##*/}
die() { printf '%s: %s\n' "$cmd" "$*" >&2; exit 1; }
for _arg; do
[ "$_arg" = "-help" ] && cat <<'HELP' && exit 0
usage: complete [-model MODEL] [-backend BACKEND] [-file NAME] [-suffix TEXT]
echo "prefix" | complete -file main.go -suffix "rest of code"
Reads prefix from stdin, prints raw completion to stdout.
Flags:
-model MODEL model (default: $OLLIE_COMPLETE_MODEL)
-backend BACKEND backend (default: $OLLIE_COMPLETE_BACKEND)
-file NAME filename for language context
-suffix TEXT code after the cursor
-context TEXT additional context (LSP symbols, completions, hover)
-cwd DIR working directory
-help show this help
HELP
done
model=${OLLIE_COMPLETE_MODEL:-}
backend=${OLLIE_COMPLETE_BACKEND:-}
file=
suffix=
context=
cwd=
while [ $# -gt 0 ]; do
case $1 in
-model) model=$2; shift ;;
-backend) backend=$2; shift ;;
-file) file=$2; shift ;;
-suffix) suffix=$2; shift ;;
-context) context=$2; shift ;;
-cwd) cwd=$2; shift ;;
-help) ;;
-*) die "unknown flag: $1" ;;
*) break ;;
esac
shift
done
[ -z "$model" ] && die "model required: set OLLIE_COMPLETE_MODEL or pass -model"
[ -z "$backend" ] && die "backend required: set OLLIE_COMPLETE_BACKEND or pass -backend"
prefix=$(cat)
# Truncate to context budget
[ ${#prefix} -gt $PREFIX_MAX ] && prefix="${prefix: -$PREFIX_MAX}"
[ ${#suffix} -gt $SUFFIX_MAX ] && suffix="${suffix:0:$SUFFIX_MAX}"
# JSON-escape a string.
jsonesc() {
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g' | tr '\n' '\1' | sed 's/\x01/\\n/g'
}
# Build JSON request for /complete endpoint
json='{"prefix":"'$(jsonesc "$prefix")'"'
json="$json,\"suffix\":\"$(jsonesc "$suffix")\""
[ -n "$file" ] && json="$json,\"file\":\"$(jsonesc "$file")\""
[ -n "$context" ] && json="$json,\"context\":\"$(jsonesc "$context")\""
json="$json,\"cwd\":\"$(jsonesc "${cwd:-$PWD}")\""
json="$json}"
# Write to /complete and read response (net/dns pattern)
result=$(printf '%s' "$json" | 9p rdwr ollie/complete) || die "complete failed (is olliesrv running?)"
# Strip markdown code fences if the model wrapped the output.
result=$(printf '%s' "$result" | sed '/^```[a-zA-Z]*$/d; /^```$/d')
# Strip prefix echo: if the result starts with a suffix of the prefix, remove it.
tail_max=200
[ ${#prefix} -lt $tail_max ] && tail_max=${#prefix}
i=$tail_max
while [ "$i" -gt 0 ]; do
tail="${prefix: -$i}"
case "$result" in
"$tail"*)
result="${result#"$tail"}"
break
;;
esac
i=$((i - 1))
done
printf '%s' "$result"

View File

@ -1,52 +0,0 @@
#!/usr/bin/env bash
# u/escalate — escalate a task to a stronger model.
#
# When a weak model can't handle a task, escalate sends it to a strong model
# and returns the result inline (blocking).
#
# Usage: escalate [flags] [prompt...]
# echo "prompt" | escalate [flags]
#
# Flags:
# -backend B expert backend (default: $OLLIE_ESCALATE_BACKEND or openrouter)
# -model M expert model (default: $OLLIE_ESCALATE_MODEL or anthropic/claude-sonnet-4-20250514)
# -keep keep the expert session after completion (don't auto-cleanup)
set -euo pipefail
OLLIE="${OLLIE:-$HOME/mnt/ollie}"
BIN="$OLLIE/s/b"
BACKEND="${OLLIE_ESCALATE_BACKEND:-openrouter}"
MODEL="${OLLIE_ESCALATE_MODEL:-anthropic/claude-sonnet-4-20250514}"
die() { printf 'escalate: %s\n' "$*" >&2; exit 1; }
keep=0
while [ $# -gt 0 ]; do
case $1 in
-backend) BACKEND=$2; shift ;;
-model) MODEL=$2; shift ;;
-keep) keep=1 ;;
--) shift; break ;;
-*) die "unknown flag: $1" ;;
*) break ;;
esac
shift
done
if [ $# -gt 0 ]; then
prompt="$*"
elif ! [ -t 0 ]; then
prompt=$(cat)
else
die "prompt required"
fi
[ -z "$prompt" ] && die "empty prompt"
flags=(-backend "$BACKEND" -model "$MODEL")
[ "$keep" -eq 1 ] && flags+=(-keep)
"$BIN" "${flags[@]}" "You are an expert model escalated to handle a hard task. Apply rigorous reasoning and produce a correct, complete answer.
$prompt"

View File

@ -1,68 +0,0 @@
#!/usr/bin/env bash
# u/optimize: generate N candidate optimized prompts and select the best.
set -euo pipefail
for _arg; do
[ "$_arg" = "-help" ] && cat <<'HELP' && exit 0
usage: optimize [flags] [prompt...]
echo "prompt" | optimize [flags]
Generates N optimized candidates for a prompt, then judges and returns the best.
Flags:
-n N number of candidates to generate (default: 3)
-cb BACKEND candidate generation backend
-cm MODEL candidate generation model
-jb BACKEND judge backend
-jm MODEL judge model
-help show this help
HELP
done
n=3; cb=; cm=; jb=; jm=
while [ $# -gt 0 ]; do
case $1 in
-n) n=$2; shift ;;
-cb) cb=$2; shift ;;
-cm) cm=$2; shift ;;
-jb) jb=$2; shift ;;
-jm) jm=$2; shift ;;
-help) ;;
--) shift; break ;;
-*) printf 'optimize: unknown flag: %s\n' "$1" >&2; exit 1 ;;
*) break ;;
esac
shift
done
if [ $# -gt 0 ]; then
prompt="$*"
elif ! [ -t 0 ]; then
prompt=$(cat)
else
printf 'optimize: prompt required\n' >&2; exit 1
fi
[ -z "$prompt" ] && { printf 'optimize: empty prompt\n' >&2; exit 1; }
B="${0%/*}/../s/b"
c_flags=()
j_flags=()
[ -n "$cb" ] && c_flags+=(-backend "$cb")
[ -n "$cm" ] && c_flags+=(-model "$cm")
[ -n "$jb" ] && j_flags+=(-backend "$jb")
[ -n "$jm" ] && j_flags+=(-model "$jm")
printf 'generating %d candidates...\n' "$n" >&2
candidates=$("$B" "${c_flags[@]}" -parallel "$n" \
"Optimize the following prompt. Return only the optimized prompt, no explanation or preamble:
$prompt")
printf 'judging...\n' >&2
"$B" "${j_flags[@]}" \
"Review these candidate prompts and return only the single best one, no explanation or preamble:
$candidates"

View File

@ -1,14 +0,0 @@
#!/bin/bash
# Wrapper for bd that resolves BEADS_DIR by walking up from CWD when unset.
# Placed in $OLLIE/x/ so it shadows the real bd on PATH for tool subprocesses.
if [ -z "$BEADS_DIR" ]; then
dir="$PWD"
while [ "$dir" != "/" ] && [ -e "$dir/.git" ]; do
if [ -d "$dir/.beads" ]; then
export BEADS_DIR="$dir/.beads"
break
fi
dir="$(dirname "$dir")"
done
fi
exec "$HOME/.local/bin/bd" "$@"

View File

@ -1,95 +0,0 @@
#!/usr/bin/env bash
# x/freeloader: turnError hook handler for free-model sessions on OpenRouter.
#
# Intercepts rate_limit and tool_unsupported errors on :free models, walks
# through every viable free model once per round, and resubmits the previous
# prompt on each switch. When the pool is exhausted, clears the tried list
# and exits 1 so normal error handling takes over.
#
# Configure in an agent .json:
# { "hooks": { "turnError": "$OLLIE/x/freeloader $OLLIE_SESSION_ID" } }
#
# Exit codes:
# 0 — error intercepted, switched model and resubmitted
# 1 — pool exhausted or error not applicable; normal handling proceeds
set -euo pipefail
OLLIE="${OLLIE:-$HOME/mnt/ollie}"
CFG="${XDG_CONFIG_HOME:-$HOME/.config}/ollie"
BLACKLIST="$CFG/freeloader-blacklist"
cmd=${0##*/}
die() { printf '%s: %s\n' "$cmd" "$*" >&2; exit 1; }
[ $# -ne 1 ] && die "usage: freeloader <session-id>"
SID="$1"
B="$OLLIE/s/$SID"
[ -d "$B" ] || die "session not found: $SID"
error_type="${OLLIE_ERROR_TYPE:-}"
current_model="${OLLIE_MODEL:-$(grep '^model=' "$B/cfg" 2>/dev/null | cut -d= -f2-)}"
# Only handle rate_limit and tool_unsupported.
case "$error_type" in
rate_limit|tool_unsupported) ;;
*) exit 1 ;;
esac
# Only act on :free models.
case "$current_model" in
*:free) ;;
*) exit 1 ;;
esac
# For tool_unsupported: permanently blacklist the current model.
if [ "$error_type" = "tool_unsupported" ]; then
mkdir -p "$CFG"
if ! grep -qxF "$current_model" "$BLACKLIST" 2>/dev/null; then
printf '%s\n' "$current_model" >> "$BLACKLIST"
printf '%s: blacklisted %s (tool_unsupported)\n' "$cmd" "$current_model" >&2
fi
fi
# Per-session tried list: tracks models attempted in the current round.
TRIED="$CFG/freeloader-tried-$SID"
mkdir -p "$CFG"
# Mark current model as tried.
if ! grep -qxF "$current_model" "$TRIED" 2>/dev/null; then
printf '%s\n' "$current_model" >> "$TRIED"
fi
# Build the full sorted :free pool (blacklist excluded).
mapfile -t pool < <(
cat "$B/models" 2>/dev/null \
| grep ':free' \
| sort \
| { [ -f "$BLACKLIST" ] && grep -vxFf "$BLACKLIST" || cat; }
)
# Find first model not yet tried this round.
next_model=""
for m in "${pool[@]}"; do
if ! grep -qxF "$m" "$TRIED" 2>/dev/null; then
next_model="$m"
break
fi
done
if [ -z "$next_model" ]; then
printf '%s: all free models exhausted, giving up\n' "$cmd" >&2
rm -f "$TRIED"
exit 1
fi
# Switch model and resubmit the previous prompt.
printf 'model %s\n' "$next_model" > "$B/ctl" || die "failed to switch model"
prev=$(cat "$B/prompt.prev" 2>/dev/null) || die "prompt.prev not available"
[ -z "$prev" ] && die "prompt.prev is empty"
printf '%s\n' "$prev" > "$B/fifo.in" || die "failed to resubmit prompt"
printf '%s: %s → %s\n' "$cmd" "$current_model" "$next_model" >&2
exit 0

View File

@ -1,29 +0,0 @@
#!/bin/bash
# Print a prompt file from $OLLIE_PROMPTS_PATH to stdout.
# Usage: prime <name> (resolves <name> or <name>.md under OLLIE_PROMPTS_PATH)
# Resolution and variable expansion is now handled by the Go prompt resolver;
# this script is a convenience wrapper for manual/CLI use.
set -euo pipefail
PROMPTS_PATH="${OLLIE_PROMPTS_PATH:-${HOME}/.config/ollie/prompts}"
if [ $# -ne 1 ]; then
echo "usage: prime <name>" >&2
exit 1
fi
NAME="$1"
IFS=: read -ra DIRS <<< "$PROMPTS_PATH"
for dir in "${DIRS[@]}"; do
[ -z "$dir" ] && continue
for path in "$dir/$NAME" "$dir/$NAME.md"; do
if [ -f "$path" ]; then
cat "$path"
exit 0
fi
done
done
echo "prime: prompt not found: $NAME" >&2
exit 1

View File

@ -1,23 +0,0 @@
#!/bin/bash
# Task dispatcher.
# list: always shows s/{sid}/plan; additionally bd list --status open if .beads present.
OLLIE="${OLLIE:-$HOME/mnt/ollie}"
show_plan() {
[ -z "$OLLIE_SESSION_ID" ] && return
plan="$OLLIE/s/$OLLIE_SESSION_ID/plan"
[ -s "$plan" ] && echo "## Session Plan" && echo && cat "$plan" && echo
}
dir="$PWD"
while [ "$dir" != "/" ]; do
if [ -d "$dir/.beads" ]; then
show_plan; exec bd list --status open
fi
[ ! -e "$dir/.git" ] && break
dir="$(dirname "$dir")"
done
show_plan
exit 0

View File

@ -59,13 +59,6 @@ var Perms = map[string]Perm{
Files: map[string]os.FileMode{
"new": 0666,
"idx": 0444,
"ls": 0555,
"kill": 0555,
"sh": 0550,
"b": 0555,
"bfg": 0555,
"bbg": 0555,
"cleanup": 0555,
},
},
PathSessionDir: {DirMode: 0755},

View File

@ -12,13 +12,12 @@ import (
"ollie/agent"
olog "ollie/log"
"ollie/paths"
coresession "ollie/session"
"ollie/skills"
"ollie/toolsrv"
)
var rootFileOrder = []string{"new", "idx", "ls", "kill", "sh", "b", "bfg", "bbg", "cleanup"}
var rootFileOrder = []string{"new", "idx"}
// FileMode returns the mode for a fixed session file,
// or 0 and false if the name is not a fixed file.
@ -341,18 +340,6 @@ func rootOpen(rs *rootState, name string) (File, error) {
BlockingReadFn: notBlocking,
}, nil
}
if _, ok := Perms[PathSessions].Files[name]; ok {
return &FileConfig{
StatFn: func() (os.FileInfo, error) {
return &SyntheticFileInfo{Name_: name, Mode_: Perms[PathSessions].Files[name]}, nil
},
ReadFn: func() ([]byte, error) {
return rs.cfg.ReadFile(paths.CfgDir() + "/scripts/session/" + name)
},
WriteFn: func([]byte) error { return fmt.Errorf("%s: not writable", name) },
BlockingReadFn: notBlocking,
}, nil
}
// Hierarchical paths: {id}/{file} or {id}/agent/{aid}/{file}
parts = strings.SplitN(name, "/", 4)

View File

@ -168,20 +168,6 @@ install-data:
install-scripts:
@echo === Installing scripts ===
mkdir -p {{cfg}}/scripts/s {{cfg}}/scripts/u {{cfg}}/scripts/x
install -m755 contrib/scripts/s/sh {{cfg}}/scripts/s/sh
install -m755 contrib/scripts/s/ls {{cfg}}/scripts/s/ls
install -m755 contrib/scripts/s/kill {{cfg}}/scripts/s/kill
install -m755 contrib/scripts/s/b {{cfg}}/scripts/s/b
install -m755 contrib/scripts/s/bfg {{cfg}}/scripts/s/bfg
install -m755 contrib/scripts/s/bbg {{cfg}}/scripts/s/bbg
install -m755 contrib/scripts/s/cleanup {{cfg}}/scripts/s/cleanup
install -m755 contrib/scripts/u/optimize {{cfg}}/scripts/u/optimize
install -m755 contrib/scripts/u/complete {{cfg}}/scripts/u/complete
install -m755 contrib/scripts/u/cascade {{cfg}}/scripts/u/cascade
install -m755 contrib/scripts/x/bd {{cfg}}/scripts/x/bd
install -m755 contrib/scripts/x/prime {{cfg}}/scripts/x/prime
install -m755 contrib/scripts/x/freeloader {{cfg}}/scripts/x/freeloader
install-autostart:
@echo === Installing autostart files ===
@ -197,7 +183,7 @@ install-contrib:
@echo === Installing contrib scripts ===
mkdir -p {{bin}}
install -m755 contrib/scripts/ollie-remount {{bin}}/ollie-remount
install -m755 contrib/scripts/s/ollie-watchdog {{bin}}/ollie-watchdog
install -m755 contrib/scripts/ollie-watchdog {{bin}}/ollie-watchdog
# === Uninstall ===

View File

@ -501,7 +501,7 @@ func (e *Server) executeWithStdin(ctx context.Context, code, language string, ti
filtered = append(filtered, ev)
}
}
cmd.Env = prependOlliePath(filtered, paths.CfgDir())
cmd.Env = filtered
cmd.Env = append(cmd.Env, "OLLIE_TOOLS_PATH="+ToolsPath())
for k, v := range e.envExtra {
cmd.Env = append(cmd.Env, k+"="+v)
@ -644,23 +644,6 @@ func (e *Server) executeWithStdin(ctx context.Context, code, language string, ti
}
}
// prependOlliePath returns env with $OLLIE_CFG_PATH/scripts/x/ prepended to PATH so wrapper
// scripts placed there shadow system binaries.
func prependOlliePath(env []string, cfgDir string) []string {
if cfgDir == "" {
return env
}
xdir := filepath.Join(cfgDir, "scripts", "x")
result := make([]string, 0, len(env))
for _, e := range env {
if strings.HasPrefix(e, "PATH=") {
e = "PATH=" + xdir + string(filepath.ListSeparator) + e[5:]
}
result = append(result, e)
}
return result
}
// plan9Namespace computes the plan9port namespace directory from the environment.
// Convention: $NAMESPACE if set, else /tmp/ns.<user>.<display> where display is
// $DISPLAY with trailing .0 stripped and / replaced by _.