memoir-cli 1.5.1 → 1.5.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/bin/memoir.js +7 -4
- package/package.json +1 -2
- package/src/adapters/index.js +7 -1
- package/src/adapters/restore.js +7 -1
- package/src/commands/push.js +3 -2
- package/src/commands/restore.js +5 -3
- package/src/providers/restore.js +4 -4
package/bin/memoir.js
CHANGED
|
@@ -24,6 +24,7 @@ if (process.argv.length <= 2) {
|
|
|
24
24
|
chalk.cyan(' memoir push ') + chalk.gray('— back up your AI memory') + '\n' +
|
|
25
25
|
chalk.cyan(' memoir restore ') + chalk.gray('— restore on a new machine') + '\n' +
|
|
26
26
|
chalk.cyan(' memoir status ') + chalk.gray('— see detected AI tools') + '\n\n' +
|
|
27
|
+
chalk.gray(' Tip: use --only claude,gemini to sync specific tools') + '\n\n' +
|
|
27
28
|
chalk.gray(`v${VERSION}`),
|
|
28
29
|
{ padding: 1, borderStyle: 'round', borderColor: 'cyan', dimBorder: true }
|
|
29
30
|
) + '\n');
|
|
@@ -58,9 +59,10 @@ program
|
|
|
58
59
|
.command('push')
|
|
59
60
|
.alias('remember')
|
|
60
61
|
.description('Back up your AI memory to the cloud')
|
|
61
|
-
.
|
|
62
|
+
.option('--only <tools>', 'Only sync specific tools (comma-separated: claude,gemini,codex,cursor,copilot,windsurf,aider)')
|
|
63
|
+
.action(async (options) => {
|
|
62
64
|
try {
|
|
63
|
-
await pushCommand();
|
|
65
|
+
await pushCommand(options);
|
|
64
66
|
} catch (err) {
|
|
65
67
|
console.error(chalk.red('\n✖ Error during sync:'), err.message);
|
|
66
68
|
process.exit(1);
|
|
@@ -71,9 +73,10 @@ program
|
|
|
71
73
|
.command('restore')
|
|
72
74
|
.alias('pull')
|
|
73
75
|
.description('Restore your AI memory on this machine')
|
|
74
|
-
.
|
|
76
|
+
.option('--only <tools>', 'Only restore specific tools (comma-separated: claude,gemini,codex,cursor,copilot,windsurf,aider)')
|
|
77
|
+
.action(async (options) => {
|
|
75
78
|
try {
|
|
76
|
-
await restoreCommand();
|
|
79
|
+
await restoreCommand(options);
|
|
77
80
|
} catch (err) {
|
|
78
81
|
console.error(chalk.red('\n✖ Error during restore:'), err.message);
|
|
79
82
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memoir-cli",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Sync and translate AI memory across devices and tools. Back up Claude, Gemini, Codex, Cursor, Copilot, Windsurf, and Aider configs. Migrate instructions between AI coding assistants with one command.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -55,7 +55,6 @@
|
|
|
55
55
|
"fs-extra": "^11.2.0",
|
|
56
56
|
"gradient-string": "^3.0.0",
|
|
57
57
|
"inquirer": "^9.2.15",
|
|
58
|
-
|
|
59
58
|
"open": "^11.0.0",
|
|
60
59
|
"ora": "^7.0.1"
|
|
61
60
|
}
|
package/src/adapters/index.js
CHANGED
|
@@ -171,11 +171,17 @@ function formatSize(bytes) {
|
|
|
171
171
|
return `${(bytes / (1024 * 1024)).toFixed(1)}mb`;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
export async function extractMemories(stagingDir, spinner) {
|
|
174
|
+
export async function extractMemories(stagingDir, spinner, onlyFilter = null) {
|
|
175
175
|
let foundAny = false;
|
|
176
176
|
const results = [];
|
|
177
177
|
|
|
178
178
|
for (const adapter of adapters) {
|
|
179
|
+
// Skip if --only filter is set and this adapter doesn't match
|
|
180
|
+
if (onlyFilter) {
|
|
181
|
+
const adapterKey = adapter.name.toLowerCase().replace(/ /g, '-').replace('cli', '').replace('openai-', '').trim().replace(/-$/, '');
|
|
182
|
+
const matches = onlyFilter.some(f => adapter.name.toLowerCase().includes(f) || adapterKey.includes(f));
|
|
183
|
+
if (!matches) continue;
|
|
184
|
+
}
|
|
179
185
|
if (adapter.customExtract) {
|
|
180
186
|
const dest = path.join(stagingDir, adapter.name.toLowerCase().replace(/ /g, '-'));
|
|
181
187
|
let foundFile = false;
|
package/src/adapters/restore.js
CHANGED
|
@@ -56,11 +56,17 @@ async function syncFiles(src, dest, changes) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export async function restoreMemories(sourceDir, spinner) {
|
|
59
|
+
export async function restoreMemories(sourceDir, spinner, onlyFilter = null) {
|
|
60
60
|
let restoredAny = false;
|
|
61
61
|
const allResults = [];
|
|
62
62
|
|
|
63
63
|
for (const adapter of adapters) {
|
|
64
|
+
// Skip if --only filter is set and this adapter doesn't match
|
|
65
|
+
if (onlyFilter) {
|
|
66
|
+
const matches = onlyFilter.some(f => adapter.name.toLowerCase().includes(f));
|
|
67
|
+
if (!matches) continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
64
70
|
const backupDir = path.join(sourceDir, adapter.name.toLowerCase().replace(/ /g, '-'));
|
|
65
71
|
|
|
66
72
|
if (await fs.pathExists(backupDir)) {
|
package/src/commands/push.js
CHANGED
|
@@ -9,7 +9,7 @@ import { getConfig } from '../config.js';
|
|
|
9
9
|
import { extractMemories, adapters } from '../adapters/index.js';
|
|
10
10
|
import { syncToLocal, syncToGit } from '../providers/index.js';
|
|
11
11
|
|
|
12
|
-
export async function pushCommand() {
|
|
12
|
+
export async function pushCommand(options = {}) {
|
|
13
13
|
const config = await getConfig();
|
|
14
14
|
|
|
15
15
|
if (!config) {
|
|
@@ -28,7 +28,8 @@ export async function pushCommand() {
|
|
|
28
28
|
await fs.ensureDir(stagingDir);
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
const
|
|
31
|
+
const onlyFilter = options.only ? options.only.split(',').map(t => t.trim().toLowerCase()) : null;
|
|
32
|
+
const foundAny = await extractMemories(stagingDir, spinner, onlyFilter);
|
|
32
33
|
|
|
33
34
|
if (!foundAny) {
|
|
34
35
|
spinner.stop();
|
package/src/commands/restore.js
CHANGED
|
@@ -8,7 +8,7 @@ import gradient from 'gradient-string';
|
|
|
8
8
|
import { getConfig } from '../config.js';
|
|
9
9
|
import { fetchFromLocal, fetchFromGit } from '../providers/restore.js';
|
|
10
10
|
|
|
11
|
-
export async function restoreCommand() {
|
|
11
|
+
export async function restoreCommand(options = {}) {
|
|
12
12
|
const config = await getConfig();
|
|
13
13
|
|
|
14
14
|
if (!config) {
|
|
@@ -29,10 +29,12 @@ export async function restoreCommand() {
|
|
|
29
29
|
try {
|
|
30
30
|
let restored = false;
|
|
31
31
|
|
|
32
|
+
const onlyFilter = options.only ? options.only.split(',').map(t => t.trim().toLowerCase()) : null;
|
|
33
|
+
|
|
32
34
|
if (config.provider === 'local' || config.provider.includes('local')) {
|
|
33
|
-
restored = await fetchFromLocal(config, stagingDir, spinner);
|
|
35
|
+
restored = await fetchFromLocal(config, stagingDir, spinner, onlyFilter);
|
|
34
36
|
} else if (config.provider === 'git' || config.provider.includes('git')) {
|
|
35
|
-
restored = await fetchFromGit(config, stagingDir, spinner);
|
|
37
|
+
restored = await fetchFromGit(config, stagingDir, spinner, onlyFilter);
|
|
36
38
|
} else {
|
|
37
39
|
spinner.fail(chalk.red(`Unknown provider: ${config.provider}`));
|
|
38
40
|
return;
|
package/src/providers/restore.js
CHANGED
|
@@ -5,7 +5,7 @@ import os from 'os';
|
|
|
5
5
|
import { execFileSync } from 'child_process';
|
|
6
6
|
import { restoreMemories } from '../adapters/restore.js';
|
|
7
7
|
|
|
8
|
-
export async function fetchFromLocal(config, stagingDir, spinner) {
|
|
8
|
+
export async function fetchFromLocal(config, stagingDir, spinner, onlyFilter = null) {
|
|
9
9
|
const sourceDir = config.localPath;
|
|
10
10
|
if (!sourceDir) throw new Error('Local path is not configured.');
|
|
11
11
|
|
|
@@ -18,10 +18,10 @@ export async function fetchFromLocal(config, stagingDir, spinner) {
|
|
|
18
18
|
spinner.text = `Fetching data from local directory: ${chalk.cyan(resolvedSource)}`;
|
|
19
19
|
await fs.copy(resolvedSource, stagingDir);
|
|
20
20
|
|
|
21
|
-
return await restoreMemories(stagingDir, spinner);
|
|
21
|
+
return await restoreMemories(stagingDir, spinner, onlyFilter);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export async function fetchFromGit(config, stagingDir, spinner) {
|
|
24
|
+
export async function fetchFromGit(config, stagingDir, spinner, onlyFilter = null) {
|
|
25
25
|
const repoUrl = config.gitRepo;
|
|
26
26
|
if (!repoUrl) throw new Error('Git repository is not configured.');
|
|
27
27
|
|
|
@@ -33,5 +33,5 @@ export async function fetchFromGit(config, stagingDir, spinner) {
|
|
|
33
33
|
throw new Error('Failed to pull from git repository. Ensure your SSH keys are configured and the repository is accessible.');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
return await restoreMemories(stagingDir, spinner);
|
|
36
|
+
return await restoreMemories(stagingDir, spinner, onlyFilter);
|
|
37
37
|
}
|