memcore-ai 1.0.2

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/.cursorrules ADDED
@@ -0,0 +1,7 @@
1
+ # Project Rules — generated by memcore
2
+
3
+ ## Project Context
4
+
5
+ - **arquitectura base**: usamos TypeScript con tsx, sin compilar, Node 24
6
+ - **stack del proyecto**: Node 24, TypeScript, tsx, sin compilar, chalk para colores
7
+
package/CLAUDE.md ADDED
@@ -0,0 +1,12 @@
1
+ # MEMCORE — Project Memory
2
+
3
+ _Auto-generated by [memcore](https://github.com/your-username/memcore). Do not edit manually._
4
+
5
+ ## Project Context
6
+
7
+ ### arquitectura base
8
+ usamos TypeScript con tsx, sin compilar, Node 24
9
+
10
+ ### stack del proyecto
11
+ Node 24, TypeScript, tsx, sin compilar, chalk para colores
12
+
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # MEMCORE — Universal AI Memory Layer
2
+
3
+ > **Git for AI memory.** Give every AI tool persistent memory across sessions.
4
+
5
+ [![npm](https://img.shields.io/npm/v/memcore)](https://www.npmjs.com/package/memcore)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ---
9
+
10
+ ## The problem
11
+
12
+ Every time you open Claude Code, Cursor, or ChatGPT — it forgets everything.
13
+ Your architecture decisions. Your team conventions. Your project context.
14
+ You explain the same things over and over. Every session. Every developer.
15
+
16
+ **No AI tool has real persistent memory. Until now.**
17
+
18
+ ---
19
+
20
+ ## What is MEMCORE?
21
+
22
+ MEMCORE is a universal memory layer that works with any AI tool.
23
+ Save context once. Every AI remembers it forever.
24
+ `ash
25
+ npm install -g memcore
26
+ `
27
+
28
+ ---
29
+
30
+ ## How it works
31
+ `ash
32
+ # 1. Initialize in your project
33
+ memcore init
34
+
35
+ # 2. Save what matters
36
+ memcore save
37
+ # > Memory name: auth system
38
+ # > Type: project
39
+ # > Content: we use JWT, not sessions — compliance requirement
40
+
41
+ # 3. Inject into your AI tools
42
+ memcore inject # → writes CLAUDE.md for Claude Code
43
+ memcore inject-cursor # → writes .cursorrules for Cursor
44
+ memcore inject-chatgpt # → exports context for ChatGPT
45
+
46
+ # 4. Your AI now knows everything — without you explaining anything
47
+ claude # Claude Code reads CLAUDE.md automatically
48
+ `
49
+
50
+ ---
51
+
52
+ ## Team sharing
53
+ `ash
54
+ # Dev 1 — save and share
55
+ memcore save
56
+ memcore push
57
+ git add memcore-sync.json && git commit -m "chore: update team memory"
58
+
59
+ # Dev 2 — get all context instantly
60
+ git pull
61
+ memcore pull
62
+ memcore inject
63
+ # Done. Full project context in seconds.
64
+ `
65
+
66
+ ---
67
+
68
+ ## Commands
69
+
70
+ | Command | What it does |
71
+ |---|---|
72
+ | memcore init | Initialize in current project |
73
+ | memcore save | Save a new memory |
74
+ | memcore list | List all memories |
75
+ | memcore search query | Search memories |
76
+ | memcore delete id | Delete a memory |
77
+ | memcore inject | Inject into CLAUDE.md |
78
+ | memcore inject-cursor | Inject into .cursorrules |
79
+ | memcore inject-chatgpt | Export for ChatGPT |
80
+ | memcore push | Export team memories |
81
+ | memcore pull | Import team memories |
82
+ | memcore export | Export to memcore.json |
83
+ | memcore import | Import from memcore.json |
84
+
85
+ ---
86
+
87
+ ## Memory types
88
+
89
+ | Type | What to save |
90
+ |---|---|
91
+ | project | Architecture decisions, tech stack, constraints |
92
+ | feedback | How to work with you, what to avoid |
93
+ | user | Your role, expertise level, preferences |
94
+ | reference | Where info lives — Linear, Jira, Slack, Grafana |
95
+
96
+ ---
97
+
98
+ ## SDK
99
+ ` ypescript
100
+ import { memcore } from 'memcore'
101
+
102
+ // Get full project context as string
103
+ const context = memcore.getContext()
104
+
105
+ // Save a memory programmatically
106
+ memcore.save('auth system', 'project', 'we use JWT — compliance requirement')
107
+
108
+ // Search memories
109
+ const results = memcore.search('auth')
110
+
111
+ // Inject into AI tools
112
+ memcore.inject() // Claude Code
113
+ memcore.injectCursor() // Cursor
114
+ `
115
+
116
+ ---
117
+
118
+ ## The memcore.json protocol
119
+
120
+ MEMCORE defines an open standard for AI memory.
121
+ Any tool can read and write it.
122
+ `json
123
+ {
124
+ "version": "1.0",
125
+ "project": { "name": "my-project" },
126
+ "memories": [
127
+ {
128
+ "name": "auth system",
129
+ "type": "project",
130
+ "content": "we use JWT, not sessions"
131
+ }
132
+ ],
133
+ "rules": ["never touch legacy/payments.ts"],
134
+ "references": { "bugs": "Linear project INGEST" },
135
+ "integrations": { "claude": true, "cursor": true, "chatgpt": true }
136
+ }
137
+ `
138
+
139
+ ---
140
+
141
+ ## AI tools supported
142
+
143
+ | Tool | How | Status |
144
+ |---|---|---|
145
+ | Claude Code | Writes CLAUDE.md | Live |
146
+ | Cursor | Writes .cursorrules | Live |
147
+ | ChatGPT | Exports .txt | Live |
148
+ | Gemini CLI | Coming soon | Planned |
149
+ | GitHub Copilot | Coming soon | Planned |
150
+
151
+ ---
152
+
153
+ ## Roadmap
154
+
155
+ - [x] Core memory system
156
+ - [x] Claude Code integration
157
+ - [x] Cursor integration
158
+ - [x] ChatGPT integration
159
+ - [x] Team sync via Git
160
+ - [x] Open protocol (memcore.json)
161
+ - [x] SDK
162
+ - [ ] Daemon (auto-injection)
163
+ - [ ] MEMCORE Cloud (team SaaS)
164
+ - [ ] Memory Graph
165
+ - [ ] Notion, Slack, Jira connectors
166
+
167
+ ---
168
+
169
+ ## License
170
+
171
+ MIT — free forever for individuals.
172
+
173
+ ---
174
+
175
+ Built with the belief that AI tools should remember what matters.
package/bin/memcore.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'child_process'
3
+ import { fileURLToPath } from 'url'
4
+ import { dirname, join } from 'path'
5
+
6
+ const __filename = fileURLToPath(import.meta.url)
7
+ const __dirname = dirname(__filename)
8
+
9
+ const cli = join(__dirname, '..', 'src', 'cli', 'index.ts')
10
+ const args = process.argv.slice(2)
11
+
12
+ const child = spawn('npx', ['tsx', cli, ...args], { stdio: 'inherit', shell: true })
13
+ child.on('exit', code => process.exit(code))
@@ -0,0 +1,27 @@
1
+ {
2
+ "teamId": "memcore",
3
+ "version": 1775348293616,
4
+ "updatedAt": "2026-04-05T00:18:13.616Z",
5
+ "memories": [
6
+ {
7
+ "id": "1775330220683-arquitectura-base",
8
+ "name": "arquitectura base",
9
+ "type": "project",
10
+ "description": "decisiones de arquitectura del proyecto",
11
+ "content": "usamos TypeScript con tsx, sin compilar, Node 24",
12
+ "author": "Roy",
13
+ "createdAt": "2026-04-04T19:17:00.683Z",
14
+ "hash": "21b5c5e1"
15
+ },
16
+ {
17
+ "id": "1775331355076-stack-del-proyecto",
18
+ "name": "stack del proyecto",
19
+ "type": "project",
20
+ "description": "tecnologías que usamos",
21
+ "content": "Node 24, TypeScript, tsx, sin compilar, chalk para colores",
22
+ "author": "Roy",
23
+ "createdAt": "2026-04-04T19:35:55.076Z",
24
+ "hash": "e5f0bd01"
25
+ }
26
+ ]
27
+ }
package/memcore.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "version": "1.0",
3
+ "project": {
4
+ "name": "memcore",
5
+ "description": ""
6
+ },
7
+ "memories": [
8
+ {
9
+ "name": "arquitectura base",
10
+ "type": "project",
11
+ "description": "decisiones de arquitectura del proyecto",
12
+ "content": "usamos TypeScript con tsx, sin compilar, Node 24"
13
+ },
14
+ {
15
+ "name": "stack del proyecto",
16
+ "type": "project",
17
+ "description": "tecnologías que usamos",
18
+ "content": "Node 24, TypeScript, tsx, sin compilar, chalk para colores"
19
+ },
20
+ {
21
+ "name": "arquitectura base",
22
+ "type": "project",
23
+ "description": "decisiones de arquitectura del proyecto",
24
+ "content": "usamos TypeScript con tsx, sin compilar, Node 24"
25
+ },
26
+ {
27
+ "name": "stack del proyecto",
28
+ "type": "project",
29
+ "description": "tecnologías que usamos",
30
+ "content": "Node 24, TypeScript, tsx, sin compilar, chalk para colores"
31
+ }
32
+ ],
33
+ "rules": [],
34
+ "references": {},
35
+ "integrations": {
36
+ "claude": true,
37
+ "cursor": true,
38
+ "chatgpt": true
39
+ }
40
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "": "https://memcore.dev/schema/v1",
3
+ "version": "1.0",
4
+ "project": {
5
+ "name": "mi-proyecto",
6
+ "description": "descripción del proyecto"
7
+ },
8
+ "memories": [
9
+ {
10
+ "name": "ejemplo",
11
+ "type": "project",
12
+ "description": "decisión de arquitectura",
13
+ "content": "usamos PostgreSQL por compliance"
14
+ }
15
+ ],
16
+ "rules": [
17
+ "nunca tocar legacy/payments.ts",
18
+ "siempre escribir tests antes del código"
19
+ ],
20
+ "references": {
21
+ "bugs": "Linear proyecto INGEST",
22
+ "deploy": "GitHub Actions",
23
+ "docs": "Notion"
24
+ },
25
+ "integrations": {
26
+ "claude": true,
27
+ "cursor": true,
28
+ "chatgpt": true
29
+ }
30
+ }
package/memoryTypes.ts ADDED
@@ -0,0 +1,20 @@
1
+ export const MEMORY_TYPES = ['user', 'feedback', 'project', 'reference'] as const
2
+
3
+ export type MemoryType = typeof MEMORY_TYPES[number]
4
+
5
+ export type Memory = {
6
+ id: string
7
+ name: string
8
+ description: string
9
+ type: MemoryType
10
+ content: string
11
+ createdAt: Date
12
+ updatedAt: Date
13
+ projectPath: string
14
+ isTeam: boolean
15
+ }
16
+
17
+ export function parseMemoryType(raw: unknown): MemoryType | undefined {
18
+ if (typeof raw !== 'string') return undefined
19
+ return MEMORY_TYPES.find(t => t === raw)
20
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "memcore-ai",
3
+ "version": "1.0.2",
4
+ "description": "Universal AI memory layer for Claude, ChatGPT, Cursor and more",
5
+ "type": "module",
6
+ "bin": {
7
+ "memcore": "./bin/memcore.js"
8
+ },
9
+ "scripts": {
10
+ "start": "tsx src/cli/index.ts",
11
+ "dev": "tsx watch src/cli/index.ts"
12
+ },
13
+ "keywords": [
14
+ "ai",
15
+ "memory",
16
+ "claude",
17
+ "cursor",
18
+ "copilot",
19
+ "chatgpt"
20
+ ],
21
+ "author": "",
22
+ "license": "MIT",
23
+ "devDependencies": {
24
+ "@types/node": "^22.0.0",
25
+ "tsx": "^4.0.0",
26
+ "typescript": "^5.0.0"
27
+ },
28
+ "dependencies": {
29
+ "chalk": "^5.3.0",
30
+ "chokidar": "^3.6.0",
31
+ "commander": "^12.0.0",
32
+ "gray-matter": "^4.0.3"
33
+ }
34
+ }
package/rl.question(q ADDED
File without changes
@@ -0,0 +1,100 @@
1
+ import chalk from 'chalk'
2
+ import { Command } from 'commander'
3
+ import * as readline from 'readline'
4
+ import { deleteMemory, initMemoryDir, loadMemories, saveMemory, searchMemories } from '../core/memory-store.js'
5
+ import { injectMemories } from '../core/injector.js'
6
+ import { injectCursor, injectChatGPT } from '../core/connectors.js'
7
+ import { exportToSync, importFromSync } from '../sync/teamSync.js'
8
+ import { exportToSchema, importFromSchema } from '../sync/protocol.js'
9
+
10
+ const program = new Command()
11
+ const PROJECT_PATH = process.cwd()
12
+
13
+ program.name('memcore').description('Universal AI memory layer').version('1.0.0')
14
+
15
+ program.command('init').description('Initialize memcore').action(() => {
16
+ initMemoryDir(PROJECT_PATH)
17
+ console.log(chalk.green('✓ Ready! Use: memcore save'))
18
+ })
19
+
20
+ program.command('save').description('Save a memory').action(async () => {
21
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
22
+ const ask = (q) => new Promise(res => rl.question(q, res))
23
+ const name = await ask('Memory name: ')
24
+ const type = await ask('Type (user/feedback/project/reference): ')
25
+ const description = await ask('Short description: ')
26
+ const content = await ask('Content: ')
27
+ rl.close()
28
+ const memory = saveMemory(PROJECT_PATH, name, type, content, description, false)
29
+ console.log(chalk.green('✓ Saved: ' + memory.name))
30
+ })
31
+
32
+ program.command('list').description('List memories').action(() => {
33
+ const memories = loadMemories(PROJECT_PATH, false)
34
+ if (memories.length === 0) { console.log(chalk.yellow('No memories yet.')); return }
35
+ console.log(chalk.bold('Memories (' + memories.length + '):'))
36
+ for (const m of memories) {
37
+ console.log(chalk.green('▸ ' + m.name) + chalk.gray(' [' + m.type + ']'))
38
+ console.log(chalk.gray(' ' + m.description))
39
+ }
40
+ })
41
+
42
+ program.command('search <query>').description('Search memories').action((query) => {
43
+ const results = searchMemories(PROJECT_PATH, query)
44
+ if (results.length === 0) { console.log(chalk.yellow('No results for: ' + query)); return }
45
+ console.log(chalk.bold('Results (' + results.length + '):'))
46
+ for (const m of results) {
47
+ console.log(chalk.green('▸ ' + m.name) + chalk.gray(' [' + m.type + ']'))
48
+ console.log(chalk.gray(' ' + m.description))
49
+ console.log(chalk.white(' ' + m.content.slice(0, 100)))
50
+ }
51
+ })
52
+
53
+ program.command('delete <id>').description('Delete a memory').action((id) => {
54
+ const deleted = deleteMemory(PROJECT_PATH, id)
55
+ if (deleted) { console.log(chalk.green('✓ Deleted: ' + id)) }
56
+ else { console.log(chalk.red('✗ Not found: ' + id)) }
57
+ })
58
+
59
+ program.command('inject').description('Inject into CLAUDE.md').action(() => {
60
+ injectMemories(PROJECT_PATH)
61
+ })
62
+
63
+ program.command('inject-cursor').description('Inject into .cursorrules').action(() => {
64
+ injectCursor(PROJECT_PATH)
65
+ })
66
+
67
+ program.command('inject-chatgpt').description('Export for ChatGPT').action(() => {
68
+ injectChatGPT(PROJECT_PATH)
69
+ })
70
+
71
+ program.command('push').description('Export memories for team').action(() => {
72
+ const manifest = exportToSync(PROJECT_PATH)
73
+ console.log(chalk.green('✓ Exported ' + manifest.memories.length + ' memories to memcore-sync.json'))
74
+ console.log(chalk.gray(' Commit this file to Git so your team can pull it.'))
75
+ })
76
+
77
+ program.command('pull').description('Import memories from team').action(() => {
78
+ const imported = importFromSync(PROJECT_PATH)
79
+ if (imported === 0) {
80
+ console.log(chalk.yellow('No new memories to import.'))
81
+ } else {
82
+ console.log(chalk.green('✓ Imported ' + imported + ' new team memories.'))
83
+ }
84
+ })
85
+
86
+ program.command('export').description('Export to memcore.json protocol').action(() => {
87
+ const memories = [...loadMemories(PROJECT_PATH, false), ...loadMemories(PROJECT_PATH, true)]
88
+ exportToSchema(PROJECT_PATH, memories)
89
+ })
90
+
91
+ program.command('import').description('Import from memcore.json protocol').action(() => {
92
+ const imported = importFromSchema(PROJECT_PATH)
93
+ if (imported === 0) {
94
+ console.log(chalk.yellow('Nothing imported.'))
95
+ } else {
96
+ console.log(chalk.green('✓ Imported ' + imported + ' items from memcore.json'))
97
+ }
98
+ })
99
+
100
+ program.parse()
@@ -0,0 +1,76 @@
1
+ import * as fs from 'fs'
2
+ import * as path from 'path'
3
+ import { loadMemories } from './memory-store.js'
4
+
5
+ export function injectCursor(projectPath) {
6
+ const all = [...loadMemories(projectPath, false), ...loadMemories(projectPath, true)]
7
+
8
+ if (all.length === 0) {
9
+ console.log('No memories to inject.')
10
+ return
11
+ }
12
+
13
+ let content = '# Project Rules — generated by memcore\n\n'
14
+
15
+ const byType = { user: [], feedback: [], project: [], reference: [] }
16
+ for (const m of all) {
17
+ if (byType[m.type]) byType[m.type].push(m)
18
+ }
19
+
20
+ if (byType.project.length > 0) {
21
+ content += '## Project Context\n\n'
22
+ for (const m of byType.project) {
23
+ content += '- **' + m.name + '**: ' + m.content + '\n'
24
+ }
25
+ content += '\n'
26
+ }
27
+
28
+ if (byType.feedback.length > 0) {
29
+ content += '## How to work with me\n\n'
30
+ for (const m of byType.feedback) {
31
+ content += '- **' + m.name + '**: ' + m.content + '\n'
32
+ }
33
+ content += '\n'
34
+ }
35
+
36
+ if (byType.user.length > 0) {
37
+ content += '## About the developer\n\n'
38
+ for (const m of byType.user) {
39
+ content += '- **' + m.name + '**: ' + m.content + '\n'
40
+ }
41
+ content += '\n'
42
+ }
43
+
44
+ if (byType.reference.length > 0) {
45
+ content += '## References\n\n'
46
+ for (const m of byType.reference) {
47
+ content += '- **' + m.name + '**: ' + m.content + '\n'
48
+ }
49
+ content += '\n'
50
+ }
51
+
52
+ const cursorRules = path.join(projectPath, '.cursorrules')
53
+ fs.writeFileSync(cursorRules, content, 'utf-8')
54
+ console.log('✓ Injected ' + all.length + ' memories into .cursorrules')
55
+ console.log(' Cursor will now read this automatically.')
56
+ }
57
+
58
+ export function injectChatGPT(projectPath) {
59
+ const all = [...loadMemories(projectPath, false), ...loadMemories(projectPath, true)]
60
+
61
+ if (all.length === 0) {
62
+ console.log('No memories to inject.')
63
+ return
64
+ }
65
+
66
+ let content = 'CONTEXT FOR THIS PROJECT:\n\n'
67
+ for (const m of all) {
68
+ content += '- ' + m.name + ': ' + m.content + '\n'
69
+ }
70
+ content += '\nPlease keep this context in mind for all responses.'
71
+
72
+ const outFile = path.join(projectPath, 'memcore-chatgpt.txt')
73
+ fs.writeFileSync(outFile, content, 'utf-8')
74
+ console.log('✓ Injected ' + all.length + ' memories into memcore-chatgpt.txt')
75
+ console.log(' Copy and paste this file content into ChatGPT as your first message.')
76
+ }
@@ -0,0 +1,100 @@
1
+ import chalk from 'chalk'
2
+ import { Command } from 'commander'
3
+ import * as readline from 'readline'
4
+ import {
5
+ deleteMemory,
6
+ initMemoryDir,
7
+ loadMemories,
8
+ saveMemory,
9
+ searchMemories,
10
+ } from '../core/memory-store.js'
11
+ import { MEMORY_TYPES, type MemoryType } from '../core/memory-types.js'
12
+
13
+ const program = new Command()
14
+ const PROJECT_PATH = process.cwd()
15
+
16
+ program
17
+ .name('memcore')
18
+ .description('Universal AI memory layer')
19
+ .version('1.0.0')
20
+
21
+ program
22
+ .command('init')
23
+ .description('Initialize memcore in current project')
24
+ .action(() => {
25
+ initMemoryDir(PROJECT_PATH)
26
+ console.log(chalk.green('\n✓ Ready. Start saving memories with: memcore save'))
27
+ })
28
+
29
+ program
30
+ .command('save')
31
+ .description('Save a new memory')
32
+ .option('-n, --name <name>', 'Memory name')
33
+ .option('-t, --type <type>', 'Memory type (user/feedback/project/reference)')
34
+ .option('-d, --desc <description>', 'Short description')
35
+ .option('-c, --content <content>', 'Memory content')
36
+ .option('--team', 'Save as team memory (shared)')
37
+ .action(async (opts) => {
38
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
39
+ const ask = (q: string) => new Promise<string>(res => rl.question(q, res))
40
+
41
+ const name = opts.name || await ask(chalk.cyan('Memory name: '))
42
+ const rawType = opts.type || await ask(chalk.cyan(`Type (${MEMORY_TYPES.join('/')}): `))
43
+ const type = (MEMORY_TYPES.includes(rawType as MemoryType) ? rawType : 'project') as MemoryType
44
+ const description = opts.desc || await ask(chalk.cyan('Short description: '))
45
+ const content = opts.content || await ask(chalk.cyan('Content: '))
46
+ rl.close()
47
+
48
+ const memory = saveMemory(PROJECT_PATH, name, type, content, description, opts.team ?? false)
49
+ console.log(chalk.green(`\n✓ Memory saved: ${memory.name} [${memory.type}]`))
50
+ })
51
+
52
+ program
53
+ .command('list')
54
+ .description('List all memories')
55
+ .option('--team', 'Show team memories')
56
+ .action((opts) => {
57
+ const memories = loadMemories(PROJECT_PATH, opts.team ?? false)
58
+ if (memories.length === 0) {
59
+ console.log(chalk.yellow('No memories found. Run: memcore save'))
60
+ return
61
+ }
62
+ console.log(chalk.bold(`\n📦 ${opts.team ? 'Team' : 'Private'} memories (${memories.length}):\n`))
63
+ for (const m of memories) {
64
+ console.log(chalk.green(`▸ ${m.name}`) + chalk.gray(` [${m.type}]`))
65
+ console.log(chalk.gray(` ${m.description}`))
66
+ console.log()
67
+ }
68
+ })
69
+
70
+ program
71
+ .command('search <query>')
72
+ .description('Search memories by keyword')
73
+ .action((query) => {
74
+ const results = searchMemories(PROJECT_PATH, query)
75
+ if (results.length === 0) {
76
+ console.log(chalk.yellow(`No memories found for: "${query}"`))
77
+ return
78
+ }
79
+ console.log(chalk.bold(`\n🔍 Results for "${query}" (${results.length}):\n`))
80
+ for (const m of results) {
81
+ console.log(chalk.green(`▸ ${m.name}`) + chalk.gray(` [${m.type}]`))
82
+ console.log(chalk.gray(` ${m.description}`))
83
+ console.log(chalk.white(` ${m.content.slice(0, 100)}...`))
84
+ console.log()
85
+ }
86
+ })
87
+
88
+ program
89
+ .command('delete <id>')
90
+ .description('Delete a memory by ID')
91
+ .action((id) => {
92
+ const deleted = deleteMemory(PROJECT_PATH, id)
93
+ if (deleted) {
94
+ console.log(chalk.green(`✓ Memory deleted: ${id}`))
95
+ } else {
96
+ console.log(chalk.red(`✗ Memory not found: ${id}`))
97
+ }
98
+ })
99
+
100
+ program.parse()
@@ -0,0 +1,59 @@
1
+ import * as fs from 'fs'
2
+ import * as path from 'path'
3
+ import { loadMemories } from './memory-store.js'
4
+
5
+ export function injectMemories(projectPath) {
6
+ const private_memories = loadMemories(projectPath, false)
7
+ const team_memories = loadMemories(projectPath, true)
8
+ const all = [...private_memories, ...team_memories]
9
+
10
+ if (all.length === 0) {
11
+ console.log('No memories to inject.')
12
+ return
13
+ }
14
+
15
+ let content = '# MEMCORE — Project Memory\n\n'
16
+ content += '_Auto-generated by [memcore](https://github.com/your-username/memcore). Do not edit manually._\n\n'
17
+
18
+ const byType = { user: [], feedback: [], project: [], reference: [] }
19
+ for (const m of all) {
20
+ if (byType[m.type]) byType[m.type].push(m)
21
+ }
22
+
23
+ if (byType.project.length > 0) {
24
+ content += '## Project Context\n\n'
25
+ for (const m of byType.project) {
26
+ content += '### ' + m.name + '\n'
27
+ content += m.content + '\n\n'
28
+ }
29
+ }
30
+
31
+ if (byType.feedback.length > 0) {
32
+ content += '## How to work with me\n\n'
33
+ for (const m of byType.feedback) {
34
+ content += '### ' + m.name + '\n'
35
+ content += m.content + '\n\n'
36
+ }
37
+ }
38
+
39
+ if (byType.user.length > 0) {
40
+ content += '## About the developer\n\n'
41
+ for (const m of byType.user) {
42
+ content += '### ' + m.name + '\n'
43
+ content += m.content + '\n\n'
44
+ }
45
+ }
46
+
47
+ if (byType.reference.length > 0) {
48
+ content += '## References\n\n'
49
+ for (const m of byType.reference) {
50
+ content += '### ' + m.name + '\n'
51
+ content += m.content + '\n\n'
52
+ }
53
+ }
54
+
55
+ const claudeMd = path.join(projectPath, 'CLAUDE.md')
56
+ fs.writeFileSync(claudeMd, content, 'utf-8')
57
+ console.log('✓ Injected ' + all.length + ' memories into CLAUDE.md')
58
+ console.log(' Claude Code will now read this automatically.')
59
+ }
@@ -0,0 +1,58 @@
1
+ import * as fs from 'fs'
2
+ import * as path from 'path'
3
+ import matter from 'gray-matter'
4
+ import { parseMemoryType } from './memory-types.js'
5
+
6
+ const MEMCORE_DIR = '.memcore'
7
+
8
+ export function getMemoryDir(projectPath) {
9
+ return path.join(projectPath, MEMCORE_DIR)
10
+ }
11
+
12
+ export function initMemoryDir(projectPath) {
13
+ const memDir = getMemoryDir(projectPath)
14
+ if (!fs.existsSync(memDir)) {
15
+ fs.mkdirSync(memDir, { recursive: true })
16
+ fs.mkdirSync(path.join(memDir, 'team'), { recursive: true })
17
+ console.log('✓ Memcore initialized at ' + memDir)
18
+ } else {
19
+ console.log('✓ Memcore already initialized')
20
+ }
21
+ }
22
+
23
+ export function saveMemory(projectPath, name, type, content, description, isTeam) {
24
+ const memDir = getMemoryDir(projectPath)
25
+ const folder = isTeam ? path.join(memDir, 'team') : memDir
26
+ const id = Date.now() + '-' + name.toLowerCase().replace(/\s+/g, '-')
27
+ const filePath = path.join(folder, id + '.md')
28
+ const fileContent = matter.stringify(content, { name, description, type, createdAt: new Date().toISOString(), isTeam })
29
+ fs.writeFileSync(filePath, fileContent, 'utf-8')
30
+ return { id, name, description, type, content, createdAt: new Date(), updatedAt: new Date(), projectPath, isTeam }
31
+ }
32
+
33
+ export function loadMemories(projectPath, isTeam) {
34
+ const memDir = getMemoryDir(projectPath)
35
+ const folder = isTeam ? path.join(memDir, 'team') : memDir
36
+ if (!fs.existsSync(folder)) return []
37
+ const files = fs.readdirSync(folder).filter(f => f.endsWith('.md'))
38
+ return files.map(file => {
39
+ const raw = fs.readFileSync(path.join(folder, file), 'utf-8')
40
+ const { data, content } = matter(raw)
41
+ return { id: file.replace('.md', ''), name: data.name ?? file, description: data.description ?? '', type: parseMemoryType(data.type) ?? 'project', content: content.trim(), createdAt: new Date(data.createdAt ?? Date.now()), updatedAt: new Date(data.updatedAt ?? Date.now()), projectPath, isTeam: data.isTeam ?? false }
42
+ })
43
+ }
44
+
45
+ export function deleteMemory(projectPath, id) {
46
+ const memDir = getMemoryDir(projectPath)
47
+ const candidates = [path.join(memDir, id + '.md'), path.join(memDir, 'team', id + '.md')]
48
+ for (const p of candidates) {
49
+ if (fs.existsSync(p)) { fs.unlinkSync(p); return true }
50
+ }
51
+ return false
52
+ }
53
+
54
+ export function searchMemories(projectPath, query) {
55
+ const all = [...loadMemories(projectPath, false), ...loadMemories(projectPath, true)]
56
+ const q = query.toLowerCase()
57
+ return all.filter(m => m.name.toLowerCase().includes(q) || m.description.toLowerCase().includes(q) || m.content.toLowerCase().includes(q))
58
+ }
@@ -0,0 +1,6 @@
1
+ export const MEMORY_TYPES = ['user', 'feedback', 'project', 'reference']
2
+
3
+ export function parseMemoryType(raw) {
4
+ if (typeof raw !== 'string') return undefined
5
+ return MEMORY_TYPES.find(t => t === raw)
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { loadMemories, saveMemory, searchMemories, initMemoryDir } from './core/memory-store.js'
2
+ import { injectMemories } from './core/injector.js'
3
+ import { injectCursor, injectChatGPT } from './core/connectors.js'
4
+ import { exportToSync, importFromSync } from './sync/teamSync.js'
5
+ import { exportToSchema, importFromSchema } from './sync/protocol.js'
6
+
7
+ export class Memcore {
8
+ private projectPath: string
9
+
10
+ constructor(projectPath: string = process.cwd()) {
11
+ this.projectPath = projectPath
12
+ initMemoryDir(projectPath)
13
+ }
14
+
15
+ getContext(): string {
16
+ const memories = [...loadMemories(this.projectPath, false), ...loadMemories(this.projectPath, true)]
17
+ if (memories.length === 0) return ''
18
+ let context = 'PROJECT CONTEXT:\n\n'
19
+ for (const m of memories) {
20
+ context += '- ' + m.name + ': ' + m.content + '\n'
21
+ }
22
+ return context
23
+ }
24
+
25
+ getMemories() {
26
+ return [...loadMemories(this.projectPath, false), ...loadMemories(this.projectPath, true)]
27
+ }
28
+
29
+ save(name: string, type: string, content: string, description: string = '', team: boolean = false) {
30
+ return saveMemory(this.projectPath, name, type as any, content, description, team)
31
+ }
32
+
33
+ search(query: string) {
34
+ return searchMemories(this.projectPath, query)
35
+ }
36
+
37
+ inject() {
38
+ injectMemories(this.projectPath)
39
+ }
40
+
41
+ injectCursor() {
42
+ injectCursor(this.projectPath)
43
+ }
44
+
45
+ injectChatGPT() {
46
+ injectChatGPT(this.projectPath)
47
+ }
48
+
49
+ push() {
50
+ return exportToSync(this.projectPath)
51
+ }
52
+
53
+ pull() {
54
+ return importFromSync(this.projectPath)
55
+ }
56
+
57
+ export() {
58
+ const memories = this.getMemories()
59
+ exportToSchema(this.projectPath, memories)
60
+ }
61
+
62
+ import() {
63
+ return importFromSchema(this.projectPath)
64
+ }
65
+ }
66
+
67
+ export const memcore = new Memcore()
68
+ export { loadMemories, saveMemory, searchMemories, initMemoryDir }
@@ -0,0 +1,69 @@
1
+ import * as fs from 'fs'
2
+ import * as path from 'path'
3
+ import { saveMemory, initMemoryDir } from '../core/memory-store.js'
4
+
5
+ export type MemcoreSchema = {
6
+ version: string
7
+ project: { name: string; description: string }
8
+ memories: { name: string; type: string; description: string; content: string }[]
9
+ rules: string[]
10
+ references: Record<string, string>
11
+ integrations: Record<string, boolean>
12
+ }
13
+
14
+ export function validateSchema(data: any): boolean {
15
+ if (!data.version) { console.error('Missing: version'); return false }
16
+ if (!data.project?.name) { console.error('Missing: project.name'); return false }
17
+ if (!Array.isArray(data.memories)) { console.error('Missing: memories[]'); return false }
18
+ return true
19
+ }
20
+
21
+ export function importFromSchema(projectPath: string): number {
22
+ const schemaPath = path.join(projectPath, 'memcore.json')
23
+ if (!fs.existsSync(schemaPath)) {
24
+ console.error('No memcore.json found in this project.')
25
+ return 0
26
+ }
27
+
28
+ const raw = fs.readFileSync(schemaPath, 'utf-8')
29
+ const data: MemcoreSchema = JSON.parse(raw)
30
+
31
+ if (!validateSchema(data)) return 0
32
+
33
+ initMemoryDir(projectPath)
34
+ let imported = 0
35
+
36
+ for (const m of data.memories) {
37
+ saveMemory(projectPath, m.name, m.type as any, m.content, m.description, true)
38
+ imported++
39
+ }
40
+
41
+ for (const rule of data.rules ?? []) {
42
+ saveMemory(projectPath, rule, 'feedback', rule, 'project rule', true)
43
+ imported++
44
+ }
45
+
46
+ for (const [key, value] of Object.entries(data.references ?? {})) {
47
+ saveMemory(projectPath, key, 'reference', value, 'external reference', true)
48
+ imported++
49
+ }
50
+
51
+ return imported
52
+ }
53
+
54
+ export function exportToSchema(projectPath: string, memories: any[]): void {
55
+ const schema: MemcoreSchema = {
56
+ version: '1.0',
57
+ project: { name: path.basename(projectPath), description: '' },
58
+ memories: memories.filter(m => m.type === 'project' || m.type === 'user').map(m => ({
59
+ name: m.name, type: m.type, description: m.description, content: m.content
60
+ })),
61
+ rules: memories.filter(m => m.type === 'feedback').map(m => m.content),
62
+ references: Object.fromEntries(memories.filter(m => m.type === 'reference').map(m => [m.name, m.content])),
63
+ integrations: { claude: true, cursor: true, chatgpt: true }
64
+ }
65
+
66
+ const schemaPath = path.join(projectPath, 'memcore.json')
67
+ fs.writeFileSync(schemaPath, JSON.stringify(schema, null, 2), 'utf-8')
68
+ console.log('✓ memcore.json created — this is your portable memory protocol file.')
69
+ }
@@ -0,0 +1,80 @@
1
+ import * as fs from 'fs'
2
+ import * as path from 'path'
3
+ import * as crypto from 'crypto'
4
+ import { loadMemories, saveMemory } from '../core/memory-store.js'
5
+
6
+ const SYNC_FILE = 'memcore-sync.json'
7
+
8
+ export type SyncMemory = {
9
+ id: string
10
+ name: string
11
+ type: string
12
+ description: string
13
+ content: string
14
+ author: string
15
+ createdAt: string
16
+ hash: string
17
+ }
18
+
19
+ export type SyncManifest = {
20
+ teamId: string
21
+ version: number
22
+ updatedAt: string
23
+ memories: SyncMemory[]
24
+ }
25
+
26
+ function hashContent(content: string): string {
27
+ return crypto.createHash('sha256').update(content).digest('hex').slice(0, 8)
28
+ }
29
+
30
+ function getAuthor(): string {
31
+ return process.env.USERNAME || process.env.USER || 'unknown'
32
+ }
33
+
34
+ export function exportToSync(projectPath: string): SyncManifest {
35
+ const memories = loadMemories(projectPath, false)
36
+ const teamMemories = loadMemories(projectPath, true)
37
+ const all = [...memories, ...teamMemories]
38
+
39
+ const manifest: SyncManifest = {
40
+ teamId: path.basename(projectPath),
41
+ version: Date.now(),
42
+ updatedAt: new Date().toISOString(),
43
+ memories: all.map(m => ({
44
+ id: m.id,
45
+ name: m.name,
46
+ type: m.type,
47
+ description: m.description,
48
+ content: m.content,
49
+ author: getAuthor(),
50
+ createdAt: m.createdAt.toISOString(),
51
+ hash: hashContent(m.content),
52
+ }))
53
+ }
54
+
55
+ const syncPath = path.join(projectPath, SYNC_FILE)
56
+ fs.writeFileSync(syncPath, JSON.stringify(manifest, null, 2), 'utf-8')
57
+ return manifest
58
+ }
59
+
60
+ export function importFromSync(projectPath: string): number {
61
+ const syncPath = path.join(projectPath, SYNC_FILE)
62
+ if (!fs.existsSync(syncPath)) {
63
+ console.log('No memcore-sync.json found. Ask your team to run: memcore sync push')
64
+ return 0
65
+ }
66
+
67
+ const manifest: SyncManifest = JSON.parse(fs.readFileSync(syncPath, 'utf-8'))
68
+ const existing = loadMemories(projectPath, true)
69
+ const existingHashes = new Set(existing.map(m => hashContent(m.content)))
70
+
71
+ let imported = 0
72
+ for (const m of manifest.memories) {
73
+ if (!existingHashes.has(m.hash)) {
74
+ saveMemory(projectPath, m.name, m.type as any, m.content, m.description, true)
75
+ imported++
76
+ }
77
+ }
78
+
79
+ return imported
80
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ // "rootDir": "./src",
6
+ // "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "nodenext",
11
+ "target": "esnext",
12
+ "types": [],
13
+ // For nodejs:
14
+ // "lib": ["esnext"],
15
+ // "types": ["node"],
16
+ // and npm install -D @types/node
17
+
18
+ // Other Outputs
19
+ "sourceMap": true,
20
+ "declaration": true,
21
+ "declarationMap": true,
22
+
23
+ // Stricter Typechecking Options
24
+ "noUncheckedIndexedAccess": true,
25
+ "exactOptionalPropertyTypes": true,
26
+
27
+ // Style Options
28
+ // "noImplicitReturns": true,
29
+ // "noImplicitOverride": true,
30
+ // "noUnusedLocals": true,
31
+ // "noUnusedParameters": true,
32
+ // "noFallthroughCasesInSwitch": true,
33
+ // "noPropertyAccessFromIndexSignature": true,
34
+
35
+ // Recommended Options
36
+ "strict": true,
37
+ "jsx": "react-jsx",
38
+ "verbatimModuleSyntax": true,
39
+ "isolatedModules": true,
40
+ "noUncheckedSideEffectImports": true,
41
+ "moduleDetection": "force",
42
+ "skipLibCheck": true,
43
+ }
44
+ }
package/{ ADDED
File without changes