fix: pre-public audit — critical install regression + 7 blockers (#41)
Mirror of keigit 3aff0029. lib-hooks.sh apostrophe-in-jq closed the bash single-quote and broke every install (fixed). cortex-ui removed from profiles+menu; forgejo/zoekt source lib-launchd; portable kei-message id (BSD date fallback); non-TTY default minimal; install stamps .kei-profile; README hook count 54; web-install warns before discarding local edits in the managed clone.
This commit is contained in:
parent
4dbe6fd159
commit
a299427367
11 changed files with 41 additions and 25 deletions
|
|
@ -8,8 +8,8 @@ OpenClaw / Kimi from the same source-of-truth.
|
||||||
|
|
||||||
**Apache 2.0** — explicit patent grant + retaliation clause. 105 Rust
|
**Apache 2.0** — explicit patent grant + retaliation clause. 105 Rust
|
||||||
crates [REAL: `grep -E '^\s*"[a-z-]+",' _primitives/_rust/Cargo.toml | wc -l`],
|
crates [REAL: `grep -E '^\s*"[a-z-]+",' _primitives/_rust/Cargo.toml | wc -l`],
|
||||||
68 skills [REAL: `ls skills/ | wc -l`], 38 hooks
|
68 skills [REAL: `ls skills/ | wc -l`], 54 hooks
|
||||||
[REAL: `grep -c '"command":' settings-snippet.json`], 38 agent manifests
|
[REAL: `ls hooks/*.sh | wc -l`], 38 agent manifests
|
||||||
[REAL: `ls _manifests/*.toml | wc -l`], 85 substrate blocks
|
[REAL: `ls _manifests/*.toml | wc -l`], 85 substrate blocks
|
||||||
[REAL: `find _blocks/ -name '*.md' | wc -l`], 18 capability atoms
|
[REAL: `find _blocks/ -name '*.md' | wc -l`], 18 capability atoms
|
||||||
[REAL: `find _capabilities/ -mindepth 2 -maxdepth 2 -type d | wc -l`],
|
[REAL: `find _capabilities/ -mindepth 2 -maxdepth 2 -type d | wc -l`],
|
||||||
|
|
@ -83,7 +83,7 @@ The web installer (`web-install.sh` in this repo, served at
|
||||||
repo and delegates to `bootstrap.sh` — single source of truth, no
|
repo and delegates to `bootstrap.sh` — single source of truth, no
|
||||||
duplicated install logic.
|
duplicated install logic.
|
||||||
|
|
||||||
38 agents + 68 skills + 38 hooks + nightly consolidation wired in
|
38 agents + 68 skills + 54 hooks + nightly consolidation wired in
|
||||||
~60 seconds. Twelve install profiles (`outcome-only`, `minimal`,
|
~60 seconds. Twelve install profiles (`outcome-only`, `minimal`,
|
||||||
`core`, `frontend`, `ops`, `dev`, `mcp`, `cortex`, `local-mirror`,
|
`core`, `frontend`, `ops`, `dev`, `mcp`, `cortex`, `local-mirror`,
|
||||||
`dashboard`, `full-hub`, `full`) defined in
|
`dashboard`, `full-hub`, `full`) defined in
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ buddy = ["kei-buddy", "kei-telegram-webhook", "kei-shared", "kei-chat-store",
|
||||||
# previous one — `dashboard` extends `local-mirror`, `full-hub` extends
|
# previous one — `dashboard` extends `local-mirror`, `full-hub` extends
|
||||||
# `dashboard`. Native macOS arm64 (brew + launchd plists). See
|
# `dashboard`. Native macOS arm64 (brew + launchd plists). See
|
||||||
# `install/lib-dev-hub-*.sh` for the install logic per component.
|
# `install/lib-dev-hub-*.sh` for the install logic per component.
|
||||||
local-mirror = ["kei-cortex", "cortex-ui", "kei-pet", "kei-shared", "kei-ledger", "kei-memory", "frustration-matrix", "kei-skill-importer", "kei-router", "kei-dna-index", "kei-atom-discovery", "dev-hub-forgejo", "dev-hub-forgejo-runner"]
|
local-mirror = ["kei-cortex", "kei-pet", "kei-shared", "kei-ledger", "kei-memory", "frustration-matrix", "kei-skill-importer", "kei-router", "kei-dna-index", "kei-atom-discovery", "dev-hub-forgejo", "dev-hub-forgejo-runner"]
|
||||||
dashboard = ["kei-cortex", "cortex-ui", "kei-pet", "kei-shared", "kei-ledger", "kei-memory", "frustration-matrix", "kei-skill-importer", "kei-router", "kei-dna-index", "kei-atom-discovery", "dev-hub-forgejo", "dev-hub-forgejo-runner", "kei-projects-index", "kei-projects-watcher", "dev-hub-datasette"]
|
dashboard = ["kei-cortex", "kei-pet", "kei-shared", "kei-ledger", "kei-memory", "frustration-matrix", "kei-skill-importer", "kei-router", "kei-dna-index", "kei-atom-discovery", "dev-hub-forgejo", "dev-hub-forgejo-runner", "kei-projects-index", "kei-projects-watcher", "dev-hub-datasette"]
|
||||||
full-hub = ["kei-cortex", "cortex-ui", "kei-pet", "kei-shared", "kei-ledger", "kei-memory", "frustration-matrix", "kei-skill-importer", "kei-router", "kei-dna-index", "kei-atom-discovery", "dev-hub-forgejo", "dev-hub-forgejo-runner", "kei-projects-index", "kei-projects-watcher", "dev-hub-datasette", "dev-hub-zoekt", "dev-hub-mdbook", "dev-hub-restic", "dev-hub-gdrive-import"]
|
full-hub = ["kei-cortex", "kei-pet", "kei-shared", "kei-ledger", "kei-memory", "frustration-matrix", "kei-skill-importer", "kei-router", "kei-dna-index", "kei-atom-discovery", "dev-hub-forgejo", "dev-hub-forgejo-runner", "kei-projects-index", "kei-projects-watcher", "dev-hub-datasette", "dev-hub-zoekt", "dev-hub-mdbook", "dev-hub-restic", "dev-hub-gdrive-import"]
|
||||||
full = ["tomd", "kei-doctor", "kei-ledger", "kei-migrate", "kei-changelog", "ssh-check", "firewall-diff", "mock-render", "visual-diff", "tokens-sync", "design-scrape", "live-preview", "figma-tokens", "frontend-inspect", "screenshot-decode", "provision-hetzner", "provision-vultr", "harden-base", "metrics-scrape", "log-ship", "kei-ci-lint", "kei-docs-scaffold", "kei-memory", "kei-conflict-scan", "kei-refactor-engine", "kei-graph-check", "kei-store", "kei-router", "kei-sage", "kei-task", "kei-chat-store", "kei-crossdomain", "kei-search-core", "kei-content-store", "kei-social-store", "kei-curator", "kei-auth", "kei-artifact", "keisei", "kei-agent-runtime", "kei-capability", "kei-provision", "kei-entity-store", "kei-pipe", "kei-cache", "kei-spawn", "kei-replay", "kei-cortex", "cortex-ui", "kei-pet", "kei-shared", "frustration-matrix", "kei-skill-importer", "kei-projects-index", "kei-projects-watcher", "dev-hub-forgejo", "dev-hub-forgejo-runner", "dev-hub-datasette", "dev-hub-zoekt", "dev-hub-mdbook", "dev-hub-restic", "dev-hub-gdrive-import"]
|
full = ["tomd", "kei-doctor", "kei-ledger", "kei-migrate", "kei-changelog", "ssh-check", "firewall-diff", "mock-render", "visual-diff", "tokens-sync", "design-scrape", "live-preview", "figma-tokens", "frontend-inspect", "screenshot-decode", "provision-hetzner", "provision-vultr", "harden-base", "metrics-scrape", "log-ship", "kei-ci-lint", "kei-docs-scaffold", "kei-memory", "kei-conflict-scan", "kei-refactor-engine", "kei-graph-check", "kei-store", "kei-router", "kei-sage", "kei-task", "kei-chat-store", "kei-crossdomain", "kei-search-core", "kei-content-store", "kei-social-store", "kei-curator", "kei-auth", "kei-artifact", "keisei", "kei-agent-runtime", "kei-capability", "kei-provision", "kei-entity-store", "kei-pipe", "kei-cache", "kei-spawn", "kei-replay", "kei-cortex", "kei-pet", "kei-shared", "frustration-matrix", "kei-skill-importer", "kei-projects-index", "kei-projects-watcher", "dev-hub-forgejo", "dev-hub-forgejo-runner", "dev-hub-datasette", "dev-hub-zoekt", "dev-hub-mdbook", "dev-hub-restic", "dev-hub-gdrive-import"]
|
||||||
|
|
||||||
# --- shell primitives (13) -------------------------------------------------
|
# --- shell primitives (13) -------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -357,12 +357,6 @@ crate = "kei-cortex"
|
||||||
deps = ["python3 (>=3.9, for whisper_worker.py subprocess)", "pip install -r scripts/requirements.txt", "ffmpeg (on PATH, faster-whisper audio demux)"]
|
deps = ["python3 (>=3.9, for whisper_worker.py subprocess)", "pip install -r scripts/requirements.txt", "ffmpeg (on PATH, faster-whisper audio demux)"]
|
||||||
desc = "Local HTTP daemon exposing chat/TTS/STT/portrait endpoints — backs cortex-ui browser app"
|
desc = "Local HTTP daemon exposing chat/TTS/STT/portrait endpoints — backs cortex-ui browser app"
|
||||||
|
|
||||||
[primitive.cortex-ui]
|
|
||||||
kind = "node"
|
|
||||||
path = "_ts_packages/packages/cortex-ui"
|
|
||||||
deps = ["node>=18", "pnpm"]
|
|
||||||
desc = "Svelte 5 + Vite 5 web UI for kei-cortex daemon (chat panel, Live2D pet renderer, portrait uploader)"
|
|
||||||
|
|
||||||
[primitive.frustration-matrix]
|
[primitive.frustration-matrix]
|
||||||
kind = "rust"
|
kind = "rust"
|
||||||
crate = "frustration-matrix"
|
crate = "frustration-matrix"
|
||||||
|
|
|
||||||
10
bin/kei
10
bin/kei
|
|
@ -62,12 +62,10 @@ agent_count() {
|
||||||
|
|
||||||
# Profile from .installed marker file
|
# Profile from .installed marker file
|
||||||
profile_name() {
|
profile_name() {
|
||||||
local f="${AGENTS_DIR}/_primitives/.installed"
|
# install.sh stamps the chosen profile here; .installed only holds primitive
|
||||||
if [ -f "$f" ]; then
|
# names (so the old `grep ^profile .installed` always returned "?").
|
||||||
grep -E "^profile" "$f" 2>/dev/null | head -1 | awk -F= '{gsub(/[ "]/,"",$2); print $2}' || echo "?"
|
local f="$HOME/.claude/.kei-profile"
|
||||||
else
|
if [ -f "$f" ]; then head -1 "$f"; else echo "?"; fi
|
||||||
echo "?"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Last Phase B sleep timestamp
|
# Last Phase B sleep timestamp
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,11 @@ prompt_profile() {
|
||||||
# Interactive iff stdin is a terminal. NOT stdout: web-install.sh tees stdout
|
# Interactive iff stdin is a terminal. NOT stdout: web-install.sh tees stdout
|
||||||
# to a logfile (pipe), so -t 1 is false even in an interactive curl|bash.
|
# to a logfile (pipe), so -t 1 is false even in an interactive curl|bash.
|
||||||
# Prompts print to the terminal via tee; the menu reads from stdin.
|
# Prompts print to the terminal via tee; the menu reads from stdin.
|
||||||
if [ ! -t 0 ]; then PROFILE="cortex"; return 0; fi
|
# Non-interactive (CI / piped, no controlling terminal) → minimal: fast,
|
||||||
|
# no 105-crate compile, can't half-fail. Matches install.sh's own default
|
||||||
|
# (was "cortex" here → divergent install vs direct install.sh). Opt up with
|
||||||
|
# --profile=cortex/full-hub.
|
||||||
|
if [ ! -t 0 ]; then PROFILE="minimal"; return 0; fi
|
||||||
cat <<'WIZARD'
|
cat <<'WIZARD'
|
||||||
|
|
||||||
╔═══════════════════════════════════════════════════════════════════╗
|
╔═══════════════════════════════════════════════════════════════════╗
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,9 @@ case "$PROFILE" in
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
say "profile: $PROFILE"
|
say "profile: $PROFILE"
|
||||||
|
# Stamp the chosen profile so `kei` splash + tools can show it (bin/kei reads this).
|
||||||
|
mkdir -p "$HOME_DIR/.claude" 2>/dev/null || true
|
||||||
|
printf '%s\n' "$PROFILE" > "$HOME_DIR/.claude/.kei-profile" 2>/dev/null || true
|
||||||
|
|
||||||
# --- resolve profile -> primitive list (UNCONDITIONAL, SSoT) -------------
|
# --- resolve profile -> primitive list (UNCONDITIONAL, SSoT) -------------
|
||||||
# Must run BEFORE any reader of PROFILE_PRIMS: the --no-execute plan block
|
# Must run BEFORE any reader of PROFILE_PRIMS: the --no-execute plan block
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,8 @@ _dhf_bootstrap_admin_user() {
|
||||||
# Public — install entry point. Called from install.sh primitives phase.
|
# Public — install entry point. Called from install.sh primitives phase.
|
||||||
install_dev_hub_forgejo() {
|
install_dev_hub_forgejo() {
|
||||||
say "[dev-hub-forgejo] install starting"
|
say "[dev-hub-forgejo] install starting"
|
||||||
|
# shellcheck source=./lib-launchd.sh
|
||||||
|
. "$KIT_DIR/install/lib-launchd.sh" # install_service / detect_brew_prefix (was unsourced → command not found)
|
||||||
_dhf_check_brew || return 1
|
_dhf_check_brew || return 1
|
||||||
_dhf_brew_install || return 1
|
_dhf_brew_install || return 1
|
||||||
_dhf_ensure_data_dir || return 1
|
_dhf_ensure_data_dir || return 1
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,8 @@ _dhz_print_banner() {
|
||||||
# Public — install entry point. Called from install.sh primitives phase.
|
# Public — install entry point. Called from install.sh primitives phase.
|
||||||
install_dev_hub_zoekt() {
|
install_dev_hub_zoekt() {
|
||||||
say "[dev-hub-zoekt] install starting"
|
say "[dev-hub-zoekt] install starting"
|
||||||
|
# shellcheck source=./lib-launchd.sh
|
||||||
|
. "$KIT_DIR/install/lib-launchd.sh" # install_service / detect_brew_prefix (was unsourced → command not found)
|
||||||
_dhz_check_brew || return 1
|
_dhz_check_brew || return 1
|
||||||
_dhz_check_go_runtime
|
_dhz_check_go_runtime
|
||||||
_dhz_brew_install || return 1
|
_dhz_brew_install || return 1
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,9 @@ _jq_merge_hooks() {
|
||||||
| reduce ($add.hooks | keys[]) as $phase ($orig;
|
| reduce ($add.hooks | keys[]) as $phase ($orig;
|
||||||
.hooks[$phase] = (
|
.hooks[$phase] = (
|
||||||
((.hooks[$phase] // []) + ($add.hooks[$phase] // []))
|
((.hooks[$phase] // []) + ($add.hooks[$phase] // []))
|
||||||
# Normalize null/absent matcher → "" (Claude Code /doctor rejects null;
|
# Normalize null/absent matcher to "" (Claude Code /doctor rejects null;
|
||||||
# user's pre-kit hooks often have no matcher field). Before group_by so
|
# pre-kit user hooks often have no matcher field) before group_by so
|
||||||
# null + "" collapse into one group.
|
# null and "" collapse into one group.
|
||||||
| map(.matcher //= "")
|
| map(.matcher //= "")
|
||||||
| group_by(.matcher)
|
| group_by(.matcher)
|
||||||
| map(
|
| map(
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ menu_whiptail_profile() {
|
||||||
"ops" "+ 9 infra tools — provision, ssh-check, firewall-diff" OFF \
|
"ops" "+ 9 infra tools — provision, ssh-check, firewall-diff" OFF \
|
||||||
"dev" "+ 17 dev tools — kei-migrate, kei-memory, deep-sleep" OFF \
|
"dev" "+ 17 dev tools — kei-migrate, kei-memory, deep-sleep" OFF \
|
||||||
"mcp" "+ 10 MCP tools — kei-router, kei-sage, kei-auth, kei-pet" OFF \
|
"mcp" "+ 10 MCP tools — kei-router, kei-sage, kei-auth, kei-pet" OFF \
|
||||||
"cortex" "+ 11 cortex stack — kei-cortex daemon + cortex-ui" OFF \
|
"cortex" "+ 11 cortex stack — kei-cortex daemon + UI primitives" OFF \
|
||||||
"full" "+ all 62 primitives (~5 min, 380 MB)" OFF \
|
"full" "+ all 62 primitives (~5 min, 380 MB)" OFF \
|
||||||
"local-mirror" "dev hub: cortex + Forgejo + CI runner (+ 13 prims)" OFF \
|
"local-mirror" "dev hub: cortex + Forgejo + CI runner (+ 13 prims)" OFF \
|
||||||
"dashboard" "local-mirror + projects-index + Datasette (+ 16 prims)" OFF \
|
"dashboard" "local-mirror + projects-index + Datasette (+ 16 prims)" OFF \
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,13 @@ case "$cmd" in
|
||||||
done
|
done
|
||||||
body="${body# }"
|
body="${body# }"
|
||||||
[ -n "$body" ] || { echo "usage: kei message send [--to <name|all>] <text>" >&2; exit 1; }
|
[ -n "$body" ] || { echo "usage: kei message send [--to <name|all>] <text>" >&2; exit 1; }
|
||||||
id="$(date +%s)$(date +%N 2>/dev/null | cut -c1-6 || printf '000000')"
|
# Sub-second component: GNU `date +%N` where available; on stock macOS (BSD
|
||||||
|
# date) %N is unsupported and prints literal "N" → fall back to /dev/urandom.
|
||||||
|
# Result id = epoch(10) + 6 digits = 16-digit integer, safely < 2^53.
|
||||||
|
ns="$(date +%N 2>/dev/null)"
|
||||||
|
case "$ns" in *[!0-9]*|'') ns="$(od -An -N4 -tu4 /dev/urandom 2>/dev/null | tr -dc 0-9)" ;; esac
|
||||||
|
sub="$(printf '%s000000' "$ns" | cut -c1-6)"
|
||||||
|
id="$(date +%s)${sub}"
|
||||||
jq -cn --argjson id "$id" --arg ts "$(date -u +%FT%TZ)" \
|
jq -cn --argjson id "$id" --arg ts "$(date -u +%FT%TZ)" \
|
||||||
--arg from "$me" --arg to "$to" --arg body "$body" \
|
--arg from "$me" --arg to "$to" --arg body "$body" \
|
||||||
'{id:$id, ts:$ts, from:$from, to:$to, body:$body}' >> "$LOG"
|
'{id:$id, ts:$ts, from:$from, to:$to, body:$body}' >> "$LOG"
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@ mkdir -p "$(dirname "$KEISEI_ROOT")"
|
||||||
if [ -d "$KEISEI_ROOT/.git" ]; then
|
if [ -d "$KEISEI_ROOT/.git" ]; then
|
||||||
say "pulling $KEISEI_REF in $KEISEI_ROOT"
|
say "pulling $KEISEI_REF in $KEISEI_ROOT"
|
||||||
git -C "$KEISEI_ROOT" fetch --depth=1 origin "$KEISEI_REF"
|
git -C "$KEISEI_ROOT" fetch --depth=1 origin "$KEISEI_REF"
|
||||||
|
# reset --hard discards ANY local edits in this managed clone. It's a managed
|
||||||
|
# dir (don't hand-edit it — change the repo + push instead), but warn loudly
|
||||||
|
# so a manual tweak isn't lost silently.
|
||||||
|
if ! git -C "$KEISEI_ROOT" diff --quiet 2>/dev/null \
|
||||||
|
|| ! git -C "$KEISEI_ROOT" diff --cached --quiet 2>/dev/null; then
|
||||||
|
say " ⚠ local changes in $KEISEI_ROOT will be DISCARDED by reset --hard"
|
||||||
|
fi
|
||||||
git -C "$KEISEI_ROOT" reset --hard "origin/$KEISEI_REF"
|
git -C "$KEISEI_ROOT" reset --hard "origin/$KEISEI_REF"
|
||||||
else
|
else
|
||||||
say "cloning $KEISEI_REPO ($KEISEI_REF) → $KEISEI_ROOT"
|
say "cloning $KEISEI_REPO ($KEISEI_REF) → $KEISEI_ROOT"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue