@unifiedmemory/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.
@@ -0,0 +1,63 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+
5
+ const TOKEN_DIR = path.join(os.homedir(), '.um');
6
+ const TOKEN_FILE = path.join(TOKEN_DIR, 'auth.json');
7
+
8
+ export function saveToken(tokenData) {
9
+ // Create directory if it doesn't exist
10
+ if (!fs.existsSync(TOKEN_DIR)) {
11
+ fs.mkdirSync(TOKEN_DIR, { recursive: true });
12
+ }
13
+
14
+ // Preserve existing organization context if not explicitly overwritten
15
+ const existingData = getToken();
16
+ if (existingData && existingData.selectedOrg && !tokenData.selectedOrg) {
17
+ tokenData.selectedOrg = existingData.selectedOrg;
18
+ }
19
+
20
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify(tokenData, null, 2));
21
+ }
22
+
23
+ export function getToken() {
24
+ if (!fs.existsSync(TOKEN_FILE)) {
25
+ return null;
26
+ }
27
+
28
+ try {
29
+ const data = fs.readFileSync(TOKEN_FILE, 'utf8');
30
+ return JSON.parse(data);
31
+ } catch (error) {
32
+ return null;
33
+ }
34
+ }
35
+
36
+ export function clearToken() {
37
+ if (fs.existsSync(TOKEN_FILE)) {
38
+ fs.unlinkSync(TOKEN_FILE);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Update the selected organization context
44
+ * @param {Object|null} orgData - Organization data or null for personal context
45
+ */
46
+ export function updateSelectedOrg(orgData) {
47
+ const tokenData = getToken();
48
+ if (!tokenData) {
49
+ throw new Error('No token found. Please login first.');
50
+ }
51
+
52
+ tokenData.selectedOrg = orgData;
53
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify(tokenData, null, 2));
54
+ }
55
+
56
+ /**
57
+ * Get the currently selected organization context
58
+ * @returns {Object|null} Organization data or null if personal context
59
+ */
60
+ export function getSelectedOrg() {
61
+ const tokenData = getToken();
62
+ return tokenData?.selectedOrg || null;
63
+ }
@@ -0,0 +1,47 @@
1
+ import { getToken } from './token-storage.js';
2
+ import { isTokenExpired, refreshAccessToken } from './token-refresh.js';
3
+
4
+ /**
5
+ * Load token and refresh if expired
6
+ * @param {boolean} requireAuth - Whether to throw if not authenticated (default true)
7
+ * @returns {Promise<Object|null>} - Token data or null
8
+ * @throws {Error} - If not authenticated and requireAuth is true, or if refresh fails
9
+ */
10
+ export async function loadAndRefreshToken(requireAuth = true) {
11
+ const tokenData = getToken();
12
+
13
+ if (!tokenData) {
14
+ if (requireAuth) {
15
+ throw new Error(
16
+ 'Not authenticated. Please run: um login\n' +
17
+ 'No token found at ~/.um/auth.json'
18
+ );
19
+ }
20
+ return null;
21
+ }
22
+
23
+ // Check expiration
24
+ if (isTokenExpired(tokenData)) {
25
+ console.error('⚠️ Token expired, attempting refresh...');
26
+
27
+ if (tokenData.refresh_token) {
28
+ try {
29
+ const refreshed = await refreshAccessToken(tokenData);
30
+ console.error('✓ Token refreshed successfully');
31
+ return refreshed;
32
+ } catch (error) {
33
+ throw new Error(
34
+ 'Token expired and refresh failed. Please run: um login\n' +
35
+ `Refresh error: ${error.message}`
36
+ );
37
+ }
38
+ } else {
39
+ throw new Error(
40
+ 'Token expired and no refresh token available. Please run: um login\n' +
41
+ 'Hint: Try logging in again to get a new refresh token'
42
+ );
43
+ }
44
+ }
45
+
46
+ return tokenData;
47
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@unifiedmemory/cli",
3
+ "version": "1.0.0",
4
+ "description": "UnifiedMemory CLI - AI code assistant integration",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "um": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node index.js",
12
+ "build": "pkg . --targets node18-linux-x64,node18-macos-x64,node18-win-x64 --output dist/um"
13
+ },
14
+ "keywords": [
15
+ "ai",
16
+ "mcp",
17
+ "claude",
18
+ "cursor",
19
+ "unified-memory",
20
+ "cli",
21
+ "code-assistant",
22
+ "model-context-protocol"
23
+ ],
24
+ "author": "Episodic Solutions Limited <support@unifiedmemory.ai>",
25
+ "license": "PROPRIETARY",
26
+ "engines": {
27
+ "node": ">=18.0.0"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/Episodic-Solutions/um-cli/issues"
31
+ },
32
+ "homepage": "https://unifiedmemory.ai",
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "^1.0.0",
35
+ "chalk": "^5.3.0",
36
+ "commander": "^11.1.0",
37
+ "inquirer": "^13.0.1",
38
+ "open": "^10.0.3",
39
+ "axios": "^1.6.2",
40
+ "fs-extra": "^11.2.0"
41
+ },
42
+ "devDependencies": {
43
+ "pkg": "^5.8.1"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/unifiedmemory/um-cli.git"
48
+ }
49
+ }