@lanonasis/cli 3.7.4 → 3.7.5

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/dist/utils/api.js CHANGED
@@ -2,7 +2,6 @@ import axios from 'axios';
2
2
  import chalk from 'chalk';
3
3
  import { randomUUID } from 'crypto';
4
4
  import { CLIConfig } from './config.js';
5
- import { ensureApiKeyHash } from './hash-utils.js';
6
5
  export class APIClient {
7
6
  client;
8
7
  config;
@@ -31,7 +30,8 @@ export class APIClient {
31
30
  const vendorKey = this.config.getVendorKey();
32
31
  if (vendorKey) {
33
32
  // Vendor key authentication (validated server-side)
34
- config.headers['X-API-Key'] = ensureApiKeyHash(vendorKey);
33
+ // Send raw key - server handles hashing for comparison
34
+ config.headers['X-API-Key'] = vendorKey;
35
35
  config.headers['X-Auth-Method'] = 'vendor_key';
36
36
  }
37
37
  else if (token) {
@@ -100,61 +100,62 @@ export class APIClient {
100
100
  return response.data;
101
101
  }
102
102
  // Memory operations - aligned with existing schema
103
+ // All memory endpoints use /api/v1/memory path
103
104
  async createMemory(data) {
104
- const response = await this.client.post('/memory', data);
105
+ const response = await this.client.post('/api/v1/memory', data);
105
106
  return response.data;
106
107
  }
107
108
  async getMemories(params = {}) {
108
- const response = await this.client.get('/memory', { params });
109
+ const response = await this.client.get('/api/v1/memory', { params });
109
110
  return response.data;
110
111
  }
111
112
  async getMemory(id) {
112
- const response = await this.client.get(`/memory/${id}`);
113
+ const response = await this.client.get(`/api/v1/memory/${id}`);
113
114
  return response.data;
114
115
  }
115
116
  async updateMemory(id, data) {
116
- const response = await this.client.put(`/memory/${id}`, data);
117
+ const response = await this.client.put(`/api/v1/memory/${id}`, data);
117
118
  return response.data;
118
119
  }
119
120
  async deleteMemory(id) {
120
- await this.client.delete(`/memory/${id}`);
121
+ await this.client.delete(`/api/v1/memory/${id}`);
121
122
  }
122
123
  async searchMemories(query, options = {}) {
123
- const response = await this.client.post('/memory/search', {
124
+ const response = await this.client.post('/api/v1/memory/search', {
124
125
  query,
125
126
  ...options
126
127
  });
127
128
  return response.data;
128
129
  }
129
130
  async getMemoryStats() {
130
- const response = await this.client.get('/memory/stats');
131
+ const response = await this.client.get('/api/v1/memory/stats');
131
132
  return response.data;
132
133
  }
133
134
  async bulkDeleteMemories(memoryIds) {
134
- const response = await this.client.post('/memory/bulk/delete', {
135
+ const response = await this.client.post('/api/v1/memory/bulk/delete', {
135
136
  memory_ids: memoryIds
136
137
  });
137
138
  return response.data;
138
139
  }
139
140
  // Topic operations - working with existing memory_topics table
140
141
  async createTopic(data) {
141
- const response = await this.client.post('/topics', data);
142
+ const response = await this.client.post('/api/v1/topics', data);
142
143
  return response.data;
143
144
  }
144
145
  async getTopics() {
145
- const response = await this.client.get('/topics');
146
+ const response = await this.client.get('/api/v1/topics');
146
147
  return response.data;
147
148
  }
148
149
  async getTopic(id) {
149
- const response = await this.client.get(`/topics/${id}`);
150
+ const response = await this.client.get(`/api/v1/topics/${id}`);
150
151
  return response.data;
151
152
  }
152
153
  async updateTopic(id, data) {
153
- const response = await this.client.put(`/topics/${id}`, data);
154
+ const response = await this.client.put(`/api/v1/topics/${id}`, data);
154
155
  return response.data;
155
156
  }
156
157
  async deleteTopic(id) {
157
- await this.client.delete(`/topics/${id}`);
158
+ await this.client.delete(`/api/v1/topics/${id}`);
158
159
  }
159
160
  // Health check
160
161
  async getHealth() {
@@ -168,9 +168,11 @@ export class CLIConfig {
168
168
  }
169
169
  }
170
170
  getApiUrl() {
171
- return process.env.MEMORY_API_URL ||
171
+ const baseUrl = process.env.MEMORY_API_URL ||
172
172
  this.config.apiUrl ||
173
- 'https://api.lanonasis.com';
173
+ 'https://mcp.lanonasis.com';
174
+ // Ensure we don't double-append /api/v1 - strip it if present since APIClient adds it
175
+ return baseUrl.replace(/\/api\/v1\/?$/, '');
174
176
  }
175
177
  // Get API URLs with fallbacks - try multiple endpoints
176
178
  getApiUrlsWithFallbacks() {
@@ -190,8 +192,8 @@ export class CLIConfig {
190
192
  if (!this.config.discoveredServices) {
191
193
  this.config.discoveredServices = {
192
194
  auth_base: 'https://auth.lanonasis.com',
193
- memory_base: 'https://mcp.lanonasis.com/api/v1',
194
- mcp_base: 'https://mcp.lanonasis.com/api/v1',
195
+ memory_base: 'https://mcp.lanonasis.com', // Base URL without /api/v1
196
+ mcp_base: 'https://mcp.lanonasis.com/api/v1', // Full MCP REST path
195
197
  mcp_ws_base: 'wss://mcp.lanonasis.com/ws',
196
198
  mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events',
197
199
  project_scope: 'lanonasis-maas'
@@ -243,13 +245,16 @@ export class CLIConfig {
243
245
  if (authBase.includes('localhost') || authBase.includes('127.0.0.1')) {
244
246
  authBase = 'https://auth.lanonasis.com';
245
247
  }
246
- const memoryBase = discovered.endpoints?.http || 'https://mcp.lanonasis.com/api/v1';
248
+ // Memory base should be the MCP base URL without /api/v1 suffix
249
+ // The API client will append the path as needed
250
+ const rawMemoryBase = discovered.endpoints?.http || 'https://mcp.lanonasis.com/api/v1';
251
+ const memoryBase = rawMemoryBase.replace(/\/api\/v1\/?$/, '') || 'https://mcp.lanonasis.com';
247
252
  this.config.discoveredServices = {
248
253
  auth_base: authBase || 'https://auth.lanonasis.com',
249
254
  memory_base: memoryBase,
250
- mcp_base: memoryBase,
255
+ mcp_base: `${memoryBase}/api/v1`, // Full path for MCP REST calls
251
256
  mcp_ws_base: discovered.endpoints?.websocket || 'wss://mcp.lanonasis.com/ws',
252
- mcp_sse_base: discovered.endpoints?.sse || 'https://mcp.lanonasis.com/api/v1/events',
257
+ mcp_sse_base: discovered.endpoints?.sse || `${memoryBase}/api/v1/events`,
253
258
  project_scope: 'lanonasis-maas'
254
259
  };
255
260
  this.config.apiUrl = memoryBase;
@@ -366,8 +371,8 @@ export class CLIConfig {
366
371
  const nodeEnv = (process.env.NODE_ENV ?? '').toLowerCase();
367
372
  const isDevEnvironment = nodeEnv === 'development' || nodeEnv === 'test';
368
373
  const defaultAuthBase = isDevEnvironment ? 'http://localhost:4000' : 'https://auth.lanonasis.com';
369
- const defaultMemoryBase = isDevEnvironment ? 'http://localhost:4000/api/v1' : 'https://mcp.lanonasis.com/api/v1';
370
- const defaultMcpBase = isDevEnvironment ? 'http://localhost:4100/api/v1' : 'https://mcp.lanonasis.com/api/v1';
374
+ const defaultMemoryBase = isDevEnvironment ? 'http://localhost:4000' : 'https://mcp.lanonasis.com'; // Base URL without /api/v1
375
+ const defaultMcpBase = isDevEnvironment ? 'http://localhost:4100/api/v1' : 'https://mcp.lanonasis.com/api/v1'; // Full MCP REST path
371
376
  const defaultMcpWsBase = isDevEnvironment ? 'ws://localhost:4100/ws' : 'wss://mcp.lanonasis.com/ws';
372
377
  const defaultMcpSseBase = isDevEnvironment ? 'http://localhost:4100/api/v1/events' : 'https://mcp.lanonasis.com/api/v1/events';
373
378
  const endpoints = {
@@ -433,8 +438,8 @@ export class CLIConfig {
433
438
  }
434
439
  const currentServices = this.config.discoveredServices ?? {
435
440
  auth_base: 'https://auth.lanonasis.com',
436
- memory_base: 'https://mcp.lanonasis.com/api/v1',
437
- mcp_base: 'https://mcp.lanonasis.com/api/v1',
441
+ memory_base: 'https://mcp.lanonasis.com', // Base URL without /api/v1
442
+ mcp_base: 'https://mcp.lanonasis.com/api/v1', // Full MCP REST path
438
443
  mcp_ws_base: 'wss://mcp.lanonasis.com/ws',
439
444
  mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events',
440
445
  project_scope: 'lanonasis-maas'
@@ -456,9 +456,11 @@ export class MCPClient {
456
456
  // Use the proper SSE endpoint from config
457
457
  const sseUrl = this.config.getMCPSSEUrl() ?? `${serverUrl}/events`;
458
458
  const token = this.config.get('token');
459
- if (token) {
459
+ const vendorKey = this.config.get('vendorKey');
460
+ const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
461
+ if (authKey) {
460
462
  // EventSource doesn't support headers directly, append token to URL
461
- this.sseConnection = new EventSource(`${sseUrl}?token=${encodeURIComponent(token)}`);
463
+ this.sseConnection = new EventSource(`${sseUrl}?token=${encodeURIComponent(authKey)}`);
462
464
  this.sseConnection.onmessage = (event) => {
463
465
  try {
464
466
  const data = JSON.parse(event.data);
@@ -478,7 +480,9 @@ export class MCPClient {
478
480
  */
479
481
  async initializeWebSocket(wsUrl) {
480
482
  const token = this.config.get('token');
481
- if (!token) {
483
+ const vendorKey = this.config.get('vendorKey');
484
+ const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
485
+ if (!authKey) {
482
486
  throw new Error('API key required for WebSocket mode. Set LANONASIS_API_KEY or login first.');
483
487
  }
484
488
  return new Promise((resolve, reject) => {
@@ -491,8 +495,8 @@ export class MCPClient {
491
495
  // Create new WebSocket connection with authentication
492
496
  this.wsConnection = new WebSocket(wsUrl, [], {
493
497
  headers: {
494
- 'Authorization': `Bearer ${token}`,
495
- 'X-API-Key': token
498
+ 'Authorization': `Bearer ${authKey}`,
499
+ 'X-API-Key': authKey
496
500
  }
497
501
  });
498
502
  this.wsConnection.on('open', () => {
@@ -624,15 +628,17 @@ export class MCPClient {
624
628
  async checkRemoteHealth() {
625
629
  const apiUrl = this.config.getMCPRestUrl() ?? 'https://mcp.lanonasis.com/api/v1';
626
630
  const token = this.config.get('token');
627
- if (!token) {
631
+ const vendorKey = this.config.get('vendorKey');
632
+ const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
633
+ if (!authKey) {
628
634
  throw new Error('No authentication token available');
629
635
  }
630
636
  try {
631
637
  const axios = (await import('axios')).default;
632
638
  await axios.get(`${apiUrl}/health`, {
633
639
  headers: {
634
- 'Authorization': `Bearer ${token}`,
635
- 'x-api-key': String(token)
640
+ 'Authorization': `Bearer ${authKey}`,
641
+ 'X-API-Key': authKey
636
642
  },
637
643
  timeout: 5000
638
644
  });
@@ -749,7 +755,9 @@ export class MCPClient {
749
755
  async callRemoteTool(toolName, args) {
750
756
  const apiUrl = this.config.getMCPRestUrl() ?? 'https://mcp.lanonasis.com/api/v1';
751
757
  const token = this.config.get('token');
752
- if (!token) {
758
+ const vendorKey = this.config.get('vendorKey');
759
+ const authKey = token || vendorKey || process.env.LANONASIS_API_KEY;
760
+ if (!authKey) {
753
761
  throw new Error('Authentication required. Run "lanonasis auth login" first.');
754
762
  }
755
763
  // Map MCP tool names to REST API endpoints
@@ -805,8 +813,8 @@ export class MCPClient {
805
813
  method: mapping.method,
806
814
  url: `${apiUrl}${endpoint}`,
807
815
  headers: {
808
- 'Authorization': `Bearer ${token}`,
809
- 'x-api-key': String(token),
816
+ 'Authorization': `Bearer ${authKey}`,
817
+ 'X-API-Key': authKey,
810
818
  'Content-Type': 'application/json'
811
819
  },
812
820
  data: mapping.transform ? mapping.transform(args) : undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lanonasis/cli",
3
- "version": "3.7.4",
3
+ "version": "3.7.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -46,7 +46,7 @@
46
46
  "@jest/globals": "^29.7.0",
47
47
  "@types/cli-progress": "^3.11.6",
48
48
  "@types/inquirer": "^9.0.7",
49
- "@types/node": "^22.10.2",
49
+ "@types/node": "^22.19.3",
50
50
  "@types/ws": "^8.5.12",
51
51
  "jest": "^29.7.0",
52
52
  "rimraf": "^5.0.7",