@unifiedmemory/cli 1.3.6 → 1.3.9
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/.github/workflows/test-and-publish.yml +6 -2
- package/index.js +8 -2
- package/lib/token-refresh.js +27 -3
- package/lib/welcome.js +32 -4
- package/package.json +1 -1
|
@@ -83,8 +83,12 @@ jobs:
|
|
|
83
83
|
run: |
|
|
84
84
|
git config user.name "github-actions[bot]"
|
|
85
85
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
86
|
-
git
|
|
87
|
-
|
|
86
|
+
if ! git ls-remote --tags origin | grep -q "refs/tags/v${{ steps.version-check.outputs.current }}"; then
|
|
87
|
+
git tag v${{ steps.version-check.outputs.current }}
|
|
88
|
+
git push origin v${{ steps.version-check.outputs.current }}
|
|
89
|
+
else
|
|
90
|
+
echo "Tag v${{ steps.version-check.outputs.current }} already exists, skipping"
|
|
91
|
+
fi
|
|
88
92
|
|
|
89
93
|
- name: Skip publish notification
|
|
90
94
|
if: steps.version-check.outputs.version_changed == 'false'
|
package/index.js
CHANGED
|
@@ -4,6 +4,9 @@ import { Command } from 'commander';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
import { dirname, join } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
7
10
|
import { login } from './commands/login.js';
|
|
8
11
|
import { init } from './commands/init.js';
|
|
9
12
|
import { switchOrg, showOrg } from './commands/org.js';
|
|
@@ -13,12 +16,15 @@ import { getSelectedOrg } from './lib/token-storage.js';
|
|
|
13
16
|
import { loadAndRefreshToken } from './lib/token-validation.js';
|
|
14
17
|
import { showWelcome } from './lib/welcome.js';
|
|
15
18
|
|
|
19
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
|
|
21
|
+
|
|
16
22
|
const program = new Command();
|
|
17
23
|
|
|
18
24
|
program
|
|
19
25
|
.name('um')
|
|
20
26
|
.description('UnifiedMemory CLI - AI code assistant integration')
|
|
21
|
-
.version(
|
|
27
|
+
.version(packageJson.version);
|
|
22
28
|
|
|
23
29
|
// Unified command (primary)
|
|
24
30
|
program
|
|
@@ -199,7 +205,7 @@ noteCommand
|
|
|
199
205
|
|
|
200
206
|
// Show welcome splash if no command provided
|
|
201
207
|
if (process.argv.length === 2) {
|
|
202
|
-
showWelcome();
|
|
208
|
+
await showWelcome();
|
|
203
209
|
program.help();
|
|
204
210
|
}
|
|
205
211
|
|
package/lib/token-refresh.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getToken, saveToken } from './token-storage.js';
|
|
2
2
|
import { config } from './config.js';
|
|
3
3
|
import { parseJWT } from './jwt-utils.js';
|
|
4
|
+
import { getOrgScopedToken } from './clerk-api.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Check if token has expired
|
|
@@ -71,13 +72,36 @@ export async function refreshAccessToken(tokenData) {
|
|
|
71
72
|
|
|
72
73
|
const newTokenData = await response.json();
|
|
73
74
|
|
|
74
|
-
// Parse
|
|
75
|
-
const
|
|
75
|
+
// Parse refreshed JWT
|
|
76
|
+
const refreshedToken = newTokenData.id_token || newTokenData.access_token;
|
|
77
|
+
let finalIdToken = newTokenData.id_token;
|
|
78
|
+
let decoded = parseJWT(refreshedToken);
|
|
79
|
+
|
|
80
|
+
// Debug: log what we got from refresh
|
|
81
|
+
console.error(` Refreshed token has sid: ${decoded?.sid ? 'yes' : 'no'}`);
|
|
82
|
+
console.error(` selectedOrg: ${tokenData.selectedOrg?.id || 'none'}`);
|
|
83
|
+
|
|
84
|
+
// If we have org context, get org-scoped token to ensure JWT has org claims
|
|
85
|
+
if (tokenData.selectedOrg?.id && decoded?.sid) {
|
|
86
|
+
try {
|
|
87
|
+
const orgToken = await getOrgScopedToken(
|
|
88
|
+
decoded.sid,
|
|
89
|
+
tokenData.selectedOrg.id,
|
|
90
|
+
refreshedToken
|
|
91
|
+
);
|
|
92
|
+
finalIdToken = orgToken.jwt;
|
|
93
|
+
decoded = parseJWT(orgToken.jwt);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
// Log warning but continue with base token
|
|
96
|
+
// The subsequent API call may fail, prompting re-login
|
|
97
|
+
console.error(`⚠️ Could not refresh org-scoped token: ${error.message}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
76
100
|
|
|
77
101
|
// Build updated token object, preserving selectedOrg
|
|
78
102
|
const updatedToken = {
|
|
79
103
|
accessToken: newTokenData.access_token,
|
|
80
|
-
idToken:
|
|
104
|
+
idToken: finalIdToken,
|
|
81
105
|
tokenType: newTokenData.token_type || 'Bearer',
|
|
82
106
|
expiresIn: newTokenData.expires_in,
|
|
83
107
|
receivedAt: Date.now(),
|
package/lib/welcome.js
CHANGED
|
@@ -2,22 +2,50 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
3
|
import { dirname, join } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
|
+
import axios from 'axios';
|
|
5
6
|
|
|
6
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
8
|
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
|
|
8
9
|
const version = packageJson.version;
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const PACKAGE_NAME = '@unifiedmemory/cli';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check npm registry for latest version (non-blocking)
|
|
15
|
+
* @returns {Promise<{latest: string, isOutdated: boolean} | null>}
|
|
16
|
+
*/
|
|
17
|
+
export async function checkLatestVersion() {
|
|
18
|
+
try {
|
|
19
|
+
const response = await axios.get(
|
|
20
|
+
`https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
|
|
21
|
+
{ timeout: 2000 }
|
|
22
|
+
);
|
|
23
|
+
const latest = response.data.version;
|
|
24
|
+
const isOutdated = latest !== version;
|
|
25
|
+
return { latest, isOutdated };
|
|
26
|
+
} catch {
|
|
27
|
+
return null; // Silently fail - don't block CLI
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function showWelcome() {
|
|
14
32
|
const gray = chalk.gray;
|
|
15
33
|
const white = chalk.white;
|
|
34
|
+
const yellow = chalk.yellow;
|
|
16
35
|
|
|
17
36
|
console.log('');
|
|
18
37
|
console.log(white.bold(' UnifiedMemory CLI ') + gray(`v${version}`));
|
|
19
38
|
console.log(gray(' AI-powered knowledge assistant'));
|
|
20
39
|
console.log('');
|
|
40
|
+
|
|
41
|
+
// Check for updates (non-blocking with short timeout)
|
|
42
|
+
const versionInfo = await checkLatestVersion();
|
|
43
|
+
if (versionInfo?.isOutdated) {
|
|
44
|
+
console.log(yellow(' ⚠ Update available: ') + white(`v${versionInfo.latest}`));
|
|
45
|
+
console.log(gray(' Run: ') + white('npm install -g @unifiedmemory/cli'));
|
|
46
|
+
console.log('');
|
|
47
|
+
}
|
|
48
|
+
|
|
21
49
|
console.log(white(' Quick Start:'));
|
|
22
50
|
console.log(gray(' um init ') + white('Initialize in current project'));
|
|
23
51
|
console.log(gray(' um status ') + white('Check configuration'));
|