@damper/cli 0.6.2 → 0.6.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.
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { statusCommand } from './commands/status.js';
|
|
|
5
5
|
import { cleanupCommand } from './commands/cleanup.js';
|
|
6
6
|
import { setupCommand } from './commands/setup.js';
|
|
7
7
|
import { releaseCommand } from './commands/release.js';
|
|
8
|
-
const VERSION = '0.6.
|
|
8
|
+
const VERSION = '0.6.4';
|
|
9
9
|
function showHelp() {
|
|
10
10
|
console.log(`
|
|
11
11
|
${pc.bold('@damper/cli')} - Agent orchestration for Damper tasks
|
package/dist/services/claude.js
CHANGED
|
@@ -178,9 +178,21 @@ export async function postTaskFlow(options) {
|
|
|
178
178
|
hasUnpushedCommits = unpushed.trim().length > 0;
|
|
179
179
|
}
|
|
180
180
|
catch {
|
|
181
|
-
// No upstream branch -
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
// No upstream branch - check against main/origin
|
|
182
|
+
try {
|
|
183
|
+
const { stdout: commits } = await execa('git', ['log', 'origin/main..HEAD', '--oneline'], { cwd, stdio: 'pipe' });
|
|
184
|
+
hasUnpushedCommits = commits.trim().length > 0;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
try {
|
|
188
|
+
const { stdout: commits } = await execa('git', ['log', 'main..HEAD', '--oneline'], { cwd, stdio: 'pipe' });
|
|
189
|
+
hasUnpushedCommits = commits.trim().length > 0;
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Can't determine - assume there are commits if branch differs from main
|
|
193
|
+
hasUnpushedCommits = currentBranch !== 'main' && currentBranch !== '';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
184
196
|
}
|
|
185
197
|
}
|
|
186
198
|
catch {
|
|
@@ -202,13 +214,13 @@ export async function postTaskFlow(options) {
|
|
|
202
214
|
}
|
|
203
215
|
console.log();
|
|
204
216
|
// Offer actions based on state
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
217
|
+
const hasChanges = hasUnpushedCommits || hasUncommittedChanges;
|
|
218
|
+
if (hasChanges) {
|
|
219
|
+
if (hasUncommittedChanges) {
|
|
220
|
+
console.log(pc.yellow('⚠ There are uncommitted changes. You may want to commit them first.\n'));
|
|
221
|
+
}
|
|
210
222
|
const mergeAction = await select({
|
|
211
|
-
message: 'How do you want to
|
|
223
|
+
message: 'How do you want to handle your changes?',
|
|
212
224
|
choices: [
|
|
213
225
|
{ name: 'Create a pull request', value: 'pr' },
|
|
214
226
|
{ name: 'Merge directly to main', value: 'merge' },
|
|
@@ -149,6 +149,7 @@ export declare class DamperApi {
|
|
|
149
149
|
}>;
|
|
150
150
|
getModule(name: string): Promise<Module>;
|
|
151
151
|
getAgentInstructions(format?: 'markdown' | 'section'): Promise<AgentInstructions>;
|
|
152
|
+
createTask(title: string, type?: 'bug' | 'feature' | 'improvement' | 'task'): Promise<Task>;
|
|
152
153
|
getLinkedFeedback(taskId: string): Promise<Array<{
|
|
153
154
|
id: string;
|
|
154
155
|
title: string;
|
|
@@ -138,6 +138,10 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
|
|
|
138
138
|
lastModified,
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
+
// Create task
|
|
142
|
+
async createTask(title, type = 'task') {
|
|
143
|
+
return this.request('POST', '/api/agent/tasks', { title, type, status: 'planned' });
|
|
144
|
+
}
|
|
141
145
|
// Feedback
|
|
142
146
|
async getLinkedFeedback(taskId) {
|
|
143
147
|
const task = await this.getTask(taskId);
|
package/dist/ui/task-picker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { select, confirm, Separator } from '@inquirer/prompts';
|
|
1
|
+
import { select, confirm, input, Separator } from '@inquirer/prompts';
|
|
2
2
|
import pc from 'picocolors';
|
|
3
3
|
function getTypeIcon(type) {
|
|
4
4
|
switch (type) {
|
|
@@ -94,14 +94,6 @@ export async function pickTask(options) {
|
|
|
94
94
|
availableChoices.push({ type: 'available', task });
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
if (inProgressChoices.length === 0 && availableChoices.length === 0 && lockedChoices.length === 0) {
|
|
98
|
-
console.log(pc.yellow('\nNo tasks available.'));
|
|
99
|
-
if (typeFilter) {
|
|
100
|
-
console.log(pc.dim(`(filtered by type: ${typeFilter})`));
|
|
101
|
-
}
|
|
102
|
-
console.log(pc.dim('Create new tasks in Damper or check your filters.\n'));
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
97
|
const choices = [];
|
|
106
98
|
if (inProgressChoices.length > 0) {
|
|
107
99
|
choices.push(new Separator(pc.bold('\n--- In Progress (your worktrees) ---')));
|
|
@@ -130,12 +122,27 @@ export async function pickTask(options) {
|
|
|
130
122
|
});
|
|
131
123
|
}
|
|
132
124
|
}
|
|
125
|
+
// Always show "Create new task" option
|
|
126
|
+
choices.push(new Separator(''));
|
|
127
|
+
choices.push({
|
|
128
|
+
name: pc.green('+ Create new task'),
|
|
129
|
+
value: { type: 'create_new' },
|
|
130
|
+
});
|
|
131
|
+
if (inProgressChoices.length === 0 && availableChoices.length === 0 && lockedChoices.length === 0) {
|
|
132
|
+
console.log(pc.yellow('\nNo existing tasks found.'));
|
|
133
|
+
if (typeFilter) {
|
|
134
|
+
console.log(pc.dim(`(filtered by type: ${typeFilter})`));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
133
137
|
console.log(pc.bold(`\nProject: ${project}`));
|
|
134
138
|
const selected = await select({
|
|
135
139
|
message: 'Select a task to work on:',
|
|
136
140
|
choices: choices,
|
|
137
141
|
pageSize: 15,
|
|
138
142
|
});
|
|
143
|
+
if (selected.type === 'create_new') {
|
|
144
|
+
return handleCreateNewTask(api);
|
|
145
|
+
}
|
|
139
146
|
if (selected.type === 'in_progress') {
|
|
140
147
|
return {
|
|
141
148
|
task: selected.task,
|
|
@@ -166,3 +173,25 @@ export async function pickTask(options) {
|
|
|
166
173
|
isResume: false,
|
|
167
174
|
};
|
|
168
175
|
}
|
|
176
|
+
async function handleCreateNewTask(api) {
|
|
177
|
+
const title = await input({
|
|
178
|
+
message: 'Task title:',
|
|
179
|
+
validate: (value) => value.trim().length > 0 || 'Title is required',
|
|
180
|
+
});
|
|
181
|
+
const type = await select({
|
|
182
|
+
message: 'Task type:',
|
|
183
|
+
choices: [
|
|
184
|
+
{ name: 'Feature', value: 'feature' },
|
|
185
|
+
{ name: 'Bug', value: 'bug' },
|
|
186
|
+
{ name: 'Improvement', value: 'improvement' },
|
|
187
|
+
{ name: 'Task', value: 'task' },
|
|
188
|
+
],
|
|
189
|
+
});
|
|
190
|
+
console.log(pc.dim('\nCreating task in Damper...'));
|
|
191
|
+
const task = await api.createTask(title.trim(), type);
|
|
192
|
+
console.log(pc.green(`✓ Created task #${task.id}: ${task.title}`));
|
|
193
|
+
return {
|
|
194
|
+
task,
|
|
195
|
+
isResume: false,
|
|
196
|
+
};
|
|
197
|
+
}
|