pmpt-cli 1.12.2 → 1.12.4

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.
@@ -126,16 +126,17 @@ export function cmdDiff(v1, v2, pathOrOptions, maybeOptions) {
126
126
  p.log.error('No snapshots found.');
127
127
  process.exit(1);
128
128
  }
129
+ const versionList = snapshots.map(s => `v${s.version}`).join(', ');
129
130
  const fromIndex = snapshots.findIndex(s => s.version === fromVersion);
130
131
  if (fromIndex === -1) {
131
- p.log.error(`Version v${fromVersion} not found.`);
132
+ p.log.error(`Version v${fromVersion} not found. Available: ${versionList}`);
132
133
  process.exit(1);
133
134
  }
134
135
  let toIndex;
135
136
  if (!diffAgainstWorking) {
136
137
  toIndex = snapshots.findIndex(s => s.version === toVersion);
137
138
  if (toIndex === -1) {
138
- p.log.error(`Version v${toVersion} not found.`);
139
+ p.log.error(`Version v${toVersion} not found. Available: ${versionList}`);
139
140
  process.exit(1);
140
141
  }
141
142
  }
@@ -25,10 +25,12 @@ export async function cmdSquash(from, to, path) {
25
25
  p.log.error('No snapshots found.');
26
26
  process.exit(1);
27
27
  }
28
+ const versionList = snapshots.map(s => `v${s.version}`).join(', ');
28
29
  // Find snapshots to squash
29
30
  const toSquash = snapshots.filter(s => s.version >= fromVersion && s.version <= toVersion);
30
31
  if (toSquash.length < 2) {
31
32
  p.log.error(`Need at least 2 versions to squash. Found ${toSquash.length} in range v${fromVersion}-v${toVersion}.`);
33
+ p.log.info(`Available versions: ${versionList}`);
32
34
  process.exit(1);
33
35
  }
34
36
  p.intro('pmpt squash');
package/dist/index.js CHANGED
@@ -42,10 +42,16 @@ import { cmdExplore } from './commands/browse.js';
42
42
  import { cmdRecover } from './commands/recover.js';
43
43
  import { cmdDiff } from './commands/diff.js';
44
44
  import { cmdInternalSeed } from './commands/internal-seed.js';
45
+ import { trackCommand } from './lib/api.js';
45
46
  import { createRequire } from 'module';
46
47
  const require = createRequire(import.meta.url);
47
48
  const { version } = require('../package.json');
48
49
  const program = new Command();
50
+ // Track every command invocation (fire-and-forget)
51
+ program.hook('preAction', (thisCommand, actionCommand) => {
52
+ const commandName = actionCommand?.name() || thisCommand.name();
53
+ trackCommand(commandName);
54
+ });
49
55
  program
50
56
  .name('pmpt')
51
57
  .description('pmpt — Record and share your AI-driven product development journey')
@@ -56,19 +62,24 @@ Examples:
56
62
  $ pmpt plan Start product planning (5 questions → AI prompt)
57
63
  $ pmpt save Save snapshot of docs folder
58
64
  $ pmpt watch Auto-detect file changes
59
- $ pmpt history View version history
65
+ $ pmpt history (hist) View version history
60
66
  $ pmpt diff v1 v2 Compare two versions
61
67
  $ pmpt diff v3 Compare v3 to working copy
62
68
  $ pmpt squash v2 v5 Merge versions v2-v5 into v2
63
69
  $ pmpt export Export as .pmpt file (single JSON)
64
70
  $ pmpt import <file.pmpt> Import from .pmpt file
65
71
  $ pmpt login Authenticate with pmptwiki
66
- $ pmpt publish Publish project to pmptwiki
72
+ $ pmpt publish (pub) Publish project to pmptwiki
67
73
  $ pmpt update Quick re-publish (content only)
68
74
  $ pmpt clone <slug> Clone a project from pmptwiki
69
- $ pmpt explore Explore projects on pmptwiki.com
75
+ $ pmpt explore (exp) Explore projects on pmptwiki.com
70
76
  $ pmpt recover Recover damaged pmpt.md via AI
71
77
 
78
+ Workflow:
79
+ init → plan → save → publish Basic publishing flow
80
+ init → plan → watch Continuous development
81
+ login → publish → update Re-publish with updates
82
+
72
83
  Documentation: https://pmptwiki.com
