pmpt-cli 1.14.0 → 1.14.2

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.
Files changed (2) hide show
  1. package/dist/mcp.js +61 -3
  2. package/package.json +1 -1
package/dist/mcp.js CHANGED
@@ -12,7 +12,7 @@ import { resolve, join } from 'path';
12
12
  import { existsSync, readFileSync, writeFileSync } from 'fs';
13
13
  import glob from 'fast-glob';
14
14
  import { createRequire } from 'module';
15
- import { isInitialized, loadConfig, getDocsDir } from './lib/config.js';
15
+ import { isInitialized, loadConfig, getDocsDir, getHistoryDir } from './lib/config.js';
16
16
  import { createFullSnapshot, getAllSnapshots, getTrackedFiles, resolveFullSnapshot } from './lib/history.js';
17
17
  import { computeQuality } from './lib/quality.js';
18
18
  import { getPlanProgress, savePlanProgress, savePlanDocuments, PLAN_QUESTIONS } from './lib/plan.js';
@@ -245,6 +245,64 @@ server.tool('pmpt_diff', 'Compare two versions, or a version against the current
245
245
  return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
246
246
  }
247
247
  });
248
+ server.tool('pmpt_squash', 'Remove empty snapshots (no file changes) and renumber remaining versions sequentially. Use this to clean up history when there are snapshots with no actual content changes.', {
249
+ projectPath: z.string().optional().describe('Project root path. Defaults to cwd.'),
250
+ }, async ({ projectPath }) => {
251
+ try {
252
+ const pp = resolveProjectPath(projectPath);
253
+ assertInitialized(pp);
254
+ const snapshots = getAllSnapshots(pp);
255
+ if (snapshots.length === 0) {
256
+ return { content: [{ type: 'text', text: 'No snapshots found.' }] };
257
+ }
258
+ const emptySnapshots = snapshots.filter(s => s.changedFiles && s.changedFiles.length === 0);
259
+ if (emptySnapshots.length === 0) {
260
+ return { content: [{ type: 'text', text: 'No empty snapshots found. History is clean.' }] };
261
+ }
262
+ // Delete empty snapshots
263
+ const { rmSync, renameSync } = await import('fs');
264
+ const { basename } = await import('path');
265
+ for (const snap of emptySnapshots) {
266
+ if (existsSync(snap.snapshotDir)) {
267
+ rmSync(snap.snapshotDir, { recursive: true });
268
+ }
269
+ }
270
+ // Renumber remaining snapshots
271
+ const historyDir = getHistoryDir(pp);
272
+ const remaining = getAllSnapshots(pp);
273
+ for (let i = 0; i < remaining.length; i++) {
274
+ const snap = remaining[i];
275
+ const newVersion = i + 1;
276
+ if (snap.version === newVersion)
277
+ continue;
278
+ const dirName = basename(snap.snapshotDir);
279
+ const newDirName = dirName.replace(/^v\d+/, `v${newVersion}`);
280
+ const newDir = join(historyDir, newDirName);
281
+ renameSync(snap.snapshotDir, newDir);
282
+ const metaPath = join(newDir, '.meta.json');
283
+ if (existsSync(metaPath)) {
284
+ const meta = JSON.parse(readFileSync(metaPath, 'utf-8'));
285
+ meta.version = newVersion;
286
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf-8');
287
+ }
288
+ }
289
+ const finalCount = getAllSnapshots(pp).length;
290
+ return {
291
+ content: [{
292
+ type: 'text',
293
+ text: [
294
+ `Squashed: removed ${emptySnapshots.length} empty snapshot(s).`,
295
+ `Remaining: ${finalCount} snapshot(s), renumbered v1-v${finalCount}.`,
296
+ '',
297
+ `Removed versions: ${emptySnapshots.map(s => `v${s.version}`).join(', ')}`,
298
+ ].join('\n'),
299
+ }],
300
+ };
301
+ }
302
+ catch (error) {
303
+ return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
304
+ }
305
+ });
248
306
  server.tool('pmpt_quality', 'Check project quality score and publish readiness.', { projectPath: z.string().optional().describe('Project root path. Defaults to cwd.') }, async ({ projectPath }) => {
249
307
  try {
250
308
  const pp = resolveProjectPath(projectPath);
@@ -524,7 +582,7 @@ server.tool('pmpt_log_decision', 'Record an architectural or technical decision
524
582
  return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
525
583
  }
526
584
  });
527
- server.tool('pmpt_publish', 'Publish the project to pmptwiki.com. Requires prior login via `pmpt login` in CLI. Packages project docs and history into a .pmpt file and uploads it.', {
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.', {
528
586
  projectPath: z.string().optional().describe('Project root path. Defaults to cwd.'),
529
587
  slug: z.string().describe('Project slug (3-50 chars, lowercase alphanumeric and hyphens).'),
530
588
  description: z.string().optional().describe('Project description (max 500 chars).'),
@@ -616,7 +674,7 @@ server.tool('pmpt_publish', 'Publish the project to pmptwiki.com. Requires prior
616
674
  return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], isError: true };
617
675
  }
618
676
  });
619
- server.tool('pmpt_graduate', 'Graduate a project on pmptwiki — archives it with a Hall of Fame badge. The project can no longer be updated. Requires prior login via `pmpt login`.', {
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.', {
620
678
  slug: z.string().describe('Project slug to graduate.'),
621
679
  note: z.string().optional().describe('Graduation note (e.g., "Reached 1000 users!").'),
622
680
  }, async ({ slug, note }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmpt-cli",
3
- "version": "1.14.0",
3
+ "version": "1.14.2",
4
4
  "description": "Record and share your AI-driven product development journey",
5
5
  "type": "module",
6
6
  "bin": {