Keep the personal half of the desktop in one place, and ask before installing it
Agent instructions, skills, SSH host aliases and expansion triggers are worth having identical on every machine one person owns, and belong in none of the shared configuration. They live in user/ now, with a manifest saying where each piece goes and a link-user stage that puts it there. That stage does nothing unless the machine said yes. Somebody who clones Panama to try the desktop keeps their own ~/.claude/CLAUDE.md exactly where it was; the question names the destinations and defaults to no. Anything displaced goes to config/old rather than being deleted. ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md were byte-identical copies of one file, which is the drift this exists to prevent. Also adds the vitals toggles for the battery and Claude usage readouts, which had preferences and no way to reach them.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# Downloads every attachment listed on a fetched Jira issue JSON file into a resources
|
||||
# directory. Filenames are preserved as-is; on a name collision the attachment id is
|
||||
# prefixed to keep both files.
|
||||
#
|
||||
# Usage: jira-download-attachments.sh <ISSUE-JSON-PATH> <RESOURCES-DIR>
|
||||
#
|
||||
# On success, prints one TSV line per downloaded file to stdout:
|
||||
# <relative-filename>\t<mimeType>\t<bytes>
|
||||
#
|
||||
# Requires: JIRA_CREDENTIALS (same as jira-fetch-issue.sh)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $(basename "$0") <ISSUE-JSON-PATH> <RESOURCES-DIR>" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ $# -eq 2 ] || usage
|
||||
|
||||
ISSUE_JSON="$1"
|
||||
RESOURCES_DIR="$2"
|
||||
|
||||
[ -f "$ISSUE_JSON" ] || { echo "No such file: $ISSUE_JSON" >&2; exit 1; }
|
||||
|
||||
if [ -z "${JIRA_CREDENTIALS:-}" ]; then
|
||||
echo "JIRA_CREDENTIALS is not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command -v curl >/dev/null 2>&1 || { echo "curl is required" >&2; exit 1; }
|
||||
command -v jq >/dev/null 2>&1 || { echo "jq is required" >&2; exit 1; }
|
||||
|
||||
mkdir -p "$RESOURCES_DIR"
|
||||
AUTH="$(printf '%s' "$JIRA_CREDENTIALS" | base64 -w0)"
|
||||
|
||||
COUNT="$(jq '(.fields.attachment // []) | length' "$ISSUE_JSON")"
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for i in $(seq 0 $((COUNT - 1))); do
|
||||
ID="$(jq -r ".fields.attachment[$i].id" "$ISSUE_JSON")"
|
||||
NAME="$(jq -r ".fields.attachment[$i].filename" "$ISSUE_JSON")"
|
||||
MIME="$(jq -r ".fields.attachment[$i].mimeType // \"application/octet-stream\"" "$ISSUE_JSON")"
|
||||
URL="$(jq -r ".fields.attachment[$i].content" "$ISSUE_JSON")"
|
||||
|
||||
DEST_NAME="$NAME"
|
||||
if [ -e "${RESOURCES_DIR}/${DEST_NAME}" ]; then
|
||||
DEST_NAME="${ID}-${NAME}"
|
||||
fi
|
||||
DEST="${RESOURCES_DIR}/${DEST_NAME}"
|
||||
|
||||
HTTP_STATUS="$(curl -sS -L -o "$DEST" -w '%{http_code}' \
|
||||
-H "Authorization: Basic ${AUTH}" \
|
||||
"$URL")"
|
||||
|
||||
if [ "$HTTP_STATUS" != "200" ]; then
|
||||
echo "Failed to download attachment ${ID} (${NAME}): HTTP ${HTTP_STATUS}" >&2
|
||||
rm -f "$DEST"
|
||||
continue
|
||||
fi
|
||||
|
||||
BYTES="$(wc -c < "$DEST" | tr -d ' ')"
|
||||
printf '%s\t%s\t%s\n' "$DEST_NAME" "$MIME" "$BYTES"
|
||||
done
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fetches a single Jira issue (fields=*all, rendered HTML description, field-name map)
|
||||
# and writes the raw API response as JSON.
|
||||
#
|
||||
# Usage: jira-fetch-issue.sh <ISSUE-KEY> <OUTPUT-JSON-PATH>
|
||||
#
|
||||
# Requires:
|
||||
# JIRA_CREDENTIALS "[email protected]:api-token" (Basic auth, same as this org's Jira client)
|
||||
# JIRA_BASE_URL optional, defaults to https://ksense-tech.atlassian.net
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $(basename "$0") <ISSUE-KEY> <OUTPUT-JSON-PATH>" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ $# -eq 2 ] || usage
|
||||
|
||||
KEY="$1"
|
||||
OUT="$2"
|
||||
|
||||
: "${JIRA_BASE_URL:=https://ksense-tech.atlassian.net}"
|
||||
JIRA_BASE_URL="${JIRA_BASE_URL%/}"
|
||||
|
||||
if [ -z "${JIRA_CREDENTIALS:-}" ]; then
|
||||
echo "JIRA_CREDENTIALS is not set. Export it as '[email protected]:api-token' and retry." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command -v curl >/dev/null 2>&1 || { echo "curl is required" >&2; exit 1; }
|
||||
command -v jq >/dev/null 2>&1 || { echo "jq is required" >&2; exit 1; }
|
||||
|
||||
AUTH="$(printf '%s' "$JIRA_CREDENTIALS" | base64 -w0)"
|
||||
|
||||
TMP="${OUT}.tmp"
|
||||
HTTP_STATUS="$(curl -sS -o "$TMP" -w '%{http_code}' \
|
||||
-H "Authorization: Basic ${AUTH}" \
|
||||
-H "Accept: application/json" \
|
||||
"${JIRA_BASE_URL}/rest/api/3/issue/${KEY}?fields=*all&expand=renderedFields,names")"
|
||||
|
||||
if [ "$HTTP_STATUS" != "200" ]; then
|
||||
echo "Jira API request for ${KEY} failed with HTTP ${HTTP_STATUS}:" >&2
|
||||
cat "$TMP" >&2
|
||||
rm -f "$TMP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! jq empty "$TMP" 2>/dev/null; then
|
||||
echo "Jira API response for ${KEY} was not valid JSON:" >&2
|
||||
cat "$TMP" >&2
|
||||
rm -f "$TMP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$OUT")"
|
||||
mv "$TMP" "$OUT"
|
||||
echo "Wrote ${OUT}"
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env bash
|
||||
# Transcribes a video/audio file using whisper.cpp in a podman container, using
|
||||
# hardware acceleration when it's available on the host:
|
||||
# - NVIDIA GPU present -> ghcr.io/ggml-org/whisper.cpp:main-cuda (CDI nvidia device)
|
||||
# - /dev/dri + vainfo -> ghcr.io/ggml-org/whisper.cpp:main-vulkan (AMD/Intel, Vulkan)
|
||||
# - neither -> ghcr.io/ggml-org/whisper.cpp:main (CPU)
|
||||
#
|
||||
# If the accelerated container fails to run (missing CDI setup, no such image tag on
|
||||
# this whisper.cpp release, etc.) this script automatically falls back to the CPU
|
||||
# image rather than failing outright, and says so on stderr.
|
||||
#
|
||||
# Usage: transcribe.sh <media-file> <output-dir> [model]
|
||||
# model defaults to "base.en" (small, fast, English). Pass e.g. "small" for a
|
||||
# multilingual model, or "medium.en" for higher accuracy.
|
||||
# On a multi-GPU AMD/Intel host, set WHISPER_VULKAN_DEVICE to the desired render
|
||||
# node, e.g. WHISPER_VULKAN_DEVICE=/dev/dri/renderD128.
|
||||
#
|
||||
# Writes:
|
||||
# <output-dir>/<basename>.transcript.txt
|
||||
# <output-dir>/<basename>.transcript.srt
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $(basename "$0") <media-file> <output-dir> [model=base.en]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ $# -ge 2 ] || usage
|
||||
|
||||
MEDIA="$1"
|
||||
OUT_DIR="$2"
|
||||
MODEL="${3:-base.en}"
|
||||
|
||||
[ -f "$MEDIA" ] || { echo "No such file: $MEDIA" >&2; exit 1; }
|
||||
command -v podman >/dev/null 2>&1 || { echo "podman is required for transcription" >&2; exit 1; }
|
||||
command -v curl >/dev/null 2>&1 || { echo "curl is required to fetch the whisper model" >&2; exit 1; }
|
||||
|
||||
MEDIA="$(cd "$(dirname "$MEDIA")" && pwd)/$(basename "$MEDIA")"
|
||||
BASENAME="$(basename "${MEDIA%.*}")"
|
||||
WORKDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORKDIR"' EXIT
|
||||
|
||||
WAV="$WORKDIR/audio.wav"
|
||||
|
||||
echo "Extracting audio..." >&2
|
||||
if command -v ffmpeg >/dev/null 2>&1; then
|
||||
ffmpeg -y -i "$MEDIA" -ar 16000 -ac 1 -c:a pcm_s16le "$WAV" -loglevel error
|
||||
else
|
||||
echo "ffmpeg not found on host, extracting via podman instead" >&2
|
||||
podman run --rm \
|
||||
-v "$(dirname "$MEDIA")":/in:Z \
|
||||
-v "$WORKDIR":/out:Z \
|
||||
jrottenberg/ffmpeg:6-alpine \
|
||||
-y -i "/in/$(basename "$MEDIA")" -ar 16000 -ac 1 -c:a pcm_s16le /out/audio.wav -loglevel error
|
||||
fi
|
||||
|
||||
MODEL_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/ticket-skill/whisper-models"
|
||||
mkdir -p "$MODEL_DIR"
|
||||
MODEL_FILE="$MODEL_DIR/ggml-${MODEL}.bin"
|
||||
if [ ! -f "$MODEL_FILE" ]; then
|
||||
echo "Downloading whisper model '${MODEL}' (first run only, cached under ${MODEL_DIR})..." >&2
|
||||
curl -sSL -o "$MODEL_FILE" "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-${MODEL}.bin"
|
||||
fi
|
||||
|
||||
ACCEL="cpu"
|
||||
IMAGE="ghcr.io/ggml-org/whisper.cpp:main"
|
||||
DEVICE_ARGS=()
|
||||
|
||||
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi -L >/dev/null 2>&1; then
|
||||
ACCEL="cuda"
|
||||
IMAGE="ghcr.io/ggml-org/whisper.cpp:main-cuda"
|
||||
DEVICE_ARGS=(--device nvidia.com/gpu=all)
|
||||
elif [ -d /dev/dri ] && command -v vainfo >/dev/null 2>&1; then
|
||||
ACCEL="vulkan"
|
||||
IMAGE="ghcr.io/ggml-org/whisper.cpp:main-vulkan"
|
||||
if [ -n "${WHISPER_VULKAN_DEVICE:-}" ]; then
|
||||
VULKAN_DEVICE="$(readlink -f "$WHISPER_VULKAN_DEVICE")"
|
||||
[ -e "$VULKAN_DEVICE" ] || {
|
||||
echo "WHISPER_VULKAN_DEVICE does not exist: $WHISPER_VULKAN_DEVICE" >&2
|
||||
exit 1
|
||||
}
|
||||
case "$VULKAN_DEVICE" in
|
||||
/dev/dri/renderD*) ;;
|
||||
*)
|
||||
echo "WHISPER_VULKAN_DEVICE must resolve to /dev/dri/renderD*: $VULKAN_DEVICE" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
DEVICE_ARGS=(--device "$VULKAN_DEVICE")
|
||||
else
|
||||
DEVICE_ARGS=(--device /dev/dri)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Selected acceleration: ${ACCEL} (image: ${IMAGE})" >&2
|
||||
|
||||
run_whisper() {
|
||||
local image="$1"
|
||||
shift
|
||||
podman run --rm "$@" \
|
||||
--entrypoint /app/build/bin/whisper-cli \
|
||||
-v "$WORKDIR":/data:Z \
|
||||
-v "$MODEL_DIR":/models:Z \
|
||||
"$image" \
|
||||
-m "/models/ggml-${MODEL}.bin" -f /data/audio.wav -otxt -osrt -of /data/transcript
|
||||
}
|
||||
|
||||
SUCCESS=0
|
||||
if [ "$ACCEL" != "cpu" ]; then
|
||||
if run_whisper "$IMAGE" "${DEVICE_ARGS[@]}"; then
|
||||
SUCCESS=1
|
||||
else
|
||||
echo "Accelerated transcription (${ACCEL}) failed, falling back to CPU." >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SUCCESS" -eq 0 ]; then
|
||||
run_whisper "ghcr.io/ggml-org/whisper.cpp:main"
|
||||
fi
|
||||
|
||||
[ -f "$WORKDIR/transcript.txt" ] || { echo "Transcription did not produce output" >&2; exit 1; }
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
cp "$WORKDIR/transcript.txt" "$OUT_DIR/${BASENAME}.transcript.txt"
|
||||
[ -f "$WORKDIR/transcript.srt" ] && cp "$WORKDIR/transcript.srt" "$OUT_DIR/${BASENAME}.transcript.srt"
|
||||
|
||||
echo "Wrote ${OUT_DIR}/${BASENAME}.transcript.txt"
|
||||
Reference in New Issue
Block a user