pmpt-cli 1.14.1 → 1.14.3
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/index.js +5 -0
- package/dist/lib/update-check.js +84 -0
- package/dist/mcp.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ import { cmdDiff } from './commands/diff.js';
|
|
|
45
45
|
import { cmdInternalSeed } from './commands/internal-seed.js';
|
|
46
46
|
import { cmdMcpSetup } from './commands/mcp-setup.js';
|
|
47
47
|
import { trackCommand } from './lib/api.js';
|
|
48
|
+
import { checkForUpdates } from './lib/update-check.js';
|
|
48
49
|
import { createRequire } from 'module';
|
|
49
50
|
const require = createRequire(import.meta.url);
|
|
50
51
|
const { version } = require('../package.json');
|
|
@@ -54,6 +55,10 @@ program.hook('preAction', (thisCommand, actionCommand) => {
|
|
|
54
55
|
const commandName = actionCommand?.name() || thisCommand.name();
|
|
55
56
|
trackCommand(commandName);
|
|
56
57
|
});
|
|
58
|
+
// Check for updates after command finishes
|
|
59
|
+
program.hook('postAction', () => {
|
|
60
|
+
checkForUpdates(version);
|
|
61
|
+
});
|
|
57
62
|
program
|
|
58
63
|
.name('pmpt')
|
|
59
64
|
.description('pmpt — Record and share your AI-driven product development journey')
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import https from 'https';
|
|
5
|
+
const CACHE_DIR = join(homedir(), '.pmpt');
|
|
6
|
+
const CACHE_FILE = join(CACHE_DIR, 'update-check.json');
|
|
7
|
+
const CHECK_INTERVAL = 1000 * 60 * 60 * 24; // 24 hours
|
|
8
|
+
function readCache() {
|
|
9
|
+
try {
|
|
10
|
+
if (!existsSync(CACHE_FILE))
|
|
11
|
+
return null;
|
|
12
|
+
return JSON.parse(readFileSync(CACHE_FILE, 'utf-8'));
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function writeCache(data) {
|
|
19
|
+
try {
|
|
20
|
+
if (!existsSync(CACHE_DIR))
|
|
21
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
22
|
+
writeFileSync(CACHE_FILE, JSON.stringify(data));
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
}
|
|
26
|
+
function fetchLatestVersion() {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const req = https.get('https://registry.npmjs.org/pmpt-cli/latest', { headers: { Accept: 'application/json' }, timeout: 3000 }, (res) => {
|
|
29
|
+
let body = '';
|
|
30
|
+
res.on('data', (d) => (body += d));
|
|
31
|
+
res.on('end', () => {
|
|
32
|
+
try {
|
|
33
|
+
resolve(JSON.parse(body).version || null);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
resolve(null);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
req.on('error', () => resolve(null));
|
|
41
|
+
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function compareVersions(current, latest) {
|
|
45
|
+
const c = current.split('.').map(Number);
|
|
46
|
+
const l = latest.split('.').map(Number);
|
|
47
|
+
for (let i = 0; i < 3; i++) {
|
|
48
|
+
if ((l[i] || 0) > (c[i] || 0))
|
|
49
|
+
return true;
|
|
50
|
+
if ((l[i] || 0) < (c[i] || 0))
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check for updates and print a notification if a newer version is available.
|
|
57
|
+
* Non-blocking, silent on failure.
|
|
58
|
+
*/
|
|
59
|
+
export async function checkForUpdates(currentVersion) {
|
|
60
|
+
try {
|
|
61
|
+
const cache = readCache();
|
|
62
|
+
let latest = null;
|
|
63
|
+
if (cache && Date.now() - cache.checkedAt < CHECK_INTERVAL) {
|
|
64
|
+
latest = cache.latest;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
latest = await fetchLatestVersion();
|
|
68
|
+
if (latest)
|
|
69
|
+
writeCache({ latest, checkedAt: Date.now() });
|
|
70
|
+
}
|
|
71
|
+
if (latest && compareVersions(currentVersion, latest)) {
|
|
72
|
+
const msg = [
|
|
73
|
+
'',
|
|
74
|
+
` \x1b[33m┌──────────────────────────────────────────┐\x1b[0m`,
|
|
75
|
+
` \x1b[33m│\x1b[0m Update available: \x1b[90m${currentVersion}\x1b[0m → \x1b[32m${latest}\x1b[0m${' '.repeat(Math.max(0, 14 - currentVersion.length - latest.length))}\x1b[33m│\x1b[0m`,
|
|
76
|
+
` \x1b[33m│\x1b[0m Run \x1b[36mnpm install -g pmpt-cli\x1b[0m to update \x1b[33m│\x1b[0m`,
|
|
77
|
+
` \x1b[33m└──────────────────────────────────────────┘\x1b[0m`,
|
|
78
|
+
'',
|
|
79
|
+
].join('\n');
|
|
80
|
+
console.error(msg);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch { }
|
|
84
|
+
}
|
package/dist/mcp.js
CHANGED
|
@@ -582,7 +582,7 @@ server.tool('pmpt_log_decision', 'Record an architectural or technical decision
|
|
|
582
582
|
return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
|
|
583
583
|
}
|
|
584
584
|
});
|
|
585
|
-
server.tool('pmpt_publish', 'Publish the project to pmptwiki.com.
|
|
585
|
+
server.tool('pmpt_publish', 'Publish the project to pmptwiki.com. This tool handles everything non-interactively — just provide the slug and optional metadata. Note: the user must have run `pmpt login` once before (check if auth exists). If not logged in, ask the user to run `pmpt login` in their terminal, then retry this tool.', {
|
|
586
586
|
projectPath: z.string().optional().describe('Project root path. Defaults to cwd.'),
|
|
587
587
|
slug: z.string().describe('Project slug (3-50 chars, lowercase alphanumeric and hyphens).'),
|
|
588
588
|
description: z.string().optional().describe('Project description (max 500 chars).'),
|
|
@@ -674,7 +674,7 @@ server.tool('pmpt_publish', 'Publish the project to pmptwiki.com. Requires prior
|
|
|
674
674
|
return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
|
|
675
675
|
}
|
|
676
676
|
});
|
|
677
|
-
server.tool('pmpt_graduate', 'Graduate a project on pmptwiki — archives it with a Hall of Fame badge. The project can no longer be updated.
|
|
677
|
+
server.tool('pmpt_graduate', 'Graduate a project on pmptwiki — archives it with a Hall of Fame badge. The project can no longer be updated. Non-interactive. User must have run `pmpt login` once before.', {
|
|
678
678
|
slug: z.string().describe('Project slug to graduate.'),
|
|
679
679
|
note: z.string().optional().describe('Graduation note (e.g., "Reached 1000 users!").'),
|
|
680
680
|
}, async ({ slug, note }) => {
|