cozo-memory 1.0.6 β 1.0.7
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 +39 -0
- package/dist/cli-commands.js +6 -0
- package/dist/cli.js +80 -0
- package/dist/index.js +94 -0
- package/dist/test-user-profile.js +59 -0
- package/dist/tui.js +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -912,6 +912,42 @@ The system maintains a persistent profile of the user (preferences, dislikes, wo
|
|
|
912
912
|
- **Mechanism**: All observations assigned to this entity receive a significant boost in search and context queries.
|
|
913
913
|
- **Initialization**: The profile is automatically created on first start.
|
|
914
914
|
|
|
915
|
+
### Manual Profile Editing
|
|
916
|
+
|
|
917
|
+
You can now directly edit the user profile using the `edit_user_profile` MCP tool:
|
|
918
|
+
|
|
919
|
+
```typescript
|
|
920
|
+
// View current profile
|
|
921
|
+
{ }
|
|
922
|
+
|
|
923
|
+
// Update metadata
|
|
924
|
+
{
|
|
925
|
+
metadata: { timezone: "Europe/Berlin", language: "de" }
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// Add preferences
|
|
929
|
+
{
|
|
930
|
+
observations: [
|
|
931
|
+
{ text: "Prefers TypeScript over JavaScript" },
|
|
932
|
+
{ text: "Likes concise documentation" }
|
|
933
|
+
]
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// Clear and reset preferences
|
|
937
|
+
{
|
|
938
|
+
clear_observations: true,
|
|
939
|
+
observations: [{ text: "New preference" }]
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Update name and type
|
|
943
|
+
{
|
|
944
|
+
name: "Developer Profile",
|
|
945
|
+
type: "UserProfile"
|
|
946
|
+
}
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
**Note**: You can still use the implicit method via `mutate_memory` with `action='add_observation'` and `entity_id='global_user_profile'`.
|
|
950
|
+
|
|
915
951
|
### Manual Tests
|
|
916
952
|
|
|
917
953
|
There are various test scripts for different features:
|
|
@@ -928,6 +964,9 @@ npx ts-node test-reflection.ts
|
|
|
928
964
|
|
|
929
965
|
# Tests user preference profiling and search boost
|
|
930
966
|
npx ts-node test-user-pref.ts
|
|
967
|
+
|
|
968
|
+
# Tests manual user profile editing
|
|
969
|
+
npx ts-node src/test-user-profile.ts
|
|
931
970
|
```
|
|
932
971
|
|
|
933
972
|
## Troubleshooting
|
package/dist/cli-commands.js
CHANGED
|
@@ -200,5 +200,11 @@ class CLICommands {
|
|
|
200
200
|
// For now, return a placeholder
|
|
201
201
|
return { status: "not_implemented", message: "Use MCP server for file ingestion" };
|
|
202
202
|
}
|
|
203
|
+
async editUserProfile(args) {
|
|
204
|
+
return await this.server.editUserProfile(args);
|
|
205
|
+
}
|
|
206
|
+
async getUserProfile() {
|
|
207
|
+
return await this.server.editUserProfile({});
|
|
208
|
+
}
|
|
203
209
|
}
|
|
204
210
|
exports.CLICommands = CLICommands;
|
package/dist/cli.js
CHANGED
|
@@ -407,4 +407,84 @@ ingest
|
|
|
407
407
|
handleError(error);
|
|
408
408
|
}
|
|
409
409
|
});
|
|
410
|
+
// User Profile commands
|
|
411
|
+
const profile = program.command('profile').description('User profile management');
|
|
412
|
+
profile
|
|
413
|
+
.command('show')
|
|
414
|
+
.description('Show current user profile')
|
|
415
|
+
.option('-f, --format <format>', 'Output format (json|pretty)', 'pretty')
|
|
416
|
+
.action(async (options) => {
|
|
417
|
+
try {
|
|
418
|
+
await cli.init();
|
|
419
|
+
const result = await cli.getUserProfile();
|
|
420
|
+
formatOutput(result, options.format);
|
|
421
|
+
await cli.close();
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
handleError(error);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
profile
|
|
428
|
+
.command('update')
|
|
429
|
+
.description('Update user profile metadata')
|
|
430
|
+
.option('-n, --name <name>', 'Profile name')
|
|
431
|
+
.option('-t, --type <type>', 'Profile type')
|
|
432
|
+
.option('-m, --metadata <json>', 'Metadata as JSON string')
|
|
433
|
+
.option('-f, --format <format>', 'Output format (json|pretty)', 'pretty')
|
|
434
|
+
.action(async (options) => {
|
|
435
|
+
try {
|
|
436
|
+
await cli.init();
|
|
437
|
+
const metadata = options.metadata ? JSON.parse(options.metadata) : undefined;
|
|
438
|
+
const result = await cli.editUserProfile({
|
|
439
|
+
name: options.name,
|
|
440
|
+
type: options.type,
|
|
441
|
+
metadata
|
|
442
|
+
});
|
|
443
|
+
formatOutput(result, options.format);
|
|
444
|
+
await cli.close();
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
handleError(error);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
profile
|
|
451
|
+
.command('add-preference')
|
|
452
|
+
.description('Add preference to user profile')
|
|
453
|
+
.requiredOption('-t, --text <text>', 'Preference text')
|
|
454
|
+
.option('-m, --metadata <json>', 'Metadata as JSON string')
|
|
455
|
+
.option('-f, --format <format>', 'Output format (json|pretty)', 'pretty')
|
|
456
|
+
.action(async (options) => {
|
|
457
|
+
try {
|
|
458
|
+
await cli.init();
|
|
459
|
+
const metadata = options.metadata ? JSON.parse(options.metadata) : undefined;
|
|
460
|
+
const result = await cli.editUserProfile({
|
|
461
|
+
observations: [{ text: options.text, metadata }]
|
|
462
|
+
});
|
|
463
|
+
formatOutput(result, options.format);
|
|
464
|
+
await cli.close();
|
|
465
|
+
}
|
|
466
|
+
catch (error) {
|
|
467
|
+
handleError(error);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
profile
|
|
471
|
+
.command('reset')
|
|
472
|
+
.description('Clear all preferences and optionally set new ones')
|
|
473
|
+
.option('-t, --text <text>', 'New preference text (can be used multiple times)')
|
|
474
|
+
.option('-f, --format <format>', 'Output format (json|pretty)', 'pretty')
|
|
475
|
+
.action(async (options) => {
|
|
476
|
+
try {
|
|
477
|
+
await cli.init();
|
|
478
|
+
const observations = options.text ? [{ text: options.text }] : [];
|
|
479
|
+
const result = await cli.editUserProfile({
|
|
480
|
+
clear_observations: true,
|
|
481
|
+
observations
|
|
482
|
+
});
|
|
483
|
+
formatOutput(result, options.format);
|
|
484
|
+
await cli.close();
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
handleError(error);
|
|
488
|
+
}
|
|
489
|
+
});
|
|
410
490
|
program.parse();
|
package/dist/index.js
CHANGED
|
@@ -2173,6 +2173,64 @@ ids[id] <- $ids
|
|
|
2173
2173
|
defaultEntityType: args.defaultEntityType
|
|
2174
2174
|
});
|
|
2175
2175
|
}
|
|
2176
|
+
async editUserProfile(args) {
|
|
2177
|
+
try {
|
|
2178
|
+
const current = await this.db.run('?[name, type, metadata] := *entity{id: $id, name, type, metadata, @ "NOW"}', { id: exports.USER_ENTITY_ID });
|
|
2179
|
+
if (current.rows.length === 0) {
|
|
2180
|
+
return { error: "User profile not found. Initialize it first." };
|
|
2181
|
+
}
|
|
2182
|
+
if (args.name || args.type || args.metadata) {
|
|
2183
|
+
const updateResult = await this.updateEntity({
|
|
2184
|
+
id: exports.USER_ENTITY_ID,
|
|
2185
|
+
name: args.name,
|
|
2186
|
+
type: args.type,
|
|
2187
|
+
metadata: args.metadata
|
|
2188
|
+
});
|
|
2189
|
+
if (updateResult.error) {
|
|
2190
|
+
return updateResult;
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
if (args.clear_observations) {
|
|
2194
|
+
const existingObs = await this.db.run('?[id] := *observation{id, entity_id: $eid, @ "NOW"}', { eid: exports.USER_ENTITY_ID });
|
|
2195
|
+
for (const row of existingObs.rows) {
|
|
2196
|
+
await this.db.run('?[id, entity_id, text, embedding, metadata, created_at] := *observation{id, entity_id, text, embedding, metadata, created_at, @ "NOW"}, id = $id :delete observation {id, entity_id, text, embedding, metadata, created_at}', { id: row[0] });
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
if (args.observations && args.observations.length > 0) {
|
|
2200
|
+
for (const obs of args.observations) {
|
|
2201
|
+
await this.addObservation({
|
|
2202
|
+
entity_id: exports.USER_ENTITY_ID,
|
|
2203
|
+
text: obs.text,
|
|
2204
|
+
metadata: { ...obs.metadata, kind: "user_preference" },
|
|
2205
|
+
deduplicate: true
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
const updated = await this.db.run('?[name, type, metadata] := *entity{id: $id, name, type, metadata, @ "NOW"}', { id: exports.USER_ENTITY_ID });
|
|
2210
|
+
const observations = await this.db.run('?[id, text, metadata] := *observation{id, entity_id: $eid, text, metadata, @ "NOW"}', { eid: exports.USER_ENTITY_ID });
|
|
2211
|
+
return {
|
|
2212
|
+
status: "User profile updated",
|
|
2213
|
+
profile: {
|
|
2214
|
+
id: exports.USER_ENTITY_ID,
|
|
2215
|
+
name: updated.rows[0][0],
|
|
2216
|
+
type: updated.rows[0][1],
|
|
2217
|
+
metadata: updated.rows[0][2],
|
|
2218
|
+
observations: observations.rows.map((r) => ({
|
|
2219
|
+
id: r[0],
|
|
2220
|
+
text: r[1],
|
|
2221
|
+
metadata: r[2]
|
|
2222
|
+
}))
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
catch (error) {
|
|
2227
|
+
console.error("[UserProfile] Error editing user profile:", error);
|
|
2228
|
+
return {
|
|
2229
|
+
error: "Failed to edit user profile",
|
|
2230
|
+
message: error.message || String(error)
|
|
2231
|
+
};
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2176
2234
|
registerTools() {
|
|
2177
2235
|
const MetadataSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.any());
|
|
2178
2236
|
const MutateMemorySchema = zod_1.z.discriminatedUnion("action", [
|
|
@@ -3378,6 +3436,42 @@ Supported actions:
|
|
|
3378
3436
|
return JSON.stringify({ error: "Unknown action" });
|
|
3379
3437
|
},
|
|
3380
3438
|
});
|
|
3439
|
+
// User Profile Management Tool
|
|
3440
|
+
this.mcp.addTool({
|
|
3441
|
+
name: "edit_user_profile",
|
|
3442
|
+
description: `Direct management of the global user profile ('global_user_profile').
|
|
3443
|
+
This tool allows manual editing of user preferences, work style, and profile metadata.
|
|
3444
|
+
|
|
3445
|
+
The user profile is automatically boosted in all searches (50% score boost) and used for personalization.
|
|
3446
|
+
|
|
3447
|
+
Parameters:
|
|
3448
|
+
- name?: string - Update the profile name (default: "The User")
|
|
3449
|
+
- type?: string - Update the profile type (default: "User")
|
|
3450
|
+
- metadata?: object - Update or merge profile metadata
|
|
3451
|
+
- observations?: Array<{ text: string, metadata?: object }> - Add new preference observations
|
|
3452
|
+
- clear_observations?: boolean - Remove all existing observations before adding new ones
|
|
3453
|
+
|
|
3454
|
+
Examples:
|
|
3455
|
+
- Add preferences: { observations: [{ text: "Prefers TypeScript over JavaScript" }] }
|
|
3456
|
+
- Update metadata: { metadata: { timezone: "Europe/Berlin", language: "de" } }
|
|
3457
|
+
- Reset and set new preferences: { clear_observations: true, observations: [{ text: "New preference" }] }
|
|
3458
|
+
|
|
3459
|
+
Note: Use 'mutate_memory' with action='add_observation' and entity_id='global_user_profile' for implicit preference updates.`,
|
|
3460
|
+
parameters: zod_1.z.object({
|
|
3461
|
+
name: zod_1.z.string().optional().describe("New name for the user profile"),
|
|
3462
|
+
type: zod_1.z.string().optional().describe("New type for the user profile"),
|
|
3463
|
+
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe("Metadata to merge with existing metadata"),
|
|
3464
|
+
observations: zod_1.z.array(zod_1.z.object({
|
|
3465
|
+
text: zod_1.z.string().describe("Preference or work style description"),
|
|
3466
|
+
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional().describe("Optional metadata for this observation")
|
|
3467
|
+
})).optional().describe("New observations to add to the profile"),
|
|
3468
|
+
clear_observations: zod_1.z.boolean().optional().default(false).describe("Clear all existing observations before adding new ones")
|
|
3469
|
+
}),
|
|
3470
|
+
execute: async (args) => {
|
|
3471
|
+
await this.initPromise;
|
|
3472
|
+
return JSON.stringify(await this.editUserProfile(args));
|
|
3473
|
+
}
|
|
3474
|
+
});
|
|
3381
3475
|
}
|
|
3382
3476
|
async start() {
|
|
3383
3477
|
await this.mcp.start({ transportType: "stdio" });
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("./index");
|
|
4
|
+
async function testUserProfileEditing() {
|
|
5
|
+
console.log("=== Testing User Profile Editing ===\n");
|
|
6
|
+
const server = new index_1.MemoryServer();
|
|
7
|
+
await server.start();
|
|
8
|
+
try {
|
|
9
|
+
// 1. View current profile
|
|
10
|
+
console.log("1. Current user profile:");
|
|
11
|
+
const currentProfile = await server.editUserProfile({});
|
|
12
|
+
console.log(JSON.stringify(currentProfile, null, 2));
|
|
13
|
+
// 2. Update metadata
|
|
14
|
+
console.log("\n2. Updating profile metadata:");
|
|
15
|
+
const metadataUpdate = await server.editUserProfile({
|
|
16
|
+
metadata: {
|
|
17
|
+
timezone: "Europe/Berlin",
|
|
18
|
+
language: "de",
|
|
19
|
+
work_hours: "09:00-17:00"
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
console.log(JSON.stringify(metadataUpdate, null, 2));
|
|
23
|
+
// 3. Add new preferences
|
|
24
|
+
console.log("\n3. Adding new preferences:");
|
|
25
|
+
const addPrefs = await server.editUserProfile({
|
|
26
|
+
observations: [
|
|
27
|
+
{ text: "Prefers TypeScript over JavaScript for type safety" },
|
|
28
|
+
{ text: "Likes clean, minimal code without unnecessary comments" },
|
|
29
|
+
{ text: "Prefers functional programming patterns" }
|
|
30
|
+
]
|
|
31
|
+
});
|
|
32
|
+
console.log(JSON.stringify(addPrefs, null, 2));
|
|
33
|
+
// 4. Clear and reset preferences
|
|
34
|
+
console.log("\n4. Clearing and resetting preferences:");
|
|
35
|
+
const resetPrefs = await server.editUserProfile({
|
|
36
|
+
clear_observations: true,
|
|
37
|
+
observations: [
|
|
38
|
+
{ text: "Works primarily with Node.js and TypeScript", metadata: { category: "tech_stack" } },
|
|
39
|
+
{ text: "Prefers concise documentation", metadata: { category: "style" } }
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
console.log(JSON.stringify(resetPrefs, null, 2));
|
|
43
|
+
// 5. Update name and type
|
|
44
|
+
console.log("\n5. Updating profile name and type:");
|
|
45
|
+
const nameUpdate = await server.editUserProfile({
|
|
46
|
+
name: "Developer Profile",
|
|
47
|
+
type: "UserProfile"
|
|
48
|
+
});
|
|
49
|
+
console.log(JSON.stringify(nameUpdate, null, 2));
|
|
50
|
+
console.log("\n=== Test completed successfully ===");
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error("Test failed:", error);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
testUserProfileEditing();
|
package/dist/tui.js
CHANGED
|
@@ -63,13 +63,13 @@ async function main() {
|
|
|
63
63
|
else if (key.downArrow) {
|
|
64
64
|
setState(prev => ({
|
|
65
65
|
...prev,
|
|
66
|
-
selectedIndex: Math.min(
|
|
66
|
+
selectedIndex: Math.min(6, prev.selectedIndex + 1)
|
|
67
67
|
}));
|
|
68
68
|
}
|
|
69
69
|
else if (key.return) {
|
|
70
|
-
const screens = ['entity', 'search', 'graph', 'system', 'result', 'menu'];
|
|
70
|
+
const screens = ['entity', 'profile', 'search', 'graph', 'system', 'result', 'menu'];
|
|
71
71
|
const newScreen = screens[state.selectedIndex];
|
|
72
|
-
if (state.selectedIndex ===
|
|
72
|
+
if (state.selectedIndex === 5) {
|
|
73
73
|
setState(prev => ({ ...prev, loading: true }));
|
|
74
74
|
cli.health().then(result => {
|
|
75
75
|
setState(prev => ({ ...prev, screen: 'result', result, loading: false }));
|
|
@@ -89,7 +89,7 @@ async function main() {
|
|
|
89
89
|
if (state.error) {
|
|
90
90
|
return React.createElement(Box, { flexDirection: 'column', padding: 1 }, React.createElement(Text, { color: 'red' }, `β Error: ${state.error}`), React.createElement(Text, { dimColor: true }, 'Press ESC to return to menu'));
|
|
91
91
|
}
|
|
92
|
-
return React.createElement(Box, { flexDirection: 'column', padding: 1 }, React.createElement(Header), state.screen === 'menu' && React.createElement(MainMenu, { selectedIndex: state.selectedIndex }), state.screen === 'entity' && React.createElement(EntityScreen), state.screen === 'search' && React.createElement(SearchScreen), state.screen === 'graph' && React.createElement(GraphScreen), state.screen === 'system' && React.createElement(SystemScreen), state.screen === 'result' && React.createElement(ResultScreen, { result: state.result }), React.createElement(Footer));
|
|
92
|
+
return React.createElement(Box, { flexDirection: 'column', padding: 1 }, React.createElement(Header), state.screen === 'menu' && React.createElement(MainMenu, { selectedIndex: state.selectedIndex }), state.screen === 'entity' && React.createElement(EntityScreen), state.screen === 'profile' && React.createElement(ProfileScreen), state.screen === 'search' && React.createElement(SearchScreen), state.screen === 'graph' && React.createElement(GraphScreen), state.screen === 'system' && React.createElement(SystemScreen), state.screen === 'result' && React.createElement(ResultScreen, { result: state.result }), React.createElement(Footer));
|
|
93
93
|
};
|
|
94
94
|
const Header = () => React.createElement(Box, {
|
|
95
95
|
flexDirection: 'column',
|
|
@@ -107,6 +107,7 @@ async function main() {
|
|
|
107
107
|
const MainMenu = ({ selectedIndex }) => {
|
|
108
108
|
const menuItems = [
|
|
109
109
|
{ icon: 'π¦', label: 'Entity Operations', desc: 'Create, read, update, delete entities' },
|
|
110
|
+
{ icon: 'π€', label: 'User Profile', desc: 'Manage user preferences and profile' },
|
|
110
111
|
{ icon: 'π', label: 'Search & Context', desc: 'Hybrid search, context retrieval' },
|
|
111
112
|
{ icon: 'πΈοΈ', label: 'Graph Operations', desc: 'Explore, PageRank, communities' },
|
|
112
113
|
{ icon: 'βοΈ', label: 'System Management', desc: 'Health, metrics, export/import' },
|
|
@@ -116,6 +117,7 @@ async function main() {
|
|
|
116
117
|
return React.createElement(Box, { flexDirection: 'column' }, React.createElement(Box, { marginBottom: 1 }, React.createElement(Text, { bold: true, color: 'yellow' }, 'Main Menu')), ...menuItems.map((item, index) => React.createElement(Box, { key: index, marginLeft: 2 }, React.createElement(Text, { color: selectedIndex === index ? 'green' : 'white' }, `${selectedIndex === index ? 'βΆ ' : ' '}${item.icon} ${item.label}`), selectedIndex === index && React.createElement(Text, { dimColor: true }, ` - ${item.desc}`))));
|
|
117
118
|
};
|
|
118
119
|
const EntityScreen = () => React.createElement(Box, { flexDirection: 'column' }, React.createElement(Text, { bold: true, color: 'cyan' }, 'π¦ Entity Operations'), React.createElement(Box, { marginTop: 1, flexDirection: 'column', marginLeft: 2 }, React.createElement(Text, null, 'β’ Create Entity: ', React.createElement(Text, { dimColor: true }, 'cozo-memory entity create -n "Name" -t "Type"')), React.createElement(Text, null, 'β’ Get Entity: ', React.createElement(Text, { dimColor: true }, 'cozo-memory entity get -i <id>')), React.createElement(Text, null, 'β’ Delete Entity: ', React.createElement(Text, { dimColor: true }, 'cozo-memory entity delete -i <id>')), React.createElement(Text, null, 'β’ Add Observation: ', React.createElement(Text, { dimColor: true }, 'cozo-memory obs add -i <id> -t "Text"'))), React.createElement(Box, { marginTop: 1 }, React.createElement(Text, { color: 'yellow' }, 'π‘ Use the CLI commands shown above for entity operations')));
|
|
120
|
+
const ProfileScreen = () => React.createElement(Box, { flexDirection: 'column' }, React.createElement(Text, { bold: true, color: 'cyan' }, 'π€ User Profile Management'), React.createElement(Box, { marginTop: 1, flexDirection: 'column', marginLeft: 2 }, React.createElement(Text, null, 'β’ Show Profile: ', React.createElement(Text, { dimColor: true }, 'cozo-memory profile show')), React.createElement(Text, null, 'β’ Update Metadata: ', React.createElement(Text, { dimColor: true }, 'cozo-memory profile update -m \'{"key":"value"}\'')), React.createElement(Text, null, 'β’ Add Preference: ', React.createElement(Text, { dimColor: true }, 'cozo-memory profile add-preference -t "I prefer TypeScript"')), React.createElement(Text, null, 'β’ Reset Preferences: ', React.createElement(Text, { dimColor: true }, 'cozo-memory profile reset'))), React.createElement(Box, { marginTop: 1 }, React.createElement(Text, { color: 'yellow' }, 'π‘ User profile preferences get 50% search boost automatically')));
|
|
119
121
|
const SearchScreen = () => React.createElement(Box, { flexDirection: 'column' }, React.createElement(Text, { bold: true, color: 'cyan' }, 'π Search & Context'), React.createElement(Box, { marginTop: 1, flexDirection: 'column', marginLeft: 2 }, React.createElement(Text, null, 'β’ Search: ', React.createElement(Text, { dimColor: true }, 'cozo-memory search query -q "your query"')), React.createElement(Text, null, 'β’ Context: ', React.createElement(Text, { dimColor: true }, 'cozo-memory search context -q "query" -w 5')), React.createElement(Text, null, 'β’ Advanced: ', React.createElement(Text, { dimColor: true }, 'With filters, entity types, time ranges'))), React.createElement(Box, { marginTop: 1 }, React.createElement(Text, { color: 'yellow' }, 'π‘ Hybrid search combines vector, keyword, and graph signals')));
|
|
120
122
|
const GraphScreen = () => React.createElement(Box, { flexDirection: 'column' }, React.createElement(Text, { bold: true, color: 'cyan' }, 'πΈοΈ Graph Operations'), React.createElement(Box, { marginTop: 1, flexDirection: 'column', marginLeft: 2 }, React.createElement(Text, null, 'β’ Explore: ', React.createElement(Text, { dimColor: true }, 'cozo-memory graph explore -s <id> -h 3')), React.createElement(Text, null, 'β’ PageRank: ', React.createElement(Text, { dimColor: true }, 'cozo-memory graph pagerank')), React.createElement(Text, null, 'β’ Communities: ', React.createElement(Text, { dimColor: true }, 'cozo-memory graph communities')), React.createElement(Text, null, 'β’ Path Finding: ', React.createElement(Text, { dimColor: true }, 'cozo-memory graph explore -s <id1> -e <id2>'))), React.createElement(Box, { marginTop: 1 }, React.createElement(Text, { color: 'yellow' }, 'π‘ Graph algorithms help discover implicit relationships')));
|
|
121
123
|
const SystemScreen = () => React.createElement(Box, { flexDirection: 'column' }, React.createElement(Text, { bold: true, color: 'cyan' }, 'βοΈ System Management'), React.createElement(Box, { marginTop: 1, flexDirection: 'column', marginLeft: 2 }, React.createElement(Text, null, 'β’ Health: ', React.createElement(Text, { dimColor: true }, 'cozo-memory system health')), React.createElement(Text, null, 'β’ Metrics: ', React.createElement(Text, { dimColor: true }, 'cozo-memory system metrics')), React.createElement(Text, null, 'β’ Export JSON: ', React.createElement(Text, { dimColor: true }, 'cozo-memory export json -o backup.json')), React.createElement(Text, null, 'β’ Export Markdown: ', React.createElement(Text, { dimColor: true }, 'cozo-memory export markdown -o notes.md')), React.createElement(Text, null, 'β’ Export Obsidian: ', React.createElement(Text, { dimColor: true }, 'cozo-memory export obsidian -o vault.zip')), React.createElement(Text, null, 'β’ Import: ', React.createElement(Text, { dimColor: true }, 'cozo-memory import file -i data.json -f cozo'))), React.createElement(Box, { marginTop: 1 }, React.createElement(Text, { color: 'yellow' }, 'π‘ Regular exports recommended for backup')));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozo-memory",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"mcpName": "io.github.tobs-code/cozo-memory",
|
|
5
5
|
"description": "Local-first persistent memory system for AI agents with hybrid search, graph reasoning, and MCP integration",
|
|
6
6
|
"main": "dist/index.js",
|