Commit Graph

18 Commits

Author SHA1 Message Date
joakimp 90e70fff61 docs: add Ecosystem diagram to README + update harness-extension conventions post-split
Two small doc updates consolidating the session's architectural arc:

1. README.md gets a new 'Ecosystem' section (after the contents list,
   before 'Why this exists') showing the five-repo composition:
     myconfigs -> opencode-toolkit + pi-toolkit -> mempalace-toolkit
   Plus an ownership table clarifying which scope lives where. The
   diagram makes the opt-out pattern visible \u2014 opencode-devbox's slim
   container path skips mempalace-toolkit and still gets a functional
   stack.

2. AGENTS.md 'Adding a new harness extension' section was still written
   for the pre-split extensions/pi/ which had keybindings.json +
   settings.example.json + pi-env.zsh. Rewrote to reflect:
   - Bridge-only scope (harness-generic config goes in <harness>-toolkit).
   - 'Probe for the sibling toolkit' step replaces the old symlink-keybindings
     and template-settings steps.
   - Worked example now points at install_pi_extension + check_pi_toolkit
     rather than the four functions that moved out.
   - Explicitly names the pattern: opencode-toolkit + pi-toolkit as
     the two existing examples of the sibling-toolkit convention.
2026-05-05 17:50:13 +02:00
joakimp 16915f0e55 refactor: split pi-generic config into pi-toolkit repo
Parallel to the opencode-toolkit split earlier today. Pi's own config
(keybindings, shell env loader, settings template) moves to a new
sibling repo so opencode-devbox's mempalace opt-out can build slim
containers that include pi without dragging in chromadb + embedding
models (~300 MB).

