Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions memory_consolidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,32 @@ def load_transcript(args, payload):
# pipeline segment, i.e. in command position, where the word is the program
# being run rather than an argument being searched for.
COMMIT_RE = re.compile(r"git(?:\s+-\S*(?:\s+[^\s-]\S*)?)*\s+commit\b")
SAVE_BASH_RE = re.compile(r"okfmem\s+sync\b|okfmem-save\b")
# The save reaches the shell in several shapes, and only the bare one used to
# match: `okfmem` is an extensionless Python script, so the real invocation is
# `python3 ~/okfmem/okfmem sync`, and Windows goes through the .ps1/.cmd
# wrappers. Missing those made the badge sit amber over a session that saved
# and pushed — systematic, not incidental, since it fired on every real save.
# Command position is still required; the prefix is stripped, not the anchor.
SAVE_BASH_RE = re.compile(
r"(?:\S*[/\\])?okfmem(?:\.(?:ps1|cmd))?\s+sync\b"
r"|(?:\S*[/\\])?okfmem-save\b"
)
# Quoted spans are data, not code — blanked BEFORE segmenting, because a
# separator inside a quoted regex (`grep 'a\|b'`) would otherwise split there
# and leave the quote's tail sitting in apparent command position.
QUOTED_RE = re.compile(r"'[^']*'|\"[^\"]*\"")
# Split on shell separators, then strip leading `(`, env assignments and
# wrappers so `cd x && FOO=1 git commit` still resolves to a commit.
# Split on shell separators, then strip leading `(`, env assignments, wrappers
# and an interpreter with its flags, so `cd x && FOO=1 git commit` resolves to
# a commit and `pwsh -File ./okfmem.ps1 sync` resolves to a save. Stripping an
# interpreter cannot manufacture a save: what follows it is still required to
# be the program, so the words as plain arguments (`py build.py okfmem sync`)
# do not match.
SEGMENT_RE = re.compile(r"\|\||&&|[;\n|]")
LEAD_RE = re.compile(r"^[\s(]*(?:[A-Za-z_]\w*=\S*\s+)*(?:(?:sudo|command|nohup)\s+)*")
INTERPRETER = r"(?:python3?|py|pwsh|powershell|bash|sh|zsh)(?:\.exe)?"
LEAD_RE = re.compile(
r"^[\s(]*(?:[A-Za-z_]\w*=\S*\s+)*(?:(?:sudo|command|nohup)\s+)*"
r"(?:(?:\S*[/\\])?" + INTERPRETER + r"\s+(?:-\S+\s+)*)?"
)
# The user invoking the skill — as a bare slash command or via Claude Code's
# `<command-name>` envelope. Anchored so a mention mid-sentence never counts.
SAVE_CMD_RE = re.compile(r"(?:^|<command-name>)\s*/(?:okfmem-save|primer)\b",
Expand Down
26 changes: 26 additions & 0 deletions tests/test_save_state_badge.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,32 @@ def test_command_must_run_not_merely_mention():
assert mc.compute_save_state(t) == "unsaved"


def test_save_is_recognised_through_path_and_interpreter_prefixes():
# `okfmem` is an extensionless Python script, so the real close-out is
# `python3 ~/okfmem/okfmem sync` — matching only the bare spelling left the
# badge amber over every genuinely saved session.
for command in ("okfmem sync",
"~/okfmem/okfmem sync",
"/abs/path/okfmem sync",
"./okfmem sync",
'python3 ~/okfmem/okfmem sync -m "msg"',
"okfmem.cmd sync",
"pwsh -File ./okfmem.ps1 sync",
"cd /r && python3 ~/okfmem/okfmem sync"):
t = _edit() + "\n" + _bash(command)
assert mc.compute_save_state(t) == "saved", command


def test_interpreter_stripping_does_not_manufacture_a_save():
# What follows the interpreter must still be the program: the same words
# as plain arguments are not a save, nor is merely naming the command.
for command in ("py build.py --then okfmem sync",
"grep -o 'okfmem sync' f",
'echo "run okfmem sync"'):
t = _edit() + "\n" + _bash(command)
assert mc.compute_save_state(t) == "unsaved", command


def test_git_commit_variants_still_count_as_work():
for command in ("git commit -m x", "git -C /repo commit --amend",
"cd /r && FOO=1 git commit", "sudo git commit -m x"):
Expand Down
Loading