tools/windows/ .ps1 (pwsh, so usable from Linux and macOS too)
tools/posix/ .sh
tools/python/ .py
tools/ .c and .pl
The .c and .pl files stay at the top level because they are not
host-specific: the build compiles or invokes them on every platform.
Call sites updated in the Makefile, ports/mk/port.mk, docs and the
project memory. The one thing that does not survive a move on its own is
a script deriving the repo root from its own location -- all nine
PowerShell tools used Split-Path $PSScriptRoot -Parent, and memory-sync.sh
used dirname/.., both of which quietly become tools/ one level deeper.
Two levels now.
Two pre-existing Windows failures surfaced while verifying, both real and
neither caused by the move:
- schfs_fsck.c did not compile under mingw at all: --extract uses
POSIX mkdir(path,mode), symlink() and link(), none of which mingw
has. That took the whole tool with it, and `make schfs-check` with
it. mkdir maps to _mkdir; symlink and link fail loudly rather than
writing a regular file in their place, because an extracted tree
that differs from the image while reporting success defeats the
point of --extract.
- the round-trip test then failed at `ln -s`, since Git Bash cannot
create symlinks without developer mode. It skips with a message now.
Not a fudge: mkschfs's mingw build cannot see a symlink either, so
the test would have compared a tree with none against an image with
none and called it a pass -- coverage reporting itself as present
while being absent.
Verified on Windows: build clean, all seven bootcheck suites green,
make schfs-check passes.
111 lines
3.8 KiB
Shell
111 lines
3.8 KiB
Shell
#!/bin/sh
|
|
# Move Claude Code's project memory between this repo and the local machine.
|
|
#
|
|
# tools/posix/memory-sync.sh export memory on this machine -> .claude/memory/
|
|
# tools/posix/memory-sync.sh import .claude/memory/ -> this machine
|
|
# tools/posix/memory-sync.sh status show both sides, change nothing
|
|
#
|
|
# Why this exists
|
|
# ---------------
|
|
# Claude Code keeps per-project memory outside the repo, under
|
|
#
|
|
# <home>/.claude/projects/<key>/memory/
|
|
#
|
|
# where <key> is the project's absolute path with the separators replaced by
|
|
# dashes: D:\DEV\SchOS becomes D--DEV-SchOS, /home/me/dev/SchOS becomes
|
|
# -home-me-dev-SchOS. Two consequences follow, and both have already bitten
|
|
# this project once:
|
|
#
|
|
# * Renaming the directory orphans the memory. D:\DEV\Schunix -> D:\DEV\SchOS
|
|
# changed the key, and everything written under the old one became
|
|
# invisible until it was moved across by hand.
|
|
# * The key is machine-specific, so memory written on Windows is not where
|
|
# Linux looks for it, even for the same checkout.
|
|
#
|
|
# Committing the memory to the repo fixes both: git carries it between hosts
|
|
# and across renames, and `import` puts it wherever this particular machine
|
|
# expects to find it. Run `export` after a session that learned something and
|
|
# `import` after cloning or pulling on another machine.
|
|
|
|
set -eu
|
|
|
|
usage() {
|
|
echo "usage: $0 {export|import|status}" >&2
|
|
exit 2
|
|
}
|
|
|
|
[ $# -eq 1 ] || usage
|
|
|
|
# Repo root: this script lives in tools/posix/, so two levels up.
|
|
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
repo=$(CDPATH= cd -- "$script_dir/../.." && pwd)
|
|
repo_mem="$repo/.claude/memory"
|
|
|
|
# The absolute path Claude Code itself sees. Under Git Bash `pwd` gives
|
|
# /d/DEV/SchOS, but Claude Code is a Windows program and uses D:\DEV\SchOS, so
|
|
# the key must be derived from the Windows form or it will not match.
|
|
native_path="$repo"
|
|
case "$(uname -s)" in
|
|
MINGW* | MSYS* | CYGWIN*)
|
|
if command -v cygpath >/dev/null 2>&1; then
|
|
native_path=$(cygpath -w "$repo")
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# Encode: every separator becomes a dash, and so does the drive colon.
|
|
#
|
|
# D:\DEV\SchOS -> D--DEV-SchOS
|
|
# /home/me/dev/SchOS -> -home-me-dev-SchOS
|
|
#
|
|
# The colon maps to a dash rather than being deleted -- that is where the
|
|
# doubled dash in the Windows form comes from, and dropping it instead yields
|
|
# D-DEV-SchOS, which matches nothing.
|
|
key=$(printf '%s' "$native_path" | tr '/\\:' '---')
|
|
|
|
home_dir=${HOME:-$USERPROFILE}
|
|
host_mem="$home_dir/.claude/projects/$key/memory"
|
|
|
|
count() { [ -d "$1" ] && find "$1" -name '*.md' 2>/dev/null | wc -l | tr -d ' ' || echo 0; }
|
|
|
|
case "$1" in
|
|
status)
|
|
echo "repo: $repo"
|
|
echo "as Claude sees it: $native_path"
|
|
echo "project key: $key"
|
|
echo
|
|
echo "in repo: $repo_mem"
|
|
echo " $(count "$repo_mem") memories"
|
|
echo "on this host: $host_mem"
|
|
echo " $(count "$host_mem") memories"
|
|
;;
|
|
|
|
export)
|
|
if [ ! -d "$host_mem" ]; then
|
|
echo "memory-sync: nothing to export -- no memory at $host_mem" >&2
|
|
echo " (is the project key right? run: $0 status)" >&2
|
|
exit 1
|
|
fi
|
|
mkdir -p "$repo_mem"
|
|
# Copy rather than mirror: deleting from the repo is a git operation and
|
|
# should be visible in a diff, not a side effect of running a sync script.
|
|
cp "$host_mem"/*.md "$repo_mem"/ 2>/dev/null || true
|
|
echo "exported $(count "$repo_mem") memories to .claude/memory/"
|
|
echo "commit them to carry them to your other machines."
|
|
;;
|
|
|
|
import)
|
|
if [ ! -d "$repo_mem" ]; then
|
|
echo "memory-sync: nothing to import -- no .claude/memory/ in this repo" >&2
|
|
exit 1
|
|
fi
|
|
mkdir -p "$host_mem"
|
|
cp "$repo_mem"/*.md "$host_mem"/ 2>/dev/null || true
|
|
echo "imported $(count "$host_mem") memories to:"
|
|
echo " $host_mem"
|
|
;;
|
|
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|