@damper/cli 0.9.18 → 0.9.20

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.
@@ -335,7 +335,7 @@ export async function postTaskFlow(options) {
335
335
  console.log(pc.dim('Cleaning up merge state...'));
336
336
  await execa('git', ['reset', '--merge'], { cwd, stdio: 'pipe' }).catch(() => { });
337
337
  }
338
- await launchClaudeForMerge({ cwd, apiKey });
338
+ await launchClaudeForMerge({ cwd, apiKey, taskTitle });
339
339
  // Verify merge was completed (origin/main should be ancestor of HEAD)
340
340
  try {
341
341
  await execa('git', ['merge-base', '--is-ancestor', 'origin/main', 'HEAD'], { cwd, stdio: 'pipe' });
@@ -582,15 +582,44 @@ export async function launchClaudeForReview(options) {
582
582
  /**
583
583
  * Launch Claude to resolve merge conflicts
584
584
  * Uses --allowedTools to restrict Claude to only git/file operations
585
- * so it doesn't pick up task context and try to work on the task
585
+ * so it doesn't pick up task context and try to work on the task.
586
+ * Runs with --dangerously-skip-permissions for fully autonomous resolution.
586
587
  */
587
588
  async function launchClaudeForMerge(options) {
588
- const { cwd, apiKey } = options;
589
- const prompt = 'IMPORTANT: Your ONLY job is to resolve merge conflicts. Do NOT read TASK_CONTEXT.md or work on any task. Run: git merge origin/main --no-edit. If there are conflicts, resolve them, stage, and commit. Do not use any MCP tools.';
589
+ const { cwd, apiKey, taskTitle } = options;
590
+ const taskContext = taskTitle
591
+ ? `You are merging a feature branch for task "${taskTitle}" into main.`
592
+ : 'You are merging a feature branch into main.';
593
+ const prompt = [
594
+ `MERGE CONFLICT RESOLUTION — Your ONLY job is to resolve merge conflicts.`,
595
+ '',
596
+ taskContext,
597
+ '',
598
+ 'Steps:',
599
+ '1. Run: git merge origin/main --no-edit',
600
+ '2. If there are conflicts, identify all conflicted files with: git diff --name-only --diff-filter=U',
601
+ '3. Read each conflicted file and resolve the conflicts:',
602
+ ' - For CLAUDE.md: keep the main (origin/main) version entirely — the feature branch appends a temporary task section that must not be merged',
603
+ ' - For code conflicts: combine both sides logically, preserving the intent of both the feature branch changes and main branch updates',
604
+ ' - For package.json / lock files: accept the version that satisfies both sides, preferring the newer version',
605
+ '4. Stage all resolved files with: git add <file>',
606
+ '5. Commit the merge with: git commit --no-edit',
607
+ '6. Verify no conflicts remain with: git diff --name-only --diff-filter=U',
608
+ '',
609
+ 'IMPORTANT:',
610
+ '- Do NOT read TASK_CONTEXT.md or work on the task itself',
611
+ '- Do NOT use any MCP tools — only use Bash, Read, Write, Edit, Glob, Grep',
612
+ '- Do NOT make any changes beyond resolving the merge conflicts',
613
+ '- If a conflict is too complex to resolve confidently, leave it and explain what needs manual attention',
614
+ ].join('\n');
590
615
  const mergeLabel = 'Resolving merge conflicts';
591
616
  setTerminalTitle(mergeLabel);
592
617
  await new Promise((resolve) => {
593
- const child = spawn('claude', ['--allowedTools', 'Bash,Read,Write,Edit,Glob,Grep', prompt], {
618
+ const child = spawn('claude', [
619
+ '--allowedTools', 'Bash,Read,Write,Edit,Glob,Grep',
620
+ '--dangerously-skip-permissions',
621
+ prompt,
622
+ ], {
594
623
  cwd,
595
624
  stdio: 'inherit',
596
625
  env: { ...process.env, DAMPER_API_KEY: apiKey },
@@ -1,5 +1,6 @@
1
1
  import { search, select, confirm, input, Separator } from '@inquirer/prompts';
2
2
  import pc from 'picocolors';
3
+ import * as readline from 'readline';
3
4
  import { shortId, shortIdRaw, getTypeIcon, getPriorityIcon, formatEffort, formatProgressCompact, formatDueDate, sectionHeader, relativeTime, getTerminalWidth, padEnd, padStart, } from './format.js';
4
5
  // Layout constants (terminal column widths)
5
6
  const CURSOR_WIDTH = 2; // inquirer select prefix (❯ or )
@@ -265,15 +266,50 @@ export async function pickTask(options) {
265
266
  action,
266
267
  };
267
268
  }
269
+ function multilineInput(message) {
270
+ return new Promise((resolve) => {
271
+ process.stdout.write(`${pc.bold(pc.green('?'))} ${pc.bold(message)} ${pc.dim('(Enter to skip)')}\n`);
272
+ const lines = [];
273
+ let hintShown = false;
274
+ let hintTimer = null;
275
+ const rl = readline.createInterface({
276
+ input: process.stdin,
277
+ output: process.stdout,
278
+ prompt: '',
279
+ });
280
+ const showHint = () => {
281
+ if (!hintShown) {
282
+ hintShown = true;
283
+ process.stdout.write(pc.dim(' (Press Enter on an empty line to submit)\n'));
284
+ }
285
+ };
286
+ rl.on('line', (line) => {
287
+ if (hintTimer)
288
+ clearTimeout(hintTimer);
289
+ if (lines.length === 0 && line === '') {
290
+ rl.close();
291
+ return;
292
+ }
293
+ if (line === '' && lines[lines.length - 1] === '') {
294
+ lines.pop(); // remove trailing empty line
295
+ rl.close();
296
+ return;
297
+ }
298
+ lines.push(line);
299
+ hintTimer = setTimeout(showHint, 50);
300
+ });
301
+ rl.on('close', () => {
302
+ resolve(lines.join('\n'));
303
+ });
304
+ });
305
+ }
268
306
  async function handleCreateNewTask(api, searchTerm) {
269
307
  const title = await input({
270
308
  message: 'Task title:',
271
309
  default: searchTerm || undefined,
272
310
  validate: (value) => value.trim().length > 0 || 'Title is required',
273
311
  });
274
- const description = await input({
275
- message: 'Description (optional, press Enter to skip):',
276
- });
312
+ const description = await multilineInput('Description (optional):');
277
313
  const type = await select({
278
314
  message: 'Task type:',
279
315
  choices: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damper/cli",
3
- "version": "0.9.18",
3
+ "version": "0.9.20",
4
4
  "description": "CLI tool for orchestrating Damper task workflows with Claude Code",
5
5
  "author": "Damper <hello@usedamper.com>",
6
6
  "repository": {