fix: pre-public audit — critical install regression + 7 blockers
Some checks are pending
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / preflight (push) Waiting to run
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / vps-smoke (push) Waiting to run
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:frustration-matrix,kei-frustration-loop,kei-skill-importer,kei-projects-index,kei-projects-watcher,kei-gdrive-import,kei-leak-matrix,kei-skills,kei-gateway,kei-cron-scheduler,kei-export-trajectories,kei-backend-daytona,kei-d… (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-compute-baremetal,kei-compute-vultr,kei-compute-linode,kei-compute-digitalocean,kei-svc-systemd,kei-llm-bridge-mlx name:hosted-sleep-compute]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-diff,kei-scheduler,kei-watch,kei-prune,kei-discover,kei-brain-view,kei-hibernate,kei-ledger-sign,kei-fork name:wave13-15]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-git-gitea,kei-git-forgejo,kei-git-gitlab,kei-git-bitbucket,kei-memory-sled,kei-memory-redis,kei-memory-postgres,kei-memory-sqlite,kei-auth-google,kei-auth-apple,kei-auth-magiclink,kei-auth-webauthn,kei-notify-slack,kei-n… (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-ledger,kei-migrate,kei-changelog,kei-memory,kei-store,kei-conflict-scan,kei-refactor-engine,kei-graph-check,kei-shared,kei-dna-index,kei-pet name:core]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-machine-probe,kei-llm-ollama,kei-llm-llamacpp,kei-llm-mlx,kei-llm-router,kei-model name:llm-stack]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates: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 name:mcp-lbm]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:keisei,kei-forge,kei-runtime,kei-runtime-core,kei-atom-discovery,kei-agent-runtime,kei-capability,kei-provision,kei-entity-store,kei-pipe,kei-cache,kei-spawn,kei-replay name:atom-substrate]) (push) Blocked by required conditions
Some checks are pending
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / preflight (push) Waiting to run
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / vps-smoke (push) Waiting to run
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:frustration-matrix,kei-frustration-loop,kei-skill-importer,kei-projects-index,kei-projects-watcher,kei-gdrive-import,kei-leak-matrix,kei-skills,kei-gateway,kei-cron-scheduler,kei-export-trajectories,kei-backend-daytona,kei-d… (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-compute-baremetal,kei-compute-vultr,kei-compute-linode,kei-compute-digitalocean,kei-svc-systemd,kei-llm-bridge-mlx name:hosted-sleep-compute]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-diff,kei-scheduler,kei-watch,kei-prune,kei-discover,kei-brain-view,kei-hibernate,kei-ledger-sign,kei-fork name:wave13-15]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-git-gitea,kei-git-forgejo,kei-git-gitlab,kei-git-bitbucket,kei-memory-sled,kei-memory-redis,kei-memory-postgres,kei-memory-sqlite,kei-auth-google,kei-auth-apple,kei-auth-magiclink,kei-auth-webauthn,kei-notify-slack,kei-n… (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-ledger,kei-migrate,kei-changelog,kei-memory,kei-store,kei-conflict-scan,kei-refactor-engine,kei-graph-check,kei-shared,kei-dna-index,kei-pet name:core]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-machine-probe,kei-llm-ollama,kei-llm-llamacpp,kei-llm-mlx,kei-llm-router,kei-model name:llm-stack]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates: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 name:mcp-lbm]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:keisei,kei-forge,kei-runtime,kei-runtime-core,kei-atom-discovery,kei-agent-runtime,kei-capability,kei-provision,kei-entity-store,kei-pipe,kei-cache,kei-spawn,kei-replay name:atom-substrate]) (push) Blocked by required conditions
CRITICAL: lib-hooks.sh had an apostrophe ("user's") inside the jq
program's bash single-quote, closing the quote and producing a parse
error so EVERY install aborted at source time (install.sh:71). Caught
by a full minimal e2e (rc=2 then rc=0 after fix). Reworded the jq
comment to drop the apostrophe.
Audit blockers fixed:
- MANIFEST: drop cortex-ui (no such primitive) from 4 profiles + block;
lib-menu desc no longer references it. Profile resolution verified clean.
- lib-dev-hub-forgejo / -zoekt: source lib-launchd.sh (register_launchd
was undefined, so full-hub dev-hub install would fail at runtime).
- kei-message: portable 16-digit id. BSD date prints literal "N" for %N;
fall back to /dev/urandom. Verified numeric in both code paths.
- bootstrap non-TTY default cortex to minimal (matches install.sh; avoids
divergent curl-bash vs direct-install behaviour and 105-crate surprise).
- install.sh stamps ~/.claude/.kei-profile; bin/kei reads it (splash
showed "profile: ?" before, since .installed holds only primitive names).
- README hook count 38 to 54 (real: ls hooks star dot sh).
- web-install warns before it discards local edits in the managed clone.
Verified: 106 shell files bash -n clean; minimal e2e rc=0 (38 agents,
57 hooks, 69 skills, profile stamped, mailbox present).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c347f329aa
commit
3aff00290f
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