Extract reusable TaskSpecFields form

Task 5608 · Done · Coder · created · updated

## Original requirement (verbatim, epic body) > When creating a cron, allo user to pick a different type of target. Currently the target is a project. Other types: node, none (just run a task without a project - we have that impelemented), what else? > > When node is a target it runs a task on all selected nodes. > > Implement a nice target selector, that allows to quickly add all, remove all, do all except specific, etc. It has to be a very compact and robust control. It must work for both projects, nodes and other targets. > > Make sure this is naturally working and improves previous work - triggers, crons, etc. All of these things (triggers, webhooks, crons, etc.) are combined into a unified coherent system that is state of the art and uses best practices (do a web research). Settled upstream (BA Task 5599 PRD decisions D1-D10; Architect Task 5600 design O1-O5). Do not reopen them: D4 crons + triggers merge into one Automation (When -> Target -> Action); D7 Task action REUSES the task-create UI; D8 action registry; O3 Task action adds Attachments + optional Assignee, excludes Dependencies and From Jira. Epic chain (this breakdown): C2 Node targets API -> C1 Automation core API -> C3 Fire engine API; C4 TargetSelector web; C5 TaskSpecFields web; then C6 Automations UI (needs C1, C3, C4, C5) alongside C8 dev docs reach infra; then C7 reader docs (needs C6, C8). ## This child: C5 TaskSpecFields (web) Extract the task-create fields from `TaskEditForm` into one controlled form both task create and the automation Task action use (D7, architecture sections 5.2, 6.5). Owns O3 (field set); contributes AC4.3 (one form; payload equality for every persona). Acceptance carried verbatim from the PRD: - **AC4.3 Task action reuses the task-create UI (D7).** The Action = Task section embeds the same component the console uses to create a task, so every field and validation there is present here. A field added to task creation later appears here with no extra work. *Verify:* a code search shows one task-create form used by both surfaces. (this child: the single form, with payload equality for every persona.) - **D7** "It should be able to start any type of task - same level of control as when creating a regular task. In fact we must reuse the UI, so that we don't have to maintain several." Fields that only make sense for one project, such as Feature, are offered only when the target resolves to exactly one project; otherwise they are hidden with a one-line reason. - **O3** Task action supports Attachments and an optional Assignee; Dependencies and "From Jira" are excluded. ### How (settled design, implement exactly) - New `apps/web/src/components/tasks/TaskSpecFields.tsx`: `type TaskSpec` = exactly these wire keys: persona, body, title_template, model, bound_provider, autonomous, project_memory, priority, playbook_id, transition_mode, assignee_id, attachment_ids, feature_id, hidden. Props: `{value, onChange, context: 'task'|'automation', projectIds: number[] (Feature offered only when length===1), orgId, targetKind?: TargetKind ('nodes' shows the assignee note), errors?, templateHint?, stagedFiles: File[], onStagedFilesChange}`. Define `TargetKind` locally or import from C4's `apps/web/src/ui/TargetSelector.tsx` if it has merged; the type is pinned as `'projects'|'nodes'`. - `TaskEditForm` (`apps/web/src/components/tasks/TaskEditForm.tsx`) renders `TaskSpecFields context="task"` and keeps submit, breadcrumb lifts, Dependencies and Jira. Its output and payload stay **identical**: guard with payload-equality and snapshot tests for EVERY persona (epic included), including the staged-upload-after-create flow (`TaskEditForm.tsx:1586-1592`). - `context="automation"`: hides Dependencies and Jira; Assignee optional; adds Hidden under Advanced; shows template help ({{body.x}} …) when `templateHint`; Feature only when projectIds.length===1 else hidden with a one-line reason; when targetKind==='nodes' an inline note: non-admin assignees fall back to unassigned on node targets; title_template field shown only when templateHint (event). - Follow `docs/standards/ui-copy-standards.md`. Credentials & reach: none - worktree tests only (architecture section 12: verified). Out of scope: Do NOT change regular task creation behaviour, payload, validation or layout (D7 / PRD section 5) - any visible diff in the task create page is a failure. Do NOT build the automation editor or pages (C6) or any API (C1). Do NOT offer Dependencies or From Jira in the automation context. Epic out of scope (PRD section 5, binds every child): No "None" target type for tasks (D1). No group, tag, node-group, cloud/self-hosted or online-only selector rules (D6). No new action types beyond Task and System function (D8). Do not change the webhook ingress URL scheme, existing secrets, signature verification or the dedup rules (D9, AC7.3). Do not change the task-create form's own behaviour to fit automations; any extension must leave regular task creation unchanged (D7). Do not change task claim/placement for non-automation tasks (D2). Do not alter what any system activity does when it runs (D5). Do not change Automation access roles (AC4.7). Do not rename or remove the agent verbs (AC5.5). Playbooks are untouched apart from their tab position. No feature flag and no "ships disabled". Deferred, NOT built here: F-contract; node_projects hygiene; elevated (root) node tasks; Dependencies and From Jira in automation Task actions; pause-on-failure; a catch-up window. Done means: - Zero behaviour change for task create: payload-equality tests for every persona (epic included) produce the same `POST /api/tasks` body before and after the extraction, and the existing TaskEditForm tests pass unchanged - oracle: vitest. - AC4.3 (component): one task-fields component; `grep` shows `TaskEditForm` renders `TaskSpecFields` and no second copy of those fields exists - oracle: code search in your report. - Automation context: Dependencies and Jira absent; Assignee optional; Hidden under Advanced; template hint shown when templateHint; Feature present only for exactly one project id, else a one-line reason; nodes assignee note shown when targetKind='nodes'; staged files reported via onStagedFilesChange - oracle: component tests. - Quality: the automation context renders legibly at 360 px and 1280 px (no overflow, labels readable) - oracle: screenshots in your report. - `./dc check full` green; PR merged to develop; Jaah Deploy for the merge commit succeeds (fix and re-merge if not).

Outcome

TaskSpecFields extracted as the one task-create form (task + automation contexts); 38 pre-extraction payload/DOM snapshots unchanged; CI gate green; PR #4919 merged, Jaah Deploy success. Also fixed a useCanCreateChats hook-order crash. Follow-ups in report.

Pull request

Artifacts

Activity

  • Draft
  • Ready
  • Runner started
  • Runner ended (done)