memoir-cli 2.1.1 → 2.4.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- # 🧠 memoir
3
+ # memoir
4
4
  **Your AI Remembers Everything. Sync It Everywhere.**
5
5
 
6
6
  [![npm version](https://img.shields.io/npm/v/memoir-cli.svg?style=flat-square)](https://npmjs.org/package/memoir-cli)
@@ -14,186 +14,164 @@
14
14
 
15
15
  ---
16
16
 
17
- ## šŸ’” The Problem
17
+ ## The Problem
18
18
 
19
- You spend weeks teaching your local AI CLI exactly how you like your code formatted, your preferred architectural patterns, and your project's unique context.
19
+ You spend weeks teaching your AI tools how you code — your preferred patterns, project context, coding standards.
20
20
 
21
- Then, you switch laptops. Or you want to share that setup with your team.
21
+ Then you switch laptops. Or try a new AI tool. Or want your team on the same page.
22
22
 
23
- Suddenly, you're starting from scratch. Your AI's "memory" is trapped in hidden `.gemini` or `.claude` folders on a single machine.
23
+ All that context is trapped in hidden dotfiles on one machine.
24
24
 
25
- ## šŸš€ The Solution
25
+ ## The Solution
26
26
 
27
- `memoir` is a zero-friction CLI that extracts, backs up, restores, and **translates** your AI's memory across any computer and any tool. Bring your own storage (a private GitHub repo or an iCloud/Dropbox folder), and `memoir` handles the rest.
28
-
29
- No locked-in SaaS, no lost context, no complex shell scripts. Switch from Claude to Gemini in one command.
30
-
31
- ### Supported Integrations
32
- - [x] **Gemini CLI**
33
- - [x] **Claude Code**
34
- - [x] **OpenAI Codex CLI**
35
- - [x] **Cursor**
36
- - [x] **GitHub Copilot**
37
- - [x] **Windsurf**
38
- - [x] **Aider**
39
-
40
- ---
41
-
42
- ## šŸ› ļø Installation
43
-
44
- Install globally via npm so you can use it anywhere on your machine:
27
+ `memoir` extracts, backs up, restores, and **translates** your AI memory across any computer and any tool. One command to save. One command to restore. One command to translate between tools.
45
28
 
46
29
  ```bash
47
30
  npm install -g memoir-cli
48
31
  ```
49
32
 
50
- ## ⚔ Quick Start
33
+ ### Supported Tools (11)
34
+ | Tool | Config synced |
35
+ |------|--------------|
36
+ | **ChatGPT** | `CHATGPT.md` — custom instructions, preferences |
37
+ | **Claude Code** | `~/.claude/` — settings, projects, memory files |
38
+ | **Gemini CLI** | `~/.gemini/` — settings, GEMINI.md |
39
+ | **OpenAI Codex** | `~/.codex/` — config, instructions |
40
+ | **Cursor** | Settings, keybindings, rules |
41
+ | **GitHub Copilot** | Config, settings |
42
+ | **Windsurf** | Settings, keybindings, rules |
43
+ | **Zed** | Settings, keymap, tasks |
44
+ | **Cline** | Settings, rules |
45
+ | **Continue.dev** | Config, rules |
46
+ | **Aider** | `.aider.conf.yml`, system prompt |
47
+
48
+ Plus **per-project configs**: automatically finds `CLAUDE.md`, `GEMINI.md`, `CHATGPT.md`, `.cursorrules`, `AGENTS.md` across all your projects.
51
49
 
52
- ### 1. Initialize
53
- Run the setup wizard. We'll help you securely link a private GitHub repository or a local sync folder.
50
+ ---
54
51
 
52
+ ## Quick Start
53
+
54
+ ### 1. Initialize
55
55
  ```bash
56
56
  memoir init
57
+ # Walks you through setup — GitHub repo or local folder
58
+ # Auto-creates a private repo if you have gh CLI
57
59
  ```
58
60
 
59
- ### 2. Backup Your Memory
60
- Just had a great session? Save your AI's learned context to the cloud:
61
-
61
+ ### 2. Back up your memory
62
62
  ```bash
63
63
  memoir push
64
- # or simply use the alias:
65
- memoir remember
66
64
  ```
67
65
 
68
- ### 3. Restore Anywhere
69
- Got a new machine? Pull your brain down instantly:
70
-
66
+ ### 3. Restore on a new machine
71
67
  ```bash
72
68
  memoir restore
73
- # or:
74
- memoir pull
75
69
  ```
76
70
 
77
- ### 4. Translate Between Tools
78
- Switch AI tools without losing context. Memoir uses Gemini AI to intelligently rewrite your memory files for any supported tool:
79
-
71
+ ### 4. Translate between tools
80
72
  ```bash
81
73
  memoir migrate --from claude --to gemini
82
- # or run interactively:
83
- memoir migrate
74
+ # AI-powered translation — not copy-paste, real rewriting
84
75
  ```
85
76
 
86
- Your Claude instructions become a proper `GEMINI.md` — not a copy-paste, but a real translation that follows each tool's conventions.
87
-
88
77
  ---
89
78
 
90
- ## šŸ“– All Commands
79
+ ## All Commands
91
80
 
92
81
  | Command | What it does |
93
82
  |---------|-------------|
94
- | `memoir init` | Setup wizard — pick GitHub or local folder, upload or download |
95
- | `memoir push` | Extract all AI tool configs, back up to GitHub/local |
96
- | `memoir restore` | Pull backup down, restore missing files (non-destructive) |
97
- | `memoir status` | Show which AI tools are detected on this machine |
98
- | `memoir view` | Preview backup contents with diffs against local |
99
- | `memoir migrate` | Translate memory between tools via Gemini AI |
83
+ | `memoir init` | Setup wizard — GitHub or local, upload or download |
84
+ | `memoir push` | Back up all AI configs |
85
+ | `memoir restore` | Restore on a new machine (non-destructive) |
86
+ | `memoir status` | Show detected AI tools |
87
+ | `memoir doctor` | Diagnose issues, scan for secrets |
88
+ | `memoir view` | Preview what's in your backup |
89
+ | `memoir diff` | Show changes since last backup |
90
+ | `memoir migrate` | Translate memory between tools via AI |
91
+ | `memoir snapshot` | Capture current coding session |
92
+ | `memoir resume` | Pick up where you left off |
93
+ | `memoir profile` | Manage profiles (personal/work) |
94
+ | `memoir update` | Self-update to latest version |
100
95
 
101
96
  ---
102
97
 
103
- ## šŸŽÆ Common Workflows
98
+ ## Profiles
99
+
100
+ Separate personal and work configs — different repos, different tools.
104
101
 
105
- ### New laptop setup
106
102
  ```bash
107
- # Old machine — save everything
108
- memoir init # → Upload → GitHub
103
+ memoir profile create work # set up work profile with its own repo
104
+ memoir profile create personal # personal side projects
109
105
 
110
- # New machine — restore everything
111
- memoir init # → Download → GitHub
112
- # All your .claude/, .gemini/, .cursorrules configs restored in 30 seconds
113
- ```
106
+ memoir push --profile work # sync only work configs
107
+ memoir restore --profile personal
114
108
 
115
- ### Switch from Claude to Gemini (or any tool)
116
- ```bash
117
- memoir migrate --from claude --to gemini
109
+ memoir profile list # see all profiles
110
+ memoir profile switch work # change default
118
111
  ```
119
- Your CLAUDE.md + Claude memory files get intelligently rewritten as a proper GEMINI.md — not a copy-paste, but a real translation that follows Gemini's conventions.
120
112
 
121
- ### Keep your whole team in sync
122
- ```bash
123
- # Team lead writes CLAUDE.md, then generates for everyone else:
124
- memoir migrate --from claude --to cursor
125
- memoir migrate --from claude --to copilot
126
- memoir migrate --from claude --to codex
127
- ```
113
+ Each profile can filter which tools to sync, so your personal side project memory never mixes with work.
128
114
 
129
- ### Fan out to every tool at once
130
- ```bash
131
- memoir migrate --from claude --to gemini
132
- memoir migrate --from claude --to codex
133
- memoir migrate --from claude --to cursor
134
- memoir migrate --from claude --to windsurf
135
- memoir migrate --from claude --to aider
136
- ```
137
- Use one tool as the source of truth, propagate to all others.
115
+ ---
116
+
117
+ ## Common Workflows
138
118
 
139
- ### Preview before committing
119
+ ### New laptop setup
140
120
  ```bash
141
- memoir migrate --from gemini --to claude --dry-run
142
- # Shows translated output but writes nothing
121
+ # Old machine
122
+ memoir push
123
+
124
+ # New machine
125
+ memoir init # → Download → same GitHub repo
126
+ memoir restore # All configs restored in seconds
143
127
  ```
144
128
 
145
- ### Protect existing files
129
+ ### Translate between tools
146
130
  ```bash
147
- memoir migrate --from claude --to gemini
148
- # → "GEMINI.md already exists."
149
- # → Overwrite / Append / Skip
150
- # Append adds a dated separator so you keep your existing instructions
131
+ memoir migrate --from chatgpt --to claude
132
+ # Your ChatGPT custom instructions become a proper CLAUDE.md
151
133
  ```
152
134
 
153
- ### Daily sync across machines
135
+ ### Fan out to every tool
154
136
  ```bash
155
- # End of day
156
- memoir push
157
-
158
- # Next morning, different machine
159
- memoir pull
137
+ memoir migrate --from chatgpt --to all
138
+ # One source of truth, every tool gets its own format
160
139
  ```
161
140
 
162
- ### Check what's on this machine
141
+ ### Daily sync
163
142
  ```bash
164
- memoir status
165
- # Shows checkmarks for every detected AI tool and their config locations
143
+ memoir push # end of day
144
+ memoir restore # next morning, different machine
166
145
  ```
167
146
 
168
147
  ---
169
148
 
170
- ## šŸ”’ Security First
149
+ ## Security
171
150
 
172
- Your AI memory files often sit right next to sensitive API keys and OAuth tokens. **`memoir` is designed to be paranoid.**
151
+ Memoir **only** syncs config files, instructions, and memory markdown. It never touches credentials, API keys, `.env` files, or auth tokens.
173
152
 
174
- Our specialized adapters intelligently filter your directories. We **only** sync configuration files, custom prompts, and markdown memory (`GEMINI.md`, `CLAUDE.md`). We will never touch, copy, or push `.env` files, `.key` files, or credential caches.
153
+ Run `memoir doctor` to see exactly what would be synced and scan for accidental secrets before pushing.
175
154
 
176
155
  ---
177
156
 
178
- ## šŸ—ŗļø Roadmap
157
+ ## Roadmap
179
158
 
180
- **What's next:**
181
- - Team sharing — sync a shared memory repo across your whole team
182
- - Auto-detect new AI tools as they appear
183
- - Two-way merge — combine memories from multiple tools into one
159
+ - **Universal format** — write one `MEMOIR.md`, generate all tool-specific configs
160
+ - **Cloud sync** — no GitHub needed, encrypted backups
161
+ - **Teams** — shared coding standards across your whole team
162
+ - **Templates** — community-shared AI tool configs
184
163
 
185
164
  ---
186
165
 
187
- ## šŸ¤ Contributing
166
+ ## Contributing
188
167
 
189
- We welcome contributions! Whether it's adding an adapter for a new AI CLI, improving the UI, or helping build the Migration Engine.
168
+ Contributions welcome — especially new tool adapters and migration improvements.
190
169
 
191
- 1. Fork the Project
192
- 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
193
- 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
194
- 4. Push to the Branch (`git push origin feature/AmazingFeature`)
195
- 5. Open a Pull Request
170
+ 1. Fork the repo
171
+ 2. Create your branch (`git checkout -b feature/my-feature`)
172
+ 3. Commit and push
173
+ 4. Open a PR
196
174
 
197
- ## šŸ“„ License
175
+ ## License
198
176
 
199
- Distributed under the MIT License. See `LICENSE` for more information.
177
+ MIT
package/bin/memoir.js CHANGED
@@ -7,11 +7,13 @@ import { initCommand } from '../src/commands/init.js';
7
7
  import { pushCommand } from '../src/commands/push.js';
8
8
  import { restoreCommand } from '../src/commands/restore.js';
9
9
  import { statusCommand } from '../src/commands/status.js';
10
+ import { doctorCommand } from '../src/commands/doctor.js';
10
11
  import { viewCommand } from '../src/commands/view.js';
11
12
  import { diffCommand } from '../src/commands/diff.js';
12
13
  import { migrateCommand } from '../src/commands/migrate.js';
13
14
  import { snapshotCommand } from '../src/commands/snapshot.js';
14
15
  import { resumeCommand } from '../src/commands/resume.js';
16
+ import { profileListCommand, profileCreateCommand, profileSwitchCommand, profileDeleteCommand } from '../src/commands/profile.js';
15
17
  import { createRequire } from 'module';
16
18
 
17
19
  const require = createRequire(import.meta.url);
@@ -26,11 +28,17 @@ async function checkForUpdate() {
26
28
  clearTimeout(timeout);
27
29
  const data = await res.json();
28
30
  const latest = data.version;
29
- if (latest && latest !== VERSION) {
31
+ // Only notify if remote is actually newer (not just different)
32
+ const isNewer = (a, b) => {
33
+ const [a1, a2, a3] = a.split('.').map(Number);
34
+ const [b1, b2, b3] = b.split('.').map(Number);
35
+ return a1 > b1 || (a1 === b1 && a2 > b2) || (a1 === b1 && a2 === b2 && a3 > b3);
36
+ };
37
+ if (latest && isNewer(latest, VERSION)) {
30
38
  console.log(
31
39
  '\n' + boxen(
32
40
  chalk.yellow(`Update available: ${VERSION} → ${chalk.green.bold(latest)}`) + '\n' +
33
- chalk.gray('Run: ') + chalk.cyan('npm install -g memoir-cli'),
41
+ chalk.gray('Run: ') + chalk.cyan('memoir update'),
34
42
  { padding: { top: 0, bottom: 0, left: 1, right: 1 }, borderStyle: 'round', borderColor: 'yellow', dimBorder: true }
35
43
  )
36
44
  );
@@ -49,8 +57,10 @@ if (process.argv.length <= 2) {
49
57
  chalk.cyan(' memoir restore ') + chalk.gray('— restore on a new machine') + '\n' +
50
58
  chalk.cyan(' memoir snapshot ') + chalk.gray('— capture your current session') + '\n' +
51
59
  chalk.cyan(' memoir resume ') + chalk.gray('— pick up where you left off') + '\n' +
52
- chalk.cyan(' memoir status ') + chalk.gray('— see detected AI tools') + '\n\n' +
53
- chalk.gray(' Tip: use --only claude,gemini to sync specific tools') + '\n\n' +
60
+ chalk.cyan(' memoir status ') + chalk.gray('— see detected AI tools') + '\n' +
61
+ chalk.cyan(' memoir profile ') + chalk.gray('— manage profiles (personal/work)') + '\n' +
62
+ chalk.cyan(' memoir update ') + chalk.gray('— update to latest version') + '\n\n' +
63
+ chalk.gray(' Tip: use --profile work to sync a specific profile') + '\n\n' +
54
64
  chalk.gray(`v${VERSION}`),
55
65
  { padding: 1, borderStyle: 'round', borderColor: 'cyan', dimBorder: true }
56
66
  ) + '\n');
@@ -85,7 +95,8 @@ program
85
95
  .command('push')
86
96
  .alias('remember')
87
97
  .description('Back up your AI memory to the cloud')
88
- .option('--only <tools>', 'Only sync specific tools (comma-separated: claude,gemini,codex,cursor,copilot,windsurf,aider)')
98
+ .option('--only <tools>', 'Only sync specific tools (comma-separated)')
99
+ .option('-p, --profile <name>', 'Use a specific profile')
89
100
  .action(async (options) => {
90
101
  try {
91
102
  await pushCommand(options);
@@ -99,8 +110,9 @@ program
99
110
  .command('restore')
100
111
  .alias('pull')
101
112
  .description('Restore your AI memory on this machine')
102
- .option('--only <tools>', 'Only restore specific tools (comma-separated: claude,gemini,codex,cursor,copilot,windsurf,aider)')
113
+ .option('--only <tools>', 'Only restore specific tools (comma-separated)')
103
114
  .option('-y, --yes', 'Skip confirmation prompts (restore all)')
115
+ .option('-p, --profile <name>', 'Use a specific profile')
104
116
  .action(async (options) => {
105
117
  try {
106
118
  await restoreCommand(options);
@@ -113,9 +125,24 @@ program
113
125
  program
114
126
  .command('status')
115
127
  .description('See what AI tools are on this machine')
116
- .action(async () => {
128
+ .option('-p, --profile <name>', 'Use a specific profile')
129
+ .action(async (options) => {
117
130
  try {
118
- await statusCommand();
131
+ await statusCommand(options);
132
+ } catch (err) {
133
+ console.error(chalk.red('\nāœ– Error:'), err.message);
134
+ process.exit(1);
135
+ }
136
+ });
137
+
138
+ program
139
+ .command('doctor')
140
+ .alias('diagnose')
141
+ .description('Diagnose common issues with your memoir setup')
142
+ .option('-p, --profile <name>', 'Use a specific profile')
143
+ .action(async (options) => {
144
+ try {
145
+ await doctorCommand(options);
119
146
  } catch (err) {
120
147
  console.error(chalk.red('\nāœ– Error:'), err.message);
121
148
  process.exit(1);
@@ -126,9 +153,10 @@ program
126
153
  .command('view')
127
154
  .alias('ls')
128
155
  .description('Preview what files are in your backup')
129
- .action(async () => {
156
+ .option('-p, --profile <name>', 'Use a specific profile')
157
+ .action(async (options) => {
130
158
  try {
131
- await viewCommand();
159
+ await viewCommand(options);
132
160
  } catch (err) {
133
161
  console.error(chalk.red('\nāœ– Error:'), err.message);
134
162
  process.exit(1);
@@ -139,9 +167,10 @@ program
139
167
  .command('diff')
140
168
  .alias('changes')
141
169
  .description('Show what changed since your last backup')
142
- .action(async () => {
170
+ .option('-p, --profile <name>', 'Use a specific profile')
171
+ .action(async (options) => {
143
172
  try {
144
- await diffCommand();
173
+ await diffCommand(options);
145
174
  } catch (err) {
146
175
  console.error(chalk.red('\nāœ– Error:'), err.message);
147
176
  process.exit(1);
@@ -154,6 +183,7 @@ program
154
183
  .description('Capture your current coding session for handoff')
155
184
  .option('--smart', 'Use AI to generate a better summary (requires Gemini API key)')
156
185
  .option('--goal <goal>', 'What you want to do next (goal-directed handoff)')
186
+ .option('-p, --profile <name>', 'Use a specific profile')
157
187
  .action(async (options) => {
158
188
  try {
159
189
  await snapshotCommand(options);
@@ -168,6 +198,7 @@ program
168
198
  .description('Pick up where you left off on another machine')
169
199
  .option('--inject', 'Write the handoff where your AI tool will read it')
170
200
  .option('--to <tool>', 'Target tool for injection (claude, gemini, cursor, codex)')
201
+ .option('-p, --profile <name>', 'Use a specific profile')
171
202
  .action(async (options) => {
172
203
  try {
173
204
  await resumeCommand(options);
@@ -177,6 +208,46 @@ program
177
208
  }
178
209
  });
179
210
 
211
+ program
212
+ .command('update')
213
+ .alias('upgrade')
214
+ .description('Update memoir to the latest version')
215
+ .action(async () => {
216
+ try {
217
+ const res = await fetch('https://registry.npmjs.org/memoir-cli/latest');
218
+ const data = await res.json();
219
+ const latest = data.version;
220
+
221
+ if (latest === VERSION) {
222
+ console.log('\n' + boxen(
223
+ chalk.green('āœ” Already up to date!') + '\n' +
224
+ chalk.gray(`v${VERSION}`),
225
+ { padding: { top: 0, bottom: 0, left: 1, right: 1 }, borderStyle: 'round', borderColor: 'green', dimBorder: true }
226
+ ) + '\n');
227
+ return;
228
+ }
229
+
230
+ console.log('\n' + chalk.cyan(`Updating memoir ${VERSION} → ${chalk.green.bold(latest)}...`) + '\n');
231
+
232
+ const { execSync } = await import('child_process');
233
+ const execPath = process.argv[1] || '';
234
+ const useBun = execPath.includes('.bun') || process.env.BUN_INSTALL;
235
+ const cmd = useBun ? 'bun install -g memoir-cli' : 'npm install -g memoir-cli';
236
+
237
+ execSync(cmd, { stdio: 'inherit' });
238
+
239
+ console.log('\n' + boxen(
240
+ gradient.pastel(' Updated! ') + '\n\n' +
241
+ chalk.white(`memoir ${VERSION} → ${chalk.green.bold(latest)}`),
242
+ { padding: 1, borderStyle: 'round', borderColor: 'green', dimBorder: true }
243
+ ) + '\n');
244
+ } catch (err) {
245
+ console.error(chalk.red('\nāœ– Update failed:'), err.message);
246
+ console.log(chalk.gray('Try manually: ') + chalk.cyan('npm install -g memoir-cli'));
247
+ process.exit(1);
248
+ }
249
+ });
250
+
180
251
  program
181
252
  .command('migrate')
182
253
  .description('Translate memory between AI tools (Claude, Gemini, Codex, Cursor, etc.)')
@@ -192,6 +263,60 @@ program
192
263
  }
193
264
  });
194
265
 
266
+ // Profile management
267
+ const profile = program.command('profile').description('Manage profiles (personal, work, etc.)');
268
+
269
+ profile
270
+ .command('list')
271
+ .alias('ls')
272
+ .description('List all profiles')
273
+ .action(async () => {
274
+ try {
275
+ await profileListCommand();
276
+ } catch (err) {
277
+ console.error(chalk.red('\nāœ– Error:'), err.message);
278
+ process.exit(1);
279
+ }
280
+ });
281
+
282
+ profile
283
+ .command('create <name>')
284
+ .description('Create a new profile')
285
+ .action(async (name) => {
286
+ try {
287
+ await profileCreateCommand(name);
288
+ } catch (err) {
289
+ console.error(chalk.red('\nāœ– Error:'), err.message);
290
+ process.exit(1);
291
+ }
292
+ });
293
+
294
+ profile
295
+ .command('switch <name>')
296
+ .alias('use')
297
+ .description('Switch to a profile')
298
+ .action(async (name) => {
299
+ try {
300
+ await profileSwitchCommand(name);
301
+ } catch (err) {
302
+ console.error(chalk.red('\nāœ– Error:'), err.message);
303
+ process.exit(1);
304
+ }
305
+ });
306
+
307
+ profile
308
+ .command('delete <name>')
309
+ .alias('rm')
310
+ .description('Delete a profile')
311
+ .action(async (name) => {
312
+ try {
313
+ await profileDeleteCommand(name);
314
+ } catch (err) {
315
+ console.error(chalk.red('\nāœ– Error:'), err.message);
316
+ process.exit(1);
317
+ }
318
+ });
319
+
195
320
  program.hook('postAction', async () => {
196
321
  await checkForUpdate();
197
322
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memoir-cli",
3
- "version": "2.1.1",
3
+ "version": "2.4.0",
4
4
  "description": "Sync AI memory across devices. Back up and restore Claude, Gemini, Codex, Cursor, Copilot, Windsurf configs. Snapshot coding sessions and resume on another machine. Migrate instructions between AI assistants.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -35,6 +35,10 @@
35
35
  "copilot",
36
36
  "windsurf",
37
37
  "aider",
38
+ "zed",
39
+ "cline",
40
+ "continue-dev",
41
+ "profiles",
38
42
  "ai-memory",
39
43
  "ai-tools",
40
44
  "dotfiles",
@@ -42,6 +46,7 @@
42
46
  "claude-code",
43
47
  "gemini-cli",
44
48
  "openai",
49
+ "chatgpt",
45
50
  "ai-assistant",
46
51
  "coding-assistant",
47
52
  "context-sync",
@@ -58,7 +63,6 @@
58
63
  "fs-extra": "^11.2.0",
59
64
  "gradient-string": "^3.0.0",
60
65
  "inquirer": "^9.2.15",
61
- "open": "^11.0.0",
62
- "ora": "^7.0.1"
66
+ "ora": "^7.0.1"
63
67
  }
64
68
  }
@@ -127,6 +127,80 @@ export const adapters = [
127
127
  return false;
128
128
  }
129
129
  },
130
+ {
131
+ name: 'Zed',
132
+ icon: 'šŸ”¶',
133
+ source: isWin
134
+ ? path.join(appData, 'Zed')
135
+ : path.join(home, '.config', 'zed'),
136
+ filter: (src) => {
137
+ const zedDir = isWin
138
+ ? path.join(appData, 'Zed')
139
+ : path.join(home, '.config', 'zed');
140
+ const rel = path.relative(zedDir, src);
141
+ if (src === zedDir) return true;
142
+ const basename = path.basename(src);
143
+ // Skip known heavy/non-config directories
144
+ const skipDirs = ['extensions', 'themes', 'logs', 'db', 'copilot', 'node', 'languages'];
145
+ const topDir = rel.split(path.sep)[0];
146
+ if (skipDirs.includes(topDir)) return false;
147
+ // Only sync specific config files in root
148
+ const allowed = ['settings.json', 'keymap.json', 'tasks.json'];
149
+ if (allowed.includes(basename) && !rel.includes(path.sep)) return true;
150
+ // Allow .md files in root
151
+ if (basename.endsWith('.md') && !rel.includes(path.sep)) return true;
152
+ return false;
153
+ }
154
+ },
155
+ {
156
+ name: 'Cline',
157
+ icon: 'šŸ¤–',
158
+ source: isWin
159
+ ? path.join(appData, 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev')
160
+ : path.join(home, 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev'),
161
+ filter: (src) => {
162
+ const clineDir = isWin
163
+ ? path.join(appData, 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev')
164
+ : path.join(home, 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev');
165
+ const rel = path.relative(clineDir, src);
166
+ if (src === clineDir) return true;
167
+ const basename = path.basename(src);
168
+ const topDir = rel.split(path.sep)[0];
169
+ // Skip known heavy/non-config directories
170
+ const skipDirs = ['tasks', 'checkpoints', '.cache', 'images'];
171
+ if (skipDirs.includes(topDir)) return false;
172
+ // Allow settings/ and rules/ directories
173
+ if (topDir === 'settings' || topDir === 'rules') return true;
174
+ // Allow .md files in root
175
+ if (basename.endsWith('.md') && !rel.includes(path.sep)) return true;
176
+ return false;
177
+ }
178
+ },
179
+ {
180
+ name: 'Continue.dev',
181
+ icon: 'šŸ”„',
182
+ source: isWin
183
+ ? path.join(process.env.USERPROFILE || home, '.continue')
184
+ : path.join(home, '.continue'),
185
+ filter: (src) => {
186
+ const continueDir = isWin
187
+ ? path.join(process.env.USERPROFILE || home, '.continue')
188
+ : path.join(home, '.continue');
189
+ const rel = path.relative(continueDir, src);
190
+ if (src === continueDir) return true;
191
+ const basename = path.basename(src);
192
+ // Skip known heavy/non-config directories
193
+ const skipDirs = ['sessions', 'dev_data', 'logs', 'index', 'cache', 'types'];
194
+ const topDir = rel.split(path.sep)[0];
195
+ if (skipDirs.includes(topDir)) return false;
196
+ // Only sync specific config files in root
197
+ const allowed = ['config.json', 'config.ts', 'config.yaml', '.continuerules'];
198
+ if (allowed.includes(basename) && !rel.includes(path.sep)) return true;
199
+ // Allow .md files in root
200
+ if (basename.endsWith('.md') && !rel.includes(path.sep)) return true;
201
+ return false;
202
+ }
203
+ },
130
204
  {
131
205
  name: 'Aider',
132
206
  icon: 'šŸ”§',
@@ -224,7 +298,7 @@ export async function extractMemories(stagingDir, spinner, onlyFilter = null) {
224
298
  spinner.text = `šŸ“ Scanning for project-level AI configs...`;
225
299
 
226
300
  const projectFiles = [
227
- 'CLAUDE.md', 'GEMINI.md', 'AGENTS.md', '.cursorrules',
301
+ 'CLAUDE.md', 'GEMINI.md', 'CHATGPT.md', 'AGENTS.md', '.cursorrules',
228
302
  '.github/copilot-instructions.md', '.windsurfrules',
229
303
  '.aider.conf.yml', '.clinerules'
230
304
  ];
@@ -50,8 +50,8 @@ function simpleDiff(oldText, newText) {
50
50
  return output;
51
51
  }
52
52
 
53
- export async function diffCommand() {
54
- const config = await getConfig();
53
+ export async function diffCommand(options = {}) {
54
+ const config = await getConfig(options.profile);
55
55
  if (!config) {
56
56
  console.log(chalk.red('\nāœ– Not configured yet. Run: memoir init\n'));
57
57
  return;