toon-memory 1.0.8 โ†’ 1.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luis Angel Valencia Valera
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # toon-memory
2
+
3
+ Persistent memory for AI coding agents โ€” remember decisions, patterns, and bugs between sessions.
4
+
5
+ ๐ŸŽ‰ **1.0 Released!**
6
+
7
+ Supercharge **OpenCode, VS Code Copilot, Claude Code, Cursor, Windsurf, Cline, Continue** and more with Persistent Memory
8
+
9
+ Saves context in **TOON format** (40% fewer tokens than JSON) ยท 5 MCP tools ยท Works everywhere
10
+
11
+ [![npm version](https://img.shields.io/npm/v/toon-memory.svg)](https://www.npmjs.com/package/toon-memory)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
13
+
14
+ ---
15
+
16
+ ## What is toon-memory?
17
+
18
+ AI agents forget everything between sessions. toon-memory fixes this by providing persistent memory that survives restarts.
19
+
20
+ **Use cases:**
21
+ - Remember design decisions ("Why did we choose X over Y?")
22
+ - Track patterns ("This project uses Zod for validation")
23
+ - Store bug resolutions ("Redis pool exhaustion fix")
24
+ - Save project knowledge ("Broker uses RESP protocol")
25
+
26
+ ---
27
+
28
+ ## Get Started
29
+
30
+ ### 1. Install (one command)
31
+
32
+ ```bash
33
+ # macOS / Linux
34
+ curl -fsSL https://raw.githubusercontent.com/LuiggiVal08/toon-memory/main/install.sh | sh
35
+
36
+ # Windows (PowerShell)
37
+ irm https://raw.githubusercontent.com/LuiggiVal08/toon-memory/main/install.ps1 | iex
38
+
39
+ # Or with npm (any platform)
40
+ npm i -g toon-memory
41
+ ```
42
+
43
+ ### 2. Configure your agent(s)
44
+
45
+ ```bash
46
+ # Interactive installer โ€” detects agents and configures MCP
47
+ npx toon-memory
48
+ ```
49
+
50
+ ### 3. Use it
51
+
52
+ ```bash
53
+ # In your next session, run:
54
+ memory_stats # See what's in memory
55
+ memory_recall # Search memory before reading files
56
+ memory_remember # Save important decisions
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Supported Agents
62
+
63
+ | Agent | Config Location | Status |
64
+ |-------|-----------------|--------|
65
+ | **OpenCode** | `.opencode/opencode.json` | โœ… Full support |
66
+ | **VS Code / Copilot** | `.vscode/mcp.json` | โœ… Full support |
67
+ | **Claude Code** | `.claude/settings.json` | โœ… Full support |
68
+ | **Cursor** | `.cursor/mcp.json` | โœ… Full support |
69
+ | **Windsurf** | `.windsurfrules` | โœ… Full support |
70
+ | **Cline** | `.cline/mcp.json` | โœ… Full support |
71
+ | **Continue** | `.continue/config.json` | โœ… Full support |
72
+ | **Aider** | `.aider.conf.yml` | โš ๏ธ Manual config |
73
+
74
+ ---
75
+
76
+ ## Tools
77
+
78
+ | Tool | Description |
79
+ |------|-------------|
80
+ | `memory_remember` | Save a decision, pattern, bug, or knowledge |
81
+ | `memory_recall` | Search memory (use BEFORE reading files) |
82
+ | `memory_forget` | Remove an entry by key or id |
83
+ | `memory_stats` | View memory state |
84
+ | `memory_summary` | Save/retrieve file summaries |
85
+
86
+ ---
87
+
88
+ ## How It Works
89
+
90
+ 1. **MCP Server** โ€” runs locally, talks to your agent via stdio
91
+ 2. **TOON Format** โ€” stores data in Token-Oriented Object Notation (~40% fewer tokens than JSON)
92
+ 3. **Per-project memory** โ€” each project gets `.opencode/memory/data.toon`
93
+ 4. **Zero config** โ€” just install and use
94
+
95
+ ### Memory File Format
96
+
97
+ ```
98
+ version: 1
99
+ entries[3|]{id|category|key|content|file|tags|date}:
100
+ a1b2c3d4|decision|use-zod|Use Zod for validation|src/types.ts|validation;types|2026-07-10
101
+ e5f6g7h8|pattern|pydantic-configs|Project uses Pydantic v2|config.py|python;patterns|2026-07-10
102
+ i9j0k1l2|bug|redis-pool-fix|Added max_connections=20|redis.ts|redis;fix|2026-07-10
103
+ summaries:
104
+ src/services/redis.ts: Redis connection pool with retry logic
105
+ ```
106
+
107
+ ---
108
+
109
+ ## CLI Commands
110
+
111
+ ```bash
112
+ npx toon-memory # Interactive installer
113
+ npx toon-memory init # Quick setup (no prompts)
114
+ npx toon-memory mcp # Run MCP server directly
115
+ npx toon-memory status # Check installation status
116
+ npx toon-memory upgrade # Update to latest version
117
+ npx toon-memory uninstall # Remove from all agents
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Uninstall
123
+
124
+ ```bash
125
+ # Remove from all agents and uninstall CLI
126
+ npx toon-memory uninstall
127
+
128
+ # Or with the global install
129
+ toon-memory uninstall
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Configuration
135
+
136
+ ### Global (all projects)
137
+
138
+ Add to `~/.config/opencode/opencode.json`:
139
+
140
+ ```json
141
+ {
142
+ "mcp": {
143
+ "toon-memory": {
144
+ "type": "local",
145
+ "command": ["npx", "-y", "toon-memory", "mcp"],
146
+ "enabled": true
147
+ }
148
+ }
149
+ }
150
+ ```
151
+
152
+ ### Project-level
153
+
154
+ Add to `.opencode/opencode.json`:
155
+
156
+ ```json
157
+ {
158
+ "mcp": {
159
+ "toon-memory": {
160
+ "type": "local",
161
+ "command": ["npx", "-y", "toon-memory", "mcp"],
162
+ "enabled": true
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ ### VS Code
169
+
170
+ Add to `.vscode/mcp.json`:
171
+
172
+ ```json
173
+ {
174
+ "servers": {
175
+ "toon-memory": {
176
+ "command": "npx",
177
+ "args": ["-y", "toon-memory", "mcp"]
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Why TOON?
186
+
187
+ TOON (Token-Oriented Object Notation) is designed for LLMs:
188
+
189
+ | Format | Token Count | LLM Accuracy |
190
+ |--------|-------------|--------------|
191
+ | JSON | 100 | 75% |
192
+ | YAML | 95 | 72% |
193
+ | **TOON** | **60** | **76.4%** |
194
+
195
+ - **40% fewer tokens** than JSON
196
+ - **Lossless roundtrip** โ€” no data loss
197
+ - **Better LLM comprehension** โ€” structured for AI consumption
198
+
199
+ ---
200
+
201
+ ## Development
202
+
203
+ ```bash
204
+ git clone https://github.com/LuiggiVal08/toon-memory.git
205
+ cd toon-memory
206
+ npm install
207
+ npm run build
208
+ ```
209
+
210
+ ---
211
+
212
+ ## License
213
+
214
+ MIT
215
+
216
+ ---
217
+
218
+ ## Credits
219
+
220
+ Built with [@toon-format/toon](https://www.npmjs.com/package/@toon-format/toon) and [@modelcontextprotocol/server](https://www.npmjs.com/package/@modelcontextprotocol/server).
package/bin/setup.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync, cpSync } from "fs"
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, cpSync, unlinkSync } from "fs"
3
3
  import { dirname, join } from "path"
4
4
  import { fileURLToPath } from "url"
5
5
  import { execSync } from "child_process"
@@ -9,7 +9,7 @@ import { createRequire } from "module"
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url))
10
10
  const projectRoot = process.cwd()
11
11
  const sourceDir = join(__dirname, "..", "src")
12
- const HOME = process.env.HOME || "~"
12
+ const HOME = process.env.HOME || process.env.USERPROFILE || "~"
13
13
 
14
14
  // Auto-install @toon-format/toon if not present
15
15
  try {
@@ -26,89 +26,62 @@ function detectAgents() {
26
26
  // OpenCode
27
27
  const opencodeGlobal = join(HOME, ".config", "opencode", "opencode.json")
28
28
  const opencodeLocal = join(projectRoot, ".opencode", "opencode.json")
29
- if (existsSync(opencodeGlobal) || existsSync(opencodeLocal) || true) { // Always show opencode
30
- agents.push({
31
- name: "opencode",
32
- global: opencodeGlobal,
33
- local: opencodeLocal,
34
- mcpKey: "mcp"
35
- })
36
- }
29
+ agents.push({
30
+ name: "opencode",
31
+ global: opencodeGlobal,
32
+ local: opencodeLocal,
33
+ mcpKey: "mcp"
34
+ })
37
35
 
38
36
  // VS Code / GitHub Copilot
39
37
  const vscodeLocal = join(projectRoot, ".vscode", "mcp.json")
40
- const vscodeGlobal = join(HOME, ".config", "Code", "User", "globalStorage", "github.copilot-chat", "mcp.json")
41
- if (existsSync(vscodeLocal) || existsSync(vscodeGlobal) || true) {
42
- agents.push({
43
- name: "vscode/copilot",
44
- global: vscodeGlobal,
45
- local: vscodeLocal,
46
- mcpKey: "servers"
47
- })
48
- }
38
+ agents.push({
39
+ name: "vscode/copilot",
40
+ local: vscodeLocal,
41
+ mcpKey: "servers"
42
+ })
49
43
 
50
44
  // Claude Code
51
45
  const claudeGlobal = join(HOME, ".claude", "settings.json")
52
46
  const claudeLocal = join(projectRoot, ".claude", "settings.json")
53
- if (existsSync(claudeGlobal) || existsSync(claudeLocal)) {
54
- agents.push({
55
- name: "claude",
56
- global: claudeGlobal,
57
- local: claudeLocal,
58
- mcpKey: "mcpServers"
59
- })
60
- }
47
+ agents.push({
48
+ name: "claude",
49
+ global: claudeGlobal,
50
+ local: claudeLocal,
51
+ mcpKey: "mcpServers"
52
+ })
61
53
 
62
54
  // Cursor
63
55
  const cursorLocal = join(projectRoot, ".cursor", "mcp.json")
64
- if (existsSync(cursorLocal)) {
65
- agents.push({
66
- name: "cursor",
67
- local: cursorLocal,
68
- mcpKey: "mcpServers"
69
- })
70
- }
56
+ agents.push({
57
+ name: "cursor",
58
+ local: cursorLocal,
59
+ mcpKey: "mcpServers"
60
+ })
71
61
 
72
62
  // Windsurf
73
- const windsurfLocal = join(projectRoot, ".windsurfrules")
74
63
  const windsurfGlobal = join(HOME, ".codeium", "windsurf", "mcp_config.json")
75
- if (existsSync(windsurfLocal) || existsSync(windsurfGlobal)) {
76
- agents.push({
77
- name: "windsurf",
78
- global: windsurfGlobal,
79
- local: windsurfLocal,
80
- mcpKey: "mcpServers"
81
- })
82
- }
64
+ agents.push({
65
+ name: "windsurf",
66
+ global: windsurfGlobal,
67
+ mcpKey: "mcpServers"
68
+ })
83
69
 
84
70
  // Cline
85
71
  const clineLocal = join(projectRoot, ".cline", "mcp.json")
86
- if (existsSync(clineLocal)) {
87
- agents.push({
88
- name: "cline",
89
- local: clineLocal,
90
- mcpKey: "mcpServers"
91
- })
92
- }
72
+ agents.push({
73
+ name: "cline",
74
+ local: clineLocal,
75
+ mcpKey: "mcpServers"
76
+ })
93
77
 
94
78
  // Continue
95
79
  const continueLocal = join(projectRoot, ".continue", "config.json")
96
- if (existsSync(continueLocal)) {
97
- agents.push({
98
- name: "continue",
99
- local: continueLocal,
100
- mcpKey: "mcpServers"
101
- })
102
- }
103
-
104
- // Aider
105
- const aiderLocal = join(projectRoot, ".aider.conf.yml")
106
- if (existsSync(aiderLocal)) {
107
- agents.push({
108
- name: "aider",
109
- local: aiderLocal
110
- })
111
- }
80
+ agents.push({
81
+ name: "continue",
82
+ local: continueLocal,
83
+ mcpKey: "mcpServers"
84
+ })
112
85
 
113
86
  return agents
114
87
  }
@@ -152,44 +125,171 @@ function installMCPConfig(agent, scope) {
152
125
  }
153
126
  }
154
127
 
155
- const mcpKey = agent.mcpKey || "mcp"
128
+ const mcpKey = agent.mcpKey || "mcpServers"
156
129
  if (!config[mcpKey]) config[mcpKey] = {}
157
130
 
158
- // Different agents use different config formats
159
- if (agent.name === "vscode/copilot") {
160
- config[mcpKey]["toon-memory"] = {
161
- command: "npx",
162
- args: ["-y", "toon-memory", "mcp"],
163
- env: {}
131
+ config[mcpKey]["toon-memory"] = {
132
+ command: "npx",
133
+ args: ["-y", "toon-memory", "mcp"]
134
+ }
135
+
136
+ writeFileSync(configPath, JSON.stringify(config, null, 2))
137
+ console.log(` MCP server added to ${configPath}`)
138
+ }
139
+
140
+ // Uninstall from all agents
141
+ function uninstall() {
142
+ console.log("\n๐Ÿง  toon-memory uninstaller\n")
143
+
144
+ const agents = detectAgents()
145
+
146
+ for (const agent of agents) {
147
+ const configs = [agent.global, agent.local].filter(Boolean)
148
+
149
+ for (const configPath of configs) {
150
+ if (!existsSync(configPath)) continue
151
+
152
+ try {
153
+ const config = JSON.parse(readFileSync(configPath, "utf-8"))
154
+ const mcpKey = agent.mcpKey || "mcpServers"
155
+
156
+ if (config[mcpKey]?.["toon-memory"]) {
157
+ delete config[mcpKey]["toon-memory"]
158
+ writeFileSync(configPath, JSON.stringify(config, null, 2))
159
+ console.log(` โœ… Removed from ${agent.name} (${configPath})`)
160
+ }
161
+ } catch {}
164
162
  }
165
- } else if (agent.name === "aider") {
166
- // Aider uses YAML, skip JSON config
167
- console.log(` ${agent.name}: Add to .aider.conf.yml:`)
168
- console.log(` mcp Servers:\n toon-memory:\n command: npx\n args: ["-y", "toon-memory", "mcp"]`)
169
- return
163
+ }
164
+
165
+ // Remove custom tools
166
+ const toolsFile = join(projectRoot, ".opencode", "tools", "memory.ts")
167
+ if (existsSync(toolsFile)) {
168
+ unlinkSync(toolsFile)
169
+ console.log(" โœ… Removed .opencode/tools/memory.ts")
170
+ }
171
+
172
+ console.log("\nโœ… toon-memory uninstalled from all agents\n")
173
+ }
174
+
175
+ // Quick init without interactive prompts
176
+ function init(scope = "local") {
177
+ console.log("\n๐Ÿง  toon-memory init\n")
178
+
179
+ const agents = detectAgents()
180
+
181
+ for (const agent of agents) {
182
+ console.log(`${agent.name}:`)
183
+
184
+ if (agent.name === "opencode") {
185
+ installOpenCodeTools()
186
+ }
187
+
188
+ installMCPConfig(agent, scope)
189
+ console.log("")
190
+ }
191
+
192
+ console.log("Done! Restart your agent to use memory tools.\n")
193
+ }
194
+
195
+ // Show installation status
196
+ function status() {
197
+ console.log("\n๐Ÿง  toon-memory status\n")
198
+
199
+ // Check npm package
200
+ try {
201
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"))
202
+ console.log(`Version: ${pkg.version}`)
203
+ } catch {
204
+ console.log("Version: unknown")
205
+ }
206
+
207
+ // Check memory file
208
+ const memoryFile = join(projectRoot, ".opencode", "memory", "data.toon")
209
+ if (existsSync(memoryFile)) {
210
+ const data = readFileSync(memoryFile, "utf-8")
211
+ const lines = data.split("\n").filter((l) => l.startsWith(" ") && l.includes("|"))
212
+ console.log(`Memory: ${lines.length} entries`)
170
213
  } else {
171
- config[mcpKey]["toon-memory"] = {
172
- command: "npx",
173
- args: ["-y", "toon-memory", "mcp"]
214
+ console.log("Memory: not initialized")
215
+ }
216
+
217
+ // Check agent configs
218
+ const agents = detectAgents()
219
+ console.log("\nAgent configs:")
220
+
221
+ for (const agent of agents) {
222
+ const configs = [agent.global, agent.local].filter(Boolean)
223
+ let found = false
224
+
225
+ for (const configPath of configs) {
226
+ if (!existsSync(configPath)) continue
227
+
228
+ try {
229
+ const config = JSON.parse(readFileSync(configPath, "utf-8"))
230
+ const mcpKey = agent.mcpKey || "mcpServers"
231
+
232
+ if (config[mcpKey]?.["toon-memory"]) {
233
+ console.log(` โœ… ${agent.name} (${configPath})`)
234
+ found = true
235
+ }
236
+ } catch {}
237
+ }
238
+
239
+ if (!found) {
240
+ console.log(` โŒ ${agent.name} (not configured)`)
174
241
  }
175
242
  }
176
243
 
177
- writeFileSync(configPath, JSON.stringify(config, null, 2))
178
- console.log(` MCP server added to ${configPath}`)
244
+ console.log("")
245
+ }
246
+
247
+ // Upgrade to latest version
248
+ function upgrade() {
249
+ console.log("\n๐Ÿง  toon-memory upgrade\n")
250
+
251
+ try {
252
+ console.log("Checking for updates...")
253
+ const latest = execSync("npm view toon-memory version", { encoding: "utf-8" }).trim()
254
+ console.log(`Latest version: ${latest}`)
255
+
256
+ console.log("Upgrading...")
257
+ execSync("npm install -g toon-memory@" + latest, { stdio: "inherit" })
258
+
259
+ console.log("\nโœ… Upgraded to toon-memory@" + latest)
260
+ console.log("Restart your agent to use the new version.\n")
261
+ } catch (error) {
262
+ console.error("Upgrade failed:", error.message)
263
+ }
179
264
  }
180
265
 
181
266
  // Main
182
- const agents = detectAgents()
183
- console.log("\n๐Ÿง  toon-memory installer\n")
267
+ const args = process.argv.slice(2)
268
+
269
+ if (args[0] === "uninstall") {
270
+ uninstall()
271
+ process.exit(0)
272
+ }
184
273
 
185
- if (agents.length === 0) {
186
- console.log("No supported agents detected. Installing custom tools...")
187
- installOpenCodeTools()
188
- console.log("\nDone! Restart your agent to use memory tools.")
274
+ if (args[0] === "init") {
275
+ init(args[1] || "local")
189
276
  process.exit(0)
190
277
  }
191
278
 
192
- console.log("Detected/supported agents:")
279
+ if (args[0] === "status") {
280
+ status()
281
+ process.exit(0)
282
+ }
283
+
284
+ if (args[0] === "upgrade") {
285
+ upgrade()
286
+ process.exit(0)
287
+ }
288
+
289
+ const agents = detectAgents()
290
+ console.log("\n๐Ÿง  toon-memory installer\n")
291
+
292
+ console.log("Supported agents:")
193
293
  agents.forEach((a, i) => console.log(` ${i + 1}. ${a.name}`))
194
294
  console.log("")
195
295
 
@@ -210,5 +310,6 @@ rl.question("Install (1) Local or (2) Global? [1/2]: ", (answer) => {
210
310
  }
211
311
 
212
312
  console.log("Done! Restart your agent to use memory tools.")
313
+ console.log("Run 'npx toon-memory uninstall' to remove.\n")
213
314
  rl.close()
214
315
  })
package/install.ps1 ADDED
@@ -0,0 +1,62 @@
1
+ # toon-memory installer for Windows (PowerShell)
2
+ # Usage: irm https://raw.githubusercontent.com/LuiggiVal08/toon-memory/main/install.ps1 | iex
3
+
4
+ $TOON_VERSION = "1.0.9"
5
+
6
+ Write-Host "๐Ÿง  toon-memory installer" -ForegroundColor Cyan
7
+ Write-Host ""
8
+
9
+ # Check if npm is available
10
+ if (Get-Command npm -ErrorAction SilentlyContinue) {
11
+ Write-Host "Installing toon-memory via npm..."
12
+ npm install -g toon-memory@$TOON_VERSION
13
+ Write-Host ""
14
+ Write-Host "โœ… toon-memory installed!" -ForegroundColor Green
15
+ Write-Host ""
16
+ Write-Host "Next steps:"
17
+ Write-Host " 1. Run: npx toon-memory"
18
+ Write-Host " 2. Select your agent(s)"
19
+ Write-Host " 3. Choose local or global install"
20
+ Write-Host ""
21
+ } else {
22
+ Write-Host "npm not found. Installing standalone..." -ForegroundColor Yellow
23
+ Write-Host ""
24
+
25
+ # Create installation directory
26
+ $INSTALL_DIR = "$env:USERPROFILE\.toon-memory"
27
+ New-Item -ItemType Directory -Force -Path $INSTALL_DIR | Out-Null
28
+
29
+ # Download the package
30
+ Write-Host "Downloading toon-memory v$TOON_VERSION..."
31
+ $url = "https://registry.npmjs.org/toon-memory/-/toon-memory-$TOON_VERSION.tgz"
32
+ $tgzPath = "$INSTALL_DIR\toon-memory.tgz"
33
+ Invoke-WebRequest -Uri $url -OutFile $tgzPath
34
+
35
+ # Extract
36
+ cd $INSTALL_DIR
37
+ tar xzf toon-memory.tgz
38
+ Move-Item -Path "package\*" -Destination "." -Force
39
+ Remove-Item -Path "package" -Recurse -Force
40
+ Remove-Item -Path $tgzPath -Force
41
+
42
+ # Create launcher script
43
+ $launcherContent = @"
44
+ `$SCRIPT_DIR = Split-Path -Parent `$MyInvocation.MyCommand.Path
45
+ node "`$SCRIPT_DIR\bin\toon-memory.js" @args
46
+ "@
47
+ Set-Content -Path "$INSTALL_DIR\toon-memory.ps1" -Value $launcherContent
48
+
49
+ # Add to PATH if not already there
50
+ $currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
51
+ if ($currentPath -notlike "*$INSTALL_DIR*") {
52
+ [Environment]::SetEnvironmentVariable("Path", "$INSTALL_DIR;$currentPath", "User")
53
+ Write-Host "Added to PATH"
54
+ }
55
+
56
+ Write-Host ""
57
+ Write-Host "โœ… toon-memory installed to $INSTALL_DIR" -ForegroundColor Green
58
+ Write-Host ""
59
+ Write-Host "โš ๏ธ Open a new PowerShell window, then run:"
60
+ Write-Host " toon-memory.ps1"
61
+ Write-Host ""
62
+ }
package/install.sh ADDED
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # toon-memory installer for macOS/Linux
5
+ # Usage: curl -fsSL https://raw.githubusercontent.com/luiggival/toon-memory/main/install.sh | sh
6
+
7
+ TOON_VERSION="1.0.8"
8
+ NPM_REGISTRY="https://registry.npmjs.org"
9
+
10
+ echo "๐Ÿง  toon-memory installer"
11
+ echo ""
12
+
13
+ # Check if npm is available
14
+ if command -v npm &> /dev/null; then
15
+ echo "Installing toon-memory via npm..."
16
+ npm install -g toon-memory@${TOON_VERSION}
17
+ echo ""
18
+ echo "โœ… toon-memory installed!"
19
+ echo ""
20
+ echo "Next steps:"
21
+ echo " 1. Run: npx toon-memory"
22
+ echo " 2. Select your agent(s)"
23
+ echo " 3. Choose local or global install"
24
+ echo ""
25
+ else
26
+ echo "npm not found. Installing standalone..."
27
+ echo ""
28
+
29
+ # Create installation directory
30
+ INSTALL_DIR="${HOME}/.toon-memory"
31
+ mkdir -p "${INSTALL_DIR}"
32
+
33
+ # Download the package
34
+ echo "Downloading toon-memory v${TOON_VERSION}..."
35
+ curl -fsSL "https://registry.npmjs.org/toon-memory/-/toon-memory-${TOON_VERSION}.tgz" -o "${INSTALL_DIR}/toon-memory.tgz"
36
+
37
+ # Extract
38
+ cd "${INSTALL_DIR}"
39
+ tar xzf toon-memory.tgz
40
+ mv package/* .
41
+ rmdir package
42
+ rm toon-memory.tgz
43
+
44
+ # Create launcher script
45
+ cat > "${INSTALL_DIR}/toon-memory" << 'LAUNCHER'
46
+ #!/bin/bash
47
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
48
+ node "${SCRIPT_DIR}/bin/toon-memory.js" "$@"
49
+ LAUNCHER
50
+ chmod +x "${INSTALL_DIR}/toon-memory"
51
+
52
+ # Add to PATH if not already there
53
+ SHELL_RC=""
54
+ if [ -f "${HOME}/.bashrc" ]; then
55
+ SHELL_RC="${HOME}/.bashrc"
56
+ elif [ -f "${HOME}/.zshrc" ]; then
57
+ SHELL_RC="${HOME}/.zshrc"
58
+ fi
59
+
60
+ if [ -n "${SHELL_RC}" ]; then
61
+ if ! grep -q "${INSTALL_DIR}" "${SHELL_RC}" 2>/dev/null; then
62
+ echo "" >> "${SHELL_RC}"
63
+ echo "# toon-memory" >> "${SHELL_RC}"
64
+ echo "export PATH=\"${INSTALL_DIR}:\$PATH\"" >> "${SHELL_RC}"
65
+ echo "Added to PATH in ${SHELL_RC}"
66
+ fi
67
+ fi
68
+
69
+ echo ""
70
+ echo "โœ… toon-memory installed to ${INSTALL_DIR}"
71
+ echo ""
72
+ echo "โš ๏ธ Open a new terminal, then run:"
73
+ echo " toon-memory"
74
+ echo ""
75
+ fi
package/mcp/server.js CHANGED
@@ -623,7 +623,7 @@ function $constructor(name, initializer3, params) {
623
623
  Object.defineProperty(_, "name", { value: name });
624
624
  return _;
625
625
  }
626
- var $brand = /* @__PURE__ */ Symbol("zod_brand");
626
+ var $brand = Symbol("zod_brand");
627
627
  var $ZodAsyncError = class extends Error {
628
628
  constructor() {
629
629
  super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
@@ -10366,8 +10366,8 @@ function yo_default() {
10366
10366
 
10367
10367
  // node_modules/zod/v4/core/registries.js
10368
10368
  var _a2;
10369
- var $output = /* @__PURE__ */ Symbol("ZodOutput");
10370
- var $input = /* @__PURE__ */ Symbol("ZodInput");
10369
+ var $output = Symbol("ZodOutput");
10370
+ var $input = Symbol("ZodInput");
10371
10371
  var $ZodRegistry = class {
10372
10372
  constructor() {
10373
10373
  this._map = /* @__PURE__ */ new WeakMap();
@@ -21148,14 +21148,14 @@ var Ajv = import_ajv.Ajv;
21148
21148
  import process3 from "node:process";
21149
21149
 
21150
21150
  // node_modules/@modelcontextprotocol/server/dist/mcp-CM8J1mhp.mjs
21151
- var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
21151
+ var COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
21152
21152
  function isCompletable(schema) {
21153
21153
  return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
21154
21154
  }
21155
21155
  function getCompleter(schema) {
21156
21156
  return schema[COMPLETABLE_SYMBOL]?.complete;
21157
21157
  }
21158
- var BRANDS = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
21158
+ var BRANDS = Symbol.for("mcp.sdk.errorBrands");
21159
21159
  function stampErrorBrands(instance, ctor) {
21160
21160
  const brands = /* @__PURE__ */ new Set();
21161
21161
  let current = ctor;
@@ -22468,7 +22468,7 @@ var CACHEABLE_RESULT_METHODS = [
22468
22468
  function isCacheableResultMethod(method) {
22469
22469
  return CACHEABLE_RESULT_METHODS.includes(method);
22470
22470
  }
22471
- var RESULT_CACHE_HINT_FALLBACK = /* @__PURE__ */ Symbol("modelcontextprotocol.resultCacheHintFallback");
22471
+ var RESULT_CACHE_HINT_FALLBACK = Symbol("modelcontextprotocol.resultCacheHintFallback");
22472
22472
  function attachCacheHintFallback(result, hint) {
22473
22473
  if (hint === void 0) return result;
22474
22474
  const attached = result[RESULT_CACHE_HINT_FALLBACK];
@@ -27664,7 +27664,7 @@ function generateId() {
27664
27664
  return randomBytes(4).toString("hex");
27665
27665
  }
27666
27666
  var server = new McpServer(
27667
- { name: "toon-memory", version: "1.0.8" },
27667
+ { name: "toon-memory", version: "1.1.0" },
27668
27668
  { capabilities: { tools: { listChanged: true } } }
27669
27669
  );
27670
27670
  server.registerTool(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toon-memory",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "Persistent memory system for AI coding agents using TOON format (40% fewer tokens than JSON)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,13 +10,23 @@
10
10
  "src/",
11
11
  "bin/",
12
12
  "mcp/",
13
- "skills/"
13
+ "skills/",
14
+ "install.sh",
15
+ "install.ps1",
16
+ "uninstall.sh"
14
17
  ],
18
+ "scripts": {
19
+ "build": "esbuild src/mcp/server.ts --bundle --platform=node --format=esm --outfile=mcp/server.js",
20
+ "prepublishOnly": "npm run build"
21
+ },
15
22
  "dependencies": {
16
23
  "@modelcontextprotocol/server": "^2.0.0-beta.3",
17
24
  "@toon-format/toon": "^2.3.0",
18
25
  "zod": "^4.4.3"
19
26
  },
27
+ "devDependencies": {
28
+ "esbuild": "^0.25.0"
29
+ },
20
30
  "keywords": [
21
31
  "opencode",
22
32
  "vscode",
@@ -33,5 +43,14 @@
33
43
  "llm",
34
44
  "token-efficiency"
35
45
  ],
36
- "license": "MIT"
46
+ "author": "luiggival",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/luiggival/toon-memory.git"
51
+ },
52
+ "homepage": "https://github.com/luiggival/toon-memory#readme",
53
+ "bugs": {
54
+ "url": "https://github.com/luiggival/toon-memory/issues"
55
+ }
37
56
  }
package/src/mcp/server.ts CHANGED
@@ -32,7 +32,7 @@ function generateId(): string {
32
32
  }
33
33
 
34
34
  const server = new McpServer(
35
- { name: "toon-memory", version: "1.0.8" },
35
+ { name: "toon-memory", version: "1.1.0" },
36
36
  { capabilities: { tools: { listChanged: true } } }
37
37
  )
38
38
 
package/uninstall.sh ADDED
@@ -0,0 +1,107 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # toon-memory uninstaller
5
+ # Usage: npx toon-memory uninstall
6
+
7
+ echo "๐Ÿง  toon-memory uninstaller"
8
+ echo ""
9
+
10
+ # Remove from OpenCode
11
+ OPENCODE_GLOBAL="${HOME}/.config/opencode/opencode.json"
12
+ OPENCODE_LOCAL=".opencode/opencode.json"
13
+
14
+ remove_from_config() {
15
+ local file="$1"
16
+ local name="$2"
17
+
18
+ if [ -f "${file}" ]; then
19
+ if grep -q "toon-memory" "${file}" 2>/dev/null; then
20
+ echo "Removing from ${name} (${file})..."
21
+ # Use node to remove the MCP entry
22
+ node -e "
23
+ const fs = require('fs');
24
+ const config = JSON.parse(fs.readFileSync('${file}', 'utf-8'));
25
+ if (config.mcp && config.mcp['toon-memory']) {
26
+ delete config.mcp['toon-memory'];
27
+ fs.writeFileSync('${file}', JSON.stringify(config, null, 2));
28
+ console.log(' โœ… Removed');
29
+ } else if (config.mcpServers && config.mcpServers['toon-memory']) {
30
+ delete config.mcpServers['toon-memory'];
31
+ fs.writeFileSync('${file}', JSON.stringify(config, null, 2));
32
+ console.log(' โœ… Removed');
33
+ } else {
34
+ console.log(' โš ๏ธ Not found');
35
+ }
36
+ " 2>/dev/null || echo " โš ๏ธ Could not parse config"
37
+ fi
38
+ fi
39
+ }
40
+
41
+ # OpenCode
42
+ remove_from_config "${OPENCODE_GLOBAL}" "OpenCode (global)"
43
+ remove_from_config "${OPENCODE_LOCAL}" "OpenCode (local)"
44
+
45
+ # VS Code
46
+ remove_from_config ".vscode/mcp.json" "VS Code"
47
+
48
+ # Claude
49
+ remove_from_config "${HOME}/.claude/settings.json" "Claude (global)"
50
+ remove_from_config ".claude/settings.json" "Claude (local)"
51
+
52
+ # Cursor
53
+ remove_from_config ".cursor/mcp.json" "Cursor"
54
+
55
+ # Cline
56
+ remove_from_config ".cline/mcp.json" "Cline"
57
+
58
+ # Continue
59
+ remove_from_config ".continue/config.json" "Continue"
60
+
61
+ # Remove custom tools if they exist
62
+ if [ -d ".opencode/tools" ]; then
63
+ if [ -f ".opencode/tools/memory.ts" ]; then
64
+ echo "Removing custom tools..."
65
+ rm -f ".opencode/tools/memory.ts"
66
+ echo " โœ… Removed memory.ts"
67
+ fi
68
+ fi
69
+
70
+ # Remove memory file (ask user)
71
+ if [ -f ".opencode/memory/data.toon" ]; then
72
+ echo ""
73
+ read -p "Remove memory file (.opencode/memory/data.toon)? [y/N] " -n 1 -r
74
+ echo
75
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
76
+ rm -rf ".opencode/memory"
77
+ echo " โœ… Removed memory directory"
78
+ fi
79
+ fi
80
+
81
+ # Uninstall npm package
82
+ echo ""
83
+ read -p "Uninstall toon-memory CLI? [y/N] " -n 1 -r
84
+ echo
85
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
86
+ if command -v npm &> /dev/null; then
87
+ npm uninstall -g toon-memory 2>/dev/null && echo " โœ… Uninstalled from npm" || echo " โš ๏ธ Not installed via npm"
88
+ fi
89
+
90
+ # Remove standalone install
91
+ if [ -d "${HOME}/.toon-memory" ]; then
92
+ rm -rf "${HOME}/.toon-memory"
93
+ echo " โœ… Removed standalone install"
94
+ fi
95
+
96
+ # Remove from PATH in shell configs
97
+ for rc in "${HOME}/.bashrc" "${HOME}/.zshrc"; do
98
+ if [ -f "${rc}" ] && grep -q "toon-memory" "${rc}" 2>/dev/null; then
99
+ sed -i '/# toon-memory/d;/.toon-memory/d' "${rc}"
100
+ echo " โœ… Cleaned ${rc}"
101
+ fi
102
+ done
103
+ fi
104
+
105
+ echo ""
106
+ echo "โœ… toon-memory uninstalled"
107
+ echo ""