用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/cwinvestments/memstack --skill diary命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Use when the user says 'save project', 'handoff', or when context is running low and state must be preserved.
Use when the user says 'create quotation', 'generate quote', 'proposal', or needs a client-facing price document.
Use when the user says 'plan', 'todo', 'copy plan', 'append plan', 'resume plan', 'priorities', or 'what's next'.
正在显示 SKILL.md
| name | diary |
| description | Use when the user says 'save diary', 'log session', 'wrapping up', or at end of a productive session. |
| version | 1.1.0 |
Document what was accomplished in each CC session for future recall.
When this skill activates, output:
📓 Diary — Logging session...
Then execute the protocol below.
| Context | Status | Priority |
|---|---|---|
| User says "save diary", "log session", "write diary" | ACTIVE — write diary | P1 |
| User explicitly says they're done ("that's it", "wrapping up") | ACTIVE — suggest diary if work was done | P2 |
| Multi-agent session (Builder/Reviewer role) | DORMANT — Manager handles diary | — |
| Mid-session, user is actively coding | DORMANT — don't interrupt flow | — |
| Casual conversation, no code changes made | DORMANT — nothing to log | — |
| User asks to recall past sessions ("what did we do") | DORMANT — Echo handles recall, not Diary | — |
| User says "save project" or "handoff" | DORMANT — Project skill handles this | — |
| Session just started, no work yet | DORMANT — nothing to log | — |
When the user asks to save a diary, keep these in mind:
| Temptation | Why it matters |
|---|---|
| "Nothing important happened" | Even small decisions have context worth capturing. |
| "Commits capture everything" | Commits don't capture decisions, blockers, or next steps. |
| "Skip the handoff section" | Handoffs are the most valuable part for session continuity. |
Never pass a JSON payload as a quoted command-line argument. Write it to a file and pipe it in with the dash sentinel, as every command below shows. On Windows, cmd.exe treats single quotes as ordinary characters, so a redirection operator anywhere in a quoted payload is executed rather than passed.
All JSON field values must be plain strings. Never pass arrays or objects. If multiple items (files, commits, decisions), join them as a comma-separated string.
Summarize the session:
Check git log for commits:
git log --oneline -10
Format the diary entry:
# Session Diary: {project}, {date}
## Accomplished
- Item 1...
## Files Changed
- path/to/file.ts: description
## Commits
- abc1234 Message
## Decisions
- Decision: reason
## Next Steps
- What to do next
## Session Handoff
**In Progress:** [what was actively being worked on when session ended]
**Uncommitted Changes:** [list any unstaged/uncommitted work, or "None"]
**Pick Up Here:** [exact instruction for next session, specific enough to start cold]
**Session Context:** [anything important that isn't captured elsewhere: temp decisions, debugging state, gotchas discovered]
Save to SQLite database (primary storage):
Write the payload to a file, then pipe it in with - as the argument. A payload on stdin is never seen by the shell's parser, so a redirection operator inside your prose cannot be read as one.
cat session.json | python "$MEMSTACK_PATH/db/memstack-db.py" add-session -
session.json contains:
{"project":"<name>"
python -m memstack_skill_loader.diary_ingest "memory/sessions/{date}-{project}.md"
This parses the ## FACTS block and stores each fact with source_type='diary'.
Read the summary it prints. This step is not fire-and-forget. It reports N ingested, M duplicate, K skipped on stdout, followed by one indented reason per skipped line naming the line number and what was wrong with it. The exit code classifies the outcome:
| Exit | Meaning |
|---|---|
| 0 | Nothing was lost: facts ingested, an all-duplicates re-run, or no FACTS block at all (which prints nothing at all). |
| 1 | Total loss. The block held lines and not one of them ingested. |
| 2 | Store failure. The run aborted at the first bad row; the Memory Engine is broken, not the diary. |
If K is not 0, fix those lines in the markdown and run the command again. A skipped line is a fact this session was supposed to hand to the next one and did not, and the most common cause is a | inside a claim. Re-running is safe: facts dedupe on source + subject + claim, so anything already stored comes back as a duplicate rather than being written twice.
A non-zero exit never means the diary failed to save. The markdown and the SQLite row are already written by this point, and ingestion cannot undo them.
The ## FACTS block is how a session hands durable, atomic knowledge to future sessions. It is machine-parsed, so the format is fixed. One fact per line:
subject | claim | method [| entities]
memstack.dashboard.start, adminstack.portal.auth). Group related facts under a shared prefix.|.verified (you saw it work / read the code / ran it), reported (stated but unconfirmed), inferred (deduced), assumed (a guess — scored lowest).## FACTS
memstack.dashboard.start | start_dashboard() in dashboard.py, port 3333, proxy opt-in | verified
memstack.memory.recall-scoring | recall score = confidence * exp(-age/half_life), computed at query time, never stored | verified
adminstack.portal.auth | portal uses Supabase magic-link auth, not passwords | reported | supabase, auth
memstack.memory.corrections | a superseded fact cannot be corrected; corrections extend from the live tip | verified | correction
verified over reported. If you actually confirmed it, say so — verified facts are trusted and decay slowest. Don't inflate: an unconfirmed claim is reported.The 500-line limit on markdown files is no longer a concern since SQLite is the source of truth.
Markdown files in memory/sessions/ are now just human-readable exports.
Old markdown files are preserved but not the primary storage.
User: "save diary"
📓 Diary — Logging session...
Saved: memory/sessions/2026-02-18-adminstack.md
Project: AdminStack | Duration: ~2 hours
Accomplished: Built CC Monitor page, API routes, setup guide
Commits: 4 (45b4c42, d1c7e11, f6c8e18, f0e793f)
Files changed: 8
This session is now searchable via Echo.
The diary system includes an automatic PreCompact hook that fires before Claude Code compresses the context window. This closes the gap where session context could be lost during long conversations.
.claude/diary/{date}-compaction.md — one file per day, appends on multiple compactionsCOMPACTION_INTERRUPTED so the next session knows context was cut| Data | Source |
|---|---|
| Uncommitted changes | git status --short |
| Recent commits | git log --oneline -5 |
| Recent shell commands | Shell history (last 5) |
| Recently modified files | Files modified since last git operation |
| Branch and project | Git branch + directory name |
| Manual Diary | PreCompact Diary | |
|---|---|---|
| Trigger | User says "save diary" | Automatic before compaction |
| Content | Full narrative with decisions, handoff | Snapshot of working state |
| Storage | SQLite + memory/sessions/ | .claude/diary/ only |
| Purpose | Session documentation | Context recovery after compaction |
When resuming after compaction, check .claude/diary/ for entries with today's date. The COMPACTION_INTERRUPTED flag signals that the previous context was truncated and these files contain the lost state.
Hook is registered in .claude/settings.json under PreCompact. Script lives at .claude/hooks/pre-compact.sh. Always exits 0 — must never block compaction.
The Diary skill is part of a broader hook system that automates session lifecycle, security, and observability. All hooks follow the same defensive pattern: set -uo pipefail, SCRIPT_DIR resolution, all external commands wrapped with fallbacks, guaranteed exit 0.
| Event | Script | Matcher | Timeout | Purpose |
|---|---|---|---|---|
| PreToolUse | pre-tool-notify.sh | Write|Edit|MultiEdit|Bash | 10s | TTS voice alert before approval prompts |
| PreToolUse | pre-push.sh | Bash (git push) | 60s | Build verification + secrets scan before push |
| PostToolUse | post-commit.sh | Bash (git commit) | 10s | Debug artifact + secrets scan after commit |
| PostToolUse | post-tool-monitor.sh | Write|Edit|MultiEdit|Bash | 10s | Observation capture — logs tool calls to .claude/observations/ |
| SessionStart | session-start.sh | (all) | 10s | CLAUDE.md indexing, monitoring ping |
| SessionStart | session-context-load.sh | (all) | 15s | Context injection — last 3 diary + observation summaries → .claude/session-context.md |
| Stop | session-end.sh | (all) | 10s | Monitoring API session-complete ping |
| PreCompact | pre-compact.sh | (all) | 15s | Auto-save diary snapshot before context compaction |
settings.json, giving it its own timeout budget.claude/observations/YYYY-MM-DD.md — daily files, append-only.claude/session-context.md on each new session.claude/observations/ and .claude/session-context.md are in .gitignore (ephemeral runtime output).claude/hooks/ and use ${CLAUDE_PROJECT_DIR} for portable path resolution.claude/rules/diary.md), always-on session logging awareness without skill file read. (Origin: MemStack v3.0-beta, Feb 2026)## FACTS block — atomic, machine-parsed cross-session knowledge (subject | claim | method | entities) ingested into the Memory Engine via diary_ingest after each save. Fail-open, dedupe-safe, corrections-first. (Origin: MemStack Memory Engine step 4, Jul 2026)Save insights for cross-project search:
Same form: write the payload to a file, pipe it in, - as the argument. Insight text is prose, so it must never travel on the command line.
cat insight.json | python "$MEMSTACK_PATH/db/memstack-db.py" add-insight -
insight.json contains:
{"project":"<name>","type":"<type>","content":"<insight>","context":"Session <date>","tags":"<project>"}
Choose <type> deliberately from this vocabulary — do not default to one:
gotcha — something that bit us and the fix. Non-obvious behavior a future session would trip on again.lesson — a general rule learned the hard way. Broader than one bug.pattern — a reusable approach or convention that worked.warning — a known hazard to avoid. Not yet a bug, but will be.failed_approach — something tried that did not work, and why. Prevents retrying it.architecture — a structural fact about how a system is built.decision — a choice made and the reasoning. Historical record.The first five are procedural — an agent can act on them at retrieval time. architecture and decision are record. When a row could be either, prefer the procedural type.
Unknown types pass through unchanged but come back as type_unknown in the JSON response — that is the signal to pick a type from the list above.
CRITICAL: The field name is "content", NOT "insight". Using "insight" will fail with a missing required field error.
Update project context with last session date:
Same form, even though this payload is only metadata. One rule with no exceptions is easier to follow than a rule you have to judge.
cat context.json | python "$MEMSTACK_PATH/db/memstack-db.py" set-context -
context.json contains:
{"project":"<name>","last_session_date":"<YYYY-MM-DD>"}
Also save markdown copy to memory/sessions/{date}-{project}.md (export format, human-readable backup). Append a ## FACTS block (see below) as the last section of this markdown.
Ingest the FACTS block into the Memory Engine, right after the markdown is written: