Initial commit — split out from cli_utils
Producer-side MemPalace tooling: two bash wrappers that bridge opencode session history and project documentation into the palace. Originally developed in cli_utils (2026-04-28); split into its own repo on 2026-04-30 because the conceptual fit was weak — cli_utils is interactive shell tooling, while this is agent memory infrastructure with its own architecture, dependency surface, and growth trajectory. Contents: - bin/mempalace-docs — docs-only mining wrapper (originally a2ddcc9 in cli_utils), bridges the gap until MemPalace PR #1213 (exclude_patterns) merges upstream. - bin/mempalace-session — opencode → palace session bridge (originally dacca0e in cli_utils). Reads ~/.local/share/opencode/opencode.db, exports each session to Claude Code JSONL, mines via 'mempalace mine --mode convos'. Bridges the gap until opencode session-stopping hooks + an opencode harness in hooks_cli.py land upstream. - ARCHITECTURE.md — canonical spec: architecture diagram, component details, setup recipe, operational notes, upstream-retirement roadmap. Originally a4cf314 in cli_utils. - SKILL.md — companion agent skill (producer side). Pairs with the consumer-side mempalace skill. Symlinked into ~/.agents/skills/opencode-mempalace-bridge/ by install.sh. - install.sh — idempotent installer, also handles --uninstall. - AGENTS.md — repo conventions. History of the individual files is not preserved in this split; see cli_utils (gitea.jordbo.se/joakimp/cli_utils) commits a2ddcc9, dacca0e, and a4cf314 for the original authorship context.
This commit is contained in:
+184
@@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env bash
|
||||
# install.sh — install mempalace-toolkit executables + companion agent skill
|
||||
#
|
||||
# Idempotent. Safe to re-run after container recreate.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── locate self ──────────────────────────────────────
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
# ── targets ──────────────────────────────────────────
|
||||
BIN_SRC="${SCRIPT_DIR}/bin"
|
||||
BIN_DEST="${HOME}/.local/bin"
|
||||
|
||||
SKILL_SRC="${SCRIPT_DIR}/SKILL.md"
|
||||
SKILL_DEST_DIR="${HOME}/.agents/skills/opencode-mempalace-bridge"
|
||||
SKILL_DEST="${SKILL_DEST_DIR}/SKILL.md"
|
||||
|
||||
# ── args ─────────────────────────────────────────────
|
||||
ACTION="install"
|
||||
ASSUME_YES="no"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--uninstall) ACTION="uninstall"; shift ;;
|
||||
-y|--yes) ASSUME_YES="yes"; shift ;;
|
||||
-h|--help)
|
||||
cat <<EOF
|
||||
install.sh — install mempalace-toolkit
|
||||
|
||||
Usage:
|
||||
./install.sh # install (interactive confirm)
|
||||
./install.sh --yes # install without prompt
|
||||
./install.sh --uninstall # remove symlinks
|
||||
|
||||
What install does:
|
||||
- Symlinks each executable in bin/ into ~/.local/bin/
|
||||
- Symlinks SKILL.md into ~/.agents/skills/opencode-mempalace-bridge/SKILL.md
|
||||
(auto-discovered by opencode; run agents-sync from cli_utils to also
|
||||
reach Claude Code and Kiro)
|
||||
|
||||
What uninstall does:
|
||||
- Removes symlinks in ~/.local/bin/ that point into this repo
|
||||
- Removes the skill symlink if it points into this repo
|
||||
EOF
|
||||
exit 0 ;;
|
||||
*) echo "Unknown flag: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ── helpers ──────────────────────────────────────────
|
||||
ok() { printf ' \e[32m✓\e[0m %s\n' "$*"; }
|
||||
note() { printf '==> %s\n' "$*"; }
|
||||
warn() { printf ' \e[33m!\e[0m %s\n' "$*" >&2; }
|
||||
err() { printf ' \e[31m✗\e[0m %s\n' "$*" >&2; }
|
||||
|
||||
confirm() {
|
||||
[[ "$ASSUME_YES" == "yes" ]] && return 0
|
||||
read -r -p "Proceed? [y/N] " ans
|
||||
[[ "$ans" =~ ^[Yy]$ ]]
|
||||
}
|
||||
|
||||
link_if_into_repo() {
|
||||
# Return 0 if $1 is a symlink pointing into $SCRIPT_DIR
|
||||
local target
|
||||
[[ -L "$1" ]] || return 1
|
||||
target=$(readlink -f "$1")
|
||||
[[ "$target" == "$SCRIPT_DIR"/* ]]
|
||||
}
|
||||
|
||||
# ── install ──────────────────────────────────────────
|
||||
install_bin() {
|
||||
mkdir -p "$BIN_DEST"
|
||||
note "Symlinking bin/ executables into $BIN_DEST"
|
||||
local count=0
|
||||
for src in "$BIN_SRC"/*; do
|
||||
[[ -x "$src" && -f "$src" ]] || continue
|
||||
local name; name=$(basename "$src")
|
||||
local dest="$BIN_DEST/$name"
|
||||
if [[ -e "$dest" || -L "$dest" ]]; then
|
||||
if link_if_into_repo "$dest"; then
|
||||
ok "Already linked: $name"
|
||||
count=$((count+1))
|
||||
continue
|
||||
else
|
||||
warn "Skipping $name: $dest exists and is not our symlink"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
ln -s "$src" "$dest"
|
||||
ok "Linked $name → $src"
|
||||
count=$((count+1))
|
||||
done
|
||||
echo
|
||||
ok "Installed $count executable(s)"
|
||||
}
|
||||
|
||||
install_skill() {
|
||||
note "Linking companion agent skill"
|
||||
mkdir -p "$SKILL_DEST_DIR"
|
||||
if [[ -e "$SKILL_DEST" || -L "$SKILL_DEST" ]]; then
|
||||
if link_if_into_repo "$SKILL_DEST"; then
|
||||
ok "Skill already linked"
|
||||
return 0
|
||||
else
|
||||
warn "Skipping skill: $SKILL_DEST exists and is not our symlink"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
ln -s "$SKILL_SRC" "$SKILL_DEST"
|
||||
ok "Linked SKILL.md → $SKILL_SRC"
|
||||
}
|
||||
|
||||
check_path() {
|
||||
case ":$PATH:" in
|
||||
*":$BIN_DEST:"*) : ;;
|
||||
*) warn "$BIN_DEST is not on \$PATH. Add to your shell rc:";
|
||||
printf ' export PATH="%s:$PATH"\n' "\$HOME/.local/bin" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
do_install() {
|
||||
echo
|
||||
echo "mempalace-toolkit installer"
|
||||
echo "Repository: $SCRIPT_DIR"
|
||||
echo
|
||||
echo "==> Installation plan:"
|
||||
echo " Symlink executables in bin/ into $BIN_DEST"
|
||||
echo " Symlink SKILL.md into $SKILL_DEST"
|
||||
echo
|
||||
confirm || { echo "Aborted."; exit 0; }
|
||||
echo
|
||||
install_bin
|
||||
echo
|
||||
install_skill
|
||||
echo
|
||||
check_path
|
||||
echo
|
||||
ok "Done."
|
||||
echo
|
||||
echo "Next: ./bin/mempalace-session --dry-run"
|
||||
echo " or: ./bin/mempalace-docs /path/to/project --dry-run"
|
||||
}
|
||||
|
||||
# ── uninstall ────────────────────────────────────────
|
||||
do_uninstall() {
|
||||
echo
|
||||
echo "mempalace-toolkit uninstaller"
|
||||
echo "Repository: $SCRIPT_DIR"
|
||||
echo
|
||||
confirm || { echo "Aborted."; exit 0; }
|
||||
echo
|
||||
|
||||
note "Removing executable symlinks from $BIN_DEST"
|
||||
local removed=0
|
||||
for src in "$BIN_SRC"/*; do
|
||||
[[ -x "$src" && -f "$src" ]] || continue
|
||||
local name; name=$(basename "$src")
|
||||
local dest="$BIN_DEST/$name"
|
||||
if link_if_into_repo "$dest"; then
|
||||
rm "$dest"
|
||||
ok "Removed $name"
|
||||
removed=$((removed+1))
|
||||
fi
|
||||
done
|
||||
ok "Removed $removed executable symlink(s)"
|
||||
|
||||
echo
|
||||
note "Removing skill symlink"
|
||||
if link_if_into_repo "$SKILL_DEST"; then
|
||||
rm "$SKILL_DEST"
|
||||
ok "Removed skill symlink"
|
||||
else
|
||||
ok "No skill symlink to remove"
|
||||
fi
|
||||
|
||||
echo
|
||||
ok "Done."
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
install) do_install ;;
|
||||
uninstall) do_uninstall ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user