summaryrefslogtreecommitdiff
path: root/web/test/subtask-placeholder.test.mjs
diff options
context:
space:
mode:
authorClaudomator Agent <agent@claudomator>2026-03-16 01:10:00 +0000
committerClaudomator Agent <agent@claudomator>2026-03-16 01:10:00 +0000
commitd911021b7e4a0c9f77ca9996b0ebdabb03c56696 (patch)
tree9fc5f8ab8bf3497ed25fbae698d7183a9e7c0fbe /web/test/subtask-placeholder.test.mjs
parent7f6254cdafc6143f80ee9ca8e482c36aff2c197e (diff)
feat: add elaboration_input field to tasks for richer subtask placeholder
- Add ElaborationInput field to Task struct (task.go) - Add DB migration and update CREATE/SELECT/scan in storage/db.go - Update handleCreateTask to accept elaboration_input from API - Update renderSubtaskRollup in app.js to prefer elaboration_input over description - Capture elaborate prompt in createTask() form submission - Update subtask-placeholder tests to cover elaboration_input priority - Fix missing io import in gemini.go When a task card is waiting for subtasks, it now shows: 1. The raw user prompt from elaboration (if stored) 2. The task description truncated at word boundary (~120 chars) 3. The task name as fallback 4. 'Waiting for subtasks…' only when all fields are empty Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'web/test/subtask-placeholder.test.mjs')
-rw-r--r--web/test/subtask-placeholder.test.mjs24
1 files changed, 19 insertions, 5 deletions
diff --git a/web/test/subtask-placeholder.test.mjs b/web/test/subtask-placeholder.test.mjs
index 2449faa..b279804 100644
--- a/web/test/subtask-placeholder.test.mjs
+++ b/web/test/subtask-placeholder.test.mjs
@@ -9,9 +9,10 @@ import assert from 'node:assert/strict';
//
// When a task is BLOCKED/READY and the subtask list is empty, the rollup shows
// meaningful content instead of a generic placeholder:
-// 1. task.description truncated to ~120 chars (word boundary)
-// 2. fallback to task.name if no description
-// 3. fallback to 'Waiting for subtasks…' if neither
+// 1. task.elaboration_input (raw user prompt) if present
+// 2. task.description truncated to ~120 chars (word boundary)
+// 3. fallback to task.name if no description
+// 4. fallback to 'Waiting for subtasks…' if neither
function truncateToWordBoundary(text, maxLen = 120) {
if (!text || text.length <= maxLen) return text;
@@ -20,7 +21,7 @@ function truncateToWordBoundary(text, maxLen = 120) {
}
function getSubtaskPlaceholder(task) {
- const blurb = task.description || task.name;
+ const blurb = task.elaboration_input || task.description || task.name;
return blurb ? truncateToWordBoundary(blurb) : 'Waiting for subtasks…';
}
@@ -60,7 +61,20 @@ describe('truncateToWordBoundary', () => {
});
describe('getSubtaskPlaceholder', () => {
- it('uses task.description when available', () => {
+ it('prefers task.elaboration_input over description and name', () => {
+ const task = { elaboration_input: 'fix the login bug', description: 'Fix authentication issue', name: 'auth-fix' };
+ assert.equal(getSubtaskPlaceholder(task), 'fix the login bug');
+ });
+
+ it('truncates task.elaboration_input at 120 chars', () => {
+ const longInput = 'Please fix the login bug that causes users to be logged out unexpectedly when they navigate between pages in the application user interface';
+ const task = { elaboration_input: longInput, name: 'auth-fix' };
+ const result = getSubtaskPlaceholder(task);
+ assert.ok(result.endsWith('…'), 'should end with ellipsis');
+ assert.ok(result.length <= 122, `result too long: ${result.length}`);
+ });
+
+ it('uses task.description when elaboration_input is absent', () => {
const task = { description: 'Fix auth bug', name: 'auth-fix' };
assert.equal(getSubtaskPlaceholder(task), 'Fix auth bug');
});