@damper/cli 0.9.5 → 0.9.6
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/ui/task-picker.js +43 -8
- package/package.json +1 -1
package/dist/ui/task-picker.js
CHANGED
|
@@ -260,6 +260,34 @@ export async function pickTask(options) {
|
|
|
260
260
|
action,
|
|
261
261
|
};
|
|
262
262
|
}
|
|
263
|
+
async function generateTaskTitle(instructions, type) {
|
|
264
|
+
try {
|
|
265
|
+
const { execa } = await import('execa');
|
|
266
|
+
const prompt = [
|
|
267
|
+
`Generate a task title for a ${type} task.`,
|
|
268
|
+
'Rules:',
|
|
269
|
+
'- Max 60 characters, sentence case, no trailing period',
|
|
270
|
+
'- Verb prefix matching type: bug → "Fix …", feature → "Add …", improvement → "Improve …", task → "Set up …" / "Update …"',
|
|
271
|
+
'- Specific enough to understand without reading a description',
|
|
272
|
+
'- Examples: "Add dark mode support", "Fix login timeout on slow connections", "Improve search result ranking"',
|
|
273
|
+
'Return ONLY the title, nothing else.',
|
|
274
|
+
'',
|
|
275
|
+
`User input: ${instructions}`,
|
|
276
|
+
].join('\n');
|
|
277
|
+
const { stdout } = await execa('claude', ['--print', '--model', 'haiku', prompt], {
|
|
278
|
+
stdio: 'pipe',
|
|
279
|
+
timeout: 15000,
|
|
280
|
+
});
|
|
281
|
+
const title = stdout.trim();
|
|
282
|
+
if (title && title.length <= 80 && !title.includes('\n')) {
|
|
283
|
+
return title;
|
|
284
|
+
}
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
263
291
|
async function handleCreateNewTask(api) {
|
|
264
292
|
const instructions = await input({
|
|
265
293
|
message: 'What needs to be done?',
|
|
@@ -274,16 +302,23 @@ async function handleCreateNewTask(api) {
|
|
|
274
302
|
{ name: 'Task', value: 'task' },
|
|
275
303
|
],
|
|
276
304
|
});
|
|
277
|
-
// Use instructions as description; derive a placeholder title
|
|
278
305
|
const trimmed = instructions.trim();
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
306
|
+
// Generate title with Claude, fall back to truncation
|
|
307
|
+
console.log(pc.dim('\nGenerating title...'));
|
|
308
|
+
const generatedTitle = await generateTaskTitle(trimmed, type);
|
|
309
|
+
let title;
|
|
310
|
+
if (generatedTitle) {
|
|
311
|
+
title = generatedTitle;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
const maxTitleLen = 60;
|
|
315
|
+
title = trimmed.length <= maxTitleLen
|
|
316
|
+
? trimmed
|
|
317
|
+
: trimmed.slice(0, trimmed.lastIndexOf(' ', maxTitleLen) || maxTitleLen) + '…';
|
|
318
|
+
}
|
|
319
|
+
console.log(pc.dim('Creating task in Damper...'));
|
|
320
|
+
const task = await api.createTask(title, type, trimmed);
|
|
285
321
|
console.log(pc.green(`✓ Created task #${shortIdRaw(task.id)}: ${task.title}`));
|
|
286
|
-
console.log(pc.dim(' The agent will refine the title after planning.'));
|
|
287
322
|
return {
|
|
288
323
|
task,
|
|
289
324
|
isResume: false,
|