claude-launchpad 0.10.0 → 0.10.1-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -120
- package/dist/chunk-7YDBTED2.js +154 -0
- package/dist/chunk-7YDBTED2.js.map +1 -0
- package/dist/chunk-J5NT4JGE.js +77 -0
- package/dist/chunk-J5NT4JGE.js.map +1 -0
- package/dist/{chunk-TALTTAMW.js → chunk-JXFTVFPC.js} +43 -3
- package/dist/chunk-JXFTVFPC.js.map +1 -0
- package/dist/{chunk-4AF3NGNF.js → chunk-YEGOHLE7.js} +3 -3
- package/dist/{chunk-JTKRLIEV.js → chunk-ZMSHFAZQ.js} +2 -1
- package/dist/cli.js +47 -90
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +39 -75
- package/dist/commands/memory/server.js.map +1 -1
- package/dist/{context-AGNCZJPC.js → context-SGPGEJV4.js} +4 -4
- package/dist/{extract-RPRYPT3Z.js → extract-T32FMLN5.js} +4 -4
- package/dist/{install-PSSMUGLO.js → install-OKLYDFBJ.js} +2 -2
- package/dist/pull-4VKUDKTB.js +66 -0
- package/dist/pull-4VKUDKTB.js.map +1 -0
- package/dist/push-WI3ZIPZU.js +89 -0
- package/dist/push-WI3ZIPZU.js.map +1 -0
- package/dist/{stats-DAUYJ4BE.js → stats-77WLARNA.js} +4 -4
- package/dist/{tui-A4TJFNE3.js → tui-YV7AFJFR.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-TALTTAMW.js.map +0 -1
- /package/dist/{chunk-4AF3NGNF.js.map → chunk-YEGOHLE7.js.map} +0 -0
- /package/dist/{chunk-JTKRLIEV.js.map → chunk-ZMSHFAZQ.js.map} +0 -0
- /package/dist/{context-AGNCZJPC.js.map → context-SGPGEJV4.js.map} +0 -0
- /package/dist/{extract-RPRYPT3Z.js.map → extract-T32FMLN5.js.map} +0 -0
- /package/dist/{install-PSSMUGLO.js.map → install-OKLYDFBJ.js.map} +0 -0
- /package/dist/{stats-DAUYJ4BE.js.map → stats-77WLARNA.js.map} +0 -0
- /package/dist/{tui-A4TJFNE3.js.map → tui-YV7AFJFR.js.map} +0 -0
package/README.md
CHANGED
|
@@ -4,106 +4,109 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/claude-launchpad)
|
|
5
5
|
[](https://github.com/mboss37/claude-launchpad)
|
|
6
6
|
[](https://github.com/mboss37/claude-launchpad/blob/master/LICENSE)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
7
10
|
|
|
8
|
-
**Score your Claude Code
|
|
11
|
+
**Score your Claude Code config. Fix it. Prove it works.**
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
Claude Code follows CLAUDE.md about 80% of the time. Hooks run at 100%. Most developers have zero hooks and too many instructions. Claude Launchpad scores your setup, fixes the gaps, and tests that Claude actually follows your rules.
|
|
14
|
+
|
|
15
|
+
This is for developers using Claude Code who want consistent results: solo devs, vibe coders, AI-first teams. If you have ever wondered why Claude ignores half your CLAUDE.md, this is the fix.
|
|
16
|
+
|
|
17
|
+
## Install and See Your Score
|
|
11
18
|
|
|
12
19
|
```bash
|
|
13
20
|
npx claude-launchpad
|
|
14
21
|
```
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
```
|
|
24
|
+
Instruction Budget ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
25
|
+
CLAUDE.md Quality ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
26
|
+
Settings ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
27
|
+
Hooks ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
28
|
+
Rules ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
29
|
+
Permissions ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
30
|
+
MCP Servers ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
17
31
|
|
|
18
|
-
|
|
32
|
+
Overall ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
✓ No issues found. Your configuration looks solid.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A typical unconfigured project scores ~31%. After `--fix`, it jumps to ~91%.
|
|
21
38
|
|
|
22
|
-
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
**New project:**
|
|
23
42
|
|
|
24
43
|
```bash
|
|
25
|
-
claude-launchpad init
|
|
44
|
+
npx claude-launchpad init
|
|
26
45
|
```
|
|
27
46
|
|
|
28
|
-
Detects your stack
|
|
29
|
-
|
|
30
|
-
Then use `/lp-enhance` inside Claude Code to have Claude read your actual codebase and fill in the architecture and guardrails — not boilerplate, real project-specific content.
|
|
47
|
+
Detects your stack, generates config, hooks, and permissions. Start at ~93%.
|
|
31
48
|
|
|
32
|
-
|
|
49
|
+
**Existing project:**
|
|
33
50
|
|
|
34
51
|
```bash
|
|
35
|
-
claude-launchpad
|
|
52
|
+
npx claude-launchpad doctor --fix
|
|
36
53
|
```
|
|
37
54
|
|
|
38
|
-
Scores your config
|
|
55
|
+
Scores your config, auto-repairs everything it can.
|
|
39
56
|
|
|
40
|
-
##
|
|
57
|
+
## The Three-File System
|
|
41
58
|
|
|
42
|
-
|
|
|
59
|
+
| File | Purpose | Example |
|
|
43
60
|
|---|---|---|
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `claude-launchpad doctor --watch` | Live score that updates when you save config files | Locally |
|
|
48
|
-
| `/lp-enhance` (skill) | Claude reads your code and completes CLAUDE.md | Inside Claude Code |
|
|
49
|
-
| `claude-launchpad eval` | Run Claude against test scenarios, prove config works | Via Claude CLI |
|
|
50
|
-
| `claude-launchpad memory` | Optional memory setup (or stats) + installs `/lp-migrate-memory` skill | Locally |
|
|
51
|
-
| `claude-launchpad memory --dashboard` | TUI dashboard for memory visualization | Locally |
|
|
61
|
+
| `CLAUDE.md` | What Claude needs to know | Stack, commands, conventions, guardrails |
|
|
62
|
+
| `TASKS.md` | What we're doing now | Current sprint, session log, progress |
|
|
63
|
+
| `BACKLOG.md` | What we're doing later | Parked features with P0/P1/P2 priority tiers |
|
|
52
64
|
|
|
53
|
-
|
|
65
|
+
Without BACKLOG.md, deferred features get lost in conversation history or bloat TASKS.md. Init generates all three. Doctor checks for them. `--fix` creates any that are missing.
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
## Commands
|
|
68
|
+
|
|
69
|
+
| Command | What it does | Runs |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `claude-launchpad` | Score your config (routes to doctor) | Locally, free |
|
|
72
|
+
| `claude-launchpad init` | Detect stack, generate config + hooks + permissions | Locally, free |
|
|
73
|
+
| `claude-launchpad doctor --fix` | Auto-fix issues found by doctor | Locally, free |
|
|
74
|
+
| `claude-launchpad eval` | Run Claude against test scenarios, score results | Via Claude CLI |
|
|
75
|
+
| `claude-launchpad memory` | Optional persistent memory system | Locally |
|
|
76
|
+
| `/lp-enhance` (skill) | Claude reads your code and completes CLAUDE.md | Inside Claude Code |
|
|
60
77
|
|
|
61
|
-
|
|
78
|
+
## Doctor
|
|
62
79
|
|
|
63
|
-
|
|
80
|
+
Runs 7 analyzers against your `.claude/` directory and CLAUDE.md. No API calls, no network, no cost.
|
|
64
81
|
|
|
65
|
-
|
|
82
|
+
**Analyzers:**
|
|
66
83
|
|
|
67
84
|
| Analyzer | What it catches |
|
|
68
85
|
|---|---|
|
|
69
|
-
| **Instruction Budget** | Too many instructions
|
|
70
|
-
| **CLAUDE.md Quality** | Missing
|
|
86
|
+
| **Instruction Budget** | Too many instructions. Claude starts ignoring rules past ~200. |
|
|
87
|
+
| **CLAUDE.md Quality** | Missing sections, vague instructions, hardcoded secrets |
|
|
71
88
|
| **Settings** | No hooks configured, dangerous tool access without safety nets |
|
|
72
|
-
| **Hooks** | Missing auto-format
|
|
89
|
+
| **Hooks** | Missing auto-format, no .env protection, no PostCompact hook |
|
|
73
90
|
| **Rules** | Dead rule files, stale references, empty configs |
|
|
74
|
-
| **Permissions** | Credential
|
|
91
|
+
| **Permissions** | Credential exposure (~/.ssh, ~/.aws), blanket Bash approval, sandbox disabled |
|
|
75
92
|
| **MCP Servers** | Invalid transport configs, missing commands/URLs |
|
|
76
93
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
Instruction Budget ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
81
|
-
CLAUDE.md Quality ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
82
|
-
Settings ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
83
|
-
Hooks ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
84
|
-
Rules ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
85
|
-
Permissions ━━━━━━━━━━━━━━━━━━━━ 100%
|
|
86
|
-
MCP Servers ━━━━━━━━━━────────── 50%
|
|
87
|
-
|
|
88
|
-
Overall ━━━━━━━━━━━━━━━━━━━─ 93%
|
|
94
|
+
An optional Memory analyzer runs when agentic memory is detected.
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**All doctor flags:**
|
|
96
|
+
**Flags:**
|
|
94
97
|
|
|
95
98
|
| Flag | What it does |
|
|
96
99
|
|---|---|
|
|
97
|
-
| `--fix` | Auto-
|
|
98
|
-
| `--fix --dry-run` | Preview
|
|
99
|
-
| `--watch` | Re-runs every second
|
|
100
|
-
| `--json` | Pure JSON output
|
|
101
|
-
| `--min-score <n>` | Exit code 1 if score is below threshold
|
|
100
|
+
| `--fix` | Auto-fix: adds hooks, CLAUDE.md sections, BACKLOG.md, rules, .claudeignore |
|
|
101
|
+
| `--fix --dry-run` | Preview fixes without applying them |
|
|
102
|
+
| `--watch` | Re-runs every second as you edit config files |
|
|
103
|
+
| `--json` | Pure JSON output for scripts and CI |
|
|
104
|
+
| `--min-score <n>` | Exit code 1 if score is below threshold (for CI) |
|
|
102
105
|
| `-p, --path <dir>` | Run on a different directory |
|
|
103
106
|
|
|
104
107
|
## Init
|
|
105
108
|
|
|
106
|
-
|
|
109
|
+
Reads your manifest files (package.json, go.mod, pyproject.toml, etc.) and generates config that fits. No templates, no menus.
|
|
107
110
|
|
|
108
111
|
```
|
|
109
112
|
→ Detecting project...
|
|
@@ -119,78 +122,40 @@ Detects your project and generates Claude Code config that fits. No templates, n
|
|
|
119
122
|
✓ Generated .claude/rules/conventions.md
|
|
120
123
|
```
|
|
121
124
|
|
|
122
|
-
**Works with:** TypeScript, JavaScript, Python, Go, Ruby, Rust, Dart, PHP, Java, Kotlin, Swift, Elixir, C# — and detects frameworks (Next.js, FastAPI, Django, Rails, Laravel, Express, SvelteKit, Angular, NestJS, and 15+ more).
|
|
123
|
-
|
|
124
125
|
**What init writes:**
|
|
125
|
-
- Always
|
|
126
|
+
- Always: `CLAUDE.md`, `TASKS.md`, `BACKLOG.md`, `.claude/settings.json`
|
|
126
127
|
- Creates when missing: `.claude/.gitignore`, `.claudeignore`, `.claude/rules/conventions.md`
|
|
127
|
-
- Offers `/lp-enhance` install (project/global/skip)
|
|
128
|
+
- Offers `/lp-enhance` install (project/global/skip) if not already present
|
|
128
129
|
|
|
129
|
-
**
|
|
130
|
-
|
|
131
|
-
| File | Purpose |
|
|
132
|
-
|---|---|
|
|
133
|
-
| `CLAUDE.md` | What Claude needs to know — stack, commands, conventions, guardrails |
|
|
134
|
-
| `TASKS.md` | What we're doing now — sprint tracking, session continuity |
|
|
135
|
-
| `BACKLOG.md` | What we're doing later — parked features with P0/P1/P2 priority tiers |
|
|
136
|
-
|
|
137
|
-
Without BACKLOG.md, deferred features get lost in conversation history or bloat TASKS.md. Init generates it, doctor checks for it, `--fix` creates it if missing.
|
|
130
|
+
**Supported stacks:** TypeScript, JavaScript, Python, Go, Ruby, Rust, Dart, PHP, Java, Kotlin, Swift, Elixir, C#. Detects frameworks: Next.js, FastAPI, Django, Rails, Laravel, Express, SvelteKit, Angular, NestJS, and 15+ more.
|
|
138
131
|
|
|
139
132
|
## Enhance
|
|
140
133
|
|
|
141
|
-
Init detects your stack but
|
|
134
|
+
Init detects your stack but cannot read your architecture. The `/lp-enhance` skill runs inside Claude Code to fill in the details.
|
|
142
135
|
|
|
143
136
|
```
|
|
144
137
|
/lp-enhance
|
|
145
138
|
```
|
|
146
139
|
|
|
147
|
-
|
|
140
|
+
Claude reads your codebase and updates CLAUDE.md with real content: actual architecture, actual conventions, actual guardrails. Not boilerplate. It also suggests project-specific hooks and MCP servers.
|
|
148
141
|
|
|
149
142
|
Stays under the 200-instruction budget. Overflows detailed content to `.claude/rules/` files. If the skill is missing, `doctor --fix` will create it.
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
Optional persistent memory system that replaces Claude Code's built-in flat-file memory with intelligent, decay-based retrieval.
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
claude-launchpad memory
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Requires native deps first: `npm install better-sqlite3 sqlite-vec` (the CLI will prompt you if missing). Interactive setup - asks before changing anything. Installs a SQLite database, hooks for automatic context injection, and 7 MCP tools.
|
|
160
|
-
|
|
161
|
-
**What it does:**
|
|
162
|
-
- **Smart session injection** - each session starts with the most relevant memories, ranked by 6 signals (context, value, importance, recency, type, noise) and packed into a 2000-token budget across three tiers (full content / summary / title-only)
|
|
163
|
-
- **Stop hook** extracts facts from the conversation transcript when you're done
|
|
164
|
-
- **Decay model** - memories fade naturally based on type (episodic: 60 days, semantic: 1 year, procedural: 2 years)
|
|
165
|
-
- **Self-tuning retrieval** - memories Claude actively searches for rise in rank; memories injected but never used gradually stop appearing
|
|
166
|
-
- **Project-scoped** - memories are partitioned per project, no cross-contamination
|
|
167
|
-
- **TUI dashboard** (`--dashboard`) for visualization with vim navigation, filtering, and search
|
|
168
|
-
|
|
169
|
-
No cloud. No sync. Everything stays in `~/.agentic-memory/memory.db`.
|
|
170
|
-
|
|
171
|
-
**Memory flags:**
|
|
172
|
-
|
|
173
|
-
| Flag | What it does |
|
|
174
|
-
|---|---|
|
|
175
|
-
| `--dashboard` | Opens the interactive TUI dashboard |
|
|
176
|
-
|
|
177
|
-
Default behavior of `claude-launchpad memory`:
|
|
178
|
-
- If memory is not installed, it runs interactive install
|
|
179
|
-
- If memory is installed, it shows memory stats
|
|
144
|
+
**When to re-run:** after major refactors, new dependencies, or architecture changes.
|
|
180
145
|
|
|
181
146
|
## Eval
|
|
182
147
|
|
|
183
|
-
|
|
148
|
+
Runs Claude against real test scenarios and scores the results. Nobody else has built this.
|
|
184
149
|
|
|
185
150
|
```bash
|
|
186
|
-
# Interactive mode
|
|
151
|
+
# Interactive mode (pick suite, runs, model)
|
|
187
152
|
claude-launchpad eval
|
|
188
153
|
|
|
189
154
|
# Or pass flags directly
|
|
190
155
|
claude-launchpad eval --suite security --runs 1 --model haiku
|
|
191
156
|
```
|
|
192
157
|
|
|
193
|
-
Each scenario creates an isolated sandbox with your full Claude Code config
|
|
158
|
+
Each scenario creates an isolated sandbox with your full Claude Code config copied in. It runs Claude with a task and checks if your configuration made Claude follow the rules.
|
|
194
159
|
|
|
195
160
|
```
|
|
196
161
|
✓ security/sql-injection 10/10 PASS
|
|
@@ -203,7 +168,7 @@ Each scenario creates an isolated sandbox with your full Claude Code config (set
|
|
|
203
168
|
Config Eval Score ━━━━━━━━━━━━━━━━━━━─ 95%
|
|
204
169
|
```
|
|
205
170
|
|
|
206
|
-
Results
|
|
171
|
+
Results save to `.claude/eval/` as structured markdown. Feed them back to Claude to fix failures.
|
|
207
172
|
|
|
208
173
|
**Suites:**
|
|
209
174
|
|
|
@@ -213,19 +178,48 @@ Results are saved to `.claude/eval/` as structured markdown — you can feed the
|
|
|
213
178
|
| `conventions` | 5 | Error handling, immutability, file size, naming, no hardcoded values |
|
|
214
179
|
| `workflow` | 4 | Git conventions, session continuity, memory persistence, deferred tracking |
|
|
215
180
|
|
|
216
|
-
**
|
|
181
|
+
**Flags:**
|
|
217
182
|
|
|
218
183
|
| Flag | What it does |
|
|
219
184
|
|---|---|
|
|
220
185
|
| `--suite <name>` | Run one suite: `security`, `conventions`, or `workflow` |
|
|
221
|
-
| `-p, --path <dir>` | Project root to evaluate (defaults to
|
|
186
|
+
| `-p, --path <dir>` | Project root to evaluate (defaults to cwd) |
|
|
222
187
|
| `--scenarios <path>` | Use a custom scenarios directory |
|
|
223
188
|
| `--model <model>` | Model to use: `haiku`, `sonnet`, `opus` |
|
|
224
189
|
| `--runs <n>` | Runs per scenario (default 3, median score used) |
|
|
225
|
-
| `--debug` | Keep sandbox directories
|
|
190
|
+
| `--debug` | Keep sandbox directories for inspection |
|
|
226
191
|
| `--json` | JSON output |
|
|
227
192
|
| `--timeout <ms>` | Timeout per run (default 120000) |
|
|
228
193
|
|
|
194
|
+
## Memory
|
|
195
|
+
|
|
196
|
+
Optional persistent memory that replaces Claude Code's built-in flat-file memory with intelligent, decay-based retrieval.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
claude-launchpad memory
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
If memory is not installed, it runs interactive setup. If installed, it shows stats. Requires native deps first: `npm install better-sqlite3 sqlite-vec`.
|
|
203
|
+
|
|
204
|
+
**What it does:**
|
|
205
|
+
- **Smart session injection** starts each session with the most relevant memories, ranked by 6 signals and packed into a 2000-token budget across three tiers
|
|
206
|
+
- **Stop hook** extracts facts from the conversation when you finish
|
|
207
|
+
- **Decay model** fades memories naturally (episodic: 60 days, semantic: 1 year, procedural: 2 years)
|
|
208
|
+
- **Self-tuning retrieval** promotes memories Claude searches for, demotes ones injected but never used
|
|
209
|
+
- **Project-scoped** with no cross-contamination between projects
|
|
210
|
+
- **TUI dashboard** (`--dashboard`) with vim navigation, filtering, and search
|
|
211
|
+
- **Cross-device sync** via private GitHub Gist — push/pull memories between machines
|
|
212
|
+
|
|
213
|
+
Data stays in `~/.agentic-memory/memory.db`. Sync is opt-in and uses your existing `gh` CLI auth.
|
|
214
|
+
|
|
215
|
+
| Flag / Subcommand | What it does |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `--dashboard` | Opens the interactive TUI dashboard |
|
|
218
|
+
| `push` | Push memories to a private GitHub Gist |
|
|
219
|
+
| `pull` | Pull memories from a private GitHub Gist |
|
|
220
|
+
| `push --project <name>` | Push only one project's memories |
|
|
221
|
+
| `pull --project <name>` | Pull only one project's memories |
|
|
222
|
+
|
|
229
223
|
## Use in CI
|
|
230
224
|
|
|
231
225
|
Block PRs that degrade your Claude Code config quality:
|
|
@@ -252,35 +246,38 @@ Score below threshold = exit code 1 = PR blocked.
|
|
|
252
246
|
|
|
253
247
|
**Doctor** reads your files and runs static analysis. No API calls. No network. No cost.
|
|
254
248
|
|
|
255
|
-
**Init** scans manifest files (package.json, go.mod, pyproject.toml, etc.)
|
|
256
|
-
|
|
257
|
-
|
|
249
|
+
**Init** scans manifest files (package.json, go.mod, pyproject.toml, etc.) and detects your stack. Generates 8 files:
|
|
250
|
+
- CLAUDE.md (sprint reviews, backlog management)
|
|
251
|
+
- TASKS.md (session log, sprint tracking)
|
|
252
|
+
- BACKLOG.md (priority-tiered feature parking)
|
|
253
|
+
- settings.json (credential deny rules, sandbox, hooks)
|
|
254
|
+
- .claude/.gitignore, .claudeignore, /lp-enhance skill, conventions.md
|
|
258
255
|
|
|
259
|
-
|
|
256
|
+
Formatter hooks use hardcoded safe commands only.
|
|
260
257
|
|
|
261
|
-
|
|
258
|
+
**Enhance** is a `/lp-enhance` skill installed during `init`. It runs inside your active Claude Code session, not a separate process. Claude already has your codebase context, so it produces better results than an external command.
|
|
262
259
|
|
|
263
|
-
|
|
260
|
+
**Eval** creates a temp directory, copies your full `.claude/` config (settings.json, rules, hooks, permissions) and `.claudeignore` into it, writes seed files from the scenario YAML, initializes a git repo, runs Claude via the Agent SDK (or falls back to CLI), then checks the output with grep/file assertions. Your code is never copied, only your Claude Code configuration. Sandbox is cleaned up after (or preserved with `--debug`).
|
|
264
261
|
|
|
265
262
|
## Glossary
|
|
266
263
|
|
|
267
|
-
New to Claude Code? Here's what the terms mean
|
|
264
|
+
New to Claude Code? Here's what the terms mean.
|
|
268
265
|
|
|
269
266
|
| Term | What it is |
|
|
270
267
|
|---|---|
|
|
271
268
|
| **CLAUDE.md** | A markdown file in your project root that tells Claude how to work on your code. Think of it as instructions for your AI pair programmer. [Official docs](https://docs.anthropic.com/en/docs/claude-code/memory#claudemd) |
|
|
272
269
|
| **TASKS.md** | Sprint tracker and session log. Claude reads this at session start to pick up where you left off. |
|
|
273
270
|
| **BACKLOG.md** | Where deferred features live. Priority tiers (P0/P1/P2) keep future ideas organized without cluttering TASKS.md. |
|
|
274
|
-
| **Hooks** | Shell commands that run automatically when Claude does something.
|
|
271
|
+
| **Hooks** | Shell commands that run automatically when Claude does something. Example: auto-format after edits, block reading `.env`. They live in `.claude/settings.json`. |
|
|
275
272
|
| **Instruction budget** | CLAUDE.md has a soft limit of ~200 actionable lines. Past that, Claude starts ignoring rules at the bottom. Doctor counts your lines and warns you. |
|
|
276
273
|
| **Rules** | Extra markdown files in `.claude/rules/` that Claude reads alongside CLAUDE.md. Use them to offload detailed conventions so CLAUDE.md stays under budget. |
|
|
277
|
-
| **Compaction** | When a
|
|
274
|
+
| **Compaction** | When a conversation gets too long, Claude compresses older messages. This can lose context. A PostCompact hook re-injects critical files (like TASKS.md) after compaction. |
|
|
278
275
|
| **MCP Servers** | External tools Claude can connect to (databases, APIs, docs). Configured in `.claude/settings.json`. Most projects don't need them. |
|
|
279
|
-
| **.claudeignore** | Like `.gitignore` but for Claude. Tells Claude which files to skip
|
|
276
|
+
| **.claudeignore** | Like `.gitignore` but for Claude. Tells Claude which files to skip so it doesn't waste time reading noise. |
|
|
280
277
|
|
|
281
278
|
## Privacy
|
|
282
279
|
|
|
283
|
-
No telemetry. No analytics. No data sent anywhere. Doctor, init, and fix are fully offline. Memory stores data locally at `~/.agentic-memory
|
|
280
|
+
No telemetry. No analytics. No data sent anywhere. Doctor, init, and fix are fully offline. Memory stores data locally at `~/.agentic-memory/`. The optional sync feature (`memory push/pull`) uses a private GitHub Gist under your own account — data goes to GitHub, not to us. Enhance and eval run through your local Claude CLI, no data passes through this tool. [Full privacy policy](https://mboss37.github.io/claude-launchpad/privacy.html).
|
|
284
281
|
|
|
285
282
|
## License
|
|
286
283
|
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_CONFIG,
|
|
4
|
+
resolveDataDir
|
|
5
|
+
} from "./chunk-ZMSHFAZQ.js";
|
|
6
|
+
|
|
7
|
+
// src/commands/memory/utils/gist-transport.ts
|
|
8
|
+
import { execSync } from "child_process";
|
|
9
|
+
import { readFileSync, writeFileSync, unlinkSync, mkdirSync } from "fs";
|
|
10
|
+
import { join, dirname } from "path";
|
|
11
|
+
import { tmpdir } from "os";
|
|
12
|
+
var EXEC_OPTS = { encoding: "utf-8", timeout: 3e4 };
|
|
13
|
+
var GIST_FILENAME = "agentic-memory-sync.json";
|
|
14
|
+
var SYNC_CONFIG_FILE = "sync-config.json";
|
|
15
|
+
function syncConfigPath() {
|
|
16
|
+
return join(resolveDataDir(DEFAULT_CONFIG.dataDir), SYNC_CONFIG_FILE);
|
|
17
|
+
}
|
|
18
|
+
function assertGhAvailable() {
|
|
19
|
+
try {
|
|
20
|
+
execSync("gh --version", { ...EXEC_OPTS, stdio: "pipe" });
|
|
21
|
+
} catch {
|
|
22
|
+
throw new Error(
|
|
23
|
+
"Memory sync requires the GitHub CLI.\nInstall: https://cli.github.com/\nThen run: gh auth login"
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
execSync("gh auth status", { ...EXEC_OPTS, stdio: "pipe" });
|
|
28
|
+
} catch {
|
|
29
|
+
throw new Error(
|
|
30
|
+
"gh is installed but not authenticated.\nRun: gh auth login"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function loadSyncConfig() {
|
|
35
|
+
try {
|
|
36
|
+
const raw = readFileSync(syncConfigPath(), "utf-8");
|
|
37
|
+
const parsed = JSON.parse(raw);
|
|
38
|
+
if (typeof parsed.gistId === "string" && parsed.gistId.length > 0) {
|
|
39
|
+
return { gistId: parsed.gistId };
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function saveSyncConfig(config) {
|
|
47
|
+
const filePath = syncConfigPath();
|
|
48
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
49
|
+
writeFileSync(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
50
|
+
}
|
|
51
|
+
function createGist(payload) {
|
|
52
|
+
const tmpFile = join(tmpdir(), GIST_FILENAME);
|
|
53
|
+
try {
|
|
54
|
+
writeFileSync(tmpFile, payload, "utf-8");
|
|
55
|
+
const result = execSync(
|
|
56
|
+
`gh gist create "${tmpFile}" --desc "agentic-memory sync" --public=false`,
|
|
57
|
+
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
58
|
+
).trim();
|
|
59
|
+
const gistId = result.split("/").pop() ?? "";
|
|
60
|
+
if (!gistId) throw new Error(`Failed to parse gist ID from: ${result}`);
|
|
61
|
+
saveSyncConfig({ gistId });
|
|
62
|
+
return gistId;
|
|
63
|
+
} finally {
|
|
64
|
+
try {
|
|
65
|
+
unlinkSync(tmpFile);
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function readGist(gistId) {
|
|
71
|
+
try {
|
|
72
|
+
return execSync(
|
|
73
|
+
`gh gist view "${gistId}" --filename "${GIST_FILENAME}" --raw`,
|
|
74
|
+
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
75
|
+
);
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function updateGist(gistId, payload) {
|
|
81
|
+
const tmpFile = join(tmpdir(), GIST_FILENAME);
|
|
82
|
+
try {
|
|
83
|
+
writeFileSync(tmpFile, payload, "utf-8");
|
|
84
|
+
execSync(
|
|
85
|
+
`gh gist edit "${gistId}" --filename "${GIST_FILENAME}" "${tmpFile}"`,
|
|
86
|
+
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
87
|
+
);
|
|
88
|
+
} finally {
|
|
89
|
+
try {
|
|
90
|
+
unlinkSync(tmpFile);
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/commands/memory/utils/sync-merge.ts
|
|
97
|
+
function memoryToSyncRow(m) {
|
|
98
|
+
return {
|
|
99
|
+
id: m.id,
|
|
100
|
+
type: m.type,
|
|
101
|
+
title: m.title,
|
|
102
|
+
content: m.content,
|
|
103
|
+
context: m.context,
|
|
104
|
+
source: m.source,
|
|
105
|
+
project: m.project,
|
|
106
|
+
tags: [...m.tags],
|
|
107
|
+
importance: m.importance,
|
|
108
|
+
access_count: m.accessCount,
|
|
109
|
+
injection_count: m.injectionCount,
|
|
110
|
+
created_at: m.createdAt,
|
|
111
|
+
updated_at: m.updatedAt,
|
|
112
|
+
last_accessed: m.lastAccessed
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function mergeFromRemote(memoryRepo, relationRepo, payload, project) {
|
|
116
|
+
let inserted = 0;
|
|
117
|
+
let updated = 0;
|
|
118
|
+
let relationsAdded = 0;
|
|
119
|
+
const memories = project ? payload.memories.filter((m) => m.project === project) : payload.memories;
|
|
120
|
+
for (const remote of memories) {
|
|
121
|
+
const local = memoryRepo.getById(remote.id);
|
|
122
|
+
if (!local) {
|
|
123
|
+
memoryRepo.upsertFromSync(remote);
|
|
124
|
+
inserted++;
|
|
125
|
+
} else if (remote.updated_at > local.updatedAt) {
|
|
126
|
+
memoryRepo.upsertFromSync(remote);
|
|
127
|
+
updated++;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const localIds = new Set(memoryRepo.getAll().map((m) => m.id));
|
|
131
|
+
const relations = payload.relations.filter(
|
|
132
|
+
(r) => localIds.has(r.source_id) && localIds.has(r.target_id)
|
|
133
|
+
);
|
|
134
|
+
for (const rel of relations) {
|
|
135
|
+
const added = relationRepo.create(
|
|
136
|
+
rel.source_id,
|
|
137
|
+
rel.target_id,
|
|
138
|
+
rel.relation_type
|
|
139
|
+
);
|
|
140
|
+
if (added) relationsAdded++;
|
|
141
|
+
}
|
|
142
|
+
return { inserted, updated, relationsAdded };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
assertGhAvailable,
|
|
147
|
+
loadSyncConfig,
|
|
148
|
+
createGist,
|
|
149
|
+
readGist,
|
|
150
|
+
updateGist,
|
|
151
|
+
memoryToSyncRow,
|
|
152
|
+
mergeFromRemote
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=chunk-7YDBTED2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/utils/gist-transport.ts","../src/commands/memory/utils/sync-merge.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { randomUUID } from 'node:crypto';\nimport { resolveDataDir, DEFAULT_CONFIG } from '../config.js';\nimport type { SyncConfig } from '../types.js';\n\nconst EXEC_OPTS = { encoding: 'utf-8' as const, timeout: 30_000 };\nconst GIST_FILENAME = 'agentic-memory-sync.json';\nconst SYNC_CONFIG_FILE = 'sync-config.json';\n\nfunction syncConfigPath(): string {\n return join(resolveDataDir(DEFAULT_CONFIG.dataDir), SYNC_CONFIG_FILE);\n}\n\nexport function assertGhAvailable(): void {\n try {\n execSync('gh --version', { ...EXEC_OPTS, stdio: 'pipe' });\n } catch {\n throw new Error(\n 'Memory sync requires the GitHub CLI.\\n' +\n 'Install: https://cli.github.com/\\n' +\n 'Then run: gh auth login'\n );\n }\n try {\n execSync('gh auth status', { ...EXEC_OPTS, stdio: 'pipe' });\n } catch {\n throw new Error(\n 'gh is installed but not authenticated.\\n' +\n 'Run: gh auth login'\n );\n }\n}\n\nexport function loadSyncConfig(): SyncConfig | null {\n try {\n const raw = readFileSync(syncConfigPath(), 'utf-8');\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (typeof parsed.gistId === 'string' && parsed.gistId.length > 0) {\n return { gistId: parsed.gistId };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function saveSyncConfig(config: SyncConfig): void {\n const filePath = syncConfigPath();\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function createGist(payload: string): string {\n const tmpFile = join(tmpdir(), GIST_FILENAME);\n try {\n writeFileSync(tmpFile, payload, 'utf-8');\n const result = execSync(\n `gh gist create \"${tmpFile}\" --desc \"agentic-memory sync\" --public=false`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n ).trim();\n const gistId = result.split('/').pop() ?? '';\n if (!gistId) throw new Error(`Failed to parse gist ID from: ${result}`);\n saveSyncConfig({ gistId });\n return gistId;\n } finally {\n try { unlinkSync(tmpFile); } catch { /* ignore */ }\n }\n}\n\nexport function readGist(gistId: string): string | null {\n try {\n return execSync(\n `gh gist view \"${gistId}\" --filename \"${GIST_FILENAME}\" --raw`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n } catch {\n return null;\n }\n}\n\nexport function updateGist(gistId: string, payload: string): void {\n const tmpFile = join(tmpdir(), GIST_FILENAME);\n try {\n writeFileSync(tmpFile, payload, 'utf-8');\n execSync(\n `gh gist edit \"${gistId}\" --filename \"${GIST_FILENAME}\" \"${tmpFile}\"`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n } finally {\n try { unlinkSync(tmpFile); } catch { /* ignore */ }\n }\n}\n","import type { Memory, SyncPayload, SyncMemoryRow, MergeResult, RelationType } from '../types.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\n\nfunction memoryToSyncRow(m: Memory): SyncMemoryRow {\n return {\n id: m.id,\n type: m.type,\n title: m.title,\n content: m.content,\n context: m.context,\n source: m.source,\n project: m.project,\n tags: [...m.tags],\n importance: m.importance,\n access_count: m.accessCount,\n injection_count: m.injectionCount,\n created_at: m.createdAt,\n updated_at: m.updatedAt,\n last_accessed: m.lastAccessed,\n };\n}\n\nexport { memoryToSyncRow };\n\nexport function mergeFromRemote(\n memoryRepo: MemoryRepo,\n relationRepo: RelationRepo,\n payload: SyncPayload,\n project?: string,\n): MergeResult {\n let inserted = 0;\n let updated = 0;\n let relationsAdded = 0;\n\n const memories = project\n ? payload.memories.filter((m) => m.project === project)\n : payload.memories;\n\n for (const remote of memories) {\n const local = memoryRepo.getById(remote.id);\n if (!local) {\n memoryRepo.upsertFromSync(remote);\n inserted++;\n } else if (remote.updated_at > local.updatedAt) {\n memoryRepo.upsertFromSync(remote);\n updated++;\n }\n }\n\n const localIds = new Set(memoryRepo.getAll().map((m) => m.id));\n const relations = payload.relations.filter(\n (r) => localIds.has(r.source_id) && localIds.has(r.target_id),\n );\n\n for (const rel of relations) {\n const added = relationRepo.create(\n rel.source_id,\n rel.target_id,\n rel.relation_type as RelationType,\n );\n if (added) relationsAdded++;\n }\n\n return { inserted, updated, relationsAdded };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/commands/memory/types.ts
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
var MEMORY_TYPES = ["working", "episodic", "semantic", "procedural", "pattern"];
|
|
6
|
+
var MEMORY_SOURCES = ["manual", "session_end", "consolidation", "hook", "import"];
|
|
7
|
+
var RELATION_TYPES = [
|
|
8
|
+
"relates_to",
|
|
9
|
+
"depends_on",
|
|
10
|
+
"contradicts",
|
|
11
|
+
"extends",
|
|
12
|
+
"implements",
|
|
13
|
+
"derived_from"
|
|
14
|
+
];
|
|
15
|
+
var StoreInputSchema = z.object({
|
|
16
|
+
type: z.enum(MEMORY_TYPES),
|
|
17
|
+
content: z.string().min(1).max(1e4),
|
|
18
|
+
title: z.string().max(200).optional(),
|
|
19
|
+
tags: z.array(z.string()).max(20).default([]),
|
|
20
|
+
importance: z.number().min(0).max(1).default(0.5),
|
|
21
|
+
context: z.string().optional(),
|
|
22
|
+
source: z.enum(MEMORY_SOURCES).default("manual"),
|
|
23
|
+
project: z.string().max(200).optional()
|
|
24
|
+
});
|
|
25
|
+
var SearchInputSchema = z.object({
|
|
26
|
+
query: z.string().min(1).max(500),
|
|
27
|
+
id: z.string().optional(),
|
|
28
|
+
type: z.enum(MEMORY_TYPES).optional(),
|
|
29
|
+
tags: z.array(z.string()).max(10).optional(),
|
|
30
|
+
limit: z.number().int().min(1).max(50).default(10),
|
|
31
|
+
min_importance: z.number().min(0).max(1).default(0),
|
|
32
|
+
project: z.string().max(200).optional()
|
|
33
|
+
});
|
|
34
|
+
var ForgetInputSchema = z.object({
|
|
35
|
+
id: z.string(),
|
|
36
|
+
hard_delete: z.boolean().default(false)
|
|
37
|
+
});
|
|
38
|
+
var RelateInputSchema = z.object({
|
|
39
|
+
source_id: z.string(),
|
|
40
|
+
target_id: z.string(),
|
|
41
|
+
relation_type: z.enum(RELATION_TYPES)
|
|
42
|
+
});
|
|
43
|
+
var SyncPayloadSchema = z.object({
|
|
44
|
+
version: z.number(),
|
|
45
|
+
machine_id: z.string(),
|
|
46
|
+
pushed_at: z.string(),
|
|
47
|
+
memories: z.array(z.object({
|
|
48
|
+
id: z.string(),
|
|
49
|
+
type: z.enum(MEMORY_TYPES),
|
|
50
|
+
title: z.string().nullable(),
|
|
51
|
+
content: z.string(),
|
|
52
|
+
context: z.string().nullable(),
|
|
53
|
+
source: z.enum(MEMORY_SOURCES).nullable(),
|
|
54
|
+
project: z.string().nullable(),
|
|
55
|
+
tags: z.array(z.string()),
|
|
56
|
+
importance: z.number(),
|
|
57
|
+
access_count: z.number(),
|
|
58
|
+
injection_count: z.number(),
|
|
59
|
+
created_at: z.string(),
|
|
60
|
+
updated_at: z.string(),
|
|
61
|
+
last_accessed: z.string().nullable()
|
|
62
|
+
})),
|
|
63
|
+
relations: z.array(z.object({
|
|
64
|
+
source_id: z.string(),
|
|
65
|
+
target_id: z.string(),
|
|
66
|
+
relation_type: z.enum(RELATION_TYPES),
|
|
67
|
+
created_at: z.string()
|
|
68
|
+
}))
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export {
|
|
72
|
+
MEMORY_TYPES,
|
|
73
|
+
MEMORY_SOURCES,
|
|
74
|
+
RELATION_TYPES,
|
|
75
|
+
SyncPayloadSchema
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=chunk-J5NT4JGE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/types.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ── Memory Types ──────────────────────────────────────────────\n\nexport const MEMORY_TYPES = ['working', 'episodic', 'semantic', 'procedural', 'pattern'] as const;\nexport type MemoryType = typeof MEMORY_TYPES[number];\n\nexport const MEMORY_SOURCES = ['manual', 'session_end', 'consolidation', 'hook', 'import'] as const;\nexport type MemorySource = typeof MEMORY_SOURCES[number];\n\nexport const RELATION_TYPES = [\n 'relates_to', 'depends_on', 'contradicts', 'extends', 'implements', 'derived_from',\n] as const;\nexport type RelationType = typeof RELATION_TYPES[number];\n\n// ── Core Entities ─────────────────────────────────────────────\n\nexport interface Memory {\n readonly id: string;\n readonly type: MemoryType;\n readonly title: string | null;\n readonly content: string;\n readonly context: string | null;\n readonly source: MemorySource | null;\n readonly project: string | null;\n readonly tags: readonly string[];\n readonly importance: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n readonly accessCount: number;\n readonly lastAccessed: string | null;\n readonly injectionCount: number;\n}\n\nexport interface Relation {\n readonly sourceId: string;\n readonly targetId: string;\n readonly relationType: RelationType;\n readonly createdAt: string;\n}\n\n// ── Search Types ──────────────────────────────────────────────\n\nexport interface SearchResult {\n readonly memory: Memory;\n readonly score: number;\n readonly explanation: string;\n}\n\nexport interface FtsMatch {\n readonly rowid: number;\n readonly memoryId: string;\n readonly rank: number;\n}\n\nexport interface ScoredCandidate {\n readonly memoryId: string;\n readonly textScore: number;\n readonly importanceScore: number;\n readonly recencyScore: number;\n readonly accessScore: number;\n readonly contextScore: number;\n readonly composite: number;\n}\n\n// ── Decay Parameters ──────────────────────────────────────────\n\nexport interface DecayParams {\n readonly tauByType: Record<MemoryType, number>;\n readonly accessModifiers: readonly { readonly maxCount: number; readonly multiplier: number }[];\n readonly relationModifier: { readonly connectedThreshold: number; readonly connectedMultiplier: number; readonly isolatedMultiplier: number };\n readonly importanceFloor: number;\n readonly pruneThreshold: number;\n readonly pruneMinAgeDays: number;\n}\n\n// ── Input Schemas (for MCP tools) ─────────────────────────────\n\nexport const StoreInputSchema = z.object({\n type: z.enum(MEMORY_TYPES),\n content: z.string().min(1).max(10000),\n title: z.string().max(200).optional(),\n tags: z.array(z.string()).max(20).default([]),\n importance: z.number().min(0).max(1).default(0.5),\n context: z.string().optional(),\n source: z.enum(MEMORY_SOURCES).default('manual'),\n project: z.string().max(200).optional(),\n});\nexport type StoreInput = z.infer<typeof StoreInputSchema>;\n\nexport const SearchInputSchema = z.object({\n query: z.string().min(1).max(500),\n id: z.string().optional(),\n type: z.enum(MEMORY_TYPES).optional(),\n tags: z.array(z.string()).max(10).optional(),\n limit: z.number().int().min(1).max(50).default(10),\n min_importance: z.number().min(0).max(1).default(0),\n project: z.string().max(200).optional(),\n});\nexport type SearchInput = z.infer<typeof SearchInputSchema>;\n\nexport const ForgetInputSchema = z.object({\n id: z.string(),\n hard_delete: z.boolean().default(false),\n});\nexport type ForgetInput = z.infer<typeof ForgetInputSchema>;\n\nexport const RelateInputSchema = z.object({\n source_id: z.string(),\n target_id: z.string(),\n relation_type: z.enum(RELATION_TYPES),\n});\nexport type RelateInput = z.infer<typeof RelateInputSchema>;\n\n// ── Sync Types ───────────────────────────────────────────────\n\nexport interface SyncPayload {\n readonly version: number;\n readonly machine_id: string;\n readonly pushed_at: string;\n readonly memories: readonly SyncMemoryRow[];\n readonly relations: readonly SyncRelationRow[];\n}\n\nexport interface SyncMemoryRow {\n readonly id: string;\n readonly type: MemoryType;\n readonly title: string | null;\n readonly content: string;\n readonly context: string | null;\n readonly source: MemorySource | null;\n readonly project: string | null;\n readonly tags: readonly string[];\n readonly importance: number;\n readonly access_count: number;\n readonly injection_count: number;\n readonly created_at: string;\n readonly updated_at: string;\n readonly last_accessed: string | null;\n}\n\nexport interface SyncRelationRow {\n readonly source_id: string;\n readonly target_id: string;\n readonly relation_type: RelationType;\n readonly created_at: string;\n}\n\nexport const SyncPayloadSchema = z.object({\n version: z.number(),\n machine_id: z.string(),\n pushed_at: z.string(),\n memories: z.array(z.object({\n id: z.string(),\n type: z.enum(MEMORY_TYPES),\n title: z.string().nullable(),\n content: z.string(),\n context: z.string().nullable(),\n source: z.enum(MEMORY_SOURCES).nullable(),\n project: z.string().nullable(),\n tags: z.array(z.string()),\n importance: z.number(),\n access_count: z.number(),\n injection_count: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n last_accessed: z.string().nullable(),\n })),\n relations: z.array(z.object({\n source_id: z.string(),\n target_id: z.string(),\n relation_type: z.enum(RELATION_TYPES),\n created_at: z.string(),\n })),\n});\n\nexport interface SyncConfig {\n readonly gistId: string;\n}\n\nexport interface MergeResult {\n readonly inserted: number;\n readonly updated: number;\n readonly relationsAdded: number;\n}\n\n// ── Stats ─────────────────────────────────────────────────────\n\nexport interface MemoryStats {\n readonly totalMemories: number;\n readonly byType: Record<MemoryType, number>;\n readonly totalRelations: number;\n readonly dbSizeBytes: number;\n readonly oldestMemory: string | null;\n readonly newestMemory: string | null;\n readonly topInjected: readonly { readonly id: string; readonly title: string | null; readonly injectionCount: number }[];\n}\n"],"mappings":"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","names":[]}
|