[aidan] feat/scheduled-tasks: calendar, rename, and edit workflows (#94)

* [aidan] bug: fix schedule button

* [aidan] fix/agent-errors: surface provider rate limits

* [aidan] ux/cards: click-to-rename for chat and workflow titles

Single-click a card's title to enter edit mode inline. Commit on Enter/blur,
cancel on Escape. Rename persists via PATCH for workflows and sessions.

* [aidan] feat/workflows: seed build prompt for zero-step workflows

When a new workflow has no steps, seed the agent with a prompt asking
the user to describe what the workflow should do, rather than starting blank.

* [aidan] feat/workflows: add-to-schedule popover for unscheduled workflows

Clicking the "+" on an unscheduled workflow row opens a popover with two options:
- Keep this schedule: enables the workflow's existing cadence and moves it to Scheduled
- Change schedule: opens the scheduling editor to pick a different time

* [aidan] ux/workflows: wire add-to-schedule popover and simplify New button

- Made the "+" icon on unscheduled workflow rows clickable, opening a popover
  to keep or change the schedule
- Removed AddIcon from toolbar "New" button (now reads "New" instead of "+ New")

* [aidan] fix/scheduled-tasks: open schedule calendar when Schedule pill clicked

Fixed the Schedule pill click being swallowed by the toolbar's dismiss handler.
Exempted the toolbar pills via data-toolbar-pills so their click handlers fire.

* [aidan] ux/workflows: open New workflow in agent build chat instead of empty card

When creating a new workflow from the hub, open it in edit_agent view (with the
agent builder chat) instead of a preview card. The workflow is created on the
backend first so the embedded session has a real ID.
This commit is contained in:
Aidan
2026-06-16 23:53:04 -07:00
committed by GitHub
parent e84eceee5b
commit 2bb5657ec0
22 changed files with 598 additions and 88 deletions
+15
View File
@@ -386,6 +386,21 @@ export const updateSystemPrompt = createAsyncThunk(
}
);
export const renameSession = createAsyncThunk(
'agents/rename',
async ({ sessionId, name }: { sessionId: string; name: string }, { dispatch }) => {
// Optimistic local update; the backend echoes the new name back over
// the agent:status broadcast, which keeps every open card in sync.
dispatch(updateSessionName({ sessionId, name }));
await fetch(`${AGENTS_API}/sessions/${sessionId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name }),
});
return { sessionId, name };
}
);
export const updateThinkingLevel = createAsyncThunk(
'agents/updateThinkingLevel',
async ({ sessionId, level }: { sessionId: string; level: 'off' | 'low' | 'medium' | 'high' | 'auto' }) => {
@@ -27,7 +27,7 @@ export const GRID_GAP = 24;
const GRID_ORIGIN = { x: 40, y: 100 };
const GRID_COLS_FALLBACK = 4;
export type CardType = 'agent' | 'view' | 'browser' | 'note' | 'workflow';
export type CardType = 'agent' | 'view' | 'browser' | 'note' | 'workflow' | 'workflows-hub';
export interface CardPosition {
session_id: string;
@@ -1080,7 +1080,7 @@ const dashboardLayoutSlice = createSlice({
moveCards(
state,
action: PayloadAction<{
items: Array<{ id: string; type: 'agent' | 'view' | 'browser' | 'note' | 'workflow' }>;
items: Array<{ id: string; type: CardType }>;
dx: number;
dy: number;
}>,
@@ -1111,6 +1111,11 @@ const dashboardLayoutSlice = createSlice({
card.x += dx;
card.y += dy;
}
} else if (item.type === 'workflows-hub') {
if (state.workflowsHub) {
state.workflowsHub.x += dx;
state.workflowsHub.y += dy;
}
} else {
const card = state.browserCards[item.id];
if (card) {