@ilivemylife/graph-sdk 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.
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Messenger Basics - Messages and Lifebot
3
+ *
4
+ * Shows how to work with the messenger in nodes:
5
+ * - Send messages (without AI)
6
+ * - Read messages
7
+ * - Ask Lifebot and wait for response
8
+ * - Ask Lifebot to create/organize nodes
9
+ *
10
+ * Getting your token:
11
+ * Option 1: npx ilml login
12
+ * Option 2: Browser DevTools → Network tab → any request → Headers → "access-token"
13
+ *
14
+ * Run:
15
+ * node examples/messenger-basics.mjs
16
+ */
17
+
18
+ import {
19
+ createGraphClient,
20
+ LIFEBOT_MESSAGE_TYPES,
21
+ LifebotTimeoutError,
22
+ LifebotRateLimitError
23
+ } from '@ilivemylife/graph-sdk';
24
+
25
+ const graph = createGraphClient({
26
+ token: process.env.ILML_TOKEN
27
+ });
28
+
29
+ console.log('='.repeat(60));
30
+ console.log('Messenger & Lifebot Example');
31
+ console.log('='.repeat(60));
32
+
33
+ // Get user's root node for demos
34
+ const me = await graph.me();
35
+ console.log('\nUsing root node:', me.rootItemId);
36
+
37
+ // ============================================================================
38
+ // 1. Read existing messages
39
+ // ============================================================================
40
+
41
+ console.log('\n[Reading Messages]');
42
+ const messages = await graph.messages(me.rootItemId, 5);
43
+ console.log(`Found ${messages.length} messages`);
44
+
45
+ messages.forEach(msg => {
46
+ const date = new Date(parseInt(msg.createdAt)).toLocaleString();
47
+ const preview = msg.content?.substring(0, 50) || '(empty)';
48
+ console.log(` [${date}] ${msg.createdBy}: ${preview}...`);
49
+ });
50
+
51
+ // ============================================================================
52
+ // 2. Send a simple message (no AI response)
53
+ // ============================================================================
54
+
55
+ console.log('\n[Sending Message - No AI]');
56
+ const simpleMsg = await graph.addMessage(me.rootItemId, 'Hello from SDK! This is a test message.', {
57
+ lifebot: LIFEBOT_MESSAGE_TYPES.off // Don't trigger AI response
58
+ });
59
+ console.log(' Sent message ID:', simpleMsg.id);
60
+ console.log(' Content:', simpleMsg.content);
61
+
62
+ // ============================================================================
63
+ // 3. Ask Lifebot a simple question
64
+ // ============================================================================
65
+
66
+ console.log('\n[Asking Lifebot - Simple Question]');
67
+ console.log(' Sending: "What is 2 + 2?"');
68
+ console.log(' Waiting for AI response...');
69
+
70
+ try {
71
+ const answer = await graph.askLifebot(me.rootItemId, 'What is 2 + 2?', {
72
+ timeout: 60000 // Wait up to 60 seconds
73
+ });
74
+ console.log(' Lifebot says:', answer.content);
75
+ } catch (error) {
76
+ if (error instanceof LifebotTimeoutError) {
77
+ console.log(' Timeout - Lifebot did not respond in time');
78
+ console.log(' (Check if Lifebot is enabled in node settings)');
79
+ } else if (error instanceof LifebotRateLimitError) {
80
+ console.log(' Rate limit exceeded, try again later');
81
+ } else {
82
+ throw error;
83
+ }
84
+ }
85
+
86
+ // ============================================================================
87
+ // 4. Ask Lifebot to search/analyze
88
+ // ============================================================================
89
+
90
+ console.log('\n[Asking Lifebot - Search in Graph]');
91
+ console.log(' Sending: "What nodes do I have in my root?"');
92
+
93
+ try {
94
+ const searchAnswer = await graph.askLifebot(
95
+ me.rootItemId,
96
+ 'What nodes do I have in my root? List the first 5.',
97
+ { timeout: 60000 }
98
+ );
99
+ console.log(' Lifebot says:', searchAnswer.content.substring(0, 200) + '...');
100
+ } catch (error) {
101
+ if (error instanceof LifebotTimeoutError) {
102
+ console.log(' Timeout - try with a longer timeout or check Lifebot settings');
103
+ } else {
104
+ throw error;
105
+ }
106
+ }
107
+
108
+ // ============================================================================
109
+ // 5. Ask Lifebot to CREATE a node
110
+ // ============================================================================
111
+
112
+ console.log('\n[Asking Lifebot - Create Node]');
113
+ console.log(' Asking Lifebot to create a project node...');
114
+
115
+ try {
116
+ const createResult = await graph.askLifebot(
117
+ me.rootItemId,
118
+ `Please create a new node called "Lifebot Demo Project".
119
+ Add a markdown description explaining that this project was created by Lifebot
120
+ as a demonstration of AI capabilities in iLiveMyLife.`,
121
+ { timeout: 120000 } // 2 minutes for complex operations
122
+ );
123
+ console.log(' Lifebot:', createResult.content.substring(0, 300));
124
+ } catch (error) {
125
+ if (error instanceof LifebotTimeoutError) {
126
+ console.log(' Timeout on create operation');
127
+ } else {
128
+ throw error;
129
+ }
130
+ }
131
+
132
+ // ============================================================================
133
+ // 6. Ask Lifebot to create STRUCTURE
134
+ // ============================================================================
135
+
136
+ console.log('\n[Asking Lifebot - Create Structure]');
137
+ console.log(' Asking Lifebot to add child nodes to the project...');
138
+
139
+ try {
140
+ const structureResult = await graph.askLifebot(
141
+ me.rootItemId,
142
+ `Inside the "Lifebot Demo Project" you just created, please add these child nodes:
143
+ 1. "Features" - describe what Lifebot can do
144
+ 2. "Examples" - list example use cases
145
+ 3. "Getting Started" - how to enable and use Lifebot
146
+
147
+ Add helpful descriptions to each.`,
148
+ { timeout: 120000 }
149
+ );
150
+ console.log(' Lifebot:', structureResult.content.substring(0, 300));
151
+ } catch (error) {
152
+ if (error instanceof LifebotTimeoutError) {
153
+ console.log(' Timeout on structure operation');
154
+ } else {
155
+ throw error;
156
+ }
157
+ }
158
+
159
+ // ============================================================================
160
+ // Done!
161
+ // ============================================================================
162
+
163
+ console.log('\n' + '='.repeat(60));
164
+ console.log('What is Lifebot?');
165
+ console.log('='.repeat(60));
166
+ console.log(`
167
+ Lifebot is the AI assistant built into iLiveMyLife. It can:
168
+
169
+ - Answer questions about your knowledge graph
170
+ - Search and find information across your nodes
171
+ - CREATE new nodes with titles and descriptions
172
+ - ORGANIZE information by creating structure
173
+ - Execute actions on your behalf
174
+
175
+ When you call askLifebot(), your message is sent to Lifebot which:
176
+ 1. Receives your question/request
177
+ 2. Has access to the current node's context
178
+ 3. Can perform actions (create, edit, etc.)
179
+ 4. Sends back a response
180
+
181
+ Tips:
182
+ - Enable Lifebot in node settings (add 'assist' tag)
183
+ - Use clear, specific requests
184
+ - For complex operations, increase timeout
185
+ - Check node settings if Lifebot doesn't respond
186
+ `);
187
+
188
+ // Free resources and close connections
189
+ graph.destroy();
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Real-time Subscriptions Example
3
+ *
4
+ * Shows how to subscribe to message and item changes.
5
+ *
6
+ * Run: node examples/subscriptions.mjs
7
+ */
8
+
9
+ import {
10
+ createGraphClient,
11
+ MESSAGE_CHANGE_TYPES,
12
+ ITEM_CHANGE_TYPES
13
+ } from '@ilivemylife/graph-sdk';
14
+
15
+ const graph = createGraphClient({
16
+ token: process.env.ILML_TOKEN
17
+ });
18
+
19
+ const nodeId = process.env.NODE_ID;
20
+
21
+ // Subscribe to messages with change type handling
22
+ console.log('Subscribing to messages...');
23
+ const unsubscribeMessages = await graph.subscribeToMessages(nodeId, (change, message) => {
24
+ if (change === MESSAGE_CHANGE_TYPES.added) {
25
+ console.log('New message:', message.content?.substring(0, 50));
26
+ } else if (change === MESSAGE_CHANGE_TYPES.edited) {
27
+ console.log('Message edited:', message.id);
28
+ } else if (change === MESSAGE_CHANGE_TYPES.deleted) {
29
+ console.log('Message deleted:', message.id);
30
+ }
31
+ });
32
+
33
+ // Subscribe to item changes with change type handling
34
+ console.log('Subscribing to items...');
35
+ const unsubscribeItems = await graph.subscribeToItems(nodeId, (change, item) => {
36
+ if (change === ITEM_CHANGE_TYPES.added) {
37
+ console.log('New item:', item.title);
38
+ } else if (change === ITEM_CHANGE_TYPES.edited) {
39
+ console.log('Item edited:', item.title);
40
+ } else if (change === ITEM_CHANGE_TYPES.movedIn) {
41
+ console.log('Item moved here:', item.title);
42
+ } else if (change === ITEM_CHANGE_TYPES.reorder) {
43
+ console.log('Item reordered:', item.title);
44
+ } else if (change === ITEM_CHANGE_TYPES.deleted) {
45
+ console.log('Item deleted:', item.id);
46
+ }
47
+ });
48
+
49
+ console.log('Listening for changes... Press Ctrl+C to stop');
50
+
51
+ // Clean up on exit
52
+ process.on('SIGINT', () => {
53
+ console.log('\nUnsubscribing...');
54
+ unsubscribeMessages();
55
+ unsubscribeItems();
56
+ process.exit(0);
57
+ });
58
+
59
+ // Keep process alive
60
+ setInterval(() => {}, 1000);
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@ilivemylife/graph-sdk",
3
+ "version": "1.0.0",
4
+ "description": "SDK and CLI for iLiveMyLife Knowledge Graph",
5
+ "license": "UNLICENSED",
6
+ "engines": {
7
+ "node": ">=18.0.0"
8
+ },
9
+ "sideEffects": false,
10
+ "type": "module",
11
+ "main": "./dist/client.cjs",
12
+ "module": "./dist/client.mjs",
13
+ "types": "./dist/client.d.ts",
14
+ "bin": {
15
+ "ilml": "./bin/ilml",
16
+ "ilml-mcp": "./dist/mcp-server.mjs"
17
+ },
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/client.d.ts",
21
+ "import": "./dist/client.mjs",
22
+ "require": "./dist/client.cjs"
23
+ },
24
+ "./queries": {
25
+ "types": "./dist/queries.d.ts",
26
+ "import": "./dist/queries.mjs",
27
+ "require": "./dist/queries.cjs"
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "bin",
33
+ "examples"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsup",
37
+ "prepublishOnly": "npm run build",
38
+ "release:patch": "npm version patch && npm publish --access public",
39
+ "release:minor": "npm version minor && npm publish --access public",
40
+ "release:major": "npm version major && npm publish --access public"
41
+ },
42
+ "keywords": [
43
+ "ilivemylife",
44
+ "ilml",
45
+ "knowledge-graph",
46
+ "pkm",
47
+ "graphql",
48
+ "sdk",
49
+ "cli",
50
+ "ai",
51
+ "lifebot"
52
+ ],
53
+ "author": "Ilya Sorokin <info@ilivemylife.io> (https://ilivemylife.io)",
54
+ "homepage": "https://ilivemylife.io",
55
+ "dependencies": {
56
+ "@apollo/client": "^3.8.0",
57
+ "@modelcontextprotocol/sdk": "^1.0.0",
58
+ "cross-fetch": "^4.0.0",
59
+ "graphql": "^16.8.0",
60
+ "graphql-ws": "^5.14.0",
61
+ "ws": "^8.18.0"
62
+ },
63
+ "devDependencies": {
64
+ "@types/ws": "^8.18.1",
65
+ "tsup": "^8.0.0",
66
+ "typescript": "^5.3.0"
67
+ }
68
+ }