FN-6335: record zero-step built-in workflow defaults

Record stepless built-in workflow defaults so zero-step selections survive task creation.\n\n- Return an explicit workflow selection for built-in workflows that compile to zero steps.\n- Cover both normal and reserved-id task creation for coding and interpreter-deferred stepwise defaults.\n- Add a patch changeset for the published Fusion package.\n\nFiles changed:\n .changeset/FN-6335-zero-step-workflow-defaults.md     |  5 +++++\n packages/core/src/__tests__/builtin-workflows.test.ts | 14 ++++++++++++++\n packages/core/src/store.ts                            |  4 +++-\n 3 files changed, 22 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6335

Fusion-Task-Lineage: 521ef05d-bef7-4d26-9f6a-592363f522d1
This commit is contained in:
gsxdsm
2026-06-13 03:37:41 -07:00
parent 35554e674e
commit 12621aaf60
3 changed files with 22 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Record explicit `builtin:coding` project-default workflow selections even when the compiled built-in has zero materialized steps, while preserving interpreter-deferred `builtin:stepwise-coding` fallback behavior.

View File

@@ -380,10 +380,24 @@ describe("built-in workflows", () => {
expect((await store.getTask(codingTask.id)).enabledWorkflowSteps ?? []).toEqual([]); expect((await store.getTask(codingTask.id)).enabledWorkflowSteps ?? []).toEqual([]);
expect(store.getTaskWorkflowSelection(codingTask.id)).toEqual({ workflowId: "builtin:coding", stepIds: [] }); expect(store.getTaskWorkflowSelection(codingTask.id)).toEqual({ workflowId: "builtin:coding", stepIds: [] });
const reservedCodingTask = await store.createTaskWithReservedId(
{ description: "reserved default builtin coding" },
{ taskId: "reserved-default-builtin-coding" },
);
expect((await store.getTask(reservedCodingTask.id)).enabledWorkflowSteps ?? []).toEqual([]);
expect(store.getTaskWorkflowSelection(reservedCodingTask.id)).toEqual({ workflowId: "builtin:coding", stepIds: [] });
await store.setDefaultWorkflowId("builtin:stepwise-coding"); await store.setDefaultWorkflowId("builtin:stepwise-coding");
const stepwiseTask = await store.createTask({ description: "default builtin stepwise" }); const stepwiseTask = await store.createTask({ description: "default builtin stepwise" });
expect((await store.getTask(stepwiseTask.id)).enabledWorkflowSteps ?? []).toEqual([]); expect((await store.getTask(stepwiseTask.id)).enabledWorkflowSteps ?? []).toEqual([]);
expect(store.getTaskWorkflowSelection(stepwiseTask.id)).toBeUndefined(); expect(store.getTaskWorkflowSelection(stepwiseTask.id)).toBeUndefined();
const reservedStepwiseTask = await store.createTaskWithReservedId(
{ description: "reserved default builtin stepwise" },
{ taskId: "reserved-default-builtin-stepwise" },
);
expect((await store.getTask(reservedStepwiseTask.id)).enabledWorkflowSteps ?? []).toEqual([]);
expect(store.getTaskWorkflowSelection(reservedStepwiseTask.id)).toBeUndefined();
}); });
it("rejects selecting the PR lifecycle fragment for a task", async () => { it("rejects selecting the PR lifecycle fragment for a task", async () => {

View File

@@ -14912,6 +14912,8 @@ ${stepsSection}`;
// default falls back cleanly with nothing written. Interpreter-deferred // default falls back cleanly with nothing written. Interpreter-deferred
// built-ins are valid selectable workflows but not lowerable to legacy // built-ins are valid selectable workflows but not lowerable to legacy
// WorkflowStep rows, so default materialization falls back to legacy defaults. // WorkflowStep rows, so default materialization falls back to legacy defaults.
// Built-ins that compile to zero steps still record a stepless selection,
// mirroring explicit workflow materialization.
let inputs: import("./types.js").WorkflowStepInput[]; let inputs: import("./types.js").WorkflowStepInput[];
try { try {
inputs = compileWorkflowToSteps(def.ir); inputs = compileWorkflowToSteps(def.ir);
@@ -14920,7 +14922,7 @@ ${stepsSection}`;
throw err; throw err;
} }
if (isBuiltinWorkflowId(workflowId) && inputs.length === 0) { if (isBuiltinWorkflowId(workflowId) && inputs.length === 0) {
return undefined; return { workflowId, stepIds: [] };
} }
const stepIds = await this.materializeWorkflowSteps(workflowId, inputs); const stepIds = await this.materializeWorkflowSteps(workflowId, inputs);
return { workflowId, stepIds }; return { workflowId, stepIds };