chore(release): v0.7.1
Version bump via changesets.
This commit is contained in:
@@ -433,7 +433,10 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
|
||||
const trimmed = description.trim();
|
||||
if (!trimmed || isSubmitting || !onCreate) return;
|
||||
|
||||
const originalDescription = description;
|
||||
setIsSubmitting(true);
|
||||
// Optimistically clear text for rapid entry; restore on failure.
|
||||
setDescription("");
|
||||
try {
|
||||
const createdTask = await onCreate({
|
||||
description: trimmed,
|
||||
@@ -467,6 +470,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
|
||||
resetForm();
|
||||
// Note: Focus restoration is handled by useEffect when isSubmitting becomes false
|
||||
} catch (err) {
|
||||
setDescription(originalDescription);
|
||||
addToast(getErrorMessage(err) || "Failed to create task", "error");
|
||||
// Keep input content on failure so user can retry
|
||||
} finally {
|
||||
|
||||
@@ -847,8 +847,10 @@
|
||||
otherwise win over the media query. */
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
width: 100% !important;
|
||||
width: 100vw !important;
|
||||
max-width: 100vw !important;
|
||||
min-height: 100dvh !important;
|
||||
height: 100dvh !important;
|
||||
max-height: 100dvh !important;
|
||||
border-radius: 0;
|
||||
|
||||
@@ -143,7 +143,40 @@ function stripTaskListHeavyFields<T>(task: T): T {
|
||||
return task;
|
||||
}
|
||||
|
||||
return { ...task, log: [] } as T;
|
||||
const candidate = task as Record<string, unknown>;
|
||||
const existingTimed = candidate.timedExecutionMs;
|
||||
// Mirror the slim REST path (listTasks): aggregate `[timing] … in <N>ms`
|
||||
// log entries before stripping the log so the board card has the same
|
||||
// total-execution figure on SSE updates as on the initial fetch.
|
||||
// Without this, `task:updated` events arrive with log=[] AND
|
||||
// timedExecutionMs=undefined, causing TaskCard to fall back to
|
||||
// workflow-only time and flicker every time an update lands.
|
||||
const timedExecutionMs =
|
||||
typeof existingTimed === "number"
|
||||
? existingTimed
|
||||
: sumTimedLogEntries(candidate.log);
|
||||
|
||||
return { ...task, log: [], timedExecutionMs } as T;
|
||||
}
|
||||
|
||||
function sumTimedLogEntries(log: unknown): number {
|
||||
if (!Array.isArray(log)) return 0;
|
||||
let total = 0;
|
||||
for (const entry of log) {
|
||||
if (!entry || typeof entry !== "object") continue;
|
||||
const action = typeof (entry as { action?: unknown }).action === "string"
|
||||
? ((entry as { action: string }).action)
|
||||
: "";
|
||||
const outcome = typeof (entry as { outcome?: unknown }).outcome === "string"
|
||||
? ((entry as { outcome: string }).outcome)
|
||||
: "";
|
||||
if (!action.includes("[timing]") && !outcome.includes("[timing]")) continue;
|
||||
const match = `${action}\n${outcome}`.match(/(\d+(?:\.\d+)?)ms\b/i);
|
||||
if (!match) continue;
|
||||
const ms = Number(match[1]);
|
||||
if (Number.isFinite(ms)) total += ms;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
function stripTaskEventHeavyFields<T>(payload: T): T {
|
||||
|
||||
Reference in New Issue
Block a user