73
84
  `);
74
85
  // Project tracking commands
@@ -87,10 +98,12 @@ program
87
98
  .action(cmdSave);
88
99
  program
89
100
  .command('status [path]')
101
+ .alias('st')
90
102
  .description('Check project status and tracked files')
91
103
  .action(cmdStatus);
92
104
  program
93
105
  .command('history [path]')
106
+ .alias('hist')
94
107
  .description('View saved version history')
95
108
  .option('-c, --compact', 'Show compact history (hide small changes)')
96
109
  .action(cmdHistory);
@@ -123,9 +136,12 @@ program
123
136
  .command('logout')
124
137
  .description('Clear saved GitHub authentication')
125
138
  .action(async () => {
139
+ const prompts = await import('@clack/prompts');
126
140
  const { clearAuth } = await import('./lib/auth.js');
141
+ prompts.intro('pmpt logout');
127
142
  clearAuth();
128
- console.log('Logged out successfully');
143
+ prompts.log.success('Logged out successfully.');
144
+ prompts.outro('');
129
145
  });
130
146
  // Platform commands
131
147
  program
@@ -134,6 +150,7 @@ program
134
150
  .action(cmdLogin);
135
151
  program
136
152
  .command('publish [path]')
153
+ .alias('pub')
137
154
  .description('Publish project to pmptwiki platform')
138
155
  .option('--non-interactive', 'Run without interactive prompts')
139
156
  .option('--meta-file <file>', 'JSON file with slug, description, tags, category')
@@ -163,6 +180,7 @@ program
163
180
  .action(cmdClone);
164
181
  program
165
182
  .command('explore')
183
+ .alias('exp')
166
184
  .description('Open pmptwiki.com to explore and search projects')
167
185
  .action(cmdExplore);
168
186
  program
@@ -174,4 +192,58 @@ program
174
192
  .command('internal-seed', { hidden: true })
175
193
  .requiredOption('--spec <file>', 'Seed spec JSON file')
176
194
  .action(cmdInternalSeed);
195
+ // "Did you mean?" helper
196
+ function levenshtein(a, b) {
197
+ const m = a.length, n = b.length;
198
+ const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)));
199
+ for (let i = 1; i <= m; i++) {
200
+ for (let j = 1; j <= n; j++) {
201
+ dp[i][j] = a[i - 1] === b[j - 1]
202
+ ? dp[i - 1][j - 1]
203
+ : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
204
+ }
205
+ }
206
+ return dp[m][n];
207
+ }
208
+ function suggestCommand(unknown) {
209
+ const available = program.commands
210
+ .filter(cmd => !cmd._hidden)
211
+ .flatMap(cmd => [cmd.name(), ...(cmd.aliases?.() ?? [])]);
212
+ let bestMatch = '';
213
+ let bestDist = Infinity;
214
+ for (const name of available) {
215
+ const dist = levenshtein(unknown, name);
216
+ if (dist < bestDist) {
217
+ bestDist = dist;
218
+ bestMatch = name;
219
+ }
220
+ }
221
+ console.error(`\n Unknown command: ${unknown}\n`);
222
+ if (bestDist <= 3 && bestMatch) {
223
+ console.error(` Did you mean \x1b[36mpmpt ${bestMatch}\x1b[0m?\n`);
224
+ }
225
+ console.error(` Run \x1b[36mpmpt --help\x1b[0m to see all commands.\n`);
226
+ process.exit(1);
227
+ }
228
+ // Handle unknown subcommands and Quick Start
229
+ program.on('command:*', (operands) => {
230
+ suggestCommand(operands[0]);
231
+ });
232
+ // Show Quick Start when no arguments provided
233
+ const args = process.argv.slice(2);
234
+ if (args.length === 0) {
235
+ console.log(`
236
+ pmpt v${version} — Record and share your AI-driven product development journey
237
+
238
+ Quick Start:
239
+ $ pmpt init 1. Initialize project
240
+ $ pmpt plan 2. Generate AI prompt (copied to clipboard)
241
+ $ pmpt save 3. Save snapshot after progress
242
+ $ pmpt publish 4. Share on pmptwiki.com
243
+
244
+ Run \x1b[36mpmpt --help\x1b[0m for all commands.
245
+ Documentation: https://pmptwiki.com
246
+ `);
247
+ process.exit(0);
248
+ }
177
249
  program.parse();
package/dist/lib/api.js CHANGED
@@ -92,3 +92,14 @@ export function trackClone(slug) {
92
92
  body: JSON.stringify({ slug }),
93
93
  }).catch(() => { });
94
94
  }
95
+ /**
96
+ * Fire-and-forget CLI command usage tracking.
97
+ * Never throws — failures are silently ignored.
98
+ */
99
+ export function trackCommand(command) {
100
+ fetch(`${API_BASE}/metrics/command`, {
101
+ method: 'POST',
102
+ headers: { 'Content-Type': 'application/json' },
103
+ body: JSON.stringify({ command }),
104
+ }).catch(() => { });
105
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmpt-cli",
3
- "version": "1.12.2",
3
+ "version": "1.12.4",
4
4
  "description": "Record and share your AI-driven product development journey",
5
5
  "type": "module",
6
6
  "bin": {