pmpt-cli 1.14.9 → 1.14.11

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.
@@ -56,6 +56,7 @@ export async function cmdEdit() {
56
56
  `Category: ${categoryLabel}`,
57
57
  project.productUrl ? `Product: ${project.productUrl}` : 'Product: (none)',
58
58
  `Visibility: ${project.unlisted ? 'Unlisted' : 'Listed'}`,
59
+ `Related: ${project.related?.length ? project.related.join(', ') : '(none)'}`,
59
60
  ].join('\n'), 'Current Settings');
60
61
  // Pick fields to edit
61
62
  const fields = await p.multiselect({
@@ -66,6 +67,7 @@ export async function cmdEdit() {
66
67
  { value: 'category', label: 'Category' },
67
68
  { value: 'productUrl', label: 'Product Link' },
68
69
  { value: 'unlisted', label: 'Visibility (listed/unlisted)' },
70
+ { value: 'related', label: 'Related Projects' },
69
71
  ],
70
72
  });
71
73
  if (p.isCancel(fields)) {
@@ -174,6 +176,19 @@ export async function cmdEdit() {
174
176
  }
175
177
  updates.unlisted = !!v;
176
178
  }
179
+ if (selected.has('related')) {
180
+ const v = await p.text({
181
+ message: 'Related project slugs (comma-separated):',
182
+ defaultValue: project.related?.join(', ') || '',
183
+ placeholder: 'e.g., my-api, my-cli, my-docs',
184
+ });
185
+ if (p.isCancel(v)) {
186
+ p.cancel('Cancelled');
187
+ process.exit(0);
188
+ }
189
+ const slugs = v.split(',').map((s) => s.trim()).filter(Boolean);
190
+ updates.related = slugs;
191
+ }
177
192
  const s2 = p.spinner();
178
193
  s2.start('Updating...');
179
194
  try {
@@ -1,7 +1,7 @@
1
1
  import * as p from '@clack/prompts';
2
- import { existsSync, readFileSync } from 'fs';
3
- import { resolve } from 'path';
4
- import { initializeProject, isInitialized } from '../lib/config.js';
2
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
3
+ import { resolve, basename, join } from 'path';
4
+ import { initializeProject, isInitialized, getDocsDir } from '../lib/config.js';
5
5
  import { isGitRepo, getGitInfo, formatGitInfo, getCommitCount } from '../lib/git.js';
6
6
  import { cmdPlan } from './plan.js';
7
7
  import { scanProject, scanResultToAnswers } from '../lib/scanner.js';
@@ -232,6 +232,7 @@ export async function cmdInit(path, options) {
232
232
  await cmdPlan(projectPath);
233
233
  }
234
234
  else {
235
+ ensureMinimalDocs(projectPath);
235
236
  p.outro('Ready! Run `pmpt plan` when you want to start.');
236
237
  }
237
238
  }
@@ -246,6 +247,7 @@ export async function cmdInit(path, options) {
246
247
  await cmdPlan(projectPath);
247
248
  }
248
249
  else {
250
+ ensureMinimalDocs(projectPath);
249
251
  p.outro('Ready! Run `pmpt plan` when you want to start.');
250
252
  }
251
253
  }
@@ -256,3 +258,23 @@ export async function cmdInit(path, options) {
256
258
  process.exit(1);
257
259
  }
258
260
  }
261
+ /** Create minimal pmpt.md so progress tracking works from the start */
262
+ function ensureMinimalDocs(projectPath) {
263
+ const docsDir = getDocsDir(projectPath);
264
+ const pmptMdPath = join(docsDir, 'pmpt.md');
265
+ if (existsSync(pmptMdPath))
266
+ return;
267
+ const name = basename(projectPath);
268
+ const skeleton = [
269
+ `# ${name}`,
270
+ '',
271
+ '## Progress',
272
+ '- Project initialized',
273
+ '',
274
+ '## Snapshot Log',
275
+ '',
276
+ '## Decisions',
277
+ '',
278
+ ].join('\n');
279
+ writeFileSync(pmptMdPath, skeleton, 'utf-8');
280
+ }
@@ -1,8 +1,9 @@
1
1
  import * as p from '@clack/prompts';