What moved to pi-toolkit (https://gitea.jordbo.se/joakimp/pi-toolkit):
- extensions/pi/keybindings.json          (mosh/tmux newline fix)
- extensions/pi/pi-env.zsh                (sources ~/.config/pi/.env)
- extensions/pi/settings.example.json     (Bedrock template)
- install.sh::install_pi_keybindings      (symlink step)
- install.sh::install_pi_env_loader       (cp step + bash fallback)
- install.sh::check_pi_settings           (probe)
- install.sh::check_aws_env               (probe)

What stays here (this is the pi\u2194mempalace bridge, mempalace-side):
- extensions/pi/mempalace.ts              (the MCP extension)
- install.sh::install_pi_extension        (symlink step)
- NEW: install.sh::check_pi_toolkit       (probe: warns if pi is
                                           installed but pi-toolkit's
                                           artifacts are missing, with
                                           git-clone pointer)

install.sh shrank from 520 to 403 lines. Uninstall mirror correctly
does NOT touch pi-toolkit-owned files (explicit comment).

Docs updated:
- extensions/pi/README.md: rewritten as 'pi\u2194MemPalace MCP bridge',
  recipe becomes 'Deploying pi with mempalace' (pi-toolkit step 3,
  this repo step 5).
- AGENTS.md: Structure block + 'What install.sh does' section reflect
  the narrower scope and list the four things that moved out.
- README.md: repo-contents line + Setup section's deploy summary.

Verified on tor-ms22: full install\u2192uninstall\u2192reinstall lifecycle clean.
After mempalace-toolkit uninstall, pi-toolkit artifacts
(~/.pi/agent/keybindings.json, ~/.oh-my-zsh/custom/pi-env.zsh) remain
intact \u2014 correctly untouched. check_pi_toolkit probe fires green when
both exist.
2026-05-05 17:26:53 +02:00
joakimp 118bd20fec feat(extensions/pi): ship pi-env.zsh shell loader
The loader that sources ~/.config/pi/.env into every shell was only
living in the myconfigs tor-ms22 backup \u2014 a fresh machine had nowhere
to get it from except copying by hand. Now canonical here.

- extensions/pi/pi-env.zsh: 20-line POSIX-compatible loader
  (set -a; source ~/.config/pi/.env; set +a). Works in bash and zsh.
- install.sh install_pi_env_loader:
  * oh-my-zsh detected (~/.oh-my-zsh/custom/ exists)
    \u2192 cp into that dir (NOT symlink \u2014 that dir is typically part of
      a dotfiles backup, and a symlink to mempalace-toolkit would
      break when restored on another host).
    \u2192 Idempotent: if target content matches repo, says 'already
      installed'. If it differs, leaves user edits alone and points
      at diff for manual reconcile.
  * No oh-my-zsh \u2192 prints source-this-line snippet for ~/.zshrc or
    ~/.bashrc (derived from $SHELL). Does NOT auto-edit rc files.
- install.sh uninstall: only removes the copy if content still matches
  repo. Local edits preserved.
- Docs:
  * extensions/pi/README.md Environment setup section rewritten with
    both install paths, step 5 of deploy recipe updated.
  * AGENTS.md Structure block lists pi-env.zsh.
  * Root README repo-contents line mentions it.

Verified on tor-ms22: install fresh \u2192 uninstall (content match \u2192 remove)
\u2192 reinstall \u2192 zsh -ic loads AWS vars correctly. Also tested bash fallback
path via HOME=/tmp/fake-home SHELL=/bin/bash \u2014 prints right .bashrc snippet.
2026-05-05 16:58:56 +02:00
joakimp 71c335148a docs(pi): full 'new machine' deploy recipe in extensions/pi/README
Consolidates the step-by-step recipe that's been living in diary entries
and session chat into the canonical pi bring-up doc. Covers:

  0. Prerequisites (zsh+oh-my-zsh, uv, tmux 3.2+, AWS creds)
  1. Dotfiles: myconfigs provision (tmux CSI-u, ~/.config/pi/.env, zsh loader)
  2. pi install (upstream brew/npm)
  3. mempalace CLI (uv tool install) + mempalace-toolkit install.sh
  4. pi settings bootstrap (start without --model, region prefix table)
  5. AWS env verification (git-crypt unlock gotcha)
  6. Opencode MCP registration pointer (if applicable)
  7. First run + wake-up injection smoke test
  + Verification checklist + uninstall

Root README.md adds a short summary box in the Setup section pointing at
the full recipe, so readers coming in from the front door find the pi
path immediately but the details stay with the files they install.

Covers: macOS + Linux. Works for homelab / work-macos / any myconfigs
profile that ships .config/pi/ + pi-env.zsh.
2026-05-05 15:20:47 +02:00
joakimp 854ae41f65 feat(extensions/pi): keybindings symlink + settings template + AWS/pi probes
Round out the pi bring-up story so a fresh machine can reach a working
pi+mempalace install with just `git clone && ./install.sh`:

- extensions/pi/keybindings.json: generic mosh/tmux newline fix
  (shift+enter, ctrl+j, alt+j). Safe on any machine — not
  region/account-specific. Symlinked into ~/.pi/agent/.
- extensions/pi/settings.example.json: template for `settings.json`
  so pi can start without --provider/--model. NOT symlinked — pi
  rewrites settings.json at runtime (lastChangelogVersion bumps),
  which would dirty the repo. Installer prints the cp + edit hint.
- install.sh: new install_pi_keybindings + uninstall mirror; new
  check_pi_settings probe (warns if settings.json missing); new
  check_aws_env probe (warns if AWS_PROFILE/AWS_REGION unset and
  settings.json selects amazon-bedrock). All new steps gated on
  pi being installed (~/.pi/agent/extensions/ exists).
- extensions/pi/README.md: documents keybindings rationale,
  settings bootstrap, and the recommended ~/.config/pi/.env +
  ~/.oh-my-zsh/custom/pi-env.zsh env layout (paired with the
  myconfigs commit 884e329 that split AWS vars out of
  ~/.config/opencode/.env).

Verified on tor-ms22: full install → uninstall → reinstall cycle,
new shell loads AWS_PROFILE/AWS_REGION from the new pi-env.zsh hook.

Works on macOS and Linux (plain ln -s, POSIX bash).
2026-05-05 13:59:20 +02:00
joakimp ef1d022fbc feat(extensions): version-control pi mempalace extension + install.sh symlink
The pi coding-agent extension at ~/.pi/agent/extensions/mempalace.ts was
living only on tor-ms22, including hand-edited fixes (Type.Unsafe
schema-passthrough for MCP tool parameters). One disk wipe away from
losing it, and no way to reproduce the install on a new machine.

- extensions/pi/mempalace.ts: canonical copy (matches tor-ms22 byte-for-byte)
- extensions/pi/README.md: what it does, the schema-passthrough gotcha,
  debugging knobs
- install.sh: new install_pi_extension step — gated on ~/.pi/agent/extensions/
  existing, backs up any real file in the way, idempotent re-runs, mirror
  block in uninstall. Works on macOS and Linux (plain ln -s, readlink -f).
- README.md: mention extensions/pi/ in the repo-contents list and in the
  Setup section

Verified on tor-ms22: install (backs up existing real file) → uninstall
(removes symlink) → reinstall (clean symlink). Re-runs are no-ops.
2026-05-05 13:42:47 +02:00
joakimp 6352373a1f fix(feeders): make post-mine repair opt-in, not default
The three feeder wrappers (mempalace-docs, mempalace-pi-session,
mempalace-session) unconditionally ran 'mempalace repair --yes' after
mining, controllable only via --no-repair opt-out. The contrib launchd
and systemd templates did not pass --no-repair, so every scheduled tick
invoked the destructive in-place HNSW rebuild.

This has bitten us twice:
  - 2026-05-04 09:08: a kickstart triggered repair while an MCP
    subprocess held the DB open; the live collection was wiped (0
    drawers) and had to be restored from the palace.backup snapshot.
  - 2026-05-05 10:00: post-mine repair crashed mid-rebuild with
    'NotFoundError: Collection [<uuid>] does not exist' - chromadb's
    rebuild recreated the collection under a new UUID while the code
    still held the old handle. Live DB survived only by luck (crash
    hit before the swap).

Fix: flip the default.
  - New flag: --repair (opt-in). Prints a warning and sleeps 3s before
    invoking 'mempalace repair --yes'.
  - --no-repair is retained as a deprecated no-op alias for backward
    compatibility with any scripts/units still passing it.
  - Default behavior: no repair. Routine ChromaDB add() keeps HNSW
    consistent; repair is a recovery op, not a maintenance tick.

Docs updated to match: README, SKILL, ARCHITECTURE, AGENTS,
contrib/README. Scheduling guidance now explicitly warns against
enabling --repair on cron/launchd/systemd-timer runs.
2026-05-05 12:35:04 +02:00
Joakim Persson 46bcce5a67 contrib: devbox-aware scheduler templates (host-side, docker exec)
On hosts running a long-lived opencode-devbox (or equivalent)
container, mempalace-session lives INSIDE the container, not on
the host. The existing contrib/* templates install a scheduler on
the machine that runs the tool; for the devbox case the scheduler
has to live on the host and reach into the container via
'docker exec'. This was noted in passing in contrib/README.md but
no templates were actually shipped for it.

Adds parallel *-devbox templates for systemd and cron:

contrib/systemd/mempalace-session-devbox.service
  - Type=oneshot, same 2h TimeoutStartSec + low Nice as the direct
    variant.
  - Two Environment knobs (CONTAINER, CONTAINER_USER) default to
    opencode-devbox/developer, overrideable via
    'systemctl --user edit'.
  - ExecCondition checks 'docker ps --filter name= --filter
    status=running' so the unit no-ops cleanly when the container
    is currently down. systemd reports this as a successful
    'condition failed' state — no alert noise across dev cycles
    of teardown/rebuild.
  - ExecStart is plain /usr/bin/docker exec with no shell; systemd
    does the env-var expansion.
  - Stdout/stderr go to journalctl --user -u <unit> (nothing to
    redirect, since docker exec surfaces container output to the
    calling process).

contrib/systemd/mempalace-session-devbox.timer
  - Mon 03:00 Persistent=true RandomizedDelaySec=30m, mirrors the
    direct timer.

contrib/cron/mempalace-session-devbox.cron
  - Equivalent shell-wrapped form for hosts using cron instead of
    systemd. 'docker ps | grep -q .' short-circuits if the container
    isn't running. Log goes to $HOME/.cache/mempalace-session/
    cron-devbox.log on the HOST (outside the container) so it's
    inspectable without dropping into the devbox.

contrib/README.md:
  - Replaces the two-paragraph 'Running inside a container' note
    with a proper section: preconditions, install recipes for both
    the systemd and cron devbox variants, verify/uninstall commands,
    customization via 'systemctl --user edit', behaviour when the
    container is down.
  - Chooser table gains a dedicated row pointing devbox users at
    the *-devbox templates, and mentions the systemd vs cron pick
    for that case.
  - New 'When to pick devbox variants vs direct ones' table covers
    the rare both-installed case (host mempalace AND in-container
    mempalace see separate palaces — they don't cross-pollinate).

Top-level README.md 'Keeping it fresh' subsection gains a quick-start
block for the devbox variant alongside the existing Linux/macOS
quick-starts.

Tested: all four systemd units parse cleanly as INI via
configparser (sections + key=value pairs); validated file sizes
and locations match the layout described in docs. Runtime
validation (systemctl --user enable; actual docker exec) requires
a host with docker + an opencode-devbox container up — deferred
to the user's Mac/Linux boxes.
2026-04-30 14:09:15 +00:00
Joakim Persson 4dcd2959ec docs+installer: how to register mempalace with opencode MCP, probe for it
Two missing pieces bundled here:

1. The README described the MCP server wrapper (mempalace-mcp-server,
   a 3-line shell script that exec's the venv's python) as the
   canonical answer on a uv-tool install. That is over-engineered and
   out of step with the live reference box: opencode.json there uses
   ['mempalace-mcp'] directly, which is the shim uv tool install
   already creates. Rewrote the section to put the simple canonical
   answer first and demote the wrapper to a legacy-fallback sidebar.

   New 'Registering mempalace with opencode' section covers:
   - The one-entry JSON stanza to paste into the mcp object.
   - A full minimal opencode.json for someone starting fresh (with
     the 'instructions' array pointing at the wake-up protocol).
   - Custom palace path variant.
   - Claude Code one-liner (claude mcp add mempalace -- mempalace-mcp).
   - Pointer at 'mempalace mcp' subcommand which prints the currently-
     recommended snippets — useful when upstream updates conventions.
   - Troubleshooting table (tools absent / server unavailable /
     ModuleNotFoundError) with per-symptom fixes.

   The legacy-fallback subsection explains what the wrapper script
   was for (the pip-install → uv-tool-install transition era), shows
   its 3-line implementation for completeness, and is explicit about
   not using it for new installs.

   Verification checklist updated: now runs 'which mempalace-mcp' and
   'mempalace-mcp --help' against the shim, not the wrapper.

2. install.sh gains a matching probe: after the existing wake-up
   protocol check, it grep-checks ~/.config/opencode/opencode.json
   for 'mempalace' + 'mempalace-mcp' substrings. Present → clean
   success line. Missing → actionable warning that prints the exact
   JSON stanza to add plus a pointer to the README anchor and the
   'mempalace mcp' CLI helper. Skipped when opencode.json doesn't
   exist (non-opencode hosts).

   Textual grep rather than strict JSON parse: we don't want to
   hard-depend on python/jq at install time, and the two substrings
   together are specific enough to avoid false positives.

   Prerequisites list gets a 5th bullet flagging MCP registration as
   required and pointing at the new section + the installer probe.

Smoke-tested both scenarios on the reference box — config with
mempalace entry present (all ticks green), config with entry removed
(actionable warning, correct snippet shown), config restored to
original state.
2026-04-30 11:21:38 +00:00
Joakim Persson 60c2a4abec install.sh: probe for mempalace wake-up protocol, warn if missing
The mempalace skill is only useful if an agent loads its wake-up
protocol at session start. Without ~/.config/opencode/instructions/
mempalace.md, the skill is reachable but never auto-runs — agents
forget to search before answering and to write a diary at wind-down.
The failure mode is silent: no error, no warning, just gradual
memory degradation.

install.sh now probes for the file after its regular installation
steps and prints an actionable warning if missing:

  !  Wake-up protocol NOT installed at /path/to/.../mempalace.md
         Without it, the mempalace skill is loadable but never auto-
         runs at session start. Install via the skillset repo:
             git clone .../skillset.git ~/skillset
             cd ~/skillset && ./deploy-skills.sh --bootstrap
         (if skillset is already cloned, just run the --bootstrap step)

If the file is present: prints a matching success line. If the host
doesn't even have ~/.config/opencode/, the check is skipped entirely
(non-opencode machine → no warning to display).

README Prerequisites gains a 4th bullet pointing at skillset's
--bootstrap as the canonical source for the wake-up protocol, so
anyone reading the docs without running install.sh also learns
about the dependency.

The wake-up file is shipped by skillset, not this toolkit. Rationale:
the file bootstraps the 'mempalace' skill (which lives in skillset)
and applies to any harness, not just opencode-plus-toolkit machines.
Cross-referenced via the skillset gitea URL in both the installer
message and the README.

Smoke-tested present + missing scenarios on the reference box —
cleanly detects both, does not hard-fail on missing.
2026-04-30 11:14:15 +00:00
Joakim Persson 2f703a8ebc Docs: explain diary vs session mine (why keep both)
Automated session mining could plausibly lead a user (or a future
agent) to conclude that writing diary entries is redundant — mining
captures every turn, so why also write a compressed summary at
wind-down? That conclusion is wrong, and it's worth explaining why
in the docs so both disciplines survive.

ARCHITECTURE.md §5 gets a new subsection 'Diary vs session mine:
why keep both?' that presents this as a first-class concept:

- Comparison table — content, granularity, compression, authorship,
  signal density, retrieval pattern, and the question each answers.
- The defining property of a diary entry: editorial judgment by the
  author. Captures meta-observations that were never said aloud
  during the session (lessons, patterns, pending items, aggregate
  counts). Mining raw turns can never surface these because the
  words don't exist verbatim.
- Three practical scenarios where the distinction bites: wake-up
  token economics, 'what did we decide' vs 'what did we say',
  redundancy covering each other's failure modes.
- Practical implications: don't skip either habit, let them
  specialize (diary = release notes; mine = git log).

README.md gets a brief teaser in the 'First mine' area with a link
to the canonical ARCHITECTURE.md section — enough for a skim reader
to decide they want to keep writing diaries, and for a deep reader
to know where to go for the full explanation.

SKILL.md replaces the three-line 'Relationship to the mempalace
skill' note with a compact version of the comparison table and a
direct call-out of the 'session mining means I don't need diaries'
misconception agents fall into. Points agents at ARCHITECTURE.md
§5 for the full treatment when users ask the question.

Cross-references verified: anchor slug for the new section is
#diary-vs-session-mine-why-keep-both (standard slug rules: colon,
spaces, punctuation removed/hyphenated). Both linking docs use the
matching fragment.
2026-04-30 08:56:20 +00:00
Joakim Persson 349a3a3d3d mempalace-session: make --dry-run dedup-aware
A --dry-run report showed all qualifying sessions without indicating
which would actually hit the palace on a real run. On a second run
against an already-mined corpus this was misleading — output said
'Exported 62 session(s)' but the real mine step would skip all 62.

The wrapper now queries the palace's chroma.sqlite3 (read-only, via
file:...?mode=ro URI) for source_file values under the staging dir,
then tags each exported session as [NEW] or [SKIP] during listing and
reports the split in the summary:

  Exported 62 session(s) to ~/.cache/mempalace-session/wing_conversations
    0 new   → will be filed on mine
    62 already filed → will be skipped (dedup by source_file)

  --dry-run: no new sessions to mine. A real run would skip all 62.

Implementation notes:
- Classification is best-effort. If the palace is unreachable (fresh
  install, moved, permission-denied, file missing) the wrapper falls
  back to treating all exports as NEW — the real mine step still
  delegates dedup to 'mempalace mine --mode convos' which is the
  authoritative source of truth. Getting the classification wrong
  in --dry-run is cosmetic; behaviour of a real run is unchanged.
- Palace path respects $MEMPALACE_PATH env var for non-default setups.
- Same classification also shown on a real (non-dry-run) mine so users
  see upfront how much of the export set is actually new before the
  miner runs.

Verified both directions:
- All-already-filed case (current box, 62 sessions in palace): reports
  0 new, 62 skipped. --dry-run message correctly says 'would skip all'.
- Partial case (simulated by deleting one session's metadata from
  palace): reports 1 new, 61 skipped. --dry-run message correctly
  says 'would file 1 new'. Palace was restored from backup
  immediately after the test.

README and SKILL.md both updated with the new dedup-aware output and
a direct answer to the FAQ 'will it mine the same sessions again?'
2026-04-30 08:33:36 +00:00
Joakim Persson 72e7019101 Fix two docs/UX errors found during Mac install (tor-ms22)
1. 'mempalace init --yes' without a dir argument fails — 'dir' is
   required. The semantics were wrong too: 'mempalace init' is
   per-project (sets up mempalace.yaml + entity detection in a specific
   directory), not a one-time global init. The palace itself is
   created lazily on first write, so neither mempalace-session nor
   mempalace-docs requires any init step.

   Removed the misleading 'One-time palace init' block from README.md,
   ARCHITECTURE.md, and SKILL.md. Added a clarifying note:
   'mempalace init <dir>' is per-project and optional (needed only to
   customize the wing name or entity detection before mempalace-docs).

2. install.sh's 'Skipping <name>: <dest> exists and is not our symlink'
   warning gave no actionable guidance. On the Mac, a leftover
   ~/.local/bin/mempalace-docs (likely from the pre-split cli_utils
   days) was blocking the new install and the user had no easy way
   to know what to do about it.

   Expanded the warning to:
   - Show whether the blocker is a symlink (and what it points at) or
     a real file.
   - Print the exact 'rm && ./install.sh' fix line.
   - Track skipped count separately and flag it in the closing
     summary so a scrolling user doesn't miss it.

   Added matching troubleshooting paragraph to the README 'Install
   mempalace-toolkit' section explaining the skip behaviour and
   pointing at the installer's own message for the fix.

Smoke-tested the new skip-warning code path by temporarily replacing
~/.local/bin/mempalace-docs with a foreign symlink and re-running
install.sh — output is clear, specific, and restores cleanly.
2026-04-30 07:32:50 +00:00
Joakim Persson 25972b7499 README: document uv-based mempalace install + MCP wrapper pitfall
mempalace-toolkit's Prerequisites section assumed mempalace was already
installed but didn't explain how. The upstream mempalace repo only
shows pip install, which fights PEP 668 on modern distros and leaks
dependencies into system site-packages. The production pattern used
in opencode-devbox (uv tool install) is cleaner but wasn't documented
here.

Adds a full 'Installing mempalace itself (prerequisite)' section with
five subsections:

1. Why uv over pip — isolated venv, no PEP 668 fight, shim makes
   the CLI accessible from any bash/zsh terminal without manual
   venv activation.
2. Personal machine —  with default paths
   (shim in ~/.local/bin, venv under ~/.local/share/uv/tools/). Simple
   one-liner plus PATH guidance. This is the recommended default.
3. System-wide / container install — the opencode-devbox pattern:
   UV_TOOL_DIR=/opt/uv-tools + UV_TOOL_BIN_DIR=/usr/local/bin, with
   the exact Dockerfile RUN step used in production (including the
   python -c build-time sanity check). Cross-references
   opencode-devbox/Dockerfile for the full canonical version.
4. MCP server wrapper — explains the 'missing venv when the container
   was deployed' pitfall from the first opencode-devbox attempt:
   with a non-default UV_TOOL_DIR, system python3 can't import
   mempalace, so MCP configs of the form
     ["python3", "-m", "mempalace.mcp_server"]
   fail silently with ModuleNotFoundError. Fix is a thin wrapper on
   PATH that exec's the venv's own python. Shows the exact 3-line
   shell wrapper from opencode-devbox/rootfs/usr/local/bin/
   mempalace-mcp-server. Points at opencode-devbox/AGENTS.md
   'Critical conventions' as the authoritative reference.
5. Verification checklist — /usr/local/bin/mempalace, MemPalace 3.3.3,
   and a minimal
=======================================================
  MemPalace Status — 4943 drawers
=======================================================

  WING: cli_utils
    ROOM: scripts                 38 drawers
    ROOM: fzf                     25 drawers
    ROOM: general                  1 drawers

  WING: opencode_devbox
    ROOM: general                203 drawers
    ROOM: configuration            3 drawers

  WING: proxmox
    ROOM: general               1046 drawers

  WING: skillset
    ROOM: general               1118 drawers

  WING: wing_conversations
    ROOM: technical             1775 drawers
    ROOM: architecture           513 drawers
    ROOM: planning               164 drawers
    ROOM: problems                42 drawers
    ROOM: general                  6 drawers
    ROOM: decisions                3 drawers

  WING: wing_orchestrator
    ROOM: diary                    6 drawers

======================================================= smoke test that catches venv
   mismatches by failing with a Python traceback instead of a clean
   error message.

Renames the existing 'Install' section to 'Install mempalace-toolkit'
to disambiguate from the new mempalace install section — the toolkit's
own install.sh still works the same, just labeled more precisely.

ARCHITECTURE.md §4 prerequisites paragraph and SKILL.md prerequisites
block both cross-reference the new section with anchor links, so any
entry point into the docs leads the reader to the right recipe.
2026-04-30 07:02:36 +00:00
Joakim Persson 720245e010 Add macOS launchd template, bringing automation parity to macOS
Ship a launchd user agent plist alongside the existing systemd and
cron templates so macOS users can schedule mempalace-session without
falling back to cron. launchd is the macOS-native equivalent of a
systemd user timer: same scheduling model, same log conventions, same
single-instance guarantees.

- contrib/launchd/se.jordbo.mempalace-session.plist:
  - Label uses reverse-DNS from the jordbo.se domain for consistency
    with other user-installed launchd jobs; fork the prefix if reusing
    this template in a different org.
  - ProgramArguments points at /Users/USER/.local/bin/mempalace-session
    (USER is substituted at install time, same pattern as
    contrib/cron/).
  - EnvironmentVariables.PATH covers ~/.local/bin, Apple Silicon
    Homebrew, Intel Homebrew, and system defaults — launchd agents
    get a minimal PATH by default and the wrapper needs to find
    mempalace + python3.
  - StartCalendarInterval matches systemd unit's schedule: Monday
    03:00 local.
  - RunAtLoad=false — load shouldn't trigger a run; schedule does.
  - ProcessType=Background + LowPriorityIO=true + Nice=10 mirror
    the systemd unit's Nice=10 + IOSchedulingClass=idle. macOS's
    automatic App Nap and resource throttling for Background jobs
    yields to interactive work cleanly.
  - ExitTimeOut=7200 matches systemd's TimeoutStartSec=7200.
  - StandardOut/ErrorPath under ~/Library/Logs/ so Console.app
    surfaces them.

- contrib/README.md gains a full launchd section:
  - Caveat table comparing to systemd (Persistent=true isn't quite
    matched; RandomizedDelaySec has no equivalent; overlap prevention
    is automatic).
  - Install recipe using launchctl bootstrap (modern) with a fallback
    note for legacy launchctl load -w on older macOS.
  - Verify section shows launchctl list, launchctl print, log tails,
    and launchctl kickstart for manual testing.
  - Uninstall via launchctl bootout.
  - Chooser table updated: macOS now explicitly points at launchd,
    not cron.

- ARCHITECTURE.md §5, SKILL.md Quick automation pitch, and README.md
  Keeping it fresh section all updated to mention the three scheduler
  options and give per-platform quick-starts.

Plist XML validated with plistlib.
2026-04-30 06:51:17 +00:00
Joakim Persson 36845e14b2 Document the operational routine + ship automation templates
Until opencode session-stopping hooks land upstream, mempalace-session
is the entire mechanism that gets opencode conversations into the
palace — skip it and session history stays trapped in a local SQLite
DB, invisible to semantic search. Previous docs covered setup well
but were thin on when and how often to run it.

- ARCHITECTURE.md §5: replace the one-line 'When to re-mine' note with
  a full Operational Routine section — triggers, cadence, relationship
  to the session lifecycle, automation pointers, verification.
- SKILL.md: add an Operational Routine section aimed at agents —
  when to suggest invoking the tool, cadence guidance, how to
  distinguish this producer-side tool from the consumer-side
  mempalace skill's in-session habits.
- README.md: add 'Keeping it fresh' subsection pointing at contrib/
  and the full docs.

contrib/ ships three ready-to-use templates:
- systemd/mempalace-session.{service,timer} — user units with weekly
  Mon 03:00 schedule, Persistent=true catch-up, RandomizedDelaySec for
  fleet-wide jitter, ConditionPathExists guard for opencode-less boxes,
  Nice+IOSchedulingClass=idle so it never fights interactive work.
- cron/mempalace-session.cron — sample crontab entry with log
  redirection and clear USER-substitution instructions.
- README.md with install/verify/uninstall recipes for both, a chooser
  table (systemd vs cron), container/devbox caveats, and tuning notes
  (daily vs weekly vs monthly trade-offs).

The user's LATER-list item 'wrap mempalace-session in cron/systemd
timer for true auto-save coverage' is now actionable: a single
systemctl --user enable --now command stands it up.
2026-04-30 06:29:55 +00:00
Joakim Persson e49d9285c4 install.sh: drop .skill-source marker in deployed skill dir
The skill directory at ~/.agents/skills/opencode-mempalace-bridge/ is a
real dir containing a single SKILL.md symlink back into this repo — the
'colocated skill' pattern. Sibling reconcilers (skillset's
deploy-skills.sh, cli_utils's agents-sync.zsh) already handle external
dirs correctly via their existing 'leave real dirs alone' policies, but
a machine-readable marker makes ownership explicit:

  # skill-source: mempalace-toolkit
  # repo: <absolute path>
  # url: ssh://git@gitea.jordbo.se:2222/joakimp/mempalace-toolkit.git

The marker is the convention for any external repo that wants to ship a
colocated skill. The name is generic (.skill-source, not
.managed-by-mempalace-toolkit) so a second colocated skill from a
different repo can reuse the same file name; the first line identifies
the owner.

--uninstall now also removes the marker (only if it still says
mempalace-toolkit) and the now-empty skill dir.

AGENTS.md + README.md describe the pattern and point at sibling docs in
cli_utils/AGENTS-SYNC.md and skillset/README.md that mirror the
convention.
2026-04-30 05:57:54 +00:00
Joakim Persson 954c3f2ebb 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.
2026-04-30 05:30:04 +00:00