Configure project memory: write CLAUDE.md with architecture context and (Tier 3) set up a self-sustaining .claude/memory/ lifecycle — SessionStart load hook, Stop save-nudge hook, and a /save-memory skill that distills each session. Called by init or standalone to configure the memory pillar. Trigger phrases: "setup memory", "write CLAUDE.md", "configure project context".
Scanned 8/31/2026
Install via CLI
openskills install ShipWithAI/shipwithai-plugins---
name: setup-memory
description: >
Configure project memory: write CLAUDE.md with architecture context and (Tier 3)
set up a self-sustaining .claude/memory/ lifecycle — SessionStart load hook, Stop
save-nudge hook, and a /save-memory skill that distills each session.
Called by init or standalone to configure the memory pillar.
Trigger phrases: "setup memory", "write CLAUDE.md", "configure project context".
argument-hint: "[--memory-only] [--claude-md-only]"
---
# /setup-memory
Configures the Memory pillar: `CLAUDE.md` (project context, all tiers) and a self-sustaining
`.claude/memory/` lifecycle — store + hooks + `/save-memory` skill (Tier 3 only).
## Flags
Check flags first — they override Mode Detection behavior:
- `--claude-md-only` — write CLAUDE.md only, skip `.claude/memory/` entirely
- `--memory-only` — create `.claude/memory/` only, skip CLAUDE.md entirely
## Mode Detection
```
Read .claude/starter-context.json if it exists
→ Exists:
- Load all fields
- For each required field that is null or missing → ask for that field only
- Use tier field to determine whether to create .claude/memory/ (Tier 3 = full / standard ≠ Tier 3)
→ Not found (standalone):
- Read existing CLAUDE.md if present (extract what's already there)
- Ask for any missing fields
- Ask: "Should I also set up .claude/memory/? (Tier 3 feature)"
```
Required fields from `starter-context.json`:
`tier`, `project.name`, `project.type`, `project.team_size`, `project.stage`,
`stack.language`, `stack.framework`, `stack.build_tool`, `stack.test_framework`, `stack.package_manager`,
`architecture.style`, `architecture.key_layers`, `architecture.entry_points`, `architecture.external_deps`,
`architecture.gotchas`, `conventions.formatter`, `conventions.branch_strategy`, `conventions.commit_format`,
`conventions.workflow_gates` (optional — absent means no workflow section generated)
## CLAUDE.md Structure
Write with actual values — no generic text, no leftover placeholders:
```markdown
# [Project Name] — Claude Context
*Generated by /shipwithai-starter on [DATE].
Edit directly — every skill reads this before doing anything.*
---
## Project identity
**Name:** [name]
**Type:** [web app / API / CLI / lib / monorepo]
**Team size:** [N developers]
**Stage:** [greenfield / active / maintenance]
---
## Tech stack
**Language(s):** [...]
**Framework(s):** [...]
**Build tool:** [...]
**Test framework:** [...]
**Package manager:** [...]
**Runtime:** [Node 20 / Python 3.12 / Go 1.22 / etc.]
---
## Architecture overview
**Style:** [monolith / microservices / modular monolith]
[Only include the following block when project.stage is "greenfield":]
**Status:** Greenfield — build toward this structure
**Build order:**
[Derive from architecture.build_order if present in starter-context.json.
Otherwise generate a sensible 3-step order based on the stack and architecture:
- Step 1: foundation first (e.g., db/schema.ts → run initial migration)
- Step 2: authentication (e.g., features/auth/ — auth before any business domain)
- Step 3: core domain (e.g., features/<core-domain>/)]
[End greenfield block — omit entirely for non-greenfield projects]
**Key layers:**
- [e.g., API layer: src/routes/]
- [e.g., Service layer: src/services/]
- [e.g., Data layer: src/db/]
**Entry points:**
- [e.g., src/index.ts → main server]
**Key directories:**
[paste tree output or describe structure]
**External dependencies:**
- [databases, queues, caches, external APIs]
---
## Key conventions
**Code style:** [ESLint + Prettier / Black / gofmt / etc.]
**Branch strategy:** [trunk-based / gitflow]
**Commit format:** [conventional / custom / none]
**Test coverage target:** [e.g., 80%]
---
## What Claude should know before touching code
**Gotchas:**
- [e.g., "src/generated/ is auto-generated, never edit manually"]
- [e.g., "migrations/ only via npm run migrate:create"]
**Build order:**
- [e.g., "codegen must run before tsc"]
**Test isolation:**
- [e.g., "integration tests require Docker Compose up"]
**Sensitive areas (extra care):**
- [e.g., "auth/ and payments/ require security review before merge"]
---
## Development workflow
[Only include this section if conventions.workflow_gates is present and not ["none"] or []]
**When working on any task, Claude must follow these gates:**
[Generate one bullet per gate selected:]
- plan-before-code → **Plan first:** For any task > 30 min, create a plan and get approval before writing code.
- tdd → **TDD:** Write failing tests first. Never write implementation without a corresponding test.
- code-review → **Code review:** Run the code-reviewer agent after every significant change. Address all CRITICAL and HIGH findings.
- security-review + sensitive_areas present → **Security review:** Before committing to [list from architecture.sensitive_areas], run security-reviewer agent.
- security-review + sensitive_areas empty → **Security review:** Before committing to sensitive areas (auth, payments, migrations), run security-reviewer agent.
[If workflow_gates is ["none"] or [] → omit this section entirely]
---
## Harness config
**Tier:** [Essential / Standard / Full]
**Last updated:** [DATE]
Hooks: see `.claude/settings.json`
MCP servers: see `.mcp.json`
```
## .claude/memory/ — lifecycle memory (Tier 3 only)
A **self-sustaining** cross-session memory that lives in the repo: load on session start →
work → nudge to save on stop → distill → handoff to the next session. Plain markdown, version-
controlled. Set up three things: the **store**, the **hooks**, and the **`/save-memory` skill**.
> Token replacements for every template below: `{{PROJECT_NAME}}` → `project.name`;
> `{{DATE}}` → today; `{{TEMPLATE_VERSION}}` → this plugin's version (from `plugin.json`).
### A. The store
Create this structure (directories + seed files from `assets/memory/`):
```
.claude/memory/
README.md ← from assets/memory/README.md.tmpl (how the system works)
MEMORY.md ← from assets/memory/MEMORY.md.tmpl (index, loaded every session)
HANDOFF.md ← from assets/memory/HANDOFF.md.tmpl (ephemeral WIP, overwritten each save)
decisions/ ← empty dir + .gitkeep (durable, append-only ADR-lite)
conventions/ ← empty dir + .gitkeep (durable conventions + gotchas)
sessions/ ← empty dir + .gitkeep (append per-day summaries)
```
Copy each `.tmpl` to its destination (drop the `.tmpl` suffix) and substitute tokens. Create
the three subdirectories, each with an empty `.gitkeep` so git tracks them.
**Memory layers** (durable vs ephemeral) — the user does not hand-maintain these; the
`/save-memory` skill writes them:
| Path | Lifetime | Holds |
|---|---|---|
| `MEMORY.md` | updated continuously | one-line index of every memory |
| `decisions/NNNN-slug.md` | durable, append-only | a decision + its rationale |
| `conventions/slug.md` | durable | a convention or gotcha |
| `HANDOFF.md` | ephemeral, overwritten | current WIP + "Context to Load" for next session |
| `sessions/YYYY-MM-DD.md` | append per day | a short session summary |
### B. The hooks (this skill installs them — Decision: setup-memory owns memory hooks)
Copy the two scripts from `assets/hooks/` into the project's `.claude/hooks/` (create the dir if
needed), then **merge** their registration into `.claude/settings.json`. Merge additively — never
overwrite an existing `hooks` object (e.g. formatter/lint hooks from `/setup-hooks`).
- `load-memory.sh` → **SessionStart**: injects `MEMORY.md` + `HANDOFF.md`, tells Claude to read
only the files under "Context to Load" (lazy load).
- `remind-save.sh` → **Stop**: nudges `/save-memory` once per session, only on real work, loop-
guarded. **On by default** at Tier 3 (opt-out = remove this Stop entry; see the seeded README).
Registration to merge into `.claude/settings.json` (paths use `$CLAUDE_PROJECT_DIR`):
```json
{
"hooks": {
"SessionStart": [
{ "hooks": [ { "type": "command", "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/load-memory.sh\"" } ] }
],
"Stop": [
{ "hooks": [ { "type": "command", "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/remind-save.sh\"" } ] }
]
}
}
```
> If a `Stop` array already exists (e.g. a test-on-stop hook), append this entry to it rather
> than replacing the array.
### C. The /save-memory skill (installed into the user project)
Install `assets/skills/save-memory.SKILL.md.tmpl` to `.claude/skills/save-memory/SKILL.md`:
1. Substitute `{{PROJECT_NAME}}` and `{{TEMPLATE_VERSION}}`.
2. **Collision-safe:** if `.claude/skills/save-memory/SKILL.md` already exists, do NOT
overwrite — report it and skip. (`template_version` in the frontmatter lets `review`
detect staleness later.)
3. It is a **project asset** — do NOT add it to this plugin's `manifest.json`.
This skill is what distills each session into the store above. Without it, the Stop nudge has
nothing to call.
## Write Rules
- Check flags first (`--claude-md-only`, `--memory-only`) before anything else
- Check if file exists before writing → Overwrite / Merge / Skip?
- **Merge strategy for CLAUDE.md:**
- Known sections (update with new values): Project identity, Tech stack, Architecture overview, Key conventions, Development workflow, What Claude should know, Harness config
- Unknown sections (preserve as-is): anything else the user added
- Always update "Last updated" date on every write, including merges
- **`.claude/memory/` already exists:**
- **Legacy layout** (`project.md` / `team.md` present — the pre-2.4.0 static memory):
do NOT delete. Offer to migrate: keep the old files, add the new structure
(`decisions/ conventions/ sessions/ HANDOFF.md README.md`) + hooks + `/save-memory`,
and fold any real facts from `project.md` into a `decisions/`/`conventions/` entry. The
user may also choose Skip.
- **New layout already present:** Ask — Overwrite seeds / Add missing only / Skip.
"Add missing only" creates any file/dir not already present, leaves existing untouched.
Never overwrite `MEMORY.md`, `HANDOFF.md`, `decisions/`, `conventions/`, or `sessions/`
if they already contain real entries.
- **Hooks merge (settings.json):** additive only — append SessionStart/Stop entries; never
clobber existing hooks (e.g. `/setup-hooks` formatter/lint/test). Skip an entry whose
command is already registered.
- **`/save-memory` skill:** collision-safe — never overwrite an existing
`.claude/skills/save-memory/SKILL.md`. Do not add it to the plugin manifest (project asset).
- Use actual values — no generic text
- No leftover [PLACEHOLDER] or `{{TOKEN}}` after writing
No comments yet. Be the first to comment!