2
- import { resolve, join } from 'path';
2
+ import { resolve, join, basename } from 'path';
3
3
  import { existsSync, statSync, readFileSync, writeFileSync } from 'fs';
4
- import { isInitialized, getDocsDir } from '../lib/config.js';
4
+ import { isInitialized, getDocsDir, loadConfig } from '../lib/config.js';
5
5
  import { createFullSnapshot, getTrackedFiles, getAllSnapshots } from '../lib/history.js';
6
+ import { getPlanProgress } from '../lib/plan.js';
6
7
  export async function cmdSave(fileOrPath) {
7
8
  const projectPath = fileOrPath && existsSync(fileOrPath) && statSync(fileOrPath).isDirectory()
8
9
  ? resolve(fileOrPath)
@@ -21,6 +22,26 @@ export async function cmdSave(fileOrPath) {
21
22
  p.outro('');
22
23
  return;
23
24
  }
25
+ // Auto-create pmpt.md if missing
26
+ const pmptMdPath = join(docsDir, 'pmpt.md');
27
+ if (!existsSync(pmptMdPath)) {
28
+ const planProgress = getPlanProgress(projectPath);
29
+ const config = loadConfig(projectPath);
30
+ const name = planProgress?.answers?.projectName || config?.lastPublishedSlug || basename(projectPath);
31
+ const skeleton = [
32
+ `# ${name}`,
33
+ '',
34
+ '## Progress',
35
+ '- Project initialized',
36
+ '',
37
+ '## Snapshot Log',
38
+ '',
39
+ '## Decisions',
40
+ '',
41
+ ].join('\n');
42
+ writeFileSync(pmptMdPath, skeleton, 'utf-8');
43
+ p.log.info('Created pmpt.md (project tracking document)');
44
+ }
24
45
  // Ask for summary
25
46
  const summary = await p.text({
26
47
  message: 'What did you accomplish? (this is shown on your project page)',
package/dist/mcp.js CHANGED
@@ -12,6 +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 { basename } from 'path';
15
16
  import { isInitialized, loadConfig, saveConfig, getDocsDir, getHistoryDir } from './lib/config.js';
16
17
  import { createFullSnapshot, getAllSnapshots, getTrackedFiles, resolveFullSnapshot } from './lib/history.js';
17
18
  import { computeQuality } from './lib/quality.js';
@@ -105,14 +106,32 @@ server.tool('pmpt_save', 'Save a snapshot of .pmpt/docs/ files. Call after compl
105
106
  try {
106
107
  const pp = resolveProjectPath(projectPath);
107
108
  assertInitialized(pp);
109
+ const docsDir = getDocsDir(pp);
110
+ // Auto-create pmpt.md if missing
111
+ const pmptMdPath = join(docsDir, 'pmpt.md');
112
+ if (!existsSync(pmptMdPath)) {
113
+ const planProgress = getPlanProgress(pp);
114
+ const config = loadConfig(pp);
115
+ const name = planProgress?.answers?.projectName || config?.lastPublishedSlug || basename(pp);
116
+ const skeleton = [
117
+ `# ${name}`,
118
+ '',
119
+ '## Progress',
120
+ '- Project initialized',
121
+ '',
122
+ '## Snapshot Log',
123
+ '',
124
+ '## Decisions',
125
+ '',
126
+ ].join('\n');
127
+ writeFileSync(pmptMdPath, skeleton, 'utf-8');
128
+ }
108
129
  const tracked = getTrackedFiles(pp);
109
130
  if (tracked.length === 0) {
110
131
  return { content: [{ type: 'text', text: 'No files to save. Add .md files to .pmpt/docs/ first.' }] };
111
132
  }
112
133
  // Auto-update pmpt.md with summary before snapshot
113
134
  if (summary) {
114
- const docsDir = getDocsDir(pp);
115
- const pmptMdPath = join(docsDir, 'pmpt.md');
116
135
  if (existsSync(pmptMdPath)) {
117
136
  let content = readFileSync(pmptMdPath, 'utf-8');
118
137
  const snapshots = getAllSnapshots(pp);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmpt-cli",
3
- "version": "1.14.9",
3
+ "version": "1.14.11",
4
4
  "description": "Record and share your AI-driven product development journey",
5
5
  "type": "module",
6
6
  "bin": {