pmpt-cli 1.14.8 → 1.14.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.
Files changed (2) hide show
  1. package/dist/commands/edit.js +124 -76
  2. package/package.json +1 -1
@@ -39,97 +39,145 @@ export async function cmdEdit() {
39
39
  process.exit(0);
40
40
  }
41
41
  const project = myProjects.find((proj) => proj.slug === slug);
42
- const description = await p.text({
43
- message: 'Description:',
44
- defaultValue: project.description,
45
- placeholder: project.description,
46
- });
47
- if (p.isCancel(description)) {
48
- p.cancel('Cancelled');
49
- process.exit(0);
50
- }
51
- const tagsInput = await p.text({
52
- message: 'Tags (comma-separated):',
53
- defaultValue: project.tags.join(', '),
54
- placeholder: project.tags.join(', '),
55
- });
56
- if (p.isCancel(tagsInput)) {
57
- p.cancel('Cancelled');
58
- process.exit(0);
59
- }
60
- const tags = tagsInput
61
- .split(',')
62
- .map((t) => t.trim().toLowerCase())
63
- .filter(Boolean);
64
- const category = await p.select({
65
- message: 'Category:',
66
- initialValue: project.category || 'other',
42
+ // Show current settings
43
+ const categoryLabel = [
44
+ { value: 'web-app', label: 'Web App' },
45
+ { value: 'mobile-app', label: 'Mobile App' },
46
+ { value: 'cli-tool', label: 'CLI Tool' },
47
+ { value: 'api-backend', label: 'API/Backend' },
48
+ { value: 'ai-ml', label: 'AI/ML' },
49
+ { value: 'game', label: 'Game' },
50
+ { value: 'library', label: 'Library' },
51
+ { value: 'other', label: 'Other' },
52
+ ].find((o) => o.value === project.category)?.label ?? project.category ?? 'Other';
53
+ p.note([
54
+ `Description: ${project.description || '(none)'}`,
55
+ `Tags: ${project.tags?.length ? project.tags.join(', ') : '(none)'}`,
56
+ `Category: ${categoryLabel}`,
57
+ project.productUrl ? `Product: ${project.productUrl}` : 'Product: (none)',
58
+ `Visibility: ${project.unlisted ? 'Unlisted' : 'Listed'}`,
59
+ ].join('\n'), 'Current Settings');
60
+ // Pick fields to edit
61
+ const fields = await p.multiselect({
62
+ message: 'What do you want to edit?',
67
63
  options: [
68
- { value: 'web-app', label: 'Web App' },
69
- { value: 'mobile-app', label: 'Mobile App' },
70
- { value: 'cli-tool', label: 'CLI Tool' },
71
- { value: 'api-backend', label: 'API/Backend' },
72
- { value: 'ai-ml', label: 'AI/ML' },
73
- { value: 'game', label: 'Game' },
74
- { value: 'library', label: 'Library' },
75
- { value: 'other', label: 'Other' },
64
+ { value: 'description', label: 'Description' },
65
+ { value: 'tags', label: 'Tags' },
66
+ { value: 'category', label: 'Category' },
67
+ { value: 'productUrl', label: 'Product Link' },
68
+ { value: 'unlisted', label: 'Visibility (listed/unlisted)' },
76
69
  ],
77
70
  });
78
- if (p.isCancel(category)) {
71
+ if (p.isCancel(fields)) {
79
72
  p.cancel('Cancelled');
80
73
  process.exit(0);
81
74
  }
82
- // Product link (optional)
83
- const linkTypeInput = await p.select({
84
- message: 'Product link (optional):',
85
- initialValue: project.productUrlType || 'none',
86
- options: [
87
- { value: 'none', label: 'No link' },
88
- { value: 'git', label: 'Git Repository' },
89
- { value: 'url', label: 'Website / URL' },
90
- ],
91
- });
92
- if (p.isCancel(linkTypeInput)) {
93
- p.cancel('Cancelled');
94
- process.exit(0);
75
+ const updates = {};
76
+ const selected = new Set(fields);
77
+ if (selected.has('description')) {
78
+ const v = await p.text({
79
+ message: 'Description:',
80
+ defaultValue: project.description,
81
+ placeholder: project.description,
82
+ });
83
+ if (p.isCancel(v)) {
84
+ p.cancel('Cancelled');
85
+ process.exit(0);
86
+ }
87
+ updates.description = v;
95
88
  }
96
- let productUrl = '';
97
- let productUrlType = '';
98
- if (linkTypeInput !== 'none') {
99
- productUrlType = linkTypeInput;
100
- const productUrlInput = await p.text({
101
- message: 'Product URL:',
102
- placeholder: linkTypeInput === 'git'
103
- ? `https://github.com/${auth.username}/${slug}`
104
- : 'https://...',
105
- defaultValue: project.productUrl || '',
106
- validate: (v) => {
107
- if (!v.trim())
108
- return 'URL is required when link type is selected.';
109
- try {
110
- new URL(v);
111
- }
112
- catch {
113
- return 'Invalid URL format.';
114
- }
115
- },
89
+ if (selected.has('tags')) {
90
+ const v = await p.text({
91
+ message: 'Tags (comma-separated):',
92
+ defaultValue: project.tags.join(', '),
93
+ placeholder: project.tags.join(', '),
116
94
  });
117
- if (p.isCancel(productUrlInput)) {
95
+ if (p.isCancel(v)) {
118
96
  p.cancel('Cancelled');
119
97
  process.exit(0);
120
98
  }
121
- productUrl = productUrlInput;
99
+ updates.tags = v.split(',').map((t) => t.trim().toLowerCase()).filter(Boolean);
100
+ }
101
+ if (selected.has('category')) {
102
+ const v = await p.select({
103
+ message: 'Category:',
104
+ initialValue: project.category || 'other',
105
+ options: [
106
+ { value: 'web-app', label: 'Web App' },
107
+ { value: 'mobile-app', label: 'Mobile App' },
108
+ { value: 'cli-tool', label: 'CLI Tool' },
109
+ { value: 'api-backend', label: 'API/Backend' },
110
+ { value: 'ai-ml', label: 'AI/ML' },
111
+ { value: 'game', label: 'Game' },
112
+ { value: 'library', label: 'Library' },
113
+ { value: 'other', label: 'Other' },
114
+ ],
115
+ });
116
+ if (p.isCancel(v)) {
117
+ p.cancel('Cancelled');
118
+ process.exit(0);
119
+ }
120
+ updates.category = v;
121
+ }
122
+ if (selected.has('productUrl')) {
123
+ const linkType = await p.select({
124
+ message: 'Product link:',
125
+ initialValue: project.productUrlType || 'none',
126
+ options: [
127
+ { value: 'none', label: 'No link' },
128
+ { value: 'git', label: 'Git Repository' },
129
+ { value: 'url', label: 'Website / URL' },
130
+ ],
131
+ });
132
+ if (p.isCancel(linkType)) {
133
+ p.cancel('Cancelled');
134
+ process.exit(0);
135
+ }
136
+ if (linkType === 'none') {
137
+ updates.productUrl = '';
138
+ updates.productUrlType = '';
139
+ }
140
+ else {
141
+ updates.productUrlType = linkType;
142
+ const urlInput = await p.text({
143
+ message: 'Product URL:',
144
+ placeholder: linkType === 'git'
145
+ ? `https://github.com/${auth.username}/${slug}`
146
+ : 'https://...',
147
+ defaultValue: project.productUrl || '',
148
+ validate: (v) => {
149
+ if (!v.trim())
150
+ return 'URL is required when link type is selected.';
151
+ try {
152
+ new URL(v);
153
+ }
154
+ catch {
155
+ return 'Invalid URL format.';
156
+ }
157
+ },
158
+ });
159
+ if (p.isCancel(urlInput)) {
160
+ p.cancel('Cancelled');
161
+ process.exit(0);
162
+ }
163
+ updates.productUrl = urlInput;
164
+ }
165
+ }
166
+ if (selected.has('unlisted')) {
167
+ const v = await p.confirm({
168
+ message: 'Unlisted? (hidden from explore, accessible via direct URL)',
169
+ initialValue: project.unlisted ?? false,
170
+ });
171
+ if (p.isCancel(v)) {
172
+ p.cancel('Cancelled');
173
+ process.exit(0);
174
+ }
175
+ updates.unlisted = !!v;
122
176
  }
123
177
  const s2 = p.spinner();
124
178
  s2.start('Updating...');
125
179
  try {
126
- await editProject(auth.token, slug, {
127
- description: description,
128
- tags,
129
- category: category,
130
- productUrl,
131
- productUrlType,
132
- });
180
+ await editProject(auth.token, slug, updates);
133
181
  s2.stop('Updated!');
134
182
  p.log.success(`Project "${slug}" has been updated.`);
135
183
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmpt-cli",
3
- "version": "1.14.8",
3
+ "version": "1.14.9",
4
4
  "description": "Record and share your AI-driven product development journey",
5
5
  "type": "module",
6
6
  "bin": {