@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.2';
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
@@ -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 - assume all commits are unpushed
182
- const { stdout: commits } = await execa('git', ['log', 'main..HEAD', '--oneline'], { cwd, stdio: 'pipe' });
183
- hasUnpushedCommits = commits.trim().length > 0;
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
- if (hasUncommittedChanges) {
206
- console.log(pc.dim('You have uncommitted changes. Commit them before pushing.\n'));
207
- }
208
- if (hasUnpushedCommits && !hasUncommittedChanges) {
209
- const { select } = await import('@inquirer/prompts');
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 merge your changes?',
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);
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damper/cli",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "CLI tool for orchestrating Damper task workflows with Claude Code",
5
5
  "author": "Damper <hello@usedamper.com>",
6
6
  "repository": {