Single-commit clean baseline after security scrub of niche-tells, project codenames, internal jargon, and contributor-email leaks. Contents: - 100 Rust crates (_primitives/_rust/) - 37 agent manifests (_manifests/) + generated specs (_generated/) - 67 user-invocable skills (skills/) - 33 hooks (hooks/) - Composition blocks (_blocks/) - Documentation (docs/, README.md) - TS adapter packages (_ts_packages/) - Assembler (_assembler/) - Roles (_roles/) - Templates (_templates/) - Forgejo CI (.forgejo/) Author: Denis Parfionovich <info@greendragon.info> License: see LICENSE.
172 lines
5.8 KiB
Bash
172 lines
5.8 KiB
Bash
# shellcheck shell=bash
|
|
# lib-dev-hub-datasette.sh — install Datasette (SQLite web UI) via pipx + launchd.
|
|
#
|
|
# Datasette serves any SQLite file as an interactive web UI + JSON API.
|
|
# We install via pipx (isolated venv, no system Python pollution) and run as
|
|
# a user-level launchd agent on http://127.0.0.1:8001/.
|
|
#
|
|
# READ-ONLY by design: every DB is opened with `--immutable` so a stray UI
|
|
# action cannot mutate the user's project databases.
|
|
#
|
|
# Architecture:
|
|
# plist (datasette.plist.tmpl) → ${KIT}/dev-hub/datasette-serve.sh wrapper
|
|
# wrapper discovers SQLite DBs at launch time → exec datasette serve
|
|
# This way newly-added DBs are picked up on next launchctl kickstart, with
|
|
# no plist rewrite needed.
|
|
#
|
|
# Sources: lib-log.sh (say/warn/err), lib-launchd.sh (install_service/unload_plist).
|
|
# Globals read: $KIT_DIR, $HOME_DIR.
|
|
|
|
# ---------- helpers (private) ----------
|
|
|
|
# Verify Python 3.11+. Returns 0 on OK, 1 on missing/old.
|
|
_datasette_check_python() {
|
|
if ! command -v python3 >/dev/null 2>&1; then
|
|
err "python3 not found — install via: brew install python@3.11"
|
|
return 1
|
|
fi
|
|
local ver
|
|
ver="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null)"
|
|
local major="${ver%.*}"
|
|
local minor="${ver#*.}"
|
|
if [ "$major" -lt 3 ] || { [ "$major" -eq 3 ] && [ "$minor" -lt 11 ]; }; then
|
|
err "python3 $ver too old (need 3.11+) — install via: brew install python@3.11"
|
|
return 1
|
|
fi
|
|
say " → python3 $ver OK"
|
|
}
|
|
|
|
# Ensure pipx is installed; if missing, install via brew.
|
|
_datasette_ensure_pipx() {
|
|
if command -v pipx >/dev/null 2>&1; then
|
|
say " → pipx $(pipx --version 2>/dev/null) already installed"
|
|
return 0
|
|
fi
|
|
if ! command -v brew >/dev/null 2>&1; then
|
|
err "neither pipx nor brew found — install Homebrew first: https://brew.sh"
|
|
return 1
|
|
fi
|
|
say " → installing pipx via brew"
|
|
brew install pipx
|
|
pipx ensurepath
|
|
}
|
|
|
|
# Write the runtime wrapper script that discovers DBs and execs datasette.
|
|
# Args: <wrapper-path>.
|
|
_datasette_write_wrapper() {
|
|
local wrapper="$1"
|
|
mkdir -p "$(dirname "$wrapper")"
|
|
cat > "$wrapper" <<'WRAPPER_EOF'
|
|
#!/usr/bin/env bash
|
|
# Auto-generated by lib-dev-hub-datasette.sh — do not edit by hand.
|
|
# Discovers SQLite DBs at launch time and serves them via Datasette (read-only).
|
|
set -eu
|
|
DBS=()
|
|
for f in "$HOME/.claude/agents"/*.sqlite "$HOME/Projects"/*/*.sqlite; do
|
|
[ -f "$f" ] && DBS+=("$f")
|
|
done
|
|
META="$HOME/Library/Application Support/keisei/datasette/metadata.yaml"
|
|
# Empty-array expansion is unsafe under `set -u` on bash 3.2 (macOS); branch.
|
|
if [ "${#DBS[@]}" -eq 0 ]; then
|
|
exec "$HOME/.local/bin/datasette" serve \
|
|
--host 127.0.0.1 --port 8001 \
|
|
--metadata "$META"
|
|
else
|
|
exec "$HOME/.local/bin/datasette" serve \
|
|
--host 127.0.0.1 --port 8001 \
|
|
--metadata "$META" \
|
|
--immutable "${DBS[@]}"
|
|
fi
|
|
WRAPPER_EOF
|
|
chmod +x "$wrapper"
|
|
}
|
|
|
|
# Write metadata.yaml if not already present (single-user, read-only defaults).
|
|
# Args: <data-dir>.
|
|
_datasette_write_metadata() {
|
|
local data_dir="$1"
|
|
local meta="$data_dir/metadata.yaml"
|
|
if [ -f "$meta" ]; then
|
|
say " → metadata.yaml already present (preserving user edits)"
|
|
return 0
|
|
fi
|
|
mkdir -p "$data_dir"
|
|
cat > "$meta" <<'META_EOF'
|
|
title: KeiSeiKit DBs
|
|
description: |
|
|
Read-only browser for KeiSeiKit SQLite databases (kei-ledger, kei-memory,
|
|
projects-index, etc.) and any project DB under ~/Projects/. Served by
|
|
Datasette in --immutable mode; no UI action can mutate these files.
|
|
allow_facet: true
|
|
allow_download: false
|
|
default_page_size: 100
|
|
META_EOF
|
|
say " → wrote $meta"
|
|
}
|
|
|
|
# ---------- public API ----------
|
|
|
|
# List SQLite paths to expose to Datasette.
|
|
# Walks: ~/.claude/agents/*.sqlite + ~/Projects/*/*.sqlite (depth 2).
|
|
# Output: newline-separated paths on stdout.
|
|
discover_databases() {
|
|
local f
|
|
for f in "$HOME_DIR/.claude/agents"/*.sqlite "$HOME_DIR/Projects"/*/*.sqlite; do
|
|
[ -f "$f" ] && printf '%s\n' "$f"
|
|
done
|
|
}
|
|
|
|
# Install Datasette + plugins + launchd service. Idempotent.
|
|
install_dev_hub_datasette() {
|
|
say "installing dev-hub-datasette"
|
|
_datasette_check_python || return 1
|
|
_datasette_ensure_pipx || return 1
|
|
|
|
say " → pipx install datasette"
|
|
pipx install datasette 2>&1 | grep -v "already seems to be installed" || true
|
|
|
|
say " → injecting plugins (cluster-map, vega, render-markdown)"
|
|
pipx inject datasette \
|
|
datasette-cluster-map \
|
|
datasette-vega \
|
|
datasette-render-markdown 2>&1 | grep -v "already" || true
|
|
|
|
local data_dir="$HOME_DIR/Library/Application Support/keisei/datasette"
|
|
_datasette_write_metadata "$data_dir"
|
|
|
|
local wrapper="$HOME_DIR/.claude/agents/_primitives/dev-hub/datasette-serve.sh"
|
|
_datasette_write_wrapper "$wrapper"
|
|
say " → wrote wrapper $wrapper"
|
|
|
|
# shellcheck source=./lib-launchd.sh
|
|
. "$KIT_DIR/install/lib-launchd.sh"
|
|
install_service datasette
|
|
|
|
say "Datasette running on http://127.0.0.1:8001/. Browse SQLite databases from the cortex-ui dashboard."
|
|
}
|
|
|
|
# Unload + remove plist. Optional --purge also removes the pipx install.
|
|
# Args: [--purge]
|
|
uninstall_dev_hub_datasette() {
|
|
say "uninstalling dev-hub-datasette"
|
|
# shellcheck source=./lib-launchd.sh
|
|
. "$KIT_DIR/install/lib-launchd.sh"
|
|
unload_plist datasette
|
|
rm -f "$HOME_DIR/.claude/agents/_primitives/dev-hub/datasette-serve.sh"
|
|
if [ "${1:-}" = "--purge" ] && command -v pipx >/dev/null 2>&1; then
|
|
say " → pipx uninstall datasette"
|
|
pipx uninstall datasette || true
|
|
fi
|
|
}
|
|
|
|
# Verify Datasette health endpoint returns 200. Returns 0 on OK, 1 on fail.
|
|
verify_dev_hub_datasette() {
|
|
local code
|
|
code="$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8001/-/health 2>/dev/null || echo 000)"
|
|
if [ "$code" = "200" ]; then
|
|
say "datasette health OK (200)"
|
|
return 0
|
|
fi
|
|
err "datasette health failed (HTTP $code) — check logs at $HOME_DIR/Library/Logs/keisei/datasette/"
|
|
return 1
|
|
}
|