feat(workflows): enhance script handling and introduce custom step names

- Updated AGENTS.md to include a `name` field for scripts, allowing custom display titles in the editor and graph.
- Enhanced script icon resolution to support `.jpeg` file extensions.
- Modified workflow parsing to accommodate the new `name` property for steps, improving step identification.
- Added new utility functions for handling custom step names and display names.
- Introduced tests to validate the functionality of custom step names in workflow YAML parsing and step labeling.

Co-authored-by: Nasyarobby Putra <nasyarobby@gmail.com>
This commit is contained in:
2026-08-22 21:48:18 +07:00
parent 71cc705cd2
commit 41cca86e6e
20 changed files with 282 additions and 71 deletions
+2 -1
View File
@@ -50,7 +50,7 @@ export function readScript(name) {
}
/**
* Icon next to the script: `fetch-html.js` → `fetch-html.png` or `.jpg`.
* Icon next to the script: `fetch-html.js` → `fetch-html.png`, `.jpg`, or `.jpeg`.
* @returns {{ filePath: string, contentType: string } | null}
*/
export function resolveScriptIcon(name) {
@@ -59,6 +59,7 @@ export function resolveScriptIcon(name) {
for (const { ext, contentType } of [
{ ext: "png", contentType: "image/png" },
{ ext: "jpg", contentType: "image/jpeg" },
{ ext: "jpeg", contentType: "image/jpeg" },
]) {
const filePath = path.join(SCRIPTS_DIR, `${base}.${ext}`);
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

+23 -5
View File
@@ -9,9 +9,10 @@ export const SET_STEP_SCRIPT = "set";
* kind: "script",
* script: string,
* profile: string | null,
* config: unknown | null,
* expression?: undefined,
* id: string | null,
* config: unknown | null,
* expression?: undefined,
* name: string | null,
* id: string | null,
* needsKind: "none" | "list" | "map",
* needs: NeedEdge[],
* when: string | null,
@@ -21,8 +22,9 @@ export const SET_STEP_SCRIPT = "set";
* script: typeof SET_STEP_SCRIPT,
* profile: null,
* config: { expression: string },
* expression: string,
* id: string | null,
* expression: string,
* name: string | null,
* id: string | null,
* needsKind: "none" | "list" | "map",
* needs: NeedEdge[],
* when: string | null,
@@ -80,6 +82,7 @@ export function parseScriptStep(step) {
script: step,
profile: null,
config: null,
name: null,
id: null,
needsKind: "none",
needs: [],
@@ -119,6 +122,7 @@ export function parseScriptStep(step) {
script: hasScript ? step.script : "",
profile: hasProfile ? step.profile : null,
config: step.config ?? null,
name: parseOptionalName(step.name),
id: parseOptionalId(step.id),
needsKind,
needs,
@@ -271,6 +275,7 @@ function parseSetStep(step) {
profile: null,
config: { expression },
expression,
name: parseOptionalName(step.name),
id: parseOptionalId(step.id),
needsKind,
needs,
@@ -291,6 +296,19 @@ function parseWhen(when) {
return when;
}
/**
* @param {unknown} name
* @returns {string | null}
*/
function parseOptionalName(name) {
if (name == null || name === "") return null;
if (typeof name !== "string") {
throw new Error(`Invalid step name: ${JSON.stringify(name)}`);
}
const trimmed = name.trim();
return trimmed || null;
}
/**
* @param {unknown} id
* @returns {string | null}