feat(FN-4150): complete Step 2 — preserve plugin workflow step mode metadata
Fusion-Task-Id: FN-4150 Fusion-Task-Lineage: 153c239b-f6cd-49e4-bc13-216e0d2ca815
This commit is contained in:
@@ -128,7 +128,7 @@ describe("TaskStore Workflow Steps", () => {
|
|||||||
expect(found).toBeUndefined();
|
expect(found).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should resolve plugin workflow steps from injected templates", async () => {
|
it("should resolve plugin script-mode workflow steps from injected templates", async () => {
|
||||||
store.setPluginWorkflowStepTemplates([
|
store.setPluginWorkflowStepTemplates([
|
||||||
{
|
{
|
||||||
pluginId: "my-plugin",
|
pluginId: "my-plugin",
|
||||||
@@ -136,6 +136,58 @@ describe("TaskStore Workflow Steps", () => {
|
|||||||
id: "plugin:my-plugin:my-step",
|
id: "plugin:my-plugin:my-step",
|
||||||
name: "My Plugin Step",
|
name: "My Plugin Step",
|
||||||
description: "Plugin-provided step",
|
description: "Plugin-provided step",
|
||||||
|
mode: "script",
|
||||||
|
phase: "pre-merge",
|
||||||
|
scriptName: "my-plugin:run-step",
|
||||||
|
prompt: "",
|
||||||
|
toolMode: "readonly",
|
||||||
|
defaultOn: false,
|
||||||
|
modelProvider: "anthropic",
|
||||||
|
modelId: "claude-sonnet-4-5",
|
||||||
|
category: "Plugin",
|
||||||
|
icon: "puzzle",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const listed = await store.listWorkflowSteps();
|
||||||
|
const listedStep = listed.find((candidate) => candidate.id === "plugin:my-plugin:my-step");
|
||||||
|
expect(listedStep).toMatchObject({
|
||||||
|
id: "plugin:my-plugin:my-step",
|
||||||
|
templateId: "my-step",
|
||||||
|
name: "My Plugin Step",
|
||||||
|
mode: "script",
|
||||||
|
phase: "pre-merge",
|
||||||
|
scriptName: "my-plugin:run-step",
|
||||||
|
defaultOn: false,
|
||||||
|
modelProvider: "anthropic",
|
||||||
|
modelId: "claude-sonnet-4-5",
|
||||||
|
});
|
||||||
|
|
||||||
|
const step = await store.getWorkflowStep("plugin:my-plugin:my-step");
|
||||||
|
expect(step).toMatchObject({
|
||||||
|
id: "plugin:my-plugin:my-step",
|
||||||
|
templateId: "my-step",
|
||||||
|
mode: "script",
|
||||||
|
phase: "pre-merge",
|
||||||
|
scriptName: "my-plugin:run-step",
|
||||||
|
defaultOn: false,
|
||||||
|
modelProvider: "anthropic",
|
||||||
|
modelId: "claude-sonnet-4-5",
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should resolve plugin prompt-mode workflow steps from injected templates", async () => {
|
||||||
|
store.setPluginWorkflowStepTemplates([
|
||||||
|
{
|
||||||
|
pluginId: "my-plugin",
|
||||||
|
template: {
|
||||||
|
id: "plugin:my-plugin:prompt-step",
|
||||||
|
name: "My Prompt Step",
|
||||||
|
description: "Prompt plugin step",
|
||||||
|
mode: "prompt",
|
||||||
|
phase: "pre-merge",
|
||||||
prompt: "Run plugin checks",
|
prompt: "Run plugin checks",
|
||||||
toolMode: "readonly",
|
toolMode: "readonly",
|
||||||
category: "Plugin",
|
category: "Plugin",
|
||||||
@@ -144,14 +196,12 @@ describe("TaskStore Workflow Steps", () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const step = await store.getWorkflowStep("plugin:my-plugin:my-step");
|
const step = await store.getWorkflowStep("plugin:my-plugin:prompt-step");
|
||||||
expect(step).toMatchObject({
|
expect(step).toMatchObject({
|
||||||
id: "plugin:my-plugin:my-step",
|
id: "plugin:my-plugin:prompt-step",
|
||||||
templateId: "my-step",
|
templateId: "prompt-step",
|
||||||
name: "My Plugin Step",
|
|
||||||
mode: "prompt",
|
mode: "prompt",
|
||||||
phase: "pre-merge",
|
prompt: "Run plugin checks",
|
||||||
enabled: true,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1042,7 +1042,14 @@ export class PluginLoader extends EventEmitter<{
|
|||||||
name: step.name,
|
name: step.name,
|
||||||
description: step.description,
|
description: step.description,
|
||||||
prompt: step.prompt ?? "",
|
prompt: step.prompt ?? "",
|
||||||
|
mode: step.mode,
|
||||||
|
phase: step.phase,
|
||||||
|
scriptName: step.scriptName,
|
||||||
toolMode: step.toolMode,
|
toolMode: step.toolMode,
|
||||||
|
defaultOn: step.defaultOn,
|
||||||
|
modelProvider: step.modelProvider,
|
||||||
|
modelId: step.modelId,
|
||||||
|
enabled: step.enabled,
|
||||||
category: "Plugin",
|
category: "Plugin",
|
||||||
icon: "puzzle",
|
icon: "puzzle",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7163,11 +7163,15 @@ ${stepsSection}`;
|
|||||||
templateId: stepId,
|
templateId: stepId,
|
||||||
name: entry.template.name,
|
name: entry.template.name,
|
||||||
description: entry.template.description,
|
description: entry.template.description,
|
||||||
mode: "prompt",
|
mode: entry.template.mode ?? "prompt",
|
||||||
phase: "pre-merge",
|
phase: entry.template.phase ?? "pre-merge",
|
||||||
prompt: entry.template.prompt,
|
prompt: entry.template.prompt ?? "",
|
||||||
|
scriptName: entry.template.scriptName,
|
||||||
toolMode: entry.template.toolMode,
|
toolMode: entry.template.toolMode,
|
||||||
enabled: entry.template.enabled ?? true,
|
enabled: entry.template.enabled ?? true,
|
||||||
|
defaultOn: entry.template.defaultOn,
|
||||||
|
modelProvider: entry.template.modelProvider,
|
||||||
|
modelId: entry.template.modelId,
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -396,8 +396,20 @@ export interface WorkflowStepTemplate {
|
|||||||
description: string;
|
description: string;
|
||||||
/** Full agent prompt template */
|
/** Full agent prompt template */
|
||||||
prompt: string;
|
prompt: string;
|
||||||
|
/** Execution mode for plugin-contributed templates; defaults to prompt. */
|
||||||
|
mode?: WorkflowStepMode;
|
||||||
|
/** Task lifecycle phase for plugin-contributed templates; defaults to pre-merge. */
|
||||||
|
phase?: "pre-merge" | "post-merge";
|
||||||
|
/** Script name for script-mode plugin templates. */
|
||||||
|
scriptName?: string;
|
||||||
/** Tool set available when the template runs as a prompt-mode step. */
|
/** Tool set available when the template runs as a prompt-mode step. */
|
||||||
toolMode?: WorkflowStepToolMode;
|
toolMode?: WorkflowStepToolMode;
|
||||||
|
/** Whether this template should be auto-selected for new tasks. */
|
||||||
|
defaultOn?: boolean;
|
||||||
|
/** AI model provider override for prompt-mode templates. */
|
||||||
|
modelProvider?: string;
|
||||||
|
/** AI model ID override for prompt-mode templates. */
|
||||||
|
modelId?: string;
|
||||||
/** Grouping category (e.g., "Quality", "Security") */
|
/** Grouping category (e.g., "Quality", "Security") */
|
||||||
category: string;
|
category: string;
|
||||||
/** Optional icon identifier for UI (e.g., "file-text", "shield") */
|
/** Optional icon identifier for UI (e.g., "file-text", "shield") */
|
||||||
|
|||||||
Reference in New Issue
Block a user