agentmemory-cli 1.0.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 +198 -0
- package/dist/commands/delete.d.ts +7 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +67 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/export.d.ts +7 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +79 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +6 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +107 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +65 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +55 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/search.d.ts +7 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +47 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/store.d.ts +8 -0
- package/dist/commands/store.d.ts.map +1 -0
- package/dist/commands/store.js +51 -0
- package/dist/commands/store.js.map +1 -0
- package/dist/commands/sync.d.ts +9 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +90 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +14 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +98 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +123 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/sync.d.ts +43 -0
- package/dist/lib/sync.d.ts.map +1 -0
- package/dist/lib/sync.js +184 -0
- package/dist/lib/sync.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
- package/src/commands/delete.ts +72 -0
- package/src/commands/export.ts +46 -0
- package/src/commands/import.ts +87 -0
- package/src/commands/init.ts +71 -0
- package/src/commands/list.ts +61 -0
- package/src/commands/search.ts +52 -0
- package/src/commands/store.ts +58 -0
- package/src/commands/sync.ts +102 -0
- package/src/index.ts +114 -0
- package/src/lib/api.ts +139 -0
- package/src/lib/config.ts +95 -0
- package/src/lib/sync.ts +186 -0
- package/src/types.ts +47 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Memory } from '../types.js';
|
|
2
|
+
interface LocalMemory {
|
|
3
|
+
content: string;
|
|
4
|
+
metadata?: Record<string, unknown>;
|
|
5
|
+
id?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse MEMORY.md file into memory entries
|
|
9
|
+
* Expected format:
|
|
10
|
+
*
|
|
11
|
+
* ## Memory Title (optional)
|
|
12
|
+
* Content here...
|
|
13
|
+
*
|
|
14
|
+
* ---
|
|
15
|
+
*
|
|
16
|
+
* ## Another Memory
|
|
17
|
+
* More content...
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseMemoryFile(filePath: string): LocalMemory[];
|
|
20
|
+
/**
|
|
21
|
+
* Write memories to MEMORY.md file
|
|
22
|
+
*/
|
|
23
|
+
export declare function writeMemoryFile(filePath: string, memories: Memory[]): void;
|
|
24
|
+
export interface SyncResult {
|
|
25
|
+
uploaded: number;
|
|
26
|
+
downloaded: number;
|
|
27
|
+
unchanged: number;
|
|
28
|
+
errors: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Bidirectional sync between local MEMORY.md and cloud
|
|
32
|
+
*/
|
|
33
|
+
export declare function syncMemories(direction?: 'push' | 'pull' | 'both'): Promise<SyncResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Get sync status without making changes
|
|
36
|
+
*/
|
|
37
|
+
export declare function getSyncStatus(): Promise<{
|
|
38
|
+
localOnly: LocalMemory[];
|
|
39
|
+
cloudOnly: Memory[];
|
|
40
|
+
synced: number;
|
|
41
|
+
}>;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CA2C/D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CA4B1E;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAkDpG;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC;IAC7C,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAcD"}
|
package/dist/lib/sync.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseMemoryFile = parseMemoryFile;
|
|
37
|
+
exports.writeMemoryFile = writeMemoryFile;
|
|
38
|
+
exports.syncMemories = syncMemories;
|
|
39
|
+
exports.getSyncStatus = getSyncStatus;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const config_js_1 = require("./config.js");
|
|
43
|
+
const api_js_1 = require("./api.js");
|
|
44
|
+
/**
|
|
45
|
+
* Parse MEMORY.md file into memory entries
|
|
46
|
+
* Expected format:
|
|
47
|
+
*
|
|
48
|
+
* ## Memory Title (optional)
|
|
49
|
+
* Content here...
|
|
50
|
+
*
|
|
51
|
+
* ---
|
|
52
|
+
*
|
|
53
|
+
* ## Another Memory
|
|
54
|
+
* More content...
|
|
55
|
+
*/
|
|
56
|
+
function parseMemoryFile(filePath) {
|
|
57
|
+
if (!fs.existsSync(filePath)) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
61
|
+
const memories = [];
|
|
62
|
+
// Split by --- separator or ## headers
|
|
63
|
+
const sections = content.split(/\n---\n|\n(?=## )/);
|
|
64
|
+
for (const section of sections) {
|
|
65
|
+
const trimmed = section.trim();
|
|
66
|
+
if (!trimmed || trimmed === '---')
|
|
67
|
+
continue;
|
|
68
|
+
// Check if it has an ID comment (for synced memories)
|
|
69
|
+
const idMatch = trimmed.match(/<!-- id: ([a-f0-9-]+) -->/);
|
|
70
|
+
const id = idMatch ? idMatch[1] : undefined;
|
|
71
|
+
// Check for category in metadata comment
|
|
72
|
+
const metaMatch = trimmed.match(/<!-- metadata: ({.*?}) -->/);
|
|
73
|
+
let metadata;
|
|
74
|
+
if (metaMatch) {
|
|
75
|
+
try {
|
|
76
|
+
metadata = JSON.parse(metaMatch[1]);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Ignore invalid metadata
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Remove the metadata comments from content
|
|
83
|
+
let cleanContent = trimmed
|
|
84
|
+
.replace(/<!-- id: [a-f0-9-]+ -->\n?/g, '')
|
|
85
|
+
.replace(/<!-- metadata: {.*?} -->\n?/g, '')
|
|
86
|
+
.replace(/^## .+\n?/, '') // Remove header if present
|
|
87
|
+
.trim();
|
|
88
|
+
if (cleanContent) {
|
|
89
|
+
memories.push({ content: cleanContent, metadata, id });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return memories;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Write memories to MEMORY.md file
|
|
96
|
+
*/
|
|
97
|
+
function writeMemoryFile(filePath, memories) {
|
|
98
|
+
const dir = path.dirname(filePath);
|
|
99
|
+
if (!fs.existsSync(dir)) {
|
|
100
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
const lines = [
|
|
103
|
+
'# Agent Memory',
|
|
104
|
+
'',
|
|
105
|
+
`> Last synced: ${new Date().toISOString()}`,
|
|
106
|
+
`> Total memories: ${memories.length}`,
|
|
107
|
+
'',
|
|
108
|
+
'---',
|
|
109
|
+
'',
|
|
110
|
+
];
|
|
111
|
+
for (const memory of memories) {
|
|
112
|
+
lines.push(`<!-- id: ${memory.id} -->`);
|
|
113
|
+
if (memory.metadata && Object.keys(memory.metadata).length > 0) {
|
|
114
|
+
lines.push(`<!-- metadata: ${JSON.stringify(memory.metadata)} -->`);
|
|
115
|
+
}
|
|
116
|
+
lines.push(memory.content);
|
|
117
|
+
lines.push('');
|
|
118
|
+
lines.push('---');
|
|
119
|
+
lines.push('');
|
|
120
|
+
}
|
|
121
|
+
fs.writeFileSync(filePath, lines.join('\n'));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Bidirectional sync between local MEMORY.md and cloud
|
|
125
|
+
*/
|
|
126
|
+
async function syncMemories(direction = 'both') {
|
|
127
|
+
const memoryFilePath = (0, config_js_1.getMemoryFilePath)();
|
|
128
|
+
const result = {
|
|
129
|
+
uploaded: 0,
|
|
130
|
+
downloaded: 0,
|
|
131
|
+
unchanged: 0,
|
|
132
|
+
errors: [],
|
|
133
|
+
};
|
|
134
|
+
// Get cloud memories
|
|
135
|
+
const cloudMemories = await (0, api_js_1.getAllMemories)();
|
|
136
|
+
const cloudById = new Map(cloudMemories.map(m => [m.id, m]));
|
|
137
|
+
const cloudByContent = new Map(cloudMemories.map(m => [m.content.trim(), m]));
|
|
138
|
+
// Get local memories
|
|
139
|
+
const localMemories = parseMemoryFile(memoryFilePath);
|
|
140
|
+
if (direction === 'push' || direction === 'both') {
|
|
141
|
+
// Upload local memories that don't exist in cloud
|
|
142
|
+
for (const local of localMemories) {
|
|
143
|
+
// Skip if already synced (has ID) or content exists in cloud
|
|
144
|
+
if (local.id && cloudById.has(local.id)) {
|
|
145
|
+
result.unchanged++;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (cloudByContent.has(local.content.trim())) {
|
|
149
|
+
result.unchanged++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
await (0, api_js_1.storeMemory)(local.content, local.metadata);
|
|
154
|
+
result.uploaded++;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
result.errors.push(`Failed to upload: ${local.content.substring(0, 50)}...`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (direction === 'pull' || direction === 'both') {
|
|
162
|
+
// Refresh cloud memories after push
|
|
163
|
+
const updatedCloudMemories = await (0, api_js_1.getAllMemories)();
|
|
164
|
+
// Write all cloud memories to local file
|
|
165
|
+
writeMemoryFile(memoryFilePath, updatedCloudMemories);
|
|
166
|
+
result.downloaded = updatedCloudMemories.length;
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get sync status without making changes
|
|
172
|
+
*/
|
|
173
|
+
async function getSyncStatus() {
|
|
174
|
+
const memoryFilePath = (0, config_js_1.getMemoryFilePath)();
|
|
175
|
+
const cloudMemories = await (0, api_js_1.getAllMemories)();
|
|
176
|
+
const localMemories = parseMemoryFile(memoryFilePath);
|
|
177
|
+
const cloudContents = new Set(cloudMemories.map(m => m.content.trim()));
|
|
178
|
+
const localContents = new Set(localMemories.map(m => m.content.trim()));
|
|
179
|
+
const localOnly = localMemories.filter(m => !cloudContents.has(m.content.trim()));
|
|
180
|
+
const cloudOnly = cloudMemories.filter(m => !localContents.has(m.content.trim()));
|
|
181
|
+
const synced = localMemories.length - localOnly.length;
|
|
182
|
+
return { localOnly, cloudOnly, synced };
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
api_key: string;
|
|
3
|
+
api_url: string;
|
|
4
|
+
memory_file: string;
|
|
5
|
+
}
|
|
6
|
+
export interface Memory {
|
|
7
|
+
id: string;
|
|
8
|
+
content: string;
|
|
9
|
+
metadata?: Record<string, unknown>;
|
|
10
|
+
created_at: string;
|
|
11
|
+
updated_at?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface MemorySearchResult extends Memory {
|
|
14
|
+
similarity: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ApiResponse<T> {
|
|
17
|
+
success: boolean;
|
|
18
|
+
data?: T;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface MemoriesListResponse {
|
|
22
|
+
memories: Memory[];
|
|
23
|
+
total: number;
|
|
24
|
+
limit: number;
|
|
25
|
+
offset: number;
|
|
26
|
+
}
|
|
27
|
+
export interface MemoryCreateResponse {
|
|
28
|
+
memory: Memory;
|
|
29
|
+
}
|
|
30
|
+
export interface MemorySearchResponse {
|
|
31
|
+
memories: MemorySearchResult[];
|
|
32
|
+
}
|
|
33
|
+
export interface SyncStatus {
|
|
34
|
+
local_only: Memory[];
|
|
35
|
+
cloud_only: Memory[];
|
|
36
|
+
conflicts: Array<{
|
|
37
|
+
local: Memory;
|
|
38
|
+
cloud: Memory;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAmB,SAAQ,MAAM;IAChD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,KAAK,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentmemory-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool for AgentMemory - persistent cloud memory for AI agents",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agentmemory": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"agent",
|
|
18
|
+
"memory",
|
|
19
|
+
"cli",
|
|
20
|
+
"openclaw",
|
|
21
|
+
"moltbook",
|
|
22
|
+
"semantic-search"
|
|
23
|
+
],
|
|
24
|
+
"author": "AgentMemory Team",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/agentmemory/agentmemory-cli"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://agentmemory.cloud",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"chalk": "^5.3.0",
|
|
33
|
+
"commander": "^12.1.0",
|
|
34
|
+
"inquirer": "^9.2.23",
|
|
35
|
+
"node-fetch": "^3.3.2"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^20.0.0",
|
|
39
|
+
"typescript": "^5.0.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { createInterface } from 'readline';
|
|
3
|
+
import { deleteMemory, getMemory } from '../lib/api.js';
|
|
4
|
+
import { isConfigured } from '../lib/config.js';
|
|
5
|
+
|
|
6
|
+
interface DeleteOptions {
|
|
7
|
+
force?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function confirm(question: string): Promise<boolean> {
|
|
12
|
+
const rl = createInterface({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
rl.question(question, (answer) => {
|
|
19
|
+
rl.close();
|
|
20
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function deleteCommand(
|
|
26
|
+
id: string,
|
|
27
|
+
options: DeleteOptions
|
|
28
|
+
): Promise<void> {
|
|
29
|
+
if (!isConfigured()) {
|
|
30
|
+
console.log(chalk.red('❌ Not configured. Run "agentmemory init" first.'));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
// First, get the memory to show what will be deleted
|
|
36
|
+
if (!options.force) {
|
|
37
|
+
try {
|
|
38
|
+
const memory = await getMemory(id);
|
|
39
|
+
const preview = memory.content.length > 100
|
|
40
|
+
? memory.content.substring(0, 100) + '...'
|
|
41
|
+
: memory.content;
|
|
42
|
+
|
|
43
|
+
console.log(chalk.yellow('\nMemory to delete:'));
|
|
44
|
+
console.log(chalk.white(` "${preview}"`));
|
|
45
|
+
console.log(chalk.dim(` Created: ${memory.created_at}\n`));
|
|
46
|
+
|
|
47
|
+
const confirmed = await confirm('Are you sure you want to delete this memory? (y/N): ');
|
|
48
|
+
if (!confirmed) {
|
|
49
|
+
console.log(chalk.dim('Cancelled.'));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
// Memory might not exist, proceed anyway
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await deleteMemory(id);
|
|
58
|
+
|
|
59
|
+
if (options.json) {
|
|
60
|
+
console.log(JSON.stringify({ success: true, deleted: id }));
|
|
61
|
+
} else {
|
|
62
|
+
console.log(chalk.green('✅ Memory deleted successfully!'));
|
|
63
|
+
}
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (error instanceof Error) {
|
|
66
|
+
console.log(chalk.red(`❌ Error: ${error.message}`));
|
|
67
|
+
} else {
|
|
68
|
+
console.log(chalk.red('❌ Unknown error occurred'));
|
|
69
|
+
}
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { getAllMemories } from '../lib/api.js';
|
|
4
|
+
import { isConfigured } from '../lib/config.js';
|
|
5
|
+
|
|
6
|
+
interface ExportOptions {
|
|
7
|
+
output?: string;
|
|
8
|
+
pretty?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function exportCommand(options: ExportOptions): Promise<void> {
|
|
12
|
+
if (!isConfigured()) {
|
|
13
|
+
console.log(chalk.red('❌ Not configured. Run "agentmemory init" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
console.log(chalk.dim('Fetching all memories...'));
|
|
19
|
+
const memories = await getAllMemories();
|
|
20
|
+
|
|
21
|
+
const exportData = {
|
|
22
|
+
exported_at: new Date().toISOString(),
|
|
23
|
+
total_memories: memories.length,
|
|
24
|
+
memories: memories,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const jsonOutput = options.pretty
|
|
28
|
+
? JSON.stringify(exportData, null, 2)
|
|
29
|
+
: JSON.stringify(exportData);
|
|
30
|
+
|
|
31
|
+
if (options.output) {
|
|
32
|
+
fs.writeFileSync(options.output, jsonOutput);
|
|
33
|
+
console.log(chalk.green(`✅ Exported ${memories.length} memories to ${options.output}`));
|
|
34
|
+
} else {
|
|
35
|
+
// Output to stdout for piping
|
|
36
|
+
console.log(jsonOutput);
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error instanceof Error) {
|
|
40
|
+
console.error(chalk.red(`❌ Error: ${error.message}`));
|
|
41
|
+
} else {
|
|
42
|
+
console.error(chalk.red('❌ Unknown error occurred'));
|
|
43
|
+
}
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { storeMemory } from '../lib/api.js';
|
|
4
|
+
import { isConfigured } from '../lib/config.js';
|
|
5
|
+
import type { Memory } from '../types.js';
|
|
6
|
+
|
|
7
|
+
interface ImportOptions {
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ImportData {
|
|
12
|
+
memories: Array<{
|
|
13
|
+
content: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function importCommand(
|
|
19
|
+
file: string,
|
|
20
|
+
options: ImportOptions
|
|
21
|
+
): Promise<void> {
|
|
22
|
+
if (!isConfigured()) {
|
|
23
|
+
console.log(chalk.red('❌ Not configured. Run "agentmemory init" first.'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Check if file exists
|
|
28
|
+
if (!fs.existsSync(file)) {
|
|
29
|
+
console.log(chalk.red(`❌ File not found: ${file}`));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
35
|
+
const data: ImportData = JSON.parse(content);
|
|
36
|
+
|
|
37
|
+
if (!data.memories || !Array.isArray(data.memories)) {
|
|
38
|
+
console.log(chalk.red('❌ Invalid import file format. Expected { memories: [...] }'));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log(chalk.dim(`Importing ${data.memories.length} memories...`));
|
|
43
|
+
|
|
44
|
+
let imported = 0;
|
|
45
|
+
let failed = 0;
|
|
46
|
+
const results: Memory[] = [];
|
|
47
|
+
|
|
48
|
+
for (const memory of data.memories) {
|
|
49
|
+
try {
|
|
50
|
+
const result = await storeMemory(memory.content, memory.metadata);
|
|
51
|
+
results.push(result);
|
|
52
|
+
imported++;
|
|
53
|
+
|
|
54
|
+
if (!options.json) {
|
|
55
|
+
process.stdout.write(chalk.green('.'));
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
failed++;
|
|
59
|
+
if (!options.json) {
|
|
60
|
+
process.stdout.write(chalk.red('x'));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options.json) {
|
|
66
|
+
console.log(JSON.stringify({
|
|
67
|
+
success: true,
|
|
68
|
+
imported,
|
|
69
|
+
failed,
|
|
70
|
+
memories: results,
|
|
71
|
+
}, null, 2));
|
|
72
|
+
} else {
|
|
73
|
+
console.log('\n');
|
|
74
|
+
console.log(chalk.green(`✅ Imported ${imported} memories successfully`));
|
|
75
|
+
if (failed > 0) {
|
|
76
|
+
console.log(chalk.yellow(`⚠️ ${failed} memories failed to import`));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error instanceof Error) {
|
|
81
|
+
console.log(chalk.red(`❌ Error: ${error.message}`));
|
|
82
|
+
} else {
|
|
83
|
+
console.log(chalk.red('❌ Unknown error occurred'));
|
|
84
|
+
}
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { createInterface } from 'readline';
|
|
3
|
+
import { saveConfig, loadConfig, getConfigPath, isConfigured } from '../lib/config.js';
|
|
4
|
+
|
|
5
|
+
async function prompt(question: string): Promise<string> {
|
|
6
|
+
const rl = createInterface({
|
|
7
|
+
input: process.stdin,
|
|
8
|
+
output: process.stdout,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
rl.question(question, (answer) => {
|
|
13
|
+
rl.close();
|
|
14
|
+
resolve(answer.trim());
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function initCommand(): Promise<void> {
|
|
20
|
+
console.log(chalk.cyan('\n🧠 AgentMemory CLI Setup\n'));
|
|
21
|
+
|
|
22
|
+
if (isConfigured()) {
|
|
23
|
+
const config = loadConfig();
|
|
24
|
+
console.log(chalk.yellow('You already have a configuration:'));
|
|
25
|
+
console.log(` API Key: ${config.api_key.substring(0, 10)}...`);
|
|
26
|
+
console.log(` API URL: ${config.api_url}`);
|
|
27
|
+
console.log(` Memory File: ${config.memory_file}\n`);
|
|
28
|
+
|
|
29
|
+
const overwrite = await prompt('Do you want to reconfigure? (y/N): ');
|
|
30
|
+
if (overwrite.toLowerCase() !== 'y') {
|
|
31
|
+
console.log(chalk.green('\nConfiguration unchanged.'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(chalk.dim('Get your API key from: https://agentmemory.cloud/dashboard\n'));
|
|
37
|
+
|
|
38
|
+
// Get API key
|
|
39
|
+
const apiKey = await prompt('Enter your API key (am_xxxxx): ');
|
|
40
|
+
|
|
41
|
+
if (!apiKey.startsWith('am_')) {
|
|
42
|
+
console.log(chalk.red('\n❌ Invalid API key format. Should start with "am_"'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Get API URL (with default)
|
|
47
|
+
const defaultUrl = 'https://agentmemory.cloud/api';
|
|
48
|
+
const apiUrlInput = await prompt(`API URL (${defaultUrl}): `);
|
|
49
|
+
const apiUrl = apiUrlInput || defaultUrl;
|
|
50
|
+
|
|
51
|
+
// Get memory file path (with default)
|
|
52
|
+
const defaultMemoryFile = './MEMORY.md';
|
|
53
|
+
const memoryFileInput = await prompt(`Local memory file path (${defaultMemoryFile}): `);
|
|
54
|
+
const memoryFile = memoryFileInput || defaultMemoryFile;
|
|
55
|
+
|
|
56
|
+
// Save configuration
|
|
57
|
+
saveConfig({
|
|
58
|
+
api_key: apiKey,
|
|
59
|
+
api_url: apiUrl,
|
|
60
|
+
memory_file: memoryFile,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log(chalk.green('\n✅ Configuration saved!'));
|
|
64
|
+
console.log(chalk.dim(` Config file: ${getConfigPath()}\n`));
|
|
65
|
+
|
|
66
|
+
console.log(chalk.cyan('You can now use AgentMemory CLI:'));
|
|
67
|
+
console.log(chalk.dim(' agentmemory store "Your memory content"'));
|
|
68
|
+
console.log(chalk.dim(' agentmemory search "query"'));
|
|
69
|
+
console.log(chalk.dim(' agentmemory list'));
|
|
70
|
+
console.log(chalk.dim(' agentmemory sync\n'));
|
|
71
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { listMemories } from '../lib/api.js';
|
|
3
|
+
import { isConfigured } from '../lib/config.js';
|
|
4
|
+
|
|
5
|
+
interface ListOptions {
|
|
6
|
+
limit?: string;
|
|
7
|
+
offset?: string;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function listCommand(options: ListOptions): Promise<void> {
|
|
12
|
+
if (!isConfigured()) {
|
|
13
|
+
console.log(chalk.red('❌ Not configured. Run "agentmemory init" first.'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const limit = options.limit ? parseInt(options.limit, 10) : 50;
|
|
19
|
+
const offset = options.offset ? parseInt(options.offset, 10) : 0;
|
|
20
|
+
|
|
21
|
+
const response = await listMemories(limit, offset);
|
|
22
|
+
|
|
23
|
+
if (options.json) {
|
|
24
|
+
console.log(JSON.stringify(response, null, 2));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (response.memories.length === 0) {
|
|
29
|
+
console.log(chalk.yellow('No memories found.'));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log(chalk.cyan(`\n📚 Memories (${response.memories.length} of ${response.total}):\n`));
|
|
34
|
+
|
|
35
|
+
for (const memory of response.memories) {
|
|
36
|
+
const date = new Date(memory.created_at).toLocaleDateString();
|
|
37
|
+
const preview = memory.content.length > 80
|
|
38
|
+
? memory.content.substring(0, 80) + '...'
|
|
39
|
+
: memory.content;
|
|
40
|
+
|
|
41
|
+
console.log(chalk.green(`• `) + chalk.white(preview));
|
|
42
|
+
console.log(chalk.dim(` ID: ${memory.id} | Created: ${date}`));
|
|
43
|
+
if (memory.metadata && Object.keys(memory.metadata).length > 0) {
|
|
44
|
+
console.log(chalk.dim(` Metadata: ${JSON.stringify(memory.metadata)}`));
|
|
45
|
+
}
|
|
46
|
+
console.log();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (response.total > response.memories.length + offset) {
|
|
50
|
+
const remaining = response.total - response.memories.length - offset;
|
|
51
|
+
console.log(chalk.dim(`... and ${remaining} more. Use --offset to paginate.`));
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
console.log(chalk.red(`❌ Error: ${error.message}`));
|
|
56
|
+
} else {
|
|
57
|
+
console.log(chalk.red('❌ Unknown error occurred'));
|
|
58
|
+
}
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|