@damper/cli 0.9.4 → 0.9.5
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/services/claude.js
CHANGED
|
@@ -174,12 +174,14 @@ export async function postTaskFlow(options) {
|
|
|
174
174
|
let taskStatus;
|
|
175
175
|
let taskTitle;
|
|
176
176
|
let hasCommits = false;
|
|
177
|
+
let isPublicTask = false;
|
|
177
178
|
try {
|
|
178
179
|
const api = createDamperApi(apiKey);
|
|
179
180
|
const task = await api.getTask(taskId);
|
|
180
181
|
taskStatus = task.status;
|
|
181
182
|
taskTitle = task.title;
|
|
182
183
|
hasCommits = (task.commits?.length ?? 0) > 0;
|
|
184
|
+
isPublicTask = !!task.publicUrl;
|
|
183
185
|
}
|
|
184
186
|
catch {
|
|
185
187
|
console.log(pc.yellow('Could not fetch task status from Damper.'));
|
|
@@ -254,6 +256,10 @@ export async function postTaskFlow(options) {
|
|
|
254
256
|
console.log(pc.yellow('⚠ Unpushed commits detected'));
|
|
255
257
|
}
|
|
256
258
|
console.log();
|
|
259
|
+
// Offer to add to changelog if task is completed
|
|
260
|
+
if (taskStatus === 'done') {
|
|
261
|
+
await offerChangelogFlow({ taskId, taskTitle, apiKey, isPublic: isPublicTask, confirm, select });
|
|
262
|
+
}
|
|
257
263
|
// Offer actions based on state
|
|
258
264
|
const hasChanges = hasUnpushedCommits || hasUncommittedChanges;
|
|
259
265
|
let worktreeRemoved = false;
|
|
@@ -441,6 +447,67 @@ export async function postTaskFlow(options) {
|
|
|
441
447
|
}
|
|
442
448
|
console.log();
|
|
443
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* Ask user if they want to add the completed task to a changelog
|
|
452
|
+
*/
|
|
453
|
+
async function offerChangelogFlow(options) {
|
|
454
|
+
const { taskId, taskTitle, apiKey, isPublic, confirm, select } = options;
|
|
455
|
+
const { input } = await import('@inquirer/prompts');
|
|
456
|
+
const addToChangelog = await confirm({
|
|
457
|
+
message: 'Add this task to a changelog?',
|
|
458
|
+
default: isPublic,
|
|
459
|
+
});
|
|
460
|
+
if (!addToChangelog)
|
|
461
|
+
return;
|
|
462
|
+
try {
|
|
463
|
+
const { createDamperApi } = await import('./damper-api.js');
|
|
464
|
+
const api = createDamperApi(apiKey);
|
|
465
|
+
// Fetch draft changelogs
|
|
466
|
+
const { changelogs } = await api.listChangelogs({ status: 'draft', limit: 10 });
|
|
467
|
+
let changelogId;
|
|
468
|
+
if (changelogs.length > 0) {
|
|
469
|
+
const choice = await select({
|
|
470
|
+
message: 'Which changelog?',
|
|
471
|
+
choices: [
|
|
472
|
+
...changelogs.map((cl) => ({
|
|
473
|
+
name: `${cl.title}${cl.version ? ` (${cl.version})` : ''} — ${cl.roadmapItemCount} item${cl.roadmapItemCount !== 1 ? 's' : ''}`,
|
|
474
|
+
value: cl.id,
|
|
475
|
+
})),
|
|
476
|
+
{ name: 'Create new changelog', value: '__new__' },
|
|
477
|
+
],
|
|
478
|
+
});
|
|
479
|
+
if (choice === '__new__') {
|
|
480
|
+
const title = await input({
|
|
481
|
+
message: 'Changelog title:',
|
|
482
|
+
default: `Release ${new Date().toISOString().slice(0, 10)}`,
|
|
483
|
+
});
|
|
484
|
+
const result = await api.createChangelog({ title });
|
|
485
|
+
changelogId = result.id;
|
|
486
|
+
console.log(pc.green(`✓ Created changelog: ${title}`));
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
changelogId = choice;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
// No drafts — create one
|
|
494
|
+
const title = await input({
|
|
495
|
+
message: 'No draft changelogs found. Create one — title:',
|
|
496
|
+
default: `Release ${new Date().toISOString().slice(0, 10)}`,
|
|
497
|
+
});
|
|
498
|
+
const result = await api.createChangelog({ title });
|
|
499
|
+
changelogId = result.id;
|
|
500
|
+
console.log(pc.green(`✓ Created changelog: ${title}`));
|
|
501
|
+
}
|
|
502
|
+
// Add the task
|
|
503
|
+
const result = await api.addToChangelog(changelogId, [taskId]);
|
|
504
|
+
console.log(pc.green(`✓ Added "${taskTitle || taskId}" to changelog (${result.roadmapItemCount} total items)\n`));
|
|
505
|
+
}
|
|
506
|
+
catch (err) {
|
|
507
|
+
const error = err;
|
|
508
|
+
console.log(pc.yellow(`Could not add to changelog: ${error.message}\n`));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
444
511
|
/**
|
|
445
512
|
* Launch Claude to review and complete a task
|
|
446
513
|
*/
|
|
@@ -37,6 +37,7 @@ export interface TaskDetail extends Task {
|
|
|
37
37
|
}>;
|
|
38
38
|
lockedBy?: string | null;
|
|
39
39
|
lockedAt?: string | null;
|
|
40
|
+
publicUrl?: string | null;
|
|
40
41
|
}
|
|
41
42
|
export interface ContextSection {
|
|
42
43
|
section: string;
|
|
@@ -76,6 +77,16 @@ export interface Module {
|
|
|
76
77
|
tags?: string[];
|
|
77
78
|
updatedAt: string;
|
|
78
79
|
}
|
|
80
|
+
export interface Changelog {
|
|
81
|
+
id: string;
|
|
82
|
+
title: string;
|
|
83
|
+
version?: string | null;
|
|
84
|
+
date?: string | null;
|
|
85
|
+
status: 'draft' | 'published';
|
|
86
|
+
publishedAt?: string | null;
|
|
87
|
+
roadmapItemCount: number;
|
|
88
|
+
contentPreview: string;
|
|
89
|
+
}
|
|
79
90
|
export interface AgentInstructions {
|
|
80
91
|
format: 'markdown' | 'section';
|
|
81
92
|
content: string;
|
|
@@ -182,6 +193,32 @@ export declare class DamperApi {
|
|
|
182
193
|
}>;
|
|
183
194
|
getModule(name: string): Promise<Module>;
|
|
184
195
|
getAgentInstructions(format?: 'markdown' | 'section'): Promise<AgentInstructions>;
|
|
196
|
+
listChangelogs(filters?: {
|
|
197
|
+
status?: 'draft' | 'published';
|
|
198
|
+
limit?: number;
|
|
199
|
+
sort?: 'newest' | 'oldest';
|
|
200
|
+
}): Promise<{
|
|
201
|
+
changelogs: Changelog[];
|
|
202
|
+
}>;
|
|
203
|
+
createChangelog(data: {
|
|
204
|
+
title: string;
|
|
205
|
+
content?: string;
|
|
206
|
+
version?: string;
|
|
207
|
+
status?: 'draft' | 'published';
|
|
208
|
+
}): Promise<{
|
|
209
|
+
id: string;
|
|
210
|
+
title: string;
|
|
211
|
+
status: string;
|
|
212
|
+
}>;
|
|
213
|
+
addToChangelog(changelogId: string, taskIds: string[]): Promise<{
|
|
214
|
+
id: string;
|
|
215
|
+
title: string;
|
|
216
|
+
roadmapItemCount: number;
|
|
217
|
+
addedItems: Array<{
|
|
218
|
+
id: string;
|
|
219
|
+
title: string;
|
|
220
|
+
}>;
|
|
221
|
+
}>;
|
|
185
222
|
createTask(title: string, type?: 'bug' | 'feature' | 'improvement' | 'task', description?: string): Promise<Task>;
|
|
186
223
|
deleteTask(taskId: string): Promise<{
|
|
187
224
|
id: string;
|
|
@@ -170,6 +170,24 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
|
|
|
170
170
|
lastModified,
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
|
+
// Changelogs
|
|
174
|
+
async listChangelogs(filters) {
|
|
175
|
+
const params = new URLSearchParams();
|
|
176
|
+
if (filters?.status)
|
|
177
|
+
params.set('status', filters.status);
|
|
178
|
+
if (filters?.limit)
|
|
179
|
+
params.set('limit', String(filters.limit));
|
|
180
|
+
if (filters?.sort)
|
|
181
|
+
params.set('sort', filters.sort);
|
|
182
|
+
const query = params.toString();
|
|
183
|
+
return this.request('GET', `/api/agent/changelogs${query ? `?${query}` : ''}`);
|
|
184
|
+
}
|
|
185
|
+
async createChangelog(data) {
|
|
186
|
+
return this.request('POST', '/api/agent/changelogs', data);
|
|
187
|
+
}
|
|
188
|
+
async addToChangelog(changelogId, taskIds) {
|
|
189
|
+
return this.request('POST', `/api/agent/changelogs/${changelogId}/items`, { taskIds });
|
|
190
|
+
}
|
|
173
191
|
// Create task
|
|
174
192
|
async createTask(title, type = 'task', description) {
|
|
175
193
|
return this.request('POST', '/api/agent/tasks', { title, type, status: 'planned', description });
|